Skip to content

Commit bc1baf9

Browse files
committed
add invalid_times
1 parent fe41eac commit bc1baf9

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

src/pynwb/data/nwb.file.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,10 @@ groups:
435435
name: trials
436436
doc: repeated experimental events that have a logical grouping
437437
quantity: '?'
438+
- neurodata_type_inc: TimeIntervals
439+
name: invalid_times
440+
doc: time intervals that should be removed from analysis
441+
quantity: '?'
438442
- neurodata_type_inc: TimeIntervals
439443
doc: an optional additional table for describing other experimental time intervals
440444
quantity: '*'

src/pynwb/file.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ class NWBFile(MultiContainerInterface):
168168
{'name': 'units', 'child': True, 'required_name': 'units'},
169169
{'name': 'subject', 'child': True, 'required_name': 'subject'},
170170
{'name': 'sweep_table', 'child': True, 'required_name': 'sweep_table'},
171+
{'name': 'invalid_times', 'child': True, 'required_name': 'invalid_times'},
171172
'epoch_tags',)
172173

173174
@docval({'name': 'session_description', 'type': str,
@@ -227,6 +228,8 @@ class NWBFile(MultiContainerInterface):
227228
'doc': 'A sorted list of tags used across all epochs', 'default': set()},
228229
{'name': 'trials', 'type': TimeIntervals,
229230
'doc': 'A table containing trial data', 'default': None},
231+
{'name': 'invalid_times', 'type': TimeIntervals,
232+
'doc': 'A table containing times to be omitted from analysis', 'default': None},
230233
{'name': 'time_intervals', 'type': (list, tuple),
231234
'doc': 'any TimeIntervals tables storing time intervals', 'default': None},
232235
{'name': 'units', 'type': DynamicTable,
@@ -289,6 +292,9 @@ def __init__(self, **kwargs):
289292
trials = getargs('trials', kwargs)
290293
if trials is not None:
291294
self.trials = trials
295+
invalid_times = getargs('invalid_times', kwargs)
296+
if invalid_times is not None:
297+
self.invalid_times = invalid_times
292298
units = getargs('units', kwargs)
293299
if units is not None:
294300
self.units = units
@@ -507,6 +513,30 @@ def add_trial(self, **kwargs):
507513
self.__check_trials()
508514
call_docval_func(self.trials.add_interval, kwargs)
509515

516+
def __check_invalid_times(self):
517+
if self.invalid_times is None:
518+
self.invalid_times = TimeIntervals('invalid_times', 'time intervals to be removed from analysis')
519+
520+
@docval(*get_docval(DynamicTable.add_column))
521+
def add_invalid_times_column(self, **kwargs):
522+
"""
523+
Add a column to the trial table.
524+
See :py:meth:`~pynwb.core.DynamicTable.add_column` for more details
525+
"""
526+
self.__check_invalid_times()
527+
call_docval_func(self.invalid_times.add_column, kwargs)
528+
529+
def add_invalid_time_interval(self, **kwargs):
530+
"""
531+
Add a trial to the trial table.
532+
See :py:meth:`~pynwb.core.DynamicTable.add_row` for more details.
533+
534+
Required fields are *start_time*, *stop_time*, and any columns that have
535+
been added (through calls to `add_invalid_times_columns`).
536+
"""
537+
self.__check_invalid_times()
538+
call_docval_func(self.invalid_times.add_interval, kwargs)
539+
510540
@docval({'name': 'electrode_table', 'type': DynamicTable, 'doc': 'the ElectrodeTable for this file'})
511541
def set_electrode_table(self, **kwargs):
512542
"""
@@ -592,3 +622,7 @@ def ElectrodeTable(name='electrodes',
592622
def TrialTable(name='trials',
593623
description='metadata about experimental trials'):
594624
return _tablefunc(name, description, ['start', 'end'])
625+
626+
627+
def InvalidTimesTable(name='invalid_times', description='time intervals to be removed from analysis'):
628+
return _tablefunc(name, description, ['start_time', 'stop_time'])

tests/unit/pynwb_tests/test_file.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,23 @@ def test_add_trial(self):
176176
self.nwbfile.add_trial(start_time=50.0, stop_time=70.0)
177177
self.assertEqual(len(self.nwbfile.trials), 3)
178178

179+
def test_add_invalid_times_column(self):
180+
self.nwbfile.add_invalid_times_column('comments', 'description of reason for omitting time')
181+
self.assertEqual(self.nwbfile.invalid_times.colnames, ('start_time', 'stop_time', 'comments'))
182+
183+
def test_add_invalid_time_interval(self):
184+
185+
self.nwbfile.add_invalid_time_interval(start_time=0.0, stop_time=12.0)
186+
self.assertEqual(len(self.nwbfile.invalid_times), 1)
187+
self.nwbfile.add_invalid_time_interval(start_time=15.0, stop_time=16.0)
188+
self.nwbfile.add_invalid_time_interval(start_time=17.0, stop_time=20.5)
189+
self.assertEqual(len(self.nwbfile.invalid_times), 3)
190+
191+
def test_add_invalid_time_w_ts(self):
192+
ts = TimeSeries(name='name', data=[1.2], rate=1.0, unit='na')
193+
self.nwbfile.add_invalid_time_interval(start_time=18.0, stop_time=20.6,
194+
timeseries=ts, tags=('hi', 'there'))
195+
179196
def test_add_electrode(self):
180197
dev1 = self.nwbfile.create_device('dev1') # noqa: F405
181198
group = self.nwbfile.create_electrode_group('tetrode1',

0 commit comments

Comments
 (0)