braindecode 1.3.0.dev177069446__py3-none-any.whl → 1.3.0.dev177628147__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.
- braindecode/augmentation/__init__.py +3 -5
- braindecode/augmentation/base.py +5 -8
- braindecode/augmentation/functional.py +22 -25
- braindecode/augmentation/transforms.py +42 -51
- braindecode/classifier.py +16 -11
- braindecode/datasets/__init__.py +3 -5
- braindecode/datasets/base.py +13 -17
- braindecode/datasets/bbci.py +14 -13
- braindecode/datasets/bcicomp.py +5 -4
- braindecode/datasets/{bids/datasets.py → bids.py} +18 -12
- braindecode/datasets/{bids/iterable.py → experimental.py} +6 -8
- braindecode/datasets/{bids/hub.py → hub.py} +350 -375
- braindecode/datasets/{bids/hub_validation.py → hub_validation.py} +1 -2
- braindecode/datasets/mne.py +19 -19
- braindecode/datasets/moabb.py +10 -10
- braindecode/datasets/nmt.py +56 -58
- braindecode/datasets/sleep_physio_challe_18.py +5 -3
- braindecode/datasets/sleep_physionet.py +5 -5
- braindecode/datasets/tuh.py +18 -21
- braindecode/datasets/xy.py +9 -10
- braindecode/datautil/__init__.py +3 -3
- braindecode/datautil/serialization.py +20 -22
- braindecode/datautil/util.py +7 -120
- braindecode/eegneuralnet.py +52 -22
- braindecode/functional/functions.py +10 -7
- braindecode/functional/initialization.py +2 -3
- braindecode/models/__init__.py +3 -5
- braindecode/models/atcnet.py +39 -43
- braindecode/models/attentionbasenet.py +41 -37
- braindecode/models/attn_sleep.py +24 -26
- braindecode/models/base.py +6 -6
- braindecode/models/bendr.py +26 -50
- braindecode/models/biot.py +30 -61
- braindecode/models/contrawr.py +5 -5
- braindecode/models/ctnet.py +35 -35
- braindecode/models/deep4.py +5 -5
- braindecode/models/deepsleepnet.py +7 -7
- braindecode/models/eegconformer.py +26 -31
- braindecode/models/eeginception_erp.py +2 -2
- braindecode/models/eeginception_mi.py +6 -6
- braindecode/models/eegitnet.py +5 -5
- braindecode/models/eegminer.py +1 -1
- braindecode/models/eegnet.py +3 -3
- braindecode/models/eegnex.py +2 -2
- braindecode/models/eegsimpleconv.py +2 -2
- braindecode/models/eegsym.py +7 -7
- braindecode/models/eegtcnet.py +6 -6
- braindecode/models/fbcnet.py +2 -2
- braindecode/models/fblightconvnet.py +3 -3
- braindecode/models/fbmsnet.py +3 -3
- braindecode/models/hybrid.py +2 -2
- braindecode/models/ifnet.py +5 -5
- braindecode/models/labram.py +46 -70
- braindecode/models/luna.py +5 -60
- braindecode/models/medformer.py +21 -23
- braindecode/models/msvtnet.py +15 -15
- braindecode/models/patchedtransformer.py +55 -55
- braindecode/models/sccnet.py +2 -2
- braindecode/models/shallow_fbcsp.py +3 -5
- braindecode/models/signal_jepa.py +12 -39
- braindecode/models/sinc_shallow.py +4 -3
- braindecode/models/sleep_stager_blanco_2020.py +2 -2
- braindecode/models/sleep_stager_chambon_2018.py +2 -2
- braindecode/models/sparcnet.py +8 -8
- braindecode/models/sstdpn.py +869 -869
- braindecode/models/summary.csv +17 -19
- braindecode/models/syncnet.py +2 -2
- braindecode/models/tcn.py +5 -5
- braindecode/models/tidnet.py +3 -3
- braindecode/models/tsinception.py +3 -3
- braindecode/models/usleep.py +7 -7
- braindecode/models/util.py +14 -165
- braindecode/modules/__init__.py +1 -9
- braindecode/modules/activation.py +3 -29
- braindecode/modules/attention.py +0 -123
- braindecode/modules/blocks.py +1 -53
- braindecode/modules/convolution.py +0 -53
- braindecode/modules/filter.py +0 -31
- braindecode/modules/layers.py +0 -84
- braindecode/modules/linear.py +1 -22
- braindecode/modules/stats.py +0 -10
- braindecode/modules/util.py +0 -9
- braindecode/modules/wrapper.py +0 -17
- braindecode/preprocessing/preprocess.py +0 -3
- braindecode/regressor.py +18 -15
- braindecode/samplers/ssl.py +1 -1
- braindecode/util.py +28 -38
- braindecode/version.py +1 -1
- braindecode-1.3.0.dev177628147.dist-info/METADATA +202 -0
- braindecode-1.3.0.dev177628147.dist-info/RECORD +114 -0
- braindecode/datasets/bids/__init__.py +0 -54
- braindecode/datasets/bids/format.py +0 -717
- braindecode/datasets/bids/hub_format.py +0 -717
- braindecode/datasets/bids/hub_io.py +0 -197
- braindecode/datasets/chb_mit.py +0 -163
- braindecode/datasets/siena.py +0 -162
- braindecode/datasets/utils.py +0 -67
- braindecode/models/brainmodule.py +0 -845
- braindecode/models/config.py +0 -233
- braindecode/models/reve.py +0 -843
- braindecode-1.3.0.dev177069446.dist-info/METADATA +0 -230
- braindecode-1.3.0.dev177069446.dist-info/RECORD +0 -124
- {braindecode-1.3.0.dev177069446.dist-info → braindecode-1.3.0.dev177628147.dist-info}/WHEEL +0 -0
- {braindecode-1.3.0.dev177069446.dist-info → braindecode-1.3.0.dev177628147.dist-info}/licenses/LICENSE.txt +0 -0
- {braindecode-1.3.0.dev177069446.dist-info → braindecode-1.3.0.dev177628147.dist-info}/licenses/NOTICE.txt +0 -0
- {braindecode-1.3.0.dev177069446.dist-info → braindecode-1.3.0.dev177628147.dist-info}/top_level.txt +0 -0
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
# mypy: ignore-errors
|
|
2
|
-
"""
|
|
3
|
-
Low-level Zarr I/O helpers for Hub integration.
|
|
4
|
-
|
|
5
|
-
These functions keep the Zarr serialization details isolated from hub.py.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from __future__ import annotations
|
|
9
|
-
|
|
10
|
-
import json
|
|
11
|
-
import warnings
|
|
12
|
-
from pathlib import Path
|
|
13
|
-
|
|
14
|
-
import numpy as np
|
|
15
|
-
import pandas as pd
|
|
16
|
-
from mne.utils import _soft_import
|
|
17
|
-
|
|
18
|
-
zarr = _soft_import("zarr", purpose="hugging face integration", strict=False)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def _sanitize_for_json(obj):
|
|
22
|
-
"""Replace NaN/Inf with None for valid JSON."""
|
|
23
|
-
if isinstance(obj, float):
|
|
24
|
-
if np.isnan(obj) or np.isinf(obj):
|
|
25
|
-
return None
|
|
26
|
-
return obj
|
|
27
|
-
if isinstance(obj, dict):
|
|
28
|
-
return {k: _sanitize_for_json(v) for k, v in obj.items()}
|
|
29
|
-
if isinstance(obj, list):
|
|
30
|
-
return [_sanitize_for_json(v) for v in obj]
|
|
31
|
-
if isinstance(obj, np.ndarray):
|
|
32
|
-
return _sanitize_for_json(obj.tolist())
|
|
33
|
-
return obj
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def _restore_nan_from_json(obj):
|
|
37
|
-
"""Restore NaN values from None in JSON-loaded data."""
|
|
38
|
-
if isinstance(obj, dict):
|
|
39
|
-
return {k: _restore_nan_from_json(v) for k, v in obj.items()}
|
|
40
|
-
if isinstance(obj, list):
|
|
41
|
-
if len(obj) > 0 and all(isinstance(x, (int, float, type(None))) for x in obj):
|
|
42
|
-
return [np.nan if x is None else x for x in obj]
|
|
43
|
-
return [_restore_nan_from_json(v) for v in obj]
|
|
44
|
-
return obj
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def _save_windows_to_zarr(
|
|
48
|
-
grp, data, metadata, description, info, compressor, target_name
|
|
49
|
-
):
|
|
50
|
-
"""Save windowed data to Zarr group (low-level function)."""
|
|
51
|
-
data_array = data.astype(np.float32)
|
|
52
|
-
compressors_list = [compressor] if compressor is not None else None
|
|
53
|
-
|
|
54
|
-
grp.create_array(
|
|
55
|
-
"data",
|
|
56
|
-
data=data_array,
|
|
57
|
-
chunks=(1, data_array.shape[1], data_array.shape[2]),
|
|
58
|
-
compressors=compressors_list,
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
store_path = getattr(grp.store, "path", getattr(grp.store, "root", None))
|
|
62
|
-
metadata_path = Path(store_path) / grp.path / "metadata.tsv"
|
|
63
|
-
metadata.to_csv(metadata_path, sep="\t", index=True)
|
|
64
|
-
|
|
65
|
-
grp.attrs["description"] = json.loads(description.to_json(date_format="iso"))
|
|
66
|
-
grp.attrs["info"] = _sanitize_for_json(info)
|
|
67
|
-
|
|
68
|
-
if target_name is not None:
|
|
69
|
-
grp.attrs["target_name"] = target_name
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def _save_eegwindows_to_zarr(
|
|
73
|
-
grp, raw, metadata, description, info, targets_from, last_target_only, compressor
|
|
74
|
-
):
|
|
75
|
-
"""Save EEG continuous raw data to Zarr group (low-level function)."""
|
|
76
|
-
continuous_data = raw.get_data()
|
|
77
|
-
continuous_float = continuous_data.astype(np.float32)
|
|
78
|
-
compressors_list = [compressor] if compressor is not None else None
|
|
79
|
-
|
|
80
|
-
grp.create_array(
|
|
81
|
-
"data",
|
|
82
|
-
data=continuous_float,
|
|
83
|
-
chunks=(continuous_float.shape[0], min(10000, continuous_float.shape[1])),
|
|
84
|
-
compressors=compressors_list,
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
store_path = getattr(grp.store, "path", getattr(grp.store, "root", None))
|
|
88
|
-
metadata_path = Path(store_path) / grp.path / "metadata.tsv"
|
|
89
|
-
metadata.to_csv(metadata_path, sep="\t", index=True)
|
|
90
|
-
|
|
91
|
-
grp.attrs["description"] = json.loads(description.to_json(date_format="iso"))
|
|
92
|
-
grp.attrs["info"] = _sanitize_for_json(info)
|
|
93
|
-
grp.attrs["targets_from"] = targets_from
|
|
94
|
-
grp.attrs["last_target_only"] = last_target_only
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def _load_windows_from_zarr(grp, preload):
|
|
98
|
-
"""Load windowed data from Zarr group (low-level function)."""
|
|
99
|
-
store_path = getattr(grp.store, "path", getattr(grp.store, "root", None))
|
|
100
|
-
metadata_path = Path(store_path) / grp.path / "metadata.tsv"
|
|
101
|
-
metadata = pd.read_csv(metadata_path, sep="\t", index_col=0)
|
|
102
|
-
|
|
103
|
-
description = pd.Series(grp.attrs["description"])
|
|
104
|
-
info_dict = _restore_nan_from_json(grp.attrs["info"])
|
|
105
|
-
|
|
106
|
-
if preload:
|
|
107
|
-
data = grp["data"][:]
|
|
108
|
-
else:
|
|
109
|
-
data = grp["data"][:]
|
|
110
|
-
warnings.warn(
|
|
111
|
-
"Lazy loading from Zarr not fully implemented yet. "
|
|
112
|
-
"Loading all data into memory.",
|
|
113
|
-
UserWarning,
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
target_name = grp.attrs.get("target_name", None)
|
|
117
|
-
|
|
118
|
-
return data, metadata, description, info_dict, target_name
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def _load_eegwindows_from_zarr(grp, preload):
|
|
122
|
-
"""Load EEG continuous raw data from Zarr group (low-level function)."""
|
|
123
|
-
store_path = getattr(grp.store, "path", getattr(grp.store, "root", None))
|
|
124
|
-
metadata_path = Path(store_path) / grp.path / "metadata.tsv"
|
|
125
|
-
metadata = pd.read_csv(metadata_path, sep="\t", index_col=0)
|
|
126
|
-
|
|
127
|
-
description = pd.Series(grp.attrs["description"])
|
|
128
|
-
info_dict = _restore_nan_from_json(grp.attrs["info"])
|
|
129
|
-
|
|
130
|
-
if preload:
|
|
131
|
-
data = grp["data"][:]
|
|
132
|
-
else:
|
|
133
|
-
data = grp["data"][:]
|
|
134
|
-
warnings.warn(
|
|
135
|
-
"Lazy loading from Zarr not fully implemented yet. "
|
|
136
|
-
"Loading all data into memory.",
|
|
137
|
-
UserWarning,
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
targets_from = grp.attrs.get("targets_from", "metadata")
|
|
141
|
-
last_target_only = grp.attrs.get("last_target_only", True)
|
|
142
|
-
|
|
143
|
-
return data, metadata, description, info_dict, targets_from, last_target_only
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def _save_raw_to_zarr(grp, raw, description, info, target_name, compressor):
|
|
147
|
-
"""Save RawDataset continuous raw data to Zarr group (low-level function)."""
|
|
148
|
-
continuous_data = raw.get_data()
|
|
149
|
-
continuous_float = continuous_data.astype(np.float32)
|
|
150
|
-
compressors_list = [compressor] if compressor is not None else None
|
|
151
|
-
|
|
152
|
-
grp.create_array(
|
|
153
|
-
"data",
|
|
154
|
-
data=continuous_float,
|
|
155
|
-
chunks=(continuous_float.shape[0], min(10000, continuous_float.shape[1])),
|
|
156
|
-
compressors=compressors_list,
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
grp.attrs["description"] = json.loads(description.to_json(date_format="iso"))
|
|
160
|
-
grp.attrs["info"] = _sanitize_for_json(info)
|
|
161
|
-
|
|
162
|
-
if target_name is not None:
|
|
163
|
-
grp.attrs["target_name"] = target_name
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
def _load_raw_from_zarr(grp, preload):
|
|
167
|
-
"""Load RawDataset continuous raw data from Zarr group (low-level function)."""
|
|
168
|
-
description = pd.Series(grp.attrs["description"])
|
|
169
|
-
info_dict = _restore_nan_from_json(grp.attrs["info"])
|
|
170
|
-
|
|
171
|
-
if preload:
|
|
172
|
-
data = grp["data"][:]
|
|
173
|
-
else:
|
|
174
|
-
data = grp["data"][:]
|
|
175
|
-
warnings.warn(
|
|
176
|
-
"Lazy loading from Zarr not fully implemented yet. "
|
|
177
|
-
"Loading all data into memory.",
|
|
178
|
-
UserWarning,
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
target_name = grp.attrs.get("target_name", None)
|
|
182
|
-
|
|
183
|
-
return data, description, info_dict, target_name
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
def _create_compressor(compression, compression_level):
|
|
187
|
-
"""Create a Zarr v3 compressor codec."""
|
|
188
|
-
if zarr is False:
|
|
189
|
-
raise ImportError(
|
|
190
|
-
"Zarr is not installed. Install with: pip install braindecode[hub]"
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
if compression is None or compression not in ("blosc", "zstd", "gzip"):
|
|
194
|
-
return None
|
|
195
|
-
|
|
196
|
-
name = "zstd" if compression == "blosc" else compression
|
|
197
|
-
return {"name": name, "configuration": {"level": compression_level}}
|
braindecode/datasets/chb_mit.py
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This dataset is a BIDS-compatible version of the CHB-MIT Scalp EEG Database.
|
|
3
|
-
|
|
4
|
-
It reorganizes the file structure to comply with the BIDS specification. To this effect:
|
|
5
|
-
|
|
6
|
-
The data from subject chb21 was moved to sub-01/ses-02.
|
|
7
|
-
Metadata was organized according to BIDS.
|
|
8
|
-
Data in the EEG edf files was modified to keep only the 18 channels from a double banana bipolar montage.
|
|
9
|
-
Annotations were formatted as BIDS-score compatible `tsv` files.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
# Authors: Dan, Jonathan
|
|
13
|
-
# Shoeb, Ali (Data collector)
|
|
14
|
-
# Bruno Aristimunha <b.aristimunha@gmail.com>
|
|
15
|
-
#
|
|
16
|
-
# License: BSD (3-clause)
|
|
17
|
-
from __future__ import annotations
|
|
18
|
-
|
|
19
|
-
from pathlib import Path
|
|
20
|
-
|
|
21
|
-
from mne.datasets import fetch_dataset
|
|
22
|
-
|
|
23
|
-
from braindecode.datasets import BIDSDataset
|
|
24
|
-
from braindecode.datasets.utils import _correct_dataset_path
|
|
25
|
-
|
|
26
|
-
CHB_MIT_URL = "https://zenodo.org/records/10259996/files/BIDS_CHB-MIT.zip"
|
|
27
|
-
CHB_MIT_archive_name = "chb_mit_bids.zip"
|
|
28
|
-
CHB_MIT_folder_name = "CHB-MIT-BIDS-eeg-dataset"
|
|
29
|
-
CHB_MIT_dataset_name = "CHB-MIT-EEG-Corpus"
|
|
30
|
-
|
|
31
|
-
CHB_MIT_dataset_params = {
|
|
32
|
-
"dataset_name": CHB_MIT_dataset_name,
|
|
33
|
-
"url": CHB_MIT_URL,
|
|
34
|
-
"archive_name": CHB_MIT_archive_name,
|
|
35
|
-
"folder_name": CHB_MIT_folder_name,
|
|
36
|
-
"hash": "078f4e110e40d10fef1a38a892571ad24666c488e8118a01002c9224909256ed", # sha256
|
|
37
|
-
"config_key": CHB_MIT_dataset_name,
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class CHBMIT(BIDSDataset):
|
|
42
|
-
"""The Children's Hospital Boston EEG Dataset.
|
|
43
|
-
|
|
44
|
-
This database, collected at the Children's Hospital Boston, consists of EEG recordings
|
|
45
|
-
from pediatric subjects with intractable seizures. Subjects were monitored for up to
|
|
46
|
-
several days following withdrawal of anti-seizure medication in order to characterize
|
|
47
|
-
their seizures and assess their candidacy for surgical intervention.
|
|
48
|
-
|
|
49
|
-
**Description of the contents of the dataset:**
|
|
50
|
-
|
|
51
|
-
Each folder (sub-01, sub-01, etc.) contains between 9 and 42 continuous .edf
|
|
52
|
-
files from a single subject. Hardware limitations resulted in gaps between
|
|
53
|
-
consecutively-numbered .edf files, during which the signals were not recorded;
|
|
54
|
-
in most cases, the gaps are 10 seconds or less, but occasionally there are much
|
|
55
|
-
longer gaps. In order to protect the privacy of the subjects, all protected health
|
|
56
|
-
information (PHI) in the original .edf files has been replaced with surrogate information
|
|
57
|
-
in the files provided here. Dates in the original .edf files have been replaced by
|
|
58
|
-
surrogate dates, but the time relationships between the individual files belonging
|
|
59
|
-
to each case have been preserved. In most cases, the .edf files contain exactly one
|
|
60
|
-
hour of digitized EEG signals, although those belonging to case sub-10 are two hours
|
|
61
|
-
long, and those belonging to cases sub-04, sub-06, sub-07, sub-09, and sub-23 are
|
|
62
|
-
four hours long; occasionally, files in which seizures are recorded are shorter.
|
|
63
|
-
|
|
64
|
-
The EEG is recorded at 256 Hz with a 16-bit resolution. The recordings are
|
|
65
|
-
referenced in a double banana bipolar montage with 18 channels from the 10-20 electrode system.
|
|
66
|
-
|
|
67
|
-
This BIDS-compatible version of the dataset was published by Jonathan Dan :footcite:`Dan2025`
|
|
68
|
-
and is based on the original CHB MIT EEG Database :footcite:`Guttag2010`, :footcite:`Shoeb2009`.
|
|
69
|
-
|
|
70
|
-
.. versionadded:: 1.3
|
|
71
|
-
|
|
72
|
-
Parameters
|
|
73
|
-
----------
|
|
74
|
-
root : pathlib.Path | str
|
|
75
|
-
The root of the BIDS path.
|
|
76
|
-
subjects : str | array-like of str | None
|
|
77
|
-
The subject ID. Corresponds to "sub".
|
|
78
|
-
sessions : str | array-like of str | None
|
|
79
|
-
The acquisition session. Corresponds to "ses".
|
|
80
|
-
tasks : str | array-like of str | None
|
|
81
|
-
The experimental task. Corresponds to "task".
|
|
82
|
-
acquisitions : str | array-like of str | None
|
|
83
|
-
The acquisition parameters. Corresponds to "acq".
|
|
84
|
-
runs : str | array-like of str | None
|
|
85
|
-
The run number. Corresponds to "run".
|
|
86
|
-
processings : str | array-like of str | None
|
|
87
|
-
The processing label. Corresponds to "proc".
|
|
88
|
-
recordings : str | array-like of str | None
|
|
89
|
-
The recording name. Corresponds to "rec".
|
|
90
|
-
spaces : str | array-like of str | None
|
|
91
|
-
The coordinate space for anatomical and sensor location
|
|
92
|
-
files (e.g., ``*_electrodes.tsv``, ``*_markers.mrk``).
|
|
93
|
-
Corresponds to "space".
|
|
94
|
-
Note that valid values for ``space`` must come from a list
|
|
95
|
-
of BIDS keywords as described in the BIDS specification.
|
|
96
|
-
splits : str | array-like of str | None
|
|
97
|
-
The split of the continuous recording file for ``.fif`` data.
|
|
98
|
-
Corresponds to "split".
|
|
99
|
-
descriptions : str | array-like of str | None
|
|
100
|
-
This corresponds to the BIDS entity ``desc``. It is used to provide
|
|
101
|
-
additional information for derivative data, e.g., preprocessed data
|
|
102
|
-
may be assigned ``description='cleaned'``.
|
|
103
|
-
suffixes : str | array-like of str | None
|
|
104
|
-
The filename suffix. This is the entity after the
|
|
105
|
-
last ``_`` before the extension. E.g., ``'channels'``.
|
|
106
|
-
The following filename suffix's are accepted:
|
|
107
|
-
'meg', 'markers', 'eeg', 'ieeg', 'T1w',
|
|
108
|
-
'participants', 'scans', 'electrodes', 'coordsystem',
|
|
109
|
-
'channels', 'events', 'headshape', 'digitizer',
|
|
110
|
-
'beh', 'physio', 'stim'
|
|
111
|
-
extensions : str | array-like of str | None
|
|
112
|
-
The extension of the filename. E.g., ``'.json'``.
|
|
113
|
-
By default, uses the ones accepted by :func:`mne_bids.read_raw_bids`.
|
|
114
|
-
datatypes : str | array-like of str | None
|
|
115
|
-
The BIDS data type, e.g., ``'anat'``, ``'func'``, ``'eeg'``, ``'meg'``,
|
|
116
|
-
``'ieeg'``.
|
|
117
|
-
check : bool
|
|
118
|
-
If ``True``, only returns paths that conform to BIDS. If ``False``
|
|
119
|
-
(default), the ``.check`` attribute of the returned
|
|
120
|
-
:class:`mne_bids.BIDSPath` object will be set to ``True`` for paths that
|
|
121
|
-
do conform to BIDS, and to ``False`` for those that don't.
|
|
122
|
-
preload : bool
|
|
123
|
-
If True, preload the data. Defaults to False.
|
|
124
|
-
n_jobs : int
|
|
125
|
-
Number of jobs to run in parallel. Defaults to 1.
|
|
126
|
-
|
|
127
|
-
References
|
|
128
|
-
----------
|
|
129
|
-
.. footbibliography::
|
|
130
|
-
"""
|
|
131
|
-
|
|
132
|
-
def __init__(self, root=None, *args, **kwargs):
|
|
133
|
-
# Download dataset if not present
|
|
134
|
-
if root is None:
|
|
135
|
-
path_root = fetch_dataset(
|
|
136
|
-
dataset_params=CHB_MIT_dataset_params,
|
|
137
|
-
path=None,
|
|
138
|
-
processor="unzip",
|
|
139
|
-
force_update=False,
|
|
140
|
-
)
|
|
141
|
-
# First time we fetch the dataset, we need to move the files to the
|
|
142
|
-
# correct directory.
|
|
143
|
-
path_root = _correct_dataset_path(
|
|
144
|
-
path_root, CHB_MIT_archive_name, "BIDS_CHB-MIT"
|
|
145
|
-
)
|
|
146
|
-
else:
|
|
147
|
-
# Validate that the provided root is a valid BIDS dataset
|
|
148
|
-
if not Path(f"{root}/participants.tsv").exists():
|
|
149
|
-
raise ValueError(
|
|
150
|
-
f"The provided root directory {root} does not contain a valid "
|
|
151
|
-
"BIDS dataset (missing participants.tsv). Please ensure the "
|
|
152
|
-
"root points directly to the BIDS dataset directory."
|
|
153
|
-
)
|
|
154
|
-
path_root = root
|
|
155
|
-
|
|
156
|
-
kwargs["root"] = path_root
|
|
157
|
-
|
|
158
|
-
super().__init__(
|
|
159
|
-
*args,
|
|
160
|
-
extensions=".edf",
|
|
161
|
-
check=False,
|
|
162
|
-
**kwargs,
|
|
163
|
-
)
|
braindecode/datasets/siena.py
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This dataset is a BIDS compatible version of the Siena Scalp EEG Database.
|
|
3
|
-
|
|
4
|
-
It reorganizes the file structure to comply with the BIDS specification. To this effect:
|
|
5
|
-
|
|
6
|
-
- Metadata was organized according to BIDS.
|
|
7
|
-
- Data in the EEG edf files was modified to keep only the 19 channels from a 10-20 EEG system.
|
|
8
|
-
- Annotations were formatted as BIDS-score compatible tsv files.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
# Authors: Dan, Jonathan
|
|
12
|
-
# Detti, Paolo
|
|
13
|
-
# Bruno Aristimunha <b.aristimunha@gmail.com>
|
|
14
|
-
#
|
|
15
|
-
# License: BSD (3-clause)
|
|
16
|
-
from __future__ import annotations
|
|
17
|
-
|
|
18
|
-
from pathlib import Path
|
|
19
|
-
|
|
20
|
-
from mne.datasets import fetch_dataset
|
|
21
|
-
|
|
22
|
-
from braindecode.datasets import BIDSDataset
|
|
23
|
-
from braindecode.datasets.utils import _correct_dataset_path
|
|
24
|
-
|
|
25
|
-
SIENA_URL = "https://zenodo.org/records/10640762/files/BIDS_Siena.zip"
|
|
26
|
-
SIENA_archive_name = "SIENA.zip"
|
|
27
|
-
SIENA_folder_name = "SIENA-BIDS-eeg-dataset"
|
|
28
|
-
SIENA_dataset_name = "SIENA-EEG-Corpus"
|
|
29
|
-
|
|
30
|
-
SIENA_dataset_params = {
|
|
31
|
-
"dataset_name": SIENA_dataset_name,
|
|
32
|
-
"url": SIENA_URL,
|
|
33
|
-
"archive_name": SIENA_archive_name,
|
|
34
|
-
"folder_name": SIENA_folder_name,
|
|
35
|
-
"hash": "126e71e18570cf359a440ba5227494ecffca4b0b0057c733f90ec29ba5e15ff8", # sha256
|
|
36
|
-
"config_key": SIENA_dataset_name,
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
class SIENA(BIDSDataset):
|
|
41
|
-
"""The Siena EEG Dataset.
|
|
42
|
-
|
|
43
|
-
The database consists of EEG recordings of 14 patients acquired at the Unit of Neurology
|
|
44
|
-
and Neurophysiology of the University of Siena.
|
|
45
|
-
|
|
46
|
-
Subjects include 9 males (ages 25-71) and 5 females (ages 20-58).
|
|
47
|
-
Subjects were monitored with a Video-EEG with a sampling rate of 512 Hz,
|
|
48
|
-
with electrodes arranged on the basis of the international 10-20 System.
|
|
49
|
-
|
|
50
|
-
Most of the recordings also contain 1 or 2 EKG signals.
|
|
51
|
-
The diagnosis of epilepsy and the classification of seizures according to the
|
|
52
|
-
criteria of the International League Against Epilepsy were performed by an expert
|
|
53
|
-
clinician after a careful review of the clinical and electrophysiological
|
|
54
|
-
data of each patient.
|
|
55
|
-
|
|
56
|
-
This BIDS-compatible version of the dataset was published by Jonathan Dan [Dan2025]_
|
|
57
|
-
and is based on the original Siena Scalp EEG Database [Detti2020a]_, [Detti2020b]_.
|
|
58
|
-
|
|
59
|
-
.. versionadded:: 1.3
|
|
60
|
-
|
|
61
|
-
Parameters
|
|
62
|
-
----------
|
|
63
|
-
root : pathlib.Path | str
|
|
64
|
-
The root of the BIDS path.
|
|
65
|
-
subjects : str | array-like of str | None
|
|
66
|
-
The subject ID. Corresponds to "sub".
|
|
67
|
-
sessions : str | array-like of str | None
|
|
68
|
-
The acquisition session. Corresponds to "ses".
|
|
69
|
-
tasks : str | array-like of str | None
|
|
70
|
-
The experimental task. Corresponds to "task".
|
|
71
|
-
acquisitions : str | array-like of str | None
|
|
72
|
-
The acquisition parameters. Corresponds to "acq".
|
|
73
|
-
runs : str | array-like of str | None
|
|
74
|
-
The run number. Corresponds to "run".
|
|
75
|
-
processings : str | array-like of str | None
|
|
76
|
-
The processing label. Corresponds to "proc".
|
|
77
|
-
recordings : str | array-like of str | None
|
|
78
|
-
The recording name. Corresponds to "rec".
|
|
79
|
-
spaces : str | array-like of str | None
|
|
80
|
-
The coordinate space for anatomical and sensor location
|
|
81
|
-
files (e.g., ``*_electrodes.tsv``, ``*_markers.mrk``).
|
|
82
|
-
Corresponds to "space".
|
|
83
|
-
Note that valid values for ``space`` must come from a list
|
|
84
|
-
of BIDS keywords as described in the BIDS specification.
|
|
85
|
-
splits : str | array-like of str | None
|
|
86
|
-
The split of the continuous recording file for ``.fif`` data.
|
|
87
|
-
Corresponds to "split".
|
|
88
|
-
descriptions : str | array-like of str | None
|
|
89
|
-
This corresponds to the BIDS entity ``desc``. It is used to provide
|
|
90
|
-
additional information for derivative data, e.g., preprocessed data
|
|
91
|
-
may be assigned ``description='cleaned'``.
|
|
92
|
-
suffixes : str | array-like of str | None
|
|
93
|
-
The filename suffix. This is the entity after the
|
|
94
|
-
last ``_`` before the extension. E.g., ``'channels'``.
|
|
95
|
-
The following filename suffix's are accepted:
|
|
96
|
-
'meg', 'markers', 'eeg', 'ieeg', 'T1w',
|
|
97
|
-
'participants', 'scans', 'electrodes', 'coordsystem',
|
|
98
|
-
'channels', 'events', 'headshape', 'digitizer',
|
|
99
|
-
'beh', 'physio', 'stim'
|
|
100
|
-
extensions : str | array-like of str | None
|
|
101
|
-
The extension of the filename. E.g., ``'.json'``.
|
|
102
|
-
By default, uses the ones accepted by :func:`mne_bids.read_raw_bids`.
|
|
103
|
-
datatypes : str | array-like of str | None
|
|
104
|
-
The BIDS data type, e.g., ``'anat'``, ``'func'``, ``'eeg'``, ``'meg'``,
|
|
105
|
-
``'ieeg'``.
|
|
106
|
-
check : bool
|
|
107
|
-
If ``True``, only returns paths that conform to BIDS. If ``False``
|
|
108
|
-
(default), the ``.check`` attribute of the returned
|
|
109
|
-
:class:`mne_bids.BIDSPath` object will be set to ``True`` for paths that
|
|
110
|
-
do conform to BIDS, and to ``False`` for those that don't.
|
|
111
|
-
preload : bool
|
|
112
|
-
If True, preload the data. Defaults to False.
|
|
113
|
-
n_jobs : int
|
|
114
|
-
Number of jobs to run in parallel. Defaults to 1.
|
|
115
|
-
|
|
116
|
-
References
|
|
117
|
-
----------
|
|
118
|
-
.. [Detti2020a] Detti, P. (2020). Siena Scalp EEG Database (version 1.0.0).
|
|
119
|
-
PhysioNet. RRID:SCR_007345. https://doi.org/10.13026/5d4a-j060
|
|
120
|
-
.. [Detti2020b] Detti, P., Vatti, G., Zabalo Manrique de Lara, G.
|
|
121
|
-
EEG Synchronization Analysis for Seizure Prediction:
|
|
122
|
-
A Study on Data of Noninvasive Recordings.
|
|
123
|
-
Processes 2020, 8(7), 846; https://doi.org/10.3390/pr8070846
|
|
124
|
-
.. [Dan2025] Dan, J., Pale, U., Amirshahi, A., Cappelletti, W.,
|
|
125
|
-
Ingolfsson, T. M., Wang, X., ... & Ryvlin, P. (2025).
|
|
126
|
-
SzCORE: seizure community open-source research evaluatio
|
|
127
|
-
framework for the validation of electroencephalography-based
|
|
128
|
-
automated seizure detection algorithms. Epilepsia, 66, 14-24.
|
|
129
|
-
"""
|
|
130
|
-
|
|
131
|
-
def __init__(self, root=None, *args, **kwargs):
|
|
132
|
-
# Download dataset if not present
|
|
133
|
-
if root is None:
|
|
134
|
-
path_root = fetch_dataset(
|
|
135
|
-
dataset_params=SIENA_dataset_params,
|
|
136
|
-
path=None,
|
|
137
|
-
processor="unzip",
|
|
138
|
-
force_update=False,
|
|
139
|
-
)
|
|
140
|
-
# First time we fetch the dataset, we need to move the files to the
|
|
141
|
-
# correct directory.
|
|
142
|
-
path_root = _correct_dataset_path(
|
|
143
|
-
path_root, SIENA_archive_name, "BIDS_Siena"
|
|
144
|
-
)
|
|
145
|
-
else:
|
|
146
|
-
# Validate that the provided root is a valid BIDS dataset
|
|
147
|
-
if not Path(f"{root}/participants.tsv").exists():
|
|
148
|
-
raise ValueError(
|
|
149
|
-
f"The provided root directory {root} does not contain a valid "
|
|
150
|
-
"BIDS dataset (missing participants.tsv). Please ensure the "
|
|
151
|
-
"root points directly to the BIDS dataset directory."
|
|
152
|
-
)
|
|
153
|
-
path_root = root
|
|
154
|
-
|
|
155
|
-
kwargs["root"] = path_root
|
|
156
|
-
|
|
157
|
-
super().__init__(
|
|
158
|
-
*args,
|
|
159
|
-
extensions=".edf",
|
|
160
|
-
check=False,
|
|
161
|
-
**kwargs,
|
|
162
|
-
)
|
braindecode/datasets/utils.py
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
"""Utility functions for dataset handling."""
|
|
2
|
-
|
|
3
|
-
# Authors: Bruno Aristimunha <b.aristimunha@gmail.com>
|
|
4
|
-
#
|
|
5
|
-
# License: BSD (3-clause)
|
|
6
|
-
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
import os
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def _correct_dataset_path(
|
|
14
|
-
path: str, archive_name: str, subfolder_name: str | None = None
|
|
15
|
-
) -> str:
|
|
16
|
-
"""
|
|
17
|
-
Correct the dataset path after download and extraction.
|
|
18
|
-
|
|
19
|
-
This function handles two common post-download scenarios:
|
|
20
|
-
1. Renames '.unzip' suffixed directories created by some extraction tools
|
|
21
|
-
2. Navigates into a subfolder if the archive extracts to a nested directory
|
|
22
|
-
|
|
23
|
-
Parameters
|
|
24
|
-
----------
|
|
25
|
-
path : str
|
|
26
|
-
Expected path to the dataset directory.
|
|
27
|
-
archive_name : str
|
|
28
|
-
Name of the downloaded archive file without extension
|
|
29
|
-
(e.g., "chb_mit_bids", "NMT").
|
|
30
|
-
subfolder_name : str | None
|
|
31
|
-
Name of the subfolder within the extracted archive that contains the
|
|
32
|
-
actual data. If provided and the subfolder exists, the path will be
|
|
33
|
-
updated to point to it. If None, only renaming is attempted.
|
|
34
|
-
Default is None.
|
|
35
|
-
|
|
36
|
-
Returns
|
|
37
|
-
-------
|
|
38
|
-
str
|
|
39
|
-
The corrected path to the dataset directory.
|
|
40
|
-
|
|
41
|
-
Raises
|
|
42
|
-
------
|
|
43
|
-
PermissionError
|
|
44
|
-
If the '.unzip' directory exists but cannot be renamed due to
|
|
45
|
-
insufficient permissions.
|
|
46
|
-
"""
|
|
47
|
-
if not Path(path).exists():
|
|
48
|
-
unzip_file_name = f"{archive_name}.unzip"
|
|
49
|
-
if (Path(path).parent / unzip_file_name).exists():
|
|
50
|
-
try:
|
|
51
|
-
os.rename(
|
|
52
|
-
src=Path(path).parent / unzip_file_name,
|
|
53
|
-
dst=Path(path),
|
|
54
|
-
)
|
|
55
|
-
except PermissionError:
|
|
56
|
-
raise PermissionError(
|
|
57
|
-
f"Please rename {Path(path).parent / unzip_file_name} "
|
|
58
|
-
f"manually to {path} and try again."
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
# Check if the subfolder exists inside the path
|
|
62
|
-
if subfolder_name is not None:
|
|
63
|
-
subfolder_path = os.path.join(path, subfolder_name)
|
|
64
|
-
if Path(subfolder_path).exists():
|
|
65
|
-
path = subfolder_path
|
|
66
|
-
|
|
67
|
-
return path
|