def test_write_cache_spec(self): ''' Round-trip test for writing spec and reading it back in ''' io = HDF5IO(self.path, self.manager) io.write(self.container, cache_spec=True) io.close() f = File(self.path) self.assertIn('specifications', f) ns_catalog = NamespaceCatalog(NWBGroupSpec, NWBDatasetSpec, NWBNamespace) HDF5IO.load_namespaces(ns_catalog, self.path, namespaces=['core']) original_ns = self.manager.namespace_catalog.get_namespace('core') cached_ns = ns_catalog.get_namespace('core') for key in ('author', 'contact', 'doc', 'full_name', 'name'): with self.subTest(namespace_field=key): self.assertEqual(original_ns[key], cached_ns[key]) for dt in original_ns.get_registered_types(): with self.subTest(neurodata_type=dt): original_spec = original_ns.get_spec(dt) cached_spec = cached_ns.get_spec(dt) with self.subTest(test='data_type spec read back in'): self.assertIsNotNone(cached_spec) with self.subTest(test='cached spec preserved original spec'): self.assertDictEqual(original_spec, cached_spec)
class TestObjectMapper(unittest.TestCase): def setUp(self): self.setUpBarSpec() self.spec_catalog = SpecCatalog() self.spec_catalog.register_spec(self.bar_spec, 'test.yaml') self.namespace = SpecNamespace('a test namespace', CORE_NAMESPACE, [{ 'source': 'test.yaml' }], catalog=self.spec_catalog) self.namespace_catalog = NamespaceCatalog() self.namespace_catalog.add_namespace(CORE_NAMESPACE, self.namespace) self.type_map = TypeMap(self.namespace_catalog) self.type_map.register_container_type(CORE_NAMESPACE, 'Bar', Bar) self.type_map.register_map(Bar, ObjectMapper) self.manager = BuildManager(self.type_map) self.mapper = ObjectMapper(self.bar_spec) def setUpBarSpec(self): raise unittest.SkipTest('setUpBarSpec not implemented') def test_default_mapping(self): attr_map = self.mapper.get_attr_names(self.bar_spec) keys = set(attr_map.keys()) for key in keys: with self.subTest(key=key): self.assertIs(attr_map[key], self.mapper.get_attr_spec(key)) self.assertIs(attr_map[key], self.mapper.get_carg_spec(key))
class TestBase(unittest.TestCase): def setUp(self): self.foo_spec = GroupSpec( 'A test group specification with a data type', namespace=CORE_NAMESPACE, data_type_def='Foo', datasets=[ DatasetSpec('an example dataset', 'int', name='my_data', attributes=[ AttributeSpec('attr2', 'an example integer attribute', 'int') ]) ], attributes=[ AttributeSpec('attr1', 'an example string attribute', 'text') ]) self.spec_catalog = SpecCatalog() self.spec_catalog.register_spec(self.foo_spec, 'test.yaml') self.namespace = SpecNamespace('a test namespace', CORE_NAMESPACE, [{ 'source': 'test.yaml' }], catalog=self.spec_catalog) self.namespace_catalog = NamespaceCatalog() self.namespace_catalog.add_namespace(CORE_NAMESPACE, self.namespace) self.type_map = TypeMap(self.namespace_catalog) self.type_map.register_container_type(CORE_NAMESPACE, 'Foo', Foo) self.type_map.register_map(Foo, ObjectMapper) self.manager = BuildManager(self.type_map)
def setUp(self): self.bar_spec = GroupSpec( 'A test group specification with a data type', data_type_def='Bar', datasets=[ DatasetSpec('an example dataset', 'int', name='data', attributes=[ AttributeSpec('attr2', 'an example integer attribute', 'int') ]) ], attributes=[ AttributeSpec('attr1', 'an example string attribute', 'str') ]) self.spec_catalog = SpecCatalog() self.spec_catalog.register_spec(self.bar_spec, 'test.yaml') self.namespace = SpecNamespace('a test namespace', CORE_NAMESPACE, [{ 'source': 'test.yaml' }], catalog=self.spec_catalog) self.namespace_catalog = NamespaceCatalog() self.namespace_catalog.add_namespace(CORE_NAMESPACE, self.namespace) self.type_map = TypeMap(self.namespace_catalog) self.type_map.register_container_type(CORE_NAMESPACE, 'Bar', Bar) self.type_map.register_map(Bar, ObjectMapper) self.manager = BuildManager(self.type_map) self.mapper = ObjectMapper(self.bar_spec)
class TestDataMap(unittest.TestCase): def setUp(self): self.setUpBazSpec() self.spec_catalog = SpecCatalog() self.spec_catalog.register_spec(self.baz_spec, 'test.yaml') self.namespace = SpecNamespace('a test namespace', CORE_NAMESPACE, [{'source': 'test.yaml'}], catalog=self.spec_catalog) self.namespace_catalog = NamespaceCatalog() self.namespace_catalog.add_namespace(CORE_NAMESPACE, self.namespace) self.type_map = TypeMap(self.namespace_catalog) self.type_map.register_container_type(CORE_NAMESPACE, 'Baz', Baz) self.type_map.register_map(Baz, ObjectMapper) self.manager = BuildManager(self.type_map) self.mapper = ObjectMapper(self.baz_spec) def setUpBazSpec(self): self.baz_spec = DatasetSpec('an Baz type', 'int', name='MyBaz', data_type_def='Baz', attributes=[AttributeSpec('baz_attr', 'an example string attribute', 'text')]) def test_build(self): ''' Test default mapping functionality when no attributes are nested ''' container = Baz('my_baz', list(range(10)), 'abcdefghijklmnopqrstuvwxyz') builder = self.mapper.build(container, self.manager) expected = DatasetBuilder('my_baz', list(range(10)), attributes={'baz_attr': 'abcdefghijklmnopqrstuvwxyz'}) self.assertDictEqual(builder, expected)
def setUp(self): self.setUpBazSpec() self.spec_catalog = SpecCatalog() self.spec_catalog.register_spec(self.baz_spec, 'test.yaml') self.namespace = SpecNamespace('a test namespace', CORE_NAMESPACE, [{'source': 'test.yaml'}], catalog=self.spec_catalog) self.namespace_catalog = NamespaceCatalog() self.namespace_catalog.add_namespace(CORE_NAMESPACE, self.namespace) self.type_map = TypeMap(self.namespace_catalog) self.type_map.register_container_type(CORE_NAMESPACE, 'Baz', Baz) self.type_map.register_map(Baz, ObjectMapper) self.manager = BuildManager(self.type_map) self.mapper = ObjectMapper(self.baz_spec)
def setUp(self): self.bar_spec = GroupSpec( 'A test group specification with a data type', data_type_def='Bar') spec_catalog = SpecCatalog() spec_catalog.register_spec(self.bar_spec, 'test.yaml') namespace = SpecNamespace('a test namespace', CORE_NAMESPACE, [{ 'source': 'test.yaml' }], catalog=spec_catalog) namespace_catalog = NamespaceCatalog() namespace_catalog.add_namespace(CORE_NAMESPACE, namespace) self.type_map = TypeMap(namespace_catalog) self.type_map.register_container_type(CORE_NAMESPACE, 'Bar', Bar)
class TestTypeMap(unittest.TestCase): def setUp(self): self.bar_spec = GroupSpec( 'A test group specification with a data type', data_type_def='Bar') self.foo_spec = GroupSpec( 'A test group specification with data type Foo', data_type_def='Foo') self.spec_catalog = SpecCatalog() self.spec_catalog.register_spec(self.bar_spec, 'test.yaml') self.spec_catalog.register_spec(self.foo_spec, 'test.yaml') self.namespace = SpecNamespace('a test namespace', CORE_NAMESPACE, [{ 'source': 'test.yaml' }], catalog=self.spec_catalog) self.namespace_catalog = NamespaceCatalog() self.namespace_catalog.add_namespace(CORE_NAMESPACE, self.namespace) self.type_map = TypeMap(self.namespace_catalog) self.type_map.register_container_type(CORE_NAMESPACE, 'Bar', Bar) self.type_map.register_container_type(CORE_NAMESPACE, 'Foo', Foo) # self.build_manager = BuildManager(self.type_map) def test_get_map_unique_mappers(self): self.type_map.register_map(Bar, ObjectMapper) self.type_map.register_map(Foo, ObjectMapper) bar_inst = Bar('my_bar', list(range(10)), 'value1', 10) foo_inst = Foo() bar_mapper = self.type_map.get_map(bar_inst) foo_mapper = self.type_map.get_map(foo_inst) self.assertIsNot(bar_mapper, foo_mapper) def test_get_map(self): self.type_map.register_map(Bar, ObjectMapper) container_inst = Bar('my_bar', list(range(10)), 'value1', 10) mapper = self.type_map.get_map(container_inst) self.assertIsInstance(mapper, ObjectMapper) self.assertIs(mapper.spec, self.bar_spec) mapper2 = self.type_map.get_map(container_inst) self.assertIs(mapper, mapper2) def test_get_map_register(self): class MyMap(ObjectMapper): pass self.type_map.register_map(Bar, MyMap) container_inst = Bar('my_bar', list(range(10)), 'value1', 10) mapper = self.type_map.get_map(container_inst) self.assertIs(mapper.spec, self.bar_spec) self.assertIsInstance(mapper, MyMap)
class TestDynamicContainer(unittest.TestCase): def setUp(self): self.bar_spec = GroupSpec( 'A test group specification with a data type', data_type_def='Bar', datasets=[ DatasetSpec('an example dataset', 'int', name='data', attributes=[ AttributeSpec('attr2', 'an example integer attribute', 'int') ]) ], attributes=[ AttributeSpec('attr1', 'an example string attribute', 'str') ]) self.spec_catalog = SpecCatalog() self.spec_catalog.register_spec(self.bar_spec, 'test.yaml') self.namespace = SpecNamespace('a test namespace', CORE_NAMESPACE, [{ 'source': 'test.yaml' }], catalog=self.spec_catalog) self.namespace_catalog = NamespaceCatalog() self.namespace_catalog.add_namespace(CORE_NAMESPACE, self.namespace) self.type_map = TypeMap(self.namespace_catalog) self.type_map.register_container_type(CORE_NAMESPACE, 'Bar', Bar) self.type_map.register_map(Bar, ObjectMapper) self.manager = BuildManager(self.type_map) self.mapper = ObjectMapper(self.bar_spec) def test_dynamic_container_creation(self): baz_spec = GroupSpec( 'A test extension with no Container class', data_type_def='Baz', data_type_inc=self.bar_spec, attributes=[ AttributeSpec('attr3', 'an example float attribute', 'float'), AttributeSpec('attr4', 'another example float attribute', 'float') ]) self.spec_catalog.register_spec(baz_spec, 'extension.yaml') cls = self.type_map.get_container_cls(CORE_NAMESPACE, 'Baz') expected_args = {'name', 'data', 'attr1', 'attr2', 'attr3', 'attr4'} received_args = set() for x in get_docval(cls.__init__): received_args.add(x['name']) with self.subTest(name=x['name']): self.assertNotIn('default', x) self.assertSetEqual(expected_args, received_args) self.assertEqual(cls.__name__, 'Baz') self.assertTrue(issubclass(cls, Bar)) def test_dynamic_container_creation_defaults(self): baz_spec = GroupSpec( 'A test extension with no Container class', data_type_def='Baz', data_type_inc=self.bar_spec, attributes=[ AttributeSpec('attr3', 'an example float attribute', 'float'), AttributeSpec('attr4', 'another example float attribute', 'float') ]) self.spec_catalog.register_spec(baz_spec, 'extension.yaml') cls = self.type_map.get_container_cls(CORE_NAMESPACE, 'Baz') expected_args = {'name', 'data', 'attr1', 'attr2', 'attr3', 'attr4'} received_args = set(map(lambda x: x['name'], get_docval(cls.__init__))) self.assertSetEqual(expected_args, received_args) self.assertEqual(cls.__name__, 'Baz') self.assertTrue(issubclass(cls, Bar)) def test_dynamic_container_constructor(self): baz_spec = GroupSpec( 'A test extension with no Container class', data_type_def='Baz', data_type_inc=self.bar_spec, attributes=[ AttributeSpec('attr3', 'an example float attribute', 'float'), AttributeSpec('attr4', 'another example float attribute', 'float') ]) self.spec_catalog.register_spec(baz_spec, 'extension.yaml') cls = self.type_map.get_container_cls(CORE_NAMESPACE, 'Baz') # TODO: test that constructor works! inst = cls('My Baz', [1, 2, 3, 4], 'string attribute', 1000, attr3=98.6, attr4=1.0) self.assertEqual(inst.name, 'My Baz') self.assertEqual(inst.data, [1, 2, 3, 4]) self.assertEqual(inst.attr1, 'string attribute') self.assertEqual(inst.attr2, 1000) self.assertEqual(inst.attr3, 98.6) self.assertEqual(inst.attr4, 1.0)
def setUp(self): self.manager = BuildManager(TypeMap(NamespaceCatalog())) self.path = "test_pynwb_io_hdf5.h5" self.start_time = datetime(1970, 1, 1, 12, 0, 0) self.create_date = datetime(2017, 4, 15, 12, 0, 0) self.ts_builder = GroupBuilder( 'test_timeseries', attributes={ 'ancestry': 'TimeSeries', 'source': 'example_source', 'neurodata_type': 'TimeSeries', 'help': 'General purpose TimeSeries' }, datasets={ 'data': DatasetBuilder('data', list(range(100, 200, 10)), attributes={ 'unit': 'SIunit', 'conversion': 1.0, 'resolution': 0.1 }), 'timestamps': DatasetBuilder('timestamps', list(range(10)), attributes={ 'unit': 'Seconds', 'interval': 1 }) }) self.ts = TimeSeries('test_timeseries', 'example_source', list(range(100, 200, 10)), unit='SIunit', resolution=0.1, timestamps=list(range(10))) self.manager.prebuilt(self.ts, self.ts_builder) self.builder = GroupBuilder( 'root', groups={ 'acquisition': GroupBuilder('acquisition', groups={ 'timeseries': GroupBuilder('timeseries', groups={ 'test_timeseries': self.ts_builder }), 'images': GroupBuilder('images') }), 'analysis': GroupBuilder('analysis'), 'epochs': GroupBuilder('epochs'), 'general': GroupBuilder('general'), 'processing': GroupBuilder('processing'), 'stimulus': GroupBuilder('stimulus', groups={ 'presentation': GroupBuilder('presentation'), 'templates': GroupBuilder('templates') }) }, datasets={ 'file_create_date': DatasetBuilder('file_create_date', [str(self.create_date)]), 'identifier': DatasetBuilder('identifier', 'TEST123'), 'session_description': DatasetBuilder('session_description', 'a test NWB File'), 'nwb_version': DatasetBuilder('nwb_version', '1.0.6'), 'session_start_time': DatasetBuilder('session_start_time', str(self.start_time)) }, attributes={'neurodata_type': 'NWBFile'})
class TestSpecLoad(unittest.TestCase): NS_NAME = 'test_ns' def setUp(self): self.attributes = [ AttributeSpec('attribute1', 'my first attribute', 'text'), AttributeSpec('attribute2', 'my second attribute', 'text') ] self.dset1_attributes = [ AttributeSpec('attribute3', 'my third attribute', 'text'), AttributeSpec('attribute4', 'my fourth attribute', 'text') ] self.dset2_attributes = [ AttributeSpec('attribute5', 'my fifth attribute', 'text'), AttributeSpec('attribute6', 'my sixth attribute', 'text') ] self.datasets = [ DatasetSpec( 'my first dataset', # noqa: F405 'int', name='dataset1', attributes=self.dset1_attributes, linkable=True), DatasetSpec( 'my second dataset', # noqa: F405 'int', name='dataset2', dimension=(None, None), attributes=self.dset2_attributes, linkable=True, data_type_def='VoltageArray') ] self.spec = GroupSpec( 'A test group', # noqa: F405 name='root_constructor_nwbtype', datasets=self.datasets, attributes=self.attributes, linkable=False, data_type_def='EphysData') dset1_attributes_ext = [ AttributeSpec('dset1_extra_attribute', 'an extra attribute for the first dataset', 'text') ] self.ext_datasets = [ DatasetSpec( 'my first dataset extension', # noqa: F405 'int', name='dataset1', attributes=dset1_attributes_ext, linkable=True), ] self.ext_attributes = [ AttributeSpec('ext_extra_attribute', 'an extra attribute for the group', 'text'), ] self.ext_spec = GroupSpec( 'A test group extension', # noqa: F405 name='root_constructor_nwbtype', datasets=self.ext_datasets, attributes=self.ext_attributes, linkable=False, data_type_inc='EphysData', data_type_def='SpikeData') to_dump = {'groups': [self.spec, self.ext_spec]} self.specs_path = 'test_load_namespace.specs.yaml' self.namespace_path = 'test_load_namespace.namespace.yaml' with open(self.specs_path, 'w') as tmp: yaml.safe_dump(json.loads(json.dumps(to_dump)), tmp, default_flow_style=False) ns_dict = { 'doc': 'a test namespace', 'name': self.NS_NAME, 'schema': [{ 'source': self.specs_path }] } self.namespace = SpecNamespace.build_namespace(**ns_dict) # noqa: F405 to_dump = {'namespaces': [self.namespace]} with open(self.namespace_path, 'w') as tmp: yaml.safe_dump(json.loads(json.dumps(to_dump)), tmp, default_flow_style=False) self.ns_catalog = NamespaceCatalog() # noqa: F405 def tearDown(self): if os.path.exists(self.namespace_path): os.remove(self.namespace_path) if os.path.exists(self.specs_path): os.remove(self.specs_path) def test_inherited_attributes(self): self.ns_catalog.load_namespaces(self.namespace_path, resolve=True) ts_spec = self.ns_catalog.get_spec(self.NS_NAME, 'EphysData') es_spec = self.ns_catalog.get_spec(self.NS_NAME, 'SpikeData') ts_attrs = {s.name for s in ts_spec.attributes} es_attrs = {s.name for s in es_spec.attributes} for attr in ts_attrs: with self.subTest(attr=attr): self.assertIn(attr, es_attrs) # self.assertSetEqual(ts_attrs, es_attrs) ts_dsets = {s.name for s in ts_spec.datasets} es_dsets = {s.name for s in es_spec.datasets} for dset in ts_dsets: with self.subTest(dset=dset): self.assertIn(dset, es_dsets) # self.assertSetEqual(ts_dsets, es_dsets) def test_inherited_attributes_not_resolved(self): self.ns_catalog.load_namespaces(self.namespace_path, resolve=False) es_spec = self.ns_catalog.get_spec(self.NS_NAME, 'SpikeData') src_attrs = {s.name for s in self.ext_attributes} ext_attrs = {s.name for s in es_spec.attributes} self.assertSetEqual(src_attrs, ext_attrs) src_dsets = {s.name for s in self.ext_datasets} ext_dsets = {s.name for s in es_spec.datasets} self.assertSetEqual(src_dsets, ext_dsets)
def setUp(self): self.attributes = [ AttributeSpec('attribute1', 'my first attribute', 'text'), AttributeSpec('attribute2', 'my second attribute', 'text') ] self.dset1_attributes = [ AttributeSpec('attribute3', 'my third attribute', 'text'), AttributeSpec('attribute4', 'my fourth attribute', 'text') ] self.dset2_attributes = [ AttributeSpec('attribute5', 'my fifth attribute', 'text'), AttributeSpec('attribute6', 'my sixth attribute', 'text') ] self.datasets = [ DatasetSpec( 'my first dataset', # noqa: F405 'int', name='dataset1', attributes=self.dset1_attributes, linkable=True), DatasetSpec( 'my second dataset', # noqa: F405 'int', name='dataset2', dimension=(None, None), attributes=self.dset2_attributes, linkable=True, data_type_def='VoltageArray') ] self.spec = GroupSpec( 'A test group', # noqa: F405 name='root_constructor_nwbtype', datasets=self.datasets, attributes=self.attributes, linkable=False, data_type_def='EphysData') dset1_attributes_ext = [ AttributeSpec('dset1_extra_attribute', 'an extra attribute for the first dataset', 'text') ] self.ext_datasets = [ DatasetSpec( 'my first dataset extension', # noqa: F405 'int', name='dataset1', attributes=dset1_attributes_ext, linkable=True), ] self.ext_attributes = [ AttributeSpec('ext_extra_attribute', 'an extra attribute for the group', 'text'), ] self.ext_spec = GroupSpec( 'A test group extension', # noqa: F405 name='root_constructor_nwbtype', datasets=self.ext_datasets, attributes=self.ext_attributes, linkable=False, data_type_inc='EphysData', data_type_def='SpikeData') to_dump = {'groups': [self.spec, self.ext_spec]} self.specs_path = 'test_load_namespace.specs.yaml' self.namespace_path = 'test_load_namespace.namespace.yaml' with open(self.specs_path, 'w') as tmp: yaml.safe_dump(json.loads(json.dumps(to_dump)), tmp, default_flow_style=False) ns_dict = { 'doc': 'a test namespace', 'name': self.NS_NAME, 'schema': [{ 'source': self.specs_path }] } self.namespace = SpecNamespace.build_namespace(**ns_dict) # noqa: F405 to_dump = {'namespaces': [self.namespace]} with open(self.namespace_path, 'w') as tmp: yaml.safe_dump(json.loads(json.dumps(to_dump)), tmp, default_flow_style=False) self.ns_catalog = NamespaceCatalog() # noqa: F405