Ejemplo n.º 1
0
def test_module(input_json):
    with patch("sys.argv", ["test_run", input_json]):
        with patch("logging.info"):
            run_ophys_time_sync.main()

    with open(input_json, "r") as f:
        input_data = json.load(f)

    output_file = input_data.pop("output_file")
    assert os.path.exists(output_file)

    input_data.pop("ophys_experiment_id")
    sync_file = input_data.pop("sync_file")
    aligner = ts.OphysTimeAligner(sync_file, **input_data)
    with h5py.File(output_file) as f:
        t, d = aligner.corrected_ophys_timestamps
        assert np.all(t == f['twop_vsync_fall'].value)
        assert np.all(d == f['ophys_delta'].value)
        st, sd, stim_delay = aligner.corrected_stim_timestamps
        align = ts.get_alignment_array(t, st)
        assert np.allclose(align,
                           f['stimulus_alignment'].value,
                           equal_nan=True)
        assert np.all(sd == f['stim_delta'].value)
        et, ed = aligner.corrected_eye_video_timestamps
        align = ts.get_alignment_array(et, t, int_method=np.ceil)
        assert np.allclose(align,
                           f['eye_tracking_alignment'].value,
                           equal_nan=True)
        assert np.all(ed == f['eye_delta'].value)
        bt, bd = aligner.corrected_behavior_video_timestamps
        align = ts.get_alignment_array(bt, t, int_method=np.ceil)
        assert np.allclose(align,
                           f['body_camera_alignment'].value,
                           equal_nan=True)
Ejemplo n.º 2
0
def main():
    parser = argparse.ArgumentParser("Generate brain observatory alignment.")
    parser.add_argument('input_json')
    parser.add_argument('--log-level', default=logging.DEBUG)
    mod = PipelineModule("Generate brain observatory alignment.", parser)

    input_data = mod.input_data()
    experiment_id = input_data.pop("ophys_experiment_id")
    sync_file = input_data.pop("sync_file")
    output_file = input_data.pop("output_file")

    aligner = ts.OphysTimeAligner(sync_file, **input_data)

    ophys_times, ophys_delta = aligner.corrected_ophys_timestamps
    stim_times, stim_delta = aligner.corrected_stim_timestamps
    eye_times, eye_delta = aligner.corrected_eye_video_timestamps
    beh_times, beh_delta = aligner.corrected_behavior_video_timestamps

    # stim array is index of ophys frame for each stim frame to match to
    # so len(stim_times)
    stim_alignment = ts.get_alignment_array(ophys_times, stim_times)

    # camera arrays are index of camera frame for each ophys frame ...
    # cam_nwb_creator depends on this so keeping it that way even though
    # it makes little sense... len(video_times)
    eye_alignment = ts.get_alignment_array(eye_times, ophys_times,
                                           int_method=np.ceil)

    behavior_alignment = ts.get_alignment_array(beh_times, ophys_times,
                                                int_method=np.ceil)

    write_output(output_file, ophys_times, stim_alignment, eye_alignment,
                 behavior_alignment, ophys_delta, stim_delta, eye_delta,
                 beh_delta)
Ejemplo n.º 3
0
def test_get_alignment_array():
    bigger = np.linspace(0, 5, 300)
    smaller = np.linspace(0.2, 3, 50)

    alignment = ts.get_alignment_array(bigger, smaller)
    assert np.all(~np.isnan(alignment))
    assert np.all(bigger[alignment.astype(int)] < smaller)

    alignment = ts.get_alignment_array(smaller, bigger)
    assert np.all(np.isnan(alignment[bigger <= 0.2]))
    assert np.all(np.isnan(alignment[bigger >= 50]))
    big_idx = np.where(~np.isnan(alignment))[0]
    small_idx = alignment[big_idx].astype(int)
    assert np.all(smaller[small_idx] < bigger[big_idx])
Ejemplo n.º 4
0
def test_regression_calculate_stimulus_alignment(nikon_input,
                                                 scientifica_input):
    for input_data in [nikon_input, scientifica_input]:
        sync_file = input_data.pop("sync_file")
        aligner = ts.OphysTimeAligner(sync_file, **input_data)
        old_align = calculate_stimulus_alignment(aligner.stim_timestamps,
                                                 aligner.ophys_timestamps)
        new_align = ts.get_alignment_array(aligner.ophys_timestamps,
                                           aligner.stim_timestamps)

        # Old alignment assigned simultaneous stim frames to the previous ophys
        # frame. Methods should only differ when ophys and stim are identical.
        mismatch = old_align != new_align
        mis_o = aligner.ophys_timestamps[new_align[mismatch].astype(int)]
        mis_s = aligner.stim_timestamps[mismatch]
        assert np.all(mis_o == mis_s)
        # Occurence of mismatch should be rare
        assert len(mis_o) < 0.005 * len(aligner.ophys_timestamps)
Ejemplo n.º 5
0
def test_regression_calculate_camera_alignment(nikon_input, scientifica_input):
    for input_data in [nikon_input, scientifica_input]:
        sync_file = input_data.pop("sync_file")
        aligner = ts.OphysTimeAligner(sync_file, **input_data)
        freq = aligner.dataset.meta_data['ni_daq']['counter_output_freq']
        old_eye_align = sync_camera_stimulus(aligner.dataset, freq, 2, 1)
        # old alignment throws out the first ophys timestamp
        new_eye_align = ts.get_alignment_array(aligner.eye_video_timestamps,
                                               aligner.ophys_timestamps[1:],
                                               int_method=np.ceil)
        mismatch = np.where(old_eye_align[:, 0] != new_eye_align)
        mis_e = \
            aligner.eye_video_timestamps[new_eye_align[mismatch].astype(int)]
        mis_o = aligner.ophys_timestamps[1:][mismatch]
        mis_o_plus = aligner.ophys_timestamps[1:][(mismatch[0] + 1, )]
        # New method should only disagree when old method was wrong (old method
        # set an eye tracking frame to an earlier ophys frame).
        assert np.all(mis_o < mis_e)
        assert np.all(mis_o_plus >= mis_e)
        # Occurence of mismatch should be rare
        assert len(mis_o) < 0.005 * len(aligner.ophys_timestamps[1:])
Ejemplo n.º 6
0
def run_ophys_time_sync(
    aligner: ts.OphysTimeAligner, 
    experiment_id: int,
    min_stimulus_delay: float,
    max_stimulus_delay: float
) -> TimeSyncOutputs:
    """ Carry out synchronization of timestamps across the data streams of an 
    ophys experiment.

    Parameters
    ----------
    aligner : drives alignment. See OphysTimeAligner for details of the 
        attributes and properties that must be implemented.
    experiment_id : unique identifier for the experiment being aligned
    min_stimulus_delay : reject alignment run (raise a ValueError) if the 
        calculated monitor delay is below this value (s).
    max_stimulus_delay : reject alignment run (raise a ValueError) if the 
        calculated monitor delay is above this value (s).

    Returns
    -------
    A TimeSyncOutputs (see definintion for more information) of output 
        parameters and arrays of aligned timestamps.

    """

    stim_times, stim_delta, stim_delay = aligner.corrected_stim_timestamps
    check_stimulus_delay(stim_delay, min_stimulus_delay, max_stimulus_delay)

    ophys_times, ophys_delta = aligner.corrected_ophys_timestamps
    eye_times, eye_delta = aligner.corrected_eye_video_timestamps
    beh_times, beh_delta = aligner.corrected_behavior_video_timestamps

    # stim array is index of ophys frame for each stim frame to match to
    # so len(stim_times)
    stim_alignment = ts.get_alignment_array(ophys_times, stim_times)

    # camera arrays are index of camera frame for each ophys frame ...
    # cam_nwb_creator depends on this so keeping it that way even though
    # it makes little sense... len(video_times)
    eye_alignment = ts.get_alignment_array(eye_times, ophys_times,
                                           int_method=np.ceil)

    behavior_alignment = ts.get_alignment_array(beh_times, ophys_times,
                                                int_method=np.ceil)

    return TimeSyncOutputs(
        experiment_id,
        stim_delay,
        ophys_delta,
        stim_delta,
        eye_delta,
        beh_delta,
        ophys_times,
        stim_times,
        eye_times,
        beh_times,
        stim_alignment,
        eye_alignment,
        behavior_alignment
    )