Source code for pycropml.xml2wf

from __future__ import absolute_import
from __future__ import print_function
try:
    from openalea.core.external import *
    from openalea.core.pkgmanager import PackageManager
    from openalea.core import node
except:
    inter = None
    package = None
    node = None
    has_openalea = False
    
from pycropml.render_python import generate_doc
from pycropml.pparse import model_parser


[docs]class XmlToWf(object): def __init__(self, xmlwf,dir, pkg_name): self.xmlwf = xmlwf self.dir=dir self.pkg_name = pkg_name self.inputLinks = self.xmlwf.inputlink self.outputLinks = self.xmlwf.outputlink self.internalLinks = self.xmlwf.internallink self.inputs = [] self.outputs = []
[docs] def run(self): self.doc = generate_doc(self.xmlwf) self.pkg = self.retrievePackage(self.pkg_name) self.compositeNodeInputs() self.compositeNodeOutputs() self.wf = CompositeNode(self.inputs_wf, self.outputs_wf) self.createNodes() # BUG: replace doc with description wf_factory = CompositeNodeFactory(self.xmlwf.name+"_wf", description=self.doc) self.connectOutputs() self.connectInputs() self.connectInternal() self.wf.to_factory(wf_factory) if wf_factory.name in self.pkg: del self.pkg[wf_factory.name] self.pkg.add_factory(wf_factory) self.pkg.write() print(self.compoPack("A"))
[docs] def retrievePackage(self, name): pm = PackageManager() pm.init(self.dir, False) pkg = pm[name] return pkg
[docs] def compoPack(self, name): for model in self.xmlwf.model: if model.name == name and model.package_name: dir = model.path
[docs] def compareInterface(self,interfaces): test= True n = 1 while(test and n!=len(interfaces)): if interfaces[n].min != interfaces[n-1].min: test=False break elif interfaces[n].max!=interfaces[n-1].max: test=False break elif interfaces[n].step!=interfaces[n-1].step: test=False break elif type(interfaces[n])!=type(interfaces[n-1]): test=False break n=n+1 return test
[docs] def compositeNodeInputs(self): ins=[] names = [] for link in self.inputLinks: name = link["source"] if name not in names: names.append(name) # some models can have the same inputs. These inputs must have the same interfaces for name in names: links_sameName = [link for link in self.inputLinks if link["source"]==name] #print(links_sameName) if len(links_sameName)!=1: interfaces=[] try: for j in links_sameName: model= j["target"].split('.')[0] inputs = self.pkg[model].inputs interface=[inp["interface"] for inp in inputs if inp["name"]==name] interfaces.append(interface[0]) #assert self.compareInterface(interfaces)== True except AssertionError: print(("inequal interface: %s %s"% (interfaces, links_sameName))) for inp in inputs: if inp["name"]==name and "value" in inp: value=inp["value"] break if value: din=dict(name=name, interface = interfaces[0], value=value) else: din=dict(name=name, interface = interfaces[0]) ins.append(din) self.inputs.append(name) else: value=None model= links_sameName[0]["target"].split('.')[0] if model in self.pkg: inputs = self.pkg[model].inputs interface=[inp["interface"] for inp in inputs if inp["name"]==name] for inp in inputs: if inp["name"]==name and "value" in inp: value=inp["value"] break if value: din=dict(name=name, interface = interface[0], value=value) else: din=dict(name=name, interface = interface[0]) ins.append(din) self.inputs.append(name) self.inputs_wf = ins
[docs] def compositeNodeOutputs(self): outs=[] # model units outputs must be unique. So model composite output is targeted by an unique output link for link in self.outputLinks: name = link["target"] model_src, out_src= link["source"].split('.') if model_src in self.pkg: outputs = self.pkg[model_src].outputs interface=[out["interface"] for out in outputs if out["name"]==name] dout= dict(name=name, interface = interface[0]) outs.append(dout) self.outputs.append(name) self.outputs_wf = outs
[docs] def createNodes(self): self.nodes = {} for m in self.xmlwf.model: if m.name in self.pkg: nf = self.pkg[m.name].instantiate() nid = self.wf.add_node(nf) self.nodes[m.name] = nid
[docs] def connectInputs(self): for link in self.inputLinks: src, tgt = link['source'], link['target'] port_out = src name_tgt, port_in = tgt.split('.') if name_tgt in self.nodes: ns, nt = self.wf.id_in, self.nodes[name_tgt] try: pout, pin = self.wf.node(ns).map_index_out[port_out], self.wf.node(nt).map_index_in[port_in] except KeyError: if port_out not in self.wf.node(ns).map_index_out: print('Error input link src : ', src) else: print(('Error input link tgt: ', tgt)) continue self.wf.connect(ns, pout, nt, pin)
[docs] def connectOutputs(self): for link in self.outputLinks: src, tgt = link['source'], link['target'] name_src, port_out = src.split('.') port_in = tgt if name_src in self.nodes: ns, nt = self.nodes[name_src], self.wf.id_out try: pout, pin = self.wf.node(ns).map_index_out[port_out], self.wf.node(nt).map_index_in[port_in] except KeyError: if port_out not in self.wf.node(ns).map_index_out: print('Error output link src: ', src) else: print(('Error output link tgt: ', tgt)) continue self.wf.connect(ns, pout, nt, pin)
[docs] def connectInternal(self): for link in self.internalLinks: src, tgt = link['source'], link['target'] name_src, port_out = src.split('.') name_tgt, port_in = tgt.split('.') if name_tgt in self.nodes and name_src in self.nodes: ns, nt = self.nodes[name_src], self.nodes[name_tgt] try: pout, pin =self. wf.node(ns).map_index_out[port_out], self.wf.node(nt).map_index_in[port_in] except KeyError: if port_out not in self.wf.node(ns).map_index_out: print('Error : ', src) else: print(('Error : ', tgt)) continue self.wf.connect(ns, pout, nt, pin)