Skip to content

Commit 894b968

Browse files
authored
Merge pull request #776 from int-brain-lab/hotfix/2.35.3
Use correct task for timeline acquisitions in make_pipeline
2 parents 7270eaf + 509cb8a commit 894b968

File tree

4 files changed

+43
-10
lines changed

4 files changed

+43
-10
lines changed

ibllib/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import logging
33
import warnings
44

5-
__version__ = '2.35.2'
5+
__version__ = '2.35.3'
66
warnings.filterwarnings('always', category=DeprecationWarning, module='ibllib')
77

88
# if this becomes a full-blown library we should let the logging configuration to the discretion of the dev

ibllib/pipes/dynamic_pipeline.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,12 @@ def make_pipeline(session_path, **pkwargs):
268268
compute_status = False
269269
else:
270270
registration_class = btasks.TrialRegisterRaw
271-
behaviour_class = btasks.ChoiceWorldTrialsNidq
271+
if sync_args['sync_namespace'] == 'timeline':
272+
behaviour_class = btasks.ChoiceWorldTrialsTimeline
273+
elif sync_args['sync_namespace'] in ('spikeglx', None):
274+
behaviour_class = btasks.ChoiceWorldTrialsNidq
275+
else:
276+
raise NotImplementedError(f'No trials task available for sync namespace "{sync_args["sync_namespace"]}"')
272277
compute_status = True
273278
else:
274279
raise NotImplementedError
@@ -278,7 +283,7 @@ def make_pipeline(session_path, **pkwargs):
278283
tasks[f'Trials_{protocol}_{i:02}'] = type(f'Trials_{protocol}_{i:02}', (behaviour_class,), {})(
279284
**kwargs, **sync_kwargs, **task_kwargs, parents=parents)
280285
if compute_status:
281-
tasks[f"TrainingStatus_{protocol}_{i:02}"] = type(f'TrainingStatus_{protocol}_{i:02}', (
286+
tasks[f'TrainingStatus_{protocol}_{i:02}'] = type(f'TrainingStatus_{protocol}_{i:02}', (
282287
btasks.TrainingStatus,), {})(**kwargs, **task_kwargs, parents=[tasks[f'Trials_{protocol}_{i:02}']])
283288

284289
# Ephys tasks
@@ -289,7 +294,10 @@ def make_pipeline(session_path, **pkwargs):
289294
all_probes = []
290295
register_tasks = []
291296
for pname, probe_info in devices['neuropixel'].items():
292-
meta_file = spikeglx.glob_ephys_files(Path(session_path).joinpath(probe_info['collection']), ext='meta')
297+
# Glob to support collections such as _00a, _00b. This doesn't fix the issue of NP2.4
298+
# extractions, however.
299+
probe_collection = next(session_path.glob(probe_info['collection'] + '*'))
300+
meta_file = spikeglx.glob_ephys_files(probe_collection, ext='meta')
293301
meta_file = meta_file[0].get('ap')
294302
nptype = spikeglx._get_neuropixel_version_from_meta(spikeglx.read_meta_data(meta_file))
295303
nshanks = spikeglx._get_nshanks_from_meta(spikeglx.read_meta_data(meta_file))
@@ -482,12 +490,15 @@ def get_trials_tasks(session_path, one=None):
482490
# If experiment description file then use this to make the pipeline
483491
if experiment_description is not None:
484492
tasks = []
485-
pipeline = make_pipeline(session_path, one=one)
486-
trials_tasks = [t for t in pipeline.tasks if 'Trials' in t]
487-
for task in trials_tasks:
488-
t = pipeline.tasks.get(task)
489-
t.__init__(session_path, **t.kwargs)
490-
tasks.append(t)
493+
try:
494+
pipeline = make_pipeline(session_path, one=one)
495+
trials_tasks = [t for t in pipeline.tasks if 'Trials' in t]
496+
for task in trials_tasks:
497+
t = pipeline.tasks.get(task)
498+
t.__init__(session_path, **t.kwargs)
499+
tasks.append(t)
500+
except NotImplementedError as ex:
501+
_logger.warning('Failed to get trials tasks: %s', ex)
491502
else:
492503
# Otherwise default to old way of doing things
493504
if one and one.to_eid(session_path):

ibllib/tests/test_dynamic_pipeline.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import ibllib.tests
1010
import ibllib.pipes.dynamic_pipeline as dyn
1111
from ibllib.pipes.tasks import Pipeline, Task
12+
import ibllib.pipes.behavior_tasks as btasks
1213
from ibllib.pipes import ephys_preprocessing
1314
from ibllib.pipes import training_preprocessing
1415
from ibllib.io import session_params
@@ -65,6 +66,7 @@ def setUp(self):
6566
{'ephysChoiceWorld': {'task_collection': 'raw_task_data_00'}},
6667
{'passiveChoiceWorld': {'task_collection': 'raw_task_data_01'}},
6768
]}
69+
self.description = description
6870
with open(self.session_path_dynamic / '_ibl_experiment.description.yaml', 'w') as fp:
6971
yaml.safe_dump(description, fp)
7072

@@ -87,8 +89,25 @@ def test_get_trials_tasks(self):
8789
one.alyx.cache_mode = None # sneaky hack as this is checked by the pipeline somewhere
8890
tasks = dyn.get_trials_tasks(self.session_path_dynamic, one)
8991
self.assertEqual(2, len(tasks))
92+
self.assertIsInstance(tasks[0], btasks.ChoiceWorldTrialsNidq)
9093
one.load_datasets.assert_called() # check that description file is checked on disk
9194

95+
# A session with timeline acquisition
96+
self.description['sync']['nidq']['acquisition_software'] = 'timeline'
97+
with open(self.session_path_dynamic / '_ibl_experiment.description.yaml', 'w') as fp:
98+
yaml.safe_dump(self.description, fp)
99+
tasks = dyn.get_trials_tasks(self.session_path_dynamic, one)
100+
self.assertIsInstance(tasks[0], btasks.ChoiceWorldTrialsTimeline)
101+
102+
# A session with an unknown sync namespace
103+
self.description['sync']['nidq']['acquisition_software'] = 'notepad'
104+
with open(self.session_path_dynamic / '_ibl_experiment.description.yaml', 'w') as fp:
105+
yaml.safe_dump(self.description, fp)
106+
with self.assertLogs(dyn.__name__, 'WARNING') as cm:
107+
self.assertEqual([], dyn.get_trials_tasks(self.session_path_dynamic))
108+
log_message = cm.records[0].getMessage()
109+
self.assertIn('sync namespace "notepad"', log_message)
110+
92111
# An ephys session
93112
tasks = dyn.get_trials_tasks(self.session_path_legacy)
94113
self.assertEqual(1, len(tasks))

release_notes.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
- Support extraction of repNum for advancedChoiceWorld
1616
- Support matplotlib v3.9; min slidingRP version now 1.1.1
1717

18+
#### 2.35.3
19+
- Use correct task for timeline acquisitions in make_pipeline
20+
1821
## Release Note 2.34.0
1922

2023
### features

0 commit comments

Comments
 (0)