py-neuromodulation 0.0.3__py3-none-any.whl → 0.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- py_neuromodulation/ConnectivityDecoding/Automated Anatomical Labeling 3 (Rolls 2020).nii +0 -0
- py_neuromodulation/ConnectivityDecoding/_get_grid_hull.m +34 -0
- py_neuromodulation/ConnectivityDecoding/_get_grid_whole_brain.py +106 -0
- py_neuromodulation/ConnectivityDecoding/_helper_write_connectome.py +119 -0
- py_neuromodulation/ConnectivityDecoding/mni_coords_cortical_surface.mat +0 -0
- py_neuromodulation/ConnectivityDecoding/mni_coords_whole_brain.mat +0 -0
- py_neuromodulation/ConnectivityDecoding/rmap_func_all.nii +0 -0
- py_neuromodulation/ConnectivityDecoding/rmap_struc.nii +0 -0
- py_neuromodulation/data/README +6 -0
- py_neuromodulation/data/dataset_description.json +8 -0
- py_neuromodulation/data/participants.json +32 -0
- py_neuromodulation/data/participants.tsv +2 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_coordsystem.json +5 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_electrodes.tsv +11 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_channels.tsv +11 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.eeg +0 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.json +18 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vhdr +35 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vmrk +13 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/sub-testsub_ses-EphysMedOff_scans.tsv +2 -0
- py_neuromodulation/grid_cortex.tsv +40 -0
- py_neuromodulation/grid_subcortex.tsv +1429 -0
- py_neuromodulation/nm_settings.json +338 -0
- py_neuromodulation/nm_stream_offline.py +7 -6
- py_neuromodulation/plots/STN_surf.mat +0 -0
- py_neuromodulation/plots/Vertices.mat +0 -0
- py_neuromodulation/plots/faces.mat +0 -0
- py_neuromodulation/plots/grid.mat +0 -0
- {py_neuromodulation-0.0.3.dist-info → py_neuromodulation-0.0.4.dist-info}/METADATA +182 -182
- py_neuromodulation-0.0.4.dist-info/RECORD +72 -0
- {py_neuromodulation-0.0.3.dist-info → py_neuromodulation-0.0.4.dist-info}/WHEEL +1 -2
- docs/build/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +0 -68
- docs/build/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +0 -233
- docs/build/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +0 -219
- docs/build/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +0 -97
- docs/build/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +0 -64
- docs/build/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +0 -192
- docs/build/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +0 -210
- docs/build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +0 -68
- docs/build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +0 -239
- docs/build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +0 -219
- docs/build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +0 -97
- docs/build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +0 -64
- docs/build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +0 -192
- docs/build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +0 -210
- docs/source/_build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +0 -76
- docs/source/_build/html/_downloads/0d0d0a76e8f648d5d3cbc47da6351932/plot_real_time_demo.py +0 -97
- docs/source/_build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +0 -240
- docs/source/_build/html/_downloads/5d73cadc59a8805c47e3b84063afc157/plot_example_BIDS.py +0 -233
- docs/source/_build/html/_downloads/7660317fa5a6bfbd12fcca9961457fc4/plot_example_rmap_computing.py +0 -63
- docs/source/_build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +0 -219
- docs/source/_build/html/_downloads/839e5b319379f7fd9e867deb00fd797f/plot_example_gridPointProjection.py +0 -210
- docs/source/_build/html/_downloads/ae8be19afe5e559f011fc9b138968ba0/plot_first_demo.py +0 -192
- docs/source/_build/html/_downloads/b8b06cacc17969d3725a0b6f1d7741c5/plot_example_sharpwave_analysis.py +0 -219
- docs/source/_build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +0 -121
- docs/source/_build/html/_downloads/c31a86c0b68cb4167d968091ace8080d/plot_example_add_feature.py +0 -68
- docs/source/_build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +0 -64
- docs/source/_build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +0 -189
- docs/source/_build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +0 -210
- docs/source/auto_examples/plot_0_first_demo.py +0 -189
- docs/source/auto_examples/plot_1_example_BIDS.py +0 -240
- docs/source/auto_examples/plot_2_example_add_feature.py +0 -76
- docs/source/auto_examples/plot_3_example_sharpwave_analysis.py +0 -219
- docs/source/auto_examples/plot_4_example_gridPointProjection.py +0 -210
- docs/source/auto_examples/plot_5_example_rmap_computing.py +0 -64
- docs/source/auto_examples/plot_6_real_time_demo.py +0 -121
- docs/source/conf.py +0 -105
- examples/plot_0_first_demo.py +0 -189
- examples/plot_1_example_BIDS.py +0 -240
- examples/plot_2_example_add_feature.py +0 -76
- examples/plot_3_example_sharpwave_analysis.py +0 -219
- examples/plot_4_example_gridPointProjection.py +0 -210
- examples/plot_5_example_rmap_computing.py +0 -64
- examples/plot_6_real_time_demo.py +0 -121
- packages/realtime_decoding/build/lib/realtime_decoding/__init__.py +0 -4
- packages/realtime_decoding/build/lib/realtime_decoding/decoder.py +0 -104
- packages/realtime_decoding/build/lib/realtime_decoding/features.py +0 -163
- packages/realtime_decoding/build/lib/realtime_decoding/helpers.py +0 -15
- packages/realtime_decoding/build/lib/realtime_decoding/run_decoding.py +0 -345
- packages/realtime_decoding/build/lib/realtime_decoding/trainer.py +0 -54
- packages/tmsi/build/lib/TMSiFileFormats/__init__.py +0 -37
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/__init__.py +0 -36
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/lsl_stream_writer.py +0 -200
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_file_writer.py +0 -496
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_to_edf_converter.py +0 -236
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/xdf_file_writer.py +0 -977
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/__init__.py +0 -35
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/edf_reader.py +0 -116
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/poly5reader.py +0 -294
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/xdf_reader.py +0 -229
- packages/tmsi/build/lib/TMSiFileFormats/file_writer.py +0 -102
- packages/tmsi/build/lib/TMSiPlotters/__init__.py +0 -2
- packages/tmsi/build/lib/TMSiPlotters/gui/__init__.py +0 -39
- packages/tmsi/build/lib/TMSiPlotters/gui/_plotter_gui.py +0 -234
- packages/tmsi/build/lib/TMSiPlotters/gui/plotting_gui.py +0 -440
- packages/tmsi/build/lib/TMSiPlotters/plotters/__init__.py +0 -44
- packages/tmsi/build/lib/TMSiPlotters/plotters/hd_emg_plotter.py +0 -446
- packages/tmsi/build/lib/TMSiPlotters/plotters/impedance_plotter.py +0 -589
- packages/tmsi/build/lib/TMSiPlotters/plotters/signal_plotter.py +0 -1326
- packages/tmsi/build/lib/TMSiSDK/__init__.py +0 -54
- packages/tmsi/build/lib/TMSiSDK/device.py +0 -588
- packages/tmsi/build/lib/TMSiSDK/devices/__init__.py +0 -34
- packages/tmsi/build/lib/TMSiSDK/devices/saga/TMSi_Device_API.py +0 -1764
- packages/tmsi/build/lib/TMSiSDK/devices/saga/__init__.py +0 -34
- packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_device.py +0 -1366
- packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_types.py +0 -520
- packages/tmsi/build/lib/TMSiSDK/devices/saga/xml_saga_config.py +0 -165
- packages/tmsi/build/lib/TMSiSDK/error.py +0 -95
- packages/tmsi/build/lib/TMSiSDK/sample_data.py +0 -63
- packages/tmsi/build/lib/TMSiSDK/sample_data_server.py +0 -99
- packages/tmsi/build/lib/TMSiSDK/settings.py +0 -45
- packages/tmsi/build/lib/TMSiSDK/tmsi_device.py +0 -111
- packages/tmsi/build/lib/__init__.py +0 -4
- packages/tmsi/build/lib/apex_sdk/__init__.py +0 -34
- packages/tmsi/build/lib/apex_sdk/device/__init__.py +0 -41
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API.py +0 -1009
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_enums.py +0 -239
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_structures.py +0 -668
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_device.py +0 -1611
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_dongle.py +0 -38
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_event_reader.py +0 -57
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_channel.py +0 -44
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_config.py +0 -150
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_const.py +0 -36
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_impedance_channel.py +0 -48
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_info.py +0 -108
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/dongle_info.py +0 -39
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/download_measurement.py +0 -77
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/eeg_measurement.py +0 -150
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/impedance_measurement.py +0 -129
- packages/tmsi/build/lib/apex_sdk/device/threads/conversion_thread.py +0 -59
- packages/tmsi/build/lib/apex_sdk/device/threads/sampling_thread.py +0 -57
- packages/tmsi/build/lib/apex_sdk/device/tmsi_channel.py +0 -83
- packages/tmsi/build/lib/apex_sdk/device/tmsi_device.py +0 -201
- packages/tmsi/build/lib/apex_sdk/device/tmsi_device_enums.py +0 -103
- packages/tmsi/build/lib/apex_sdk/device/tmsi_dongle.py +0 -43
- packages/tmsi/build/lib/apex_sdk/device/tmsi_event_reader.py +0 -50
- packages/tmsi/build/lib/apex_sdk/device/tmsi_measurement.py +0 -118
- packages/tmsi/build/lib/apex_sdk/sample_data_server/__init__.py +0 -33
- packages/tmsi/build/lib/apex_sdk/sample_data_server/event_data.py +0 -44
- packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data.py +0 -50
- packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data_server.py +0 -136
- packages/tmsi/build/lib/apex_sdk/tmsi_errors/error.py +0 -126
- packages/tmsi/build/lib/apex_sdk/tmsi_sdk.py +0 -113
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/apex/apex_structure_generator.py +0 -134
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/decorators.py +0 -60
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/logger_filter.py +0 -42
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/singleton.py +0 -42
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/support_functions.py +0 -72
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/tmsi_logger.py +0 -98
- py_neuromodulation-0.0.3.dist-info/RECORD +0 -188
- py_neuromodulation-0.0.3.dist-info/top_level.txt +0 -5
- tests/__init__.py +0 -0
- tests/conftest.py +0 -117
- tests/test_all_examples.py +0 -10
- tests/test_all_features.py +0 -63
- tests/test_bispectra.py +0 -70
- tests/test_bursts.py +0 -105
- tests/test_feature_sampling_rates.py +0 -143
- tests/test_fooof.py +0 -16
- tests/test_initalization_offline_stream.py +0 -41
- tests/test_multiprocessing.py +0 -58
- tests/test_nan_values.py +0 -29
- tests/test_nm_filter.py +0 -95
- tests/test_nm_resample.py +0 -63
- tests/test_normalization_settings.py +0 -146
- tests/test_notch_filter.py +0 -31
- tests/test_osc_features.py +0 -424
- tests/test_preprocessing_filter.py +0 -151
- tests/test_rereference.py +0 -171
- tests/test_sampling.py +0 -57
- tests/test_settings_change_after_init.py +0 -76
- tests/test_sharpwave.py +0 -165
- tests/test_target_channel_add.py +0 -100
- tests/test_timing.py +0 -80
- {py_neuromodulation-0.0.3.dist-info → py_neuromodulation-0.0.4.dist-info/licenses}/LICENSE +0 -0
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
ECoG Movement decoding example
|
|
3
|
-
==============================
|
|
4
|
-
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
# %%
|
|
8
|
-
# This example notebook read openly accessible data from the publication
|
|
9
|
-
# *Electrocorticography is superior to subthalamic local field potentials
|
|
10
|
-
# for movement decoding in Parkinson’s disease*
|
|
11
|
-
# (`Merk et al. 2022 <https://elifesciences.org/articles/75126>_`).
|
|
12
|
-
# The dataset is available `here <https://doi.org/10.7910/DVN/IO2FLM>`_.
|
|
13
|
-
#
|
|
14
|
-
# For simplicity one example subject is automatically shipped within
|
|
15
|
-
# this repo at the *py_neuromodulation/data* folder, stored in
|
|
16
|
-
# `iEEG BIDS <https://www.nature.com/articles/s41597-019-0105-7>`_ format.
|
|
17
|
-
|
|
18
|
-
# %%
|
|
19
|
-
from sklearn import metrics, model_selection, linear_model
|
|
20
|
-
import matplotlib.pyplot as plt
|
|
21
|
-
|
|
22
|
-
import py_neuromodulation as nm
|
|
23
|
-
from py_neuromodulation import (
|
|
24
|
-
nm_analysis,
|
|
25
|
-
nm_decode,
|
|
26
|
-
nm_define_nmchannels,
|
|
27
|
-
nm_IO,
|
|
28
|
-
nm_plots,
|
|
29
|
-
nm_settings,
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
# %%
|
|
33
|
-
# Let's read the example using `mne_bids <https://mne.tools/mne-bids/stable/index.html>`_.
|
|
34
|
-
# The resulting raw object is of type `mne.RawArray <https://mne.tools/stable/generated/mne.io.RawArray.html>`_.
|
|
35
|
-
# We can use the properties such as sampling frequency, channel names, channel types all from the mne array and create the *nm_channels* DataFrame:
|
|
36
|
-
|
|
37
|
-
(
|
|
38
|
-
RUN_NAME,
|
|
39
|
-
PATH_RUN,
|
|
40
|
-
PATH_BIDS,
|
|
41
|
-
PATH_OUT,
|
|
42
|
-
datatype,
|
|
43
|
-
) = nm_IO.get_paths_example_data()
|
|
44
|
-
|
|
45
|
-
(
|
|
46
|
-
raw,
|
|
47
|
-
data,
|
|
48
|
-
sfreq,
|
|
49
|
-
line_noise,
|
|
50
|
-
coord_list,
|
|
51
|
-
coord_names,
|
|
52
|
-
) = nm_IO.read_BIDS_data(
|
|
53
|
-
PATH_RUN=PATH_RUN, BIDS_PATH=PATH_BIDS, datatype=datatype
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
nm_channels = nm_define_nmchannels.set_channels(
|
|
57
|
-
ch_names=raw.ch_names,
|
|
58
|
-
ch_types=raw.get_channel_types(),
|
|
59
|
-
reference="default",
|
|
60
|
-
bads=raw.info["bads"],
|
|
61
|
-
new_names="default",
|
|
62
|
-
used_types=("ecog", "dbs", "seeg"),
|
|
63
|
-
target_keywords=["MOV_RIGHT"],
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
nm_channels
|
|
67
|
-
|
|
68
|
-
# %%
|
|
69
|
-
# This example contains the grip force movement traces, we'll use the *MOV_RIGHT* channel as a decoding target channel.
|
|
70
|
-
# Let's check some of the raw feature and time series traces:
|
|
71
|
-
|
|
72
|
-
plt.figure(figsize=(12, 4), dpi=300)
|
|
73
|
-
plt.subplot(121)
|
|
74
|
-
plt.plot(raw.times, data[-1, :])
|
|
75
|
-
plt.xlabel("Time [s]")
|
|
76
|
-
plt.ylabel("a.u.")
|
|
77
|
-
plt.title("Movement label")
|
|
78
|
-
plt.xlim(0, 20)
|
|
79
|
-
|
|
80
|
-
plt.subplot(122)
|
|
81
|
-
for idx, ch_name in enumerate(nm_channels.query("used == 1").name):
|
|
82
|
-
plt.plot(raw.times, data[idx, :] + idx * 300, label=ch_name)
|
|
83
|
-
plt.legend(bbox_to_anchor=(1, 0.5), loc="center left")
|
|
84
|
-
plt.title("ECoG + STN-LFP time series")
|
|
85
|
-
plt.xlabel("Time [s]")
|
|
86
|
-
plt.ylabel("Voltage a.u.")
|
|
87
|
-
plt.xlim(0, 20)
|
|
88
|
-
|
|
89
|
-
# %%
|
|
90
|
-
settings = nm_settings.get_default_settings()
|
|
91
|
-
settings = nm_settings.set_settings_fast_compute(settings)
|
|
92
|
-
|
|
93
|
-
settings["features"]["welch"] = True
|
|
94
|
-
settings["features"]["fft"] = True
|
|
95
|
-
settings["features"]["bursts"] = True
|
|
96
|
-
settings["features"]["sharpwave_analysis"] = True
|
|
97
|
-
settings["features"]["coherence"] = True
|
|
98
|
-
settings["coherence"]["channels"] = [["LFP_RIGHT_0", "ECOG_RIGHT_0"]]
|
|
99
|
-
settings["coherence"]["frequency_bands"] = ["high beta", "low gamma"]
|
|
100
|
-
settings["sharpwave_analysis_settings"]["estimator"]["mean"] = []
|
|
101
|
-
for sw_feature in list(
|
|
102
|
-
settings["sharpwave_analysis_settings"]["sharpwave_features"].keys()
|
|
103
|
-
):
|
|
104
|
-
settings["sharpwave_analysis_settings"]["sharpwave_features"][
|
|
105
|
-
sw_feature
|
|
106
|
-
] = True
|
|
107
|
-
settings["sharpwave_analysis_settings"]["estimator"]["mean"].append(
|
|
108
|
-
sw_feature
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
# %%
|
|
112
|
-
stream = nm.Stream(
|
|
113
|
-
sfreq=sfreq,
|
|
114
|
-
nm_channels=nm_channels,
|
|
115
|
-
settings=settings,
|
|
116
|
-
line_noise=line_noise,
|
|
117
|
-
coord_list=coord_list,
|
|
118
|
-
coord_names=coord_names,
|
|
119
|
-
verbose=True,
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
# %%
|
|
123
|
-
features = stream.run(
|
|
124
|
-
data=data,
|
|
125
|
-
out_path_root=PATH_OUT,
|
|
126
|
-
folder_name=RUN_NAME,
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
# %%
|
|
130
|
-
# Feature Analysis Movement
|
|
131
|
-
# -------------------------
|
|
132
|
-
# The obtained performances can now be read and visualized using the :class:`nm_analysis.Feature_Reader`.
|
|
133
|
-
|
|
134
|
-
# initialize analyzer
|
|
135
|
-
feature_reader = nm_analysis.Feature_Reader(
|
|
136
|
-
feature_dir=PATH_OUT,
|
|
137
|
-
feature_file=RUN_NAME,
|
|
138
|
-
)
|
|
139
|
-
feature_reader.label_name = "MOV_RIGHT"
|
|
140
|
-
feature_reader.label = feature_reader.feature_arr["MOV_RIGHT"]
|
|
141
|
-
|
|
142
|
-
# %%
|
|
143
|
-
feature_reader.feature_arr.iloc[100:108, -6:]
|
|
144
|
-
|
|
145
|
-
# %%
|
|
146
|
-
print(feature_reader.feature_arr.shape)
|
|
147
|
-
|
|
148
|
-
# %%
|
|
149
|
-
feature_reader._get_target_ch()
|
|
150
|
-
|
|
151
|
-
# %%
|
|
152
|
-
feature_reader.plot_target_averaged_channel(
|
|
153
|
-
ch="ECOG_RIGHT_0",
|
|
154
|
-
list_feature_keywords=None,
|
|
155
|
-
epoch_len=4,
|
|
156
|
-
threshold=0.5,
|
|
157
|
-
ytick_labelsize=7,
|
|
158
|
-
figsize_x=12,
|
|
159
|
-
figsize_y=12,
|
|
160
|
-
)
|
|
161
|
-
|
|
162
|
-
# %%
|
|
163
|
-
feature_reader.plot_all_features(
|
|
164
|
-
ytick_labelsize=6,
|
|
165
|
-
clim_low=-2,
|
|
166
|
-
clim_high=2,
|
|
167
|
-
ch_used="ECOG_RIGHT_0",
|
|
168
|
-
time_limit_low_s=0,
|
|
169
|
-
time_limit_high_s=20,
|
|
170
|
-
normalize=True,
|
|
171
|
-
save=True,
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
# %%
|
|
175
|
-
nm_plots.plot_corr_matrix(
|
|
176
|
-
feature=feature_reader.feature_arr.filter(regex="ECOG_RIGHT_0"),
|
|
177
|
-
ch_name="ECOG_RIGHT_0-avgref",
|
|
178
|
-
feature_names=feature_reader.feature_arr.filter(
|
|
179
|
-
regex="ECOG_RIGHT_0-avgref"
|
|
180
|
-
).columns,
|
|
181
|
-
feature_file=feature_reader.feature_file,
|
|
182
|
-
show_plot=True,
|
|
183
|
-
figsize=(15, 15),
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
# %%
|
|
187
|
-
# Decoding
|
|
188
|
-
# --------
|
|
189
|
-
#
|
|
190
|
-
# The main focus of the *py_neuromodulation* pipeline is feature estimation.
|
|
191
|
-
# Nevertheless, the user can also use the pipeline for machine learning decoding.
|
|
192
|
-
# It can be used for regression and classification problems and also dimensionality reduction such as PCA and CCA.
|
|
193
|
-
#
|
|
194
|
-
# Here, we show an example using the XGBOOST classifier. The used labels came from a continuous grip force movement target, named "MOV_RIGHT".
|
|
195
|
-
#
|
|
196
|
-
# First we initialize the :class:`~nm_decode.Decoder` class, which the specified *validation method*, here being a simple 3-fold cross validation,
|
|
197
|
-
# the evaluation metric, used machine learning model, and the channels we want to evaluate performances for.
|
|
198
|
-
#
|
|
199
|
-
# There are many more implemented methods, but we will here limit it to the ones presented.
|
|
200
|
-
|
|
201
|
-
model = linear_model.LinearRegression()
|
|
202
|
-
|
|
203
|
-
feature_reader.decoder = nm_decode.Decoder(
|
|
204
|
-
features=feature_reader.feature_arr,
|
|
205
|
-
label=feature_reader.label,
|
|
206
|
-
label_name=feature_reader.label_name,
|
|
207
|
-
used_chs=feature_reader.used_chs,
|
|
208
|
-
model=model,
|
|
209
|
-
eval_method=metrics.r2_score,
|
|
210
|
-
cv_method=model_selection.KFold(n_splits=3, shuffle=True),
|
|
211
|
-
)
|
|
212
|
-
|
|
213
|
-
# %%
|
|
214
|
-
performances = feature_reader.run_ML_model(
|
|
215
|
-
estimate_channels=True,
|
|
216
|
-
estimate_gridpoints=False,
|
|
217
|
-
estimate_all_channels_combined=True,
|
|
218
|
-
save_results=True,
|
|
219
|
-
)
|
|
220
|
-
|
|
221
|
-
# %%
|
|
222
|
-
# The performances are a dictionary that can be transformed into a DataFrame:
|
|
223
|
-
|
|
224
|
-
df_per = feature_reader.get_dataframe_performances(performances)
|
|
225
|
-
|
|
226
|
-
df_per
|
|
227
|
-
|
|
228
|
-
# %%
|
|
229
|
-
ax = nm_plots.plot_df_subjects(
|
|
230
|
-
df_per,
|
|
231
|
-
x_col="sub",
|
|
232
|
-
y_col="performance_test",
|
|
233
|
-
hue="ch_type",
|
|
234
|
-
PATH_SAVE=PATH_OUT / RUN_NAME / (RUN_NAME + "_decoding_performance.png"),
|
|
235
|
-
figsize_tuple=(8, 5),
|
|
236
|
-
)
|
|
237
|
-
ax.set_ylabel(r"$R^2$ Correlation")
|
|
238
|
-
ax.set_xlabel("Subject 000")
|
|
239
|
-
ax.set_title("Performance comparison Movement decoding")
|
|
240
|
-
plt.tight_layout()
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
ECoG Movement decoding example
|
|
3
|
-
==============================
|
|
4
|
-
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
# %%
|
|
8
|
-
# This example notebook read openly accessible data from the publication
|
|
9
|
-
# *Electrocorticography is superior to subthalamic local field potentials
|
|
10
|
-
# for movement decoding in Parkinson’s disease*
|
|
11
|
-
# (`Merk et al. 2022 <https://elifesciences.org/articles/75126>_`).
|
|
12
|
-
# The dataset is available `here <https://doi.org/10.7910/DVN/IO2FLM>`_.
|
|
13
|
-
#
|
|
14
|
-
# For simplicity one example subject is automatically shipped within
|
|
15
|
-
# this repo at the *py_neuromodulation/data* folder, stored in
|
|
16
|
-
# `iEEG BIDS <https://www.nature.com/articles/s41597-019-0105-7>`_ format.
|
|
17
|
-
|
|
18
|
-
# %%
|
|
19
|
-
from sklearn import metrics, model_selection, linear_model
|
|
20
|
-
import matplotlib.pyplot as plt
|
|
21
|
-
|
|
22
|
-
import py_neuromodulation as nm
|
|
23
|
-
from py_neuromodulation import (
|
|
24
|
-
nm_analysis,
|
|
25
|
-
nm_decode,
|
|
26
|
-
nm_define_nmchannels,
|
|
27
|
-
nm_IO,
|
|
28
|
-
nm_plots,
|
|
29
|
-
nm_settings,
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
# %%
|
|
33
|
-
# Let's read the example using `mne_bids <https://mne.tools/mne-bids/stable/index.html>`_.
|
|
34
|
-
# The resulting raw object is of type `mne.RawArray <https://mne.tools/stable/generated/mne.io.RawArray.html>`_.
|
|
35
|
-
# We can use the properties such as sampling frequency, channel names, channel types all from the mne array and create the *nm_channels* DataFrame:
|
|
36
|
-
|
|
37
|
-
RUN_NAME, PATH_RUN, PATH_BIDS, PATH_OUT, datatype = nm_IO.get_paths_example_data()
|
|
38
|
-
|
|
39
|
-
(
|
|
40
|
-
raw,
|
|
41
|
-
data,
|
|
42
|
-
sfreq,
|
|
43
|
-
line_noise,
|
|
44
|
-
coord_list,
|
|
45
|
-
coord_names,
|
|
46
|
-
) = nm_IO.read_BIDS_data(
|
|
47
|
-
PATH_RUN=PATH_RUN, BIDS_PATH=PATH_BIDS, datatype=datatype
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
nm_channels = nm_define_nmchannels.set_channels(
|
|
51
|
-
ch_names=raw.ch_names,
|
|
52
|
-
ch_types=raw.get_channel_types(),
|
|
53
|
-
reference="default",
|
|
54
|
-
bads=raw.info["bads"],
|
|
55
|
-
new_names="default",
|
|
56
|
-
used_types=("ecog", "dbs", "seeg"),
|
|
57
|
-
target_keywords=["MOV_RIGHT"],
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
nm_channels
|
|
61
|
-
|
|
62
|
-
# %%
|
|
63
|
-
# This example contains the grip force movement traces, we'll use the *MOV_RIGHT_CLEAN* channel as a decoding target channel.
|
|
64
|
-
# Let's check some of the raw feature and time series traces:
|
|
65
|
-
|
|
66
|
-
plt.figure(figsize=(12, 4), dpi=300)
|
|
67
|
-
plt.subplot(121)
|
|
68
|
-
plt.plot(raw.times, data[-1, :])
|
|
69
|
-
plt.xlabel("Time [s]")
|
|
70
|
-
plt.ylabel("a.u.")
|
|
71
|
-
plt.title("Movement label")
|
|
72
|
-
plt.xlim(0, 20)
|
|
73
|
-
|
|
74
|
-
plt.subplot(122)
|
|
75
|
-
for idx, ch_name in enumerate(nm_channels.query("used == 1").name):
|
|
76
|
-
plt.plot(raw.times, data[idx, :] + idx * 300, label=ch_name)
|
|
77
|
-
plt.legend(bbox_to_anchor=(1, 0.5), loc="center left")
|
|
78
|
-
plt.title("ECoG + STN-LFP time series")
|
|
79
|
-
plt.xlabel("Time [s]")
|
|
80
|
-
plt.ylabel("Voltage a.u.")
|
|
81
|
-
plt.xlim(0, 20)
|
|
82
|
-
|
|
83
|
-
# %%
|
|
84
|
-
settings = nm_settings.get_default_settings()
|
|
85
|
-
settings = nm_settings.set_settings_fast_compute(settings)
|
|
86
|
-
|
|
87
|
-
settings["features"]["fft"] = True
|
|
88
|
-
settings["features"]["bursts"] = False
|
|
89
|
-
settings["features"]["sharpwave_analysis"] = False
|
|
90
|
-
settings["features"]["coherence"] = False # True
|
|
91
|
-
settings["coherence"]["channels"] = [["LFP_RIGHT_0", "ECOG_RIGHT_0"]]
|
|
92
|
-
settings["coherence"]["frequency_bands"] = ["high beta", "low gamma"]
|
|
93
|
-
settings["sharpwave_analysis_settings"]["estimator"]["mean"] = []
|
|
94
|
-
for sw_feature in list(
|
|
95
|
-
settings["sharpwave_analysis_settings"]["sharpwave_features"].keys()
|
|
96
|
-
):
|
|
97
|
-
settings["sharpwave_analysis_settings"]["sharpwave_features"][
|
|
98
|
-
sw_feature
|
|
99
|
-
] = True
|
|
100
|
-
settings["sharpwave_analysis_settings"]["estimator"]["mean"].append(
|
|
101
|
-
sw_feature
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
# %%
|
|
105
|
-
stream = nm.Stream(
|
|
106
|
-
sfreq=sfreq,
|
|
107
|
-
nm_channels=nm_channels,
|
|
108
|
-
settings=settings,
|
|
109
|
-
line_noise=line_noise,
|
|
110
|
-
coord_list=coord_list,
|
|
111
|
-
coord_names=coord_names,
|
|
112
|
-
verbose=True,
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
# %%
|
|
116
|
-
features = stream.run(
|
|
117
|
-
data=data,
|
|
118
|
-
out_path_root=PATH_OUT,
|
|
119
|
-
folder_name=RUN_NAME,
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
# %%
|
|
123
|
-
# Feature Analysis
|
|
124
|
-
# ----------------
|
|
125
|
-
# The obtained performances can now be read and visualized using the :class:`nm_analysis.Feature_Reader`.
|
|
126
|
-
|
|
127
|
-
# initialize analyzer
|
|
128
|
-
feature_reader = nm_analysis.Feature_Reader(
|
|
129
|
-
feature_dir=PATH_OUT,
|
|
130
|
-
feature_file=RUN_NAME,
|
|
131
|
-
)
|
|
132
|
-
feature_reader.label_name = "MOV_RIGHT"
|
|
133
|
-
feature_reader.label = feature_reader.feature_arr["MOV_RIGHT"]
|
|
134
|
-
|
|
135
|
-
# %%
|
|
136
|
-
feature_reader.feature_arr.iloc[100:108, -6:]
|
|
137
|
-
|
|
138
|
-
# %%
|
|
139
|
-
print(feature_reader.feature_arr.shape)
|
|
140
|
-
|
|
141
|
-
# %%
|
|
142
|
-
feature_reader._get_target_ch()
|
|
143
|
-
|
|
144
|
-
# %%
|
|
145
|
-
feature_reader.plot_target_averaged_channel(
|
|
146
|
-
ch="ECOG_RIGHT_0",
|
|
147
|
-
list_feature_keywords=None,
|
|
148
|
-
epoch_len=4,
|
|
149
|
-
threshold=0.5,
|
|
150
|
-
ytick_labelsize=7,
|
|
151
|
-
figsize_x=12,
|
|
152
|
-
figsize_y=12,
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
# %%
|
|
156
|
-
feature_reader.plot_all_features(
|
|
157
|
-
ytick_labelsize=3,
|
|
158
|
-
clim_low=-2,
|
|
159
|
-
clim_high=2,
|
|
160
|
-
ch_used="ECOG_RIGHT_0",
|
|
161
|
-
time_limit_low_s=0,
|
|
162
|
-
time_limit_high_s=20,
|
|
163
|
-
normalize=True,
|
|
164
|
-
save=True,
|
|
165
|
-
)
|
|
166
|
-
|
|
167
|
-
# %%
|
|
168
|
-
nm_plots.plot_corr_matrix(
|
|
169
|
-
feature=feature_reader.feature_arr.filter(regex="ECOG_RIGHT_0"),
|
|
170
|
-
ch_name="ECOG_RIGHT_0-avgref",
|
|
171
|
-
feature_names=feature_reader.feature_arr.filter(
|
|
172
|
-
regex="ECOG_RIGHT_0-avgref"
|
|
173
|
-
).columns,
|
|
174
|
-
feature_file=feature_reader.feature_file,
|
|
175
|
-
show_plot=True,
|
|
176
|
-
figsize=(15, 15),
|
|
177
|
-
)
|
|
178
|
-
|
|
179
|
-
# %%
|
|
180
|
-
# Decoding
|
|
181
|
-
# --------
|
|
182
|
-
#
|
|
183
|
-
# The main focus of the *py_neuromodulation* pipeline is feature estimation.
|
|
184
|
-
# Nevertheless, the user can also use the pipeline for machine learning decoding.
|
|
185
|
-
# It can be used for regression and classification problems and also dimensionality reduction such as PCA and CCA.
|
|
186
|
-
#
|
|
187
|
-
# Here, we show an example using the XGBOOST classifier. The used labels came from a continuous grip force movement target, named "MOV_LEFT_CLEAN".
|
|
188
|
-
#
|
|
189
|
-
# First we initialize the :class:`~nm_decode.Decoder` class, which the specified *validation method*, here being a simple 3-fold cross validation,
|
|
190
|
-
# the evaluation metric, used machine learning model, and the channels we want to evaluate performances for.
|
|
191
|
-
#
|
|
192
|
-
# There are many more implemented methods, but we will here limit it to the ones presented.
|
|
193
|
-
|
|
194
|
-
model = linear_model.LinearRegression()
|
|
195
|
-
|
|
196
|
-
feature_reader.decoder = nm_decode.Decoder(
|
|
197
|
-
features=feature_reader.feature_arr,
|
|
198
|
-
label=feature_reader.label,
|
|
199
|
-
label_name=feature_reader.label_name,
|
|
200
|
-
used_chs=feature_reader.used_chs,
|
|
201
|
-
model=model,
|
|
202
|
-
eval_method=metrics.r2_score,
|
|
203
|
-
cv_method=model_selection.KFold(n_splits=3, shuffle=True),
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
# %%
|
|
207
|
-
performances = feature_reader.run_ML_model(
|
|
208
|
-
estimate_channels=True,
|
|
209
|
-
estimate_gridpoints=False,
|
|
210
|
-
estimate_all_channels_combined=True,
|
|
211
|
-
save_results=True,
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
# %%
|
|
215
|
-
# The performances are a dictionary that can be transformed into a DataFrame:
|
|
216
|
-
|
|
217
|
-
df_per = feature_reader.get_dataframe_performances(performances)
|
|
218
|
-
|
|
219
|
-
df_per
|
|
220
|
-
|
|
221
|
-
# %%
|
|
222
|
-
ax = nm_plots.plot_df_subjects(
|
|
223
|
-
df_per,
|
|
224
|
-
x_col="sub",
|
|
225
|
-
y_col="performance_test",
|
|
226
|
-
hue="ch_type",
|
|
227
|
-
PATH_SAVE=PATH_OUT / RUN_NAME / (RUN_NAME + "_decoding_performance.png"),
|
|
228
|
-
figsize_tuple=(8, 5)
|
|
229
|
-
)
|
|
230
|
-
ax.set_ylabel(r"$R^2$ Correlation")
|
|
231
|
-
ax.set_xlabel("Subject 000")
|
|
232
|
-
ax.set_title("Performance comparison Movement decoding")
|
|
233
|
-
plt.tight_layout()
|
docs/source/_build/html/_downloads/7660317fa5a6bfbd12fcca9961457fc4/plot_example_rmap_computing.py
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
R-Map computation
|
|
3
|
-
=================
|
|
4
|
-
|
|
5
|
-
"""
|
|
6
|
-
# %%
|
|
7
|
-
# sphinx_gallery_thumbnail_path = '_static/RMAP_figure.png'
|
|
8
|
-
|
|
9
|
-
# %%
|
|
10
|
-
# Across patient decoding using R-Map optimal connectivity
|
|
11
|
-
# --------------------------------------------------------
|
|
12
|
-
#
|
|
13
|
-
# ECoG electrode placement is commonly very heterogeneous across patients and cohorts.
|
|
14
|
-
# To still facilitate approaches that are able to perform decoding applications without patient individual training,
|
|
15
|
-
# two across-patient decoding approaches were previously investigated for movement decoding:
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
# * grid-point decoding
|
|
19
|
-
# * optimal connectivity channel decoding
|
|
20
|
-
#
|
|
21
|
-
# First, the grid-point decoding approach relies on definition of a cortical or subcortical grid.
|
|
22
|
-
# Data from individual grid points is then interpolated onto those common grid points.
|
|
23
|
-
# The approach was also explained in the :ref:`/auto_examples/plot_example_gridPointProjection.rst` notebook.
|
|
24
|
-
#
|
|
25
|
-
# .. image:: ../_static/RMAP_figure.png
|
|
26
|
-
# :alt: R-Map and grid point approach for decoding without patient-individual training
|
|
27
|
-
#
|
|
28
|
-
# The R-Map decoding approach relies on the other hand on computation of whole brain connectivity. The electrode MNI space locations need to be known,
|
|
29
|
-
# then the following steps can be performed for decoding without patient individual training:
|
|
30
|
-
#
|
|
31
|
-
# #. Using the `wjn_toolbox <https://github.com/neuromodulation/wjn_toolbox>`_ *wjn_specrical_roi* function, the MNI coordinates can be transformed into NIFTI (.nii) files,
|
|
32
|
-
# containing the electrode contact region of interest (ROI):
|
|
33
|
-
#
|
|
34
|
-
# .. code-block:: python
|
|
35
|
-
#
|
|
36
|
-
# wjn_spherical_roi(roiname, mni, 4)
|
|
37
|
-
#
|
|
38
|
-
# #. For the given *ROI.nii* files, the LeadDBS `LeadMapper <https://netstim.gitbook.io/leaddbs/connectomics/lead-mapper>`_ tool can be used for functional or structural connectivity estimation.
|
|
39
|
-
# #. The py_neuromodulation :class:`~nm_RMAP.py` module can then compute the R-Map given the contact-individual connectivity fingerprints:
|
|
40
|
-
#
|
|
41
|
-
# .. code-block:: python
|
|
42
|
-
#
|
|
43
|
-
# nm_RMAP.calculate_RMap_numba(fingerprints, performances)
|
|
44
|
-
#
|
|
45
|
-
# #. The fingerprints from test-set patients can then be correlated with the calculated R-Map:
|
|
46
|
-
#
|
|
47
|
-
# .. code-block:: python
|
|
48
|
-
#
|
|
49
|
-
# nm_RMAP.get_corr_numba(fp, fp_test)
|
|
50
|
-
#
|
|
51
|
-
# #. The channel with highest correlation can then be selected for decoding without individual training. :class:`~nm_RMAP.py` contain already leave one channel
|
|
52
|
-
# and leave one patient out cross validation functions:
|
|
53
|
-
#
|
|
54
|
-
# .. code-block:: python
|
|
55
|
-
#
|
|
56
|
-
# nm_RMAP.leave_one_sub_out_cv(l_fps_names, l_fps_dat, l_per, sub_list)
|
|
57
|
-
#
|
|
58
|
-
# #. The obtained R-Map correlations can then be estimated statistically and plotted against true correlates:
|
|
59
|
-
#
|
|
60
|
-
# .. code-block:: python
|
|
61
|
-
#
|
|
62
|
-
# nm_RMAP.plot_performance_prediction_correlation(per_left_out, per_predict, out_path_save)
|
|
63
|
-
#
|