py-neuromodulation 0.0.4__py3-none-any.whl → 0.0.6__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.
Files changed (109) hide show
  1. py_neuromodulation/ConnectivityDecoding/_get_grid_hull.m +34 -34
  2. py_neuromodulation/ConnectivityDecoding/_get_grid_whole_brain.py +95 -106
  3. py_neuromodulation/ConnectivityDecoding/_helper_write_connectome.py +107 -119
  4. py_neuromodulation/__init__.py +80 -13
  5. py_neuromodulation/{nm_RMAP.py → analysis/RMAP.py} +496 -531
  6. py_neuromodulation/analysis/__init__.py +4 -0
  7. py_neuromodulation/{nm_decode.py → analysis/decode.py} +918 -992
  8. py_neuromodulation/{nm_analysis.py → analysis/feature_reader.py} +994 -1074
  9. py_neuromodulation/{nm_plots.py → analysis/plots.py} +627 -612
  10. py_neuromodulation/{nm_stats.py → analysis/stats.py} +458 -480
  11. py_neuromodulation/data/README +6 -6
  12. py_neuromodulation/data/dataset_description.json +8 -8
  13. py_neuromodulation/data/participants.json +32 -32
  14. py_neuromodulation/data/participants.tsv +2 -2
  15. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_coordsystem.json +5 -5
  16. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_electrodes.tsv +11 -11
  17. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_channels.tsv +11 -11
  18. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.json +18 -18
  19. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vhdr +35 -35
  20. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vmrk +13 -13
  21. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/sub-testsub_ses-EphysMedOff_scans.tsv +2 -2
  22. py_neuromodulation/default_settings.yaml +241 -0
  23. py_neuromodulation/features/__init__.py +31 -0
  24. py_neuromodulation/features/bandpower.py +165 -0
  25. py_neuromodulation/features/bispectra.py +157 -0
  26. py_neuromodulation/features/bursts.py +297 -0
  27. py_neuromodulation/features/coherence.py +255 -0
  28. py_neuromodulation/features/feature_processor.py +121 -0
  29. py_neuromodulation/features/fooof.py +142 -0
  30. py_neuromodulation/features/hjorth_raw.py +57 -0
  31. py_neuromodulation/features/linelength.py +21 -0
  32. py_neuromodulation/features/mne_connectivity.py +148 -0
  33. py_neuromodulation/features/nolds.py +94 -0
  34. py_neuromodulation/features/oscillatory.py +249 -0
  35. py_neuromodulation/features/sharpwaves.py +432 -0
  36. py_neuromodulation/filter/__init__.py +3 -0
  37. py_neuromodulation/filter/kalman_filter.py +67 -0
  38. py_neuromodulation/filter/kalman_filter_external.py +1890 -0
  39. py_neuromodulation/filter/mne_filter.py +128 -0
  40. py_neuromodulation/filter/notch_filter.py +93 -0
  41. py_neuromodulation/grid_cortex.tsv +40 -40
  42. py_neuromodulation/liblsl/libpugixml.so.1.12 +0 -0
  43. py_neuromodulation/liblsl/linux/bionic_amd64/liblsl.1.16.2.so +0 -0
  44. py_neuromodulation/liblsl/linux/bookworm_amd64/liblsl.1.16.2.so +0 -0
  45. py_neuromodulation/liblsl/linux/focal_amd46/liblsl.1.16.2.so +0 -0
  46. py_neuromodulation/liblsl/linux/jammy_amd64/liblsl.1.16.2.so +0 -0
  47. py_neuromodulation/liblsl/linux/jammy_x86/liblsl.1.16.2.so +0 -0
  48. py_neuromodulation/liblsl/linux/noble_amd64/liblsl.1.16.2.so +0 -0
  49. py_neuromodulation/liblsl/macos/amd64/liblsl.1.16.2.dylib +0 -0
  50. py_neuromodulation/liblsl/macos/arm64/liblsl.1.16.0.dylib +0 -0
  51. py_neuromodulation/liblsl/windows/amd64/liblsl.1.16.2.dll +0 -0
  52. py_neuromodulation/liblsl/windows/x86/liblsl.1.16.2.dll +0 -0
  53. py_neuromodulation/processing/__init__.py +10 -0
  54. py_neuromodulation/{nm_artifacts.py → processing/artifacts.py} +29 -25
  55. py_neuromodulation/processing/data_preprocessor.py +77 -0
  56. py_neuromodulation/processing/filter_preprocessing.py +78 -0
  57. py_neuromodulation/processing/normalization.py +175 -0
  58. py_neuromodulation/{nm_projection.py → processing/projection.py} +370 -394
  59. py_neuromodulation/{nm_rereference.py → processing/rereference.py} +97 -95
  60. py_neuromodulation/{nm_resample.py → processing/resample.py} +56 -50
  61. py_neuromodulation/stream/__init__.py +3 -0
  62. py_neuromodulation/stream/data_processor.py +325 -0
  63. py_neuromodulation/stream/generator.py +53 -0
  64. py_neuromodulation/stream/mnelsl_player.py +94 -0
  65. py_neuromodulation/stream/mnelsl_stream.py +120 -0
  66. py_neuromodulation/stream/settings.py +292 -0
  67. py_neuromodulation/stream/stream.py +427 -0
  68. py_neuromodulation/utils/__init__.py +2 -0
  69. py_neuromodulation/{nm_define_nmchannels.py → utils/channels.py} +305 -302
  70. py_neuromodulation/utils/database.py +149 -0
  71. py_neuromodulation/utils/io.py +378 -0
  72. py_neuromodulation/utils/keyboard.py +52 -0
  73. py_neuromodulation/utils/logging.py +66 -0
  74. py_neuromodulation/utils/types.py +251 -0
  75. {py_neuromodulation-0.0.4.dist-info → py_neuromodulation-0.0.6.dist-info}/METADATA +28 -33
  76. py_neuromodulation-0.0.6.dist-info/RECORD +89 -0
  77. {py_neuromodulation-0.0.4.dist-info → py_neuromodulation-0.0.6.dist-info}/WHEEL +1 -1
  78. {py_neuromodulation-0.0.4.dist-info → py_neuromodulation-0.0.6.dist-info}/licenses/LICENSE +21 -21
  79. py_neuromodulation/FieldTrip.py +0 -589
  80. py_neuromodulation/_write_example_dataset_helper.py +0 -65
  81. py_neuromodulation/nm_EpochStream.py +0 -92
  82. py_neuromodulation/nm_IO.py +0 -417
  83. py_neuromodulation/nm_across_patient_decoding.py +0 -927
  84. py_neuromodulation/nm_bispectra.py +0 -168
  85. py_neuromodulation/nm_bursts.py +0 -198
  86. py_neuromodulation/nm_coherence.py +0 -205
  87. py_neuromodulation/nm_cohortwrapper.py +0 -435
  88. py_neuromodulation/nm_eval_timing.py +0 -239
  89. py_neuromodulation/nm_features.py +0 -116
  90. py_neuromodulation/nm_features_abc.py +0 -39
  91. py_neuromodulation/nm_filter.py +0 -219
  92. py_neuromodulation/nm_filter_preprocessing.py +0 -91
  93. py_neuromodulation/nm_fooof.py +0 -159
  94. py_neuromodulation/nm_generator.py +0 -37
  95. py_neuromodulation/nm_hjorth_raw.py +0 -73
  96. py_neuromodulation/nm_kalmanfilter.py +0 -58
  97. py_neuromodulation/nm_linelength.py +0 -33
  98. py_neuromodulation/nm_mne_connectivity.py +0 -112
  99. py_neuromodulation/nm_nolds.py +0 -93
  100. py_neuromodulation/nm_normalization.py +0 -214
  101. py_neuromodulation/nm_oscillatory.py +0 -448
  102. py_neuromodulation/nm_run_analysis.py +0 -435
  103. py_neuromodulation/nm_settings.json +0 -338
  104. py_neuromodulation/nm_settings.py +0 -68
  105. py_neuromodulation/nm_sharpwaves.py +0 -401
  106. py_neuromodulation/nm_stream_abc.py +0 -218
  107. py_neuromodulation/nm_stream_offline.py +0 -359
  108. py_neuromodulation/utils/_logging.py +0 -24
  109. py_neuromodulation-0.0.4.dist-info/RECORD +0 -72
@@ -1,34 +1,34 @@
1
- addpath('C:\code\wjn_toolbox');
2
- addpath(genpath('C:\code\leaddbs'));
3
- addpath(genpath('C:\code\spm12'));
4
-
5
-
6
- %%
7
- ctx = wjn_mni_cortex();
8
- downsample_ctx=ctx.vertices(1:20:end,:); %downsample by 10
9
-
10
- save("downsampled_cortex.mat", "downsample_ctx")
11
-
12
- figure;
13
- scatter3(downsample_ctx(:,1), downsample_ctx(:,2), downsample_ctx(:,3), 'filled');
14
- title('3D Scatter Plot Example');
15
- xlabel('X-axis');
16
- ylabel('Y-axis');
17
- zlabel('Z-axis');
18
- grid on;
19
-
20
-
21
-
22
- PATH_OUT = "D:\Connectome_RMAP_OUT\ROIs";
23
-
24
- for a =1:size(downsample_ctx,1)
25
- disp(a)
26
- roiname = fullfile(PATH_OUT, strcat('ROI-', string(a), '.nii'));
27
- mni = [downsample_ctx(a, 1) downsample_ctx(a, 2) downsample_ctx(a, 3)];
28
- wjn_spherical_roi(roiname,mni,4);
29
- end
30
-
31
-
32
-
33
-
34
-
1
+ addpath('C:\code\wjn_toolbox');
2
+ addpath(genpath('C:\code\leaddbs'));
3
+ addpath(genpath('C:\code\spm12'));
4
+
5
+
6
+ %%
7
+ ctx = wjn_mni_cortex();
8
+ downsample_ctx=ctx.vertices(1:20:end,:); %downsample by 10
9
+
10
+ save("downsampled_cortex.mat", "downsample_ctx")
11
+
12
+ figure;
13
+ scatter3(downsample_ctx(:,1), downsample_ctx(:,2), downsample_ctx(:,3), 'filled');
14
+ title('3D Scatter Plot Example');
15
+ xlabel('X-axis');
16
+ ylabel('Y-axis');
17
+ zlabel('Z-axis');
18
+ grid on;
19
+
20
+
21
+
22
+ PATH_OUT = "D:\Connectome_RMAP_OUT\ROIs";
23
+
24
+ for a =1:size(downsample_ctx,1)
25
+ disp(a)
26
+ roiname = fullfile(PATH_OUT, strcat('ROI-', string(a), '.nii'));
27
+ mni = [downsample_ctx(a, 1) downsample_ctx(a, 2) downsample_ctx(a, 3)];
28
+ wjn_spherical_roi(roiname,mni,4);
29
+ end
30
+
31
+
32
+
33
+
34
+
@@ -1,106 +1,95 @@
1
- import nibabel as nib
2
- import numpy as np
3
- import scipy.io as sio
4
- import os
5
- from matplotlib import pyplot as plt
6
-
7
-
8
- class NiiToMNI:
9
-
10
- def __init__(
11
- self,
12
- PATH_nii_file: str = r"C:\code\RMap_ROI_Estimation\Automated Anatomical Labeling 3 (Rolls 2020).nii",
13
- ) -> None:
14
-
15
- self.img = nib.load(PATH_nii_file)
16
- self.data = self.img.get_fdata()
17
-
18
- def downsample_nii(
19
- self,
20
- resampling_factor: int = 150,
21
- ):
22
-
23
- # PATH_MNI_TO_ATLAS = r"C:\code\mni_to_atlas\src\mni_to_atlas\atlases\AAL.nii"
24
- # img_mni_to_atlas = nib.load(PATH_MNI_TO_ATLAS)
25
-
26
- x_dim, y_dim, z_dim = self.data.shape
27
-
28
- # Create arrays of voxel coordinates
29
- x_coords, y_coords, z_coords = np.meshgrid(
30
- range(x_dim), range(y_dim), range(z_dim), indexing="ij"
31
- )
32
-
33
- # Downsample here the voxels --> check lateron if the voxels have non-zero values
34
- x_c_flatten = x_coords.flatten()[::resampling_factor]
35
- y_c_flatten = y_coords.flatten()[::resampling_factor]
36
- z_c_flatten = z_coords.flatten()[::resampling_factor]
37
-
38
- # Combine coordinates into a single array
39
- voxel_coordinates = np.column_stack(
40
- (
41
- x_c_flatten,
42
- y_c_flatten,
43
- z_c_flatten,
44
- np.ones(x_c_flatten.shape[0]),
45
- )
46
- )
47
-
48
- aff_m = self.img.affine
49
- aff_m[0, 0] = 2
50
- aff_m[0, 3] = -90
51
-
52
- mni_coordinates = np.dot(aff_m, voxel_coordinates.T).T[:, :3]
53
-
54
- return mni_coordinates
55
-
56
- def select_non_zero_voxels(
57
- self,
58
- mni_coordinates: np.array,
59
- ):
60
-
61
- coords = np.hstack(
62
- (mni_coordinates, np.ones((mni_coordinates.shape[0], 1)))
63
- )
64
-
65
- # and transform back to get the voxel values
66
- voxels_downsampled = np.array(
67
- np.linalg.solve(self.img.affine, coords.T).T
68
- ).astype(int)[:, :3]
69
-
70
- ival = []
71
- coord_ = []
72
- for i in range(voxels_downsampled.shape[0]):
73
- ival.append(self.data[tuple(voxels_downsampled[i, :])])
74
- coord_.append(mni_coordinates[i, :])
75
-
76
- # get only voxel values non-zero
77
- ival = np.array(ival)
78
- coord_ = np.array(coord_)
79
- ival_non_zero = ival[ival != 0]
80
- coord_non_zero = coord_[ival != 0]
81
- print(coord_non_zero.shape)
82
-
83
- return coord_non_zero, ival_non_zero
84
-
85
- def plot_3d_coordinates(self, coord_non_zero: np.array):
86
- fig = plt.figure()
87
- ax = fig.add_subplot(111, projection="3d")
88
- ax.scatter(
89
- coord_non_zero[:, 0],
90
- coord_non_zero[:, 1],
91
- coord_non_zero[:, 2],
92
- s=50,
93
- alpha=0.2,
94
- )
95
- plt.show()
96
-
97
-
98
- if __name__ == "__main__":
99
-
100
- nii_to_mni = NiiToMNI(
101
- PATH_nii_file=r"C:\code\py_neuromodulation\ConnectivityDecoding\Automated Anatomical Labeling 3 (Rolls 2020).nii"
102
- )
103
- mni_coordinates = nii_to_mni.downsample_nii(resampling_factor=150)
104
- coord_non_zero, ival_non_zero = nii_to_mni.select_non_zero_voxels(
105
- mni_coordinates
106
- )
1
+ import nibabel as nib
2
+ import numpy as np
3
+ from matplotlib import pyplot as plt
4
+
5
+
6
+ class NiiToMNI:
7
+ def __init__(
8
+ self,
9
+ PATH_nii_file: str = r"C:\code\RMap_ROI_Estimation\Automated Anatomical Labeling 3 (Rolls 2020).nii",
10
+ ) -> None:
11
+ self.img = nib.Nifti1Image.from_filename(PATH_nii_file)
12
+ self.data = self.img.get_fdata()
13
+
14
+ def downsample_nii(
15
+ self,
16
+ resampling_factor: int = 150,
17
+ ):
18
+ # PATH_MNI_TO_ATLAS = r"C:\code\mni_to_atlas\src\mni_to_atlas\atlases\AAL.nii"
19
+ # img_mni_to_atlas = nib.load(PATH_MNI_TO_ATLAS)
20
+
21
+ x_dim, y_dim, z_dim = self.data.shape
22
+
23
+ # Create arrays of voxel coordinates
24
+ x_coords, y_coords, z_coords = np.meshgrid(
25
+ range(x_dim), range(y_dim), range(z_dim), indexing="ij"
26
+ )
27
+
28
+ # Downsample here the voxels --> check lateron if the voxels have non-zero values
29
+ x_c_flatten = x_coords.flatten()[::resampling_factor]
30
+ y_c_flatten = y_coords.flatten()[::resampling_factor]
31
+ z_c_flatten = z_coords.flatten()[::resampling_factor]
32
+
33
+ # Combine coordinates into a single array
34
+ voxel_coordinates = np.column_stack(
35
+ (
36
+ x_c_flatten,
37
+ y_c_flatten,
38
+ z_c_flatten,
39
+ np.ones(x_c_flatten.shape[0]),
40
+ )
41
+ )
42
+
43
+ aff_m = self.img.affine
44
+ aff_m[0, 0] = 2
45
+ aff_m[0, 3] = -90
46
+
47
+ mni_coordinates = np.dot(aff_m, voxel_coordinates.T).T[:, :3]
48
+
49
+ return mni_coordinates
50
+
51
+ def select_non_zero_voxels(
52
+ self,
53
+ mni_coordinates: np.ndarray,
54
+ ):
55
+ coords = np.hstack((mni_coordinates, np.ones((mni_coordinates.shape[0], 1))))
56
+
57
+ # and transform back to get the voxel values
58
+ voxels_downsampled = np.array(
59
+ np.linalg.solve(self.img.affine, coords.T).T
60
+ ).astype(int)[:, :3]
61
+
62
+ ival = []
63
+ coord_ = []
64
+ for i in range(voxels_downsampled.shape[0]):
65
+ ival.append(self.data[tuple(voxels_downsampled[i, :])])
66
+ coord_.append(mni_coordinates[i, :])
67
+
68
+ # get only voxel values non-zero
69
+ ival_arr = np.array(ival)
70
+ coord_arr = np.array(coord_)
71
+ ival_non_zero = ival_arr[ival != 0]
72
+ coord_non_zero = coord_arr[ival != 0]
73
+ print(coord_non_zero.shape)
74
+
75
+ return coord_non_zero, ival_non_zero
76
+
77
+ def plot_3d_coordinates(self, coord_non_zero: np.ndarray):
78
+ fig = plt.figure()
79
+ ax = fig.add_subplot(111, projection="3d")
80
+ ax.scatter(
81
+ coord_non_zero[:, 0],
82
+ coord_non_zero[:, 1],
83
+ coord_non_zero[:, 2],
84
+ s=50,
85
+ alpha=0.2,
86
+ )
87
+ plt.show()
88
+
89
+
90
+ if __name__ == "__main__":
91
+ nii_to_mni = NiiToMNI(
92
+ PATH_nii_file=r"C:\code\py_neuromodulation\ConnectivityDecoding\Automated Anatomical Labeling 3 (Rolls 2020).nii"
93
+ )
94
+ mni_coordinates = nii_to_mni.downsample_nii(resampling_factor=150)
95
+ coord_non_zero, ival_non_zero = nii_to_mni.select_non_zero_voxels(mni_coordinates)
@@ -1,119 +1,107 @@
1
- import nibabel as nib
2
- import numpy as np
3
- import scipy.io as sio
4
- import os
5
- from matplotlib import pyplot as plt
6
-
7
-
8
- def write_connectome_mat(
9
- PATH_Fingerprints: str = r"D:\Connectome_RMAP_OUT\ROIs\HCP1000 6K",
10
- PATH_CONNECTOME: str = os.path.join(
11
- "py_neuromodulation",
12
- "ConnectivityDecoding",
13
- "connectome_struct.mat",
14
- ),
15
- func_: bool = False,
16
- ):
17
-
18
- # connectome = sio.loadmat(PATH_CONNECTOME) # check if read was successful
19
-
20
- # load all fingerprints and put them in .npy
21
- dict_connectome = {}
22
- if func_ is False:
23
- files_fps = [f for f in os.listdir(PATH_Fingerprints) if ".nii" in f]
24
- else:
25
- files_fps = [
26
- f
27
- for f in os.listdir(PATH_Fingerprints)
28
- if "func_seed_AvgR_Fz.nii" in f
29
- ]
30
-
31
- # I except 1025 files, check which ones are missing
32
- missing_files = []
33
-
34
- for i in range(1, 1026):
35
-
36
- MISSING = False
37
-
38
- if func_ is False:
39
- if f"ROI-{i}_struc_seed.nii" not in files_fps:
40
- missing_files.append(f"ROI-{i}_struc_seed.nii")
41
- MISSING = True
42
- else:
43
- if f"ROI-{i}_func_seed_AvgR_Fz.nii" not in files_fps:
44
- missing_files.append(f"ROI-{i}_func_seed_AvgR_Fz.nii")
45
- MISSING = True
46
-
47
- if MISSING:
48
- ROI_file = os.path.join(
49
- r"D:\Connectome_RMAP_OUT\whole_brain\ROIs", f"ROI-{i}.nii"
50
- )
51
- # copy the ROI file to the following folder:
52
- PATH_ROI_OUT = (
53
- r"D:\Connectome_RMAP_OUT\whole_brain\ROI_missing_struc"
54
- )
55
- import shutil
56
-
57
- shutil.copy(ROI_file, os.path.join(PATH_ROI_OUT, f"ROI-{i}.nii"))
58
-
59
- for idx, f in enumerate(files_fps):
60
- # load the .nii file and put it all in in a dictionary with the name of the file
61
- fp = (
62
- nib.load(os.path.join(PATH_Fingerprints, f))
63
- .get_fdata()
64
- .astype(np.float16)
65
- )
66
- if "struc" in f:
67
- dict_connectome[f[f.find("ROI-") + 4 : f.find("_struc")]] = fp
68
- else:
69
- dict_connectome[
70
- f[f.find("ROI-") + 4 : f.find("_func_seed_AvgR_Fz.nii")]
71
- ] = fp
72
-
73
- print(idx)
74
- # save the dictionary
75
- sio.savemat(
76
- PATH_CONNECTOME,
77
- dict_connectome,
78
- )
79
-
80
-
81
- if __name__ == "__main__":
82
-
83
- write_connectome_mat(
84
- PATH_Fingerprints=r"D:\Connectome_RMAP_OUT\whole_brain\struc\HCP1000 6K",
85
- PATH_CONNECTOME=os.path.join(
86
- "py_neuromodulation",
87
- "ConnectivityDecoding",
88
- "connectome_whole_brain_struc.mat",
89
- ),
90
- ) # 58 files are missing
91
-
92
- write_connectome_mat(
93
- PATH_Fingerprints=r"D:\Connectome_RMAP_OUT\whole_brain\func",
94
- PATH_CONNECTOME=os.path.join(
95
- "py_neuromodulation",
96
- "ConnectivityDecoding",
97
- "connectome_whole_brain_func.mat",
98
- ),
99
- func_=True,
100
- )
101
-
102
- write_connectome_mat(
103
- PATH_Fingerprints=r"D:\Connectome_RMAP_OUT\hull\func\GSP 1000 (Yeo 2011)_Full Set (Yeo 2011)",
104
- PATH_CONNECTOME=os.path.join(
105
- "py_neuromodulation",
106
- "ConnectivityDecoding",
107
- "connectome_hull_func.mat",
108
- ),
109
- func_=True,
110
- ) # all there
111
-
112
- write_connectome_mat(
113
- PATH_Fingerprints=r"D:\Connectome_RMAP_OUT\hull\struc\HCP1000 6K",
114
- PATH_CONNECTOME=os.path.join(
115
- "py_neuromodulation",
116
- "ConnectivityDecoding",
117
- "connectome_hull_struc.mat",
118
- ),
119
- ) # 5 missing
1
+ import nibabel as nib
2
+ import numpy as np
3
+ import scipy.io as sio
4
+ import os
5
+
6
+
7
+ def write_connectome_mat(
8
+ PATH_Fingerprints: str = r"D:\Connectome_RMAP_OUT\ROIs\HCP1000 6K",
9
+ PATH_CONNECTOME: str = os.path.join(
10
+ "py_neuromodulation",
11
+ "ConnectivityDecoding",
12
+ "connectome_struct.mat",
13
+ ),
14
+ func_: bool = False,
15
+ ):
16
+ # connectome = sio.loadmat(PATH_CONNECTOME) # check if read was successful
17
+
18
+ # load all fingerprints and put them in .npy
19
+ dict_connectome = {}
20
+ if func_ is False:
21
+ files_fps = [f for f in os.listdir(PATH_Fingerprints) if ".nii" in f]
22
+ else:
23
+ files_fps = [
24
+ f for f in os.listdir(PATH_Fingerprints) if "func_seed_AvgR_Fz.nii" in f
25
+ ]
26
+
27
+ # I except 1025 files, check which ones are missing
28
+ missing_files = []
29
+
30
+ for i in range(1, 1026):
31
+ MISSING = False
32
+
33
+ if func_ is False:
34
+ if f"ROI-{i}_struc_seed.nii" not in files_fps:
35
+ missing_files.append(f"ROI-{i}_struc_seed.nii")
36
+ MISSING = True
37
+ else:
38
+ if f"ROI-{i}_func_seed_AvgR_Fz.nii" not in files_fps:
39
+ missing_files.append(f"ROI-{i}_func_seed_AvgR_Fz.nii")
40
+ MISSING = True
41
+
42
+ if MISSING:
43
+ ROI_file = os.path.join(
44
+ r"D:\Connectome_RMAP_OUT\whole_brain\ROIs", f"ROI-{i}.nii"
45
+ )
46
+ # copy the ROI file to the following folder:
47
+ PATH_ROI_OUT = r"D:\Connectome_RMAP_OUT\whole_brain\ROI_missing_struc"
48
+ import shutil
49
+
50
+ shutil.copy(ROI_file, os.path.join(PATH_ROI_OUT, f"ROI-{i}.nii"))
51
+
52
+ for idx, f in enumerate(files_fps):
53
+ # load the .nii file and put it all in in a dictionary with the name of the file
54
+ fp = nib.load(os.path.join(PATH_Fingerprints, f)).get_fdata().astype(np.float16)
55
+ if "struc" in f:
56
+ dict_connectome[f[f.find("ROI-") + 4 : f.find("_struc")]] = fp
57
+ else:
58
+ dict_connectome[
59
+ f[f.find("ROI-") + 4 : f.find("_func_seed_AvgR_Fz.nii")]
60
+ ] = fp
61
+
62
+ print(idx)
63
+ # save the dictionary
64
+ sio.savemat(
65
+ PATH_CONNECTOME,
66
+ dict_connectome,
67
+ )
68
+
69
+
70
+ if __name__ == "__main__":
71
+ write_connectome_mat(
72
+ PATH_Fingerprints=r"D:\Connectome_RMAP_OUT\whole_brain\struc\HCP1000 6K",
73
+ PATH_CONNECTOME=os.path.join(
74
+ "py_neuromodulation",
75
+ "ConnectivityDecoding",
76
+ "connectome_whole_brain_struc.mat",
77
+ ),
78
+ ) # 58 files are missing
79
+
80
+ write_connectome_mat(
81
+ PATH_Fingerprints=r"D:\Connectome_RMAP_OUT\whole_brain\func",
82
+ PATH_CONNECTOME=os.path.join(
83
+ "py_neuromodulation",
84
+ "ConnectivityDecoding",
85
+ "connectome_whole_brain_func.mat",
86
+ ),
87
+ func_=True,
88
+ )
89
+
90
+ write_connectome_mat(
91
+ PATH_Fingerprints=r"D:\Connectome_RMAP_OUT\hull\func\GSP 1000 (Yeo 2011)_Full Set (Yeo 2011)",
92
+ PATH_CONNECTOME=os.path.join(
93
+ "py_neuromodulation",
94
+ "ConnectivityDecoding",
95
+ "connectome_hull_func.mat",
96
+ ),
97
+ func_=True,
98
+ ) # all there
99
+
100
+ write_connectome_mat(
101
+ PATH_Fingerprints=r"D:\Connectome_RMAP_OUT\hull\struc\HCP1000 6K",
102
+ PATH_CONNECTOME=os.path.join(
103
+ "py_neuromodulation",
104
+ "ConnectivityDecoding",
105
+ "connectome_hull_struc.mat",
106
+ ),
107
+ ) # 5 missing
@@ -1,13 +1,80 @@
1
- from . import (
2
- nm_analysis,
3
- nm_stream_abc,
4
- nm_cohortwrapper,
5
- nm_across_patient_decoding,
6
- nm_stream_offline,
7
- nm_settings,
8
- nm_define_nmchannels,
9
- )
10
- from .nm_stream_offline import Stream
11
- from .nm_run_analysis import DataProcessor
12
-
13
- __version__ = "0.1.0.dev1"
1
+ import os
2
+ import platform
3
+ from pathlib import PurePath
4
+ from importlib.metadata import version
5
+ from py_neuromodulation.utils.logging import NMLogger
6
+
7
+ #####################################
8
+ # Globals and environment variables #
9
+ #####################################
10
+
11
+ __version__ = version("py_neuromodulation") # get version from pyproject.toml
12
+
13
+ # Check if the module is running headless (no display) for tests and doc builds
14
+ PYNM_HEADLESS: bool = not os.environ.get("DISPLAY")
15
+ PYNM_DIR = PurePath(__file__).parent # Define constant for py_nm directory
16
+
17
+ os.environ["MPLBACKEND"] = "agg" if PYNM_HEADLESS else "qtagg" # Set matplotlib backend
18
+
19
+ # Set environment variable MNE_LSL_LIB (required to import Stream below)
20
+ LSL_DICT = {
21
+ "windows_32bit": "windows/x86/liblsl.1.16.2.dll",
22
+ "windows_64bit": "windows/amd64/liblsl.1.16.2.dll",
23
+ "darwin_i386": "macos/amd64/liblsl.1.16.2.dylib",
24
+ "darwin_arm": "macos/arm64/liblsl.1.16.0.dylib",
25
+ "linux_jammy_32bit": "linux/jammy_x86/liblsl.1.16.2.so",
26
+ "linux_jammy_64bit": "linux/jammy_amd64/liblsl.1.16.2.so",
27
+ "linux_focal_64bit": "linux/focal_amd64/liblsl.1.16.2.so",
28
+ "linux_bionic_64bit": "linux/bionic_amd64/liblsl.1.16.2.so",
29
+ "linux_bookworm_64bit": "linux/bookworm_amd64/liblsl.1.16.2.so",
30
+ "linux_noble_64bit": "linux/noble_amd64/liblsl.1.16.2.so",
31
+ "linux_32bit": "linux/jammy_x86/liblsl.1.16.2.so",
32
+ "linux_64bit": "linux/jammy_amd64/liblsl.1.16.2.so",
33
+ }
34
+
35
+ PLATFORM = platform.system().lower().strip()
36
+ ARCH = platform.architecture()[0]
37
+ match PLATFORM:
38
+ case "windows":
39
+ KEY = PLATFORM + "_" + ARCH
40
+ case "darwin":
41
+ KEY = PLATFORM + "_" + platform.processor()
42
+ case "linux":
43
+ DIST = platform.freedesktop_os_release()["VERSION_CODENAME"]
44
+ KEY = PLATFORM + "_" + DIST + "_" + ARCH
45
+ if KEY not in LSL_DICT:
46
+ KEY = PLATFORM + "_" + ARCH
47
+ case _:
48
+ KEY = ""
49
+
50
+ if KEY in LSL_DICT:
51
+ os.environ["MNE_LSL_LIB"] = str(PYNM_DIR / "liblsl" / LSL_DICT[KEY])
52
+
53
+
54
+ # Create global dictionary to store user-defined features
55
+ user_features = {}
56
+
57
+
58
+ ######################################
59
+ # Logger initialization and settings #
60
+ ######################################
61
+
62
+ logger = NMLogger(__name__) # logger initialization first to prevent circular import
63
+
64
+ ####################################
65
+ # API: Exposed classes and methods #
66
+ ####################################
67
+ from .stream.stream import Stream
68
+ from .stream.data_processor import DataProcessor
69
+ from .stream.settings import NMSettings
70
+
71
+ from .analysis.feature_reader import FeatureReader
72
+ from .features.feature_processor import add_custom_feature, remove_custom_feature
73
+
74
+ from .utils import types
75
+ from .utils import io
76
+
77
+ from . import stream
78
+ from . import analysis
79
+
80
+ from .stream.settings import get_default_settings, get_fast_compute, reset_settings