eegdash 0.3.6.dev183416654__tar.gz → 0.3.7.dev104__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.
Potentially problematic release.
This version of eegdash might be problematic. Click here for more details.
- {eegdash-0.3.6.dev183416654/eegdash.egg-info → eegdash-0.3.7.dev104}/PKG-INFO +1 -1
- eegdash-0.3.7.dev104/eegdash/__init__.py +11 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/api.py +28 -3
- eegdash-0.3.6.dev183416654/eegdash/dataset.py → eegdash-0.3.7.dev104/eegdash/const.py +0 -95
- eegdash-0.3.7.dev104/eegdash/dataset.py +118 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104/eegdash.egg-info}/PKG-INFO +1 -1
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash.egg-info/SOURCES.txt +1 -2
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/tests/test_correctness.py +1 -1
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/tests/test_dataset.py +34 -1
- eegdash-0.3.6.dev183416654/eegdash/__init__.py +0 -10
- eegdash-0.3.6.dev183416654/eegdash/preprocessing.py +0 -63
- eegdash-0.3.6.dev183416654/tests/test_database.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/LICENSE +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/MANIFEST.in +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/README.md +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/docs/Makefile +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/docs/source/conf.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/docs/source/dataset_summary.rst +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/docs/source/index.rst +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/docs/source/install/install.rst +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/docs/source/install/install_pip.rst +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/docs/source/install/install_source.rst +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/docs/source/overview.rst +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/data_config.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/data_utils.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/dataset_summary.csv +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/__init__.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/datasets.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/decorators.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/extractors.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/feature_bank/__init__.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/feature_bank/complexity.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/feature_bank/connectivity.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/feature_bank/csp.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/feature_bank/dimensionality.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/feature_bank/signal.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/feature_bank/spectral.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/feature_bank/utils.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/inspect.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/serialization.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/utils.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/mongodb.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/registry.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/utils.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash.egg-info/dependency_links.txt +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash.egg-info/requires.txt +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash.egg-info/top_level.txt +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/pyproject.toml +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/setup.cfg +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/tests/test_api.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/tests/test_challenge_kwargs.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/tests/test_dataset_registration.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/tests/test_eegdash.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/tests/test_functional.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/tests/test_init.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/tests/test_minirelease.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/tests/test_mongo_connection.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/tests/test_offline.py +0 -0
- {eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/tests/test_query.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: eegdash
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.7.dev104
|
|
4
4
|
Summary: EEG data for machine learning
|
|
5
5
|
Author-email: Young Truong <dt.young112@gmail.com>, Arnaud Delorme <adelorme@gmail.com>, Aviv Dotan <avivd220@gmail.com>, Oren Shriki <oren70@gmail.com>, Bruno Aristimunha <b.aristimunha@gmail.com>
|
|
6
6
|
License-Expression: GPL-3.0-only
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from .api import EEGDash, EEGDashDataset
|
|
2
|
+
from .dataset import EEGChallengeDataset
|
|
3
|
+
from .hbn import preprocessing # noqa: F401
|
|
4
|
+
from .utils import __init__mongo_client
|
|
5
|
+
|
|
6
|
+
__init__mongo_client()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
__all__ = ["EEGDash", "EEGDashDataset", "EEGChallengeDataset", "preprocessing"]
|
|
10
|
+
|
|
11
|
+
__version__ = "0.3.7.dev104"
|
|
@@ -17,6 +17,7 @@ from s3fs import S3FileSystem
|
|
|
17
17
|
|
|
18
18
|
from braindecode.datasets import BaseConcatDataset
|
|
19
19
|
|
|
20
|
+
from .const import RELEASE_TO_OPENNEURO_DATASET_MAP
|
|
20
21
|
from .data_config import config as data_config
|
|
21
22
|
from .data_utils import EEGBIDSDataset, EEGDashBaseDataset
|
|
22
23
|
from .mongodb import MongoConnectionManager
|
|
@@ -710,6 +711,7 @@ class EEGDashDataset(BaseConcatDataset):
|
|
|
710
711
|
eeg_dash_instance=None,
|
|
711
712
|
records: list[dict] | None = None,
|
|
712
713
|
offline_mode: bool = False,
|
|
714
|
+
n_jobs: int = -1,
|
|
713
715
|
**kwargs,
|
|
714
716
|
):
|
|
715
717
|
"""Create a new EEGDashDataset from a given query or local BIDS dataset directory
|
|
@@ -758,6 +760,8 @@ class EEGDashDataset(BaseConcatDataset):
|
|
|
758
760
|
offline_mode : bool
|
|
759
761
|
If True, do not attempt to query MongoDB at all. This is useful if you want to
|
|
760
762
|
work with a local cache only, or if you are offline.
|
|
763
|
+
n_jobs : int
|
|
764
|
+
The number of jobs to run in parallel (default is -1, meaning using all processors).
|
|
761
765
|
kwargs : dict
|
|
762
766
|
Additional keyword arguments to be passed to the EEGDashBaseDataset
|
|
763
767
|
constructor.
|
|
@@ -780,7 +784,22 @@ class EEGDashDataset(BaseConcatDataset):
|
|
|
780
784
|
raise ValueError("You must provide a 'dataset' argument")
|
|
781
785
|
|
|
782
786
|
self.data_dir = self.cache_dir / self.query["dataset"]
|
|
783
|
-
|
|
787
|
+
if self.query["dataset"] in RELEASE_TO_OPENNEURO_DATASET_MAP.values():
|
|
788
|
+
warn(
|
|
789
|
+
"If you are not participating in the competition, you can ignore this warning!"
|
|
790
|
+
"\n\n"
|
|
791
|
+
"EEG 2025 Competition Data Notice:\n"
|
|
792
|
+
"---------------------------------\n"
|
|
793
|
+
" You are loading the dataset that is used in the EEG 2025 Competition:\n"
|
|
794
|
+
"IMPORTANT: The data accessed via `EEGDashDataset` is NOT identical to what you get from `EEGChallengeDataset` object directly.\n"
|
|
795
|
+
"and it is not what you will use for the competition. Downsampling and filtering were applied to the data"
|
|
796
|
+
"to allow more people to participate.\n"
|
|
797
|
+
"\n"
|
|
798
|
+
"If you are participating in the competition, always use `EEGChallengeDataset` to ensure consistency with the challenge data.\n"
|
|
799
|
+
"\n",
|
|
800
|
+
UserWarning,
|
|
801
|
+
module="eegdash",
|
|
802
|
+
)
|
|
784
803
|
_owns_client = False
|
|
785
804
|
if self.eeg_dash is None and records is None:
|
|
786
805
|
self.eeg_dash = EEGDash()
|
|
@@ -801,11 +820,12 @@ class EEGDashDataset(BaseConcatDataset):
|
|
|
801
820
|
elif offline_mode: # only assume local data is complete if in offline mode
|
|
802
821
|
if self.data_dir.exists():
|
|
803
822
|
# This path loads from a local directory and is not affected by DB query logic
|
|
804
|
-
datasets = self.
|
|
823
|
+
datasets = self.load_bids_daxtaset(
|
|
805
824
|
dataset=self.query["dataset"],
|
|
806
825
|
data_dir=self.data_dir,
|
|
807
826
|
description_fields=description_fields,
|
|
808
827
|
s3_bucket=s3_bucket,
|
|
828
|
+
n_jobs=n_jobs,
|
|
809
829
|
**base_dataset_kwargs,
|
|
810
830
|
)
|
|
811
831
|
else:
|
|
@@ -898,6 +918,7 @@ class EEGDashDataset(BaseConcatDataset):
|
|
|
898
918
|
data_dir: str | Path,
|
|
899
919
|
description_fields: list[str],
|
|
900
920
|
s3_bucket: str | None = None,
|
|
921
|
+
n_jobs: int = -1,
|
|
901
922
|
**kwargs,
|
|
902
923
|
):
|
|
903
924
|
"""Helper method to load a single local BIDS dataset and return it as a list of
|
|
@@ -912,13 +933,17 @@ class EEGDashDataset(BaseConcatDataset):
|
|
|
912
933
|
description_fields : list[str]
|
|
913
934
|
A list of fields to be extracted from the dataset records
|
|
914
935
|
and included in the returned dataset description(s).
|
|
936
|
+
s3_bucket : str | None
|
|
937
|
+
The S3 bucket to upload the dataset files to (if any).
|
|
938
|
+
n_jobs : int
|
|
939
|
+
The number of jobs to run in parallel (default is -1, meaning using all processors).
|
|
915
940
|
|
|
916
941
|
"""
|
|
917
942
|
bids_dataset = EEGBIDSDataset(
|
|
918
943
|
data_dir=data_dir,
|
|
919
944
|
dataset=dataset,
|
|
920
945
|
)
|
|
921
|
-
datasets = Parallel(n_jobs
|
|
946
|
+
datasets = Parallel(n_jobs=n_jobs, prefer="threads", verbose=1)(
|
|
922
947
|
delayed(self.get_base_dataset_from_bids_file)(
|
|
923
948
|
bids_dataset=bids_dataset,
|
|
924
949
|
bids_file=bids_file,
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
from .api import EEGDashDataset
|
|
4
|
-
from .registry import register_openneuro_datasets
|
|
5
|
-
|
|
6
1
|
RELEASE_TO_OPENNEURO_DATASET_MAP = {
|
|
7
2
|
"R11": "ds005516",
|
|
8
3
|
"R10": "ds005515",
|
|
@@ -261,93 +256,3 @@ SUBJECT_MINI_RELEASE_MAP = {
|
|
|
261
256
|
"NDARFW972KFQ",
|
|
262
257
|
],
|
|
263
258
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
class EEGChallengeDataset(EEGDashDataset):
|
|
267
|
-
def __init__(
|
|
268
|
-
self,
|
|
269
|
-
release: str,
|
|
270
|
-
cache_dir: str,
|
|
271
|
-
mini: bool = True,
|
|
272
|
-
query: dict | None = None,
|
|
273
|
-
s3_bucket: str | None = "s3://nmdatasets/NeurIPS25",
|
|
274
|
-
**kwargs,
|
|
275
|
-
):
|
|
276
|
-
"""Create a new EEGDashDataset from a given query or local BIDS dataset directory
|
|
277
|
-
and dataset name. An EEGDashDataset is pooled collection of EEGDashBaseDataset
|
|
278
|
-
instances (individual recordings) and is a subclass of braindecode's BaseConcatDataset.
|
|
279
|
-
|
|
280
|
-
Parameters
|
|
281
|
-
----------
|
|
282
|
-
release: str
|
|
283
|
-
Release name. Can be one of ["R1", ..., "R11"]
|
|
284
|
-
mini: bool, default True
|
|
285
|
-
Whether to use the mini-release version of the dataset. It is recommended
|
|
286
|
-
to use the mini version for faster training and evaluation.
|
|
287
|
-
query : dict | None
|
|
288
|
-
Optionally a dictionary that specifies a query to be executed,
|
|
289
|
-
in addition to the dataset (automatically inferred from the release argument).
|
|
290
|
-
See EEGDash.find() for details on the query format.
|
|
291
|
-
cache_dir : str
|
|
292
|
-
A directory where the dataset will be cached locally.
|
|
293
|
-
s3_bucket : str | None
|
|
294
|
-
An optional S3 bucket URI to use instead of the
|
|
295
|
-
default OpenNeuro bucket for loading data files.
|
|
296
|
-
kwargs : dict
|
|
297
|
-
Additional keyword arguments to be passed to the EEGDashDataset
|
|
298
|
-
constructor.
|
|
299
|
-
|
|
300
|
-
"""
|
|
301
|
-
self.release = release
|
|
302
|
-
self.mini = mini
|
|
303
|
-
|
|
304
|
-
if release not in RELEASE_TO_OPENNEURO_DATASET_MAP:
|
|
305
|
-
raise ValueError(
|
|
306
|
-
f"Unknown release: {release}, expected one of {list(RELEASE_TO_OPENNEURO_DATASET_MAP.keys())}"
|
|
307
|
-
)
|
|
308
|
-
|
|
309
|
-
dataset_parameters = []
|
|
310
|
-
if isinstance(release, str):
|
|
311
|
-
dataset_parameters.append(RELEASE_TO_OPENNEURO_DATASET_MAP[release])
|
|
312
|
-
else:
|
|
313
|
-
raise ValueError(
|
|
314
|
-
f"Unknown release type: {type(release)}, the expected type is str."
|
|
315
|
-
)
|
|
316
|
-
|
|
317
|
-
if query and "dataset" in query:
|
|
318
|
-
raise ValueError(
|
|
319
|
-
"Query using the parameters `dataset` with the class EEGChallengeDataset is not possible."
|
|
320
|
-
"Please use the release argument instead, or the object EEGDashDataset instead."
|
|
321
|
-
)
|
|
322
|
-
|
|
323
|
-
if self.mini:
|
|
324
|
-
# Disallow mixing subject selection with mini=True since mini already
|
|
325
|
-
# applies a predefined subject subset.
|
|
326
|
-
if (query and "subject" in query) or ("subject" in kwargs):
|
|
327
|
-
raise ValueError(
|
|
328
|
-
"Query using the parameters `subject` with the class EEGChallengeDataset and `mini==True` is not possible."
|
|
329
|
-
"Please don't use the `subject` selection twice."
|
|
330
|
-
"Set `mini=False` to use the `subject` selection."
|
|
331
|
-
)
|
|
332
|
-
kwargs["subject"] = SUBJECT_MINI_RELEASE_MAP[release]
|
|
333
|
-
s3_bucket = f"{s3_bucket}/{release}_mini_L100_bdf"
|
|
334
|
-
else:
|
|
335
|
-
s3_bucket = f"{s3_bucket}/{release}_L100_bdf"
|
|
336
|
-
|
|
337
|
-
super().__init__(
|
|
338
|
-
dataset=RELEASE_TO_OPENNEURO_DATASET_MAP[release],
|
|
339
|
-
query=query,
|
|
340
|
-
cache_dir=cache_dir,
|
|
341
|
-
s3_bucket=s3_bucket,
|
|
342
|
-
**kwargs,
|
|
343
|
-
)
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
registered_classes = register_openneuro_datasets(
|
|
347
|
-
summary_file=Path(__file__).with_name("dataset_summary.csv"),
|
|
348
|
-
base_class=EEGDashDataset,
|
|
349
|
-
namespace=globals(),
|
|
350
|
-
)
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
__all__ = ["EEGChallengeDataset"] + list(registered_classes.keys())
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from mne.utils import warn
|
|
5
|
+
|
|
6
|
+
from .api import EEGDashDataset
|
|
7
|
+
from .const import RELEASE_TO_OPENNEURO_DATASET_MAP, SUBJECT_MINI_RELEASE_MAP
|
|
8
|
+
from .registry import register_openneuro_datasets
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger("eegdash")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class EEGChallengeDataset(EEGDashDataset):
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
release: str,
|
|
17
|
+
cache_dir: str,
|
|
18
|
+
mini: bool = True,
|
|
19
|
+
query: dict | None = None,
|
|
20
|
+
s3_bucket: str | None = "s3://nmdatasets/NeurIPS25",
|
|
21
|
+
**kwargs,
|
|
22
|
+
):
|
|
23
|
+
"""Create a new EEGDashDataset from a given query or local BIDS dataset directory
|
|
24
|
+
and dataset name. An EEGDashDataset is pooled collection of EEGDashBaseDataset
|
|
25
|
+
instances (individual recordings) and is a subclass of braindecode's BaseConcatDataset.
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
release: str
|
|
30
|
+
Release name. Can be one of ["R1", ..., "R11"]
|
|
31
|
+
mini: bool, default True
|
|
32
|
+
Whether to use the mini-release version of the dataset. It is recommended
|
|
33
|
+
to use the mini version for faster training and evaluation.
|
|
34
|
+
query : dict | None
|
|
35
|
+
Optionally a dictionary that specifies a query to be executed,
|
|
36
|
+
in addition to the dataset (automatically inferred from the release argument).
|
|
37
|
+
See EEGDash.find() for details on the query format.
|
|
38
|
+
cache_dir : str
|
|
39
|
+
A directory where the dataset will be cached locally.
|
|
40
|
+
s3_bucket : str | None
|
|
41
|
+
An optional S3 bucket URI to use instead of the
|
|
42
|
+
default OpenNeuro bucket for loading data files.
|
|
43
|
+
kwargs : dict
|
|
44
|
+
Additional keyword arguments to be passed to the EEGDashDataset
|
|
45
|
+
constructor.
|
|
46
|
+
|
|
47
|
+
"""
|
|
48
|
+
self.release = release
|
|
49
|
+
self.mini = mini
|
|
50
|
+
|
|
51
|
+
if release not in RELEASE_TO_OPENNEURO_DATASET_MAP:
|
|
52
|
+
raise ValueError(
|
|
53
|
+
f"Unknown release: {release}, expected one of {list(RELEASE_TO_OPENNEURO_DATASET_MAP.keys())}"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
dataset_parameters = []
|
|
57
|
+
if isinstance(release, str):
|
|
58
|
+
dataset_parameters.append(RELEASE_TO_OPENNEURO_DATASET_MAP[release])
|
|
59
|
+
else:
|
|
60
|
+
raise ValueError(
|
|
61
|
+
f"Unknown release type: {type(release)}, the expected type is str."
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
if query and "dataset" in query:
|
|
65
|
+
raise ValueError(
|
|
66
|
+
"Query using the parameters `dataset` with the class EEGChallengeDataset is not possible."
|
|
67
|
+
"Please use the release argument instead, or the object EEGDashDataset instead."
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
if self.mini:
|
|
71
|
+
# Disallow mixing subject selection with mini=True since mini already
|
|
72
|
+
# applies a predefined subject subset.
|
|
73
|
+
if (query and "subject" in query) or ("subject" in kwargs):
|
|
74
|
+
raise ValueError(
|
|
75
|
+
"Query using the parameters `subject` with the class EEGChallengeDataset and `mini==True` is not possible."
|
|
76
|
+
"Please don't use the `subject` selection twice."
|
|
77
|
+
"Set `mini=False` to use the `subject` selection."
|
|
78
|
+
)
|
|
79
|
+
kwargs["subject"] = SUBJECT_MINI_RELEASE_MAP[release]
|
|
80
|
+
s3_bucket = f"{s3_bucket}/{release}_mini_L100_bdf"
|
|
81
|
+
else:
|
|
82
|
+
s3_bucket = f"{s3_bucket}/{release}_L100_bdf"
|
|
83
|
+
|
|
84
|
+
warn(
|
|
85
|
+
"\n\n"
|
|
86
|
+
"[EEGChallengeDataset] EEG 2025 Competition Data Notice:\n"
|
|
87
|
+
"-------------------------------------------------------\n"
|
|
88
|
+
"This object loads the HBN dataset that has been preprocessed for the EEG Challenge:\n"
|
|
89
|
+
" - Downsampled from 500Hz to 100Hz\n"
|
|
90
|
+
" - Bandpass filtered (0.5–50 Hz)\n"
|
|
91
|
+
"\n"
|
|
92
|
+
"For full preprocessing details, see:\n"
|
|
93
|
+
" https://github.com/eeg2025/downsample-datasets\n"
|
|
94
|
+
"\n"
|
|
95
|
+
"IMPORTANT: The data accessed via `EEGChallengeDataset` is NOT identical to what you get from `EEGDashDataset` directly.\n"
|
|
96
|
+
"If you are participating in the competition, always use `EEGChallengeDataset` to ensure consistency with the challenge data.\n"
|
|
97
|
+
"\n",
|
|
98
|
+
UserWarning,
|
|
99
|
+
module="eegdash",
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
super().__init__(
|
|
103
|
+
dataset=RELEASE_TO_OPENNEURO_DATASET_MAP[release],
|
|
104
|
+
query=query,
|
|
105
|
+
cache_dir=cache_dir,
|
|
106
|
+
s3_bucket=s3_bucket,
|
|
107
|
+
**kwargs,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
registered_classes = register_openneuro_datasets(
|
|
112
|
+
summary_file=Path(__file__).with_name("dataset_summary.csv"),
|
|
113
|
+
base_class=EEGDashDataset,
|
|
114
|
+
namespace=globals(),
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
__all__ = ["EEGChallengeDataset"] + list(registered_classes.keys())
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: eegdash
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.7.dev104
|
|
4
4
|
Summary: EEG data for machine learning
|
|
5
5
|
Author-email: Young Truong <dt.young112@gmail.com>, Arnaud Delorme <adelorme@gmail.com>, Aviv Dotan <avivd220@gmail.com>, Oren Shriki <oren70@gmail.com>, Bruno Aristimunha <b.aristimunha@gmail.com>
|
|
6
6
|
License-Expression: GPL-3.0-only
|
|
@@ -12,12 +12,12 @@ docs/source/install/install_pip.rst
|
|
|
12
12
|
docs/source/install/install_source.rst
|
|
13
13
|
eegdash/__init__.py
|
|
14
14
|
eegdash/api.py
|
|
15
|
+
eegdash/const.py
|
|
15
16
|
eegdash/data_config.py
|
|
16
17
|
eegdash/data_utils.py
|
|
17
18
|
eegdash/dataset.py
|
|
18
19
|
eegdash/dataset_summary.csv
|
|
19
20
|
eegdash/mongodb.py
|
|
20
|
-
eegdash/preprocessing.py
|
|
21
21
|
eegdash/registry.py
|
|
22
22
|
eegdash/utils.py
|
|
23
23
|
eegdash.egg-info/PKG-INFO
|
|
@@ -43,7 +43,6 @@ eegdash/features/feature_bank/utils.py
|
|
|
43
43
|
tests/test_api.py
|
|
44
44
|
tests/test_challenge_kwargs.py
|
|
45
45
|
tests/test_correctness.py
|
|
46
|
-
tests/test_database.py
|
|
47
46
|
tests/test_dataset.py
|
|
48
47
|
tests/test_dataset_registration.py
|
|
49
48
|
tests/test_eegdash.py
|
|
@@ -22,7 +22,7 @@ from braindecode.preprocessing import (
|
|
|
22
22
|
)
|
|
23
23
|
from braindecode.util import set_random_seeds
|
|
24
24
|
from eegdash import EEGDashDataset
|
|
25
|
-
from eegdash.preprocessing import hbn_ec_ec_reannotation
|
|
25
|
+
from eegdash.hbn.preprocessing import hbn_ec_ec_reannotation
|
|
26
26
|
|
|
27
27
|
cache_folder = get_config("MNE_DATA")
|
|
28
28
|
if cache_folder is None:
|
|
@@ -3,7 +3,7 @@ from pathlib import Path
|
|
|
3
3
|
|
|
4
4
|
import pytest
|
|
5
5
|
|
|
6
|
-
from eegdash.api import EEGDash
|
|
6
|
+
from eegdash.api import EEGDash, EEGDashDataset
|
|
7
7
|
from eegdash.dataset import EEGChallengeDataset
|
|
8
8
|
|
|
9
9
|
RELEASES = ["R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11"]
|
|
@@ -117,3 +117,36 @@ def test_eeg_dash_integration(eeg_dash_instance, release="R5", mini=True):
|
|
|
117
117
|
)
|
|
118
118
|
raw = dataset_obj.datasets[0].raw
|
|
119
119
|
assert raw is not None
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def test_eeg_dash_integration_warning():
|
|
123
|
+
"""Test that EEGChallengeDataset emits the expected UserWarning on init."""
|
|
124
|
+
release = "R5"
|
|
125
|
+
mini = True
|
|
126
|
+
with pytest.warns(UserWarning) as record:
|
|
127
|
+
_ = EEGChallengeDataset(
|
|
128
|
+
release=release,
|
|
129
|
+
task="RestingState",
|
|
130
|
+
cache_dir=CACHE_DIR,
|
|
131
|
+
mini=mini,
|
|
132
|
+
)
|
|
133
|
+
# There may be multiple warnings, check that at least one matches expected text
|
|
134
|
+
found = any("EEG 2025 Competition Data Notice" in str(w.message) for w in record)
|
|
135
|
+
assert found, (
|
|
136
|
+
"Expected competition warning not found in warnings emitted by EEGChallengeDataset"
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def test_eeg_dashdataset():
|
|
141
|
+
"""Test that EEGDashDataset emits the expected UserWarning on init."""
|
|
142
|
+
with pytest.warns(UserWarning) as record:
|
|
143
|
+
_ = EEGDashDataset(
|
|
144
|
+
dataset="ds005505",
|
|
145
|
+
task="RestingState",
|
|
146
|
+
cache_dir=CACHE_DIR,
|
|
147
|
+
)
|
|
148
|
+
# There may be multiple warnings, check that at least one matches expected text
|
|
149
|
+
found = any("EEG 2025 Competition Data Notice" in str(w.message) for w in record)
|
|
150
|
+
assert found, (
|
|
151
|
+
"Expected competition warning not found in warnings emitted by EEGChallengeDataset"
|
|
152
|
+
)
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
from .api import EEGDash, EEGDashDataset
|
|
2
|
-
from .dataset import EEGChallengeDataset
|
|
3
|
-
from .utils import __init__mongo_client
|
|
4
|
-
|
|
5
|
-
__init__mongo_client()
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
__all__ = ["EEGDash", "EEGDashDataset", "EEGChallengeDataset"]
|
|
9
|
-
|
|
10
|
-
__version__ = "0.3.6.dev183416654"
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
|
-
import mne
|
|
4
|
-
import numpy as np
|
|
5
|
-
|
|
6
|
-
from braindecode.preprocessing import Preprocessor
|
|
7
|
-
|
|
8
|
-
logger = logging.getLogger("eegdash")
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class hbn_ec_ec_reannotation(Preprocessor):
|
|
12
|
-
"""Preprocessor to reannotate the raw data for eyes open and eyes closed events.
|
|
13
|
-
|
|
14
|
-
This processor is designed for HBN datasets.
|
|
15
|
-
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
def __init__(self):
|
|
19
|
-
super().__init__(fn=self.transform, apply_on_array=False)
|
|
20
|
-
|
|
21
|
-
def transform(self, raw):
|
|
22
|
-
"""Reannotate the raw data to create new events for eyes open and eyes closed
|
|
23
|
-
|
|
24
|
-
This function modifies the raw MNE object by creating new events based on
|
|
25
|
-
the existing annotations for "instructed_toCloseEyes" and "instructed_toOpenEyes".
|
|
26
|
-
It generates new events every 2 seconds within specified time ranges after
|
|
27
|
-
the original events, and replaces the existing annotations with these new events.
|
|
28
|
-
|
|
29
|
-
Parameters
|
|
30
|
-
----------
|
|
31
|
-
raw : mne.io.Raw
|
|
32
|
-
The raw MNE object containing EEG data and annotations.
|
|
33
|
-
|
|
34
|
-
"""
|
|
35
|
-
events, event_id = mne.events_from_annotations(raw)
|
|
36
|
-
|
|
37
|
-
logger.info("Original events found with ids: %s", event_id)
|
|
38
|
-
|
|
39
|
-
# Create new events array for 2-second segments
|
|
40
|
-
new_events = []
|
|
41
|
-
sfreq = raw.info["sfreq"]
|
|
42
|
-
for event in events[events[:, 2] == event_id["instructed_toCloseEyes"]]:
|
|
43
|
-
# For each original event, create events every 2 seconds from 15s to 29s after
|
|
44
|
-
start_times = event[0] + np.arange(15, 29, 2) * sfreq
|
|
45
|
-
new_events.extend([[int(t), 0, 1] for t in start_times])
|
|
46
|
-
|
|
47
|
-
for event in events[events[:, 2] == event_id["instructed_toOpenEyes"]]:
|
|
48
|
-
# For each original event, create events every 2 seconds from 5s to 19s after
|
|
49
|
-
start_times = event[0] + np.arange(5, 19, 2) * sfreq
|
|
50
|
-
new_events.extend([[int(t), 0, 2] for t in start_times])
|
|
51
|
-
|
|
52
|
-
# replace events in raw
|
|
53
|
-
new_events = np.array(new_events)
|
|
54
|
-
|
|
55
|
-
annot_from_events = mne.annotations_from_events(
|
|
56
|
-
events=new_events,
|
|
57
|
-
event_desc={1: "eyes_closed", 2: "eyes_open"},
|
|
58
|
-
sfreq=raw.info["sfreq"],
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
raw.set_annotations(annot_from_events)
|
|
62
|
-
|
|
63
|
-
return raw
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/feature_bank/__init__.py
RENAMED
|
File without changes
|
{eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/feature_bank/complexity.py
RENAMED
|
File without changes
|
{eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/feature_bank/connectivity.py
RENAMED
|
File without changes
|
|
File without changes
|
{eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/feature_bank/dimensionality.py
RENAMED
|
File without changes
|
|
File without changes
|
{eegdash-0.3.6.dev183416654 → eegdash-0.3.7.dev104}/eegdash/features/feature_bank/spectral.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|