py-neuromodulation 0.0.1__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.
Files changed (206) hide show
  1. docs/build/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +68 -0
  2. docs/build/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +233 -0
  3. docs/build/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +219 -0
  4. docs/build/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +97 -0
  5. docs/build/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +64 -0
  6. docs/build/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +192 -0
  7. docs/build/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +210 -0
  8. docs/build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +68 -0
  9. docs/build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +239 -0
  10. docs/build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +219 -0
  11. docs/build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +97 -0
  12. docs/build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +64 -0
  13. docs/build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +192 -0
  14. docs/build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +210 -0
  15. docs/source/_build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +76 -0
  16. docs/source/_build/html/_downloads/0d0d0a76e8f648d5d3cbc47da6351932/plot_real_time_demo.py +97 -0
  17. docs/source/_build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +240 -0
  18. docs/source/_build/html/_downloads/5d73cadc59a8805c47e3b84063afc157/plot_example_BIDS.py +233 -0
  19. docs/source/_build/html/_downloads/7660317fa5a6bfbd12fcca9961457fc4/plot_example_rmap_computing.py +63 -0
  20. docs/source/_build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +219 -0
  21. docs/source/_build/html/_downloads/839e5b319379f7fd9e867deb00fd797f/plot_example_gridPointProjection.py +210 -0
  22. docs/source/_build/html/_downloads/ae8be19afe5e559f011fc9b138968ba0/plot_first_demo.py +192 -0
  23. docs/source/_build/html/_downloads/b8b06cacc17969d3725a0b6f1d7741c5/plot_example_sharpwave_analysis.py +219 -0
  24. docs/source/_build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +121 -0
  25. docs/source/_build/html/_downloads/c31a86c0b68cb4167d968091ace8080d/plot_example_add_feature.py +68 -0
  26. docs/source/_build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +64 -0
  27. docs/source/_build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +189 -0
  28. docs/source/_build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +210 -0
  29. docs/source/auto_examples/plot_0_first_demo.py +189 -0
  30. docs/source/auto_examples/plot_1_example_BIDS.py +240 -0
  31. docs/source/auto_examples/plot_2_example_add_feature.py +76 -0
  32. docs/source/auto_examples/plot_3_example_sharpwave_analysis.py +219 -0
  33. docs/source/auto_examples/plot_4_example_gridPointProjection.py +210 -0
  34. docs/source/auto_examples/plot_5_example_rmap_computing.py +64 -0
  35. docs/source/auto_examples/plot_6_real_time_demo.py +121 -0
  36. docs/source/conf.py +105 -0
  37. examples/plot_0_first_demo.py +189 -0
  38. examples/plot_1_example_BIDS.py +240 -0
  39. examples/plot_2_example_add_feature.py +76 -0
  40. examples/plot_3_example_sharpwave_analysis.py +219 -0
  41. examples/plot_4_example_gridPointProjection.py +210 -0
  42. examples/plot_5_example_rmap_computing.py +64 -0
  43. examples/plot_6_real_time_demo.py +121 -0
  44. packages/realtime_decoding/build/lib/realtime_decoding/__init__.py +4 -0
  45. packages/realtime_decoding/build/lib/realtime_decoding/decoder.py +104 -0
  46. packages/realtime_decoding/build/lib/realtime_decoding/features.py +163 -0
  47. packages/realtime_decoding/build/lib/realtime_decoding/helpers.py +15 -0
  48. packages/realtime_decoding/build/lib/realtime_decoding/run_decoding.py +345 -0
  49. packages/realtime_decoding/build/lib/realtime_decoding/trainer.py +54 -0
  50. packages/tmsi/build/lib/TMSiFileFormats/__init__.py +37 -0
  51. packages/tmsi/build/lib/TMSiFileFormats/file_formats/__init__.py +36 -0
  52. packages/tmsi/build/lib/TMSiFileFormats/file_formats/lsl_stream_writer.py +200 -0
  53. packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_file_writer.py +496 -0
  54. packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_to_edf_converter.py +236 -0
  55. packages/tmsi/build/lib/TMSiFileFormats/file_formats/xdf_file_writer.py +977 -0
  56. packages/tmsi/build/lib/TMSiFileFormats/file_readers/__init__.py +35 -0
  57. packages/tmsi/build/lib/TMSiFileFormats/file_readers/edf_reader.py +116 -0
  58. packages/tmsi/build/lib/TMSiFileFormats/file_readers/poly5reader.py +294 -0
  59. packages/tmsi/build/lib/TMSiFileFormats/file_readers/xdf_reader.py +229 -0
  60. packages/tmsi/build/lib/TMSiFileFormats/file_writer.py +102 -0
  61. packages/tmsi/build/lib/TMSiPlotters/__init__.py +2 -0
  62. packages/tmsi/build/lib/TMSiPlotters/gui/__init__.py +39 -0
  63. packages/tmsi/build/lib/TMSiPlotters/gui/_plotter_gui.py +234 -0
  64. packages/tmsi/build/lib/TMSiPlotters/gui/plotting_gui.py +440 -0
  65. packages/tmsi/build/lib/TMSiPlotters/plotters/__init__.py +44 -0
  66. packages/tmsi/build/lib/TMSiPlotters/plotters/hd_emg_plotter.py +446 -0
  67. packages/tmsi/build/lib/TMSiPlotters/plotters/impedance_plotter.py +589 -0
  68. packages/tmsi/build/lib/TMSiPlotters/plotters/signal_plotter.py +1326 -0
  69. packages/tmsi/build/lib/TMSiSDK/__init__.py +54 -0
  70. packages/tmsi/build/lib/TMSiSDK/device.py +588 -0
  71. packages/tmsi/build/lib/TMSiSDK/devices/__init__.py +34 -0
  72. packages/tmsi/build/lib/TMSiSDK/devices/saga/TMSi_Device_API.py +1764 -0
  73. packages/tmsi/build/lib/TMSiSDK/devices/saga/__init__.py +34 -0
  74. packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_device.py +1366 -0
  75. packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_types.py +520 -0
  76. packages/tmsi/build/lib/TMSiSDK/devices/saga/xml_saga_config.py +165 -0
  77. packages/tmsi/build/lib/TMSiSDK/error.py +95 -0
  78. packages/tmsi/build/lib/TMSiSDK/sample_data.py +63 -0
  79. packages/tmsi/build/lib/TMSiSDK/sample_data_server.py +99 -0
  80. packages/tmsi/build/lib/TMSiSDK/settings.py +45 -0
  81. packages/tmsi/build/lib/TMSiSDK/tmsi_device.py +111 -0
  82. packages/tmsi/build/lib/__init__.py +4 -0
  83. packages/tmsi/build/lib/apex_sdk/__init__.py +34 -0
  84. packages/tmsi/build/lib/apex_sdk/device/__init__.py +41 -0
  85. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API.py +1009 -0
  86. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_enums.py +239 -0
  87. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_structures.py +668 -0
  88. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_device.py +1611 -0
  89. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_dongle.py +38 -0
  90. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_event_reader.py +57 -0
  91. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_channel.py +44 -0
  92. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_config.py +150 -0
  93. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_const.py +36 -0
  94. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_impedance_channel.py +48 -0
  95. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_info.py +108 -0
  96. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/dongle_info.py +39 -0
  97. packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/download_measurement.py +77 -0
  98. packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/eeg_measurement.py +150 -0
  99. packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/impedance_measurement.py +129 -0
  100. packages/tmsi/build/lib/apex_sdk/device/threads/conversion_thread.py +59 -0
  101. packages/tmsi/build/lib/apex_sdk/device/threads/sampling_thread.py +57 -0
  102. packages/tmsi/build/lib/apex_sdk/device/tmsi_channel.py +83 -0
  103. packages/tmsi/build/lib/apex_sdk/device/tmsi_device.py +201 -0
  104. packages/tmsi/build/lib/apex_sdk/device/tmsi_device_enums.py +103 -0
  105. packages/tmsi/build/lib/apex_sdk/device/tmsi_dongle.py +43 -0
  106. packages/tmsi/build/lib/apex_sdk/device/tmsi_event_reader.py +50 -0
  107. packages/tmsi/build/lib/apex_sdk/device/tmsi_measurement.py +118 -0
  108. packages/tmsi/build/lib/apex_sdk/sample_data_server/__init__.py +33 -0
  109. packages/tmsi/build/lib/apex_sdk/sample_data_server/event_data.py +44 -0
  110. packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data.py +50 -0
  111. packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data_server.py +136 -0
  112. packages/tmsi/build/lib/apex_sdk/tmsi_errors/error.py +126 -0
  113. packages/tmsi/build/lib/apex_sdk/tmsi_sdk.py +113 -0
  114. packages/tmsi/build/lib/apex_sdk/tmsi_utilities/apex/apex_structure_generator.py +134 -0
  115. packages/tmsi/build/lib/apex_sdk/tmsi_utilities/decorators.py +60 -0
  116. packages/tmsi/build/lib/apex_sdk/tmsi_utilities/logger_filter.py +42 -0
  117. packages/tmsi/build/lib/apex_sdk/tmsi_utilities/singleton.py +42 -0
  118. packages/tmsi/build/lib/apex_sdk/tmsi_utilities/support_functions.py +72 -0
  119. packages/tmsi/build/lib/apex_sdk/tmsi_utilities/tmsi_logger.py +98 -0
  120. py_neuromodulation/{helper.py → _write_example_dataset_helper.py} +1 -1
  121. py_neuromodulation/nm_EpochStream.py +2 -3
  122. py_neuromodulation/nm_IO.py +43 -70
  123. py_neuromodulation/nm_RMAP.py +308 -11
  124. py_neuromodulation/nm_analysis.py +1 -1
  125. py_neuromodulation/nm_artifacts.py +25 -0
  126. py_neuromodulation/nm_bispectra.py +168 -0
  127. py_neuromodulation/nm_bursts.py +43 -31
  128. py_neuromodulation/nm_coherence.py +2 -1
  129. py_neuromodulation/nm_define_nmchannels.py +1 -1
  130. py_neuromodulation/nm_features.py +6 -1
  131. py_neuromodulation/nm_filter.py +63 -32
  132. py_neuromodulation/nm_filter_preprocessing.py +91 -0
  133. py_neuromodulation/nm_fooof.py +47 -29
  134. py_neuromodulation/nm_generator.py +10 -10
  135. py_neuromodulation/nm_mne_connectivity.py +1 -1
  136. py_neuromodulation/nm_normalization.py +50 -74
  137. py_neuromodulation/nm_oscillatory.py +151 -31
  138. py_neuromodulation/nm_plots.py +13 -10
  139. py_neuromodulation/nm_rereference.py +10 -8
  140. py_neuromodulation/nm_run_analysis.py +28 -13
  141. py_neuromodulation/nm_sharpwaves.py +103 -136
  142. py_neuromodulation/nm_stats.py +44 -30
  143. py_neuromodulation/nm_stream_abc.py +18 -10
  144. py_neuromodulation/nm_stream_offline.py +185 -43
  145. py_neuromodulation/utils/_logging.py +24 -0
  146. {py_neuromodulation-0.0.1.dist-info → py_neuromodulation-0.0.3.dist-info}/METADATA +182 -131
  147. py_neuromodulation-0.0.3.dist-info/RECORD +188 -0
  148. {py_neuromodulation-0.0.1.dist-info → py_neuromodulation-0.0.3.dist-info}/WHEEL +2 -1
  149. py_neuromodulation-0.0.3.dist-info/top_level.txt +5 -0
  150. tests/__init__.py +0 -0
  151. tests/conftest.py +117 -0
  152. tests/test_all_examples.py +10 -0
  153. tests/test_all_features.py +63 -0
  154. tests/test_bispectra.py +70 -0
  155. tests/test_bursts.py +105 -0
  156. tests/test_feature_sampling_rates.py +143 -0
  157. tests/test_fooof.py +16 -0
  158. tests/test_initalization_offline_stream.py +41 -0
  159. tests/test_multiprocessing.py +58 -0
  160. tests/test_nan_values.py +29 -0
  161. tests/test_nm_filter.py +95 -0
  162. tests/test_nm_resample.py +63 -0
  163. tests/test_normalization_settings.py +146 -0
  164. tests/test_notch_filter.py +31 -0
  165. tests/test_osc_features.py +424 -0
  166. tests/test_preprocessing_filter.py +151 -0
  167. tests/test_rereference.py +171 -0
  168. tests/test_sampling.py +57 -0
  169. tests/test_settings_change_after_init.py +76 -0
  170. tests/test_sharpwave.py +165 -0
  171. tests/test_target_channel_add.py +100 -0
  172. tests/test_timing.py +80 -0
  173. py_neuromodulation/data/README +0 -6
  174. py_neuromodulation/data/dataset_description.json +0 -8
  175. py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/MOV_aligned_features_ch_ECOG_RIGHT_0_all.png +0 -0
  176. py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/all_feature_plt.pdf +0 -0
  177. py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_FEATURES.csv +0 -182
  178. 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
  179. py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_SETTINGS.json +0 -273
  180. py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_SIDECAR.json +0 -6
  181. 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
  182. 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
  183. py_neuromodulation/data/participants.json +0 -32
  184. py_neuromodulation/data/participants.tsv +0 -2
  185. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_coordsystem.json +0 -5
  186. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_electrodes.tsv +0 -11
  187. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_channels.tsv +0 -11
  188. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.eeg +0 -0
  189. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.json +0 -18
  190. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vhdr +0 -35
  191. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vmrk +0 -13
  192. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/sub-testsub_ses-EphysMedOff_scans.tsv +0 -2
  193. py_neuromodulation/grid_cortex.tsv +0 -40
  194. py_neuromodulation/grid_subcortex.tsv +0 -1429
  195. py_neuromodulation/nm_settings.json +0 -261
  196. py_neuromodulation/plots/STN_surf.mat +0 -0
  197. py_neuromodulation/plots/Vertices.mat +0 -0
  198. py_neuromodulation/plots/faces.mat +0 -0
  199. py_neuromodulation/plots/grid.mat +0 -0
  200. py_neuromodulation/py_neuromodulation.egg-info/PKG-INFO +0 -104
  201. py_neuromodulation/py_neuromodulation.egg-info/dependency_links.txt +0 -1
  202. py_neuromodulation/py_neuromodulation.egg-info/requires.txt +0 -26
  203. py_neuromodulation/py_neuromodulation.egg-info/top_level.txt +0 -1
  204. py_neuromodulation-0.0.1.dist-info/RECORD +0 -72
  205. /py_neuromodulation/{py_neuromodulation.egg-info/SOURCES.txt → utils/__init__.py} +0 -0
  206. {py_neuromodulation-0.0.1.dist-info → py_neuromodulation-0.0.3.dist-info}/LICENSE +0 -0
@@ -0,0 +1,95 @@
1
+ """Test the nm_filter module."""
2
+ import numpy as np
3
+ from py_neuromodulation import nm_filter
4
+ import pytest
5
+
6
+
7
+ class TestMNEFilterData:
8
+ """Test filter_data method of MNEFilter class."""
9
+
10
+ @pytest.mark.parametrize(
11
+ "filter_length",
12
+ ["500ms", "999ms", "1999ms", "3999ms", "2s"],
13
+ )
14
+ def test_filter_length(self, filter_length) -> None:
15
+ """Test different filter lengths."""
16
+ f_ranges = [
17
+ [13, 35],
18
+ ]
19
+ sfreq = 4000
20
+ duration = 10
21
+ times = np.linspace(0, duration, int(duration * sfreq))
22
+ bandpass_filter = nm_filter.MNEFilter(
23
+ f_ranges=f_ranges,
24
+ sfreq=sfreq,
25
+ filter_length=filter_length,
26
+ l_trans_bandwidth=8, # transition bandwidth needs to be adjusted for smaller filter length
27
+ h_trans_bandwidth=8,
28
+ verbose=None,
29
+ )
30
+ oscill_freqs = 50
31
+ data = np.sin(2 * np.pi * times * oscill_freqs)
32
+ data_filtered = bandpass_filter.filter_data(data)
33
+ assert data_filtered.shape == (
34
+ 1,
35
+ len(f_ranges),
36
+ duration * sfreq,
37
+ )
38
+
39
+ def test_filter_1d(self) -> None:
40
+ """Test filtering of 1d array with multiple frequency ranges."""
41
+ f_ranges = [
42
+ [4, 8],
43
+ [8, 12],
44
+ [13, 35],
45
+ [60, 200],
46
+ [200, 500],
47
+ ]
48
+ sfreq = 4000
49
+ duration = 10
50
+ times = np.linspace(0, duration, int(duration * sfreq))
51
+ bandpass_filter = nm_filter.MNEFilter(
52
+ f_ranges=f_ranges,
53
+ sfreq=sfreq,
54
+ filter_length="999ms",
55
+ l_trans_bandwidth=4,
56
+ h_trans_bandwidth=4,
57
+ verbose=None,
58
+ )
59
+ oscill_freqs = 50
60
+ data = np.sin(2 * np.pi * times * oscill_freqs)
61
+ data_filtered = bandpass_filter.filter_data(data)
62
+ assert data_filtered.shape == (
63
+ 1,
64
+ len(f_ranges),
65
+ duration * sfreq,
66
+ )
67
+
68
+ def test_filter_2d(self) -> None:
69
+ """Test filtering of 2d array with multiple frequency ranges and multiple channels."""
70
+ f_ranges = [
71
+ [4, 8],
72
+ [8, 12],
73
+ [13, 35],
74
+ [60, 200],
75
+ [200, 500],
76
+ ]
77
+ sfreq = 4000
78
+ duration = 10
79
+ times = np.linspace(0, duration, int(duration * sfreq))
80
+ bandpass_filter = nm_filter.MNEFilter(
81
+ f_ranges=f_ranges,
82
+ sfreq=sfreq,
83
+ filter_length="999ms",
84
+ l_trans_bandwidth=4,
85
+ h_trans_bandwidth=4,
86
+ verbose=None,
87
+ )
88
+ oscill_freqs = np.expand_dims(np.arange(10, 51, 10), axis=-1)
89
+ data = np.sin(2 * np.pi * times * oscill_freqs)
90
+ data_filtered = bandpass_filter.filter_data(data)
91
+ assert data_filtered.shape == (
92
+ oscill_freqs.shape[0],
93
+ len(f_ranges),
94
+ duration * sfreq,
95
+ )
@@ -0,0 +1,63 @@
1
+ """Test the nm_resample module."""
2
+ import numpy as np
3
+
4
+ from py_neuromodulation import nm_resample
5
+
6
+
7
+ def test_upsample():
8
+ """Test case where data is upsampled."""
9
+ sfreq_old = 4000.0
10
+ duration = 10
11
+ times = np.linspace(0, duration, int(duration * sfreq_old))
12
+ oscill_freqs = np.expand_dims(np.arange(10, 51, 10), axis=-1)
13
+ data = np.sin(2 * np.pi * times * oscill_freqs)
14
+
15
+ sfreq_new = 1000.0
16
+ resample = nm_resample.Resampler(
17
+ resample_freq_hz=sfreq_new,
18
+ sfreq=sfreq_old,
19
+ )
20
+ data_resampled = resample.process(data)
21
+ assert data_resampled.shape[-1] == int(duration * sfreq_new)
22
+ # This test only works when ratio of old and new sfreq is an integer
23
+ # It will also only work up to a certain decimal precision.
24
+ resampled_naive = data[..., :: int(sfreq_old / sfreq_new)]
25
+ np.testing.assert_array_almost_equal(
26
+ data[..., :: int(sfreq_old / sfreq_new)],
27
+ resampled_naive,
28
+ decimal=2,
29
+ )
30
+
31
+
32
+ def test_downsample():
33
+ """Test case where data is downsampled."""
34
+ sfreq_old = 1000.0
35
+ duration = 10
36
+ times = np.linspace(0, duration, int(duration * sfreq_old))
37
+ oscill_freqs = np.expand_dims(np.arange(10, 51, 10), axis=-1)
38
+ data = np.sin(2 * np.pi * times * oscill_freqs)
39
+
40
+ sfreq_new = 4000.0
41
+ resample = nm_resample.Resampler(
42
+ resample_freq_hz=sfreq_new,
43
+ sfreq=sfreq_old,
44
+ )
45
+ data_resampled = resample.process(data)
46
+ assert data_resampled.shape[-1] == int(duration * sfreq_new)
47
+
48
+
49
+ def test_no_resample():
50
+ """Test case where no resampling is performed."""
51
+ sfreq_old = 1000.0
52
+ duration = 10
53
+ times = np.linspace(0, duration, int(duration * sfreq_old))
54
+ oscill_freqs = np.expand_dims(np.arange(10, 51, 10), axis=-1)
55
+ data = np.sin(2 * np.pi * times * oscill_freqs)
56
+
57
+ sfreq_new = 1000.0
58
+ resample = nm_resample.Resampler(
59
+ resample_freq_hz=sfreq_new,
60
+ sfreq=sfreq_old,
61
+ )
62
+ data_resampled = resample.process(data)
63
+ np.testing.assert_array_almost_equal(data, data_resampled)
@@ -0,0 +1,146 @@
1
+ import os
2
+ import unittest
3
+ import pytest
4
+ import numpy as np
5
+
6
+ from py_neuromodulation import nm_normalization
7
+
8
+
9
+ def test_raw_normalization_init():
10
+ with pytest.raises(Exception):
11
+ nm_normalization.RawNormalizer(
12
+ sfreq=1000,
13
+ sampling_rate_features_hz=500,
14
+ normalization_method="meann",
15
+ normalization_time_s=30,
16
+ clip=3,
17
+ )
18
+
19
+
20
+ def test_feature_normalization_init():
21
+ with pytest.raises(Exception):
22
+ nm_normalization.FeatureNormalizer(
23
+ sampling_rate_features_hz=500,
24
+ normalization_method="meann",
25
+ normalization_time_s=30,
26
+ clip=3,
27
+ )
28
+
29
+
30
+ def test_process_norm_features():
31
+ norm = nm_normalization.FeatureNormalizer(
32
+ sampling_rate_features_hz=500,
33
+ normalization_method="mean",
34
+ normalization_time_s=30,
35
+ clip=3,
36
+ )
37
+ data = np.ones([1, 5])
38
+ data_normed = norm.process(data)
39
+
40
+ assert np.all(np.isfinite(data_normed) == True)
41
+
42
+ assert np.all(np.equal(data, norm.previous) == 1)
43
+
44
+
45
+ def test_previous_size_FeatureNorm():
46
+ norm = nm_normalization.FeatureNormalizer(
47
+ sampling_rate_features_hz=10,
48
+ normalization_method="zscore",
49
+ normalization_time_s=10,
50
+ clip=3,
51
+ )
52
+
53
+ num_features = 5
54
+
55
+ for _ in range(150):
56
+ np.random.seed(0)
57
+ data = norm.process(np.random.random([1, num_features]))
58
+
59
+ assert norm.previous.shape[0] < norm.num_samples_normalize
60
+
61
+
62
+ def test_zscore_feature_analysis():
63
+ norm = nm_normalization.FeatureNormalizer(
64
+ sampling_rate_features_hz=10,
65
+ normalization_method="zscore",
66
+ normalization_time_s=30,
67
+ clip=False,
68
+ )
69
+
70
+ num_features = 5
71
+
72
+ for _ in range(400):
73
+ np.random.seed(0)
74
+ data_to_norm = np.random.random([1, num_features])
75
+ data_normed = norm.process(data_to_norm)
76
+
77
+ expect_res = (
78
+ norm.previous[:, 0].std() * data_normed[0, 0]
79
+ + norm.previous[:, 0].mean()
80
+ )
81
+
82
+ assert pytest.approx(expect_res, 0.1) == data_to_norm[0, 0]
83
+
84
+
85
+ def test_zscore_raw_analysis():
86
+ norm = nm_normalization.RawNormalizer(
87
+ sampling_rate_features_hz=10,
88
+ normalization_method="zscore",
89
+ normalization_time_s=30,
90
+ sfreq=10,
91
+ clip=False,
92
+ )
93
+
94
+ num_samples = 100
95
+
96
+ for _ in range(400):
97
+ data_to_norm = np.random.random([1, num_samples])
98
+ data_normed = norm.process(data_to_norm)
99
+
100
+ expect_res = (
101
+ norm.previous[:, 0].std() * data_normed[0, 0]
102
+ + norm.previous[:, 0].mean()
103
+ )
104
+
105
+ np.testing.assert_allclose(
106
+ expect_res, data_to_norm[0, 0], rtol=0.1, atol=0.1
107
+ )
108
+
109
+
110
+ def test_all_norm_methods_raw():
111
+ for norm_method in [e.value for e in nm_normalization.NORM_METHODS]:
112
+ norm = nm_normalization.RawNormalizer(
113
+ sampling_rate_features_hz=10,
114
+ normalization_method=norm_method,
115
+ normalization_time_s=30,
116
+ sfreq=10,
117
+ clip=False,
118
+ )
119
+
120
+ num_samples = 10
121
+
122
+ for _ in range(10):
123
+ np.random.seed(0)
124
+ data_to_norm = np.random.random([1, num_samples])
125
+ data_normed = norm.process(data_to_norm)
126
+
127
+ assert np.all(np.isfinite(data_normed) == True)
128
+
129
+
130
+ def test_all_norm_methods_feature():
131
+ for norm_method in [e.value for e in nm_normalization.NORM_METHODS]:
132
+ norm = nm_normalization.FeatureNormalizer(
133
+ sampling_rate_features_hz=10,
134
+ normalization_method=norm_method,
135
+ normalization_time_s=30,
136
+ clip=False,
137
+ )
138
+
139
+ num_samples = 10
140
+
141
+ for i in range(10):
142
+ np.random.seed(i)
143
+ data_to_norm = np.random.random([1, num_samples])
144
+ data_normed = norm.process(data_to_norm)
145
+
146
+ assert np.all(np.isfinite(data_normed) == True)
@@ -0,0 +1,31 @@
1
+ import numpy as np
2
+ import pytest
3
+ from scipy import fft, signal
4
+
5
+ from py_neuromodulation import nm_filter
6
+
7
+
8
+ def test_notch_filter_setup():
9
+
10
+ # by Nyquist theorem, frequencies are computed up to half sfreq
11
+ for sfreq in [150, 200, 500, 1000]:
12
+ line_noise = 50
13
+
14
+ notch_filter = nm_filter.NotchFilter(sfreq, line_noise)
15
+
16
+ # the computed filter is saved in self.filter_bank
17
+
18
+ data = np.random.random(sfreq)
19
+ filtered_dat = notch_filter.process(data)
20
+
21
+ Z_filtered = np.abs(fft.rfft(filtered_dat))
22
+ Z_nonfiltered = np.abs(fft.rfft(data))
23
+ freqs = fft.rfftfreq(sfreq, 1 / sfreq)
24
+ idx = (np.abs(freqs - line_noise)).argmin()
25
+
26
+ assert np.mean(Z_filtered[idx - 1 : idx + 1]) < np.mean(
27
+ Z_nonfiltered[idx - 1 : idx + 1]
28
+ ), (
29
+ f"testing notch filter with sampling frequency {line_noise} failed"
30
+ f" for comparison fft power vs no filtering"
31
+ )