Source code for allensdk.brain_observatory.behavior.validation

import h5py
import os

from allensdk.internal.api.behavior_ophys_api import BehaviorOphysLimsApi
from allensdk.internal.api.ophys_lims_api import OphysLimsApi
from allensdk.brain_observatory.behavior.behavior_ophys_session import BehaviorOphysSession

[docs]class ValidationError(AssertionError): pass
[docs]def get_raw_ophys_file_shape(raw_filepath): with h5py.File(raw_filepath, 'r') as raw_file: raw_data_shape = raw_file['data'].shape return raw_data_shape
[docs]def validate_ophys_dff_length(ophys_experiment_id, api=None): api = OphysLimsApi() if api is None else api ophys_experiment_dir = api.get_ophys_experiment_dir(ophys_experiment_id) raw_filepath = os.path.join(ophys_experiment_dir, str(ophys_experiment_id)+'.h5') raw_data_shape = get_raw_ophys_file_shape(raw_filepath) dff_filepath = api.get_dff_file(ophys_experiment_id=ophys_experiment_id) dff_shape = get_raw_ophys_file_shape(dff_filepath) if raw_data_shape[0] != dff_shape[1]: raise ValidationError('dff length does not match raw data length')
[docs]def validate_ophys_timestamps(ophys_experiment_id, api=None): api = BehaviorOphysLimsApi() if api is None else api ophys_experiment_dir = api.get_ophys_experiment_dir(ophys_experiment_id) raw_filepath = os.path.join(ophys_experiment_dir, str(ophys_experiment_id)+'.h5') raw_data_shape = get_raw_ophys_file_shape(raw_filepath) ophys_timestamps_shape = api.get_ophys_timestamps(ophys_experiment_id=ophys_experiment_id).shape if raw_data_shape[0] != ophys_timestamps_shape[0]: raise ValidationError('ophys_timestamp length does not match raw data length')
[docs]def validate_last_trial_ends_adjacent_to_flash(ophys_experiment_id, api=None, verbose=False): # ensure that the last trial ends sometime on the last flash/blank cycle # i.e, if this is the last flash/blank iteration (high = stimulus present): # ------- ------- ------- ------- # | | | | | | | | # --------- --------- --------- --------- ------------------------------------------- # ^ ^ # The last trial has to have ended somewhere between the two carrots where: # the first carrot represents the time of the last recorded stimulus flash # the second carrot represents the time at which another flash should have started, after accounting for the possibility of the session ending on an omitted flash api = BehaviorOphysLimsApi() if api is None else api session = BehaviorOphysSession(api) # get the flash/blank parameters max_flash_duration = session.stimulus_presentations['duration'].max() max_blank_duration = session.task_parameters['blank_duration_sec'][1] # count number of omitted flashes at the very end of the session N_final_omitted_flashes = session.stimulus_presentations.index.max() - session.stimulus_presentations.query('omitted == False').index.max() # get the start/end time of the last valid (non-omitted) flash last_flash_start = session.stimulus_presentations.query('omitted == False')['start_time'].iloc[-1] last_flash_end = session.stimulus_presentations.query('omitted == False')['stop_time'].iloc[-1] # calculate when the next stimulus should have flashed, after accounting for any omitted flashes at the end of the session next_flash_would_have_started = last_flash_end + max_blank_duration + N_final_omitted_flashes*(max_flash_duration + max_blank_duration) # get the end time of the last trial last_trial_end = session.trials.iloc[-1]['stop_time'] if verbose: print('last flash ended at {}'.format(last_flash_end)) print('another flash should have started by {}'.format(next_flash_would_have_started)) print('last trial ended at {}'.format(last_trial_end)) if not last_flash_start <= last_trial_end <= next_flash_would_have_started: raise ValidationError('The last trial does not end between the start of the last flash and the expected start time of the next flash')
if __name__ == "__main__": api = BehaviorOphysLimsApi() ophys_experiment_id_list = [775614751, 778644591, 787461073, 782675436, 783928214, 783927872, 787501821, 787498309, 788490510, 788488596, 788489531, 789359614, 790149413, 790709081, 791119849, 791453282, 791980891, 792813858, 792812544, 792816531, 792815735, 794381992, 794378505, 795076128, 795073741, 795952471, 795952488, 795953296, 795948257, 796106850, 796106321, 796108483, 796105823, 796308505, 797255551, 795075034, 798403387, 798404219, 799366517, 799368904, 799368262, 803736273, 805100431, 805784331, 805784313, 806456687, 806455766, 806989729, 807753318, 807752719, 807753334, 807753920, 796105304, 784482326, 779335436, 782675457, 791974731, 791979236, 800034837, 802649986, 806990245, 808621958, 808619526, 808619543, 808621034, 808621015] for ophys_experiment_id in ophys_experiment_id_list: validation_functions_to_run = [ validate_ophys_timestamps, validate_ophys_dff_length, validate_last_trial_ends_adjacent_to_flash, ] for validation_function in validation_functions_to_run: try: validation_function(ophys_experiment_id, api=api) except ValidationError as e: print(ophys_experiment_id, e)