Пример #1
0
    def from_data_file(cls,
                       data_file: EyeTrackingFile,
                       sync_file: SyncFile,
                       z_threshold: float = 3.0,
                       dilation_frames: int = 2) -> "EyeTrackingTable":
        """
        Parameters
        ----------
        data_file
        sync_file
        z_threshold : float, optional
            See EyeTracking.from_lims
        dilation_frames : int, optional
             See EyeTracking.from_lims
        """
        cls._logger.info(f"Getting eye_tracking_data with "
                         f"'z_threshold={z_threshold}', "
                         f"'dilation_frames={dilation_frames}'")

        sync_path = Path(sync_file.filepath)

        frame_times = sync_utilities.get_synchronized_frame_times(
            session_sync_file=sync_path,
            sync_line_label_keys=Dataset.EYE_TRACKING_KEYS,
            trim_after_spike=False)

        eye_tracking_data = process_eye_tracking_data(data_file.data,
                                                      frame_times, z_threshold,
                                                      dilation_frames)
        return EyeTrackingTable(eye_tracking=eye_tracking_data)
Пример #2
0
def test_get_synchronized_frame_times(monkeypatch, mock_dataset_fixture,
                                      sync_line_label_keys, expected):
    monkeypatch.setattr(su, "Dataset", mock_dataset_fixture)

    obtained = su.get_synchronized_frame_times("dummy_path",
                                               sync_line_label_keys)
    assert np.allclose(obtained, expected)
Пример #3
0
def load_sync_file_timings(sync_file: Path,
                           pupil_params_rows: int) -> pd.Series:
    """Load sync file timings from .h5 file.

    Parameters
    ----------
    sync_file : Path
        Path to .h5 sync file.
    pupil_params_rows : int
        Number of rows in pupil params.

    Returns
    -------
    pd.Series
        A series of frame times. (New frame times according to synchronized
        timings from DAQ)

    Raises
    ------
    RuntimeError
        If the number of eye tracking frames (pupil_params_rows) does not match
        up with number of new frame times from the sync file.
    """
    # Add synchronized frame times
    frame_times = su.get_synchronized_frame_times(
        session_sync_file=sync_file,
        sync_line_label_keys=Dataset.EYE_TRACKING_KEYS)
    if (pupil_params_rows != len(frame_times)):
        raise RuntimeError("The number of camera sync pulses in the "
                           f"sync file ({len(frame_times)}) do not match "
                           "with the number of eye tracking frames "
                           f"({pupil_params_rows})!!!")
    return frame_times
Пример #4
0
    def get_eye_tracking(self,
                         z_threshold: float = 3.0,
                         dilation_frames: int = 2) -> Optional[pd.DataFrame]:
        """Gets corneal, eye, and pupil ellipse fit data

        Parameters
        ----------
        z_threshold : float, optional
            The z-threshold when determining which frames likely contain
            outliers for eye or pupil areas. Influences which frames
            are considered 'likely blinks'. By default 3.0
        dilation_frames : int, optional
             Determines the number of additional adjacent frames to mark as
            'likely_blink', by default 2.

        Returns
        -------
        Optional[pd.DataFrame]
            *_area
            *_center_x
            *_center_y
            *_height
            *_phi
            *_width
            likely_blink
        where "*" can be "corneal", "pupil" or "eye"

        Will return None if class attr _skip_eye_tracking is True.
        """
        if self._skip_eye_tracking:
            return None

        self.logger.info(f"Getting eye_tracking_data with "
                         f"'z_threshold={z_threshold}', "
                         f"'dilation_frames={dilation_frames}'")

        filepath = Path(self.extractor.get_eye_tracking_filepath())
        sync_path = Path(self.extractor.get_sync_file())

        eye_tracking_data = load_eye_tracking_hdf(filepath)
        frame_times = sync_utilities.get_synchronized_frame_times(
            session_sync_file=sync_path,
            sync_line_label_keys=Dataset.EYE_TRACKING_KEYS,
            trim_after_spike=False)

        eye_tracking_data = process_eye_tracking_data(eye_tracking_data,
                                                      frame_times,
                                                      z_threshold,
                                                      dilation_frames)

        return eye_tracking_data
Пример #5
0
    def get_eye_tracking(self,
                         z_threshold: float = 3.0,
                         dilation_frames: int = 2):
        logger = logging.getLogger("BehaviorOphysLimsApi")

        logger.info(f"Getting eye_tracking_data with "
                    f"'z_threshold={z_threshold}', "
                    f"'dilation_frames={dilation_frames}'")

        filepath = Path(self.get_eye_tracking_filepath())
        sync_path = Path(self.get_sync_file())

        eye_tracking_data = load_eye_tracking_hdf(filepath)
        frame_times = sync_utilities.get_synchronized_frame_times(
            session_sync_file=sync_path,
            sync_line_label_keys=Dataset.EYE_TRACKING_KEYS)

        eye_tracking_data = process_eye_tracking_data(eye_tracking_data,
                                                      frame_times, z_threshold,
                                                      dilation_frames)

        return eye_tracking_data
Пример #6
0
def write_ecephys_nwb(output_path,
                      session_id,
                      session_start_time,
                      stimulus_table_path,
                      invalid_epochs,
                      probes,
                      running_speed_path,
                      session_sync_path,
                      eye_tracking_rig_geometry,
                      eye_dlc_ellipses_path,
                      eye_gaze_mapping_path,
                      pool_size,
                      optotagging_table_path=None,
                      session_metadata=None,
                      **kwargs):

    nwbfile = pynwb.NWBFile(
        session_description='Data and metadata for an Ecephys session',
        identifier=f"{session_id}",
        session_id=f"{session_id}",
        session_start_time=session_start_time,
        institution="Allen Institute for Brain Science")

    if session_metadata is not None:
        nwbfile = add_metadata_to_nwbfile(nwbfile, session_metadata)

    stimulus_columns_to_drop = [
        "colorSpace", "depth", "interpolate", "pos", "rgbPedestal", "tex",
        "texRes", "flipHoriz", "flipVert", "rgb", "signalDots"
    ]
    stimulus_table = read_stimulus_table(
        stimulus_table_path, columns_to_drop=stimulus_columns_to_drop)
    nwbfile = add_stimulus_timestamps(
        nwbfile, stimulus_table['start_time'].values
    )  # TODO: patch until full timestamps are output by stim table module
    nwbfile = add_stimulus_presentations(nwbfile, stimulus_table)
    nwbfile = add_invalid_times(nwbfile, invalid_epochs)

    if optotagging_table_path is not None:
        optotagging_table = pd.read_csv(optotagging_table_path)
        nwbfile = add_optotagging_table_to_nwbfile(nwbfile, optotagging_table)

    nwbfile = add_probewise_data_to_nwbfile(nwbfile, probes)

    running_speed, raw_running_data = read_running_speed(running_speed_path)
    add_running_speed_to_nwbfile(nwbfile, running_speed)
    add_raw_running_data_to_nwbfile(nwbfile, raw_running_data)

    add_eye_tracking_rig_geometry_data_to_nwbfile(nwbfile,
                                                  eye_tracking_rig_geometry)

    # Collect eye tracking/gaze mapping data from files
    eye_tracking_frame_times = su.get_synchronized_frame_times(
        session_sync_file=session_sync_path,
        sync_line_label_keys=Dataset.EYE_TRACKING_KEYS)
    eye_dlc_tracking_data = read_eye_dlc_tracking_ellipses(
        Path(eye_dlc_ellipses_path))
    if eye_gaze_mapping_path:
        eye_gaze_data = read_eye_gaze_mappings(Path(eye_gaze_mapping_path))
    else:
        eye_gaze_data = None

    add_eye_tracking_data_to_nwbfile(nwbfile, eye_tracking_frame_times,
                                     eye_dlc_tracking_data, eye_gaze_data)

    Manifest.safe_make_parent_dirs(output_path)
    with pynwb.NWBHDF5IO(output_path, mode='w') as io:
        logging.info(f"writing session nwb file to {output_path}")
        io.write(nwbfile, cache_spec=True)

    probes_with_lfp = [p for p in probes if p["lfp"] is not None]
    probe_outputs = write_probewise_lfp_files(probes_with_lfp,
                                              session_id,
                                              session_metadata,
                                              session_start_time,
                                              pool_size=pool_size)

    return {'nwb_path': output_path, "probe_outputs": probe_outputs}
Пример #7
0
def write_ecephys_nwb(output_path,
                      session_id,
                      session_start_time,
                      stimulus_table_path,
                      invalid_epochs,
                      probes,
                      running_speed_path,
                      session_sync_path,
                      eye_tracking_rig_geometry,
                      eye_dlc_ellipses_path,
                      eye_gaze_mapping_path,
                      pool_size,
                      optotagging_table_path=None,
                      session_metadata=None,
                      **kwargs):

    nwbfile = pynwb.NWBFile(session_description='EcephysSession',
                            identifier='{}'.format(session_id),
                            session_start_time=session_start_time)

    if session_metadata is not None:
        nwbfile = add_metadata_to_nwbfile(nwbfile, session_metadata)

    stimulus_table = read_stimulus_table(stimulus_table_path)
    nwbfile = add_stimulus_timestamps(
        nwbfile, stimulus_table['start_time'].values
    )  # TODO: patch until full timestamps are output by stim table module
    nwbfile = add_stimulus_presentations(nwbfile, stimulus_table)
    nwbfile = add_invalid_times(nwbfile, invalid_epochs)

    if optotagging_table_path is not None:
        optotagging_table = pd.read_csv(optotagging_table_path)
        nwbfile = add_optotagging_table_to_nwbfile(nwbfile, optotagging_table)

    nwbfile = add_probewise_data_to_nwbfile(nwbfile, probes)

    running_speed, raw_running_data = read_running_speed(running_speed_path)
    add_running_speed_to_nwbfile(nwbfile, running_speed)
    add_raw_running_data_to_nwbfile(nwbfile, raw_running_data)

    # --- Add eye tracking ellipse fits to nwb file ---
    eye_tracking_frame_times = su.get_synchronized_frame_times(
        session_sync_file=session_sync_path,
        sync_line_label_keys=Dataset.EYE_TRACKING_KEYS)
    eye_dlc_tracking_data = read_eye_dlc_tracking_ellipses(
        Path(eye_dlc_ellipses_path))

    if eye_tracking_data_is_valid(eye_dlc_tracking_data=eye_dlc_tracking_data,
                                  synced_timestamps=eye_tracking_frame_times):
        add_eye_tracking_ellipse_fit_data_to_nwbfile(
            nwbfile,
            eye_dlc_tracking_data=eye_dlc_tracking_data,
            synced_timestamps=eye_tracking_frame_times)

        # --- Append eye tracking rig geometry info to nwb file (with eye tracking) ---
        append_eye_tracking_rig_geometry_data_to_nwbfile(
            nwbfile, eye_tracking_rig_geometry=eye_tracking_rig_geometry)

        # --- Add gaze mapped positions to nwb file ---
        if eye_gaze_mapping_path:
            eye_gaze_data = read_eye_gaze_mappings(Path(eye_gaze_mapping_path))
            add_eye_gaze_mapping_data_to_nwbfile(nwbfile,
                                                 eye_gaze_data=eye_gaze_data)

    Manifest.safe_make_parent_dirs(output_path)
    io = pynwb.NWBHDF5IO(output_path, mode='w')
    logging.info(f"writing session nwb file to {output_path}")
    io.write(nwbfile)
    io.close()

    probes_with_lfp = [p for p in probes if p["lfp"] is not None]
    probe_outputs = write_probewise_lfp_files(probes_with_lfp,
                                              session_start_time,
                                              pool_size=pool_size)

    return {'nwb_path': output_path, "probe_outputs": probe_outputs}