From 7b39676a266f15ca6ef65c46985ce19e2d44d0b5 Mon Sep 17 00:00:00 2001 From: Oliver Ruebel Date: Thu, 5 Jul 2018 10:16:39 -0700 Subject: [PATCH 1/4] Added missing /general/data_collection field to NWBFile --- src/pynwb/file.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pynwb/file.py b/src/pynwb/file.py index 8dc8cefee..d3d4920cd 100644 --- a/src/pynwb/file.py +++ b/src/pynwb/file.py @@ -144,6 +144,7 @@ class NWBFile(MultiContainerInterface): ] __nwbfields__ = ('experimenter', + 'data_collection', 'description', 'experiment_description', 'session_id', @@ -192,6 +193,8 @@ class NWBFile(MultiContainerInterface): 'thickness, orientation, temperature and bath solution', 'default': None}, {'name': 'source_script', 'type': str, 'doc': 'Script file used to create this NWB file.', 'default': None}, + {'name': 'data_collection', 'type': str, + 'doc': 'Notes about data collection and analysis.', 'default': None}, {'name': 'surgery', 'type': str, 'doc': 'Narrative description about surgery/surgeries, including date(s) ' 'and who performed surgery.', 'default': None}, @@ -273,6 +276,7 @@ def __init__(self, **kwargs): 'session_id', 'lab', 'institution', + 'data_collection', 'notes', 'pharmacology', 'protocol', From 1c81fdba7e2896b9eab4e84a0f0d35a0e1ac6529 Mon Sep 17 00:00:00 2001 From: Oliver Ruebel Date: Thu, 5 Jul 2018 10:24:04 -0700 Subject: [PATCH 2/4] Added missing /general/stimulus to the NWBFile API --- src/pynwb/file.py | 4 ++++ src/pynwb/io/file.py | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pynwb/file.py b/src/pynwb/file.py index d3d4920cd..58c879c1e 100644 --- a/src/pynwb/file.py +++ b/src/pynwb/file.py @@ -158,6 +158,7 @@ class NWBFile(MultiContainerInterface): 'source_script', 'surgery', 'virus', + 'stimulus_notes', {'name': 'ec_electrodes', 'child': True}, {'name': 'epochs', 'child': True}, {'name': 'trials', 'child': True}, @@ -201,6 +202,8 @@ class NWBFile(MultiContainerInterface): {'name': 'virus', 'type': str, 'doc': 'Information about virus(es) used in experiments, including virus ID, ' 'source, date made, injection location, volume, etc.', 'default': None}, + {'name': 'stimulus_notes', 'type': str, + 'doc': 'Notes about stimuli, such as how and where presented.', 'default': None}, {'name': 'lab', 'type': str, 'doc': 'lab where experiment was performed', 'default': None}, {'name': 'acquisition', 'type': (list, tuple), 'doc': 'Raw TimeSeries objects belonging to this NWBFile', 'default': None}, @@ -285,6 +288,7 @@ def __init__(self, **kwargs): 'source_script', 'surgery', 'virus', + 'stimulus_notes', ] for attr in recommended: setattr(self, attr, kwargs.get(attr, None)) diff --git a/src/pynwb/io/file.py b/src/pynwb/io/file.py index 795a624ea..aa8041e56 100644 --- a/src/pynwb/io/file.py +++ b/src/pynwb/io/file.py @@ -39,7 +39,8 @@ def __init__(self, spec): self.map_spec( 'modules', self.spec.get_group('processing').get_neurodata_type('ProcessingModule')) - self.unmap(general_spec.get_dataset('stimulus')) + #self.unmap(general_spec.get_dataset('stimulus')) + self.map_spec('stimulus_notes', general_spec.get_dataset('stimulus')) self.map_spec('subject', general_spec.get_group('subject')) self.map_spec('devices', general_spec.get_group('devices').get_neurodata_type('Device')) From 4f7555dddeb2faa1bb862c229a9f8bd4cc3a38a8 Mon Sep 17 00:00:00 2001 From: Oliver Ruebel Date: Thu, 5 Jul 2018 11:17:20 -0700 Subject: [PATCH 3/4] Added missing attribute from /general/source_script.file_name to the NWBFile API --- src/pynwb/file.py | 7 +++++++ src/pynwb/io/file.py | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/pynwb/file.py b/src/pynwb/file.py index 58c879c1e..564820caf 100644 --- a/src/pynwb/file.py +++ b/src/pynwb/file.py @@ -156,6 +156,7 @@ class NWBFile(MultiContainerInterface): 'related_publications', 'slices', 'source_script', + 'source_script_file_name', 'surgery', 'virus', 'stimulus_notes', @@ -194,6 +195,8 @@ class NWBFile(MultiContainerInterface): 'thickness, orientation, temperature and bath solution', 'default': None}, {'name': 'source_script', 'type': str, 'doc': 'Script file used to create this NWB file.', 'default': None}, + {'name': 'source_script_file_name', 'type': str, + 'doc': 'Name of the sourc_script file', 'default': None}, {'name': 'data_collection', 'type': str, 'doc': 'Notes about data collection and analysis.', 'default': None}, {'name': 'surgery', 'type': str, @@ -286,6 +289,7 @@ def __init__(self, **kwargs): 'related_publications', 'slices', 'source_script', + 'source_script_file_name', 'surgery', 'virus', 'stimulus_notes', @@ -293,6 +297,9 @@ def __init__(self, **kwargs): for attr in recommended: setattr(self, attr, kwargs.get(attr, None)) + if getargs('source_script', kwargs) is None and getargs('source_script_file_name', kwargs) is not None: + raise ValueError("'source_script' cannot be None when 'source_script_file_name' is set") + def all_children(self): stack = [self] ret = list() diff --git a/src/pynwb/io/file.py b/src/pynwb/io/file.py index aa8041e56..7cd92668f 100644 --- a/src/pynwb/io/file.py +++ b/src/pynwb/io/file.py @@ -39,8 +39,9 @@ def __init__(self, spec): self.map_spec( 'modules', self.spec.get_group('processing').get_neurodata_type('ProcessingModule')) - #self.unmap(general_spec.get_dataset('stimulus')) + # self.unmap(general_spec.get_dataset('stimulus')) self.map_spec('stimulus_notes', general_spec.get_dataset('stimulus')) + self.map_spec('source_script_file_name', general_spec.get_dataset('source_script').get_attribute('file_name')) self.map_spec('subject', general_spec.get_group('subject')) self.map_spec('devices', general_spec.get_group('devices').get_neurodata_type('Device')) From 2bac460bcd553f40707f8f96ffd39a770f1f1b90 Mon Sep 17 00:00:00 2001 From: Oliver Ruebel Date: Thu, 5 Jul 2018 11:18:12 -0700 Subject: [PATCH 4/4] Added fields from /general to the integration test for NWBFile and unit tests --- tests/build_fake_data.py | 2 + tests/integration/ui_write/test_nwbfile.py | 43 +++++++++++++++++++++- tests/unit/pynwb_tests/test_file.py | 17 ++++++++- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/tests/build_fake_data.py b/tests/build_fake_data.py index 97d94638c..0aea0b644 100644 --- a/tests/build_fake_data.py +++ b/tests/build_fake_data.py @@ -20,6 +20,8 @@ lab='Bag End Labatory', institution='University of Middle Earth at the Shire', experiment_description='I went on an adventure with thirteen dwarves to reclaim vast treasures.', + stimulus_notes='The one ring to rule them all has been found', + data_collection='The ring was found in cave and stolen from Gollum', session_id='LONELYMTN') # Create the electrode group this simulated data is generated from diff --git a/tests/integration/ui_write/test_nwbfile.py b/tests/integration/ui_write/test_nwbfile.py index 34fb95d41..b2ed1e0ff 100644 --- a/tests/integration/ui_write/test_nwbfile.py +++ b/tests/integration/ui_write/test_nwbfile.py @@ -58,12 +58,34 @@ def setUpBuilder(self): DatasetBuilder('description', "A fake Clustering interface")})}) + general_builder = GroupBuilder('general', + datasets={ + 'experimenter': DatasetBuilder('experimenter', 'test experimenter'), + 'stimulus': DatasetBuilder('stimulus', 'test stimulus notes'), + 'experiment_description': DatasetBuilder('experiment_description', + 'test experiment description'), + 'data_collection': DatasetBuilder('data_collection', + 'test data collection notes'), + 'institution': DatasetBuilder('institution', 'nomad'), + 'lab': DatasetBuilder('lab', 'nolab'), + 'notes': DatasetBuilder('notes', 'nonotes'), + 'pharmacology': DatasetBuilder('pharmacology', 'nopharmacology'), + 'protocol': DatasetBuilder('protocol', 'noprotocol'), + 'related_publications': DatasetBuilder('related_publications', 'nopubs'), + 'session_id': DatasetBuilder('session_id', '007'), + 'slices': DatasetBuilder('slices', 'noslices'), + 'source_script': DatasetBuilder('source_script', 'nosources', + attributes={'file_name': 'nofilename'}), + 'surgery': DatasetBuilder('surgery', 'nosurgery'), + 'virus': DatasetBuilder('virus', 'novirus')} + ) + return GroupBuilder('root', groups={'acquisition': GroupBuilder( 'acquisition', groups={'test_timeseries': ts_builder}), 'analysis': GroupBuilder('analysis'), - 'general': GroupBuilder('general'), + 'general': general_builder, 'processing': GroupBuilder('processing', groups={'test_module': module_builder}), 'stimulus': GroupBuilder( 'stimulus', @@ -84,7 +106,24 @@ def setUpBuilder(self): def setUpContainer(self): container = NWBFile('a test source', 'a test NWB File', 'TEST123', - self.start_time, file_create_date=self.create_date) + self.start_time, + file_create_date=self.create_date, + experimenter='test experimenter', + stimulus_notes='test stimulus notes', + experiment_description='test experiment description', + data_collection='test data collection notes', + institution='nomad', + lab='nolab', + notes='nonotes', + pharmacology='nopharmacology', + protocol='noprotocol', + related_publications='nopubs', + session_id='007', + slices='noslices', + source_script='nosources', + surgery='nosurgery', + virus='novirus', + source_script_file_name='nofilename') self.ts = TimeSeries('test_timeseries', 'example_source', list(range(100, 200, 10)), 'SIunit', timestamps=list(range(10)), resolution=0.1) container.add_acquisition(self.ts) diff --git a/tests/unit/pynwb_tests/test_file.py b/tests/unit/pynwb_tests/test_file.py index 3fcf655b0..4f4da58ee 100644 --- a/tests/unit/pynwb_tests/test_file.py +++ b/tests/unit/pynwb_tests/test_file.py @@ -28,7 +28,11 @@ def setUp(self): related_publications='my pubs', slices='my slices', surgery='surgery', - virus='a virus') + virus='a virus', + source_script='noscript', + source_script_file_name='nofilename', + stimulus_notes='test stimulus notes', + data_collection='test data collection notes') def test_constructor(self): self.assertEqual(self.nwbfile.session_description, 'a test session description for a test NWBFile') @@ -39,6 +43,10 @@ def test_constructor(self): self.assertEqual(self.nwbfile.institution, 'a test institution') self.assertEqual(self.nwbfile.experiment_description, 'a test experiment description') self.assertEqual(self.nwbfile.session_id, 'test1') + self.assertEqual(self.nwbfile.stimulus_notes, 'test stimulus notes') + self.assertEqual(self.nwbfile.data_collection, 'test data collection notes') + self.assertEqual(self.nwbfile.source_script, 'noscript') + self.assertEqual(self.nwbfile.source_script_file_name, 'nofilename') def test_create_electrode_group(self): name = 'example_electrode_group' @@ -160,6 +168,13 @@ def test_all_children(self): self.assertIn(device, children) self.assertIn(elecgrp, children) + def test_fail_if_source_script_file_name_without_source_script(self): + with self.assertRaises(ValueError): + # <-- source_script_file_name without source_script is not allowed + NWBFile('a fake source', 'a test session description for a test NWBFile', 'FILE123', self.start, + source_script=None, + source_script_file_name='nofilename') + class SubjectTest(unittest.TestCase): def setUp(self):