eegdash 0.3.6__tar.gz → 0.3.6.dev97__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 (119) hide show
  1. {eegdash-0.3.6/eegdash.egg-info → eegdash-0.3.6.dev97}/PKG-INFO +2 -1
  2. eegdash-0.3.6.dev97/docs/source/dataset_summary.rst +201 -0
  3. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/__init__.py +1 -1
  4. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/registry.py +13 -3
  5. {eegdash-0.3.6 → eegdash-0.3.6.dev97/eegdash.egg-info}/PKG-INFO +2 -1
  6. eegdash-0.3.6.dev97/eegdash.egg-info/SOURCES.txt +54 -0
  7. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash.egg-info/requires.txt +1 -0
  8. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/pyproject.toml +1 -0
  9. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/tests/test_dataset_registration.py +3 -3
  10. eegdash-0.3.6/docs/build/html/_downloads/22c048359758b424393a09689a41275e/challenge_1.ipynb +0 -140
  11. eegdash-0.3.6/docs/build/html/_downloads/2c592649a2079630923cb072bc1beaf3/tutorial_eoec.ipynb +0 -176
  12. eegdash-0.3.6/docs/build/html/_downloads/7af8e218488251a3d4f109ff980adb18/plot_challenge_1.ipynb +0 -154
  13. eegdash-0.3.6/docs/build/html/_downloads/893ab57ca8de4ec74e7c17907d3e8a27/challenge_2.ipynb +0 -151
  14. eegdash-0.3.6/docs/build/html/_downloads/98d7bd44ce227c21b44549b2fa2df263/sex_classification.ipynb +0 -245
  15. eegdash-0.3.6/docs/build/html/_downloads/befd83bab11618bf4f65555df6b7d484/challenge_2_machine_learning.ipynb +0 -224
  16. eegdash-0.3.6/docs/build/html/_downloads/ddd2e23bdceb54b00ad13077b36e6b4a/plot_challenge_2.ipynb +0 -151
  17. eegdash-0.3.6/docs/build/html/_downloads/ea36209601ea25b5b442358dcfa59a7a/plot_challenge_2_machine_learning.ipynb +0 -224
  18. eegdash-0.3.6/docs/build/html/_downloads/f3cf56a30a7c06a2eccae3b5b3d28e35/tutorial_feature_extractor_open_close_eye.ipynb +0 -260
  19. eegdash-0.3.6/docs/build/html/notebooks/generated/auto_examples/core/tutorial_eoec.ipynb +0 -176
  20. eegdash-0.3.6/docs/build/html/notebooks/generated/auto_examples/core/tutorial_feature_extractor_open_close_eye.ipynb +0 -260
  21. eegdash-0.3.6/docs/build/html/notebooks/generated/auto_examples/eeg2025/plot_challenge_1.ipynb +0 -154
  22. eegdash-0.3.6/docs/build/html/notebooks/generated/auto_examples/eeg2025/plot_challenge_2.ipynb +0 -151
  23. eegdash-0.3.6/docs/build/html/notebooks/generated/auto_examples/eeg2025/plot_challenge_2_machine_learning.ipynb +0 -224
  24. eegdash-0.3.6/docs/source/api/eegdash.api.rst +0 -7
  25. eegdash-0.3.6/docs/source/api/eegdash.data_config.rst +0 -7
  26. eegdash-0.3.6/docs/source/api/eegdash.data_utils.rst +0 -7
  27. eegdash-0.3.6/docs/source/api/eegdash.dataset.rst +0 -7
  28. eegdash-0.3.6/docs/source/api/eegdash.features.datasets.rst +0 -7
  29. eegdash-0.3.6/docs/source/api/eegdash.features.decorators.rst +0 -7
  30. eegdash-0.3.6/docs/source/api/eegdash.features.extractors.rst +0 -7
  31. eegdash-0.3.6/docs/source/api/eegdash.features.feature_bank.complexity.rst +0 -7
  32. eegdash-0.3.6/docs/source/api/eegdash.features.feature_bank.connectivity.rst +0 -7
  33. eegdash-0.3.6/docs/source/api/eegdash.features.feature_bank.csp.rst +0 -7
  34. eegdash-0.3.6/docs/source/api/eegdash.features.feature_bank.dimensionality.rst +0 -7
  35. eegdash-0.3.6/docs/source/api/eegdash.features.feature_bank.rst +0 -21
  36. eegdash-0.3.6/docs/source/api/eegdash.features.feature_bank.signal.rst +0 -7
  37. eegdash-0.3.6/docs/source/api/eegdash.features.feature_bank.spectral.rst +0 -7
  38. eegdash-0.3.6/docs/source/api/eegdash.features.feature_bank.utils.rst +0 -7
  39. eegdash-0.3.6/docs/source/api/eegdash.features.inspect.rst +0 -7
  40. eegdash-0.3.6/docs/source/api/eegdash.features.rst +0 -28
  41. eegdash-0.3.6/docs/source/api/eegdash.features.serialization.rst +0 -7
  42. eegdash-0.3.6/docs/source/api/eegdash.features.utils.rst +0 -7
  43. eegdash-0.3.6/docs/source/api/eegdash.mongodb.rst +0 -7
  44. eegdash-0.3.6/docs/source/api/eegdash.preprocessing.rst +0 -7
  45. eegdash-0.3.6/docs/source/api/eegdash.rst +0 -29
  46. eegdash-0.3.6/docs/source/api/eegdash.utils.rst +0 -7
  47. eegdash-0.3.6/docs/source/api/modules.rst +0 -7
  48. eegdash-0.3.6/docs/source/dataset_summary.rst +0 -85
  49. eegdash-0.3.6/docs/source/generated/auto_examples/core/sex_classification.ipynb +0 -245
  50. eegdash-0.3.6/docs/source/generated/auto_examples/core/sex_classification.rst +0 -464
  51. eegdash-0.3.6/docs/source/generated/auto_examples/core/sg_execution_times.rst +0 -40
  52. eegdash-0.3.6/docs/source/generated/auto_examples/core/tutorial_eoec.ipynb +0 -176
  53. eegdash-0.3.6/docs/source/generated/auto_examples/core/tutorial_eoec.rst +0 -388
  54. eegdash-0.3.6/docs/source/generated/auto_examples/core/tutorial_feature_extractor_open_close_eye.ipynb +0 -260
  55. eegdash-0.3.6/docs/source/generated/auto_examples/core/tutorial_feature_extractor_open_close_eye.rst +0 -510
  56. eegdash-0.3.6/docs/source/generated/auto_examples/eeg2025/challenge_1.ipynb +0 -140
  57. eegdash-0.3.6/docs/source/generated/auto_examples/eeg2025/challenge_1.rst +0 -381
  58. eegdash-0.3.6/docs/source/generated/auto_examples/eeg2025/challenge_2.ipynb +0 -151
  59. eegdash-0.3.6/docs/source/generated/auto_examples/eeg2025/challenge_2.rst +0 -311
  60. eegdash-0.3.6/docs/source/generated/auto_examples/eeg2025/challenge_2_machine_learning.ipynb +0 -224
  61. eegdash-0.3.6/docs/source/generated/auto_examples/eeg2025/challenge_2_machine_learning.rst +0 -390
  62. eegdash-0.3.6/docs/source/generated/auto_examples/eeg2025/plot_challenge_1.ipynb +0 -154
  63. eegdash-0.3.6/docs/source/generated/auto_examples/eeg2025/plot_challenge_1.rst +0 -326
  64. eegdash-0.3.6/docs/source/generated/auto_examples/eeg2025/plot_challenge_2.ipynb +0 -151
  65. eegdash-0.3.6/docs/source/generated/auto_examples/eeg2025/plot_challenge_2.rst +0 -318
  66. eegdash-0.3.6/docs/source/generated/auto_examples/eeg2025/plot_challenge_2_machine_learning.ipynb +0 -224
  67. eegdash-0.3.6/docs/source/generated/auto_examples/eeg2025/plot_challenge_2_machine_learning.rst +0 -392
  68. eegdash-0.3.6/docs/source/generated/auto_examples/eeg2025/sg_execution_times.rst +0 -43
  69. eegdash-0.3.6/docs/source/generated/auto_examples/index.rst +0 -195
  70. eegdash-0.3.6/docs/source/generated/auto_examples/sg_execution_times.rst +0 -37
  71. eegdash-0.3.6/docs/source/sg_execution_times.rst +0 -49
  72. eegdash-0.3.6/eegdash.egg-info/SOURCES.txt +0 -115
  73. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/LICENSE +0 -0
  74. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/MANIFEST.in +0 -0
  75. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/README.md +0 -0
  76. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/docs/Makefile +0 -0
  77. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/docs/source/conf.py +0 -0
  78. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/docs/source/index.rst +0 -0
  79. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/docs/source/install/install.rst +0 -0
  80. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/docs/source/install/install_pip.rst +0 -0
  81. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/docs/source/install/install_source.rst +0 -0
  82. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/docs/source/overview.rst +0 -0
  83. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/api.py +0 -0
  84. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/data_config.py +0 -0
  85. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/data_utils.py +0 -0
  86. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/dataset.py +0 -0
  87. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/dataset_summary.csv +0 -0
  88. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/__init__.py +0 -0
  89. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/datasets.py +0 -0
  90. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/decorators.py +0 -0
  91. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/extractors.py +0 -0
  92. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/feature_bank/__init__.py +0 -0
  93. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/feature_bank/complexity.py +0 -0
  94. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/feature_bank/connectivity.py +0 -0
  95. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/feature_bank/csp.py +0 -0
  96. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/feature_bank/dimensionality.py +0 -0
  97. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/feature_bank/signal.py +0 -0
  98. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/feature_bank/spectral.py +0 -0
  99. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/feature_bank/utils.py +0 -0
  100. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/inspect.py +0 -0
  101. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/serialization.py +0 -0
  102. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/features/utils.py +0 -0
  103. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/mongodb.py +0 -0
  104. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/preprocessing.py +0 -0
  105. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash/utils.py +0 -0
  106. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash.egg-info/dependency_links.txt +0 -0
  107. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/eegdash.egg-info/top_level.txt +0 -0
  108. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/setup.cfg +0 -0
  109. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/tests/test_api.py +0 -0
  110. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/tests/test_challenge_kwargs.py +0 -0
  111. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/tests/test_correctness.py +0 -0
  112. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/tests/test_dataset.py +0 -0
  113. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/tests/test_eegdash.py +0 -0
  114. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/tests/test_functional.py +0 -0
  115. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/tests/test_init.py +0 -0
  116. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/tests/test_minirelease.py +0 -0
  117. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/tests/test_mongo_connection.py +0 -0
  118. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/tests/test_offline.py +0 -0
  119. {eegdash-0.3.6 → eegdash-0.3.6.dev97}/tests/test_query.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eegdash
3
- Version: 0.3.6
3
+ Version: 0.3.6.dev97
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
@@ -59,6 +59,7 @@ Requires-Dist: numpydoc; extra == "docs"
59
59
  Requires-Dist: memory_profiler; extra == "docs"
60
60
  Requires-Dist: ipython; extra == "docs"
61
61
  Requires-Dist: lightgbm; extra == "docs"
62
+ Requires-Dist: plotly; extra == "docs"
62
63
  Provides-Extra: all
63
64
  Requires-Dist: eegdash[docs]; extra == "all"
64
65
  Requires-Dist: eegdash[dev]; extra == "all"
@@ -0,0 +1,201 @@
1
+ .. meta::
2
+ :hide_sidebar: true
3
+
4
+ :html_theme.sidebar_secondary.remove:
5
+ :html_theme.sidebar_primary.remove:
6
+
7
+ .. _data_summary:
8
+
9
+ EEGDash
10
+ ========
11
+
12
+ 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.
13
+
14
+ The archive is currently still in :bdg-danger:`beta testing` mode, so be kind.
15
+
16
+ .. raw:: html
17
+
18
+ <figure class="eegdash-figure" style="margin: 0 0 1.25rem 0;">
19
+
20
+ .. raw:: html
21
+ :file: ../build/dataset_bubble.html
22
+
23
+ .. raw:: html
24
+
25
+ <figcaption class="eegdash-caption">
26
+ Figure: Dataset landscape. Each bubble represents a dataset: x-axis shows the number of records,
27
+ y-axis the number of subjects, bubble area encodes on-disk size, and color indicates sampling frequency band.
28
+ Hover for details and use the legend to highlight groups.
29
+ </figcaption>
30
+ </figure>
31
+
32
+
33
+ .. raw:: html
34
+
35
+ <figure class="eegdash-figure" style="margin: 1.0rem 0 0 0;">
36
+
37
+
38
+ MEEG Datasets Table
39
+ ===================
40
+
41
+ The data in EEG-DaSh originates from a collaboration involving 25 laboratories, encompassing 27,053 participants. This extensive collection includes MEEG data, which is a combination of EEG and MEG signals. The data is sourced from various studies conducted by these labs,
42
+ involving both healthy subjects and clinical populations with conditions such as ADHD, depression, schizophrenia, dementia, autism, and psychosis. Additionally, data spans different mental states like sleep, meditation, and cognitive tasks.
43
+
44
+ In addition, EEG-DaSh will incorporate a subset of the data converted from `NEMAR <https://nemar.org/>`__, which includes 330 MEEG BIDS-formatted datasets, further expanding the archive with well-curated, standardized neuroelectromagnetic data.
45
+
46
+ .. raw:: html
47
+ :file: ../build/dataset_summary_table.html
48
+
49
+ .. raw:: html
50
+
51
+ <figcaption class="eegdash-caption">
52
+ Table: Sortable catalogue of EEG‑DaSh datasets. Use the “Filters” button to open column filters;
53
+ click a column header to jump directly to a filter pane. The Total row is pinned at the bottom.
54
+ * means that we use the median value across multiple recordings in the dataset, and empty cells
55
+ when the metainformation is not extracted yet.
56
+ </figcaption>
57
+ </figure>
58
+
59
+ .. raw:: html
60
+
61
+ <!-- jQuery + DataTables core -->
62
+ <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
63
+ <link rel="stylesheet" href="https://cdn.datatables.net/v/bm/dt-1.13.4/datatables.min.css"/>
64
+ <script src="https://cdn.datatables.net/v/bm/dt-1.13.4/datatables.min.js"></script>
65
+
66
+ <!-- Buttons + SearchPanes (+ Select required by SearchPanes) -->
67
+ <link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.4.2/css/buttons.dataTables.min.css">
68
+ <script src="https://cdn.datatables.net/buttons/2.4.2/js/dataTables.buttons.min.js"></script>
69
+ <link rel="stylesheet" href="https://cdn.datatables.net/select/1.7.0/css/select.dataTables.min.css">
70
+ <link rel="stylesheet" href="https://cdn.datatables.net/searchpanes/2.3.1/css/searchPanes.dataTables.min.css">
71
+ <script src="https://cdn.datatables.net/select/1.7.0/js/dataTables.select.min.js"></script>
72
+ <script src="https://cdn.datatables.net/searchpanes/2.3.1/js/dataTables.searchPanes.min.js"></script>
73
+
74
+ <style>
75
+ /* Styling for the Total row (placed in tfoot) */
76
+ table.sd-table tfoot td {
77
+ font-weight: 600;
78
+ border-top: 2px solid rgba(0,0,0,0.2);
79
+ background: #f9fafb;
80
+ /* Match body cell padding to keep perfect alignment */
81
+ padding: 8px 10px !important;
82
+ vertical-align: middle;
83
+ }
84
+
85
+ /* Right-align numeric-like columns (2..8) consistently for body & footer */
86
+ table.sd-table tbody td:nth-child(n+2),
87
+ table.sd-table tfoot td:nth-child(n+2) {
88
+ text-align: right;
89
+ }
90
+ /* Keep first column (Dataset/Total) left-aligned */
91
+ table.sd-table tbody td:first-child,
92
+ table.sd-table tfoot td:first-child {
93
+ text-align: left;
94
+ }
95
+ </style>
96
+
97
+ <script>
98
+ // Helper: robustly extract values for SearchPanes when needed
99
+ function tagsArrayFromHtml(html) {
100
+ if (html == null) return [];
101
+ // If it's numeric or plain text, just return as a single value
102
+ if (typeof html === 'number') return [String(html)];
103
+ if (typeof html === 'string' && html.indexOf('<') === -1) return [html.trim()];
104
+ // Else parse any .tag elements inside HTML
105
+ var tmp = document.createElement('div');
106
+ tmp.innerHTML = html;
107
+ var tags = Array.from(tmp.querySelectorAll('.tag')).map(function(el){
108
+ return (el.textContent || '').trim();
109
+ });
110
+ return tags.length ? tags : [tmp.textContent.trim()];
111
+ }
112
+
113
+ // Helper: parse human-readable sizes like "4.31 GB" into bytes (number)
114
+ function parseSizeToBytes(text) {
115
+ if (!text) return 0;
116
+ var s = String(text).trim();
117
+ var m = s.match(/([\d,.]+)\s*(TB|GB|MB|KB|B)/i);
118
+ if (!m) return 0;
119
+ var value = parseFloat(m[1].replace(/,/g, ''));
120
+ var unit = m[2].toUpperCase();
121
+ var factor = { B:1, KB:1024, MB:1024**2, GB:1024**3, TB:1024**4 }[unit] || 1;
122
+ return value * factor;
123
+ }
124
+
125
+ $(function () {
126
+ // 1) Move the "Total" row into <tfoot> so sorting/filtering never moves it
127
+ $('.sortable').each(function(){
128
+ var $t = $(this);
129
+ var $tbody = $t.find('tbody');
130
+ var $total = $tbody.find('tr').filter(function(){
131
+ return $(this).find('td').eq(0).text().trim() === 'Total';
132
+ });
133
+ if ($total.length) {
134
+ var $tfoot = $t.find('tfoot');
135
+ if (!$tfoot.length) $tfoot = $('<tfoot/>').appendTo($t);
136
+ $total.appendTo($tfoot);
137
+ }
138
+ });
139
+
140
+ // 2) Initialize DataTable with SearchPanes button
141
+ var FILTER_COLS = [1,2,3,4,5,6];
142
+ // Detect the index of the size column by header text
143
+ var sizeIdx = (function(){
144
+ var idx = -1;
145
+ $('.sortable thead th').each(function(i){
146
+ var t = $(this).text().trim().toLowerCase();
147
+ if (t === 'size on disk' || t === 'size') idx = i;
148
+ });
149
+ return idx;
150
+ })();
151
+
152
+ var table = $('.sortable').DataTable({
153
+ dom: 'Blfrtip',
154
+ paging: false,
155
+ searching: true,
156
+ info: false,
157
+ language: {
158
+ search: 'Filter dataset:',
159
+ searchPanes: { collapse: { 0: 'Filters', _: 'Filters (%d)' } }
160
+ },
161
+ buttons: [{
162
+ extend: 'searchPanes',
163
+ text: 'Filters',
164
+ config: { cascadePanes: true, viewTotal: true, layout: 'columns-4', initCollapsed: false }
165
+ }],
166
+ columnDefs: (function(){
167
+ var defs = [
168
+ { searchPanes: { show: true }, targets: FILTER_COLS }
169
+ ];
170
+ if (sizeIdx !== -1) {
171
+ defs.push({
172
+ targets: sizeIdx,
173
+ render: function(data, type) {
174
+ if (type === 'sort' || type === 'type') {
175
+ return parseSizeToBytes(data);
176
+ }
177
+ return data;
178
+ }
179
+ });
180
+ }
181
+ return defs;
182
+ })()
183
+ });
184
+
185
+ // 3) UX: click a header to open the relevant filter pane
186
+ $('.sortable thead th').each(function (i) {
187
+ if ([1,2,3,4].indexOf(i) === -1) return;
188
+ $(this).css('cursor','pointer').attr('title','Click to filter this column');
189
+ $(this).on('click', function () {
190
+ table.button('.buttons-searchPanes').trigger();
191
+ setTimeout(function () {
192
+ var idx = [1,2,3,4].indexOf(i);
193
+ var $container = $(table.searchPanes.container());
194
+ var $pane = $container.find('.dtsp-pane').eq(idx);
195
+ var $title = $pane.find('.dtsp-title');
196
+ if ($title.length) $title.trigger('click');
197
+ }, 0);
198
+ });
199
+ });
200
+ });
201
+ </script>
@@ -7,4 +7,4 @@ __init__mongo_client()
7
7
 
8
8
  __all__ = ["EEGDash", "EEGDashDataset", "EEGChallengeDataset"]
9
9
 
10
- __version__ = "0.3.6"
10
+ __version__ = "0.3.6.dev97"
@@ -57,7 +57,7 @@ def register_openneuro_datasets(
57
57
 
58
58
  init = make_init(dataset_id)
59
59
 
60
- doc = f"""Create an instance for OpenNeuro dataset ``{dataset_id}``.
60
+ doc = f"""OpenNeuro dataset ``{dataset_id}``.
61
61
 
62
62
  {markdown_table(row_series)}
63
63
 
@@ -69,11 +69,15 @@ def register_openneuro_datasets(
69
69
  Extra Mongo query merged with ``{{'dataset': '{dataset_id}'}}``.
70
70
  s3_bucket : str | None
71
71
  Optional S3 bucket name.
72
+ subject : str | None
73
+ Optional subject identifier.
74
+ task : str | None
75
+ Optional task identifier.
72
76
  **kwargs
73
77
  Passed through to {base_class.__name__}.
74
78
  """
75
79
 
76
- init.__doc__ = doc
80
+ # init.__doc__ = doc
77
81
 
78
82
  cls = type(
79
83
  class_name,
@@ -101,6 +105,7 @@ def markdown_table(row_series: pd.Series) -> str:
101
105
  """Create a reStructuredText grid table from a pandas Series."""
102
106
  if row_series.empty:
103
107
  return ""
108
+ dataset_id = row_series["dataset"]
104
109
 
105
110
  # Prepare the dataframe with user's suggested logic
106
111
  df = (
@@ -112,6 +117,7 @@ def markdown_table(row_series: pd.Series) -> str:
112
117
  "n_tasks": "#Classes",
113
118
  "sampling_freqs": "Freq(Hz)",
114
119
  "duration_hours_total": "Duration(H)",
120
+ "size": "Size",
115
121
  }
116
122
  )
117
123
  .reindex(
@@ -122,6 +128,7 @@ def markdown_table(row_series: pd.Series) -> str:
122
128
  "#Classes",
123
129
  "Freq(Hz)",
124
130
  "Duration(H)",
131
+ "Size",
125
132
  ]
126
133
  )
127
134
  .infer_objects(copy=False)
@@ -131,6 +138,9 @@ def markdown_table(row_series: pd.Series) -> str:
131
138
  # Use tabulate for the final rst formatting
132
139
  table = tabulate(df, headers="keys", tablefmt="rst", showindex=False)
133
140
 
141
+ # Add a caption for the table
142
+ caption = f"Short overview of dataset {dataset_id} more details in the `Nemar documentation <https://nemar.org/dataexplorer/detail?dataset_id={dataset_id}>`_."
143
+ # adding caption below the table
134
144
  # Indent the table to fit within the admonition block
135
145
  indented_table = "\n".join(" " + line for line in table.split("\n"))
136
- return f"\n\n{indented_table}"
146
+ return f"\n\n{indented_table}\n\n{caption}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eegdash
3
- Version: 0.3.6
3
+ Version: 0.3.6.dev97
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
@@ -59,6 +59,7 @@ Requires-Dist: numpydoc; extra == "docs"
59
59
  Requires-Dist: memory_profiler; extra == "docs"
60
60
  Requires-Dist: ipython; extra == "docs"
61
61
  Requires-Dist: lightgbm; extra == "docs"
62
+ Requires-Dist: plotly; extra == "docs"
62
63
  Provides-Extra: all
63
64
  Requires-Dist: eegdash[docs]; extra == "all"
64
65
  Requires-Dist: eegdash[dev]; extra == "all"
@@ -0,0 +1,54 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ pyproject.toml
5
+ docs/Makefile
6
+ docs/source/conf.py
7
+ docs/source/dataset_summary.rst
8
+ docs/source/index.rst
9
+ docs/source/overview.rst
10
+ docs/source/install/install.rst
11
+ docs/source/install/install_pip.rst
12
+ docs/source/install/install_source.rst
13
+ eegdash/__init__.py
14
+ eegdash/api.py
15
+ eegdash/data_config.py
16
+ eegdash/data_utils.py
17
+ eegdash/dataset.py
18
+ eegdash/dataset_summary.csv
19
+ eegdash/mongodb.py
20
+ eegdash/preprocessing.py
21
+ eegdash/registry.py
22
+ eegdash/utils.py
23
+ eegdash.egg-info/PKG-INFO
24
+ eegdash.egg-info/SOURCES.txt
25
+ eegdash.egg-info/dependency_links.txt
26
+ eegdash.egg-info/requires.txt
27
+ eegdash.egg-info/top_level.txt
28
+ eegdash/features/__init__.py
29
+ eegdash/features/datasets.py
30
+ eegdash/features/decorators.py
31
+ eegdash/features/extractors.py
32
+ eegdash/features/inspect.py
33
+ eegdash/features/serialization.py
34
+ eegdash/features/utils.py
35
+ eegdash/features/feature_bank/__init__.py
36
+ eegdash/features/feature_bank/complexity.py
37
+ eegdash/features/feature_bank/connectivity.py
38
+ eegdash/features/feature_bank/csp.py
39
+ eegdash/features/feature_bank/dimensionality.py
40
+ eegdash/features/feature_bank/signal.py
41
+ eegdash/features/feature_bank/spectral.py
42
+ eegdash/features/feature_bank/utils.py
43
+ tests/test_api.py
44
+ tests/test_challenge_kwargs.py
45
+ tests/test_correctness.py
46
+ tests/test_dataset.py
47
+ tests/test_dataset_registration.py
48
+ tests/test_eegdash.py
49
+ tests/test_functional.py
50
+ tests/test_init.py
51
+ tests/test_minirelease.py
52
+ tests/test_mongo_connection.py
53
+ tests/test_offline.py
54
+ tests/test_query.py
@@ -34,6 +34,7 @@ numpydoc
34
34
  memory_profiler
35
35
  ipython
36
36
  lightgbm
37
+ plotly
37
38
 
38
39
  [tests]
39
40
  pytest
@@ -81,6 +81,7 @@ docs = [
81
81
  "memory_profiler",
82
82
  "ipython",
83
83
  "lightgbm",
84
+ "plotly"
84
85
  ]
85
86
 
86
87
  all = [
@@ -16,9 +16,9 @@ def test_register_openneuro_datasets(tmp_path: Path):
16
16
  summary.write_text(
17
17
  "\n".join(
18
18
  [
19
- "dataset_id,num_subjects,num_sessions,num_runs,num_channels,sampling_rate,duration",
20
- "ds002718,18,18,1,74,250,14.844",
21
- "ds000001,1,1,1,1,1,1",
19
+ "dataset,num_subjects,num_sessions,num_runs,num_channels,sampling_rate,duration,size",
20
+ "ds002718,18,18,1,74,250,14.844,1.2GB",
21
+ "ds000001,1,1,1,1,1,1,100MB",
22
22
  ]
23
23
  )
24
24
  )
@@ -1,140 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": null,
6
- "metadata": {
7
- "collapsed": false
8
- },
9
- "outputs": [],
10
- "source": [
11
- "# For tips on running notebooks in Google Colab:\n# `pip install eegdash`\n%matplotlib inline"
12
- ]
13
- },
14
- {
15
- "cell_type": "markdown",
16
- "metadata": {},
17
- "source": [
18
- "\n# Challenge 1: Transfer Learning (Contrast\u2011Change Detection, CCD)\n\nThis tutorial walks you through preparing **Challenge\u00a01** data for the EEG 2025 competition.\nYou will load a CCD recording from OpenNeuro, extract trial\u2011wise behavioral metadata\n(**stimulus side, correctness, response time**), epoch around contrast\u2011change onsets,\nand produce a :class:`braindecode.datasets.WindowsDataset` ready for training.\n\n## Why this matters\nChallenge\u00a01 evaluates representations that **transfer across subjects, sessions, and sites**.\nYour pipeline should emphasize **robust, interpretable features** over brittle task\u2011specific hacks.\n\n## What you\u2019ll do\n- Load subject ``NDARAG340ERT`` from OpenNeuro ``ds005507`` (also in the R3 minsets).\n- Read the BIDS ``events.tsv`` to access **stimulus**, **button press**, and **feedback** rows.\n- Compute **response time** and **correctness** per trial.\n- Epoch around **contrast\u2011change** onsets and attach the behavioral metadata.\n- Build a :class:`braindecode.datasets.WindowsDataset` for model training/evaluation.\n\n## Prerequisites\n- Packages: :mod:`eegdash`, :mod:`braindecode`, :mod:`mne`, :mod:`numpy`, :mod:`pandas`.\n- Data: a BIDS cache managed by EEGDash (it will download on first use).\n- Hardware: any modern CPU; a GPU is optional for later modeling steps.\n\n## Notes\n- This tutorial **only** covers the CCD task for Challenge\u00a01. The **SuS** task is not covered here.\n- Large models are allowed, but the emphasis is on **features that generalize** across cohorts.\n\n## References\n- [OpenNeuro ds005507 (CCD)](https://openneuro.org/datasets/ds005507)\n- [EEGDash documentation](https://github.com/eegdash/eegdash)\n- [Braindecode documentation](https://braindecode.org/)\n"
19
- ]
20
- },
21
- {
22
- "cell_type": "code",
23
- "execution_count": null,
24
- "metadata": {
25
- "collapsed": false
26
- },
27
- "outputs": [],
28
- "source": [
29
- "import os\nfrom pathlib import Path\nimport pandas as pd\nimport numpy as np\nimport mne\nfrom eegdash import EEGDashDataset\nfrom braindecode.preprocessing import create_windows_from_events\nimport warnings\n\n# Suppress warnings for cleaner output\nwarnings.filterwarnings(\"ignore\")"
30
- ]
31
- },
32
- {
33
- "cell_type": "markdown",
34
- "metadata": {},
35
- "source": [
36
- "## 1. Loading the Data\n\nWe'll load the data for subject `NDARAG340ERT` from the `ds005507` dataset. `EEGDashDataset` will handle the download and preprocessing automatically.\n\n\n"
37
- ]
38
- },
39
- {
40
- "cell_type": "markdown",
41
- "metadata": {},
42
- "source": [
43
- "Load the dataset\n\n"
44
- ]
45
- },
46
- {
47
- "cell_type": "code",
48
- "execution_count": null,
49
- "metadata": {
50
- "collapsed": false
51
- },
52
- "outputs": [],
53
- "source": [
54
- "cache_dir = (Path.home() / \"mne_data\" / \"eeg_challenge_cache\").resolve()\n\ndataset_name = \"ds005507\"\ndataset = EEGDashDataset(\n {\n \"dataset\": dataset_name,\n \"subject\": \"NDARAG340ERT\",\n \"task\": \"contrastChangeDetection\",\n \"run\": 1,\n },\n cache_dir=cache_dir,\n)\n\n# Get the raw EEG data\nraw = dataset.datasets[0].raw\nprint(\"Dataset loaded successfully!\")\nprint(f\"Sampling frequency: {raw.info['sfreq']} Hz\")\nprint(f\"Duration: {raw.times[-1]:.1f} seconds\")\nprint(f\"Number of channels: {len(raw.ch_names)}\")\nprint(f\"Channel names: {raw.ch_names[:10]}...\") # Show first 10 channels"
55
- ]
56
- },
57
- {
58
- "cell_type": "markdown",
59
- "metadata": {},
60
- "source": [
61
- "## 2. Reading BIDS Events File with Additional Columns\n\nThe power of BIDS-formatted datasets is that they include rich metadata in standardized formats. The events.tsv file contains additional columns like `feedback` that aren't available through MNE's annotation system. Let's read the BIDS events file directly using pandas to access ALL the columns:\n\n\n"
62
- ]
63
- },
64
- {
65
- "cell_type": "markdown",
66
- "metadata": {},
67
- "source": [
68
- "The key insight: We can read the BIDS events.tsv file directly using pandas!\nThis gives us access to ALL columns including the crucial 'feedback' column\n\n"
69
- ]
70
- },
71
- {
72
- "cell_type": "code",
73
- "execution_count": null,
74
- "metadata": {
75
- "collapsed": false
76
- },
77
- "outputs": [],
78
- "source": [
79
- "# Get the events file path from the EEGDashDataset\nbids_args = dataset.datasets[0].get_raw_bids_args()\nevents_file = os.path.join(\n cache_dir,\n dataset_name,\n f\"sub-{bids_args['subject']}/eeg/sub-{bids_args['subject']}_task-{bids_args['task']}_run-{bids_args['run']}_events.tsv\",\n)\n\n# Read the events.tsv file using pandas\nevents_df = pd.read_csv(events_file, sep=\"\\t\")\n\nprint(\"BIDS Events File Structure:\")\nprint(f\"Shape: {events_df.shape}\")\nprint(f\"Columns: {list(events_df.columns)}\")\nprint(\"\\nFirst 10 rows:\")\nprint(events_df.head(10))\n\nprint(\"\\nFeedback column unique values:\")\nprint(events_df[\"feedback\"].value_counts())"
80
- ]
81
- },
82
- {
83
- "cell_type": "markdown",
84
- "metadata": {},
85
- "source": [
86
- "## 3. Calculate Response Times and Correctness from BIDS Events\n\nNow we'll calculate response times and correctness by matching stimulus events with their corresponding button presses and feedback. This approach uses the temporal sequence of events in the BIDS file.\n\n\n"
87
- ]
88
- },
89
- {
90
- "cell_type": "code",
91
- "execution_count": null,
92
- "metadata": {
93
- "collapsed": false
94
- },
95
- "outputs": [],
96
- "source": [
97
- "def calculate_behavioral_metrics_from_bids(events_df):\n \"\"\"Calculate response times and correctness from BIDS events DataFrame.\n\n This function matches stimulus events with subsequent button presses and feedback.\n \"\"\"\n # Get stimulus events\n stimuli = events_df[events_df[\"value\"].isin([\"left_target\", \"right_target\"])].copy()\n\n # Get button press events\n responses = events_df[\n events_df[\"value\"].isin([\"left_buttonPress\", \"right_buttonPress\"])\n ]\n\n # Get contrast trial start events\n contrast_trials = events_df[events_df[\"value\"] == \"contrastTrial_start\"]\n\n # Initialize columns\n stimuli[\"response_time\"] = np.nan\n stimuli[\"correct\"] = None\n stimuli[\"response_type\"] = None\n stimuli[\"contrast_trial_start\"] = None\n\n for idx, stimulus in stimuli.iterrows():\n # Find the next button press after this stimulus, but make sure it is before next 'contrastTrial_start'\n next_contrast_start = contrast_trials[\n contrast_trials[\"onset\"] > stimulus[\"onset\"]\n ].iloc[0][\"onset\"]\n future_responses = responses[\n (responses[\"onset\"] > stimulus[\"onset\"])\n & (responses[\"onset\"] < next_contrast_start)\n ]\n stimuli.loc[idx, \"contrast_trial_start\"] = contrast_trials[\n contrast_trials[\"onset\"] < stimulus[\"onset\"]\n ].iloc[-1][\"onset\"]\n if len(future_responses) > 0:\n # Get the first (closest) response\n next_response = future_responses.iloc[0]\n # Calculate response time\n response_time = next_response[\"onset\"] - stimulus[\"onset\"]\n stimuli.loc[idx, \"response_time\"] = response_time\n stimuli.loc[idx, \"response_type\"] = next_response[\"value\"]\n # We can use the feedback column directly!\n # Find feedback that corresponds to the button press\n if len(next_response[\"feedback\"]) > 0:\n feedback = next_response[\"feedback\"]\n # Map feedback to correctness\n if feedback == \"smiley_face\":\n stimuli.loc[idx, \"correct\"] = True\n elif feedback == \"sad_face\":\n stimuli.loc[idx, \"correct\"] = False\n # Note: 'non_target' feedback might indicate a different type of trial\n return stimuli\n\n\n# Calculate behavioral metrics\nstimulus_metadata = calculate_behavioral_metrics_from_bids(events_df)\nprint(\"Behavioral Analysis Results:\")\nprint(f\"Total stimulus events: {len(stimulus_metadata)}\")\nprint(f\"Events with responses: {stimulus_metadata['response_time'].notna().sum()}\")\nprint(f\"Correct responses: {stimulus_metadata['correct'].sum()}\")\nprint(\n f\"Incorrect responses: {stimulus_metadata['response_time'].notna().sum() - stimulus_metadata['correct'].sum()}\"\n)\nprint(\"Response time statistics:\")\nprint(stimulus_metadata[\"response_time\"].describe())\nprint(\"First few trials with calculated metrics:\")\nprint(\n stimulus_metadata[\n [\n \"onset\",\n \"value\",\n \"response_time\",\n \"correct\",\n \"response_type\",\n \"contrast_trial_start\",\n ]\n ].head(8)\n)"
98
- ]
99
- },
100
- {
101
- "cell_type": "markdown",
102
- "metadata": {},
103
- "source": [
104
- "## 4. Creating Epochs with Braindecode and BIDS Metadata\nNow we'll create epochs using `braindecode`'s `create_windows_from_events`. According to the EEG 2025 challenge requirements, epochs should start from **contrast trial starts** and be **2 seconds long**. This epoching approach ensures we capture:\n\n- The entire trial from contrast trial start (t=0)\n- The stimulus presentation (usually ~2.8 seconds after trial start)\n- The response window (usually within 2 seconds of stimulus)\n- Full behavioral context for each trial\n\nWe'll use our enhanced metadata that includes the behavioral information extracted from the BIDS events file.\n\n\n"
105
- ]
106
- },
107
- {
108
- "cell_type": "code",
109
- "execution_count": null,
110
- "metadata": {
111
- "collapsed": false
112
- },
113
- "outputs": [],
114
- "source": [
115
- "# Create epochs from contrast trial starts with 2-second duration as per EEG 2025 challenge\n# IMPORTANT: Only epoch trials that have valid behavioral data (stimulus + response)\n\n# First, get all contrast trial start events from the BIDS events\nall_contrast_trials = events_df[events_df[\"value\"] == \"contrastTrial_start\"].copy()\nprint(f\"Found {len(all_contrast_trials)} total contrast trial start events\")\n\n# Filter to only include contrast trials that have valid behavioral data\n# Get the contrast trial start times that correspond to trials with valid stimulus/response data\nvalid_contrast_times = stimulus_metadata[\"contrast_trial_start\"].dropna().unique()\nprint(f\"Found {len(valid_contrast_times)} contrast trials with valid behavioral data\")\n\n# Filter contrast trial events to only those with valid behavioral data\nvalid_contrast_trials = all_contrast_trials[\n all_contrast_trials[\"onset\"].isin(valid_contrast_times)\n].copy()\n\nprint(\n f\"Epoching {len(valid_contrast_trials)} contrast trials (only those with behavioral data)\"\n)\nprint(\n f\"Excluded {len(all_contrast_trials) - len(valid_contrast_trials)} trials without behavioral data\"\n)\n\n# Convert valid contrast trial start onset times to samples for MNE\nvalid_contrast_trials[\"sample_mne\"] = (\n valid_contrast_trials[\"onset\"] * raw.info[\"sfreq\"]\n).astype(int)\n\n# Create new events array with valid contrast trial starts only\n# Format: [sample, previous_sample, event_id]\nnew_events = np.column_stack(\n [\n valid_contrast_trials[\"sample_mne\"].values,\n np.zeros(len(valid_contrast_trials), dtype=int),\n np.full(\n len(valid_contrast_trials), 99, dtype=int\n ), # Use event_id 99 for contrast_trial_start\n ]\n)\n\n# Create new annotations from these events to replace the original annotations\n# This is the key step - we need to replace the annotations in the raw object\nannot_from_events = mne.annotations_from_events(\n events=new_events,\n event_desc={99: \"contrast_trial_start\"},\n sfreq=raw.info[\"sfreq\"],\n orig_time=raw.info[\"meas_date\"],\n)\n\n# Replace the annotations in the raw object\nprint(f\"Original annotations: {len(raw.annotations)} events\")\nraw.set_annotations(annot_from_events)\nprint(\n f\"New annotations: {len(raw.annotations)} contrast trial start events (valid trials only)\"\n)\n\n# Verify the new annotations\nevents_check, event_id_check = mne.events_from_annotations(raw)\nprint(f\"Events from new annotations: {len(events_check)} events\")\nprint(f\"Event ID mapping: {event_id_check}\")\n\n# Now use braindecode's create_windows_from_events to create 2-second epochs\n# Calculate the window size in samples (2 seconds * sampling rate)\nwindow_size_samples = int(2.0 * raw.info[\"sfreq\"]) # 2 seconds in samples\nprint(\n f\"Window size: {window_size_samples} samples ({window_size_samples / raw.info['sfreq']:.1f} seconds)\"\n)\n\n# Create 2-second epochs from valid contrast trial starts only\nwindows_dataset = create_windows_from_events(\n dataset, # The EEGDashDataset\n trial_start_offset_samples=0, # Start from the contrast trial start (no offset)\n trial_stop_offset_samples=window_size_samples, # End 2 seconds later\n preload=True,\n)\n\nprint(f\"Created {len(windows_dataset)} epochs with behavioral data\")\nprint(\"All epochs should now have valid stimulus and response information\")\n\n\n# ## Conclusion\n# - The epoched data is now ready under `windows_dataset`.\n# - The response time is under `stimulus_metadata['response_time']`. (required for challenge 1 regression task)\n# - The correctness is under `stimulus_metadata['correct']`. (required for challenge 1 classification task)\n# - The stimulus type (left or right) is under `stimulus_metadata['value']`. (might be useful)"
116
- ]
117
- }
118
- ],
119
- "metadata": {
120
- "kernelspec": {
121
- "display_name": "Python 3",
122
- "language": "python",
123
- "name": "python3"
124
- },
125
- "language_info": {
126
- "codemirror_mode": {
127
- "name": "ipython",
128
- "version": 3
129
- },
130
- "file_extension": ".py",
131
- "mimetype": "text/x-python",
132
- "name": "python",
133
- "nbconvert_exporter": "python",
134
- "pygments_lexer": "ipython3",
135
- "version": "3.11.0"
136
- }
137
- },
138
- "nbformat": 4,
139
- "nbformat_minor": 0
140
- }