Skip to content

Commit 4eb749b

Browse files
committed
Merge remote-tracking branch 'origin/develop' into manual_curation_ssloader
2 parents 89fadae + 6e63c9e commit 4eb749b

File tree

3 files changed

+27
-6
lines changed

3 files changed

+27
-6
lines changed

ibllib/io/extractors/mesoscope.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -672,8 +672,8 @@ def _extract(self, sync=None, chmap=None, device_collection='raw_imaging_data',
672672
_, fov_time_shifts, line_time_shifts = self.get_timeshifts(imaging_data['meta'])
673673
assert len(fov_time_shifts) == self.n_FOVs, f'unexpected number of FOVs for {collection}'
674674
ts = frame_times[np.logical_and(frame_times >= tmin, frame_times <= tmax)]
675-
assert ts.size >= imaging_data['times_scanImage'].size, (f'fewer DAQ timestamps for {collection} '
676-
f'than expected')
675+
assert ts.size >= imaging_data[
676+
'times_scanImage'].size, f"fewer DAQ timestamps for {collection} than expected: DAQ/frames = {ts.size}/{imaging_data['times_scanImage'].size}"
677677
if ts.size > imaging_data['times_scanImage'].size:
678678
_logger.warning(
679679
'More DAQ frame times detected for %s than were found in the raw image data.\n'

ibllib/pipes/dynamic_pipeline.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,15 +232,21 @@ def _get_trials_tasks(session_path, acquisition_description=None, sync_tasks=Non
232232
sync_kwargs = {'sync': sync, **sync_args}
233233

234234
# Behavior tasks
235+
protocol_numbers = set()
235236
task_protocols = acquisition_description.get('tasks', [])
236237
for i, (protocol, task_info) in enumerate(chain(*map(dict.items, task_protocols))):
237238
collection = task_info.get('collection', f'raw_task_data_{i:02}')
238239
task_kwargs = {'protocol': protocol, 'collection': collection}
239-
# For now the order of protocols in the list will take precedence. If collections are numbered,
240-
# check that the numbers match the order. This may change in the future.
240+
# The order of protocols in the list will take precedence unless protocol_number is present.
241+
# If collections are numbered, check that the numbers match the order.
242+
n = i
241243
if re.match(r'^raw_task_data_\d{2}$', collection):
242-
task_kwargs['protocol_number'] = i
243-
if int(collection.split('_')[-1]) != i:
244+
# Protocol number may be overridden by the protocol_number key
245+
if task_info.get('protocol_number') is not None:
246+
n = task_info['protocol_number']
247+
task_kwargs['protocol_number'] = n
248+
assert not (n in protocol_numbers or protocol_numbers.add(n)), 'protocol numbers must be unique'
249+
if int(collection.split('_')[-1]) != n:
244250
_logger.warning('Number in collection name does not match task order')
245251
if extractors := task_info.get('extractors', False):
246252
extractors = (extractors,) if isinstance(extractors, str) else extractors

ibllib/tests/test_dynamic_pipeline.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import unittest
44
from unittest import mock
55
from itertools import chain
6+
from copy import deepcopy
67

78
import yaml
89

@@ -79,6 +80,20 @@ def test_get_trials_tasks(self):
7980
self.assertIsInstance(tasks[0], btasks.ChoiceWorldTrialsNidq)
8081
one.load_datasets.assert_called() # check that description file is checked on disk
8182

83+
# A session where protocol number is specified
84+
description = deepcopy(self.description)
85+
description['tasks'][1]['passiveChoiceWorld']['protocol_number'] = 2
86+
fcn_to_patch = 'ibllib.pipes.dynamic_pipeline._load_acquisition_description'
87+
with mock.patch(fcn_to_patch, return_value=description), self.assertLogs(dyn.__name__, 'WARNING') as cm:
88+
tasks = dyn.get_trials_tasks(self.session_path_dynamic)
89+
self.assertEqual(2, tasks[1].protocol_number)
90+
self.assertRegex(cm.records[0].getMessage(), 'Number in collection name does not match task order')
91+
# If protocol number is not unique, an assertion error should be raised
92+
description = deepcopy(self.description)
93+
description['tasks'][1]['passiveChoiceWorld']['protocol_number'] = 0
94+
with mock.patch(fcn_to_patch, return_value=description):
95+
self.assertRaises(AssertionError, dyn.get_trials_tasks, self.session_path_dynamic)
96+
8297
# A session with timeline acquisition
8398
self.description['sync']['nidq']['acquisition_software'] = 'timeline'
8499
with open(self.session_path_dynamic / '_ibl_experiment.description.yaml', 'w') as fp:

0 commit comments

Comments
 (0)