def create_many_to_one_relationship(self, force=False, recursive=True): """ For each child of the current object that can only have a single parent, set its parent to be the current object. Usage: >>> a_block.create_many_to_one_relationship() >>> a_block.create_many_to_one_relationship(force=True) If the current object is a :class:`Block`, you want to run populate_RecordingChannel first, because this will create new objects that this method will link up. If force is True overwrite any existing relationships If recursive is True desecend into child objects and create relationships there """ parent_name = _reference_name(self.__class__.__name__) for child in self._single_children: if (hasattr(child, parent_name) and getattr(child, parent_name) is None or force): setattr(child, parent_name, self) if recursive: for child in self.container_children: child.create_many_to_one_relationship(force=force, recursive=True)
def assert_neo_object_is_compliant(ob): ''' Test neo compliance of one object and sub objects (one_to_many_relation only): * check types and/or presence of necessary and recommended attribute. * If attribute is Quantities or numpy.ndarray it also check ndim. * If attribute is numpy.ndarray also check dtype.kind. ''' assert type(ob) in objectlist, \ '%s is not a neo object' % (type(ob)) classname = ob.__class__.__name__ # test presence of necessary attributes for ioattr in ob._necessary_attrs: attrname, attrtype = ioattr[0], ioattr[1] # ~ if attrname != '': if not hasattr(ob, '_quantity_attr'): assert hasattr(ob, attrname), '%s neo obect does not have %s' % \ (classname, attrname) # test attributes types for ioattr in ob._all_attrs: attrname, attrtype = ioattr[0], ioattr[1] if (hasattr(ob, '_quantity_attr') and ob._quantity_attr == attrname and (attrtype == pq.Quantity or attrtype == np.ndarray)): # object inherits from Quantity (AnalogSignal, SpikeTrain, ...) ndim = ioattr[2] assert ob.ndim == ndim, \ '%s dimension is %d should be %d' % (classname, ob.ndim, ndim) if attrtype == np.ndarray: dtp = ioattr[3] assert ob.dtype.kind == dtp.kind, \ '%s dtype.kind is %s should be %s' % (classname, ob.dtype.kind, dtp.kind) elif hasattr(ob, attrname): if getattr(ob, attrname) is not None: obattr = getattr(ob, attrname) assert issubclass(type(obattr), attrtype), \ '%s in %s is %s should be %s' % \ (attrname, classname, type(obattr), attrtype) if attrtype == pq.Quantity or attrtype == np.ndarray: ndim = ioattr[2] assert obattr.ndim == ndim, \ '%s.%s dimension is %d should be %d' % \ (classname, attrname, obattr.ndim, ndim) if attrtype == np.ndarray: dtp = ioattr[3] assert obattr.dtype.kind == dtp.kind, \ '%s.%s dtype.kind is %s should be %s' % \ (classname, attrname, obattr.dtype.kind, dtp.kind) # test bijectivity : parents and children for container in getattr(ob, '_single_child_containers', []): for i, child in enumerate(getattr(ob, container, [])): assert hasattr(child, _reference_name(classname)), \ '%s should have %s attribute (2 way relationship)' % \ (container, _reference_name(classname)) if hasattr(child, _reference_name(classname)): parent = getattr(child, _reference_name(classname)) assert parent == ob, \ '%s.%s %s is not symetric with %s.%s' % \ (container, _reference_name(classname), i, classname, container) # recursive on one to many rel for i, child in enumerate(getattr(ob, 'children', [])): try: assert_neo_object_is_compliant(child) # intercept exceptions and add more information except BaseException as exc: exc.args += ('from %s %s of %s' % (child.__class__.__name__, i, classname),) raise
def assert_neo_object_is_compliant(ob): ''' Test neo compliance of one object and sub objects (one_to_many_relation only): * check types and/or presence of necessary and recommended attribute. * If attribute is Quantities or numpy.ndarray it also check ndim. * If attribute is numpy.ndarray also check dtype.kind. ''' assert type(ob) in objectlist, \ '%s is not a neo object' % (type(ob)) classname = ob.__class__.__name__ # test presence of necessary attributes for ioattr in ob._necessary_attrs: attrname, attrtype = ioattr[0], ioattr[1] #~ if attrname != '': if not hasattr(ob, '_quantity_attr'): assert hasattr(ob, attrname), '%s neo obect does not have %s' % \ (classname, attrname) # test attributes types for ioattr in ob._all_attrs: attrname, attrtype = ioattr[0], ioattr[1] if (hasattr(ob, '_quantity_attr') and ob._quantity_attr == attrname and (attrtype == pq.Quantity or attrtype == np.ndarray)): # object inherits from Quantity (AnalogSignal, SpikeTrain, ...) ndim = ioattr[2] assert ob.ndim == ndim, \ '%s dimension is %d should be %d' % (classname, ob.ndim, ndim) if attrtype == np.ndarray: dtp = ioattr[3] assert ob.dtype.kind == dtp.kind, \ '%s dtype.kind is %s should be %s' % (classname, ob.dtype.kind, dtp.kind) elif hasattr(ob, attrname): if getattr(ob, attrname) is not None: obattr = getattr(ob, attrname) assert issubclass(type(obattr), attrtype), \ '%s in %s is %s should be %s' % \ (attrname, classname, type(obattr), attrtype) if attrtype == pq.Quantity or attrtype == np.ndarray: ndim = ioattr[2] assert obattr.ndim == ndim, \ '%s.%s dimension is %d should be %d' % \ (classname, attrname, obattr.ndim, ndim) if attrtype == np.ndarray: dtp = ioattr[3] assert obattr.dtype.kind == dtp.kind, \ '%s.%s dtype.kind is %s should be %s' % \ (classname, attrname, obattr.dtype.kind, dtp.kind) # test bijectivity : parents and children for container in getattr(ob, '_single_child_containers', []): for i, child in enumerate(getattr(ob, container, [])): assert hasattr(child, _reference_name(classname)), \ '%s should have %s attribute (2 way relationship)' % \ (container, _reference_name(classname)) if hasattr(child, _reference_name(classname)): parent = getattr(child, _reference_name(classname)) assert parent == ob, \ '%s.%s %s is not symetric with %s.%s' % \ (container, _reference_name(classname), i, classname, container) # recursive on one to many rel for i, child in enumerate(getattr(ob, 'children', [])): try: assert_neo_object_is_compliant(child) # intercept exceptions and add more information except BaseException as exc: exc.args += ('from %s %s of %s' % (child.__class__.__name__, i, classname),) raise