def test_extension_overwrite(self): link0 = LinkSpec(doc='Link 0', target_type='TargetType0', name='MyType0') link1 = LinkSpec(doc='Link 1', target_type='TargetType1', name='MyType1') # NOTE overwriting unnamed LinkSpec is not allowed # NOTE overwriting spec with quantity that could be >1 is not allowed links = [link0, link1] parent_spec = GroupSpec(doc='A test group', name='parent', links=links, data_type_def='ParentType') link0_overwrite = LinkSpec(doc='New link 0', target_type='TargetType0', name='MyType0') link1_overwrite = LinkSpec(doc='New link 1', target_type='TargetType1Child', name='MyType1') overwritten_links = [link0_overwrite, link1_overwrite] child_spec = GroupSpec(doc='A test group', name='child', links=overwritten_links, data_type_inc=parent_spec, data_type_def='ChildType') for link in overwritten_links: with self.subTest(link_target_type=link.target_type): self.assertTrue(child_spec.is_inherited_spec(link)) self.assertTrue(child_spec.is_overridden_spec(link))
def create_specs(self, quantity): # Type SimpleBucket contains: # - [quantity] groups of data_type_inc SimpleFoo and [quantity] group of data_type_inc NotSimpleFoo # - [quantity] datasets of data_type_inc SimpleQux and [quantity] datasets of data_type_inc NotSimpleQux # - [quantity] links of target_type SimpleFoo and [quantity] links of target_type NotSimpleFoo foo_spec = GroupSpec( doc='A test group specification with a data type', data_type_def='SimpleFoo', ) not_foo_spec = GroupSpec( doc='A test group specification with a data type', data_type_def='NotSimpleFoo', ) qux_spec = DatasetSpec( doc='A test group specification with a data type', data_type_def='SimpleQux', ) not_qux_spec = DatasetSpec( doc='A test group specification with a data type', data_type_def='NotSimpleQux', ) foo_inc_spec = GroupSpec( doc='the SimpleFoos in this bucket', data_type_inc='SimpleFoo', quantity=quantity ) not_foo_inc_spec = GroupSpec( doc='the SimpleFoos in this bucket', data_type_inc='NotSimpleFoo', quantity=quantity ) qux_inc_spec = DatasetSpec( doc='the SimpleQuxs in this bucket', data_type_inc='SimpleQux', quantity=quantity ) not_qux_inc_spec = DatasetSpec( doc='the SimpleQuxs in this bucket', data_type_inc='NotSimpleQux', quantity=quantity ) foo_link_spec = LinkSpec( doc='the links in this bucket', target_type='SimpleFoo', quantity=quantity ) not_foo_link_spec = LinkSpec( doc='the links in this bucket', target_type='NotSimpleFoo', quantity=quantity ) bucket_spec = GroupSpec( doc='A test group specification for a data type containing data type', name="test_bucket", data_type_def='SimpleBucket', groups=[foo_inc_spec, not_foo_inc_spec], datasets=[qux_inc_spec, not_qux_inc_spec], links=[foo_link_spec, not_foo_link_spec] ) return [foo_spec, not_foo_spec, qux_spec, not_qux_spec, bucket_spec]
def test_constructor(self): link0 = LinkSpec(doc='Link 0', target_type='TargetType0') link1 = LinkSpec(doc='Link 1', target_type='TargetType1') links = [link0, link1] spec = GroupSpec(doc='A test group', name='root', links=links) self.assertIs(spec, links[0].parent) self.assertIs(spec, links[1].parent) json.dumps(spec)
def test_unnamed_named_link_same_type(self): """Test get_target_type when a group contains both an unnamed and named link with type X.""" child0 = LinkSpec(doc='Group 0', target_type='Type0') child1 = LinkSpec(doc='Group 1', target_type='Type0', name='type1') parent_spec = GroupSpec(doc='A test group', name='parent', links=[child0, child1], data_type_def='ParentType') self.assertIs(parent_spec.get_target_type('Type0'), child0)
def test_two_unnamed_links_same_type(self): """Test creating a group contains multiple unnamed links with type X.""" child0 = LinkSpec(doc='Group 0', target_type='Type0') child1 = LinkSpec(doc='Group 1', target_type='Type0') msg = "Cannot have multiple links with the same target type without specifying name" with self.assertRaisesWith(ValueError, msg): GroupSpec(doc='A test group', name='parent', links=[child0, child1], data_type_def='ParentType')
def test_two_named_links_same_type(self): """Test get_target_type when a group contains multiple named links with type X.""" child0 = LinkSpec(doc='Group 0', target_type='Type0', name='group0') child1 = LinkSpec(doc='Group 1', target_type='Type0', name='group1') parent_spec = GroupSpec(doc='A test group', name='parent', links=[child0, child1], data_type_def='ParentType') self.assertEqual(parent_spec.get_target_type('Type0'), [child0, child1])
def test_required_is_many(self): quantity_opts = ['?', 1, '*', '+'] is_required = [False, True, False, True] is_many = [False, False, True, True] for (quantity, req, many) in zip(quantity_opts, is_required, is_many): with self.subTest(quantity=quantity): spec = LinkSpec( doc='A test link', target_type='Group1', quantity=quantity, name='Link1', ) self.assertEqual(spec.required, req) self.assertEqual(spec.is_many(), many)
def test_constructor_defaults(self): spec = LinkSpec( doc='A test link', target_type='Group1', ) self.assertEqual(spec.quantity, 1) self.assertIsNone(spec.name) json.dumps(spec)
def test_set_link(self): group = GroupSpec(doc='A test group', name='root') link = LinkSpec(doc='A test link', target_type='LinkTarget', name='link_name') group.set_link(link) self.assertIs(group, link.parent) self.assertIs(group.get_link('link_name'), link)
def create_specs(self, quantity): # Type SimpleBucket contains: # - an untyped group "foo_holder" which contains [quantity] groups of data_type_inc SimpleFoo # - an untyped group "qux_holder" which contains [quantity] datasets of data_type_inc SimpleQux # - an untyped group "link_holder" which contains [quantity] links of target_type SimpleFoo foo_spec = GroupSpec( doc='A test group specification with a data type', data_type_def='SimpleFoo', ) not_foo_spec = GroupSpec( doc='A test group specification with a data type', data_type_def='NotSimpleFoo', ) qux_spec = DatasetSpec( doc='A test group specification with a data type', data_type_def='SimpleQux', ) not_qux_spec = DatasetSpec( doc='A test group specification with a data type', data_type_def='NotSimpleQux', ) foo_inc_spec = GroupSpec( doc='the SimpleFoos in this bucket', data_type_inc='SimpleFoo', quantity=quantity ) foo_holder_spec = GroupSpec( doc='An untyped subgroup for SimpleFoos', name='foo_holder', groups=[foo_inc_spec] ) qux_inc_spec = DatasetSpec( doc='the SimpleQuxs in this bucket', data_type_inc='SimpleQux', quantity=quantity ) qux_holder_spec = GroupSpec( doc='An untyped subgroup for SimpleQuxs', name='qux_holder', datasets=[qux_inc_spec] ) foo_link_spec = LinkSpec( doc='the links in this bucket', target_type='SimpleFoo', quantity=quantity ) link_holder_spec = GroupSpec( doc='An untyped subgroup for links', name='link_holder', links=[foo_link_spec] ) bucket_spec = GroupSpec( doc='A test group specification for a data type containing data type', name="test_bucket", data_type_def='SimpleBucket', groups=[foo_holder_spec, qux_holder_spec, link_holder_spec] ) return [foo_spec, not_foo_spec, qux_spec, not_qux_spec, bucket_spec]
def test_unnamed_dataset_link_same_type(self): child = DatasetSpec(doc='Dataset 0', data_type_inc='Type0') link = LinkSpec(doc='Link 0', target_type='Type0') parent_spec = GroupSpec(doc='A test group', name='parent', datasets=[child], links=[link], data_type_def='ParentType') self.assertIs(parent_spec.get_data_type('Type0'), child) self.assertIs(parent_spec.get_target_type('Type0'), link)
def test_constructor_target_spec_inc(self): group_spec_inc = GroupSpec( data_type_inc='Group1', doc='A test group', ) msg = "'target_type' must be a string or a GroupSpec or DatasetSpec with a 'data_type_def' key." with self.assertRaisesWith(ValueError, msg): LinkSpec( doc='A test link', target_type=group_spec_inc, )
def test_constructor_target_spec_def(self): group_spec_def = GroupSpec( data_type_def='Group1', doc='A test group', ) spec = LinkSpec( doc='A test link', target_type=group_spec_def, ) self.assertEqual(spec.target_type, 'Group1') json.dumps(spec)
def test_constructor(self): spec = LinkSpec( doc='A test link', target_type='Group1', quantity='+', name='Link1', ) self.assertEqual(spec.doc, 'A test link') self.assertEqual(spec.target_type, 'Group1') self.assertEqual(spec.data_type_inc, 'Group1') self.assertEqual(spec.quantity, '+') self.assertEqual(spec.name, 'Link1') json.dumps(spec)
def test_extension_no_overwrite(self): link0 = LinkSpec(doc='Link 0', target_type='TargetType0') # test unnamed link1 = LinkSpec(doc='Link 1', target_type='TargetType1', name='MyType1') # test named link2 = LinkSpec(doc='Link 2', target_type='TargetType2', quantity='*') # test named, multiple links = [link0, link1, link2] parent_spec = GroupSpec(doc='A test group', name='parent', links=links, data_type_def='ParentType') child_spec = GroupSpec(doc='A test group', name='child', data_type_inc=parent_spec, data_type_def='ChildType') for link in links: with self.subTest(link_target_type=link.target_type): self.assertTrue(child_spec.is_inherited_spec(link)) self.assertFalse(child_spec.is_overridden_spec(link))
def test_unnamed_link_data_type_inc(self): """Test get_subspec on a builder that maps to an unnamed link.""" link_spec = LinkSpec(doc='This Bar', target_type='Bar') parent_spec = GroupSpec(doc='Something to hold a Bar', name='bar_bucket', links=[link_spec]) bar_builder = GroupBuilder(name='my_bar', attributes={ 'data_type': 'Bar', 'namespace': CORE_NAMESPACE, 'object_id': -1 }) sub_builder = LinkBuilder(builder=bar_builder, name='my_link') GroupBuilder(name='bar_bucket', links={'my_bar': sub_builder}) result = self.type_map.get_subspec(parent_spec, sub_builder) self.assertIs(result, link_spec)
def test_process_field_spec_link(self): """Test that processing a link spec does not set child=True in __fields__.""" classdict = {} not_inherited_fields = { 'attr3': LinkSpec(name='attr3', target_type='EmptyBar', doc='a link') } CustomClassGenerator.process_field_spec( classdict=classdict, docval_args=[], parent_cls=EmptyBar, # <-- arbitrary class attr_name='attr3', not_inherited_fields=not_inherited_fields, type_map=self.type_map, spec=GroupSpec('dummy', 'doc')) expected = {'__fields__': [{'name': 'attr3', 'doc': 'a link'}]} self.assertDictEqual(classdict, expected)
def main(): # these arguments were auto-generated from your cookie-cutter inputs ns_builder = NamespaceBuilder( doc= """Objects for rigorously defining spatial coordinates, object shapes, and transformations""", name="""ndx-spatial-coordinates""", version="""0.1.0""", author=list(map(str.strip, """Ben Dichter""".split(','))), contact=list( map(str.strip, """*****@*****.**""".split(',')))) # TODO: specify the neurodata_types that are used by the extension as well # as in which namespace they are found # this is similar to specifying the Python modules that need to be imported # to use your new data types # as of HDMF 1.6.1, the full ancestry of the neurodata_types that are used by # the extension should be included, i.e., the neurodata_type and its parent # type and its parent type and so on. this will be addressed in a future # release of HDMF. ns_builder.include_type('Container', namespace='hdmf-common') # TODO: define your new data types # see https://pynwb.readthedocs.io/en/latest/extensions.html#extending-nwb # for more information Space = GroupSpec(data_type_def='Space', data_type_inc='Container', doc='space', attributes=[ AttributeSpec(name='R', doc='dimensionality of space', dtype='int') ]) Spaces = GroupSpec(data_type_def='Spaces', data_type_inc='Container', doc='contains spaces', groups=[ GroupSpec(data_type_inc=Space, quantity='*', doc='spaces are stored here') ]) CoordinateSystem = GroupSpec( data_type_def='CoordinateSystem', data_type_inc='Container', doc='coordinate system', links=[ LinkSpec(doc='link to space', target_type='Space', name='space') ], attributes=[ AttributeSpec(name='R', doc='dimensionality of coordinate system', dtype='int') ]) CoordinateSystems = GroupSpec( data_type_def='CoordinateSystems', data_type_inc='Container', doc='coordinate systems', groups=[ GroupSpec(data_type_inc=CoordinateSystem, quantity='*', doc='coordinate systems are stored here') ], ) RegistrationProtocol = GroupSpec(data_type_def='RegistrationProtocol', data_type_inc='Container', doc='registration protocol') RegistrationProtocols = GroupSpec( data_type_def='RegistrationProtocols', data_type_inc='Container', doc='registration protocols', groups=[ GroupSpec(data_type_inc=RegistrationProtocol, quantity='*', doc='registration protocols are stored here') ], ) CoordinateRegistrationProcess = GroupSpec( data_type_def='CoordinateRegistrationProcess', data_type_inc='Container', doc='coordinate registration process', links=[ LinkSpec(doc='registration protocol', target_type='RegistrationProtocol', name='registration_protocol') ]) CoordinateRegistrationProcesses = GroupSpec( data_type_def='CoordinateRegistrationProcesses', data_type_inc='Container', doc='registration process', groups=[ GroupSpec(data_type_inc=CoordinateRegistrationProcess, quantity='*', doc='registration processes are stored here') ], ) Transform = GroupSpec( data_type_def='Transform', data_type_inc='Container', doc='transform', links=[ LinkSpec(doc='domain coordinate system', target_type='CoordinateSystem', name='domain_coordinate_system'), LinkSpec(doc='range coordinate system', target_type='CoordinateSystem', name='range_coordinate_system') ], ) AffineTransform = GroupSpec(data_type_def='AffineTransform', data_type_inc=Transform, doc='affine transform', datasets=[ DatasetSpec(doc='affine transform matrix', dtype='float', shape=(None, None), name='M') ]) DeformableTransform = GroupSpec( data_type_def='DeformableTransform', data_type_inc=Transform, doc='deformable transform', datasets=[DatasetSpec(doc='vector image', dtype='float', name='I')]) Transforms = GroupSpec( data_type_def='Transforms', data_type_inc='Container', doc='transforms', groups=[ GroupSpec(data_type_inc=Transform, quantity='*', doc='transforms are stored here') ], ) PhysicalObjectType = GroupSpec(data_type_def='PhysicalObjectType', data_type_inc='Container', doc='physical object type', groups=[ GroupSpec(name='geometry', doc='geometry', datasets=[ DatasetSpec(name='nodes', doc='nodes', dtype='float', shape=(None, 3)), DatasetSpec(name='edges', doc='edges', dtype='uint', shape=(None, 3)) ]) ], links=[ LinkSpec(name='coordinate_system', doc='coordinate system', target_type='CoordinateSystem') ]) ElectrodeType = GroupSpec(data_type_def='ElectrodeType', data_type_inc=PhysicalObjectType, doc='electrode type', attributes=[ AttributeSpec(name='electrode_type', doc='electrode type', dtype='text') ]) ElectrodeTypes = GroupSpec( data_type_def='ElectrodeTypes', data_type_inc='Container', doc='electrode types', groups=[ GroupSpec(data_type_inc=ElectrodeType, quantity='*', doc='electrode types are stored here') ], ) PhysicalObjectWithSubObjectsType = GroupSpec( data_type_def='PhysicalObjectWithSubObjectsType', data_type_inc=PhysicalObjectType, doc='physical object with sub objects', groups=[ GroupSpec( name='sites', doc='sites', datasets=[ DatasetSpec( name='sites', doc='sites', dtype=[ DtypeSpec( name='position', doc='position', dtype='float', #shape=(3,) ), DtypeSpec( name='normal', doc='normal', dtype='float', #shape=(3,) ), DtypeSpec(name='object_type', doc='object type', dtype=RefSpec( target_type='PhysicalObjectType', reftype='object')), ]) ]) ]) ProbeType = GroupSpec( data_type_def='ProbeType', data_type_inc=PhysicalObjectWithSubObjectsType, doc='probe type', ) ProbeTypes = GroupSpec( data_type_def='ProbeTypes', data_type_inc='Container', doc='probe types', groups=[ GroupSpec(data_type_inc=ProbeType, quantity='*', doc='probe types are stored here') ], ) SubjectBrain = GroupSpec(data_type_def='SubjectBrain', data_type_inc=PhysicalObjectWithSubObjectsType, doc='subject brain') SpaceInfo = GroupSpec( data_type_def='SpaceInfo', data_type_inc='Container', doc='all space info goes in here', groups=[ GroupSpec(data_type_inc=Spaces, doc='spaces'), GroupSpec(data_type_inc=CoordinateSystems, doc='coordinate systems'), GroupSpec(data_type_inc=RegistrationProtocols, doc='registration protocols'), GroupSpec(data_type_inc=CoordinateRegistrationProcesses, doc='registration processes'), GroupSpec(data_type_inc=Transforms, doc='transforms'), GroupSpec(data_type_inc=ElectrodeTypes, doc='electrode types'), GroupSpec(data_type_inc=ProbeTypes, doc='probe types'), GroupSpec(data_type_inc=SubjectBrain, doc='subject brain') ]) new_data_types = [ Space, Spaces, CoordinateSystem, CoordinateSystems, RegistrationProtocol, RegistrationProtocols, CoordinateRegistrationProcess, CoordinateRegistrationProcesses, Transform, AffineTransform, DeformableTransform, Transforms, PhysicalObjectType, ElectrodeType, ElectrodeTypes, PhysicalObjectWithSubObjectsType, ProbeType, ProbeTypes, SubjectBrain, SpaceInfo ] # export the spec to yaml files in the spec folder output_dir = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..', 'spec')) export_spec(ns_builder, new_data_types, output_dir)