Пример #1
0
def test_write_probe_lfp_file_roundtrip(tmpdir_factory, roundtrip, lfp_data, probe_data, csd_data):

    expected_csd = xr.DataArray(
        name="CSD",
        data=csd_data["csd"],
        dims=["virtual_channel_index", "time"],
        coords={
            "virtual_channel_index": np.arange(csd_data["csd"].shape[0]),
            "time": csd_data["relative_window"],
            "vertical_position": (("virtual_channel_index",), csd_data["csd_locations"][:, 1]),
            "horizontal_position": (("virtual_channel_index",), csd_data["csd_locations"][:, 0]),
        }
    )

    expected_lfp = xr.DataArray(
        name="LFP",
        data=lfp_data["data"],
        dims=["time", "channel"],
        coords=[lfp_data["timestamps"], [2, 1]]
    )

    tmpdir = Path(tmpdir_factory.mktemp("probe_lfp_nwb"))
    input_data_path = tmpdir / Path("lfp_data.dat")
    input_timestamps_path = tmpdir / Path("lfp_timestamps.npy")
    input_channels_path = tmpdir / Path("lfp_channels.npy")
    input_csd_path = tmpdir / Path("csd.h5")
    output_path = str(tmpdir / Path("lfp.nwb"))  # pynwb.NWBHDF5IO chokes on Path

    test_lfp_paths = {
        "input_data_path": input_data_path,
        "input_timestamps_path": input_timestamps_path,
        "input_channels_path": input_channels_path,
        "output_path": output_path
    }

    probe_data.update({"lfp": test_lfp_paths})
    probe_data.update({"csd_path": input_csd_path})

    write_csd_to_h5(path=input_csd_path, **csd_data)

    np.save(input_timestamps_path, lfp_data["timestamps"], allow_pickle=False)
    np.save(input_channels_path, lfp_data["subsample_channels"], allow_pickle=False)
    with open(input_data_path, "wb") as input_data_file:
        input_data_file.write(lfp_data["data"].tobytes())

    write_nwb.write_probe_lfp_file(4242, None, datetime.now(), logging.INFO, probe_data)

    obt = EcephysNwbSessionApi(path=None, probe_lfp_paths={12345: NWBHDF5IO(output_path, "r").read})

    obtained_lfp = obt.get_lfp(12345)
    obtained_csd = obt.get_current_source_density(12345)

    xr.testing.assert_equal(obtained_lfp, expected_lfp)
    xr.testing.assert_equal(obtained_csd, expected_csd)
Пример #2
0
def test_write_probe_lfp_file(tmpdir_factory, lfp_data, probe_data, csd_data):

    tmpdir = Path(tmpdir_factory.mktemp("probe_lfp_nwb"))
    input_data_path = tmpdir / Path("lfp_data.dat")
    input_timestamps_path = tmpdir / Path("lfp_timestamps.npy")
    input_channels_path = tmpdir / Path("lfp_channels.npy")
    input_csd_path = tmpdir / Path("csd.h5")
    output_path = str(tmpdir / Path("lfp.nwb"))  # pynwb.NWBHDF5IO chokes on Path

    test_lfp_paths = {
        "input_data_path": input_data_path,
        "input_timestamps_path": input_timestamps_path,
        "input_channels_path": input_channels_path,
        "output_path": output_path
    }

    test_session_metadata = {
        "specimen_name": "A",
        "age_in_days": 100.0,
        "full_genotype": "wt",
        "strain": "A strain",
        "sex": "M",
        "stimulus_name": "test_stim",
        "species": "Mus musculus",
        "donor_id": 42
    }

    probe_data.update({"lfp": test_lfp_paths})
    probe_data.update({"csd_path": input_csd_path})

    write_csd_to_h5(path=input_csd_path, **csd_data)

    np.save(input_timestamps_path, lfp_data["timestamps"], allow_pickle=False)
    np.save(input_channels_path, lfp_data["subsample_channels"], allow_pickle=False)
    with open(input_data_path, "wb") as input_data_file:
        input_data_file.write(lfp_data["data"].tobytes())

    write_nwb.write_probe_lfp_file(4242, test_session_metadata, datetime.now(), logging.INFO, probe_data)

    exp_electrodes = pd.DataFrame(probe_data["channels"]).set_index("id").loc[[2, 1], :]
    exp_electrodes.rename(columns={"anterior_posterior_ccf_coordinate": "x",
                                   "dorsal_ventral_ccf_coordinate": "y",
                                   "left_right_ccf_coordinate": "z",
                                   "manual_structure_acronym": "location"}, inplace=True)

    with pynwb.NWBHDF5IO(output_path, "r") as obt_io:
        obt_f = obt_io.read()

        obt_ser = obt_f.get_acquisition("probe_12345_lfp").electrical_series["probe_12345_lfp_data"]
        assert np.allclose(lfp_data["data"], obt_ser.data[:])
        assert np.allclose(lfp_data["timestamps"], obt_ser.timestamps[:])

        obt_electrodes = obt_f.electrodes.to_dataframe().loc[
            :, ["local_index", "probe_horizontal_position",
                "probe_id", "probe_vertical_position",
                "valid_data", "x", "y", "z", "location", "impedence",
                "filtering"]
        ]

        assert obt_f.session_id == "4242"
        assert obt_f.subject.subject_id == "42"

        # There is a difference in how int dtypes are being saved in Windows
        # that are causing tests to fail.
        # Perhaps related to: https://stackoverflow.com/a/36279549
        if platform.system() == "Windows":
            pd.testing.assert_frame_equal(obt_electrodes, exp_electrodes, check_like=True, check_dtype=False)
        else:
            pd.testing.assert_frame_equal(obt_electrodes, exp_electrodes, check_like=True)

        csd_series = obt_f.get_processing_module("current_source_density")["current_source_density"]

        assert np.allclose(csd_data["csd"], csd_series.time_series.data[:].T)
        assert np.allclose(csd_data["relative_window"], csd_series.time_series.timestamps[:])
        obt_channel_locations = np.stack((csd_series.virtual_electrode_x_positions,
                                          csd_series.virtual_electrode_y_positions),
                                         axis=1)
        assert np.allclose([[1, 2], [3, 3]], obt_channel_locations)  # csd interpolated channel locations
Пример #3
0
def test_write_probe_lfp_file(tmpdir_factory, lfp_data):

    tmpdir = Path(tmpdir_factory.mktemp("probe_lfp_nwb"))
    input_data_path = tmpdir / Path("lfp_data.dat")
    input_timestamps_path = tmpdir / Path("lfp_timestamps.npy")
    input_channels_path = tmpdir / Path("lfp_channels.npy")
    input_csd_path = tmpdir / Path("csd.h5")
    output_path = str(tmpdir /
                      Path("lfp.nwb"))  # pynwb.NWBHDF5IO chokes on Path

    probe_data = {
        "id":
        12345,
        "name":
        "probeA",
        "sampling_rate":
        29.0,
        "lfp_sampling_rate":
        10.0,
        "temporal_subsampling_factor":
        2.0,
        "channels": [{
            'id': 0,
            'probe_id': 12,
            'local_index': 1,
            'probe_vertical_position': 21,
            'probe_horizontal_position': 33
        }, {
            'id': 1,
            'probe_id': 12,
            'local_index': 2,
            'probe_vertical_position': 21,
            'probe_horizontal_position': 32
        }, {
            'id': 2,
            'probe_id': 12,
            'local_index': 3,
            'probe_vertical_position': 21,
            'probe_horizontal_position': 31
        }],
        "lfp": {
            "input_data_path": input_data_path,
            "input_timestamps_path": input_timestamps_path,
            "input_channels_path": input_channels_path,
            "output_path": output_path
        },
        "csd_path":
        input_csd_path,
        "amplitude_scale_factor":
        1.0
    }

    csd = np.arange(20).reshape([2, 10])
    csd_times = np.linspace(-1, 1, 10)
    csd_channels = np.array([3, 2])
    csd_locations = np.array([[1, 2], [3, 3]])

    write_csd_to_h5(path=input_csd_path,
                    csd=csd,
                    relative_window=csd_times,
                    channels=csd_channels,
                    csd_locations=csd_locations,
                    stimulus_name="foo",
                    stimulus_index=None,
                    num_trials=1000)

    np.save(input_timestamps_path, lfp_data["timestamps"], allow_pickle=False)
    np.save(input_channels_path,
            lfp_data["subsample_channels"],
            allow_pickle=False)
    with open(input_data_path, "wb") as input_data_file:
        input_data_file.write(lfp_data["data"].tobytes())

    write_nwb.write_probe_lfp_file(datetime.now(), logging.INFO, probe_data)

    exp_electrodes = pd.DataFrame(
        probe_data["channels"]).set_index("id").loc[[2, 1], :]

    with pynwb.NWBHDF5IO(output_path, "r") as obt_io:
        obt_f = obt_io.read()

        obt_ser = obt_f.get_acquisition(
            "probe_12345_lfp").electrical_series["probe_12345_lfp_data"]
        assert np.allclose(lfp_data["data"], obt_ser.data[:])
        assert np.allclose(lfp_data["timestamps"], obt_ser.timestamps[:])

        obt_electrodes = obt_f.electrodes.to_dataframe().loc[:, [
            'local_index', 'probe_horizontal_position', 'probe_id',
            'probe_vertical_position'
        ]]

        pd.testing.assert_frame_equal(exp_electrodes,
                                      obt_electrodes,
                                      check_like=True)

        csd_series = obt_f.get_processing_module(
            "current_source_density")["current_source_density"]

        assert np.allclose(csd, csd_series.data[:])
        assert np.allclose(csd_times, csd_series.timestamps[:])
        assert np.allclose(
            [[1, 2], [3, 3]],
            csd_series.control[:])  # csd interpolated channel locations