Skip to content

Commit

Permalink
FpgaTrials supports alignment of Bpod datasets not part of trials object
Browse files Browse the repository at this point in the history
  • Loading branch information
k1o0 committed Mar 6, 2024
1 parent cd1e945 commit e9719ed
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 7 deletions.
2 changes: 1 addition & 1 deletion ibllib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging
import warnings

__version__ = '2.32.0'
__version__ = '2.32.1'
warnings.filterwarnings('always', category=DeprecationWarning, module='ibllib')

# if this becomes a full-blown library we should let the logging configuration to the discretion of the dev
Expand Down
34 changes: 33 additions & 1 deletion ibllib/io/extractors/ephys_fpga.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import spikeglx
import ibldsp.utils
import one.alf.io as alfio
from one.alf.files import filename_parts
from iblutil.util import Bunch
from iblutil.spacer import Spacer

Expand Down Expand Up @@ -816,6 +817,34 @@ def _extract(self, sync=None, chmap=None, sync_collection='raw_ephys_data',
assert self.var_names == tuple(out.keys())
return out

def _is_trials_object_attribute(self, var_name, variable_length_vars=None):
"""
Check if variable name is expected to have the same length as trials.intervals.
Parameters
----------
var_name : str
The variable name to check.
variable_length_vars : list
Set of variable names that are not expected to have the same length as trials.intervals.
This list may be passed by superclasses.
Returns
-------
bool
True if variable is a trials dataset.
Examples
--------
>>> assert self._is_trials_object_attribute('stimOnTrigger_times') is True
>>> assert self._is_trials_object_attribute('wheel_position') is False
"""
save_name = self.save_names[self.var_names.index(var_name)] if var_name in self.var_names else None
if save_name:
return filename_parts(save_name)[1] == 'trials'
else:
return var_name not in (variable_length_vars or [])

def build_trials(self, sync, chmap, display=False, **kwargs):
"""
Extract task related event times from the sync.
Expand Down Expand Up @@ -914,7 +943,10 @@ def build_trials(self, sync, chmap, display=False, **kwargs):
# Add the Bpod trial events, converting the timestamp fields to FPGA time.
# NB: The trial intervals are by default a Bpod rsync field.
out.update({k: self.bpod_trials[k][ibpod] for k in self.bpod_fields})
out.update({k: self.bpod2fpga(self.bpod_trials[k][ibpod]) for k in self.bpod_rsync_fields})
for k in self.bpod_rsync_fields:
# Some personal projects may extract non-trials object datasets that may not have 1 event per trial
idx = ibpod if self._is_trials_object_attribute(k) else np.arange(len(self.bpod_trials[k]), dtype=int)
out[k] = self.bpod2fpga(self.bpod_trials[k][idx])
out.update({k: fpga_trials[k][ifpga] for k in fpga_trials.keys()})

if display: # pragma: no cover
Expand Down
17 changes: 17 additions & 0 deletions ibllib/tests/extractors/test_ephys_fpga.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,23 @@ def test_time_fields(self):
fields = ephys_fpga.FpgaTrials._time_fields(expected + ('position', 'timebase', 'fooBaz'))
self.assertCountEqual(expected, fields)

def test_is_trials_object_attribute(self):
"""Test for FpgaTrials._is_trials_object_attribute method."""
extractor = ephys_fpga.FpgaTrials('subject/2020-01-01/001')
# Should assume this is a trials attribute if no save name defined
self.assertTrue(extractor._is_trials_object_attribute('stimOnTrigger_times'))
# Save name not trials attribute
self.assertFalse(extractor._is_trials_object_attribute('wheel_position'))
# Save name is trials attribute
self.assertTrue(extractor._is_trials_object_attribute('table'))
# Check with toy variables
extractor.var_names += ('foo_bar',)
extractor.save_names += (None,)
self.assertTrue(extractor._is_trials_object_attribute('foo_bar'))
self.assertFalse(extractor._is_trials_object_attribute('foo_bar', variable_length_vars='foo_bar'))
extractor.save_names = extractor.save_names[:-1] + ('_ibl_foo.bar_times.csv',)
self.assertFalse(extractor._is_trials_object_attribute('foo_bar'))


if __name__ == '__main__':
unittest.main(exit=False, verbosity=2)
13 changes: 8 additions & 5 deletions release_notes.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
## Release Notes 2.32

## features
- SDSC patcher automatically support revisons
- SDSC patcher automatically support revisions

## others
## other
- Add extra key to alignment qc with manual resolution for channel upload
-

#### 2.32.1
- FpgaTrials supports alignment of Bpod datasets not part of trials object

## Release Notes 2.31

### features
- training status uses new extractor map
- refactor neurodsp to ibldsp
- Training status uses new extractor map
- Refactor neurodsp to ibldsp
- ITI qc check for iblrig v8
- Support habituationChoiceWorld extraction in iblrig v8.15.0

Expand Down

0 comments on commit e9719ed

Please sign in to comment.