Source code for core.alea

# -*- python -*-
#
#       OpenAlea.Core
#
#       Copyright 2006-2009 INRIA - CIRAD - INRA
#
#       File author(s): Samuel Dufour-Kowalski <samuel.dufour@sophia.inria.fr>
#
#       Distributed under the Cecill-C License.
#       See accompanying file LICENSE.txt or copy at
#           http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html
#
#       OpenAlea WebSite : http://openalea.gforge.inria.fr
#
###############################################################################
""" a script to run alea dataflow and scripts"""

__license__ = "Cecill-C"
__revision__ = "$Id$"

import sys
from optparse import OptionParser
#import threading
from openalea.core.pkgmanager import PackageManager


[docs]def start_qt(factory, node): """ Start Qt, and open widget of factory, node :param factory: todo :param node: todo """ from openalea.vpltk.qt import QtGui, QtCore app = QtGui.QApplication(sys.argv) # CTRL+C binding import signal signal.signal(signal.SIGINT, signal.SIG_DFL) dialog = QtGui.QDialog() widget = factory.instantiate_widget(node, autonomous=True) dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose) widget.setParent(dialog) vboxlayout = QtGui.QVBoxLayout(dialog) vboxlayout.setContentsMargins(3, 3, 3, 3) vboxlayout.setSpacing(5) vboxlayout.addWidget(widget) dialog.setWindowTitle(factory.name) dialog.show() app.exec_()
[docs]def load_package_manager(*args): """ Return the package manager :param pkg_id: package id :param node_id: node id :returns: package manager """ pm = PackageManager() pm.init(verbose=False) return pm
[docs]def get_node(component, inputs, pm=None): """ retrieve a node from its component name and inputs :param component: todo :param inputs: todo :param pm: package manager """ pkg_id, node_id = component if (not pm): pm = load_package_manager() try: factory = pm[pkg_id][node_id] except Exception, e: print "Cannot run node %s:%s" % (pkg_id, node_id) query(component, pm) raise e node = factory.instantiate() if (inputs): for k, v in inputs.iteritems(): try: node.set_input(k, v) except KeyError, e: print "Unknown input %s" % (k, ) query(component, pm) raise e return factory, node
[docs]def run_and_display(component, inputs, gui=False, pm=None): """ run component with inputs :param component: todo :param inputs: todo :param gui: todo :param pm: package manager :type gui: boolean (default is False) :type pm: package manager """ factory, node = get_node(component, inputs, pm) if (not gui): try: node.eval() print _outputs(node) except Exception, error: print "Error while executing component : ", error print "Try with -g flag" return else: start_qt(factory, node)
[docs]def run(component, inputs, pm=None, vtx_id=-1): """ Run component with inputs. can exit by exception. If node_id is given, eval the dataflow from that node and return the result. """ _factory, node = get_node(component, inputs, pm) if vtx_id < 0: node.eval() return _outputs(node) else: node.eval_as_expression(vtx_id) return _outputs(node.node(vtx_id))
[docs]def query(component, pm=None): """ show help of component """ pkg_id, node_id = component if (not pm): pm = load_package_manager() # package not found if (not pkg_id or not pm.has_key(pkg_id)): print "Package '%s' not found." % (pkg_id) print "\nAvailable packages are :" keys = pm.keys() keys.sort() for p in keys: print " ", p return pkg = pm[pkg_id] if(not pkg.has_key(node_id)): print "Unknown node '%s'" % (node_id, ) node_id = None # query package print "\nPackage" print "-------" print "name : ", pkg.name for key, info in pkg.metainfo.iteritems(): print "%s : %s" % (key, info) if(not node_id): keys = pkg.keys() keys.sort() print "\nAvailable nodes are:" for k in keys: print " ", pkg[k].get_id() # query node else: factory = pkg[node_id] node = factory.instantiate() doc = node.__doc__ if doc: doc = doc.split('\n') doc = [x.strip() for x in doc] doc = '\n'.join(doc) else: doc = factory.description print "\nComponent" print "---------" print "Name : %s" % (factory.name) print "Documentation : %s" % (doc, ) print "Inputs:" for i in xrange(node.get_nb_input()): port = node.get_input_port(i) print " ", port.get_tip() print "Outputs:" for port in node.output_desc: print " ", port.get_tip()
[docs]def parse_component(name): """ Return (pkg_id, node_id) from name """ tname = name.split('/') if(len(tname)<2): tname = name.split(':') if(len(tname) == 1): return (tname[0], None) elif(len(tname) == 2): return (tname[0], tname[1]) else: raise ValueError("Component name error :\ cannot parse 'pkg_id:node_id'")
[docs]def get_intput_callback(option, opt_str, value, parser): """todo""" assert value is None value = {} rargs = parser.rargs while rargs: arg = rargs[0] # Stop if we hit an arg like "--foo", "-a", "-fx", "--file=f", # etc. Note that this also stops on "-3" or "-3.0", so if # your option takes numeric values, you will need to handle # this. if ((arg[:2] == "--" and len(arg) > 2) or (arg[:1] == "-" and len(arg) > 1 and arg[1] != "-")): break else: v = arg.split("=") if(len(v) != 2): raise ValueError("Invalid input %s" % (str(arg))) value[v[0]] = v[1] del rargs[0] for k, v in value.iteritems(): try: v = eval(v) value[k] = v except: pass setattr(parser.values, option.dest, value)
[docs]def function(factory): ''' Return a function which is evaluated like a python function. factory is a NodeFactory. ''' node = factory.instantiate() def f(*args, **kwds): for i, v in enumerate(args): node.set_input(i,v) for k, v in kwds.iteritems(): node.set_input(k,v) node.eval() nb_output = node.get_nb_output() return tuple(node.output(i) for i in range(nb_output)) return f
def _outputs(node): #return node.outputs return [node.output(i) for i in range(node.get_nb_output())]
[docs]def main(): """ Parse options """ # options usage = """ %prog [-r|-q] package_id[:node_id] [-i key1=val1 key2=val2 ...] or %prog [-r|-q] package_id[/node_id] [-i key1=val1 key2=val2 ...] """ parser = OptionParser(usage=usage) parser.add_option("-q", "--query", dest="query", help="Show package/component help.", action="store_true", default=True) parser.add_option("-r", "--run", dest="run", help="Run component.", action="store_true", default=False) parser.add_option("-g", "--gui", help="Open graphical user interface", action="store_true", default=False) parser.add_option("-l", "--local_data", help="Data are local (ie in current directory)", action="store_true", default=False) parser.add_option("-i", "--input", action="callback", callback=get_intput_callback, help="Specify inputs as KEY=VALUE, KEY=VALUE...", dest="input") try: (options, args)= parser.parse_args() except Exception, error: parser.print_usage() print "Error while parsing args:", error return if(len(args) < 1): parser.error("Incomplete command : specify a 'package_id:node_id'") component = parse_component(args[0]) # Execute if(options.local_data): import openalea.core.data openalea.core.data.PackageData.__local__ = True if(options.run): run_and_display(component, options.input, options.gui) else: query(component, )
if __name__ == "__main__": main() # this example need to be fixed #python alea.py -r -g "adel.macro:6 plot_scene" #-i leafdb="'$OPENALEAPKG/adel/adel/data/leaves1.db'" # lsystem="'$OPENALEAPKG/adel/adel/lsystem/Adel.l'"