eegdash 0.4.0.dev173498563__tar.gz → 0.4.1.dev185__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.

Files changed (94) hide show
  1. {eegdash-0.4.0.dev173498563/eegdash.egg-info → eegdash-0.4.1.dev185}/PKG-INFO +7 -8
  2. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/Makefile +2 -2
  3. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/source/_templates/autosummary/module.rst +16 -0
  4. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/source/api/api_core.rst +2 -3
  5. eegdash-0.4.1.dev185/docs/source/api/api_features.rst +24 -0
  6. eegdash-0.4.1.dev185/docs/source/api/features_overview.rst +37 -0
  7. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/source/conf.py +179 -9
  8. eegdash-0.4.1.dev185/docs/source/dataset_summary/treemap.rst +19 -0
  9. eegdash-0.4.1.dev185/docs/source/dataset_summary.rst +99 -0
  10. eegdash-0.4.1.dev185/docs/source/developer_notes.rst +129 -0
  11. eegdash-0.4.1.dev185/docs/source/index.rst +86 -0
  12. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/source/install/install_source.rst +2 -0
  13. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/source/user_guide.rst +6 -1
  14. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/__init__.py +3 -3
  15. eegdash-0.4.1.dev185/eegdash/api.py +570 -0
  16. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/bids_eeg_metadata.py +139 -39
  17. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/const.py +25 -0
  18. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/dataset/__init__.py +8 -2
  19. eegdash-0.4.1.dev185/eegdash/dataset/base.py +311 -0
  20. eegdash-0.4.1.dev185/eegdash/dataset/bids_dataset.py +443 -0
  21. eegdash-0.4.1.dev185/eegdash/dataset/dataset.py +692 -0
  22. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/dataset/dataset_summary.csv +255 -255
  23. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/dataset/registry.py +69 -4
  24. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/downloader.py +95 -9
  25. eegdash-0.4.1.dev185/eegdash/features/datasets.py +683 -0
  26. eegdash-0.4.1.dev185/eegdash/features/decorators.py +144 -0
  27. eegdash-0.4.1.dev185/eegdash/features/extractors.py +366 -0
  28. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/features/feature_bank/complexity.py +7 -3
  29. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/features/feature_bank/dimensionality.py +1 -1
  30. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/features/feature_bank/signal.py +11 -10
  31. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/features/feature_bank/utils.py +8 -0
  32. eegdash-0.4.1.dev185/eegdash/features/inspect.py +134 -0
  33. eegdash-0.4.1.dev185/eegdash/features/serialization.py +124 -0
  34. eegdash-0.4.1.dev185/eegdash/features/utils.py +190 -0
  35. eegdash-0.4.1.dev185/eegdash/hbn/preprocessing.py +105 -0
  36. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/hbn/windows.py +145 -32
  37. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/logging.py +19 -0
  38. eegdash-0.4.1.dev185/eegdash/mongodb.py +97 -0
  39. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/paths.py +15 -5
  40. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/utils.py +16 -1
  41. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185/eegdash.egg-info}/PKG-INFO +7 -8
  42. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash.egg-info/SOURCES.txt +8 -2
  43. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash.egg-info/requires.txt +7 -7
  44. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/pyproject.toml +19 -17
  45. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_api.py +1 -1
  46. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_cache_folder_suffix.py +1 -2
  47. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_challenge_kwargs.py +1 -2
  48. eegdash-0.4.1.dev185/tests/test_features.py +67 -0
  49. eegdash-0.4.1.dev185/tests/test_speed_regression.py +337 -0
  50. eegdash-0.4.0.dev173498563/docs/source/api/api_features.rst +0 -16
  51. eegdash-0.4.0.dev173498563/docs/source/dataset_summary.rst +0 -40
  52. eegdash-0.4.0.dev173498563/docs/source/index.rst +0 -63
  53. eegdash-0.4.0.dev173498563/eegdash/api.py +0 -953
  54. eegdash-0.4.0.dev173498563/eegdash/data_utils.py +0 -677
  55. eegdash-0.4.0.dev173498563/eegdash/dataset/dataset.py +0 -167
  56. eegdash-0.4.0.dev173498563/eegdash/features/datasets.py +0 -493
  57. eegdash-0.4.0.dev173498563/eegdash/features/decorators.py +0 -51
  58. eegdash-0.4.0.dev173498563/eegdash/features/extractors.py +0 -209
  59. eegdash-0.4.0.dev173498563/eegdash/features/inspect.py +0 -48
  60. eegdash-0.4.0.dev173498563/eegdash/features/serialization.py +0 -87
  61. eegdash-0.4.0.dev173498563/eegdash/features/utils.py +0 -116
  62. eegdash-0.4.0.dev173498563/eegdash/hbn/preprocessing.py +0 -72
  63. eegdash-0.4.0.dev173498563/eegdash/mongodb.py +0 -80
  64. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/LICENSE +0 -0
  65. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/MANIFEST.in +0 -0
  66. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/README.md +0 -0
  67. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/source/api/api.rst +0 -0
  68. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/source/dataset_summary/bubble.rst +0 -0
  69. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/source/dataset_summary/kde.rst +0 -0
  70. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/source/dataset_summary/sankey.rst +0 -0
  71. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/source/dataset_summary/table.rst +0 -0
  72. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/source/install/install.rst +0 -0
  73. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/source/install/install_pip.rst +0 -0
  74. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/docs/source/sg_execution_times.rst +0 -0
  75. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/features/__init__.py +0 -0
  76. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/features/feature_bank/__init__.py +0 -0
  77. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/features/feature_bank/connectivity.py +0 -0
  78. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/features/feature_bank/csp.py +0 -0
  79. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/features/feature_bank/spectral.py +0 -0
  80. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash/hbn/__init__.py +0 -0
  81. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash.egg-info/dependency_links.txt +0 -0
  82. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/eegdash.egg-info/top_level.txt +0 -0
  83. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/setup.cfg +0 -0
  84. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_bids_dependencies.py +0 -0
  85. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_correctness.py +0 -0
  86. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_dataset.py +0 -0
  87. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_dataset_registration.py +0 -0
  88. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_downloader.py +0 -0
  89. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_eegdash.py +0 -0
  90. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_init.py +0 -0
  91. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_minirelease.py +0 -0
  92. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_mongo_connection.py +0 -0
  93. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_offline.py +0 -0
  94. {eegdash-0.4.0.dev173498563 → eegdash-0.4.1.dev185}/tests/test_query.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eegdash
3
- Version: 0.4.0.dev173498563
3
+ Version: 0.4.1.dev185
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
@@ -27,23 +27,17 @@ License-File: LICENSE
27
27
  Requires-Dist: braindecode>=1.0
28
28
  Requires-Dist: mne_bids>=0.17.0
29
29
  Requires-Dist: numba
30
- Requires-Dist: numpy
31
- Requires-Dist: pandas
32
- Requires-Dist: pybids
33
30
  Requires-Dist: pymongo
34
- Requires-Dist: python-dotenv
35
31
  Requires-Dist: s3fs
36
- Requires-Dist: scipy
37
32
  Requires-Dist: tqdm
38
- Requires-Dist: h5io>=0.2.4
39
33
  Requires-Dist: pymatreader
40
34
  Requires-Dist: eeglabio
41
35
  Requires-Dist: tabulate
42
- Requires-Dist: docstring_inheritance
43
36
  Requires-Dist: rich
44
37
  Provides-Extra: tests
45
38
  Requires-Dist: pytest; extra == "tests"
46
39
  Requires-Dist: pytest-cov; extra == "tests"
40
+ Requires-Dist: pytest-sugar; extra == "tests"
47
41
  Requires-Dist: codecov; extra == "tests"
48
42
  Requires-Dist: pytest_cases; extra == "tests"
49
43
  Requires-Dist: pytest-benchmark; extra == "tests"
@@ -66,10 +60,15 @@ Requires-Dist: lightgbm; extra == "docs"
66
60
  Requires-Dist: plotly; extra == "docs"
67
61
  Requires-Dist: nbformat; extra == "docs"
68
62
  Requires-Dist: graphviz; extra == "docs"
63
+ Requires-Dist: neato; extra == "docs"
64
+ Provides-Extra: digestion
65
+ Requires-Dist: pybids; extra == "digestion"
66
+ Requires-Dist: python-dotenv; extra == "digestion"
69
67
  Provides-Extra: all
70
68
  Requires-Dist: eegdash[docs]; extra == "all"
71
69
  Requires-Dist: eegdash[dev]; extra == "all"
72
70
  Requires-Dist: eegdash[tests]; extra == "all"
71
+ Requires-Dist: eegdash[digestion]; extra == "all"
73
72
  Dynamic: license-file
74
73
 
75
74
  # EEG-Dash
@@ -12,9 +12,9 @@ help:
12
12
  .PHONY: apidoc
13
13
  apidoc:
14
14
  # Generate full API docs, then prune duplicates covered by autosummary
15
+ @rm -f "$(APIDIR)"/dataset/eegdash.features*
15
16
  @SPHINX_APIDOC_OPTIONS=members,undoc-members,show-inheritance,noindex \
16
- python -m sphinx.ext.apidoc -f -e -M -o "$(APIDIR)/dataset" "../$(PKG)"
17
- # Remove top-level package page and modules covered elsewhere
17
+ python -m sphinx.ext.apidoc -f -e -T -o "$(APIDIR)/dataset" "../$(PKG)" "../$(PKG)/features"
18
18
 
19
19
 
20
20
  # Standard build runs examples
@@ -63,3 +63,19 @@
63
63
  {% endif %}
64
64
  {%- endblock %}
65
65
 
66
+ {% if sg_api_usage %}
67
+ .. _sg_api_{{ fullname }}:
68
+
69
+ API Usage
70
+ ---------
71
+
72
+ .. raw:: html
73
+
74
+ <div class="sg-api-usage">
75
+
76
+ {{ sg_api_usage }}
77
+
78
+ .. raw:: html
79
+
80
+ </div>
81
+ {% endif %}
@@ -53,8 +53,8 @@ The API is organized into focused modules that handle specific aspects of EEG da
53
53
 
54
54
  * :mod:`~eegdash.api` - Main interface for data access and manipulation
55
55
  * :mod:`~eegdash.const` - Constants and enumerations used throughout the package
56
+ * :doc:`dataset/api_dataset` - Dataset object management and operations
56
57
  * :mod:`~eegdash.bids_eeg_metadata` - BIDS-compliant metadata handling
57
- * :mod:`~eegdash.data_utils` - Data preprocessing and transformation utilities
58
58
  * :mod:`~eegdash.mongodb` - Database connection and query operations
59
59
  * :mod:`~eegdash.paths` - File system and storage path management
60
60
  * :mod:`~eegdash.utils` - General utility functions and helpers
@@ -71,9 +71,8 @@ API Reference
71
71
  api
72
72
  bids_eeg_metadata
73
73
  const
74
- data_utils
75
74
  logging
76
75
  hbn
77
76
  mongodb
78
77
  paths
79
- utils
78
+ utils
@@ -0,0 +1,24 @@
1
+ Feature API
2
+ ===========
3
+
4
+ .. toctree::
5
+ :maxdepth: 1
6
+
7
+ Feature Package Overview <features_overview>
8
+
9
+ .. autosummary::
10
+ :toctree: generated/api-features
11
+
12
+ eegdash.features.datasets
13
+ eegdash.features.decorators
14
+ eegdash.features.extractors
15
+ eegdash.features.inspect
16
+ eegdash.features.serialization
17
+ eegdash.features.utils
18
+ eegdash.features.feature_bank.complexity
19
+ eegdash.features.feature_bank.connectivity
20
+ eegdash.features.feature_bank.csp
21
+ eegdash.features.feature_bank.dimensionality
22
+ eegdash.features.feature_bank.signal
23
+ eegdash.features.feature_bank.spectral
24
+ eegdash.features.feature_bank.utils
@@ -0,0 +1,37 @@
1
+ Feature Package Overview
2
+ ========================
3
+
4
+ .. currentmodule:: eegdash.features
5
+
6
+ The :mod:`eegdash.features` namespace re-exports feature extractors,
7
+ decorators, and dataset utilities from the underlying submodules so callers can
8
+ import the most common helpers from a single place. To avoid duplicated
9
+ documentation in the API reference, the classes themselves are documented in
10
+ their defining modules (see the links below). This page focuses on the
11
+ high-level orchestration helpers that only live in the package ``__init__``.
12
+
13
+ High-level discovery helpers
14
+ ----------------------------
15
+
16
+ .. autofunction:: get_all_features
17
+ .. autofunction:: get_feature_kind
18
+ .. autofunction:: get_feature_predecessors
19
+ .. autofunction:: get_all_feature_extractors
20
+ .. autofunction:: get_all_feature_kinds
21
+
22
+ Dataset and extraction utilities
23
+ --------------------------------
24
+
25
+ .. autofunction:: extract_features
26
+ .. autofunction:: fit_feature_extractors
27
+ .. autofunction:: load_features_concat_dataset
28
+
29
+ See also
30
+ --------
31
+
32
+ - :mod:`eegdash.features.extractors` for the feature-extraction base classes
33
+ such as :class:`~eegdash.features.extractors.FeatureExtractor`.
34
+ - :mod:`eegdash.features.datasets` for dataset wrappers like
35
+ :class:`~eegdash.features.datasets.FeaturesConcatDataset`.
36
+ - :mod:`eegdash.features.feature_bank.*` for the concrete feature families
37
+ (complexity, connectivity, spectral, and more).
@@ -2,6 +2,7 @@ import csv
2
2
  import importlib
3
3
  import inspect
4
4
  import os
5
+ import shutil
5
6
  import sys
6
7
  from collections import Counter
7
8
  from datetime import datetime, timezone
@@ -12,13 +13,15 @@ from sphinx.util import logging
12
13
  from sphinx_gallery.sorting import ExplicitOrder, FileNameSortKey
13
14
  from tabulate import tabulate
14
15
 
16
+ sys.path.insert(0, os.path.abspath(".."))
17
+
15
18
  import eegdash
16
19
 
17
20
  # -- Project information -----------------------------------------------------
18
21
 
19
22
  project = "EEG Dash"
20
23
  copyright = f"2025–{datetime.now(tz=timezone.utc).year}, {project} Developers"
21
- author = "Arnaud Delorme"
24
+ author = "Bruno Aristimunha and Arnaud Delorme"
22
25
  release = eegdash.__version__
23
26
  version = ".".join(release.split(".")[:2])
24
27
 
@@ -44,6 +47,7 @@ extensions = [
44
47
  "sphinx_sitemap",
45
48
  "sphinx_copybutton",
46
49
  "sphinx.ext.graphviz",
50
+ "sphinx_time_estimation",
47
51
  ]
48
52
 
49
53
  templates_path = ["_templates"]
@@ -61,6 +65,16 @@ suppress_warnings = [
61
65
  "config.cache",
62
66
  ]
63
67
 
68
+ autodoc_type_aliases = {
69
+ "FeatureExtractor": "eegdash.features.extractors.FeatureExtractor",
70
+ "MultivariateFeature": "eegdash.features.extractors.MultivariateFeature",
71
+ "FeaturesConcatDataset": "eegdash.features.datasets.FeaturesConcatDataset",
72
+ "FeaturesDataset": "eegdash.features.datasets.FeaturesDataset",
73
+ "TrainableFeature": "eegdash.features.extractors.TrainableFeature",
74
+ }
75
+
76
+ python_use_unqualified_type_names = False
77
+
64
78
  # -- Options for HTML output -------------------------------------------------
65
79
 
66
80
  html_theme = "pydata_sphinx_theme"
@@ -75,6 +89,7 @@ html_css_files = [
75
89
  "https://cdn.datatables.net/select/1.7.0/css/select.dataTables.min.css",
76
90
  "https://cdn.datatables.net/searchpanes/2.3.1/css/searchPanes.dataTables.min.css",
77
91
  "custom.css",
92
+ "css/treemap.css",
78
93
  ]
79
94
  html_js_files = [
80
95
  "https://code.jquery.com/jquery-3.7.1.min.js",
@@ -103,8 +118,8 @@ html_theme_options = {
103
118
  "navbar_end": ["theme-switcher", "navbar-icon-links"],
104
119
  "footer_start": ["copyright"],
105
120
  "logo": {
106
- "image_light": "_static/eegdash_long.png",
107
- "image_dark": "_static/eegdash_long.png",
121
+ "image_light": "_static/eegdash_long_white.svg",
122
+ "image_dark": "_static/eegdash_long_dark.svg",
108
123
  "alt_text": "EEG Dash Logo",
109
124
  },
110
125
  "external_links": [
@@ -218,11 +233,23 @@ EX_DIR = "../../examples" # relative to docs/source
218
233
  sphinx_gallery_conf = {
219
234
  "examples_dirs": [f"{EX_DIR}"],
220
235
  "gallery_dirs": ["generated/auto_examples"],
236
+ # Disable plotting during doc builds; matches `html-noplot` behaviour.
237
+ "plot_gallery": False,
238
+ "binder": {
239
+ "org": "sccn",
240
+ "repo": "EEGDash",
241
+ "branch": "main",
242
+ "binderhub_url": "https://mybinder.org",
243
+ "dependencies": "binder/requirements.txt",
244
+ "notebooks_dir": "notebooks",
245
+ "use_jupyter_lab": True,
246
+ },
247
+ "capture_repr": ("_repr_html_", "__repr__"),
221
248
  "nested_sections": False,
222
249
  "backreferences_dir": "gen_modules/backreferences",
223
250
  "inspect_global_variables": True,
224
251
  "show_memory": True,
225
- "show_api_usage": False,
252
+ "show_api_usage": True,
226
253
  "doc_module": ("eegdash", "numpy", "scipy", "matplotlib"),
227
254
  "reference_url": {"eegdash": None},
228
255
  "filename_pattern": r"/(?:plot|tutorial)_(?!_).*\.py",
@@ -243,8 +270,8 @@ LOGGER = logging.getLogger(__name__)
243
270
 
244
271
 
245
272
  AUTOGEN_NOTICE = """..
246
- This file is auto-generated during the Sphinx build.
247
- Do not edit by hand; changes will be overwritten.
273
+ This documentation page is generated during the Sphinx build.
274
+ The underlying code is manually maintained and not autogenerated.
248
275
 
249
276
  """
250
277
 
@@ -279,7 +306,9 @@ See Also
279
306
  """
280
307
 
281
308
 
282
- DATASET_INDEX_TEMPLATE = """{notice}Datasets API
309
+ DATASET_INDEX_TEMPLATE = """{notice}.. _api/dataset/api_dataset:
310
+
311
+ Datasets API
283
312
  =======================
284
313
 
285
314
  The :mod:`eegdash.dataset` package exposes dynamically registered dataset
@@ -299,6 +328,7 @@ Base Dataset API
299
328
  .. toctree::
300
329
  :maxdepth: 1
301
330
 
331
+ eegdash.EEGDashDataset
302
332
  eegdash.dataset.EEGChallengeDataset
303
333
 
304
334
  .. list-table:: Dataset counts by experimental type
@@ -338,6 +368,39 @@ EEGChallengeDataset
338
368
  """
339
369
 
340
370
 
371
+ PRIMARY_DATASET_TEMPLATE = """{notice}.. _api_eegdash_dataset:
372
+
373
+ .. currentmodule:: eegdash
374
+
375
+ EEGDashDataset
376
+ ==============
377
+
378
+ .. autoclass:: eegdash.EEGDashDataset
379
+ :members:
380
+ :undoc-members:
381
+ :show-inheritance:
382
+ :inherited-members:
383
+ :member-order: bysource
384
+
385
+ Usage Example
386
+ -------------
387
+
388
+ .. code-block:: python
389
+
390
+ from eegdash import EEGDashDataset
391
+
392
+ dataset = EEGDashDataset(cache_dir="./data", dataset="ds002718")
393
+ print(f"Number of recordings: {{len(dataset)}}")
394
+
395
+ See Also
396
+ --------
397
+
398
+ * :mod:`eegdash.dataset`
399
+ * :class:`eegdash.dataset.EEGChallengeDataset`
400
+
401
+ """
402
+
403
+
341
404
  def _write_if_changed(path: Path, content: str) -> bool:
342
405
  """Write ``content`` to ``path`` if it differs from the current file."""
343
406
  existing = path.read_text(encoding="utf-8") if path.exists() else None
@@ -350,7 +413,7 @@ def _write_if_changed(path: Path, content: str) -> bool:
350
413
  def _iter_dataset_classes() -> Sequence[str]:
351
414
  """Return the sorted dataset class names exported by ``eegdash.dataset``."""
352
415
  import eegdash.dataset as dataset_module # local import for clarity
353
- from eegdash.api import EEGDashDataset
416
+ from eegdash.dataset import EEGDashDataset
354
417
 
355
418
  class_names: list[str] = []
356
419
  for name in getattr(dataset_module, "__all__", []):
@@ -569,6 +632,11 @@ def _generate_dataset_docs(app) -> None:
569
632
  if _write_if_changed(base_path, base_content):
570
633
  LOGGER.info("[dataset-docs] Updated %s", base_path.relative_to(app.srcdir))
571
634
 
635
+ primary_content = PRIMARY_DATASET_TEMPLATE.format(notice=AUTOGEN_NOTICE)
636
+ primary_path = dataset_dir / "eegdash.EEGDashDataset.rst"
637
+ if _write_if_changed(primary_path, primary_content):
638
+ LOGGER.info("[dataset-docs] Updated %s", primary_path.relative_to(app.srcdir))
639
+
572
640
  generated_paths: set[Path] = set()
573
641
  for name in dataset_names:
574
642
  title = f"eegdash.dataset.{name}"
@@ -599,8 +667,108 @@ def _generate_dataset_docs(app) -> None:
599
667
  continue
600
668
 
601
669
 
670
+ def _split_tokens(value: str | None) -> set[str]:
671
+ tokens: set[str] = set()
672
+ if not value:
673
+ return tokens
674
+ for part in value.split(","):
675
+ cleaned = part.strip()
676
+ if cleaned:
677
+ tokens.add(cleaned)
678
+ return tokens
679
+
680
+
681
+ def _compute_dataset_counter_defaults() -> dict[str, int]:
682
+ csv_path = Path(importlib.import_module("eegdash.dataset").__file__).with_name(
683
+ "dataset_summary.csv"
684
+ )
685
+ if not csv_path.exists():
686
+ return {}
687
+
688
+ dataset_ids: set[str] = set()
689
+ modalities: set[str] = set()
690
+ cognitive: set[str] = set()
691
+ subject_total = 0
692
+
693
+ with csv_path.open(encoding="utf-8") as handle:
694
+ filtered = (
695
+ line
696
+ for line in handle
697
+ if line.strip() and not line.lstrip().startswith("#")
698
+ )
699
+ reader = csv.DictReader(filtered)
700
+ for row in reader:
701
+ dataset = (row.get("dataset") or row.get("Dataset") or "").strip()
702
+ if dataset:
703
+ dataset_ids.add(dataset)
704
+
705
+ try:
706
+ subject_total += int(float(row.get("n_subjects", "0") or 0))
707
+ except (TypeError, ValueError):
708
+ pass
709
+
710
+ modalities.update(_split_tokens(row.get("record_modality")))
711
+ cognitive.update(_split_tokens(row.get("type of exp")))
712
+
713
+ return {
714
+ "datasets": len(dataset_ids),
715
+ "subjects": subject_total,
716
+ "modalities": len(modalities),
717
+ "cognitive": len(cognitive),
718
+ }
719
+
720
+
721
+ _DATASET_COUNTER_DEFAULTS = _compute_dataset_counter_defaults()
722
+
723
+
724
+ def _format_counter(key: str) -> str:
725
+ value = _DATASET_COUNTER_DEFAULTS.get(key, 0)
726
+ if isinstance(value, (int, float)):
727
+ if isinstance(value, float) and not value.is_integer():
728
+ return f"{value:,.2f}"
729
+ return f"{int(value):,}"
730
+ return str(value)
731
+
732
+
733
+ _DATASET_COUNTER_PLACEHOLDERS = {
734
+ "|datasets_total|": _format_counter("datasets"),
735
+ "|subjects_total|": _format_counter("subjects"),
736
+ "|modalities_total|": _format_counter("modalities"),
737
+ "|cognitive_total|": _format_counter("cognitive"),
738
+ }
739
+
740
+
741
+ def _copy_dataset_summary(app, exception) -> None:
742
+ if exception is not None or not getattr(app, "builder", None):
743
+ return
744
+
745
+ csv_path = Path(importlib.import_module("eegdash.dataset").__file__).with_name(
746
+ "dataset_summary.csv"
747
+ )
748
+ if not csv_path.exists():
749
+ LOGGER.warning("dataset_summary.csv not found; skipping counter data copy.")
750
+ return
751
+
752
+ static_dir = Path(app.outdir) / "_static"
753
+ try:
754
+ static_dir.mkdir(parents=True, exist_ok=True)
755
+ shutil.copy2(csv_path, static_dir / "dataset_summary.csv")
756
+ except OSError as exc:
757
+ LOGGER.warning("Unable to copy dataset_summary.csv to _static: %s", exc)
758
+
759
+
760
+ def _inject_counter_values(app, docname, source) -> None:
761
+ if docname != "dataset_summary":
762
+ return
763
+
764
+ text = source[0]
765
+ for token, value in _DATASET_COUNTER_PLACEHOLDERS.items():
766
+ text = text.replace(token, value)
767
+ source[0] = text
768
+
769
+
602
770
  def setup(app):
603
- """Create the back-references directory if it doesn't exist."""
771
+ """Create the back-references directory and setup Sphinx events."""
604
772
  backreferences_dir = os.path.join(
605
773
  app.srcdir, sphinx_gallery_conf["backreferences_dir"]
606
774
  )
@@ -608,6 +776,8 @@ def setup(app):
608
776
  os.makedirs(backreferences_dir)
609
777
 
610
778
  app.connect("builder-inited", _generate_dataset_docs)
779
+ app.connect("build-finished", _copy_dataset_summary)
780
+ app.connect("source-read", _inject_counter_values)
611
781
 
612
782
 
613
783
  # Configure sitemap URL format (omit .html where possible)
@@ -0,0 +1,19 @@
1
+ .. title:: Dataset treemap
2
+
3
+ .. rubric:: Dataset treemap
4
+
5
+ .. raw:: html
6
+
7
+ <figure class="eegdash-figure" style="margin: 0 0 1.25rem 0;">
8
+
9
+ .. raw:: html
10
+ :file: ../_static/dataset_generated/dataset_treemap.html
11
+
12
+ .. raw:: html
13
+
14
+ <figcaption class="eegdash-caption">
15
+ Figure: Treemap of EEG Dash datasets. The top level groups population type,
16
+ the second level breaks down experimental modality, and leaves list individual datasets.
17
+ Tile area encodes the total number of subjects; hover to view aggregated hours (or records when unavailable).
18
+ </figcaption>
19
+ </figure>
@@ -0,0 +1,99 @@
1
+ :hide_sidebar: true
2
+ :html_theme.sidebar_secondary.remove: true
3
+ :html_theme.sidebar_primary.remove: true
4
+
5
+ .. _data_summary:
6
+
7
+ .. raw:: html
8
+
9
+ <script>document.documentElement.classList.add('dataset-summary-page');</script>
10
+
11
+ .. rst-class:: dataset-summary-article
12
+
13
+ Datasets Catalog
14
+ ================
15
+
16
+ To leverage recent and ongoing advancements in large-scale computational methods and to ensure the preservation of scientific data generated from publicly funded research, the EEG-DaSh data archive will create a data-sharing resource for MEEG (EEG, MEG) data contributed by collaborators for machine learning (ML) and deep learning (DL) applications.
17
+
18
+ .. raw:: html
19
+
20
+ <section class="dataset-counter-grid">
21
+ <article class="dataset-counter-card">
22
+ <div class="dataset-counter-icon" aria-hidden="true">
23
+ <svg class="dataset-counter-svg" viewBox="0 0 24 24" role="presentation" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
24
+ <ellipse cx="12" cy="5" rx="7" ry="3"></ellipse>
25
+ <path d="M5 5v10c0 1.66 3.13 3 7 3s7-1.34 7-3V5"></path>
26
+ <path d="M5 12c0 1.66 3.13 3 7 3s7-1.34 7-3"></path>
27
+ </svg>
28
+ </div>
29
+ <div class="dataset-counter-body">
30
+ <span class="dataset-counter-label">Datasets</span>
31
+ <span class="dataset-counter-value">|datasets_total|</span>
32
+ </div>
33
+ </article>
34
+ <article class="dataset-counter-card">
35
+ <div class="dataset-counter-icon" aria-hidden="true">
36
+ <svg class="dataset-counter-svg" viewBox="0 0 24 24" role="presentation" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
37
+ <circle cx="8" cy="9" r="3"></circle>
38
+ <circle cx="16" cy="9" r="3"></circle>
39
+ <path d="M4 19c0-3 2.24-5 4-5s4 2 4 5"></path>
40
+ <path d="M12 19c0-3 2.24-5 4-5s4 2 4 5"></path>
41
+ </svg>
42
+ </div>
43
+ <div class="dataset-counter-body">
44
+ <span class="dataset-counter-label">Subjects</span>
45
+ <span class="dataset-counter-value">|subjects_total|</span>
46
+ </div>
47
+ </article>
48
+ <article class="dataset-counter-card">
49
+ <div class="dataset-counter-icon" aria-hidden="true">
50
+ <svg class="dataset-counter-svg" viewBox="0 0 24 24" role="presentation" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
51
+ <path d="M3 15c2.5 0 2.5-6 5-6s2.5 6 5 6 2.5-6 5-6 2.5 6 5 6"></path>
52
+ <path d="M3 9c2.5 0 2.5-5 5-5s2.5 5 5 5 2.5-5 5-5 2.5 5 5 5"></path>
53
+ </svg>
54
+ </div>
55
+ <div class="dataset-counter-body">
56
+ <span class="dataset-counter-label">Experiment Modalities</span>
57
+ <span class="dataset-counter-value">|modalities_total|</span>
58
+ </div>
59
+ </article>
60
+ <article class="dataset-counter-card">
61
+ <div class="dataset-counter-icon" aria-hidden="true">
62
+ <svg class="dataset-counter-svg" viewBox="0 0 24 24" role="presentation" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
63
+ <path d="M12 4c-3.5 0-7 2-7 6 0 3.5 2.5 6 6 6v4l3-2 3 2v-4c2.5 0 4-2 4-5 0-3.5-2.5-7-9-7z"></path>
64
+ </svg>
65
+ </div>
66
+ <div class="dataset-counter-body">
67
+ <span class="dataset-counter-label">Cognitive Domains</span>
68
+ <span class="dataset-counter-value">|cognitive_total|</span>
69
+ </div>
70
+ </article>
71
+ </section>
72
+
73
+ .. raw:: html
74
+
75
+ <script src="https://cdn.plot.ly/plotly-3.1.0.min.js"></script>
76
+
77
+ .. tab-set::
78
+
79
+ .. tab-item:: Dataset Table
80
+
81
+ .. include:: dataset_summary/table.rst
82
+
83
+ .. tab-item:: Participant Distribution
84
+
85
+ .. include:: dataset_summary/kde.rst
86
+
87
+ .. tab-item:: Dataset Flow
88
+
89
+ .. include:: dataset_summary/sankey.rst
90
+
91
+ .. tab-item:: Dataset Treemap
92
+
93
+ .. include:: dataset_summary/treemap.rst
94
+
95
+ .. tab-item:: Scatter of Sample Size vs. Recording Duration
96
+
97
+ .. include:: dataset_summary/bubble.rst
98
+
99
+ The archive is currently still in :bdg-danger:`beta testing` mode, so be kind.