mep-cmap-analyser 0.9.1__tar.gz

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 (30) hide show
  1. mep_cmap_analyser-0.9.1/LICENSE +21 -0
  2. mep_cmap_analyser-0.9.1/PKG-INFO +288 -0
  3. mep_cmap_analyser-0.9.1/README.md +247 -0
  4. mep_cmap_analyser-0.9.1/mep_cmap/__init__.py +70 -0
  5. mep_cmap_analyser-0.9.1/mep_cmap/__main__.py +7 -0
  6. mep_cmap_analyser-0.9.1/mep_cmap/app.py +3950 -0
  7. mep_cmap_analyser-0.9.1/mep_cmap/bids.py +73 -0
  8. mep_cmap_analyser-0.9.1/mep_cmap/compat.py +63 -0
  9. mep_cmap_analyser-0.9.1/mep_cmap/dataset_session.py +397 -0
  10. mep_cmap_analyser-0.9.1/mep_cmap/detection.py +377 -0
  11. mep_cmap_analyser-0.9.1/mep_cmap/filter_preview.py +1314 -0
  12. mep_cmap_analyser-0.9.1/mep_cmap/filters.py +91 -0
  13. mep_cmap_analyser-0.9.1/mep_cmap/formats/__init__.py +1 -0
  14. mep_cmap_analyser-0.9.1/mep_cmap/formats/labchart.py +267 -0
  15. mep_cmap_analyser-0.9.1/mep_cmap/formats/spike2.py +192 -0
  16. mep_cmap_analyser-0.9.1/mep_cmap/inspector.py +945 -0
  17. mep_cmap_analyser-0.9.1/mep_cmap/io.py +152 -0
  18. mep_cmap_analyser-0.9.1/mep_cmap/normalisation.py +167 -0
  19. mep_cmap_analyser-0.9.1/mep_cmap/pipeline.py +1240 -0
  20. mep_cmap_analyser-0.9.1/mep_cmap/preferences.py +207 -0
  21. mep_cmap_analyser-0.9.1/mep_cmap/stage2.py +832 -0
  22. mep_cmap_analyser-0.9.1/mep_cmap/utils.py +36 -0
  23. mep_cmap_analyser-0.9.1/mep_cmap_analyser.egg-info/PKG-INFO +288 -0
  24. mep_cmap_analyser-0.9.1/mep_cmap_analyser.egg-info/SOURCES.txt +28 -0
  25. mep_cmap_analyser-0.9.1/mep_cmap_analyser.egg-info/dependency_links.txt +1 -0
  26. mep_cmap_analyser-0.9.1/mep_cmap_analyser.egg-info/entry_points.txt +2 -0
  27. mep_cmap_analyser-0.9.1/mep_cmap_analyser.egg-info/requires.txt +6 -0
  28. mep_cmap_analyser-0.9.1/mep_cmap_analyser.egg-info/top_level.txt +2 -0
  29. mep_cmap_analyser-0.9.1/pyproject.toml +34 -0
  30. mep_cmap_analyser-0.9.1/setup.cfg +4 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Justin Andrushko, Northumbria University
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,288 @@
1
+ Metadata-Version: 2.4
2
+ Name: mep-cmap-analyser
3
+ Version: 0.9.1
4
+ Summary: BIDS-compliant TMS/EMG neurophysiology analysis tool for MEP and CMAP quantification
5
+ Author-email: Justin Andrushko <justin.andrushko@northumbria.ac.uk>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Justin Andrushko, Northumbria University
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/justinAndrushko/mep-cmap-analyser
29
+ Project-URL: Repository, https://github.com/justinAndrushko/mep-cmap-analyser
30
+ Project-URL: Bug Tracker, https://github.com/justinAndrushko/mep-cmap-analyser/issues
31
+ Requires-Python: >=3.9
32
+ Description-Content-Type: text/markdown
33
+ License-File: LICENSE
34
+ Requires-Dist: numpy>=1.24
35
+ Requires-Dist: pandas>=1.5
36
+ Requires-Dist: matplotlib>=3.7
37
+ Requires-Dist: scipy>=1.10
38
+ Requires-Dist: PyWavelets>=1.4
39
+ Requires-Dist: Pillow>=9.0
40
+ Dynamic: license-file
41
+
42
+ # MEP-CMAP Analyser
43
+
44
+ **Version 0.9.1 | May 2026**
45
+ *Author: Justin Andrushko PhD, Northumbria University*
46
+
47
+ A BIDS-compliant, open-source tool for processing and quantifying TMS-evoked motor evoked potentials (MEPs) and cortical silent periods (cSPs) from Spike-2 EMG recordings.
48
+
49
+ \---
50
+
51
+ ## Features
52
+
53
+ * **Dataset Setup** — multi-file session management with a persistent file queue, BIDS folder auto-detection, processing status tracking, and excluded-file management across sessions
54
+ * **BIDS-compliant** derivatives output with automatic participant/session naming
55
+ * **Per-trial MEP quantification** — PTP amplitude, onset latency, AUC, cSP duration, paired-pulse ratios
56
+ * **Physiologically-bounded MEP onset detection** — peak-anchored backward scan with per-stim-type latency profiles derived from published normative data (TMS: hand/FDI 18–30 ms, vastus lateralis 18–35 ms, leg 28–45 ms; peripheral nerve: upper limb 2–12 ms, lower limb 4–18 ms)
57
+ * **Cortical silent period (cSP) detection** using a vectorised bootstrap threshold method with MEP-anchored search cap
58
+ * **Auto AUC** — onset-to-cSP start computed automatically for all event types; user can override via drag selector
59
+ * **Auto SP and AUC for unreviewed segments** — silent period and AUC computed in the pipeline for any segment not manually reviewed in the Data Inspector
60
+ * **M-wave normalisation** with plateau-based Mmax detection
61
+ * **Paired-pulse ratios** (SICI, ICF, etc.) with flexible per-stim reference assignment in Stage 1a
62
+ * **Data Inspector** — interactive per-trial review with draggable markers, zoom toolbar, AUC selector, silent period annotation; all edits persist across reruns
63
+ * **Filter preview** — real-time frequency response and wavelet time-frequency display
64
+ * **Outlier detection** with interactive review and Z-score thresholding
65
+ * **Multi-channel support** — additional EMG and force channels for visual inspection
66
+ * **Full session persistence** — every adjustable setting (filters, onset detection, CSP, latency profiles, normalisation, inspector edits, analysis options) is saved and restored automatically per file
67
+ * **Group analysis** — Stage 2 merges all processed sessions into a single LME-ready CSV with study design columns (between/within-subject factors, stim roles)
68
+ * **LME-ready trial-level CSV output** with Z-scores, detrended values, normalised PTP, and pooled statistics
69
+ * **Cross-platform** — Windows, macOS, and Linux supported
70
+
71
+ \---
72
+
73
+ ## Workflow
74
+
75
+ The tool is organised into four tabs:
76
+
77
+ ### Dataset Setup
78
+
79
+ Load a study folder or individual files. The tool auto-detects `rawdata/` and `derivatives/` subfolders (BIDS structure) or accepts manual folder selection. The derivatives folder is always placed beside `rawdata/`, never inside it. A persistent file queue tracks processing status across sessions — files are marked Not started, In progress, Needs review, Complete, or Stale.
80
+
81
+ * Double-click any file to load it
82
+ * Use **Run all unprocessed** to batch process
83
+ * Use **Refresh** to detect newly added files (previously excluded files are remembered and not re-added)
84
+ * Right-click → **Show excluded files** to restore previously removed files
85
+ * Queue state is saved to `dataset\\\_session.json` in the derivatives folder
86
+
87
+ ### Stage 1a — Labels \& Analysis Setup
88
+
89
+ Appears automatically after a file is loaded. Configure per-stim-type settings:
90
+
91
+ * Label, colour, gap (ms), CSP detection toggle
92
+ * Stimulation type and muscle group (sets physiological latency bounds for onset detection)
93
+ * Internal normalisation references and plateau tolerance for Mmax detection
94
+
95
+ Confirming setup auto-switches to Stage 1b. Settings persist between files.
96
+
97
+ ### Stage 1b — Single File Processing
98
+
99
+ Filter settings (bandpass, notch, mains noise canceller), time window and MEP onset detection parameters, CSP detection settings, outlier review, and analysis options. All settings are saved per file and restored on reload.
100
+
101
+ When reloading a previously processed file:
102
+
103
+ * Option to reuse the saved data range, select a new range, or use the whole file
104
+ * Previously adjusted marker positions, notes, exclusions, and AUC windows are restored and carried through the re-analysis
105
+
106
+ ### Stage 2 — Group Analysis LME Setup
107
+
108
+ Scan the derivatives folder to discover all processed sessions. Assign study design columns (e.g. Group, Condition, Timepoint), configure stim type roles (Reference, Conditioned, M-wave), and click **Build group analysis file** to merge all selected sessions into a single `group\\\_level\\\_LME\\\_ready.csv`.
109
+
110
+ \---
111
+
112
+ ## Installation
113
+
114
+ ### Option 1: pip (recommended for Python users)
115
+
116
+ ```bash
117
+ pip install mep-cmap-analyser
118
+ mep-cmap
119
+ ```
120
+
121
+ Python 3.9+ required. Tkinter must be available:
122
+
123
+ * **Windows/Mac**: included with standard Python
124
+ * **Linux (Ubuntu/Debian)**: `sudo apt install python3-tk`
125
+
126
+ ### Option 2: Compiled binaries (no Python required)
127
+
128
+ Download the latest release for your platform from the [Releases page](https://github.com/justinAndrushko/mep-cmap-analyser/releases):
129
+
130
+ |Platform|File|
131
+ |-|-|
132
+ |Windows|`MEP-CMAP\\\_Analyser\\\_Windows.zip`|
133
+ |macOS|`MEP-CMAP\\\_Analyser\\\_Mac.zip`|
134
+ |Linux|`MEP-CMAP\\\_Analyser\\\_Linux.tar.gz`|
135
+
136
+ Unzip and run the executable — no installation required.
137
+
138
+ ### Option 3: Run from source
139
+
140
+ ```bash
141
+ git clone https://github.com/justinAndrushko/mep-cmap-analyser.git
142
+ cd mep-cmap-analyser
143
+ pip install -r requirements.txt
144
+ python MEP\\\_CMAP\\\_Analyser.py
145
+ ```
146
+
147
+ \---
148
+
149
+ ## Quick start
150
+
151
+ ```bash
152
+ # Launch the GUI
153
+ mep-cmap
154
+
155
+ # Or from Python
156
+ from mep\\\_cmap import run\\\_app
157
+ run\\\_app()
158
+ ```
159
+
160
+ ### Scripted pipeline (no GUI)
161
+
162
+ ```python
163
+ from mep\\\_cmap import run\\\_pipeline, PipelineConfig
164
+
165
+ run\\\_pipeline(
166
+ input\\\_path = "path/to/recording.txt",
167
+ pre\\\_ms = 20,
168
+ post\\\_ms = 400,
169
+ ptp\\\_start = 10,
170
+ ptp\\\_end = 50,
171
+ prestim\\\_ms = 100,
172
+ marker\\\_name = "Keyboard",
173
+ )
174
+ ```
175
+
176
+ \---
177
+
178
+ ## Input format
179
+
180
+ The tool reads **Spike-2 text exports** (`.txt`) containing:
181
+
182
+ * Waveform channels (EMG, force, etc.)
183
+ * DigMark event timestamps
184
+
185
+ Files should follow BIDS naming conventions for automatic metadata parsing:
186
+
187
+ ```
188
+ sub-001\\\_ses-01\\\_limb-left\\\_recording.txt
189
+ ```
190
+
191
+ Single-file recordings with multiple stimulus types and multi-file sessions (one file per condition) are both supported.
192
+
193
+ \---
194
+
195
+ ## Output
196
+
197
+ Results are saved to a `derivatives/` folder beside (not inside) the raw data folder, following BIDS structure:
198
+
199
+ ```
200
+ study/
201
+ ├── rawdata/
202
+ │ └── sub-001/ses-01/...
203
+ └── derivatives/
204
+ ├── dataset\\\_session.json ← queue state, processing status, excluded files
205
+ ├── group\\\_level\\\_LME\\\_ready.csv ← merged group-level output (Stage 2)
206
+ └── sub-001/
207
+ └── ses-01/
208
+ ├── results/
209
+ │ ├── sub-001\\\_ses-01\\\_limb-left\\\_All\\\_stims\\\_trial\\\_summary.csv
210
+ │ ├── sub-001\\\_ses-01\\\_limb-left\\\_All\\\_stims\\\_trial\\\_summary.json
211
+ │ ├── sub-001\\\_ses-01\\\_limb-left\\\_ptp\\\_results.csv
212
+ │ └── sub-001\\\_ses-01\\\_limb-left\\\_ptp\\\_results\\\_with\\\_outliers.csv
213
+ ├── figures/
214
+ └── sub-001\\\_ses-01\\\_limb-left\\\_session.json ← per-file session state
215
+ ```
216
+
217
+ ### Trial-level CSV columns
218
+
219
+ |Column|Description|
220
+ |-|-|
221
+ |`PTP(mV)`|MEP peak-to-peak amplitude|
222
+ |`Latency(ms)`|MEP onset latency|
223
+ |`cSP\\\_Duration(ms)`|Cortical silent period duration|
224
+ |`cSP\\\_MEP\\\_Offset(ms)`|Time from stim to cSP onset|
225
+ |`cSP\\\_EMG\\\_Return(ms)`|Time from stim to EMG return after cSP|
226
+ |`MEP\\\_cSP\\\_Ratio`|PTP / cSP duration (Orth \& Rothwell, 2004)|
227
+ |`AUC(mV\\\*s)`|Area under the rectified EMG curve (onset to cSP start)|
228
+ |`Normalised\\\_PTP`|PTP / reference mean (Mmax or single-pulse reference)|
229
+ |`Reference\\\_Type`|How the reference mean was computed|
230
+ |`Reference\\\_Mean(mV)`|Reference amplitude used for normalisation|
231
+ |`Z\\\_PTP\\\_Within`|Z-score within stim type|
232
+ |`Z\\\_PTP\\\_Pooled`|Z-score pooled across all conditions|
233
+ |`PTP\\\_Detrended(mV)`|Linearly detrended PTP amplitude|
234
+ |`Outlier\\\_Decision`|Include / Exclude / Reviewed|
235
+ |`Manual\\\_Note`|Annotator note from Data Inspector|
236
+
237
+ ### Group-level CSV additional columns
238
+
239
+ |Column|Description|
240
+ |-|-|
241
+ |`participant\\\_id`|BIDS participant identifier|
242
+ |`session`|Session label|
243
+ |`task`|Task label (if assigned)|
244
+ |`timepoint`|Timepoint label (if assigned)|
245
+ |`Limb`|Limb identifier parsed from filename|
246
+ |`Stim\\\_Role`|Role assigned in Stage 2 (Reference, Conditioned, M-wave, etc.)|
247
+ |`\\\[custom columns]`|User-defined between/within-subject factors|
248
+
249
+ \---
250
+
251
+ ## Building from source (developers)
252
+
253
+ ```bash
254
+ # Windows
255
+ python build\\\_windows.py
256
+
257
+ # Linux
258
+ python3 -m venv venv\\\_linux
259
+ source venv\\\_linux/bin/activate
260
+ pip install -r requirements.txt
261
+ python3 build\\\_linux.py
262
+
263
+ # macOS
264
+ python3 build\\\_mac.py
265
+ ```
266
+
267
+ \---
268
+
269
+ ## Citation
270
+
271
+ If you use this tool in your research, please cite:
272
+
273
+ > Andrushko, J.W. (2026). MEP-CMAP Analyser (Version 0.9.1) \\\[Software].
274
+ > Northumbria University. https://doi.org/10.5281/zenodo.XXXXXXX
275
+
276
+ \---
277
+
278
+ ## References
279
+
280
+ * Orth, M., \& Rothwell, J.C. (2004). The cortical silent period: intrinsic variability and relation to the waveform of the transcranial magnetic stimulation pulse. *Clinical Neurophysiology*, 115(5), 1076–1082.
281
+ * Hupfeld, K.E., Swanson, C.W., Fling, B.W., \& Seidler, R.D. (2021). TMS-induced silent periods: A review of methods and call for consistency. *Journal of Neuroscience Methods*, 346, 108950.
282
+
283
+ \---
284
+
285
+ ## License
286
+
287
+ MIT License — see [LICENSE](LICENSE) for details.
288
+
@@ -0,0 +1,247 @@
1
+ # MEP-CMAP Analyser
2
+
3
+ **Version 0.9.1 | May 2026**
4
+ *Author: Justin Andrushko PhD, Northumbria University*
5
+
6
+ A BIDS-compliant, open-source tool for processing and quantifying TMS-evoked motor evoked potentials (MEPs) and cortical silent periods (cSPs) from Spike-2 EMG recordings.
7
+
8
+ \---
9
+
10
+ ## Features
11
+
12
+ * **Dataset Setup** — multi-file session management with a persistent file queue, BIDS folder auto-detection, processing status tracking, and excluded-file management across sessions
13
+ * **BIDS-compliant** derivatives output with automatic participant/session naming
14
+ * **Per-trial MEP quantification** — PTP amplitude, onset latency, AUC, cSP duration, paired-pulse ratios
15
+ * **Physiologically-bounded MEP onset detection** — peak-anchored backward scan with per-stim-type latency profiles derived from published normative data (TMS: hand/FDI 18–30 ms, vastus lateralis 18–35 ms, leg 28–45 ms; peripheral nerve: upper limb 2–12 ms, lower limb 4–18 ms)
16
+ * **Cortical silent period (cSP) detection** using a vectorised bootstrap threshold method with MEP-anchored search cap
17
+ * **Auto AUC** — onset-to-cSP start computed automatically for all event types; user can override via drag selector
18
+ * **Auto SP and AUC for unreviewed segments** — silent period and AUC computed in the pipeline for any segment not manually reviewed in the Data Inspector
19
+ * **M-wave normalisation** with plateau-based Mmax detection
20
+ * **Paired-pulse ratios** (SICI, ICF, etc.) with flexible per-stim reference assignment in Stage 1a
21
+ * **Data Inspector** — interactive per-trial review with draggable markers, zoom toolbar, AUC selector, silent period annotation; all edits persist across reruns
22
+ * **Filter preview** — real-time frequency response and wavelet time-frequency display
23
+ * **Outlier detection** with interactive review and Z-score thresholding
24
+ * **Multi-channel support** — additional EMG and force channels for visual inspection
25
+ * **Full session persistence** — every adjustable setting (filters, onset detection, CSP, latency profiles, normalisation, inspector edits, analysis options) is saved and restored automatically per file
26
+ * **Group analysis** — Stage 2 merges all processed sessions into a single LME-ready CSV with study design columns (between/within-subject factors, stim roles)
27
+ * **LME-ready trial-level CSV output** with Z-scores, detrended values, normalised PTP, and pooled statistics
28
+ * **Cross-platform** — Windows, macOS, and Linux supported
29
+
30
+ \---
31
+
32
+ ## Workflow
33
+
34
+ The tool is organised into four tabs:
35
+
36
+ ### Dataset Setup
37
+
38
+ Load a study folder or individual files. The tool auto-detects `rawdata/` and `derivatives/` subfolders (BIDS structure) or accepts manual folder selection. The derivatives folder is always placed beside `rawdata/`, never inside it. A persistent file queue tracks processing status across sessions — files are marked Not started, In progress, Needs review, Complete, or Stale.
39
+
40
+ * Double-click any file to load it
41
+ * Use **Run all unprocessed** to batch process
42
+ * Use **Refresh** to detect newly added files (previously excluded files are remembered and not re-added)
43
+ * Right-click → **Show excluded files** to restore previously removed files
44
+ * Queue state is saved to `dataset\\\_session.json` in the derivatives folder
45
+
46
+ ### Stage 1a — Labels \& Analysis Setup
47
+
48
+ Appears automatically after a file is loaded. Configure per-stim-type settings:
49
+
50
+ * Label, colour, gap (ms), CSP detection toggle
51
+ * Stimulation type and muscle group (sets physiological latency bounds for onset detection)
52
+ * Internal normalisation references and plateau tolerance for Mmax detection
53
+
54
+ Confirming setup auto-switches to Stage 1b. Settings persist between files.
55
+
56
+ ### Stage 1b — Single File Processing
57
+
58
+ Filter settings (bandpass, notch, mains noise canceller), time window and MEP onset detection parameters, CSP detection settings, outlier review, and analysis options. All settings are saved per file and restored on reload.
59
+
60
+ When reloading a previously processed file:
61
+
62
+ * Option to reuse the saved data range, select a new range, or use the whole file
63
+ * Previously adjusted marker positions, notes, exclusions, and AUC windows are restored and carried through the re-analysis
64
+
65
+ ### Stage 2 — Group Analysis LME Setup
66
+
67
+ Scan the derivatives folder to discover all processed sessions. Assign study design columns (e.g. Group, Condition, Timepoint), configure stim type roles (Reference, Conditioned, M-wave), and click **Build group analysis file** to merge all selected sessions into a single `group\\\_level\\\_LME\\\_ready.csv`.
68
+
69
+ \---
70
+
71
+ ## Installation
72
+
73
+ ### Option 1: pip (recommended for Python users)
74
+
75
+ ```bash
76
+ pip install mep-cmap-analyser
77
+ mep-cmap
78
+ ```
79
+
80
+ Python 3.9+ required. Tkinter must be available:
81
+
82
+ * **Windows/Mac**: included with standard Python
83
+ * **Linux (Ubuntu/Debian)**: `sudo apt install python3-tk`
84
+
85
+ ### Option 2: Compiled binaries (no Python required)
86
+
87
+ Download the latest release for your platform from the [Releases page](https://github.com/justinAndrushko/mep-cmap-analyser/releases):
88
+
89
+ |Platform|File|
90
+ |-|-|
91
+ |Windows|`MEP-CMAP\\\_Analyser\\\_Windows.zip`|
92
+ |macOS|`MEP-CMAP\\\_Analyser\\\_Mac.zip`|
93
+ |Linux|`MEP-CMAP\\\_Analyser\\\_Linux.tar.gz`|
94
+
95
+ Unzip and run the executable — no installation required.
96
+
97
+ ### Option 3: Run from source
98
+
99
+ ```bash
100
+ git clone https://github.com/justinAndrushko/mep-cmap-analyser.git
101
+ cd mep-cmap-analyser
102
+ pip install -r requirements.txt
103
+ python MEP\\\_CMAP\\\_Analyser.py
104
+ ```
105
+
106
+ \---
107
+
108
+ ## Quick start
109
+
110
+ ```bash
111
+ # Launch the GUI
112
+ mep-cmap
113
+
114
+ # Or from Python
115
+ from mep\\\_cmap import run\\\_app
116
+ run\\\_app()
117
+ ```
118
+
119
+ ### Scripted pipeline (no GUI)
120
+
121
+ ```python
122
+ from mep\\\_cmap import run\\\_pipeline, PipelineConfig
123
+
124
+ run\\\_pipeline(
125
+ input\\\_path = "path/to/recording.txt",
126
+ pre\\\_ms = 20,
127
+ post\\\_ms = 400,
128
+ ptp\\\_start = 10,
129
+ ptp\\\_end = 50,
130
+ prestim\\\_ms = 100,
131
+ marker\\\_name = "Keyboard",
132
+ )
133
+ ```
134
+
135
+ \---
136
+
137
+ ## Input format
138
+
139
+ The tool reads **Spike-2 text exports** (`.txt`) containing:
140
+
141
+ * Waveform channels (EMG, force, etc.)
142
+ * DigMark event timestamps
143
+
144
+ Files should follow BIDS naming conventions for automatic metadata parsing:
145
+
146
+ ```
147
+ sub-001\\\_ses-01\\\_limb-left\\\_recording.txt
148
+ ```
149
+
150
+ Single-file recordings with multiple stimulus types and multi-file sessions (one file per condition) are both supported.
151
+
152
+ \---
153
+
154
+ ## Output
155
+
156
+ Results are saved to a `derivatives/` folder beside (not inside) the raw data folder, following BIDS structure:
157
+
158
+ ```
159
+ study/
160
+ ├── rawdata/
161
+ │ └── sub-001/ses-01/...
162
+ └── derivatives/
163
+ ├── dataset\\\_session.json ← queue state, processing status, excluded files
164
+ ├── group\\\_level\\\_LME\\\_ready.csv ← merged group-level output (Stage 2)
165
+ └── sub-001/
166
+ └── ses-01/
167
+ ├── results/
168
+ │ ├── sub-001\\\_ses-01\\\_limb-left\\\_All\\\_stims\\\_trial\\\_summary.csv
169
+ │ ├── sub-001\\\_ses-01\\\_limb-left\\\_All\\\_stims\\\_trial\\\_summary.json
170
+ │ ├── sub-001\\\_ses-01\\\_limb-left\\\_ptp\\\_results.csv
171
+ │ └── sub-001\\\_ses-01\\\_limb-left\\\_ptp\\\_results\\\_with\\\_outliers.csv
172
+ ├── figures/
173
+ └── sub-001\\\_ses-01\\\_limb-left\\\_session.json ← per-file session state
174
+ ```
175
+
176
+ ### Trial-level CSV columns
177
+
178
+ |Column|Description|
179
+ |-|-|
180
+ |`PTP(mV)`|MEP peak-to-peak amplitude|
181
+ |`Latency(ms)`|MEP onset latency|
182
+ |`cSP\\\_Duration(ms)`|Cortical silent period duration|
183
+ |`cSP\\\_MEP\\\_Offset(ms)`|Time from stim to cSP onset|
184
+ |`cSP\\\_EMG\\\_Return(ms)`|Time from stim to EMG return after cSP|
185
+ |`MEP\\\_cSP\\\_Ratio`|PTP / cSP duration (Orth \& Rothwell, 2004)|
186
+ |`AUC(mV\\\*s)`|Area under the rectified EMG curve (onset to cSP start)|
187
+ |`Normalised\\\_PTP`|PTP / reference mean (Mmax or single-pulse reference)|
188
+ |`Reference\\\_Type`|How the reference mean was computed|
189
+ |`Reference\\\_Mean(mV)`|Reference amplitude used for normalisation|
190
+ |`Z\\\_PTP\\\_Within`|Z-score within stim type|
191
+ |`Z\\\_PTP\\\_Pooled`|Z-score pooled across all conditions|
192
+ |`PTP\\\_Detrended(mV)`|Linearly detrended PTP amplitude|
193
+ |`Outlier\\\_Decision`|Include / Exclude / Reviewed|
194
+ |`Manual\\\_Note`|Annotator note from Data Inspector|
195
+
196
+ ### Group-level CSV additional columns
197
+
198
+ |Column|Description|
199
+ |-|-|
200
+ |`participant\\\_id`|BIDS participant identifier|
201
+ |`session`|Session label|
202
+ |`task`|Task label (if assigned)|
203
+ |`timepoint`|Timepoint label (if assigned)|
204
+ |`Limb`|Limb identifier parsed from filename|
205
+ |`Stim\\\_Role`|Role assigned in Stage 2 (Reference, Conditioned, M-wave, etc.)|
206
+ |`\\\[custom columns]`|User-defined between/within-subject factors|
207
+
208
+ \---
209
+
210
+ ## Building from source (developers)
211
+
212
+ ```bash
213
+ # Windows
214
+ python build\\\_windows.py
215
+
216
+ # Linux
217
+ python3 -m venv venv\\\_linux
218
+ source venv\\\_linux/bin/activate
219
+ pip install -r requirements.txt
220
+ python3 build\\\_linux.py
221
+
222
+ # macOS
223
+ python3 build\\\_mac.py
224
+ ```
225
+
226
+ \---
227
+
228
+ ## Citation
229
+
230
+ If you use this tool in your research, please cite:
231
+
232
+ > Andrushko, J.W. (2026). MEP-CMAP Analyser (Version 0.9.1) \\\[Software].
233
+ > Northumbria University. https://doi.org/10.5281/zenodo.XXXXXXX
234
+
235
+ \---
236
+
237
+ ## References
238
+
239
+ * Orth, M., \& Rothwell, J.C. (2004). The cortical silent period: intrinsic variability and relation to the waveform of the transcranial magnetic stimulation pulse. *Clinical Neurophysiology*, 115(5), 1076–1082.
240
+ * Hupfeld, K.E., Swanson, C.W., Fling, B.W., \& Seidler, R.D. (2021). TMS-induced silent periods: A review of methods and call for consistency. *Journal of Neuroscience Methods*, 346, 108950.
241
+
242
+ \---
243
+
244
+ ## License
245
+
246
+ MIT License — see [LICENSE](LICENSE) for details.
247
+
@@ -0,0 +1,70 @@
1
+ """
2
+ mep_cmap
3
+ ~~~~~~~~
4
+ MEP-CMAP Analysis Tool — BIDS-compliant TMS/EMG neurophysiology pipeline.
5
+
6
+ Package layout
7
+ --------------
8
+ compat — gc patch, numpy shim, tk thread-safety
9
+ bids — StudyMetadata, BIDS label sanitisation
10
+ utils — shared helpers (_add_time_and_digmark)
11
+ io — Spike-2 file reading
12
+ filters — EMG filter functions
13
+ detection — MEP onset + CSP bootstrap detection
14
+ pipeline — PipelineConfig + all pipeline_* subfunctions + run_pipeline
15
+ inspector — DataInspectorWindow (per-trial interactive review)
16
+ stage2 — Stage2Mixin (group analysis tab)
17
+ filter_preview — FilterPreviewMixin (filter preview popup)
18
+ app — TMSAnalysisApp (main GUI, inherits stage2 + filter_preview)
19
+
20
+ Quickstart
21
+ ----------
22
+ python -m mep_cmap # launch the GUI
23
+ from mep_cmap import run_app; run_app()
24
+ """
25
+
26
+ # compat must be imported first — it disables the cyclic GC and patches tkinter
27
+ from . import compat # noqa: F401
28
+
29
+ from .bids import StudyMetadata, TOOL_VERSION
30
+ from .preferences import prefs, apply_scaling
31
+ from .pipeline import PipelineConfig, run_pipeline
32
+ from .detection import detect_mep_onset_peak_fraction, detect_csp_bootstrap
33
+
34
+ __version__ = TOOL_VERSION
35
+ __all__ = [
36
+ "run_app",
37
+ "StudyMetadata",
38
+ "PipelineConfig",
39
+ "run_pipeline",
40
+ "detect_mep_onset_peak_fraction",
41
+ "detect_csp_bootstrap",
42
+ ]
43
+
44
+
45
+ def run_app():
46
+ """Launch the MEP-CMAP Analysis GUI."""
47
+ import sys
48
+ import tkinter as tk
49
+
50
+ # Windows: create Tk root before numpy to avoid Tcl_AsyncDelete crash
51
+ pre_root = None
52
+ if sys.platform == "win32":
53
+ pre_root = tk.Tk()
54
+ pre_root.withdraw()
55
+
56
+ # Now safe to import matplotlib TkAgg backend
57
+ import matplotlib
58
+ matplotlib.use("TkAgg")
59
+ import matplotlib.pyplot as plt
60
+ from matplotlib.backends.backend_tkagg import (
61
+ FigureCanvasTkAgg, NavigationToolbar2Tk)
62
+
63
+ from .app import TMSAnalysisApp
64
+
65
+ root = pre_root if pre_root is not None else tk.Tk()
66
+ root.tk.call("tk", "scaling", 1.0)
67
+ root.deiconify()
68
+
69
+ app = TMSAnalysisApp(root)
70
+ root.mainloop()
@@ -0,0 +1,7 @@
1
+ """
2
+ Entry point for python -m mep_cmap
3
+ """
4
+ from mep_cmap import run_app
5
+
6
+ if __name__ == "__main__":
7
+ run_app()