Skip to content

Commit c327cfa

Browse files
committed
HERD Changes internal file
1 parent f56b6f4 commit c327cfa

File tree

4 files changed

+224
-2
lines changed

4 files changed

+224
-2
lines changed

src/pynwb/file.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ class NWBFile(MultiContainerInterface, HERDManager):
339339
{'name': 'keywords', 'type': 'array_data', 'doc': 'Terms to search over', 'default': None},
340340
{'name': 'notes', 'type': str,
341341
'doc': 'Notes about the experiment.', 'default': None},
342+
{'name': 'external_resources', 'child': True, 'required_name': 'external_resources'},
342343
{'name': 'pharmacology', 'type': str,
343344
'doc': 'Description of drugs used, including how and when they were administered. '
344345
'Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc.', 'default': None},
@@ -483,9 +484,13 @@ def __init__(self, **kwargs):
483484
'icephys_experimental_conditions'
484485
]
485486
args_to_set = popargs_to_dict(keys_to_set, kwargs)
487+
args_to_set['internal_herd'] = popargs('external_resources', kwargs)
486488
kwargs['name'] = 'root'
487489
super().__init__(**kwargs)
488490

491+
self.reset_herd = False
492+
self.external_herd = None
493+
489494
# add timezone to session_start_time if missing
490495
session_start_time = args_to_set['session_start_time']
491496
if session_start_time.tzinfo is None:
@@ -570,6 +575,29 @@ def all_children(self):
570575
stack.append(c)
571576
return ret
572577

578+
def link_resources(self, herd):
579+
"""
580+
This method is to set an external HERD file as the external resources for this file.
581+
This will not persist on export. # TODO: This could change in the future with further development.
582+
"""
583+
self.external_herd = herd
584+
self.reset_herd = True
585+
586+
@property
587+
def external_resources(self):
588+
if self.reset_herd:
589+
return self.external_herd
590+
else:
591+
return self.internal_herd
592+
593+
@external_resources.setter
594+
def external_resources(self, herd):
595+
"""
596+
This is here to set HERD for the file if the user did not do so using __init__.
597+
"""
598+
self.internal_herd = herd
599+
self.internal_herd.parent = self
600+
573601
@property
574602
def objects(self):
575603
if self.__obj is None:
@@ -1152,4 +1180,4 @@ def ElectrodeTable(name='electrodes',
11521180
description='metadata about extracellular electrodes'):
11531181
warn("The ElectrodeTable convenience function is deprecated. Please create a new instance of "
11541182
"the ElectrodesTable class instead.", DeprecationWarning)
1155-
return ElectrodesTable()
1183+
return ElectrodesTable()

src/pynwb/io/file.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ def __init__(self, spec):
110110

111111
self.map_spec('subject', general_spec.get_group('subject'))
112112

113+
self.map_spec('external_resources', general_spec.get_group('external_resources'))
114+
113115
device_spec = general_spec.get_group('devices')
114116
self.unmap(device_spec)
115117
self.map_spec('devices', device_spec.get_neurodata_type('Device'))

src/pynwb/nwb-schema

tests/unit/test_resources.py

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,27 @@
11
import warnings
2+
from datetime import datetime
3+
from uuid import uuid4
4+
import os
5+
import numpy as np
6+
7+
from dateutil import tz
28

39
from pynwb.resources import HERD
10+
from pynwb.file import Subject
11+
from pynwb import NWBHDF5IO, NWBFile
412
from pynwb.testing import TestCase
513

614

715
class TestNWBContainer(TestCase):
16+
def setUp(self):
17+
self.path = "resources_file.nwb"
18+
self.export_path = "export_file.nwb"
19+
20+
def tearDown(self):
21+
for path in [self.path, self.export_path]:
22+
if os.path.isfile(path):
23+
os.remove(path)
24+
825
def test_constructor(self):
926
"""
1027
Test constructor
@@ -17,3 +34,178 @@ def test_constructor(self):
1734
)
1835
er = HERD()
1936
self.assertIsInstance(er, HERD)
37+
38+
def test_nwbfile_init_herd(self):
39+
session_start_time = datetime(2018, 4, 25, 2, 30, 3, tzinfo=tz.gettz("US/Pacific"))
40+
herd = HERD()
41+
nwbfile = NWBFile(
42+
session_description="A Person undergoing brain pokes.",
43+
identifier=str(uuid4()),
44+
session_start_time=session_start_time,
45+
external_resources=herd
46+
)
47+
self.assertTrue(isinstance(nwbfile.external_resources, HERD))
48+
49+
def test_nwbfile_set_herd(self):
50+
session_start_time = datetime(2018, 4, 25, 2, 30, 3, tzinfo=tz.gettz("US/Pacific"))
51+
herd = HERD()
52+
nwbfile = NWBFile(
53+
session_description="A Person undergoing brain pokes.",
54+
identifier=str(uuid4()),
55+
session_start_time=session_start_time,
56+
)
57+
nwbfile.external_resources = herd
58+
self.assertTrue(isinstance(nwbfile.external_resources, HERD))
59+
self.assertEqual(nwbfile.external_resources.parent, nwbfile)
60+
61+
def test_resources_roundtrip(self):
62+
session_start_time = datetime(2018, 4, 25, 2, 30, 3, tzinfo=tz.gettz("US/Pacific"))
63+
64+
nwbfile = NWBFile(
65+
session_description="A Person undergoing brain pokes.",
66+
identifier=str(uuid4()),
67+
session_start_time=session_start_time,
68+
)
69+
subject = Subject(
70+
subject_id="001",
71+
age="26",
72+
description="human 5",
73+
species='Homo sapiens',
74+
sex="M",
75+
)
76+
77+
nwbfile.subject = subject
78+
herd = HERD()
79+
nwbfile.external_resources = herd
80+
81+
nwbfile.external_resources.add_ref(container=nwbfile.subject,
82+
key=nwbfile.subject.species,
83+
entity_id="NCBI_TAXON:9606",
84+
entity_uri='https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=9606')
85+
86+
with NWBHDF5IO(self.path, "w") as io:
87+
io.write(nwbfile)
88+
89+
with NWBHDF5IO(self.path, "r") as io:
90+
read_nwbfile = io.read()
91+
self.assertEqual(
92+
read_nwbfile.external_resources.keys[:],
93+
np.array(
94+
[[(b'Homo sapiens',)]],
95+
dtype=[('key', 'O')]
96+
)
97+
)
98+
99+
self.assertEqual(
100+
read_nwbfile.external_resources.entities[:],
101+
np.array(
102+
[
103+
('NCBI_TAXON:9606',
104+
'https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=9606')
105+
],
106+
dtype=[('entity_id', 'O'), ('entity_uri', 'O')]
107+
)
108+
)
109+
110+
self.assertEqual(
111+
read_nwbfile.external_resources.objects[:],
112+
np.array(
113+
[
114+
(0,
115+
subject.object_id,
116+
'Subject',
117+
'',
118+
'')
119+
],
120+
dtype=[
121+
('files_idx', '<u4'),
122+
('object_id', 'O'),
123+
('object_type', 'O'),
124+
('relative_path', 'O'),
125+
('field', 'O')
126+
]
127+
)
128+
)
129+
130+
def test_link_resources(self):
131+
"""
132+
Note: Make sure that the internal HERD is not overwritten on export.
133+
"""
134+
session_start_time = datetime(2018, 4, 25, 2, 30, 3, tzinfo=tz.gettz("US/Pacific"))
135+
136+
nwbfile = NWBFile(
137+
session_description="A Person undergoing brain pokes.",
138+
identifier=str(uuid4()),
139+
session_start_time=session_start_time,
140+
)
141+
subject = Subject(
142+
subject_id="001",
143+
age="26",
144+
description="human 5",
145+
species='Homo sapiens',
146+
sex="M",
147+
)
148+
149+
nwbfile.subject = subject
150+
herd = HERD()
151+
nwbfile.external_resources = herd
152+
153+
nwbfile.external_resources.add_ref(container=nwbfile.subject,
154+
key=nwbfile.subject.species,
155+
entity_id="NCBI_TAXON:9606",
156+
entity_uri='https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=9606')
157+
158+
with NWBHDF5IO(self.path, "w") as io:
159+
io.write(nwbfile)
160+
161+
with NWBHDF5IO(self.path, mode='r') as read_io:
162+
read_nwbfile = read_io.read()
163+
read_nwbfile.link_resources(HERD())
164+
165+
self.assertEqual(read_nwbfile.external_resources.keys.data, [])
166+
self.assertEqual(read_nwbfile.external_resources.entities.data, [])
167+
self.assertEqual(read_nwbfile.external_resources.objects.data, [])
168+
169+
with NWBHDF5IO(self.export_path, mode='w') as export_io:
170+
export_io.export(src_io=read_io, nwbfile=read_nwbfile)
171+
172+
with NWBHDF5IO(self.export_path, mode='r') as read_export_io:
173+
read_export_nwbfile = read_export_io.read()
174+
self.assertEqual(
175+
read_export_nwbfile.external_resources.keys[:],
176+
np.array(
177+
[[(b'Homo sapiens',)]],
178+
dtype=[('key', 'O')]
179+
)
180+
)
181+
182+
self.assertEqual(
183+
read_export_nwbfile.external_resources.entities[:],
184+
np.array(
185+
[
186+
('NCBI_TAXON:9606',
187+
'https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=9606')
188+
],
189+
dtype=[('entity_id', 'O'), ('entity_uri', 'O')]
190+
)
191+
)
192+
193+
self.assertEqual(
194+
read_export_nwbfile.external_resources.objects[:],
195+
np.array(
196+
[
197+
(0,
198+
subject.object_id,
199+
'Subject',
200+
'',
201+
'')
202+
],
203+
dtype=[
204+
('files_idx', '<u4'),
205+
('object_id', 'O'),
206+
('object_type', 'O'),
207+
('relative_path', 'O'),
208+
('field', 'O')
209+
]
210+
)
211+
)

0 commit comments

Comments
 (0)