braindecode 1.3.0.dev177069446__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/__init__.py +9 -0
- braindecode/augmentation/__init__.py +52 -0
- braindecode/augmentation/base.py +225 -0
- braindecode/augmentation/functional.py +1300 -0
- braindecode/augmentation/transforms.py +1356 -0
- braindecode/classifier.py +258 -0
- braindecode/datasets/__init__.py +44 -0
- braindecode/datasets/base.py +823 -0
- braindecode/datasets/bbci.py +693 -0
- braindecode/datasets/bcicomp.py +193 -0
- braindecode/datasets/bids/__init__.py +54 -0
- braindecode/datasets/bids/datasets.py +239 -0
- braindecode/datasets/bids/format.py +717 -0
- braindecode/datasets/bids/hub.py +987 -0
- braindecode/datasets/bids/hub_format.py +717 -0
- braindecode/datasets/bids/hub_io.py +197 -0
- braindecode/datasets/bids/hub_validation.py +114 -0
- braindecode/datasets/bids/iterable.py +220 -0
- braindecode/datasets/chb_mit.py +163 -0
- braindecode/datasets/mne.py +170 -0
- braindecode/datasets/moabb.py +219 -0
- braindecode/datasets/nmt.py +313 -0
- braindecode/datasets/registry.py +120 -0
- braindecode/datasets/siena.py +162 -0
- braindecode/datasets/sleep_physio_challe_18.py +411 -0
- braindecode/datasets/sleep_physionet.py +125 -0
- braindecode/datasets/tuh.py +591 -0
- braindecode/datasets/utils.py +67 -0
- braindecode/datasets/xy.py +96 -0
- braindecode/datautil/__init__.py +62 -0
- braindecode/datautil/channel_utils.py +114 -0
- braindecode/datautil/hub_formats.py +180 -0
- braindecode/datautil/serialization.py +359 -0
- braindecode/datautil/util.py +154 -0
- braindecode/eegneuralnet.py +372 -0
- braindecode/functional/__init__.py +22 -0
- braindecode/functional/functions.py +251 -0
- braindecode/functional/initialization.py +47 -0
- braindecode/models/__init__.py +117 -0
- braindecode/models/atcnet.py +830 -0
- braindecode/models/attentionbasenet.py +727 -0
- braindecode/models/attn_sleep.py +549 -0
- braindecode/models/base.py +574 -0
- braindecode/models/bendr.py +493 -0
- braindecode/models/biot.py +537 -0
- braindecode/models/brainmodule.py +845 -0
- braindecode/models/config.py +233 -0
- braindecode/models/contrawr.py +319 -0
- braindecode/models/ctnet.py +541 -0
- braindecode/models/deep4.py +376 -0
- braindecode/models/deepsleepnet.py +417 -0
- braindecode/models/eegconformer.py +475 -0
- braindecode/models/eeginception_erp.py +379 -0
- braindecode/models/eeginception_mi.py +379 -0
- braindecode/models/eegitnet.py +302 -0
- braindecode/models/eegminer.py +256 -0
- braindecode/models/eegnet.py +359 -0
- braindecode/models/eegnex.py +354 -0
- braindecode/models/eegsimpleconv.py +201 -0
- braindecode/models/eegsym.py +917 -0
- braindecode/models/eegtcnet.py +337 -0
- braindecode/models/fbcnet.py +225 -0
- braindecode/models/fblightconvnet.py +315 -0
- braindecode/models/fbmsnet.py +338 -0
- braindecode/models/hybrid.py +126 -0
- braindecode/models/ifnet.py +443 -0
- braindecode/models/labram.py +1316 -0
- braindecode/models/luna.py +891 -0
- braindecode/models/medformer.py +760 -0
- braindecode/models/msvtnet.py +377 -0
- braindecode/models/patchedtransformer.py +640 -0
- braindecode/models/reve.py +843 -0
- braindecode/models/sccnet.py +280 -0
- braindecode/models/shallow_fbcsp.py +212 -0
- braindecode/models/signal_jepa.py +1122 -0
- braindecode/models/sinc_shallow.py +339 -0
- braindecode/models/sleep_stager_blanco_2020.py +169 -0
- braindecode/models/sleep_stager_chambon_2018.py +159 -0
- braindecode/models/sparcnet.py +426 -0
- braindecode/models/sstdpn.py +869 -0
- braindecode/models/summary.csv +47 -0
- braindecode/models/syncnet.py +234 -0
- braindecode/models/tcn.py +275 -0
- braindecode/models/tidnet.py +397 -0
- braindecode/models/tsinception.py +295 -0
- braindecode/models/usleep.py +439 -0
- braindecode/models/util.py +369 -0
- braindecode/modules/__init__.py +92 -0
- braindecode/modules/activation.py +86 -0
- braindecode/modules/attention.py +883 -0
- braindecode/modules/blocks.py +160 -0
- braindecode/modules/convolution.py +330 -0
- braindecode/modules/filter.py +654 -0
- braindecode/modules/layers.py +216 -0
- braindecode/modules/linear.py +70 -0
- braindecode/modules/parametrization.py +38 -0
- braindecode/modules/stats.py +87 -0
- braindecode/modules/util.py +85 -0
- braindecode/modules/wrapper.py +90 -0
- braindecode/preprocessing/__init__.py +271 -0
- braindecode/preprocessing/eegprep_preprocess.py +1317 -0
- braindecode/preprocessing/mne_preprocess.py +240 -0
- braindecode/preprocessing/preprocess.py +579 -0
- braindecode/preprocessing/util.py +177 -0
- braindecode/preprocessing/windowers.py +1037 -0
- braindecode/regressor.py +234 -0
- braindecode/samplers/__init__.py +18 -0
- braindecode/samplers/base.py +399 -0
- braindecode/samplers/ssl.py +263 -0
- braindecode/training/__init__.py +23 -0
- braindecode/training/callbacks.py +23 -0
- braindecode/training/losses.py +105 -0
- braindecode/training/scoring.py +477 -0
- braindecode/util.py +419 -0
- braindecode/version.py +1 -0
- braindecode/visualization/__init__.py +8 -0
- braindecode/visualization/confusion_matrices.py +289 -0
- braindecode/visualization/gradients.py +62 -0
- braindecode-1.3.0.dev177069446.dist-info/METADATA +230 -0
- braindecode-1.3.0.dev177069446.dist-info/RECORD +124 -0
- braindecode-1.3.0.dev177069446.dist-info/WHEEL +5 -0
- braindecode-1.3.0.dev177069446.dist-info/licenses/LICENSE.txt +31 -0
- braindecode-1.3.0.dev177069446.dist-info/licenses/NOTICE.txt +20 -0
- braindecode-1.3.0.dev177069446.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Authors: Maciej Sliwowski <maciek.sliwowski@gmail.com>
|
|
2
|
+
# Mohammed Fattouh <mo.fattouh@gmail.com>
|
|
3
|
+
#
|
|
4
|
+
# License: BSD (3-clause)
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import glob
|
|
9
|
+
import os
|
|
10
|
+
import os.path as osp
|
|
11
|
+
from os import remove
|
|
12
|
+
from shutil import unpack_archive
|
|
13
|
+
|
|
14
|
+
import mne
|
|
15
|
+
import numpy as np
|
|
16
|
+
from mne.utils import verbose
|
|
17
|
+
from scipy.io import loadmat
|
|
18
|
+
|
|
19
|
+
from braindecode.datasets import BaseConcatDataset, RawDataset
|
|
20
|
+
|
|
21
|
+
DATASET_URL = (
|
|
22
|
+
"https://stacks.stanford.edu/file/druid:zk881ps0522/"
|
|
23
|
+
"BCI_Competion4_dataset4_data_fingerflexions.zip"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class BCICompetitionIVDataset4(BaseConcatDataset):
|
|
28
|
+
"""BCI competition IV dataset 4.
|
|
29
|
+
|
|
30
|
+
Contains ECoG recordings for three patients moving fingers during the experiment.
|
|
31
|
+
Targets correspond to the time courses of the flexion of each of five fingers.
|
|
32
|
+
See http://www.bbci.de/competition/iv/desc_4.pdf and
|
|
33
|
+
http://www.bbci.de/competition/iv/ for the dataset and competition description.
|
|
34
|
+
ECoG library containing the dataset: https://searchworks.stanford.edu/view/zk881ps0522
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
subject_ids : list(int) | int | None
|
|
39
|
+
(list of) int of subject(s) to be loaded. If None, load all available
|
|
40
|
+
subjects. Should be in range 1-3.
|
|
41
|
+
|
|
42
|
+
Notes
|
|
43
|
+
-----
|
|
44
|
+
When using this dataset please cite [1]_ .
|
|
45
|
+
|
|
46
|
+
References
|
|
47
|
+
----------
|
|
48
|
+
.. [1] Miller, Kai J. "A library of human electrocorticographic data and analyses."
|
|
49
|
+
Nature human behaviour 3, no. 11 (2019): 1225-1235.
|
|
50
|
+
https://doi.org/10.1038/s41562-019-0678-3
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
possible_subjects = [1, 2, 3]
|
|
54
|
+
|
|
55
|
+
def __init__(self, subject_ids: list[int] | int | None = None):
|
|
56
|
+
data_path = self.download()
|
|
57
|
+
if isinstance(subject_ids, int):
|
|
58
|
+
subject_ids = [subject_ids]
|
|
59
|
+
if subject_ids is None:
|
|
60
|
+
subject_ids = self.possible_subjects
|
|
61
|
+
self._validate_subjects(subject_ids)
|
|
62
|
+
files_list = [f"{data_path}/sub{i}_comp.mat" for i in subject_ids]
|
|
63
|
+
datasets = []
|
|
64
|
+
for file_path in files_list:
|
|
65
|
+
raw_train, raw_test = self._load_data_to_mne(file_path)
|
|
66
|
+
desc_train = dict(
|
|
67
|
+
subject=file_path.split("/")[-1].split("sub")[1][0],
|
|
68
|
+
file_name=file_path.split("/")[-1],
|
|
69
|
+
session="train",
|
|
70
|
+
)
|
|
71
|
+
desc_test = dict(
|
|
72
|
+
subject=file_path.split("/")[-1].split("sub")[1][0],
|
|
73
|
+
file_name=file_path.split("/")[-1],
|
|
74
|
+
session="test",
|
|
75
|
+
)
|
|
76
|
+
datasets.append(RawDataset(raw_train, description=desc_train))
|
|
77
|
+
datasets.append(RawDataset(raw_test, description=desc_test))
|
|
78
|
+
super().__init__(datasets)
|
|
79
|
+
|
|
80
|
+
@staticmethod
|
|
81
|
+
def download(path=None, force_update=False, verbose=None):
|
|
82
|
+
"""Download the dataset.
|
|
83
|
+
|
|
84
|
+
Parameters
|
|
85
|
+
----------
|
|
86
|
+
path (None | str) – Location of where to look for the data storing location.
|
|
87
|
+
If None, the environment variable or config parameter
|
|
88
|
+
MNE_DATASETS_(dataset)_PATH is used. If it doesn't exist, the “~/mne_data”
|
|
89
|
+
directory is used. If the dataset is not found under the given path, the data
|
|
90
|
+
will be automatically downloaded to the specified folder.
|
|
91
|
+
force_update (bool) – Force update of the dataset even if a local copy exists.
|
|
92
|
+
verbose (bool, str, int, or None) – If not None, override default verbose level
|
|
93
|
+
(see mne.verbose())
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
-------
|
|
97
|
+
"""
|
|
98
|
+
signature = "BCICompetitionIVDataset4"
|
|
99
|
+
folder_name = "BCI_Competion4_dataset4_data_fingerflexions"
|
|
100
|
+
# Check if the dataset already exists (unpacked). We have to do that manually
|
|
101
|
+
# because we are removing .zip file from disk to save disk space.
|
|
102
|
+
|
|
103
|
+
from moabb.datasets.download import get_dataset_path # keep soft dependency
|
|
104
|
+
|
|
105
|
+
path = get_dataset_path(signature, path)
|
|
106
|
+
key_dest = "MNE-{:s}-data".format(signature.lower())
|
|
107
|
+
# We do not use mne _url_to_local_path due to ':' in the url that causes problems on Windows
|
|
108
|
+
destination = osp.join(path, key_dest, folder_name)
|
|
109
|
+
if len(list(glob.glob(osp.join(destination, "*.mat")))) == 6:
|
|
110
|
+
return destination
|
|
111
|
+
data_path = _data_dl(
|
|
112
|
+
DATASET_URL,
|
|
113
|
+
osp.join(destination, folder_name, signature),
|
|
114
|
+
force_update=force_update,
|
|
115
|
+
)
|
|
116
|
+
unpack_archive(data_path, osp.dirname(destination))
|
|
117
|
+
# removes .zip file that the data was unpacked from
|
|
118
|
+
remove(data_path)
|
|
119
|
+
return destination
|
|
120
|
+
|
|
121
|
+
@staticmethod
|
|
122
|
+
def _prepare_targets(upsampled_targets, targets_stride):
|
|
123
|
+
original_targets = np.full_like(upsampled_targets, np.nan)
|
|
124
|
+
original_targets[::targets_stride] = upsampled_targets[::targets_stride]
|
|
125
|
+
return original_targets
|
|
126
|
+
|
|
127
|
+
def _load_data_to_mne(self, file_path):
|
|
128
|
+
data = loadmat(file_path)
|
|
129
|
+
test_labels = loadmat(file_path.replace("comp.mat", "testlabels.mat"))
|
|
130
|
+
train_data = data["train_data"]
|
|
131
|
+
test_data = data["test_data"]
|
|
132
|
+
upsampled_train_targets = data["train_dg"]
|
|
133
|
+
upsampled_test_targets = test_labels["test_dg"]
|
|
134
|
+
|
|
135
|
+
signal_sfreq = 1000
|
|
136
|
+
original_target_sfreq = 25
|
|
137
|
+
targets_stride = int(signal_sfreq / original_target_sfreq)
|
|
138
|
+
|
|
139
|
+
original_targets = self._prepare_targets(
|
|
140
|
+
upsampled_train_targets, targets_stride
|
|
141
|
+
)
|
|
142
|
+
original_test_targets = self._prepare_targets(
|
|
143
|
+
upsampled_test_targets, targets_stride
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
ch_names = [f"{i}" for i in range(train_data.shape[1])]
|
|
147
|
+
ch_names += [f"target_{i}" for i in range(original_targets.shape[1])]
|
|
148
|
+
ch_types = ["ecog" for _ in range(train_data.shape[1])]
|
|
149
|
+
ch_types += ["misc" for _ in range(original_targets.shape[1])]
|
|
150
|
+
|
|
151
|
+
info = mne.create_info(sfreq=signal_sfreq, ch_names=ch_names, ch_types=ch_types)
|
|
152
|
+
info["temp"] = dict(target_sfreq=original_target_sfreq)
|
|
153
|
+
train_data = np.concatenate([train_data, original_targets], axis=1)
|
|
154
|
+
test_data = np.concatenate([test_data, original_test_targets], axis=1)
|
|
155
|
+
|
|
156
|
+
raw_train = mne.io.RawArray(train_data.T, info=info)
|
|
157
|
+
raw_test = mne.io.RawArray(test_data.T, info=info)
|
|
158
|
+
# TODO: show how to resample targets
|
|
159
|
+
return raw_train, raw_test
|
|
160
|
+
|
|
161
|
+
def _validate_subjects(self, subject_ids):
|
|
162
|
+
if isinstance(subject_ids, (list, tuple)):
|
|
163
|
+
if not all((subject in self.possible_subjects for subject in subject_ids)):
|
|
164
|
+
raise ValueError(
|
|
165
|
+
f"Wrong subject_ids parameter. Possible values: {self.possible_subjects}. "
|
|
166
|
+
f"Provided {subject_ids}."
|
|
167
|
+
)
|
|
168
|
+
else:
|
|
169
|
+
raise ValueError(
|
|
170
|
+
"Wrong subject_ids format. Expected types: None, list, tuple, int."
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@verbose
|
|
175
|
+
def _data_dl(url, destination, force_update=False, verbose=None):
|
|
176
|
+
# Code taken from moabb due to problem with ':' occurring in path
|
|
177
|
+
# On Windows ':' is a forbidden in folder name
|
|
178
|
+
# moabb/datasets/download.py
|
|
179
|
+
|
|
180
|
+
from pooch import file_hash, retrieve # keep soft dependency
|
|
181
|
+
|
|
182
|
+
if not osp.isfile(destination) or force_update:
|
|
183
|
+
if osp.isfile(destination):
|
|
184
|
+
os.remove(destination)
|
|
185
|
+
if not osp.isdir(osp.dirname(destination)):
|
|
186
|
+
os.makedirs(osp.dirname(destination))
|
|
187
|
+
known_hash = None
|
|
188
|
+
else:
|
|
189
|
+
known_hash = file_hash(destination)
|
|
190
|
+
data_path = retrieve(
|
|
191
|
+
url, known_hash, fname=osp.basename(url), path=osp.dirname(destination)
|
|
192
|
+
)
|
|
193
|
+
return data_path
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# mypy: ignore-errors
|
|
2
|
+
"""
|
|
3
|
+
BIDS (Brain Imaging Data Structure) integration for braindecode.
|
|
4
|
+
|
|
5
|
+
This subpackage provides:
|
|
6
|
+
- BIDS dataset loading (BIDSDataset, BIDSEpochsDataset)
|
|
7
|
+
- BIDS-like format utilities for Hub integration
|
|
8
|
+
- Hugging Face Hub push/pull functionality
|
|
9
|
+
- Validation utilities for Hub operations
|
|
10
|
+
|
|
11
|
+
More information on BIDS can be found at https://bids.neuroimaging.io
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
# Authors: Bruno Aristimunha <b.aristimunha@gmail.com>
|
|
15
|
+
# Pierre Guetschel <pierre.guetschel@gmail.com>
|
|
16
|
+
# Kuntal Kokate
|
|
17
|
+
#
|
|
18
|
+
# License: BSD (3-clause)
|
|
19
|
+
|
|
20
|
+
from typing import TYPE_CHECKING
|
|
21
|
+
|
|
22
|
+
# Only import hub at init level (needed by base.py)
|
|
23
|
+
# Other imports are deferred to avoid circular imports
|
|
24
|
+
from .hub import HubDatasetMixin
|
|
25
|
+
|
|
26
|
+
# For static type checkers (mypy), provide explicit imports
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from .datasets import BIDSDataset, BIDSEpochsDataset
|
|
29
|
+
from .iterable import BIDSIterableDataset
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def __getattr__(name: str):
|
|
33
|
+
"""Lazy imports to avoid circular dependencies."""
|
|
34
|
+
if name in ("BIDSDataset", "BIDSEpochsDataset"):
|
|
35
|
+
from .datasets import BIDSDataset, BIDSEpochsDataset
|
|
36
|
+
|
|
37
|
+
return {"BIDSDataset": BIDSDataset, "BIDSEpochsDataset": BIDSEpochsDataset}[
|
|
38
|
+
name
|
|
39
|
+
]
|
|
40
|
+
elif name == "BIDSIterableDataset":
|
|
41
|
+
from .iterable import BIDSIterableDataset
|
|
42
|
+
|
|
43
|
+
return BIDSIterableDataset
|
|
44
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
__all__ = [
|
|
48
|
+
# Dataset classes
|
|
49
|
+
"BIDSDataset",
|
|
50
|
+
"BIDSEpochsDataset",
|
|
51
|
+
"BIDSIterableDataset",
|
|
52
|
+
# Hub integration
|
|
53
|
+
"HubDatasetMixin",
|
|
54
|
+
]
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# mypy: ignore-errors
|
|
2
|
+
"""Dataset for loading BIDS.
|
|
3
|
+
|
|
4
|
+
More information on BIDS (Brain Imaging Data Structure) can be found at https://bids.neuroimaging.io
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# Authors: Pierre Guetschel <pierre.guetschel@gmail.com>
|
|
8
|
+
#
|
|
9
|
+
# License: BSD (3-clause)
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from dataclasses import dataclass, field
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
import mne
|
|
18
|
+
import mne_bids
|
|
19
|
+
import numpy as np
|
|
20
|
+
import pandas as pd
|
|
21
|
+
from joblib import Parallel, delayed
|
|
22
|
+
|
|
23
|
+
from ..base import BaseConcatDataset, RawDataset, WindowsDataset
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _description_from_bids_path(bids_path: mne_bids.BIDSPath) -> dict[str, Any]:
|
|
27
|
+
description = {"path": bids_path.fpath, **bids_path.entities}
|
|
28
|
+
description.update(
|
|
29
|
+
{
|
|
30
|
+
"suffix": bids_path.suffix,
|
|
31
|
+
"extension": bids_path.extension,
|
|
32
|
+
"datatype": bids_path.datatype,
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
return description
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class BIDSDataset(BaseConcatDataset):
|
|
40
|
+
"""Dataset for loading BIDS.
|
|
41
|
+
|
|
42
|
+
This class has the same parameters as the :func:`mne_bids.find_matching_paths` function
|
|
43
|
+
as it will be used to find the files to load. The default ``extensions`` parameter was changed.
|
|
44
|
+
|
|
45
|
+
More information on BIDS (Brain Imaging Data Structure)
|
|
46
|
+
can be found at https://bids.neuroimaging.io
|
|
47
|
+
|
|
48
|
+
.. Note::
|
|
49
|
+
For loading "unofficial" BIDS datasets containing epoched data,
|
|
50
|
+
you can use :class:`BIDSEpochsDataset`.
|
|
51
|
+
|
|
52
|
+
Parameters
|
|
53
|
+
----------
|
|
54
|
+
root : pathlib.Path | str
|
|
55
|
+
The root of the BIDS path.
|
|
56
|
+
subjects : str | array-like of str | None
|
|
57
|
+
The subject ID. Corresponds to "sub".
|
|
58
|
+
sessions : str | array-like of str | None
|
|
59
|
+
The acquisition session. Corresponds to "ses".
|
|
60
|
+
tasks : str | array-like of str | None
|
|
61
|
+
The experimental task. Corresponds to "task".
|
|
62
|
+
acquisitions : str | array-like of str | None
|
|
63
|
+
The acquisition parameters. Corresponds to "acq".
|
|
64
|
+
runs : str | array-like of str | None
|
|
65
|
+
The run number. Corresponds to "run".
|
|
66
|
+
processings : str | array-like of str | None
|
|
67
|
+
The processing label. Corresponds to "proc".
|
|
68
|
+
recordings : str | array-like of str | None
|
|
69
|
+
The recording name. Corresponds to "rec".
|
|
70
|
+
spaces : str | array-like of str | None
|
|
71
|
+
The coordinate space for anatomical and sensor location
|
|
72
|
+
files (e.g., ``*_electrodes.tsv``, ``*_markers.mrk``).
|
|
73
|
+
Corresponds to "space".
|
|
74
|
+
Note that valid values for ``space`` must come from a list
|
|
75
|
+
of BIDS keywords as described in the BIDS specification.
|
|
76
|
+
splits : str | array-like of str | None
|
|
77
|
+
The split of the continuous recording file for ``.fif`` data.
|
|
78
|
+
Corresponds to "split".
|
|
79
|
+
descriptions : str | array-like of str | None
|
|
80
|
+
This corresponds to the BIDS entity ``desc``. It is used to provide
|
|
81
|
+
additional information for derivative data, e.g., preprocessed data
|
|
82
|
+
may be assigned ``description='cleaned'``.
|
|
83
|
+
suffixes : str | array-like of str | None
|
|
84
|
+
The filename suffix. This is the entity after the
|
|
85
|
+
last ``_`` before the extension. E.g., ``'channels'``.
|
|
86
|
+
The following filename suffix's are accepted:
|
|
87
|
+
'meg', 'markers', 'eeg', 'ieeg', 'T1w',
|
|
88
|
+
'participants', 'scans', 'electrodes', 'coordsystem',
|
|
89
|
+
'channels', 'events', 'headshape', 'digitizer',
|
|
90
|
+
'beh', 'physio', 'stim'
|
|
91
|
+
extensions : str | array-like of str | None
|
|
92
|
+
The extension of the filename. E.g., ``'.json'``.
|
|
93
|
+
By default, uses the ones accepted by :func:`mne_bids.read_raw_bids`.
|
|
94
|
+
datatypes : str | array-like of str | None
|
|
95
|
+
The BIDS data type, e.g., ``'anat'``, ``'func'``, ``'eeg'``, ``'meg'``,
|
|
96
|
+
``'ieeg'``.
|
|
97
|
+
check : bool
|
|
98
|
+
If ``True``, only returns paths that conform to BIDS. If ``False``
|
|
99
|
+
(default), the ``.check`` attribute of the returned
|
|
100
|
+
:class:`mne_bids.BIDSPath` object will be set to ``True`` for paths that
|
|
101
|
+
do conform to BIDS, and to ``False`` for those that don't.
|
|
102
|
+
preload : bool
|
|
103
|
+
If True, preload the data. Defaults to False.
|
|
104
|
+
n_jobs : int
|
|
105
|
+
Number of jobs to run in parallel. Defaults to 1.
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
root: Path | str
|
|
109
|
+
subjects: str | list[str] | None = None
|
|
110
|
+
sessions: str | list[str] | None = None
|
|
111
|
+
tasks: str | list[str] | None = None
|
|
112
|
+
acquisitions: str | list[str] | None = None
|
|
113
|
+
runs: str | list[str] | None = None
|
|
114
|
+
processings: str | list[str] | None = None
|
|
115
|
+
recordings: str | list[str] | None = None
|
|
116
|
+
spaces: str | list[str] | None = None
|
|
117
|
+
splits: str | list[str] | None = None
|
|
118
|
+
descriptions: str | list[str] | None = None
|
|
119
|
+
suffixes: str | list[str] | None = None
|
|
120
|
+
extensions: str | list[str] | None = field(
|
|
121
|
+
default_factory=lambda: [
|
|
122
|
+
".con",
|
|
123
|
+
".sqd",
|
|
124
|
+
".pdf",
|
|
125
|
+
".fif",
|
|
126
|
+
".ds",
|
|
127
|
+
".vhdr",
|
|
128
|
+
".set",
|
|
129
|
+
".edf",
|
|
130
|
+
".bdf",
|
|
131
|
+
".EDF",
|
|
132
|
+
".snirf",
|
|
133
|
+
".cdt",
|
|
134
|
+
".mef",
|
|
135
|
+
".nwb",
|
|
136
|
+
]
|
|
137
|
+
)
|
|
138
|
+
datatypes: str | list[str] | None = None
|
|
139
|
+
check: bool = False
|
|
140
|
+
preload: bool = False
|
|
141
|
+
n_jobs: int = 1
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def _filter_out_epochs(self):
|
|
145
|
+
return True
|
|
146
|
+
|
|
147
|
+
def __post_init__(self):
|
|
148
|
+
bids_paths = mne_bids.find_matching_paths(
|
|
149
|
+
root=self.root,
|
|
150
|
+
subjects=self.subjects,
|
|
151
|
+
sessions=self.sessions,
|
|
152
|
+
tasks=self.tasks,
|
|
153
|
+
acquisitions=self.acquisitions,
|
|
154
|
+
runs=self.runs,
|
|
155
|
+
processings=self.processings,
|
|
156
|
+
recordings=self.recordings,
|
|
157
|
+
spaces=self.spaces,
|
|
158
|
+
splits=self.splits,
|
|
159
|
+
descriptions=self.descriptions,
|
|
160
|
+
suffixes=self.suffixes,
|
|
161
|
+
extensions=self.extensions,
|
|
162
|
+
datatypes=self.datatypes,
|
|
163
|
+
check=self.check,
|
|
164
|
+
)
|
|
165
|
+
# Filter out .json files files:
|
|
166
|
+
# (argument ignore_json only available in mne-bids>=0.16)
|
|
167
|
+
bids_paths = [
|
|
168
|
+
bids_path for bids_path in bids_paths if bids_path.extension != ".json"
|
|
169
|
+
]
|
|
170
|
+
# Filter out _epo.fif files:
|
|
171
|
+
if self._filter_out_epochs:
|
|
172
|
+
bids_paths = [
|
|
173
|
+
bids_path
|
|
174
|
+
for bids_path in bids_paths
|
|
175
|
+
if not (bids_path.suffix == "epo" and bids_path.extension == ".fif")
|
|
176
|
+
]
|
|
177
|
+
|
|
178
|
+
all_base_ds = Parallel(n_jobs=self.n_jobs)(
|
|
179
|
+
delayed(self._get_dataset)(bids_path) for bids_path in bids_paths
|
|
180
|
+
)
|
|
181
|
+
super().__init__(all_base_ds)
|
|
182
|
+
|
|
183
|
+
def _get_dataset(self, bids_path: mne_bids.BIDSPath) -> RawDataset:
|
|
184
|
+
description = _description_from_bids_path(bids_path)
|
|
185
|
+
raw = mne_bids.read_raw_bids(bids_path, verbose=False)
|
|
186
|
+
if self.preload:
|
|
187
|
+
raw.load_data()
|
|
188
|
+
return RawDataset(raw, description)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class BIDSEpochsDataset(BIDSDataset):
|
|
192
|
+
"""**Experimental** dataset for loading :class:`mne.Epochs` organised in BIDS.
|
|
193
|
+
|
|
194
|
+
The files must end with ``_epo.fif``.
|
|
195
|
+
|
|
196
|
+
.. Warning::
|
|
197
|
+
Epoched data is not officially supported in BIDS.
|
|
198
|
+
|
|
199
|
+
.. Note::
|
|
200
|
+
**Parameters:** This class has the same parameters as :class:`BIDSDataset` except
|
|
201
|
+
for arguments ``datatypes``, ``extensions`` and ``check`` which are fixed.
|
|
202
|
+
"""
|
|
203
|
+
|
|
204
|
+
@property
|
|
205
|
+
def _filter_out_epochs(self):
|
|
206
|
+
return False
|
|
207
|
+
|
|
208
|
+
def __init__(self, *args, **kwargs):
|
|
209
|
+
super().__init__(
|
|
210
|
+
*args,
|
|
211
|
+
extensions=".fif",
|
|
212
|
+
suffixes="epo",
|
|
213
|
+
check=False,
|
|
214
|
+
**kwargs,
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
def _set_metadata(self, epochs: mne.BaseEpochs) -> None:
|
|
218
|
+
# events = mne.events_from_annotations(epochs
|
|
219
|
+
n_times = epochs.times.shape[0]
|
|
220
|
+
# id_event = {v: k for k, v in epochs.event_id.items()}
|
|
221
|
+
annotations = epochs.annotations
|
|
222
|
+
if annotations is not None:
|
|
223
|
+
target = annotations.description
|
|
224
|
+
else:
|
|
225
|
+
id_events = {v: k for k, v in epochs.event_id.items()}
|
|
226
|
+
target = [id_events[event_id] for event_id in epochs.events[:, -1]]
|
|
227
|
+
metadata_dict = {
|
|
228
|
+
"i_window_in_trial": np.zeros(len(epochs)),
|
|
229
|
+
"i_start_in_trial": np.zeros(len(epochs)),
|
|
230
|
+
"i_stop_in_trial": np.zeros(len(epochs)) + n_times,
|
|
231
|
+
"target": target,
|
|
232
|
+
}
|
|
233
|
+
epochs.metadata = pd.DataFrame(metadata_dict)
|
|
234
|
+
|
|
235
|
+
def _get_dataset(self, bids_path):
|
|
236
|
+
description = _description_from_bids_path(bids_path)
|
|
237
|
+
epochs = mne.read_epochs(bids_path.fpath)
|
|
238
|
+
self._set_metadata(epochs)
|
|
239
|
+
return WindowsDataset(epochs, description=description, targets_from="metadata")
|