Beispiel #1
0
    def __init__(self, *args, **kwargs):
        """
        :param args: if given, only the first one is considered, and it becomes the name
                     of the BlackBox
        :param kwargs: any parameter that is a declared parameter or a forwarded one
        """
        # check that the overrides have proper types
        # declare_direct_params has to be a classmethod or a staticmethod (as declare_params uses it and it's a
        # classmethod)
        for func in [self.__class__.declare_cells, self.__class__.declare_direct_params,
                     self.__class__.declare_forwards]:
            if type(func) != types.FunctionType:
                if type(func) != types.MethodType:
                    raise BlackBoxError('The "%s" member of the BlackBox %s ' % (func.__name__,
                                        self.__class__.__name__) + 'is not a function.')
                if func.__self__ is None:
                    raise BlackBoxError('The "%s" function of the BlackBox %s '  % (func.__name__,
                                self.__class__.__name__) + 'needs to be decorated with @classmethod or @staticmethod.')

        self.niter = kwargs.get('niter', 1)
        self.__impl = None
        self.__doc__ = ''

        self.__params = ecto.Tendrils()
        self.__inputs = ecto.Tendrils()
        self.__outputs = ecto.Tendrils()

        self.__configure(**kwargs)
        self.__connect()
        self.__impl.name(self.__class__.__name__)
        self.__gen_doc()
        if len(args) > 0:
            self.__impl.name(args[0])
Beispiel #2
0
def config_yaml_for_ecto_cell(cls, header=None):
    """
    Given an ecto cell, generate YAML for all the possibles parameters

    :param cls: the class of an ecto cell
    :param header: this is just the name of the cell section. If None, no header is written and no indent is given
    """
    if header:
        res = '%s:\n' % header
        indent = '   '
    else:
        res = ''
        indent = ''
    res += '%stype: %s\n' % (indent, cls.__name__)
    res += '%smodule: %s\n' % (indent, cls.__module__)
    # display the parameters
    res += '%sparameters:\n' % indent
    p = ecto.Tendrils()
    try:
        cls.declare_params(p)
    except AttributeError:
        p = cls.params
    for tendril_name, tendril in list(p.items()):
        # Split the doc string to 100 characters
        line = '%s   # ' % indent
        for word in tendril.doc.split():
            if len(line + ' ' + word) > 100:
                res += line + '\n'
                line = '%s   # %s' % (indent, word)
            else:
                line += ' ' + word
        res += line + '\n'
        res += '%s   %s: %s\n' % (indent, tendril_name, tendril.val)

    return res
Beispiel #3
0
def test_bb2(options):
    # start is going to be ignored as it is set to 20 by default
    mm = MyBlackBox2(start=0, step=3, amount1=10, amount2=50)
    # make sure the declare functions work
    p = ecto.Tendrils()
    i = ecto.Tendrils()
    o = ecto.Tendrils()
    mm.declare_params(p)
    mm.declare_io(p, i, o)
    # run the BlackBox
    plasm = ecto.Plasm()
    plasm.insert(mm)
    options.niter = 5
    run_plasm(options, plasm)
    # final value is start + step*(5-1)+amount1+amount2
    assert mm.outputs.value == 92
    run_plasm(options, plasm)
    # final value is start + step*(5+5-1)+amount1+amount2
    assert mm.outputs.value == 107
Beispiel #4
0
def test_tendrils_serialization():
    t = ecto.Tendrils()
    t.declare("Hello", ecto.Tendril.createT('std::string'))

    t.declare("Woot", ecto.Tendril.createT('double'))
    t.Hello = 'World'
    t.Woot = math.pi
    ofs = StringIO()
    t.save(ecto.ostream(ofs))

    #grab the string
    ifs = StringIO(ofs.getvalue())

    t_ds = ecto.Tendrils()
    t_ds.load(ecto.istream(ifs))
    print 'loaded:'
    for key, val in t_ds.iteritems():
        print key, val.val
    assert t_ds.Woot == math.pi
    assert t_ds.Hello == 'World'
Beispiel #5
0
    def declare_io(cls, p, i, o):
        """
        This function has the same meaning as in C++ and should NOT be overriden by a child class.

        :param p: an ecto.Tendrils object for the parameters
        :param i: an ecto.Tendrils object for the inputs
        :param o: an ecto.Tendrils object for the outputs   
        """
        cell_infos = cls.declare_cells(p)
        try:
            _p_forwards, i_forwards, o_forwards = cls.declare_forwards(p)
        except:
            raise BlackBoxError('Your declare_forwards needs to return a tuple of 3 dictionaries '
                                'of the form:\n'
                                '{"cell_name": "all", "cell_name": [BlackBoxForward1, BlackBoxForward2]}')

        # go over the two sets of tendrils: i and o
        for info_tuple in [(i_forwards, i, 'inputs'), (o_forwards, o, 'outputs')]:
            cell_forwards, tendrils, tendril_type = info_tuple
            for cell_name, forwards in cell_forwards.items():
                cell_info = cell_infos[cell_name]
                if isinstance(cell_infos[cell_name], _BlackBoxCellInfo):
                    python_class = cell_infos[cell_name].python_class
                    if hasattr(python_class, tendril_type):
                        # get the tendrils from the class if it has them
                        _deep_copy_tendrils_to_tendrils(getattr(python_class, tendril_type), forwards, tendrils)
                    else:
                        # in case the cell has no 'inputs'/'outputs' attribute (e.g. if it is a BlackBox
                        # or a pure Python cell)
                        cell_params = _get_param_tendrils(cell_info, forwards.get(cell_name, {}))
                        cell_tendrils = ecto.Tendrils()
                        if tendril_type == 'inputs':
                            python_class.declare_io(cell_params, cell_tendrils, ecto.Tendrils())
                        else:
                            python_class.declare_io(cell_params, ecto.Tendrils(), cell_tendrils)

                        _deep_copy_tendrils_to_tendrils(cell_tendrils, forwards, tendrils)
                else:
                    _deep_copy_tendrils_to_tendrils(getattr(cell_info, tendril_type), forwards, tendrils)
Beispiel #6
0
 def solidify_forward_declares(self):
     tendrils = ecto.Tendrils()
     for cell_name, keys in self.forwards.iteritems():
         cell = self.__get_cell(cell_name)
         ctendrils = getattr(cell, self.tt_key)
         for key, cell_key in keys:
             tendrils.declare(key, ctendrils.at(cell_key))
             tendrils.at(key).copy_value(
                 self._tendrils.at(key))  #set the cells to parameters.
     for key, tendril in self._tendrils:
         if not key in tendrils:
             tendrils.declare(key, tendril)
     self._tendrils = tendrils
def test_tendrils():
    t = ecto.Tendrils()
    t.declare("Hello","doc str",6)
    assert t.Hello == 6
    assert t["Hello"] == 6
    t.declare("x","a number", "str")
    assert len(t) == 2
    assert t["x"] == "str"
    assert t.x == "str"
    #test the redeclare
    try:
        t.declare("Hello","new doc", "you")
        util.fail()
    except ecto.TendrilRedeclaration, e:
        print str(e)
        assert('TendrilRedeclaration' in str(e))
Beispiel #8
0
def _get_param_tendrils(cell_info, forwards=None, params=None):
    """
    This function returns the params ecto.Tendrils of a cell but it also overrides
    the default values with the arguments, in order of priority (from low to high):
    - the defaults of cell_info
    - the forwards
    - any given parameters
    :param cell_info: a BlackBoxCellInfo object
    :param forwards: a list of BlackBoxForward or the string 'all'
    :param params: a dictionary of values to give to the parameters that have no default
    :return: params Tendrils of a class with values overriden from cell_info or forwards
    """
    if forwards is None:
        forwards = []
    if params is None:
        params = {}

    cell_class = cell_info.python_class
    if hasattr(cell_class, 'params'):
        # this is a C++ cell visible from Python
        tendrils = _deep_copy_tendrils(cell_class.params)
    else:
        # otherwise, call the declare_params function
        tendrils = ecto.Tendrils()
        if issubclass(cell_class, BlackBox):
            cell_class.declare_params(tendrils, **params)
        else:
            cell_class.declare_params(tendrils)

    # override the values with whatever is in params
    for key, val in params.items():
        if key in tendrils:
            tendrils.at(key).set(val)

    # override the values with whatever is in forwards
    if isinstance(forwards, list):
        for forward in forwards:
            if forward.key in tendrils and forward.new_default is not None:
                tendrils.at(forward.key).set(forward.new_default)

    # override the values with whatever is in cell_info
    for key, val in cell_info.params.items():
        if key in tendrils:
            tendrils.at(key).set(val)

    return tendrils
Beispiel #9
0
def _deep_copy_tendrils(tendrils_in, values=None):
    """
    Given some tendrils and their values, deep copy them
    :param tendrils_in: an ecto.Tendrils()
    :param values: a dictionary {'tendril_key': tendril_value}
                  if 'tendril_key' is not in 'tendrils_in', it will be ignored
    :return: a deep copy of 'tendrils_in' with the values from 'values'
    """
    if values is None:
        values = {}
    tendrils_out = ecto.Tendrils()
    for key, tendril in tendrils_in:
        new_tendril = ecto.Tendril.createT(tendril.type_name)
        if key in values:
            new_tendril.set(values[key])
        else:
            new_tendril.copy_value(tendril)
        new_tendril.doc = tendril.doc
        tendrils_out.declare(key, new_tendril)

    return tendrils_out
Beispiel #10
0
    def __configure(self, **kwargs):
        """
        Private implementation that generates the cells/tendrils inside the BlackBox
        """
        p = ecto.Tendrils()
        self.declare_direct_params(p)

        # complete the p using the default values given in **kwargs
        for key, val in kwargs.items():
            if key in p:
                p.at(key).set(val)

        try:
            p_forwards, i_forwards, o_forwards = self.declare_forwards(p)
        except Exception as e:
            raise BlackBoxError('Your declare_forwards needs to return a tuple of 3 dictionaries '
                                'of the form:\n'
                                '{"cell_name": "all", "cell_name": [BlackBoxForward1, BlackBoxForward2]}: %s' % e)

        # create the cells
        cell_infos = self.declare_cells(p)
        for cell_name, cell_info in cell_infos.items():
            # if a full-fledged cell is given, just assign it to the blackbox member right away
            if not isinstance(cell_info, _BlackBoxCellInfo):
                setattr(self, cell_name, cell_info)
                continue

            cell_tendrils = _get_param_tendrils(cell_info, p_forwards.get(cell_name, []), kwargs)

            # convert the tendrils to parameters to send to the constructor
            params = {}
            for key, tendril in cell_tendrils.items():
                params[key] = tendril.val

            # add the cell to the BlackBox
            if cell_info.name:
                setattr(self, cell_name, cell_info.python_class(cell_info.name, **params))
            else:
                setattr(self, cell_name, cell_info.python_class(**params))

        # redefine the parameters so that they are linked to tendrils of actual cells
        self.__params = ecto.Tendrils()
        self.declare_direct_params(self.__params)

        for cell_name, forwards in p_forwards.items():
            cell = getattr(self, cell_name)
            _copy_tendrils_to_tendrils(cell.params, forwards, self.__params)

        # complete the params using the default values given in **kwargs
        for key, val in kwargs.items():
            if key in self.__params:
                self.__params.at(key).set(val)

        # redefine the io so that they are linked to tendrils of actual cells
        self.__inputs = ecto.Tendrils()
        self.__outputs = ecto.Tendrils()
        for tendril_type, all_forwards in [('inputs', i_forwards), ('outputs', o_forwards)]:
            for cell_name, forwards in all_forwards.items():
                if not hasattr(self, cell_name):
                    raise BlackBoxError('Cell of name "%s" needs to be ' % cell_name +
                                        'declared in "declare_cells"')
                cell = getattr(self, cell_name)
                if not hasattr(cell, tendril_type):
                    raise BlackBoxError('Cell of name "%s" needs has no %s ' %
                                        (cell_name, tendril_type))
                if tendril_type=='inputs':
                    _copy_tendrils_to_tendrils(cell.inputs, forwards, self.__inputs)
                else:
                    _copy_tendrils_to_tendrils(cell.outputs, forwards, self.__outputs)

        # call the configure from the user
        self.configure(self.__params, self.__inputs, self.__outputs)
Beispiel #11
0
 def __init__(self, bb, tendril_type):
     self._tendrils = ecto.Tendrils()
     self.tt = tendril_type
     self.tt_key = BlackBoxTendrils.tt_key[self.tt]
     self.bb = bb
     self.forwards = {}
Beispiel #12
0
#!/usr/bin/env python
from object_recognition.common.io.source import _assert_source_interface

#test that names have to be correct.
try:
    from ecto import And
    a = And()
    _assert_source_interface(a)
    assert False == "Should not have gotten here."
except NotImplementedError,e:
    assert "Must have an output named K" in str(e)


import ecto
outputs = ecto.Tendrils()
outputs.declare("image","an image", "image image")
outputs.declare("depth","a depth map", "depth depth")
outputs.declare("K","a camera matrix", "eye(3)")
outputs.declare("points3d","A matrix of 3 vectors", "Mat(N,3)")

class Source(object):
    pass
kr = Source()
kr.outputs = outputs
try:
    _assert_source_interface(kr)
    assert False == "Should not have gotten here."
except NotImplementedError,e:
    assert "This cells output at K has type boost::python::api::object" in str(e)

Beispiel #13
0
def make_tendrils():
    ts = ecto.Tendrils()
    ts.declare('foo', ecto.make_tendril('std::string'))
    ts.declare('bar', ecto.make_tendril('double'))
    return ts
Beispiel #14
0
#!/usr/bin/env python
import ecto

ts = ecto.Tendrils()
ts.declare('foo', ecto.Tendril.createT('std::string'))

ts_pass = ecto.PassthroughTendrils(tendrils=ts)

ts.foo = "hello"
ts_pass.process()
assert ts.foo == "hello"
assert ts_pass.outputs.foo == "hello"
assert ts_pass.inputs.foo == "hello"

ts_pass.inputs.foo = "world"
assert ts.foo == "world"
assert ts_pass.outputs.foo == "world"
assert ts_pass.inputs.foo == "world"