Skip to content

Commit

Permalink
Add lab meta data (#751)
Browse files Browse the repository at this point in the history
You can now write zero or more lab extensions and put them in /general/ by making them inherit from LabMetaData and calling nwbfile.add_lab_meta_data

tests were also added
  • Loading branch information
bendichter authored Dec 5, 2018
1 parent 7e2365c commit 779fa25
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 4 deletions.
4 changes: 4 additions & 0 deletions src/pynwb/data/nwb.file.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,10 @@ groups:
date made, injection location, volume, etc.
quantity: '?'
groups:
- neurodata_type_def: LabMetaData
neurodata_type_inc: NWBContainer
doc: 'place-holder than can be extended so that lab-specific meta-data can be placed in /general'
quantity: '*'
- name: devices
doc: 'Description of hardware devices used during experiment. COMMENT: Eg, monitors,
ADC boards, microscopes, etc'
Expand Down
13 changes: 13 additions & 0 deletions src/pynwb/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ class SpecFile(Container):
pass


@register_class('LabMetaData', CORE_NAMESPACE)
class LabMetaData(NWBContainer):
def __init__(self, **kwargs):
super(LabMetaData, self).__init__(kwargs['name'])


@register_class('Subject', CORE_NAMESPACE)
class Subject(NWBContainer):

Expand Down Expand Up @@ -141,6 +147,13 @@ class NWBFile(MultiContainerInterface):
'create': 'create_time_intervals',
'get': 'get_time_intervals'
},
{
'attr': 'lab_meta_data',
'add': 'add_lab_meta_data',
'type': LabMetaData,
'create': 'create_lab_meta_data',
'get': 'get_lab_meta_data'
}
]

__nwbfields__ = ('timestamps_reference_time',
Expand Down
1 change: 1 addition & 0 deletions src/pynwb/io/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def __init__(self, spec):

self.map_spec('subject', general_spec.get_group('subject'))
self.map_spec('devices', general_spec.get_group('devices').get_neurodata_type('Device'))
self.map_spec('lab_meta_data', general_spec.get_neurodata_type('LabMetaData'))

@ObjectMapper.constructor_arg('session_start_time')
def dateconversion(self, builder, manager):
Expand Down
1 change: 1 addition & 0 deletions tests/unit/pynwb_tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ def test_print_file(self):
epoch_tags: """ + empty_set_str + """
ic_electrodes: { }
imaging_planes: { }
lab_meta_data: { }
modules: { }
ogen_sites: { }
stimulus: { }
Expand Down
40 changes: 36 additions & 4 deletions tests/unit/pynwb_tests/test_extension.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import unittest2 as unittest
import os
from tempfile import gettempdir
import random
import string
from datetime import datetime
from dateutil.tz import tzlocal
from tempfile import gettempdir

from pynwb.spec import NWBNamespaceBuilder, NWBGroupSpec, NWBAttributeSpec, NWBDatasetSpec
import unittest2 as unittest
from pynwb import get_type_map, TimeSeries, NWBFile, register_class, docval, load_namespaces, popargs
from pynwb.form.spec.spec import RefSpec
from pynwb import get_type_map, TimeSeries
from pynwb.form.utils import get_docval
from pynwb.spec import NWBNamespaceBuilder, NWBGroupSpec, NWBAttributeSpec, NWBDatasetSpec
from pynwb.file import LabMetaData


def id_generator(N=10):
Expand Down Expand Up @@ -80,6 +83,35 @@ def test_load_namespace_with_reftype_attribute_check_autoclass_const(self):
self.assertIsNotNone(docval)
self.assertEqual(docval['type'], TimeSeries)

def test_lab_meta(self):
ns_builder = NWBNamespaceBuilder('Extension for use in my Lab', self.prefix)
test_meta_ext = NWBGroupSpec(
neurodata_type_def='MyTestMetaData',
neurodata_type_inc='LabMetaData',
doc='my test meta data',
attributes=[
NWBAttributeSpec(name='test_attr', dtype='float', doc='test_dtype')])
ns_builder.add_spec(self.ext_source, test_meta_ext)
ns_builder.export(self.ns_path, outdir=self.tempdir)
ns_abs_path = os.path.join(self.tempdir, self.ns_path)

load_namespaces(ns_abs_path)

@register_class('MyTestMetaData', self.prefix)
class MyTestMetaData(LabMetaData):
__nwbfields__ = ('test_attr',)

@docval({'name': 'name', 'type': str, 'doc': 'name'},
{'name': 'test_attr', 'type': float, 'doc': 'test attribute'})
def __init__(self, **kwargs):
test_attr = popargs('test_attr', kwargs)
super(MyTestMetaData, self).__init__(**kwargs)
self.test_attr = test_attr

nwbfile = NWBFile("a file with header data", "NB123A", datetime(2017, 5, 1, 12, 0, 0, tzinfo=tzlocal()))

nwbfile.add_lab_meta_data(MyTestMetaData(name='test_name', test_attr=5.))


class TestCatchDupNS(unittest.TestCase):

Expand Down

0 comments on commit 779fa25

Please sign in to comment.