Source code for core.system.systemnodes

# -*- python -*-
#
#       OpenAlea.Core
#
#       Copyright 2006-2009 INRIA - CIRAD - INRA
#
#       File author(s): Samuel Dufour-Kowalski <samuel.dufour@sophia.inria.fr>
#                       Christophe Pradal <christophe.prada@cirad.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
#
###############################################################################
"""System Nodes"""

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

from openalea.core.node import AbstractNode, Node, Annotation
from openalea.core.dataflow import SubDataflow

DEBUG = False


[docs]class AnnotationNode(Annotation): """ A DummyNode is a fake node.""" __graphitem__ = "annotation.Annotation"
[docs] def get_nb_input(self): """ Return the nb of input ports """ return 0
[docs] def get_nb_output(self): """ Return the nb of output ports """ return 0
[docs] def eval(self): return False
[docs]class IterNode(Node): """ Iteration Node """ def __init__(self, *args): """ Constructor """ Node.__init__(self, *args) self.iterable = "Empty"
[docs] def reset(self): """ Reset to the intial state """ self.iterable = "Empty" if hasattr(self, 'nextval'): del self.nextval
[docs] def eval(self): """ Return True if the node need a reevaluation """ try: if self.iterable == "Empty": self.iterable = iter(self.inputs[0]) if(hasattr(self, "nextval")): self.outputs[0] = self.nextval else: self.outputs[0] = self.iterable.next() self.nextval = self.iterable.next() return True except TypeError, e: self.outputs[0] = self.inputs[0] return False except StopIteration, e: self.iterable = "Empty" if(hasattr(self, "nextval")): del self.nextval return False
[docs]class IterWithDelayNode(IterNode): """ Iteration Node """
[docs] def eval(self): """ Return True if the node need a reevaluation """ try: if self.iterable == "Empty": self.iterable = iter(self.inputs[0]) if(hasattr(self, "nextval")): self.outputs[0] = self.nextval else: self.outputs[0] = self.iterable.next() self.nextval = self.iterable.next() return self.inputs[1] except TypeError, e: self.outputs[0] = self.inputs[0] return False except StopIteration, e: self.iterable = "Empty" if(hasattr(self, "nextval")): del self.nextval return False
[docs]class StopSimulation(Node): """ Iteration Node """ def __init__(self, *args): """ Constructor """ Node.__init__(self, *args) self.reset()
[docs] def reset(self): self._nb_cycles = 0
[docs] def eval(self): """ Stop the simulation after a given number of steps """ nb_cycles = self.inputs[1] self.outputs[0] = self.inputs[0] self._nb_cycles += 1 if self._nb_cycles < nb_cycles: return 1 else: return False
[docs]class Counter(Node): """ Loop a number of cycle, then stop """ def __init__(self, *args): """ Constructor """ Node.__init__(self, *args) self.reset()
[docs] def reset(self): self._current_cycle = None
[docs] def eval(self): """ Stop the simulation after a given number of steps """ start, stop, step = self.inputs[:3] delay = self.delay if self._current_cycle is None: self._current_cycle = start self.outputs[0] = self._current_cycle return delay if self._current_cycle + step < stop: self._current_cycle += step self.outputs[0] = self._current_cycle return delay return False
[docs]class RDVNode(Node): """ Rendez Vous node (synchronisation) In1 : Value In2 : Unused (control flow) Out : Value, result of the control flow evaluation """ def __call__(self, inputs): """ inputs is the list of input values """ return inputs[0], inputs[1]
from openalea.core.datapool import DataPool
[docs]class PoolReader(Node): """ In : Name (key) Out : Object (value) """ def __init__(self, inputs, outputs): Node.__init__(self, inputs, outputs) self.pool = DataPool() def __call__(self, inputs): """ inputs is the list of input values """ key = inputs[0] obj = self.pool.get(key) if key in self.pool: self.set_caption("%s" % (key, )) return (obj, )
[docs]class PoolWriter(Node): """ In : Name (String), Object (Any) """ def __init__(self, inputs, outputs): Node.__init__(self, inputs, outputs) self.pool = DataPool() def __call__(self, inputs): """ inputs is the list of input values """ key = inputs[0] obj = inputs[1] self.set_caption("%s = %s" % (key, obj)) self.pool[key] = obj return (obj, )
[docs]class PoolDefault(Node): """ In : Name (key), Default Value Out : Object (value) """ def __init__(self, inputs, outputs): Node.__init__(self, inputs, outputs) self.pool = DataPool()
[docs] def reset(self): if hasattr(self, 'key'): del self.pool[self.key]
def __call__(self, inputs): """ inputs is the list of input values """ key = inputs[0] default_value = inputs[1] self.default = default_value self.key = key obj = self.pool.setdefault(key, default_value) if key in self.pool: self.set_caption("%s" % (key,)) else: self.set_caption("%s = %s" % (key, default_value)) return (obj, )
[docs]class InitNode(Node): """ In0 : Init value In1 : Current Value In2 : State (Bool) If state is true, return In0, else return In1 state is set to false in the first execution. """ def __init__(self, inputs, outputs): Node.__init__(self, inputs, outputs) self.state = True def __call__(self, inputs): """ inputs is the list of input values """ if(self.state): ret = inputs[0] else: ret = inputs[1] self.state = False return (ret, )
[docs] def reset(self): Node.reset(self) self.state = True
[docs]class AccuList(Node): """ List Accumulator Add to a list (in datapool) the receive value :param inputs: a list containing the value to append and the name of the datapool variable """ def __init__(self, inputs, outputs): Node.__init__(self, inputs, outputs) self.pool = DataPool() def __call__(self, inputs): varname = inputs[1] value = inputs[0] if(not varname): varname = "AccuList_%i" % (id(self)) # Create datapool variable if necessary if(not self.pool.has_key(varname) or not isinstance(self.pool[varname], list)): l = list() self.pool[varname] = l else: l = self.pool[varname] self.set_caption("list accumulator : %s" % (repr(str(varname)))) l.append(value) return (l, )
[docs]class AccuFloat(Node): """ Float Accumulator Add to a Float (in datapool) the receive value :param inputs: a list containing the value to append and the name of the datapool variable """ def __init__(self, inputs, outputs): Node.__init__(self, inputs, outputs) self.pool = DataPool() def __call__(self, inputs): varname = inputs[1] value = inputs[0] if(not varname): varname = "AccuFloat_%i" % (id(self)) # Create datapool variable if necessary if(not self.pool.has_key(varname) or not isinstance(self.pool[varname], float)): self.pool[varname] = 0. self.set_caption("float accumulator : %s" % (repr(str(varname)))) self.pool[varname] += float(value) return (self.pool[varname], )
[docs]class LambdaVar(Node): """ Return a lambda variable """ # cpt = 0 def __init__(self, *args): Node.__init__(self, *args) self.set_caption("X") # self.set_caption("X" + str(LambdaVar.cpt)) # LambdaVar.cpt = 1 def __call__(self, inputs): return SubDataflow(None, None, 0, 0)
[docs]class Delay(Node): """ Return the previous value or an initial value """ def __init__(self, *args): Node.__init__(self, *args) self.previous = None def __call__(self, inputs): init, x = inputs[:2] if self.previous is None: res = self.previous = init else: res = self.previous self.previous = x return res,
[docs] def reset(self): """ Reset to the intial state """ self.previous = None
[docs]class WhileUniVar(Node): """ While Loop Univariate In 0 : Initial value In 1 : Test function In 2 : Process Function Out 0 : Result value """ def __call__(self, inputs): value = inputs[0] test = inputs[1] func = inputs[2] cpt = 0 while(test(value)): newvalue = func(value) # Test for infinite loop if(value == newvalue): cpt += 1 if(cpt > 1000): raise RuntimeError("Infinite Loop") else: value = newvalue if DEBUG: print value return (value, )
[docs]class WhileMultiVar(Node): """ While Loop Multivariate In 0 : List of initial value In 1 : Test function In 2 : List of Process Function Out 0 : Result variables """ def __call__(self, inputs): values = inputs[0] test = inputs[1] funcs = inputs[2] cpt = 0 while(test(*values)): newvals = [] for f in funcs: res = f(*values) newvals.append(res) # Test for infinite loop if(values == newvals): cpt += 1 if(cpt > 1000): raise RuntimeError("Infinite Loop") else: values = newvals if DEBUG: print values return values
[docs]def while_multi2(values, test, function): cpt = 0 while(test(*values)): newvals = function(*values) # Test for infinite loop if(values == newvals): cpt += 1 if(cpt > 1000): raise RuntimeError("Infinite Loop") else: values = newvals print values return values
[docs]def system_cmd(str_list): """ Execute a system command Input : a list of string Output : subprocess stdout, stderr """ import subprocess return subprocess.Popen(str_list, stdout=subprocess.PIPE).communicate()
[docs]def shell_command(cmd, directory): """ Execute a command in a shell cmd : the command as a string dir : the directory where the cmd is executed Output : status """ from subprocess import Popen, STDOUT, PIPE p = Popen(cmd, shell=True, cwd=directory, stdin=PIPE, stdout=STDOUT, stderr=STDOUT) status = p.wait() return status,
[docs]class For(Node): """ While Loop Univariate In 0 : Initial value In 1 : Sequence In 2 : Process Function Out 0 : Result value """ def __call__(self, inputs): value = inputs[0] l = inputs[1] func = inputs[2] for i in l: value = func(value, i) return (value, )
[docs]def get_data(pattern='*.*', pkg_name=None, as_paths=False): """ Return all data that match the pattern """ from openalea.core.pkgmanager import PackageManager pm = PackageManager() result = pm.get_data(pattern, pkg_name, as_paths) nodes = [x.instantiate() for x in result] for node in nodes: node.eval() names = [x.name for x in result] filenames = [node.get_output(0) for node in nodes] return dict(zip(names, filenames))