From bd2995aabc417884e7cfebd71854b0e34dfb4d27 Mon Sep 17 00:00:00 2001 From: Miles Wells Date: Wed, 6 Nov 2024 16:23:42 +0200 Subject: [PATCH] Resolves #877 --- ibllib/oneibl/registration.py | 7 ++--- ibllib/tests/test_oneibl.py | 48 ++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/ibllib/oneibl/registration.py b/ibllib/oneibl/registration.py index 2b7b3a2c4..48767628e 100644 --- a/ibllib/oneibl/registration.py +++ b/ibllib/oneibl/registration.py @@ -24,7 +24,8 @@ _logger = logging.getLogger(__name__) EXCLUDED_EXTENSIONS = ['.flag', '.error', '.avi'] -REGISTRATION_GLOB_PATTERNS = ['alf/**/*.*', +REGISTRATION_GLOB_PATTERNS = ['_ibl_experiment.description.yaml', + 'alf/**/*.*.*', 'raw_behavior_data/**/_iblrig_*.*', 'raw_task_data_*/**/_iblrig_*.*', 'raw_passive_data/**/_iblrig_*.*', @@ -238,9 +239,9 @@ def register_session(self, ses_path, file_list=True, projects=None, procedures=N missing = [k for k in required if not session_details[k]] assert not any(missing), 'missing session information: ' + ', '.join(missing) task_protocols = task_data = settings = [] - json_field = None + json_field = end_time = None users = session_details['users'] - n_trials, n_correct_trials = 0 + n_trials = n_correct_trials = 0 else: # Get session info from task data collections = ensure_list(collections) # read meta data from the rig for the session from the task settings file diff --git a/ibllib/tests/test_oneibl.py b/ibllib/tests/test_oneibl.py index 913fcec9e..1d75d4f0c 100644 --- a/ibllib/tests/test_oneibl.py +++ b/ibllib/tests/test_oneibl.py @@ -388,6 +388,7 @@ def test_create_sessions(self): self.assertFalse(flag_file.exists()) def test_registration_session(self): + """Test IBLRegistrationClient.register_session method.""" settings_file = self._write_settings_file() rc = registration.IBLRegistrationClient(one=self.one) rc.register_session(str(self.session_path), procedures=['Ephys recording with acute probe(s)']) @@ -427,8 +428,52 @@ def test_registration_session(self): self.assertEqual(self.settings['SESSION_END_TIME'], ses_info['end_time']) self.one.alyx.rest('sessions', 'delete', id=eid) + def test_registration_session_passive(self): + """Test IBLRegistrationClient.register_session method when there is no iblrig bpod data. + + For truly passive sessions there is no Bpod data (no raw_behavior_data or raw_task_data folders). + In this situation the must already be a session on Alyx manually created by the experimenter, + which needs to contain the start time, location, lab, and user data. + """ + rc = registration.IBLRegistrationClient(one=self.one) + experiment_description = { + 'procedures': ['Ephys recording with acute probe(s)'], + 'sync': {'nidq': {'collection': 'raw_ephys_data'}}} + session_params.write_params(self.session_path, experiment_description) + # Should fail because the session doesn't exist on Alyx + self.assertRaises(AssertionError, rc.register_session, self.session_path) + # Create the session + ses_ = { + 'subject': self.subject, 'users': [self.one.alyx.user], + 'type': 'Experiment', 'number': int(self.session_path.name), + 'start_time': rc.ensure_ISO8601(self.session_path.parts[-2]), + 'n_correct_trials': 100, 'n_trials': 200 + } + session = self.one.alyx.rest('sessions', 'create', data=ses_) + # Should fail because the session lacks critical information + self.assertRaisesRegex( + AssertionError, 'missing session information: location', rc.register_session, self.session_path) + session = self.one.alyx.rest( + 'sessions', 'partial_update', id=session['url'][-36:], data={'location': self.settings['PYBPOD_BOARD']}) + # Should now register + ses, dsets = rc.register_session(self.session_path) + # Check that session was updated, namely the n trials and procedures + self.assertEqual(session['url'], ses['url']) + self.assertTrue(ses['n_correct_trials'] == ses['n_trials'] == 0) + self.assertEqual(experiment_description['procedures'], ses['procedures']) + self.assertEqual(5, len(dsets)) + registered = [d['file_records'][0]['relative_path'] for d in dsets] + expected = [ + f'{self.subject}/2018-04-01/002/_ibl_experiment.description.yaml', + f'{self.subject}/2018-04-01/002/alf/spikes.amps.npy', + f'{self.subject}/2018-04-01/002/alf/spikes.times.npy', + f'{self.subject}/2018-04-01/002/alf/#{self.revision}#/spikes.amps.npy', + f'{self.subject}/2018-04-01/002/alf/#{self.revision}#/spikes.times.npy' + ] + self.assertCountEqual(expected, registered) + def test_register_chained_session(self): - """Tests for registering a session with chained (multiple) protocols""" + """Tests for registering a session with chained (multiple) protocols.""" behaviour_paths = [self.session_path.joinpath(f'raw_task_data_{i:02}') for i in range(2)] for p in behaviour_paths: p.mkdir() @@ -459,6 +504,7 @@ def test_register_chained_session(self): rc = registration.IBLRegistrationClient(one=self.one) session, recs = rc.register_session(self.session_path) + self.assertEqual(7, len(recs)) ses_info = self.one.alyx.rest('sessions', 'read', id=session['id']) self.assertCountEqual(experiment_description['procedures'], ses_info['procedures']) self.assertCountEqual(experiment_description['projects'], ses_info['projects'])