diff --git a/brainbox/behavior/training.py b/brainbox/behavior/training.py index 4a247d819..2e6c9f9fd 100644 --- a/brainbox/behavior/training.py +++ b/brainbox/behavior/training.py @@ -83,7 +83,8 @@ class TrainingStatus(IntFlag): ... assert TrainingStatus[status.upper()] in ~TrainingStatus.FAILED, 'Subject untrained' ... assert TrainingStatus[status.upper()] in TrainingStatus.TRAINED ^ TrainingStatus.READY - # Get the next training status + Get the next training status + >>> next(member for member in sorted(TrainingStatus) if member > TrainingStatus[status.upper()]) @@ -91,7 +92,7 @@ class TrainingStatus(IntFlag): ----- - ~TrainingStatus.TRAINED means any status but trained 1a or trained 1b. - A subject may acheive both TRAINED_1A and TRAINED_1B within a single session, therefore it - is possible to have skipped the TRAINED_1A session status. + is possible to have skipped the TRAINED_1A session status. """ UNTRAINABLE = auto() UNBIASABLE = auto() diff --git a/ibllib/io/extractors/mesoscope.py b/ibllib/io/extractors/mesoscope.py index 78ed21674..4def5ed3a 100644 --- a/ibllib/io/extractors/mesoscope.py +++ b/ibllib/io/extractors/mesoscope.py @@ -280,6 +280,7 @@ def get_wheel_positions(self, ticks=WHEEL_TICKS, radius=WHEEL_RADIUS_CM, coding= moves = extract_wheel_moves(wheel['timestamps'], wheel['position']) if display: + assert self.bpod_trials, 'no bpod trials to compare' fig, (ax0, ax1) = plt.subplots(nrows=2, sharex=True) bpod_ts = self.bpod_trials['wheel_timestamps'] bpod_pos = self.bpod_trials['wheel_position'] diff --git a/ibllib/pipes/mesoscope_tasks.py b/ibllib/pipes/mesoscope_tasks.py index fee1a9c4a..683395431 100644 --- a/ibllib/pipes/mesoscope_tasks.py +++ b/ibllib/pipes/mesoscope_tasks.py @@ -216,6 +216,7 @@ def signature(self): ('mpciROIs.stackPos.npy', 'alf/FOV*', True), ('mpciROIs.mpciROITypes.npy', 'alf/FOV*', True), ('mpciROIs.cellClassifier.npy', 'alf/FOV*', True), + ('mpciROIs.uuids.csv', 'alf/FOV*', True), ('mpciROITypes.names.tsv', 'alf/FOV*', True), ('mpciROIs.masks.npy', 'alf/FOV*', True), ('mpciROIs.neuropilMasks.npy', 'alf/FOV*', True), @@ -328,6 +329,11 @@ def _rename_outputs(self, suite2p_dir, frameQC_names, frameQC, rename_dict=None) np.save(fov_dir.joinpath('mpciROIs.stackPos.npy'), np.asarray([(*s['med'], 0) for s in stat], dtype=int)) np.save(fov_dir.joinpath('mpciROIs.cellClassifier.npy'), np.asarray(iscell[:, 1], dtype=float)) np.save(fov_dir.joinpath('mpciROIs.mpciROITypes.npy'), np.asarray(iscell[:, 0], dtype=np.int16)) + # clusters uuids + uuid_list = ['uuids'] + list(map(str, [uuid.uuid4() for _ in range(len(iscell))])) + with open(fov_dir.joinpath('mpciROIs.uuids.csv'), 'w+') as fid: + fid.write('\n'.join(uuid_list)) + pd.DataFrame([(0, 'no cell'), (1, 'cell')], columns=['roi_values', 'roi_labels'] ).to_csv(fov_dir.joinpath('mpciROITypes.names.tsv'), sep='\t', index=False) # ROI and neuropil masks diff --git a/ibllib/tests/extractors/test_ephys_trials.py b/ibllib/tests/extractors/test_ephys_trials.py index ba49d31bb..d5483792f 100644 --- a/ibllib/tests/extractors/test_ephys_trials.py +++ b/ibllib/tests/extractors/test_ephys_trials.py @@ -90,6 +90,10 @@ def test_align_to_trial(self): desired_out = np.array([4, 13, np.nan, 33, np.nan]) self.assertTrue(np.allclose(desired_out, t_event_nans, equal_nan=True, atol=0, rtol=0)) + # test errors + self.assertRaises(ValueError, ephys_fpga._assign_events_to_trial, np.array([0., 2., 1.]), t_event) + self.assertRaises(ValueError, ephys_fpga._assign_events_to_trial, t_trial_start, np.array([0., 2., 1.])) + def test_wheel_trace_from_sync(self): pos_ = - np.array([-1, 0, -1, -2, -1, -2]) * (np.pi / ephys_fpga.WHEEL_TICKS) ta = np.array([1, 2, 3, 4, 5, 6]) diff --git a/ibllib/tests/test_mesoscope.py b/ibllib/tests/test_mesoscope.py index b828386db..7ae3e5cd4 100644 --- a/ibllib/tests/test_mesoscope.py +++ b/ibllib/tests/test_mesoscope.py @@ -4,6 +4,7 @@ from unittest import mock import tempfile import json +from itertools import chain from pathlib import Path from one.api import ONE @@ -11,6 +12,7 @@ from ibllib.pipes.mesoscope_tasks import MesoscopePreprocess, MesoscopeFOV, \ find_triangle, surface_normal, _nearest_neighbour_1d +from ibllib.io.extractors import mesoscope from ibllib.tests import TEST_DB # Mock suit2p which is imported in MesoscopePreprocess @@ -248,3 +250,21 @@ def tearDown(self) -> None: Here we return the mode back to the default after testing behaviour in offline mode. """ self.one.mode = 'auto' + + +class TestImagingMeta(unittest.TestCase): + """Test raw imaging metadata versioning.""" + def test_patch_imaging_meta(self): + """Test for ibllib.io.extractors.mesoscope.patch_imaging_meta function.""" + meta = {'version': '0.1.0', 'FOV': [{'roiUuid': None}, {'roiUUID': None}]} + new_meta = mesoscope.patch_imaging_meta(meta) + self.assertEqual(set(chain(*map(dict.keys, new_meta['FOV']))), {'roiUUID'}) + meta = {'FOV': [ + dict.fromkeys(['topLeftDeg', 'topRightDeg', 'bottomLeftDeg', 'bottomRightDeg']), + dict.fromkeys(['topLeftMM', 'topRightMM', 'bottomLeftMM', 'bottomRightMM']) + ]} + new_meta = mesoscope.patch_imaging_meta(meta) + self.assertIn('channelSaved', new_meta) + self.assertCountEqual(new_meta['FOV'][0], ('Deg', 'MM')) + expected = ('topLeft', 'topRight', 'bottomLeft', 'bottomRight') + self.assertCountEqual(new_meta['FOV'][0]['MM'], expected)