def add_eye_tracking_rig_geometry_data_to_nwbfile( nwbfile: NWBFile, eye_tracking_rig_geometry: dict) -> NWBFile: """ Rig geometry dict should consist of the following fields: monitor_position_mm: [x, y, z] monitor_rotation_deg: [x, y, z] camera_position_mm: [x, y, z] camera_rotation_deg: [x, y, z] led_position: [x, y, z] equipment: A string describing rig """ eye_tracking_rig_mod = pynwb.ProcessingModule( name='eye_tracking_rig_metadata', description='Eye tracking rig metadata module') ophys_eye_tracking_rig_metadata = load_pynwb_extension( OphysEyeTrackingRigMetadataSchema, 'ndx-aibs-behavior-ophys') rig_metadata = ophys_eye_tracking_rig_metadata( name="eye_tracking_rig_metadata", equipment=eye_tracking_rig_geometry['equipment'], monitor_position=eye_tracking_rig_geometry['monitor_position_mm'], monitor_position__unit_of_measurement="mm", camera_position=eye_tracking_rig_geometry['camera_position_mm'], camera_position__unit_of_measurement="mm", led_position=eye_tracking_rig_geometry['led_position'], led_position__unit_of_measurement="mm", monitor_rotation=eye_tracking_rig_geometry['monitor_rotation_deg'], monitor_rotation__unit_of_measurement="deg", camera_rotation=eye_tracking_rig_geometry['camera_rotation_deg'], camera_rotation__unit_of_measurement="deg") eye_tracking_rig_mod.add_data_interface(rig_metadata) nwbfile.add_processing_module(eye_tracking_rig_mod) return nwbfile
def add_metadata(nwbfile, metadata: dict): # Rename incoming metadata fields to conform with pynwb Subject fields metadata = metadata.copy() metadata["subject_id"] = metadata.pop("LabTracks_ID") metadata["genotype"] = metadata.pop("full_genotype") metadata_clean = CompleteOphysBehaviorMetadataSchema().dump(metadata) # Subject related metadata should be saved to our BehaviorSubject # (augmented pyNWB 'Subject') NWB class subject_fields = {"age", "driver_line", "genotype", "subject_id", "reporter_line", "sex"} subject_metadata = {k: v for k, v in metadata_clean.items() if k in subject_fields} for subject_key in subject_metadata.keys(): metadata_clean.pop(subject_key, None) BehaviorSubject = load_pynwb_extension(SubjectMetadataSchema, 'ndx-aibs-behavior-ophys') nwb_subject = BehaviorSubject( description="A visual behavior subject with a LabTracks ID", age=subject_metadata["age"], driver_line=subject_metadata["driver_line"], genotype=subject_metadata["genotype"], subject_id=str(subject_metadata["subject_id"]), reporter_line=subject_metadata["reporter_line"], sex=subject_metadata["sex"], species='Mus musculus') nwbfile.subject = nwb_subject # Remove metadata that will go into pyNWB base classes for key in OphysBehaviorMetadataSchema.neurodata_skip: metadata_clean.pop(key, None) # Remaining metadata can go into our custom extension new_metadata_dict = {} for key, val in metadata_clean.items(): if isinstance(val, list): new_metadata_dict[key] = np.array(val) elif isinstance(val, (datetime.datetime, uuid.UUID)): new_metadata_dict[key] = str(val) else: new_metadata_dict[key] = val OphysBehaviorMetadata = load_pynwb_extension(OphysBehaviorMetadataSchema, 'ndx-aibs-behavior-ophys') nwb_metadata = OphysBehaviorMetadata(name='metadata', **new_metadata_dict) nwbfile.add_lab_meta_data(nwb_metadata)
def add_task_parameters(nwbfile, task_parameters): OphysBehaviorTaskParameters = load_pynwb_extension( BehaviorTaskParametersSchema, 'ndx-aibs-behavior-ophys') task_parameters_clean = BehaviorTaskParametersSchema().dump( task_parameters) new_task_parameters_dict = {} for key, val in task_parameters_clean.items(): if isinstance(val, list): new_task_parameters_dict[key] = np.array(val) else: new_task_parameters_dict[key] = val nwb_task_parameters = OphysBehaviorTaskParameters( name='task_parameters', **new_task_parameters_dict) nwbfile.add_lab_meta_data(nwb_task_parameters)
BehaviorTaskParametersSchema, OphysEyeTrackingRigMetadataSchema) from allensdk.brain_observatory.behavior.trials_processing import ( TRIAL_COLUMN_DESCRIPTION_DICT) from allensdk.brain_observatory.nwb import TimeSeries from allensdk.brain_observatory.nwb.eye_tracking.ndx_ellipse_eye_tracking import ( # noqa: E501 EllipseEyeTracking, EllipseSeries) from allensdk.brain_observatory.behavior.write_nwb.extensions \ .event_detection.ndx_ophys_events import OphysEventDetection from allensdk.brain_observatory.nwb.metadata import load_pynwb_extension from allensdk.brain_observatory.behavior.session_apis.data_io import ( BehaviorNwbApi) from allensdk.brain_observatory.nwb.nwb_utils import set_omitted_stop_time from allensdk.brain_observatory.behavior.eye_tracking_processing import ( determine_outliers, determine_likely_blinks) load_pynwb_extension(BehaviorTaskParametersSchema, 'ndx-aibs-behavior-ophys') class BehaviorOphysNwbApi(BehaviorNwbApi, BehaviorOphysBase): """A data fetching class that serves as an API for fetching 'raw' data from an NWB file that is both necessary and sufficient for filling a 'BehaviorOphysSession'. """ def __init__(self, *args, **kwargs): self.filter_invalid_rois = kwargs.pop("filter_invalid_rois", False) super().__init__(*args, **kwargs) def save(self, session_object): # Cannot type session_object due to a circular dependency # TODO fix circular dependency and add type
def add_metadata(nwbfile, metadata: dict, behavior_only: bool): # Rename or reformat incoming metadata fields to conform with pynwb fields tmp_metadata = metadata.copy() tmp_metadata["subject_id"] = tmp_metadata.pop("mouse_id") tmp_metadata["genotype"] = tmp_metadata.pop("full_genotype") if not behavior_only: imaging_plane_group = metadata["imaging_plane_group"] if imaging_plane_group is None: tmp_metadata["imaging_plane_group"] = -1 else: tmp_metadata["imaging_plane_group"] = imaging_plane_group metadata_clean = CompleteOphysBehaviorMetadataSchema().dump(tmp_metadata) # Subject related metadata should be saved to our BehaviorSubject # (augmented pyNWB 'Subject') NWB class subject_fields = { "age_in_days", "driver_line", "genotype", "subject_id", "reporter_line", "sex" } subject_metadata = { k: v for k, v in metadata_clean.items() if k in subject_fields } for subject_key in subject_metadata.keys(): metadata_clean.pop(subject_key, None) BehaviorSubject = load_pynwb_extension(SubjectMetadataSchema, 'ndx-aibs-behavior-ophys') def _get_age(age_in_days: Optional[int]) -> Optional[str]: """Convert numeric age_in_days to ISO 8601""" if age_in_days is None: return 'null' return f'P{age_in_days}D' nwb_subject = BehaviorSubject( description="A visual behavior subject with a LabTracks ID", age=_get_age(age_in_days=subject_metadata['age_in_days']), driver_line=subject_metadata["driver_line"], genotype=subject_metadata["genotype"], subject_id=str(subject_metadata["subject_id"]), reporter_line=subject_metadata["reporter_line"], sex=subject_metadata["sex"], species='Mus musculus') nwbfile.subject = nwb_subject # Remove metadata that will go into pyNWB base classes for key in OphysBehaviorMetadataSchema.neurodata_skip: metadata_clean.pop(key, None) # Remaining metadata can go into our custom extension new_metadata_dict = {} for key, val in metadata_clean.items(): if isinstance(val, list): new_metadata_dict[key] = np.array(val) elif isinstance(val, (datetime.datetime, uuid.UUID)): new_metadata_dict[key] = str(val) else: new_metadata_dict[key] = val if behavior_only: BehaviorMetadata = load_pynwb_extension(BehaviorMetadataSchema, 'ndx-aibs-behavior-ophys') nwb_metadata = BehaviorMetadata(name='metadata', **new_metadata_dict) else: OphysBehaviorMetadata = load_pynwb_extension( OphysBehaviorMetadataSchema, 'ndx-aibs-behavior-ophys') nwb_metadata = OphysBehaviorMetadata(name='metadata', **new_metadata_dict) nwbfile.add_lab_meta_data(nwb_metadata)