py-neuromodulation 0.0.2__py3-none-any.whl → 0.0.3__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.
- docs/build/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +68 -0
- docs/build/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +233 -0
- docs/build/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +219 -0
- docs/build/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +97 -0
- docs/build/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +64 -0
- docs/build/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +192 -0
- docs/build/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +210 -0
- docs/build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +68 -0
- docs/build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +239 -0
- docs/build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +219 -0
- docs/build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +97 -0
- docs/build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +64 -0
- docs/build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +192 -0
- docs/build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +210 -0
- docs/source/_build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +76 -0
- docs/source/_build/html/_downloads/0d0d0a76e8f648d5d3cbc47da6351932/plot_real_time_demo.py +97 -0
- docs/source/_build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +240 -0
- docs/source/_build/html/_downloads/5d73cadc59a8805c47e3b84063afc157/plot_example_BIDS.py +233 -0
- docs/source/_build/html/_downloads/7660317fa5a6bfbd12fcca9961457fc4/plot_example_rmap_computing.py +63 -0
- docs/source/_build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +219 -0
- docs/source/_build/html/_downloads/839e5b319379f7fd9e867deb00fd797f/plot_example_gridPointProjection.py +210 -0
- docs/source/_build/html/_downloads/ae8be19afe5e559f011fc9b138968ba0/plot_first_demo.py +192 -0
- docs/source/_build/html/_downloads/b8b06cacc17969d3725a0b6f1d7741c5/plot_example_sharpwave_analysis.py +219 -0
- docs/source/_build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +121 -0
- docs/source/_build/html/_downloads/c31a86c0b68cb4167d968091ace8080d/plot_example_add_feature.py +68 -0
- docs/source/_build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +64 -0
- docs/source/_build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +189 -0
- docs/source/_build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +210 -0
- docs/source/auto_examples/plot_0_first_demo.py +189 -0
- docs/source/auto_examples/plot_1_example_BIDS.py +240 -0
- docs/source/auto_examples/plot_2_example_add_feature.py +76 -0
- docs/source/auto_examples/plot_3_example_sharpwave_analysis.py +219 -0
- docs/source/auto_examples/plot_4_example_gridPointProjection.py +210 -0
- docs/source/auto_examples/plot_5_example_rmap_computing.py +64 -0
- docs/source/auto_examples/plot_6_real_time_demo.py +121 -0
- docs/source/conf.py +105 -0
- examples/plot_0_first_demo.py +189 -0
- examples/plot_1_example_BIDS.py +240 -0
- examples/plot_2_example_add_feature.py +76 -0
- examples/plot_3_example_sharpwave_analysis.py +219 -0
- examples/plot_4_example_gridPointProjection.py +210 -0
- examples/plot_5_example_rmap_computing.py +64 -0
- examples/plot_6_real_time_demo.py +121 -0
- packages/realtime_decoding/build/lib/realtime_decoding/__init__.py +4 -0
- packages/realtime_decoding/build/lib/realtime_decoding/decoder.py +104 -0
- packages/realtime_decoding/build/lib/realtime_decoding/features.py +163 -0
- packages/realtime_decoding/build/lib/realtime_decoding/helpers.py +15 -0
- packages/realtime_decoding/build/lib/realtime_decoding/run_decoding.py +345 -0
- packages/realtime_decoding/build/lib/realtime_decoding/trainer.py +54 -0
- packages/tmsi/build/lib/TMSiFileFormats/__init__.py +37 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/__init__.py +36 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/lsl_stream_writer.py +200 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_file_writer.py +496 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_to_edf_converter.py +236 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/xdf_file_writer.py +977 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/__init__.py +35 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/edf_reader.py +116 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/poly5reader.py +294 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/xdf_reader.py +229 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_writer.py +102 -0
- packages/tmsi/build/lib/TMSiPlotters/__init__.py +2 -0
- packages/tmsi/build/lib/TMSiPlotters/gui/__init__.py +39 -0
- packages/tmsi/build/lib/TMSiPlotters/gui/_plotter_gui.py +234 -0
- packages/tmsi/build/lib/TMSiPlotters/gui/plotting_gui.py +440 -0
- packages/tmsi/build/lib/TMSiPlotters/plotters/__init__.py +44 -0
- packages/tmsi/build/lib/TMSiPlotters/plotters/hd_emg_plotter.py +446 -0
- packages/tmsi/build/lib/TMSiPlotters/plotters/impedance_plotter.py +589 -0
- packages/tmsi/build/lib/TMSiPlotters/plotters/signal_plotter.py +1326 -0
- packages/tmsi/build/lib/TMSiSDK/__init__.py +54 -0
- packages/tmsi/build/lib/TMSiSDK/device.py +588 -0
- packages/tmsi/build/lib/TMSiSDK/devices/__init__.py +34 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/TMSi_Device_API.py +1764 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/__init__.py +34 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_device.py +1366 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_types.py +520 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/xml_saga_config.py +165 -0
- packages/tmsi/build/lib/TMSiSDK/error.py +95 -0
- packages/tmsi/build/lib/TMSiSDK/sample_data.py +63 -0
- packages/tmsi/build/lib/TMSiSDK/sample_data_server.py +99 -0
- packages/tmsi/build/lib/TMSiSDK/settings.py +45 -0
- packages/tmsi/build/lib/TMSiSDK/tmsi_device.py +111 -0
- packages/tmsi/build/lib/__init__.py +4 -0
- packages/tmsi/build/lib/apex_sdk/__init__.py +34 -0
- packages/tmsi/build/lib/apex_sdk/device/__init__.py +41 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API.py +1009 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_enums.py +239 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_structures.py +668 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_device.py +1611 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_dongle.py +38 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_event_reader.py +57 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_channel.py +44 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_config.py +150 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_const.py +36 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_impedance_channel.py +48 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_info.py +108 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/dongle_info.py +39 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/download_measurement.py +77 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/eeg_measurement.py +150 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/impedance_measurement.py +129 -0
- packages/tmsi/build/lib/apex_sdk/device/threads/conversion_thread.py +59 -0
- packages/tmsi/build/lib/apex_sdk/device/threads/sampling_thread.py +57 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_channel.py +83 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_device.py +201 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_device_enums.py +103 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_dongle.py +43 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_event_reader.py +50 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_measurement.py +118 -0
- packages/tmsi/build/lib/apex_sdk/sample_data_server/__init__.py +33 -0
- packages/tmsi/build/lib/apex_sdk/sample_data_server/event_data.py +44 -0
- packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data.py +50 -0
- packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data_server.py +136 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_errors/error.py +126 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_sdk.py +113 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/apex/apex_structure_generator.py +134 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/decorators.py +60 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/logger_filter.py +42 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/singleton.py +42 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/support_functions.py +72 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/tmsi_logger.py +98 -0
- py_neuromodulation/{helper.py → _write_example_dataset_helper.py} +1 -1
- py_neuromodulation/nm_EpochStream.py +2 -3
- py_neuromodulation/nm_IO.py +43 -70
- py_neuromodulation/nm_RMAP.py +308 -11
- py_neuromodulation/nm_analysis.py +1 -1
- py_neuromodulation/nm_artifacts.py +25 -0
- py_neuromodulation/nm_bispectra.py +64 -29
- py_neuromodulation/nm_bursts.py +44 -30
- py_neuromodulation/nm_coherence.py +2 -1
- py_neuromodulation/nm_features.py +4 -2
- py_neuromodulation/nm_filter.py +63 -32
- py_neuromodulation/nm_filter_preprocessing.py +91 -0
- py_neuromodulation/nm_fooof.py +47 -29
- py_neuromodulation/nm_mne_connectivity.py +1 -1
- py_neuromodulation/nm_normalization.py +50 -74
- py_neuromodulation/nm_oscillatory.py +151 -31
- py_neuromodulation/nm_plots.py +13 -10
- py_neuromodulation/nm_rereference.py +10 -8
- py_neuromodulation/nm_run_analysis.py +28 -13
- py_neuromodulation/nm_sharpwaves.py +103 -136
- py_neuromodulation/nm_stats.py +44 -30
- py_neuromodulation/nm_stream_abc.py +18 -10
- py_neuromodulation/nm_stream_offline.py +181 -40
- py_neuromodulation/utils/_logging.py +24 -0
- {py_neuromodulation-0.0.2.dist-info → py_neuromodulation-0.0.3.dist-info}/METADATA +182 -142
- py_neuromodulation-0.0.3.dist-info/RECORD +188 -0
- {py_neuromodulation-0.0.2.dist-info → py_neuromodulation-0.0.3.dist-info}/WHEEL +2 -1
- py_neuromodulation-0.0.3.dist-info/top_level.txt +5 -0
- tests/__init__.py +0 -0
- tests/conftest.py +117 -0
- tests/test_all_examples.py +10 -0
- tests/test_all_features.py +63 -0
- tests/test_bispectra.py +70 -0
- tests/test_bursts.py +105 -0
- tests/test_feature_sampling_rates.py +143 -0
- tests/test_fooof.py +16 -0
- tests/test_initalization_offline_stream.py +41 -0
- tests/test_multiprocessing.py +58 -0
- tests/test_nan_values.py +29 -0
- tests/test_nm_filter.py +95 -0
- tests/test_nm_resample.py +63 -0
- tests/test_normalization_settings.py +146 -0
- tests/test_notch_filter.py +31 -0
- tests/test_osc_features.py +424 -0
- tests/test_preprocessing_filter.py +151 -0
- tests/test_rereference.py +171 -0
- tests/test_sampling.py +57 -0
- tests/test_settings_change_after_init.py +76 -0
- tests/test_sharpwave.py +165 -0
- tests/test_target_channel_add.py +100 -0
- tests/test_timing.py +80 -0
- py_neuromodulation/data/README +0 -6
- py_neuromodulation/data/dataset_description.json +0 -8
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/MOV_aligned_features_ch_ECOG_RIGHT_0_all.png +0 -0
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/all_feature_plt.pdf +0 -0
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_FEATURES.csv +0 -182
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_LM_ML_RES.p +0 -0
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_SETTINGS.json +0 -273
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_SIDECAR.json +0 -6
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_decoding_performance.png +0 -0
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_nm_channels.csv +0 -11
- py_neuromodulation/data/participants.json +0 -32
- py_neuromodulation/data/participants.tsv +0 -2
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_coordsystem.json +0 -5
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_electrodes.tsv +0 -11
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_channels.tsv +0 -11
- 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 +0 -18
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vhdr +0 -35
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vmrk +0 -13
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/sub-testsub_ses-EphysMedOff_scans.tsv +0 -2
- py_neuromodulation/grid_cortex.tsv +0 -40
- py_neuromodulation/grid_subcortex.tsv +0 -1429
- py_neuromodulation/nm_settings.json +0 -290
- 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/py_neuromodulation.egg-info/PKG-INFO +0 -104
- py_neuromodulation/py_neuromodulation.egg-info/dependency_links.txt +0 -1
- py_neuromodulation/py_neuromodulation.egg-info/requires.txt +0 -26
- py_neuromodulation/py_neuromodulation.egg-info/top_level.txt +0 -1
- py_neuromodulation-0.0.2.dist-info/RECORD +0 -73
- /py_neuromodulation/{py_neuromodulation.egg-info/SOURCES.txt → utils/__init__.py} +0 -0
- {py_neuromodulation-0.0.2.dist-info → py_neuromodulation-0.0.3.dist-info}/LICENSE +0 -0
|
@@ -4,11 +4,11 @@ import pickle
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
import pandas as pd
|
|
6
6
|
|
|
7
|
-
import py_neuromodulation as
|
|
7
|
+
import py_neuromodulation as nm
|
|
8
8
|
from py_neuromodulation import nm_generator
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class EpochStream(
|
|
11
|
+
class EpochStream(nm.nm_stream.PNStream):
|
|
12
12
|
def __init__(self) -> None:
|
|
13
13
|
super().__init__()
|
|
14
14
|
|
|
@@ -43,7 +43,6 @@ class EpochStream(py_nm.nm_stream.PNStream):
|
|
|
43
43
|
def run(
|
|
44
44
|
self,
|
|
45
45
|
):
|
|
46
|
-
|
|
47
46
|
self._set_run()
|
|
48
47
|
# shape is n, channels=7, 800 Hz
|
|
49
48
|
|
py_neuromodulation/nm_IO.py
CHANGED
|
@@ -2,6 +2,10 @@ import json
|
|
|
2
2
|
import os
|
|
3
3
|
import sys
|
|
4
4
|
from pathlib import Path
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger("PynmLogger")
|
|
8
|
+
|
|
5
9
|
|
|
6
10
|
import mne
|
|
7
11
|
import mne_bids
|
|
@@ -9,6 +13,9 @@ import numpy as np
|
|
|
9
13
|
import pandas as pd
|
|
10
14
|
from scipy import io
|
|
11
15
|
|
|
16
|
+
import pyarrow
|
|
17
|
+
from pyarrow import csv
|
|
18
|
+
|
|
12
19
|
import py_neuromodulation
|
|
13
20
|
|
|
14
21
|
_PathLike = str | os.PathLike
|
|
@@ -27,7 +34,6 @@ def load_nm_channels(
|
|
|
27
34
|
reference Union[list, str]
|
|
28
35
|
"""
|
|
29
36
|
|
|
30
|
-
|
|
31
37
|
if isinstance(nm_channels, pd.DataFrame):
|
|
32
38
|
nm_ch_return = nm_channels
|
|
33
39
|
elif nm_channels:
|
|
@@ -39,6 +45,7 @@ def load_nm_channels(
|
|
|
39
45
|
|
|
40
46
|
return nm_ch_return
|
|
41
47
|
|
|
48
|
+
|
|
42
49
|
def read_BIDS_data(
|
|
43
50
|
PATH_RUN: _PathLike | mne_bids.BIDSPath,
|
|
44
51
|
BIDS_PATH: _PathLike | None = None,
|
|
@@ -70,10 +77,8 @@ def read_BIDS_data(
|
|
|
70
77
|
if raw_arr.info["line_freq"] is not None:
|
|
71
78
|
line_noise = int(raw_arr.info["line_freq"])
|
|
72
79
|
else:
|
|
73
|
-
|
|
74
|
-
"Line noise is not available in the data, using value of {} Hz."
|
|
75
|
-
line_noise
|
|
76
|
-
)
|
|
80
|
+
logger.info(
|
|
81
|
+
f"Line noise is not available in the data, using value of {line_noise} Hz."
|
|
77
82
|
)
|
|
78
83
|
return (
|
|
79
84
|
raw_arr,
|
|
@@ -120,7 +125,6 @@ def read_grid(PATH_GRIDS: _PathLike | None, grid_str: str) -> pd.DataFrame:
|
|
|
120
125
|
def get_annotations(
|
|
121
126
|
PATH_ANNOTATIONS: str, PATH_RUN: str, raw_arr: mne.io.RawArray
|
|
122
127
|
):
|
|
123
|
-
|
|
124
128
|
try:
|
|
125
129
|
annot = mne.read_annotations(
|
|
126
130
|
Path(PATH_ANNOTATIONS) / (os.path.basename(PATH_RUN)[:-5] + ".txt")
|
|
@@ -130,18 +134,19 @@ def get_annotations(
|
|
|
130
134
|
# annotations starting with "BAD" are omitted with reject_by_annotations 'omit' param
|
|
131
135
|
annot_data = raw_arr.get_data(reject_by_annotation="omit")
|
|
132
136
|
except FileNotFoundError:
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"expected location: "
|
|
137
|
+
logger.critical(
|
|
138
|
+
"Annotations file could not be found"
|
|
139
|
+
+ "expected location: "
|
|
136
140
|
+ str(
|
|
137
|
-
Path(PATH_ANNOTATIONS)
|
|
141
|
+
Path(PATH_ANNOTATIONS)
|
|
142
|
+
/ (os.path.basename(PATH_RUN)[:-5] + ".txt")
|
|
138
143
|
)
|
|
139
144
|
)
|
|
140
145
|
return annot, annot_data, raw_arr
|
|
141
146
|
|
|
142
147
|
|
|
143
148
|
def read_plot_modules(
|
|
144
|
-
PATH_PLOT: _PathLike = Path(__file__).absolute().parent / "plots"
|
|
149
|
+
PATH_PLOT: _PathLike = Path(__file__).absolute().parent / "plots",
|
|
145
150
|
):
|
|
146
151
|
"""Read required .mat files for plotting
|
|
147
152
|
|
|
@@ -180,55 +185,6 @@ def read_plot_modules(
|
|
|
180
185
|
)
|
|
181
186
|
|
|
182
187
|
|
|
183
|
-
def add_labels(
|
|
184
|
-
features: pd.DataFrame,
|
|
185
|
-
settings: dict,
|
|
186
|
-
nm_channels: pd.DataFrame,
|
|
187
|
-
raw_arr_data: np.ndarray,
|
|
188
|
-
fs: int | float,
|
|
189
|
-
) -> pd.DataFrame | None:
|
|
190
|
-
"""Given a constructed feature data frame, resample the target labels and add to dataframe
|
|
191
|
-
|
|
192
|
-
Parameters
|
|
193
|
-
----------
|
|
194
|
-
features : pd.DataFrame
|
|
195
|
-
computed feature dataframe
|
|
196
|
-
settings_wrapper : settings.py
|
|
197
|
-
initialized settings used for feature estimation
|
|
198
|
-
raw_arr_data : np.ndarray
|
|
199
|
-
raw data including target
|
|
200
|
-
|
|
201
|
-
Returns
|
|
202
|
-
-------
|
|
203
|
-
pd.DataFrame | None
|
|
204
|
-
computed feature dataframe including resampled features
|
|
205
|
-
"""
|
|
206
|
-
# resample_label
|
|
207
|
-
ind_label = np.where(nm_channels.target == 1)[0]
|
|
208
|
-
if ind_label.shape[0] == 0:
|
|
209
|
-
print("no target specified")
|
|
210
|
-
return None
|
|
211
|
-
|
|
212
|
-
offset_time = settings["segment_length_features_ms"]
|
|
213
|
-
|
|
214
|
-
offset_start = np.ceil(offset_time / 1000 * fs).astype(int)
|
|
215
|
-
data = raw_arr_data[ind_label, offset_start:]
|
|
216
|
-
if data.ndim == 1:
|
|
217
|
-
data = np.expand_dims(data, axis=0)
|
|
218
|
-
label_downsampled = data[
|
|
219
|
-
:,
|
|
220
|
-
:: int(np.ceil(fs / settings["sampling_rate_features_hz"])),
|
|
221
|
-
]
|
|
222
|
-
|
|
223
|
-
# and add to df
|
|
224
|
-
if features.shape[0] == label_downsampled.shape[1]:
|
|
225
|
-
for idx, label_ch in enumerate(nm_channels.name[ind_label]):
|
|
226
|
-
features[label_ch] = label_downsampled[idx, :]
|
|
227
|
-
else:
|
|
228
|
-
print("label dimensions don't match, saving downsampled label extra")
|
|
229
|
-
return features
|
|
230
|
-
|
|
231
|
-
|
|
232
188
|
def save_features_and_settings(
|
|
233
189
|
df_features,
|
|
234
190
|
run_analysis,
|
|
@@ -256,7 +212,7 @@ def save_features_and_settings(
|
|
|
256
212
|
|
|
257
213
|
# create out folder if doesn't exist
|
|
258
214
|
if not os.path.exists(os.path.join(out_path, folder_name)):
|
|
259
|
-
|
|
215
|
+
logger.Info(f"Creating output folder: {folder_name}")
|
|
260
216
|
os.makedirs(os.path.join(out_path, folder_name))
|
|
261
217
|
|
|
262
218
|
dict_sidecar = {"fs": fs, "coords": coords, "line_noise": line_noise}
|
|
@@ -267,6 +223,16 @@ def save_features_and_settings(
|
|
|
267
223
|
save_nm_channels(nm_channels, out_path, folder_name)
|
|
268
224
|
|
|
269
225
|
|
|
226
|
+
def write_csv(df, path_out):
|
|
227
|
+
"""
|
|
228
|
+
Function to save Pandas dataframes to disk as CSV using
|
|
229
|
+
PyArrow (almost 10x faster than Pandas)
|
|
230
|
+
Difference with pandas.df.to_csv() is that it does not
|
|
231
|
+
write an index column by default
|
|
232
|
+
"""
|
|
233
|
+
csv.write_csv(pyarrow.Table.from_pandas(df), path_out)
|
|
234
|
+
|
|
235
|
+
|
|
270
236
|
def save_settings(
|
|
271
237
|
settings: dict, path_out: _PathLike, folder_name: str | None = None
|
|
272
238
|
) -> None:
|
|
@@ -278,7 +244,7 @@ def save_settings(
|
|
|
278
244
|
|
|
279
245
|
with open(path_out, "w") as f:
|
|
280
246
|
json.dump(settings, f, indent=4)
|
|
281
|
-
|
|
247
|
+
logger.info(f"settings.json saved to {path_out}")
|
|
282
248
|
|
|
283
249
|
|
|
284
250
|
def save_nm_channels(
|
|
@@ -291,8 +257,8 @@ def save_nm_channels(
|
|
|
291
257
|
path_out = os.path.join(
|
|
292
258
|
path_out, folder_name, folder_name + "_nm_channels.csv"
|
|
293
259
|
)
|
|
294
|
-
nmchannels
|
|
295
|
-
|
|
260
|
+
write_csv(nmchannels, path_out)
|
|
261
|
+
logger.info(f"nm_channels.csv saved to {path_out}")
|
|
296
262
|
|
|
297
263
|
|
|
298
264
|
def save_features(
|
|
@@ -305,8 +271,8 @@ def save_features(
|
|
|
305
271
|
path_out = os.path.join(
|
|
306
272
|
path_out, folder_name, folder_name + "_FEATURES.csv"
|
|
307
273
|
)
|
|
308
|
-
df_features
|
|
309
|
-
|
|
274
|
+
write_csv(df_features, path_out)
|
|
275
|
+
logger.info(f"FEATURES.csv saved to {str(path_out)}")
|
|
310
276
|
|
|
311
277
|
|
|
312
278
|
def save_sidecar(
|
|
@@ -333,7 +299,7 @@ def save_general_dict(
|
|
|
333
299
|
indent=4,
|
|
334
300
|
separators=(",", ": "),
|
|
335
301
|
)
|
|
336
|
-
|
|
302
|
+
logger.info(f"{str_add} saved to " + str(path_out))
|
|
337
303
|
|
|
338
304
|
|
|
339
305
|
def default_json_convert(obj) -> list | int | float:
|
|
@@ -359,11 +325,11 @@ def read_settings(PATH: str) -> dict:
|
|
|
359
325
|
|
|
360
326
|
|
|
361
327
|
def read_features(PATH: str) -> pd.DataFrame:
|
|
362
|
-
return pd.read_csv(PATH + "_FEATURES.csv",
|
|
328
|
+
return pd.read_csv(PATH + "_FEATURES.csv", engine="pyarrow")
|
|
363
329
|
|
|
364
330
|
|
|
365
331
|
def read_nm_channels(PATH: str) -> pd.DataFrame:
|
|
366
|
-
return pd.read_csv(PATH + "_nm_channels.csv"
|
|
332
|
+
return pd.read_csv(PATH + "_nm_channels.csv")
|
|
367
333
|
|
|
368
334
|
|
|
369
335
|
def get_run_list_indir(PATH: str) -> list:
|
|
@@ -405,7 +371,14 @@ def get_paths_example_data():
|
|
|
405
371
|
|
|
406
372
|
PATH_BIDS = Path(SCRIPT_DIR) / "data"
|
|
407
373
|
|
|
408
|
-
PATH_RUN =
|
|
374
|
+
PATH_RUN = (
|
|
375
|
+
Path(SCRIPT_DIR)
|
|
376
|
+
/ "data"
|
|
377
|
+
/ f"sub-{sub}"
|
|
378
|
+
/ f"ses-{ses}"
|
|
379
|
+
/ datatype
|
|
380
|
+
/ RUN_NAME
|
|
381
|
+
)
|
|
409
382
|
|
|
410
383
|
# Provide a path for the output data.
|
|
411
384
|
PATH_OUT = PATH_BIDS / "derivatives"
|
py_neuromodulation/nm_RMAP.py
CHANGED
|
@@ -1,14 +1,304 @@
|
|
|
1
|
-
import enum
|
|
2
|
-
import nibabel as nib
|
|
3
1
|
import numpy as np
|
|
4
2
|
import os
|
|
5
|
-
|
|
3
|
+
import wget
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# from numba import jit
|
|
6
7
|
from scipy import stats
|
|
8
|
+
import scipy.io as sio
|
|
7
9
|
import pandas as pd
|
|
10
|
+
from typing import Union, Tuple, List
|
|
11
|
+
import nibabel as nib
|
|
12
|
+
from matplotlib import pyplot as plt
|
|
13
|
+
|
|
14
|
+
import py_neuromodulation
|
|
8
15
|
|
|
9
16
|
from py_neuromodulation import nm_plots
|
|
10
17
|
|
|
11
|
-
|
|
18
|
+
LIST_STRUC_UNCONNECTED_GRIDPOINTS_HULL = [256, 385, 417, 447, 819, 914]
|
|
19
|
+
LIST_STRUC_UNCONNECTED_GRIDPOINTS_WHOLEBRAIN = [
|
|
20
|
+
1,
|
|
21
|
+
8,
|
|
22
|
+
16,
|
|
23
|
+
33,
|
|
24
|
+
34,
|
|
25
|
+
35,
|
|
26
|
+
36,
|
|
27
|
+
37,
|
|
28
|
+
51,
|
|
29
|
+
75,
|
|
30
|
+
77,
|
|
31
|
+
78,
|
|
32
|
+
99,
|
|
33
|
+
109,
|
|
34
|
+
115,
|
|
35
|
+
136,
|
|
36
|
+
155,
|
|
37
|
+
170,
|
|
38
|
+
210,
|
|
39
|
+
215,
|
|
40
|
+
243,
|
|
41
|
+
352,
|
|
42
|
+
359,
|
|
43
|
+
361,
|
|
44
|
+
415,
|
|
45
|
+
416,
|
|
46
|
+
422,
|
|
47
|
+
529,
|
|
48
|
+
567,
|
|
49
|
+
569,
|
|
50
|
+
622,
|
|
51
|
+
623,
|
|
52
|
+
625,
|
|
53
|
+
627,
|
|
54
|
+
632,
|
|
55
|
+
633,
|
|
56
|
+
634,
|
|
57
|
+
635,
|
|
58
|
+
639,
|
|
59
|
+
640,
|
|
60
|
+
641,
|
|
61
|
+
643,
|
|
62
|
+
644,
|
|
63
|
+
650,
|
|
64
|
+
661,
|
|
65
|
+
663,
|
|
66
|
+
667,
|
|
67
|
+
683,
|
|
68
|
+
684,
|
|
69
|
+
685,
|
|
70
|
+
704,
|
|
71
|
+
708,
|
|
72
|
+
722,
|
|
73
|
+
839,
|
|
74
|
+
840,
|
|
75
|
+
905,
|
|
76
|
+
993,
|
|
77
|
+
1011,
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class ConnectivityChannelSelector:
|
|
82
|
+
|
|
83
|
+
def __init__(
|
|
84
|
+
self,
|
|
85
|
+
whole_brain_connectome: bool = True,
|
|
86
|
+
func_connectivity: bool = True,
|
|
87
|
+
) -> None:
|
|
88
|
+
"""ConnectivityChannelSelector
|
|
89
|
+
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
whole_brain_connectome : bool, optional
|
|
93
|
+
if True a 1236 whole-brain point grid is chosen,
|
|
94
|
+
if False, a 1025 point grid of the cortical hull is loaded,
|
|
95
|
+
by default True
|
|
96
|
+
func_connectivity : bool, optional
|
|
97
|
+
if true, functional connectivity fMRI is loaded,
|
|
98
|
+
if false structural dMRIby, default True
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
self.connectome_name = self._get_connectome_name(
|
|
102
|
+
whole_brain_connectome, func_connectivity
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
self.whole_brain_connectome = whole_brain_connectome
|
|
106
|
+
self.func_connectivity = func_connectivity
|
|
107
|
+
|
|
108
|
+
self.PATH_CONN_DECODING = os.path.join(
|
|
109
|
+
py_neuromodulation.__path__[0],
|
|
110
|
+
"ConnectivityDecoding",
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
if whole_brain_connectome:
|
|
114
|
+
self.PATH_GRID = os.path.join(
|
|
115
|
+
self.PATH_CONN_DECODING,
|
|
116
|
+
"mni_coords_whole_brain.mat",
|
|
117
|
+
)
|
|
118
|
+
self.grid = sio.loadmat(self.PATH_GRID)["downsample_ctx"]
|
|
119
|
+
if func_connectivity is False:
|
|
120
|
+
# reduce the grid to only valid points that are not in LIST_STRUC_UNCONNECTED_GRIDPOINTS_WHOLEBRAIN
|
|
121
|
+
self.grid = np.delete(
|
|
122
|
+
self.grid,
|
|
123
|
+
LIST_STRUC_UNCONNECTED_GRIDPOINTS_WHOLEBRAIN,
|
|
124
|
+
axis=0,
|
|
125
|
+
)
|
|
126
|
+
else:
|
|
127
|
+
self.PATH_GRID = os.path.join(
|
|
128
|
+
self.PATH_CONN_DECODING,
|
|
129
|
+
"mni_coords_cortical_surface.mat",
|
|
130
|
+
)
|
|
131
|
+
self.grid = sio.loadmat(self.PATH_GRID)["downsample_ctx"]
|
|
132
|
+
if func_connectivity is False:
|
|
133
|
+
# reduce the grid to only valid points that are not in LIST_STRUC_UNCONNECTED_GRIDPOINTS_HULL
|
|
134
|
+
self.grid = np.delete(
|
|
135
|
+
self.grid, LIST_STRUC_UNCONNECTED_GRIDPOINTS_HULL, axis=0
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
if func_connectivity:
|
|
139
|
+
self.RMAP_arr = nib.load(
|
|
140
|
+
os.path.join(self.PATH_CONN_DECODING, "RMAP_func_all.nii")
|
|
141
|
+
).get_fdata()
|
|
142
|
+
else:
|
|
143
|
+
self.RMAP_arr = nib.load(
|
|
144
|
+
os.path.join(self.PATH_CONN_DECODING, "RMAP_struc.nii")
|
|
145
|
+
).get_fdata()
|
|
146
|
+
|
|
147
|
+
def _get_connectome_name(
|
|
148
|
+
self, whole_brain_connectome: str, func_connectivity: str
|
|
149
|
+
):
|
|
150
|
+
|
|
151
|
+
connectome_name = "connectome_"
|
|
152
|
+
if whole_brain_connectome:
|
|
153
|
+
connectome_name += "whole_brain_"
|
|
154
|
+
else:
|
|
155
|
+
connectome_name += "hull_"
|
|
156
|
+
if func_connectivity:
|
|
157
|
+
connectome_name += "func"
|
|
158
|
+
else:
|
|
159
|
+
connectome_name += "struc"
|
|
160
|
+
return connectome_name
|
|
161
|
+
|
|
162
|
+
def get_available_connectomes(self) -> list:
|
|
163
|
+
"""Return list of saved connectomes in the
|
|
164
|
+
package folder/ConnectivityDecoding/connectome_folder/ folder.
|
|
165
|
+
|
|
166
|
+
Returns
|
|
167
|
+
-------
|
|
168
|
+
list_connectomes: list
|
|
169
|
+
"""
|
|
170
|
+
return os.listdir(
|
|
171
|
+
os.path.join(
|
|
172
|
+
self.PATH_CONN_DECODING,
|
|
173
|
+
"connectome_folder",
|
|
174
|
+
)
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
def plot_grid(self) -> None:
|
|
178
|
+
"""Plot the loaded template grid that passed coordinates are matched to."""
|
|
179
|
+
|
|
180
|
+
fig = plt.figure()
|
|
181
|
+
ax = fig.add_subplot(111, projection="3d")
|
|
182
|
+
ax.scatter(
|
|
183
|
+
self.grid[:, 0], self.grid[:, 1], self.grid[:, 2], s=50, alpha=0.2
|
|
184
|
+
)
|
|
185
|
+
plt.show()
|
|
186
|
+
|
|
187
|
+
def get_closest_node(
|
|
188
|
+
self, coord: Union[List, np.array]
|
|
189
|
+
) -> Tuple[List, List]:
|
|
190
|
+
"""Given a list or np.array of coordinates, return the closest nodes in the
|
|
191
|
+
grid and their indices.
|
|
192
|
+
|
|
193
|
+
Parameters
|
|
194
|
+
----------
|
|
195
|
+
coord : np.array
|
|
196
|
+
MNI coordinates with shape (num_channels, 3)
|
|
197
|
+
|
|
198
|
+
Returns
|
|
199
|
+
-------
|
|
200
|
+
Tuple[List, List]
|
|
201
|
+
Grid coordinates, grid indices
|
|
202
|
+
"""
|
|
203
|
+
|
|
204
|
+
idx_ = []
|
|
205
|
+
for c in coord:
|
|
206
|
+
dist = np.linalg.norm(self.grid - c, axis=1)
|
|
207
|
+
idx_.append(np.argmin(dist))
|
|
208
|
+
|
|
209
|
+
return [self.grid[idx] for idx in idx_], idx_
|
|
210
|
+
|
|
211
|
+
def get_rmap_correlations(
|
|
212
|
+
self, fps: Union[list, np.array], RMAP_use: np.array = None
|
|
213
|
+
) -> List:
|
|
214
|
+
"""Calculate correlations of passed fingerprints with the RMAP
|
|
215
|
+
|
|
216
|
+
Parameters
|
|
217
|
+
----------
|
|
218
|
+
fps : Union[list, np.array]
|
|
219
|
+
List of fingerprints
|
|
220
|
+
RMAP_use : np.array, optional
|
|
221
|
+
Passed RMAP, by default None
|
|
222
|
+
|
|
223
|
+
Returns
|
|
224
|
+
-------
|
|
225
|
+
List
|
|
226
|
+
correlation values
|
|
227
|
+
"""
|
|
228
|
+
|
|
229
|
+
RMAP_ = self.RMAP_arr if RMAP_use is None else RMAP_use
|
|
230
|
+
RMAP_ = RMAP_.flatten()
|
|
231
|
+
corrs = []
|
|
232
|
+
for fp in fps:
|
|
233
|
+
corrs.append(np.corrcoef(RMAP_, fp.flatten())[0][1])
|
|
234
|
+
return corrs
|
|
235
|
+
|
|
236
|
+
def load_connectome(
|
|
237
|
+
self,
|
|
238
|
+
whole_brain_connectome: bool = None,
|
|
239
|
+
func_connectivity: bool = None,
|
|
240
|
+
) -> None:
|
|
241
|
+
"""Load connectome, if not available download connectome from
|
|
242
|
+
Zenodo.
|
|
243
|
+
|
|
244
|
+
Parameters
|
|
245
|
+
----------
|
|
246
|
+
whole_brain_connectome : bool, optional
|
|
247
|
+
if true whole brain connectome
|
|
248
|
+
if false cortical hull grid connectome, by default None
|
|
249
|
+
func_connectivity : bool, optional
|
|
250
|
+
if true fMRI if false dMRI, by default None
|
|
251
|
+
"""
|
|
252
|
+
|
|
253
|
+
if whole_brain_connectome is not None:
|
|
254
|
+
self.whole_brain_connectome = whole_brain_connectome
|
|
255
|
+
if func_connectivity is not None:
|
|
256
|
+
self.func_connectivity = func_connectivity
|
|
257
|
+
|
|
258
|
+
self.connectome_name = self._get_connectome_name(
|
|
259
|
+
self.whole_brain_connectome, self.func_connectivity
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
PATH_CONNECTOME = os.path.join(
|
|
263
|
+
self.PATH_CONN_DECODING,
|
|
264
|
+
"connectome_folder",
|
|
265
|
+
self.connectome_name + ".mat",
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
if os.path.exists(PATH_CONNECTOME) is False:
|
|
269
|
+
user_input = input(
|
|
270
|
+
"Do you want to download the connectome? (yes/no): "
|
|
271
|
+
).lower()
|
|
272
|
+
if user_input == "yes":
|
|
273
|
+
self._download_connectome()
|
|
274
|
+
elif user_input == "no":
|
|
275
|
+
print("Connectome missing, has to be downloaded")
|
|
276
|
+
|
|
277
|
+
self.connectome = sio.loadmat(PATH_CONNECTOME)
|
|
278
|
+
|
|
279
|
+
def get_grid_fingerprints(self, grid_idx: Union[list, np.array]) -> list:
|
|
280
|
+
return [self.connectome[str(grid_idx)] for grid_idx in grid_idx]
|
|
281
|
+
|
|
282
|
+
def download_connectome(
|
|
283
|
+
self,
|
|
284
|
+
):
|
|
285
|
+
# download the connectome from the Zenodo API
|
|
286
|
+
print("Downloading the connectome...")
|
|
287
|
+
|
|
288
|
+
record_id = "10804702"
|
|
289
|
+
file_name = self.connectome_name
|
|
290
|
+
|
|
291
|
+
wget.download(
|
|
292
|
+
f"https://zenodo.org/api/records/{record_id}/files/{file_name}/content",
|
|
293
|
+
out=os.path.join(
|
|
294
|
+
self.PATH_CONN_DECODING,
|
|
295
|
+
"connectome_folder",
|
|
296
|
+
f"{self.connectome_name}.mat",
|
|
297
|
+
),
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
class RMAPCross_Val_ChannelSelector:
|
|
12
302
|
|
|
13
303
|
def __init__(self) -> None:
|
|
14
304
|
pass
|
|
@@ -90,7 +380,7 @@ class RMAPChannelSelector:
|
|
|
90
380
|
return r
|
|
91
381
|
|
|
92
382
|
@staticmethod
|
|
93
|
-
|
|
383
|
+
# @jit(nopython=True)
|
|
94
384
|
def calculate_RMap_numba(fp, performances):
|
|
95
385
|
# The RMap also needs performances; for every fingerprint / channel
|
|
96
386
|
# Save the corresponding performance
|
|
@@ -112,7 +402,7 @@ class RMAPChannelSelector:
|
|
|
112
402
|
return RMAP
|
|
113
403
|
|
|
114
404
|
@staticmethod
|
|
115
|
-
|
|
405
|
+
# @jit(nopython=True)
|
|
116
406
|
def get_corr_numba(fp, fp_test):
|
|
117
407
|
val = np.corrcoef(fp_test, fp)[0][1]
|
|
118
408
|
return val
|
|
@@ -126,7 +416,7 @@ class RMAPChannelSelector:
|
|
|
126
416
|
per_predict = []
|
|
127
417
|
|
|
128
418
|
for idx_left_out, f_left_out in enumerate(l_fps_names):
|
|
129
|
-
print(idx_left_out)
|
|
419
|
+
# print(idx_left_out)
|
|
130
420
|
l_cv = l_fps_dat.copy()
|
|
131
421
|
per_cv = l_per.copy()
|
|
132
422
|
|
|
@@ -160,7 +450,7 @@ class RMAPChannelSelector:
|
|
|
160
450
|
per_left_out = []
|
|
161
451
|
|
|
162
452
|
for subject_test in sub_list:
|
|
163
|
-
print(subject_test)
|
|
453
|
+
# print(subject_test)
|
|
164
454
|
idx_test = [
|
|
165
455
|
idx for idx, f in enumerate(l_fps_names) if subject_test in f
|
|
166
456
|
]
|
|
@@ -224,11 +514,18 @@ class RMAPChannelSelector:
|
|
|
224
514
|
idx_max = np.argmax(np.array(fp_pairs)[:, 3])
|
|
225
515
|
return fp_pairs[idx_max][0:3]
|
|
226
516
|
|
|
227
|
-
def plot_performance_prediction_correlation(
|
|
517
|
+
def plot_performance_prediction_correlation(
|
|
518
|
+
per_left_out, per_predict, out_path_save: str = None
|
|
519
|
+
):
|
|
228
520
|
df_plt_corr = pd.DataFrame()
|
|
229
521
|
df_plt_corr["test_performance"] = per_left_out
|
|
230
|
-
df_plt_corr["struct_conn_predict"] =
|
|
522
|
+
df_plt_corr["struct_conn_predict"] = (
|
|
523
|
+
per_predict # change "struct" with "funct" for functional connectivity
|
|
524
|
+
)
|
|
231
525
|
|
|
232
526
|
nm_plots.reg_plot(
|
|
233
|
-
x_col="test_performance",
|
|
527
|
+
x_col="test_performance",
|
|
528
|
+
y_col="struct_conn_predict",
|
|
529
|
+
data=df_plt_corr,
|
|
530
|
+
out_path_save=out_path_save,
|
|
234
531
|
)
|
|
@@ -221,7 +221,7 @@ class Feature_Reader:
|
|
|
221
221
|
pd.DataFrame: z-scored feature_arr
|
|
222
222
|
"""
|
|
223
223
|
cols_norm = [c for c in self.feature_arr.columns if "time" not in c]
|
|
224
|
-
feature_arr_norm = stats.zscore(self.feature_arr[cols_norm])
|
|
224
|
+
feature_arr_norm = stats.zscore(self.feature_arr[cols_norm], nan_policy="omit")
|
|
225
225
|
feature_arr_norm["time"] = self.feature_arr["time"]
|
|
226
226
|
return feature_arr_norm
|
|
227
227
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from pyparrm import PARRM
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class PARRMArtifactRejection:
|
|
5
|
+
def __init__(self, data, sampling_freq, artefact_freq, verbose=False):
|
|
6
|
+
self.data = data
|
|
7
|
+
self.sampling_freq = sampling_freq
|
|
8
|
+
self.artefact_freq = artefact_freq
|
|
9
|
+
self.verbose = verbose
|
|
10
|
+
|
|
11
|
+
self.parrm = PARRM(
|
|
12
|
+
data=data,
|
|
13
|
+
sampling_freq=sampling_freq,
|
|
14
|
+
artefact_freq=artefact_freq,
|
|
15
|
+
verbose=False,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
def filter_data(self):
|
|
19
|
+
self.parrm.find_period()
|
|
20
|
+
self.parrm.create_filter(
|
|
21
|
+
filter_direction="both",
|
|
22
|
+
)
|
|
23
|
+
filtered_data = self.parrm.filter_data()
|
|
24
|
+
|
|
25
|
+
return filtered_data
|