def test_stimulus_file_from_json(stimulus_file_fixture): stim_pkl_path, stim_pkl_data = stimulus_file_fixture # Basic test case input_json_dict = {"behavior_stimulus_file": str(stim_pkl_path)} stimulus_file = StimulusFile.from_json(input_json_dict) assert stimulus_file.data == stim_pkl_data # Now test caching by deleting the stimulus_file stim_pkl_path.unlink() stimulus_file_cached = StimulusFile.from_json(input_json_dict) assert stimulus_file_cached.data == stim_pkl_data
def from_json(cls, dict_repr: dict) -> "StimulusTimestamps": if 'sync_file' in dict_repr: sync_file = SyncFile.from_json(dict_repr=dict_repr) return cls.from_sync_file(sync_file=sync_file) else: stim_file = StimulusFile.from_json(dict_repr=dict_repr) return cls.from_stimulus_file(stimulus_file=stim_file)
def test_from_stimulus_file2(self, tmpdir): """ Test that Licks.from_stimulus_file returns a dataframe of licks whose timestamps are based on their frame number with respect to the stimulus_timestamps """ stimulus_filepath = self._create_test_stimulus_file( lick_events=[12, 15, 90, 136], tmpdir=tmpdir) stimulus_file = StimulusFile.from_json( dict_repr={'behavior_stimulus_file': str(stimulus_filepath)}) timestamps = StimulusTimestamps(timestamps=np.arange(0, 2.0, 0.01)) licks = Licks.from_stimulus_file(stimulus_file=stimulus_file, stimulus_timestamps=timestamps) expected_dict = { 'timestamps': [0.12, 0.15, 0.90, 1.36], 'frame': [12, 15, 90, 136] } expected_df = pd.DataFrame(expected_dict) assert expected_df.columns.equals(licks.value.columns) np.testing.assert_array_almost_equal( expected_df.timestamps.to_numpy(), licks.value['timestamps'].to_numpy(), decimal=10) np.testing.assert_array_almost_equal(expected_df.frame.to_numpy(), licks.value['frame'].to_numpy(), decimal=10)
def from_json(cls, session_data: dict, monitor_delay: Optional[float] = None) \ -> "BehaviorSession": """ Parameters ---------- session_data Dict of input data necessary to construct a session monitor_delay Monitor delay. If not provided, will use an estimate. To provide this value, see for example allensdk.brain_observatory.behavior.data_objects.stimuli.util. calculate_monitor_delay Returns ------- `BehaviorSession` instance """ behavior_session_id = BehaviorSessionId.from_json( dict_repr=session_data) stimulus_file = StimulusFile.from_json(dict_repr=session_data) stimulus_timestamps = StimulusTimestamps.from_json( dict_repr=session_data) running_acquisition = RunningAcquisition.from_json( dict_repr=session_data) raw_running_speed = RunningSpeed.from_json(dict_repr=session_data, filtered=False) running_speed = RunningSpeed.from_json(dict_repr=session_data) metadata = BehaviorMetadata.from_json(dict_repr=session_data) if monitor_delay is None: monitor_delay = cls._get_monitor_delay() licks, rewards, stimuli, task_parameters, trials = \ cls._read_data_from_stimulus_file( stimulus_file=stimulus_file, stimulus_timestamps=stimulus_timestamps, trial_monitor_delay=monitor_delay ) date_of_acquisition = DateOfAcquisition.from_json( dict_repr=session_data)\ .validate( stimulus_file=stimulus_file, behavior_session_id=behavior_session_id.value) return BehaviorSession(behavior_session_id=behavior_session_id, stimulus_timestamps=stimulus_timestamps, running_acquisition=running_acquisition, raw_running_speed=raw_running_speed, running_speed=running_speed, metadata=metadata, licks=licks, rewards=rewards, stimuli=stimuli, task_parameters=task_parameters, trials=trials, date_of_acquisition=date_of_acquisition)
def test_get_licks_excess(self, tmpdir): """ Test that Licks.from_stimulus_file in the case where there is an extra frame at the end of the trial log and the mouse licked on that frame https://github.com/AllenInstitute/visual_behavior_analysis/blob /master/visual_behavior/translator/foraging2/extract.py#L640-L647 """ stimulus_filepath = self._create_test_stimulus_file( lick_events=[12, 15, 90, 136, 200], # len(timestamps) == 200, tmpdir=tmpdir) stimulus_file = StimulusFile.from_json( dict_repr={'behavior_stimulus_file': str(stimulus_filepath)}) timestamps = StimulusTimestamps(timestamps=np.arange(0, 2.0, 0.01)) licks = Licks.from_stimulus_file(stimulus_file=stimulus_file, stimulus_timestamps=timestamps) expected_dict = { 'timestamps': [0.12, 0.15, 0.90, 1.36], 'frame': [12, 15, 90, 136] } expected_df = pd.DataFrame(expected_dict) assert expected_df.columns.equals(licks.value.columns) np.testing.assert_array_almost_equal( expected_df.timestamps.to_numpy(), licks.value['timestamps'].to_numpy(), decimal=10) np.testing.assert_array_almost_equal(expected_df.frame.to_numpy(), licks.value['frame'].to_numpy(), decimal=10)
def setup_class(cls): dir = Path(__file__).parent.resolve() test_data_dir = dir / 'test_data' cls.stimulus_file = StimulusFile(filepath=test_data_dir / 'behavior_stimulus_file.pkl') expected = pd.read_pickle(str(test_data_dir / 'licks.pkl')) cls.expected = Licks(licks=expected)
def test_from_stimulus_file(self): stimulus_file = StimulusFile.from_lims( behavior_session_id=self.behavior_session_id, db=self.dbconn) timestamps = StimulusTimestamps.from_stimulus_file( stimulus_file=stimulus_file) rewards = Rewards.from_stimulus_file(stimulus_file=stimulus_file, stimulus_timestamps=timestamps) assert rewards == self.expected
def setup_class(cls): dir = Path(__file__).parent.resolve() test_data_dir = dir / 'test_data' stimulus_file = StimulusFile(filepath=test_data_dir / 'behavior_stimulus_file.pkl') ts = StimulusTimestamps.from_stimulus_file(stimulus_file=stimulus_file) cls.licks = Licks.from_stimulus_file(stimulus_file=stimulus_file, stimulus_timestamps=ts)
def setup_method(self, method): self.nwbfile = pynwb.NWBFile(session_description='asession', identifier='1234', session_start_time=datetime.now()) # Need to write stimulus timestamps first bsf = StimulusFile(filepath=self.test_data_dir / 'behavior_stimulus_file.pkl') ts = StimulusTimestamps.from_stimulus_file(stimulus_file=bsf) ts.to_nwb(nwbfile=self.nwbfile)
def test_get_licks_failure(self, tmpdir): stimulus_filepath = self._create_test_stimulus_file( lick_events=[12, 15, 90, 136, 201], # len(timestamps) == 200, tmpdir=tmpdir) stimulus_file = StimulusFile.from_json( dict_repr={'behavior_stimulus_file': str(stimulus_filepath)}) timestamps = StimulusTimestamps(timestamps=np.arange(0, 2.0, 0.01)) with pytest.raises(IndexError): Licks.from_stimulus_file(stimulus_file=stimulus_file, stimulus_timestamps=timestamps)
def test_stimulus_file_from_lims(stimulus_file_fixture, behavior_session_id): stim_pkl_path, stim_pkl_data = stimulus_file_fixture mock_db_conn = create_autospec(PostgresQueryMixin, instance=True) # Basic test case mock_db_conn.fetchone.return_value = str(stim_pkl_path) stimulus_file = StimulusFile.from_lims(mock_db_conn, behavior_session_id) assert stimulus_file.data == stim_pkl_data # Now test caching by deleting stimulus_file and also asserting db # `fetchone` called only once stim_pkl_path.unlink() stimfile_cached = StimulusFile.from_lims(mock_db_conn, behavior_session_id) assert stimfile_cached.data == stim_pkl_data query = STIMULUS_FILE_QUERY_TEMPLATE.format( behavior_session_id=behavior_session_id) mock_db_conn.fetchone.assert_called_once_with(query, strict=True)
def test_stimulus_timestamps_from_json2(): dir = Path(__file__).parent.parent.resolve() test_data_dir = dir / 'test_data' sf_path = test_data_dir / 'stimulus_file.pkl' sf = StimulusFile.from_json( dict_repr={'behavior_stimulus_file': str(sf_path)}) stimulus_timestamps = StimulusTimestamps.from_stimulus_file( stimulus_file=sf) expected = np.array([0.016 * i for i in range(11)]) assert np.allclose(expected, stimulus_timestamps.value)
def test_from_stimulus_file(self): stimulus_file = StimulusFile.from_lims( behavior_session_id=self.behavior_session_id, db=self.dbconn) stimulus_timestamps = StimulusTimestamps.from_stimulus_file( stimulus_file=stimulus_file) stimuli = Stimuli.from_stimulus_file( stimulus_file=stimulus_file, stimulus_timestamps=stimulus_timestamps, limit_to_images=['im065']) assert stimuli.presentations == self.expected_presentations assert stimuli.templates == self.expected_templates
def from_lims( cls, db: PostgresQueryMixin, behavior_session_id: int, ophys_experiment_id: Optional[int] = None) -> "StimulusTimestamps": stimulus_file = StimulusFile.from_lims(db, behavior_session_id) if ophys_experiment_id: sync_file = SyncFile.from_lims( db=db, ophys_experiment_id=ophys_experiment_id) return cls.from_sync_file(sync_file=sync_file) else: return cls.from_stimulus_file(stimulus_file=stimulus_file)
def test_from_stimulus_file2(self, tmpdir): """ Test that Rewards.from_stimulus_file returns expected results (main nuance is that timestamps should be determined by applying the reward frame as an index to stimulus_timestamps) """ def _create_dummy_stimulus_file(): trial_log = [{ 'rewards': [(0.001, -1.0, 4)], 'trial_params': { 'auto_reward': True } }, { 'rewards': [] }, { 'rewards': [(0.002, -1.0, 10)], 'trial_params': { 'auto_reward': False } }] data = { 'items': { 'behavior': { 'trial_log': trial_log } }, } tmp_path = tmpdir / 'stimulus_file.pkl' with open(tmp_path, 'wb') as f: pickle.dump(data, f) f.seek(0) return tmp_path stimulus_filepath = _create_dummy_stimulus_file() stimulus_file = StimulusFile.from_json( dict_repr={'behavior_stimulus_file': str(stimulus_filepath)}) timestamps = StimulusTimestamps(timestamps=np.arange(0, 2.0, 0.01)) rewards = Rewards.from_stimulus_file(stimulus_file=stimulus_file, stimulus_timestamps=timestamps) expected_dict = { 'volume': [0.001, 0.002], 'timestamps': [0.04, 0.1], 'autorewarded': [True, False] } expected_df = pd.DataFrame(expected_dict) expected_df = expected_df assert expected_df.equals(rewards.value)
def from_json(cls, dict_repr: dict, filtered: bool = True, zscore_threshold: float = 10.0) -> "RunningSpeed": stimulus_file = StimulusFile.from_json(dict_repr) stimulus_timestamps = StimulusTimestamps.from_json(dict_repr) running_speed = cls._get_running_speed_df(stimulus_file, stimulus_timestamps, filtered, zscore_threshold) return cls(running_speed=running_speed, stimulus_file=stimulus_file, stimulus_timestamps=stimulus_timestamps, filtered=filtered)
def from_json( cls, dict_repr: dict, ) -> "RunningAcquisition": stimulus_file = StimulusFile.from_json(dict_repr) stimulus_timestamps = StimulusTimestamps.from_json(dict_repr) running_acq_df = get_running_df( data=stimulus_file.data, time=stimulus_timestamps.value, ) running_acq_df.drop("speed", axis=1, inplace=True) return cls( running_acquisition=running_acq_df, stimulus_file=stimulus_file, stimulus_timestamps=stimulus_timestamps, )
def from_lims( cls, db: PostgresQueryMixin, behavior_session_id: int, filtered: bool = True, zscore_threshold: float = 10.0, stimulus_timestamps: Optional[StimulusTimestamps] = None ) -> "RunningSpeed": stimulus_file = StimulusFile.from_lims(db, behavior_session_id) if stimulus_timestamps is None: stimulus_timestamps = StimulusTimestamps.from_stimulus_file( stimulus_file=stimulus_file) running_speed = cls._get_running_speed_df(stimulus_file, stimulus_timestamps, filtered, zscore_threshold) return cls(running_speed=running_speed, stimulus_file=stimulus_file, stimulus_timestamps=stimulus_timestamps, filtered=filtered)
def test_empty_licks(self, tmpdir): """ Test that Licks.from_stimulus_file in the case where there are no licks """ stimulus_filepath = self._create_test_stimulus_file(lick_events=[], tmpdir=tmpdir) stimulus_file = StimulusFile.from_json( dict_repr={'behavior_stimulus_file': str(stimulus_filepath)}) timestamps = StimulusTimestamps(timestamps=np.arange(0, 2.0, 0.01)) licks = Licks.from_stimulus_file(stimulus_file=stimulus_file, stimulus_timestamps=timestamps) expected_dict = {'timestamps': [], 'frame': []} expected_df = pd.DataFrame(expected_dict) assert expected_df.columns.equals(licks.value.columns) np.testing.assert_array_equal(expected_df.timestamps.to_numpy(), licks.value['timestamps'].to_numpy()) np.testing.assert_array_equal(expected_df.frame.to_numpy(), licks.value['frame'].to_numpy())
def from_lims( cls, db: PostgresQueryMixin, behavior_session_id: int, ophys_experiment_id: Optional[int] = None, ) -> "RunningAcquisition": stimulus_file = StimulusFile.from_lims(db, behavior_session_id) stimulus_timestamps = StimulusTimestamps.from_stimulus_file( stimulus_file=stimulus_file) running_acq_df = get_running_df( data=stimulus_file.data, time=stimulus_timestamps.value, ) running_acq_df.drop("speed", axis=1, inplace=True) return cls( running_acquisition=running_acq_df, stimulus_file=stimulus_file, stimulus_timestamps=stimulus_timestamps, )
def test_get_date_of_acquisition(self, tmp_path, test_params, expected_warn_msg): mock_session_id = test_params["behavior_session_id"] pkl_save_path = tmp_path / f"mock_pkl_{mock_session_id}.pkl" with open(pkl_save_path, 'wb') as handle: pickle.dump({"start_time": test_params['pkl_expt_date']}, handle) tz = pytz.timezone("America/Los_Angeles") extractor_expt_date = tz.localize( test_params['extractor_expt_date']).astimezone(pytz.utc) stimulus_file = StimulusFile(filepath=pkl_save_path) obt_date = DateOfAcquisition(date_of_acquisition=extractor_expt_date) if expected_warn_msg: with pytest.warns(Warning, match=expected_warn_msg): obt_date.validate( stimulus_file=stimulus_file, behavior_session_id=test_params['behavior_session_id']) assert obt_date.value == extractor_expt_date
def test_stimulus_timestamps_from_json3(): """ Test that StimulusTimestamps.from_stimulus_file just returns the sum of the intervalsms field in the behavior stimulus pickle file, padded with a zero at the first timestamp. """ dir = Path(__file__).parent.parent.resolve() test_data_dir = dir / 'test_data' sf_path = test_data_dir / 'stimulus_file.pkl' sf = StimulusFile.from_json( dict_repr={'behavior_stimulus_file': str(sf_path)}) sf._data['items']['behavior']['intervalsms'] = [0.1, 0.2, 0.3, 0.4] stimulus_timestamps = StimulusTimestamps.from_stimulus_file( stimulus_file=sf) expected = np.array([0., 0.0001, 0.0003, 0.0006, 0.001]) np.testing.assert_array_almost_equal(stimulus_timestamps.value, expected, decimal=10)
def test_stimulus_file_to_json(stimulus_file_fixture): stim_pkl_path, stim_pkl_data = stimulus_file_fixture stimulus_file = StimulusFile(filepath=stim_pkl_path) obt_json = stimulus_file.to_json() assert obt_json == {"behavior_stimulus_file": str(stim_pkl_path)}
def from_lims(cls, behavior_session_id: int, lims_db: Optional[PostgresQueryMixin] = None, stimulus_timestamps: Optional[StimulusTimestamps] = None, monitor_delay: Optional[float] = None, date_of_acquisition: Optional[DateOfAcquisition] = None) \ -> "BehaviorSession": """ Parameters ---------- behavior_session_id Behavior session id lims_db Database connection. If not provided will create a new one. stimulus_timestamps Stimulus timestamps. If not provided, will calculate stimulus timestamps from stimulus file. monitor_delay Monitor delay. If not provided, will use an estimate. To provide this value, see for example allensdk.brain_observatory.behavior.data_objects.stimuli.util. calculate_monitor_delay date_of_acquisition Date of acquisition. If not provided, will read from behavior_sessions table. Returns ------- `BehaviorSession` instance """ if lims_db is None: lims_db = db_connection_creator( fallback_credentials=LIMS_DB_CREDENTIAL_MAP) behavior_session_id = BehaviorSessionId(behavior_session_id) stimulus_file = StimulusFile.from_lims( db=lims_db, behavior_session_id=behavior_session_id.value) if stimulus_timestamps is None: stimulus_timestamps = StimulusTimestamps.from_stimulus_file( stimulus_file=stimulus_file) running_acquisition = RunningAcquisition.from_lims( lims_db, behavior_session_id.value) raw_running_speed = RunningSpeed.from_lims( lims_db, behavior_session_id.value, filtered=False, stimulus_timestamps=stimulus_timestamps) running_speed = RunningSpeed.from_lims( lims_db, behavior_session_id.value, stimulus_timestamps=stimulus_timestamps) behavior_metadata = BehaviorMetadata.from_lims( behavior_session_id=behavior_session_id, lims_db=lims_db) if monitor_delay is None: monitor_delay = cls._get_monitor_delay() licks, rewards, stimuli, task_parameters, trials = \ cls._read_data_from_stimulus_file( stimulus_file=stimulus_file, stimulus_timestamps=stimulus_timestamps, trial_monitor_delay=monitor_delay ) if date_of_acquisition is None: date_of_acquisition = DateOfAcquisition.from_lims( behavior_session_id=behavior_session_id.value, lims_db=lims_db) date_of_acquisition = date_of_acquisition.validate( stimulus_file=stimulus_file, behavior_session_id=behavior_session_id.value) return BehaviorSession(behavior_session_id=behavior_session_id, stimulus_timestamps=stimulus_timestamps, running_acquisition=running_acquisition, raw_running_speed=raw_running_speed, running_speed=running_speed, metadata=behavior_metadata, licks=licks, rewards=rewards, stimuli=stimuli, task_parameters=task_parameters, trials=trials, date_of_acquisition=date_of_acquisition)
def _get_stimulus_data(): lims_db = db_connection_creator( fallback_credentials=LIMS_DB_CREDENTIAL_MAP) stimulus_file = StimulusFile.from_lims( db=lims_db, behavior_session_id=behavior_experiment_id) return stimulus_file.data
def test_from_stimulus_file(self): stimulus_file = StimulusFile.from_lims( behavior_session_id=self.behavior_session_id, db=self.dbconn) tp = TaskParameters.from_stimulus_file(stimulus_file=stimulus_file) assert tp == self.expected
def setup_class(cls): dir = Path(__file__).parent.parent.parent.resolve() test_data_dir = dir / 'test_data' sf_path = test_data_dir / 'stimulus_file.pkl' cls.stimulus_file = StimulusFile.from_json( dict_repr={'behavior_stimulus_file': str(sf_path)})