Exemplo n.º 1
0
def write_behavior_nwb(session_data, nwb_filepath):

    nwb_filepath_inprogress = nwb_filepath+'.inprogress'
    nwb_filepath_error = nwb_filepath+'.error'

    # Clean out files from previous runs:
    for filename in [nwb_filepath_inprogress,
                     nwb_filepath_error,
                     nwb_filepath]:
        if os.path.exists(filename):
            os.remove(filename)

    try:
        json_session = BehaviorSession(api=BehaviorJsonApi(session_data))
        lims_api = BehaviorLimsApi(
            behavior_session_id=session_data['behavior_session_id'])
        lims_session = BehaviorSession(api=lims_api)

        logging.info("Comparing a BehaviorSession created from JSON "
                     "with a BehaviorSession created from LIMS")
        assert sessions_are_equal(json_session, lims_session, reraise=True)

        BehaviorNwbApi(nwb_filepath_inprogress).save(json_session)

        logging.info("Comparing a BehaviorSession created from JSON "
                     "with a BehaviorSession created from NWB")
        nwb_api = BehaviorNwbApi(nwb_filepath_inprogress)
        nwb_session = BehaviorSession(api=nwb_api)
        assert sessions_are_equal(json_session, nwb_session, reraise=True)

        os.rename(nwb_filepath_inprogress, nwb_filepath)
        return {'output_path': nwb_filepath}
    except Exception as e:
        os.rename(nwb_filepath_inprogress, nwb_filepath_error)
        raise e
Exemplo n.º 2
0
 def get_behavior_session(self,
                          behavior_session_id: int) -> BehaviorSession:
     """Returns a BehaviorSession object that contains methods to
     analyze a single behavior session.
     :param behavior_session_id: id that corresponds to a behavior session
     :type behavior_session_id: int
     :rtype: BehaviorSession
     """
     return BehaviorSession(BehaviorLimsApi(behavior_session_id))
Exemplo n.º 3
0
def test_behavior_session_list_data_attributes_and_methods():
    # Test that data related methods/attributes/properties for
    # BehaviorSession are returned properly.

    # This test will need to be updated if:
    # 1. Data being returned by class has changed
    # 2. Inheritance of class has changed
    expected = {
        'behavior_session_id', 'get_performance_metrics', 'get_reward_rate',
        'get_rolling_performance_df', 'licks', 'metadata', 'raw_running_speed',
        'rewards', 'running_speed', 'stimulus_presentations',
        'stimulus_templates', 'stimulus_timestamps', 'task_parameters',
        'trials'
    }

    behavior_session = BehaviorSession(api=MagicMock())
    obt = behavior_session.list_data_attributes_and_methods()

    assert any(expected ^ set(obt)) is False
Exemplo n.º 4
0
def test_behavior_session_list_data_attributes_and_methods(monkeypatch):
    """Test that data related methods/attributes/properties for
    BehaviorSession are returned properly."""
    def dummy_init(self):
        pass

    with monkeypatch.context() as ctx:
        ctx.setattr(BehaviorSession, '__init__', dummy_init)
        bs = BehaviorSession()
        obt = bs.list_data_attributes_and_methods()

    expected = {
        'behavior_session_id', 'get_performance_metrics', 'get_reward_rate',
        'get_rolling_performance_df', 'licks', 'metadata', 'raw_running_speed',
        'rewards', 'running_speed', 'stimulus_presentations',
        'stimulus_templates', 'stimulus_timestamps', 'task_parameters',
        'trials'
    }

    assert any(expected ^ set(obt)) is False
Exemplo n.º 5
0
def write_behavior_nwb(session_data, nwb_filepath):

    nwb_filepath_inprogress = nwb_filepath + '.inprogress'
    nwb_filepath_error = nwb_filepath + '.error'

    # Clean out files from previous runs:
    for filename in [
            nwb_filepath_inprogress, nwb_filepath_error, nwb_filepath
    ]:
        if os.path.exists(filename):
            os.remove(filename)

    try:
        json_session = BehaviorSession.from_json(session_data)

        behavior_session_id = session_data['behavior_session_id']
        lims_session = BehaviorSession.from_lims(behavior_session_id)

        logging.info("Comparing a BehaviorSession created from JSON "
                     "with a BehaviorSession created from LIMS")
        assert sessions_are_equal(json_session, lims_session, reraise=True)

        nwbfile = lims_session.to_nwb()
        with NWBHDF5IO(nwb_filepath_inprogress, 'w') as nwb_file_writer:
            nwb_file_writer.write(nwbfile)

        logging.info("Comparing a BehaviorSession created from JSON "
                     "with a BehaviorSession created from NWB")
        nwb_session = BehaviorSession.from_nwb_path(nwb_filepath_inprogress)
        assert sessions_are_equal(json_session, nwb_session, reraise=True)

        os.rename(nwb_filepath_inprogress, nwb_filepath)
        return {'output_path': nwb_filepath}
    except Exception as e:
        if os.path.isfile(nwb_filepath_inprogress):
            os.rename(nwb_filepath_inprogress, nwb_filepath_error)
        raise e
    def get_behavior_session(self,
                             behavior_session_id: int) -> BehaviorSession:
        """get a BehaviorSession by specifying behavior_session_id

        Parameters
        ----------
        behavior_session_id: int
            the id of the behavior_session

        Returns
        -------
        BehaviorSession

        Notes
        -----
        entries in the _behavior_session_table represent
        (1) ophys_sessions which have a many-to-one mapping between nwb files
        and behavior sessions. (file_id is NaN)
        AND
        (2) behavior only sessions, which have a one-to-one mapping with
        nwb files. (file_id is not Nan)
        In the case of (1) this method returns an object which is just behavior
        data which is shared by all experiments in 1 session. This is extracted
        from the nwb file for the first-listed ophys_experiment.

        """
        row = self._behavior_session_table.query(
            f"behavior_session_id=={behavior_session_id}")
        if row.shape[0] != 1:
            raise RuntimeError("The behavior_session_table should have "
                               "1 and only 1 entry for a given "
                               "behavior_session_id. For "
                               f"{behavior_session_id} "
                               f" there are {row.shape[0]} entries.")
        row = row.squeeze()
        has_file_id = not pd.isna(row[self.cache.file_id_column])
        if not has_file_id:
            oeid = row.ophys_experiment_id[0]
            row = self._ophys_experiment_table.query(f"index=={oeid}")
        file_id = str(int(row[self.cache.file_id_column]))
        data_path = self._get_data_path(file_id=file_id)
        return BehaviorSession.from_nwb_path(str(data_path))
def test_eye_tracking(dilation_frames, z_threshold, monkeypatch):
    """A very long test just to test that eye tracking arguments are sent to
    EyeTrackingTable factory method from BehaviorOphysExperiment.from_lims"""
    expected = EyeTrackingTable(eye_tracking=pd.DataFrame([1, 2, 3]))
    EyeTrackingTable_mock = create_autospec(EyeTrackingTable)
    EyeTrackingTable_mock.from_data_file.return_value = expected

    etf = create_autospec(EyeTrackingFile, instance=True)
    sf = create_autospec(SyncFile, instance=True)

    with monkeypatch.context() as ctx:
        ctx.setattr(
            'allensdk.brain_observatory.behavior.'
            'behavior_ophys_experiment.db_connection_creator',
            create_autospec(db_connection_creator, instance=True))
        ctx.setattr(SyncFile, 'from_lims', lambda db, ophys_experiment_id: sf)
        ctx.setattr(
            StimulusTimestamps, 'from_sync_file',
            lambda sync_file: create_autospec(StimulusTimestamps,
                                              instance=True))
        ctx.setattr(
            BehaviorSessionId, 'from_lims',
            lambda db, ophys_experiment_id: create_autospec(BehaviorSessionId,
                                                            instance=True))
        ctx.setattr(ImagingPlaneGroup, 'from_lims',
                    lambda lims_db, ophys_experiment_id: None)
        ctx.setattr(
            BehaviorOphysMetadata, 'from_lims',
            lambda lims_db, ophys_experiment_id, is_multiplane:
            create_autospec(BehaviorOphysMetadata, instance=True))
        ctx.setattr(
            'allensdk.brain_observatory.behavior.'
            'behavior_ophys_experiment.calculate_monitor_delay',
            create_autospec(calculate_monitor_delay))
        ctx.setattr(
            DateOfAcquisitionOphys, 'from_lims',
            lambda lims_db, ophys_experiment_id: create_autospec(
                DateOfAcquisitionOphys, instance=True))
        ctx.setattr(
            BehaviorSession, 'from_lims',
            lambda lims_db, behavior_session_id, stimulus_timestamps,
            monitor_delay, date_of_acquisition: BehaviorSession(
                behavior_session_id=None,
                stimulus_timestamps=None,
                running_acquisition=None,
                raw_running_speed=None,
                running_speed=None,
                licks=None,
                rewards=None,
                stimuli=None,
                task_parameters=None,
                trials=None,
                metadata=None,
                date_of_acquisition=None,
            ))
        ctx.setattr(
            OphysTimestamps, 'from_sync_file',
            lambda sync_file: create_autospec(OphysTimestamps, instance=True))
        ctx.setattr(
            Projections, 'from_lims', lambda lims_db, ophys_experiment_id:
            create_autospec(Projections, instance=True))
        ctx.setattr(
            CellSpecimens, 'from_lims', lambda lims_db, ophys_experiment_id,
            ophys_timestamps, segmentation_mask_image_spacing, events_params,
            exclude_invalid_rois: create_autospec(BehaviorSession,
                                                  instance=True))
        ctx.setattr(
            RigidMotionTransformFile, 'from_lims',
            lambda db, ophys_experiment_id: create_autospec(
                RigidMotionTransformFile, instance=True))
        ctx.setattr(EyeTrackingFile, 'from_lims',
                    lambda db, ophys_experiment_id: etf)
        ctx.setattr(
            EyeTrackingTable, 'from_data_file', lambda data_file, sync_file,
            z_threshold, dilation_frames: EyeTrackingTable_mock.from_data_file(
                data_file=data_file,
                sync_file=sync_file,
                z_threshold=z_threshold,
                dilation_frames=dilation_frames))
        ctx.setattr(
            EyeTrackingRigGeometry, 'from_lims',
            lambda lims_db, ophys_experiment_id: create_autospec(
                EyeTrackingRigGeometry, instance=True))
        boe = BehaviorOphysExperiment.from_lims(
            ophys_experiment_id=1,
            eye_tracking_z_threshold=z_threshold,
            eye_tracking_dilation_frames=dilation_frames)

        obtained = boe.eye_tracking
        assert obtained.equals(expected.value)
        EyeTrackingTable_mock.from_data_file.assert_called_with(
            data_file=etf,
            sync_file=sf,
            z_threshold=z_threshold,
            dilation_frames=dilation_frames)
Exemplo n.º 8
0
    def __init__(self,
                 api=None,
                 eye_tracking_z_threshold: float = 3.0,
                 eye_tracking_dilation_frames: int = 2,
                 events_filter_scale: float = 2.0,
                 events_filter_n_time_steps: int = 20):
        """
        Parameters
        ----------
        api : object, optional
            The backend api used by the session object to get behavior ophys
            data, by default None.
        eye_tracking_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
        eye_tracking_dilation_frames : int, optional
            Determines the number of adjacent frames that will be marked
            as 'likely_blink' when performing blink detection for
            `eye_tracking` data, by default 2
        events_filter_scale : float, optional
            Stdev of halfnorm distribution used to convolve ophys events with
            a 1d causal half-gaussian filter to smooth it for visualization,
            by default 2.0
        events_filter_n_time_steps : int, optional
            Number of time steps to use for convolution of ophys events
        """

        BehaviorSession.__init__(self, api=api)
        ParamsMixin.__init__(self, ignore={'api'})

        # eye_tracking processing params
        self._eye_tracking_z_threshold = eye_tracking_z_threshold
        self._eye_tracking_dilation_frames = eye_tracking_dilation_frames

        # events processing params
        self._events_filter_scale = events_filter_scale
        self._events_filter_n_time_steps = events_filter_n_time_steps

        # LazyProperty constructor provided by LazyPropertyMixin
        LazyProperty = self.LazyProperty

        # Initialize attributes to be lazily evaluated
        self._ophys_session_id = LazyProperty(self.api.get_ophys_session_id)
        self._ophys_experiment_id = LazyProperty(
            self.api.get_ophys_experiment_id)
        self._max_projection = LazyProperty(self.api.get_max_projection,
                                            wrappers=[ImageApi.deserialize])
        self._average_projection = LazyProperty(
            self.api.get_average_projection, wrappers=[ImageApi.deserialize])
        self._ophys_timestamps = LazyProperty(self.api.get_ophys_timestamps,
                                              settable=True)
        self._dff_traces = LazyProperty(self.api.get_dff_traces, settable=True)
        self._events = LazyProperty(self.api.get_events, settable=True)
        self._cell_specimen_table = LazyProperty(
            self.api.get_cell_specimen_table, settable=True)
        self._corrected_fluorescence_traces = LazyProperty(
            self.api.get_corrected_fluorescence_traces, settable=True)
        self._motion_correction = LazyProperty(self.api.get_motion_correction,
                                               settable=True)
        self._segmentation_mask_image = LazyProperty(
            self.get_segmentation_mask_image)
        self._eye_tracking = LazyProperty(
            self.api.get_eye_tracking,
            settable=True,
            z_threshold=self._eye_tracking_z_threshold,
            dilation_frames=self._eye_tracking_dilation_frames)
        self._eye_tracking_rig_geometry = LazyProperty(
            self.api.get_eye_tracking_rig_geometry)
    def from_json(cls,
                  session_data: dict,
                  eye_tracking_z_threshold: float = 3.0,
                  eye_tracking_dilation_frames: int = 2,
                  events_filter_scale: float = 2.0,
                  events_filter_n_time_steps: int = 20,
                  exclude_invalid_rois=True,
                  skip_eye_tracking=False) -> \
            "BehaviorOphysExperiment":
        """

        Parameters
        ----------
        session_data
        eye_tracking_z_threshold
            See `BehaviorOphysExperiment.from_nwb`
        eye_tracking_dilation_frames
            See `BehaviorOphysExperiment.from_nwb`
        events_filter_scale
            See `BehaviorOphysExperiment.from_nwb`
        events_filter_n_time_steps
            See `BehaviorOphysExperiment.from_nwb`
        exclude_invalid_rois
            Whether to exclude invalid rois
        skip_eye_tracking
            Used to skip returning eye tracking data

        """
        def _is_multi_plane_session():
            imaging_plane_group_meta = ImagingPlaneGroup.from_json(
                dict_repr=session_data)
            return cls._is_multi_plane_session(
                imaging_plane_group_meta=imaging_plane_group_meta)

        def _get_motion_correction():
            rigid_motion_transform_file = RigidMotionTransformFile.from_json(
                dict_repr=session_data)
            return MotionCorrection.from_data_file(
                rigid_motion_transform_file=rigid_motion_transform_file)

        def _get_eye_tracking_table(sync_file: SyncFile):
            eye_tracking_file = EyeTrackingFile.from_json(
                dict_repr=session_data)
            eye_tracking_table = EyeTrackingTable.from_data_file(
                data_file=eye_tracking_file,
                sync_file=sync_file,
                z_threshold=eye_tracking_z_threshold,
                dilation_frames=eye_tracking_dilation_frames)
            return eye_tracking_table

        sync_file = SyncFile.from_json(dict_repr=session_data)
        is_multiplane_session = _is_multi_plane_session()
        meta = BehaviorOphysMetadata.from_json(
            dict_repr=session_data, is_multiplane=is_multiplane_session)
        monitor_delay = calculate_monitor_delay(
            sync_file=sync_file, equipment=meta.behavior_metadata.equipment)
        behavior_session = BehaviorSession.from_json(
            session_data=session_data, monitor_delay=monitor_delay)

        if is_multiplane_session:
            ophys_timestamps = OphysTimestampsMultiplane.from_sync_file(
                sync_file=sync_file,
                group_count=meta.ophys_metadata.imaging_plane_group_count,
                plane_group=meta.ophys_metadata.imaging_plane_group)
        else:
            ophys_timestamps = OphysTimestamps.from_sync_file(
                sync_file=sync_file)

        projections = Projections.from_json(dict_repr=session_data)
        cell_specimens = CellSpecimens.from_json(
            dict_repr=session_data,
            ophys_timestamps=ophys_timestamps,
            segmentation_mask_image_spacing=projections.max_projection.spacing,
            events_params=EventsParams(
                filter_scale=events_filter_scale,
                filter_n_time_steps=events_filter_n_time_steps),
            exclude_invalid_rois=exclude_invalid_rois)
        motion_correction = _get_motion_correction()
        if skip_eye_tracking:
            eye_tracking_table = None
            eye_tracking_rig_geometry = None
        else:
            eye_tracking_table = _get_eye_tracking_table(sync_file=sync_file)
            eye_tracking_rig_geometry = EyeTrackingRigGeometry.from_json(
                dict_repr=session_data)

        return BehaviorOphysExperiment(
            behavior_session=behavior_session,
            cell_specimens=cell_specimens,
            ophys_timestamps=ophys_timestamps,
            metadata=meta,
            projections=projections,
            motion_correction=motion_correction,
            eye_tracking_table=eye_tracking_table,
            eye_tracking_rig_geometry=eye_tracking_rig_geometry,
            date_of_acquisition=behavior_session._date_of_acquisition)
Exemplo n.º 10
0
    def from_nwb(cls,
                 nwbfile: NWBFile,
                 eye_tracking_z_threshold: float = 3.0,
                 eye_tracking_dilation_frames: int = 2,
                 events_filter_scale: float = 2.0,
                 events_filter_n_time_steps: int = 20,
                 exclude_invalid_rois=True) -> "BehaviorOphysExperiment":
        """

        Parameters
        ----------
        nwbfile
        eye_tracking_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
        eye_tracking_dilation_frames : int, optional
            Determines the number of adjacent frames that will be marked
            as 'likely_blink' when performing blink detection for
            `eye_tracking` data, by default 2
        events_filter_scale : float, optional
            Stdev of halfnorm distribution used to convolve ophys events with
            a 1d causal half-gaussian filter to smooth it for visualization,
            by default 2.0
        events_filter_n_time_steps : int, optional
            Number of time steps to use for convolution of ophys events
        exclude_invalid_rois
            Whether to exclude invalid rois
        """
        def _is_multi_plane_session():
            imaging_plane_group_meta = ImagingPlaneGroup.from_nwb(
                nwbfile=nwbfile)
            return cls._is_multi_plane_session(
                imaging_plane_group_meta=imaging_plane_group_meta)

        behavior_session = BehaviorSession.from_nwb(nwbfile=nwbfile)
        projections = Projections.from_nwb(nwbfile=nwbfile)
        cell_specimens = CellSpecimens.from_nwb(
            nwbfile=nwbfile,
            segmentation_mask_image_spacing=projections.max_projection.spacing,
            events_params=EventsParams(
                filter_scale=events_filter_scale,
                filter_n_time_steps=events_filter_n_time_steps),
            exclude_invalid_rois=exclude_invalid_rois)
        eye_tracking_rig_geometry = EyeTrackingRigGeometry.from_nwb(
            nwbfile=nwbfile)
        eye_tracking_table = EyeTrackingTable.from_nwb(
            nwbfile=nwbfile,
            z_threshold=eye_tracking_z_threshold,
            dilation_frames=eye_tracking_dilation_frames)
        motion_correction = MotionCorrection.from_nwb(nwbfile=nwbfile)
        is_multiplane_session = _is_multi_plane_session()
        metadata = BehaviorOphysMetadata.from_nwb(
            nwbfile=nwbfile, is_multiplane=is_multiplane_session)
        if is_multiplane_session:
            ophys_timestamps = OphysTimestampsMultiplane.from_nwb(
                nwbfile=nwbfile)
        else:
            ophys_timestamps = OphysTimestamps.from_nwb(nwbfile=nwbfile)
        date_of_acquisition = DateOfAcquisitionOphys.from_nwb(nwbfile=nwbfile)

        return BehaviorOphysExperiment(
            behavior_session=behavior_session,
            cell_specimens=cell_specimens,
            eye_tracking_rig_geometry=eye_tracking_rig_geometry,
            eye_tracking_table=eye_tracking_table,
            motion_correction=motion_correction,
            metadata=metadata,
            ophys_timestamps=ophys_timestamps,
            projections=projections,
            date_of_acquisition=date_of_acquisition)
Exemplo n.º 11
0
    def from_lims(cls,
                  ophys_experiment_id: int,
                  eye_tracking_z_threshold: float = 3.0,
                  eye_tracking_dilation_frames: int = 2,
                  events_filter_scale: float = 2.0,
                  events_filter_n_time_steps: int = 20,
                  exclude_invalid_rois=True,
                  skip_eye_tracking=False) -> \
            "BehaviorOphysExperiment":
        """
        Parameters
        ----------
        ophys_experiment_id
        eye_tracking_z_threshold
            See `BehaviorOphysExperiment.from_nwb`
        eye_tracking_dilation_frames
            See `BehaviorOphysExperiment.from_nwb`
        events_filter_scale
            See `BehaviorOphysExperiment.from_nwb`
        events_filter_n_time_steps
            See `BehaviorOphysExperiment.from_nwb`
        exclude_invalid_rois
            Whether to exclude invalid rois
        skip_eye_tracking
            Used to skip returning eye tracking data
        """
        def _is_multi_plane_session():
            imaging_plane_group_meta = ImagingPlaneGroup.from_lims(
                ophys_experiment_id=ophys_experiment_id, lims_db=lims_db)
            return cls._is_multi_plane_session(
                imaging_plane_group_meta=imaging_plane_group_meta)

        def _get_motion_correction():
            rigid_motion_transform_file = RigidMotionTransformFile.from_lims(
                ophys_experiment_id=ophys_experiment_id, db=lims_db)
            return MotionCorrection.from_data_file(
                rigid_motion_transform_file=rigid_motion_transform_file)

        def _get_eye_tracking_table(sync_file: SyncFile):
            eye_tracking_file = EyeTrackingFile.from_lims(
                db=lims_db, ophys_experiment_id=ophys_experiment_id)
            eye_tracking_table = EyeTrackingTable.from_data_file(
                data_file=eye_tracking_file,
                sync_file=sync_file,
                z_threshold=eye_tracking_z_threshold,
                dilation_frames=eye_tracking_dilation_frames)
            return eye_tracking_table

        lims_db = db_connection_creator(
            fallback_credentials=LIMS_DB_CREDENTIAL_MAP)
        sync_file = SyncFile.from_lims(db=lims_db,
                                       ophys_experiment_id=ophys_experiment_id)
        stimulus_timestamps = StimulusTimestamps.from_sync_file(
            sync_file=sync_file)
        behavior_session_id = BehaviorSessionId.from_lims(
            db=lims_db, ophys_experiment_id=ophys_experiment_id)
        is_multiplane_session = _is_multi_plane_session()
        meta = BehaviorOphysMetadata.from_lims(
            ophys_experiment_id=ophys_experiment_id,
            lims_db=lims_db,
            is_multiplane=is_multiplane_session)
        monitor_delay = calculate_monitor_delay(
            sync_file=sync_file, equipment=meta.behavior_metadata.equipment)
        date_of_acquisition = DateOfAcquisitionOphys.from_lims(
            ophys_experiment_id=ophys_experiment_id, lims_db=lims_db)
        behavior_session = BehaviorSession.from_lims(
            lims_db=lims_db,
            behavior_session_id=behavior_session_id.value,
            stimulus_timestamps=stimulus_timestamps,
            monitor_delay=monitor_delay,
            date_of_acquisition=date_of_acquisition)
        if is_multiplane_session:
            ophys_timestamps = OphysTimestampsMultiplane.from_sync_file(
                sync_file=sync_file,
                group_count=meta.ophys_metadata.imaging_plane_group_count,
                plane_group=meta.ophys_metadata.imaging_plane_group)
        else:
            ophys_timestamps = OphysTimestamps.from_sync_file(
                sync_file=sync_file)

        projections = Projections.from_lims(
            ophys_experiment_id=ophys_experiment_id, lims_db=lims_db)
        cell_specimens = CellSpecimens.from_lims(
            ophys_experiment_id=ophys_experiment_id,
            lims_db=lims_db,
            ophys_timestamps=ophys_timestamps,
            segmentation_mask_image_spacing=projections.max_projection.spacing,
            events_params=EventsParams(
                filter_scale=events_filter_scale,
                filter_n_time_steps=events_filter_n_time_steps),
            exclude_invalid_rois=exclude_invalid_rois)
        motion_correction = _get_motion_correction()
        if skip_eye_tracking:
            eye_tracking_table = None
            eye_tracking_rig_geometry = None
        else:
            eye_tracking_table = _get_eye_tracking_table(sync_file=sync_file)
            eye_tracking_rig_geometry = EyeTrackingRigGeometry.from_lims(
                ophys_experiment_id=ophys_experiment_id, lims_db=lims_db)

        return BehaviorOphysExperiment(
            behavior_session=behavior_session,
            cell_specimens=cell_specimens,
            ophys_timestamps=ophys_timestamps,
            metadata=meta,
            projections=projections,
            motion_correction=motion_correction,
            eye_tracking_table=eye_tracking_table,
            eye_tracking_rig_geometry=eye_tracking_rig_geometry,
            date_of_acquisition=date_of_acquisition)
 def test_cache_clear_no_warning(self, caplog):
     caplog.clear()
     bs = BehaviorSession(api=DummyApiCache())
     bs.cache_clear()
     assert len(caplog.record_tuples) == 0
 def setup_class(cls):
     cls.behavior_session = BehaviorSession(api=DummyApi())