Braindecode 1.3.0.dev183173928__tar.gz → 1.3.0.dev183374645__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.
Files changed (157) hide show
  1. {braindecode-1.3.0.dev183173928/braindecode.egg-info → braindecode-1.3.0.dev183374645}/PKG-INFO +2 -1
  2. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/__init__.py +0 -16
  3. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/base.py +8 -2
  4. braindecode-1.3.0.dev183374645/braindecode/datasets/bids/__init__.py +54 -0
  5. braindecode-1.3.0.dev183173928/braindecode/datasets/bids.py → braindecode-1.3.0.dev183374645/braindecode/datasets/bids/datasets.py +11 -17
  6. braindecode-1.3.0.dev183173928/braindecode/datasets/bids_format.py → braindecode-1.3.0.dev183374645/braindecode/datasets/bids/format.py +118 -115
  7. {braindecode-1.3.0.dev183173928/braindecode/datasets → braindecode-1.3.0.dev183374645/braindecode/datasets/bids}/hub.py +197 -370
  8. braindecode-1.3.0.dev183374645/braindecode/datasets/bids/hub_format.py +717 -0
  9. braindecode-1.3.0.dev183374645/braindecode/datasets/bids/hub_io.py +197 -0
  10. {braindecode-1.3.0.dev183173928/braindecode/datasets → braindecode-1.3.0.dev183374645/braindecode/datasets/bids}/hub_validation.py +2 -1
  11. braindecode-1.3.0.dev183173928/braindecode/datasets/experimental.py → braindecode-1.3.0.dev183374645/braindecode/datasets/bids/iterable.py +5 -5
  12. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/nmt.py +1 -1
  13. braindecode-1.3.0.dev183374645/braindecode/version.py +1 -0
  14. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645/braindecode.egg-info}/PKG-INFO +2 -1
  15. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode.egg-info/SOURCES.txt +8 -5
  16. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode.egg-info/requires.txt +1 -0
  17. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/api.rst +19 -0
  18. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/whats_new.rst +4 -0
  19. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/pyproject.toml +1 -0
  20. braindecode-1.3.0.dev183173928/braindecode/version.py +0 -1
  21. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/LICENSE.txt +0 -0
  22. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/MANIFEST.in +0 -0
  23. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/NOTICE.txt +0 -0
  24. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/README.rst +0 -0
  25. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/__init__.py +0 -0
  26. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/augmentation/__init__.py +0 -0
  27. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/augmentation/base.py +0 -0
  28. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/augmentation/functional.py +0 -0
  29. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/augmentation/transforms.py +0 -0
  30. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/classifier.py +0 -0
  31. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/bbci.py +0 -0
  32. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/bcicomp.py +0 -0
  33. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/chb_mit.py +0 -0
  34. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/mne.py +0 -0
  35. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/moabb.py +0 -0
  36. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/registry.py +0 -0
  37. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/siena.py +0 -0
  38. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  39. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/sleep_physionet.py +0 -0
  40. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/tuh.py +0 -0
  41. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/utils.py +0 -0
  42. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datasets/xy.py +0 -0
  43. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datautil/__init__.py +0 -0
  44. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datautil/channel_utils.py +0 -0
  45. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datautil/hub_formats.py +0 -0
  46. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datautil/serialization.py +0 -0
  47. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/datautil/util.py +0 -0
  48. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/eegneuralnet.py +0 -0
  49. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/functional/__init__.py +0 -0
  50. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/functional/functions.py +0 -0
  51. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/functional/initialization.py +0 -0
  52. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/__init__.py +0 -0
  53. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/atcnet.py +0 -0
  54. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/attentionbasenet.py +0 -0
  55. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/attn_sleep.py +0 -0
  56. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/base.py +0 -0
  57. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/bendr.py +0 -0
  58. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/biot.py +0 -0
  59. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/brainmodule.py +0 -0
  60. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/config.py +0 -0
  61. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/contrawr.py +0 -0
  62. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/ctnet.py +0 -0
  63. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/deep4.py +0 -0
  64. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/deepsleepnet.py +0 -0
  65. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/eegconformer.py +0 -0
  66. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/eeginception_erp.py +0 -0
  67. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/eeginception_mi.py +0 -0
  68. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/eegitnet.py +0 -0
  69. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/eegminer.py +0 -0
  70. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/eegnet.py +0 -0
  71. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/eegnex.py +0 -0
  72. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/eegsimpleconv.py +0 -0
  73. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/eegsym.py +0 -0
  74. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/eegtcnet.py +0 -0
  75. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/fbcnet.py +0 -0
  76. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/fblightconvnet.py +0 -0
  77. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/fbmsnet.py +0 -0
  78. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/hybrid.py +0 -0
  79. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/ifnet.py +0 -0
  80. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/labram.py +0 -0
  81. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/luna.py +0 -0
  82. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/medformer.py +0 -0
  83. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/msvtnet.py +0 -0
  84. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/patchedtransformer.py +0 -0
  85. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/reve.py +0 -0
  86. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/sccnet.py +0 -0
  87. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/shallow_fbcsp.py +0 -0
  88. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/signal_jepa.py +0 -0
  89. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/sinc_shallow.py +0 -0
  90. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  91. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  92. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/sparcnet.py +0 -0
  93. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/sstdpn.py +0 -0
  94. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/summary.csv +0 -0
  95. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/syncnet.py +0 -0
  96. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/tcn.py +0 -0
  97. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/tidnet.py +0 -0
  98. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/tsinception.py +0 -0
  99. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/usleep.py +0 -0
  100. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/models/util.py +0 -0
  101. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/modules/__init__.py +0 -0
  102. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/modules/activation.py +0 -0
  103. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/modules/attention.py +0 -0
  104. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/modules/blocks.py +0 -0
  105. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/modules/convolution.py +0 -0
  106. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/modules/filter.py +0 -0
  107. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/modules/layers.py +0 -0
  108. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/modules/linear.py +0 -0
  109. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/modules/parametrization.py +0 -0
  110. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/modules/stats.py +0 -0
  111. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/modules/util.py +0 -0
  112. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/modules/wrapper.py +0 -0
  113. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/preprocessing/__init__.py +0 -0
  114. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
  115. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/preprocessing/mne_preprocess.py +0 -0
  116. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/preprocessing/preprocess.py +0 -0
  117. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/preprocessing/util.py +0 -0
  118. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/preprocessing/windowers.py +0 -0
  119. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/regressor.py +0 -0
  120. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/samplers/__init__.py +0 -0
  121. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/samplers/base.py +0 -0
  122. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/samplers/ssl.py +0 -0
  123. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/training/__init__.py +0 -0
  124. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/training/callbacks.py +0 -0
  125. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/training/losses.py +0 -0
  126. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/training/scoring.py +0 -0
  127. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/util.py +0 -0
  128. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/visualization/__init__.py +0 -0
  129. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/visualization/confusion_matrices.py +0 -0
  130. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode/visualization/gradients.py +0 -0
  131. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode.egg-info/dependency_links.txt +0 -0
  132. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/braindecode.egg-info/top_level.txt +0 -0
  133. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/Makefile +0 -0
  134. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/_templates/autosummary/class.rst +0 -0
  135. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/_templates/autosummary/function.rst +0 -0
  136. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/cite.rst +0 -0
  137. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/conf.py +0 -0
  138. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/help.rst +0 -0
  139. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/index.rst +0 -0
  140. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/install/install.rst +0 -0
  141. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/install/install_pip.rst +0 -0
  142. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/install/install_source.rst +0 -0
  143. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/models/categorization/attention.rst +0 -0
  144. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/models/categorization/channel.rst +0 -0
  145. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/models/categorization/convolution.rst +0 -0
  146. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/models/categorization/filterbank.rst +0 -0
  147. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/models/categorization/gnn.rst +0 -0
  148. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/models/categorization/interpretable.rst +0 -0
  149. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/models/categorization/lbm.rst +0 -0
  150. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/models/categorization/recurrent.rst +0 -0
  151. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/models/categorization/spd.rst +0 -0
  152. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/models/models.rst +0 -0
  153. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/models/models_categorization.rst +0 -0
  154. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/models/models_table.rst +0 -0
  155. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/models/models_visualization.rst +0 -0
  156. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/docs/sg_execution_times.rst +0 -0
  157. {braindecode-1.3.0.dev183173928 → braindecode-1.3.0.dev183374645}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.3.0.dev183173928
3
+ Version: 1.3.0.dev183374645
4
4
  Summary: Deep learning software to decode EEG, ECG or MEG signals
5
5
  Author-email: Robin Tibor Schirrmeister <robintibor@gmail.com>, Bruno Aristimunha Pinto <b.aristimunha@gmail.com>, Alexandre Gramfort <agramfort@meta.com>
6
6
  Maintainer-email: Alexandre Gramfort <agramfort@meta.com>, Bruno Aristimunha Pinto <b.aristimunha@gmail.com>, Robin Tibor Schirrmeister <robintibor@gmail.com>
@@ -48,6 +48,7 @@ Requires-Dist: codecov; extra == "tests"
48
48
  Requires-Dist: pytest_cases; extra == "tests"
49
49
  Requires-Dist: mypy; extra == "tests"
50
50
  Requires-Dist: transformers>=4.57.0; extra == "tests"
51
+ Requires-Dist: bids_validator; extra == "tests"
51
52
  Provides-Extra: typing
52
53
  Requires-Dist: exca==0.4; extra == "typing"
53
54
  Requires-Dist: numpydantic>=1.7; extra == "typing"
@@ -11,15 +11,6 @@ from .base import (
11
11
  )
12
12
  from .bcicomp import BCICompetitionIVDataset4
13
13
  from .bids import BIDSDataset, BIDSEpochsDataset
14
- from .bids_format import (
15
- BIDSDerivativesLayout,
16
- create_channels_tsv,
17
- create_eeg_json_sidecar,
18
- create_events_tsv,
19
- create_participants_tsv,
20
- description_to_bids_path,
21
- make_dataset_description,
22
- )
23
14
  from .chb_mit import CHBMIT
24
15
  from .mne import create_from_mne_epochs, create_from_mne_raw
25
16
  from .moabb import BNCI2014_001, HGD, MOABBDataset
@@ -38,13 +29,6 @@ __all__ = [
38
29
  "BaseConcatDataset",
39
30
  "BIDSDataset",
40
31
  "BIDSEpochsDataset",
41
- "BIDSDerivativesLayout",
42
- "create_events_tsv",
43
- "create_participants_tsv",
44
- "create_channels_tsv",
45
- "create_eeg_json_sidecar",
46
- "make_dataset_description",
47
- "description_to_bids_path",
48
32
  "MOABBDataset",
49
33
  "HGD",
50
34
  "BNCI2014_001",
@@ -28,7 +28,7 @@ from mne.utils.docs import deprecated
28
28
  from torch.utils.data import ConcatDataset, Dataset
29
29
  from typing_extensions import TypeVar
30
30
 
31
- from .hub import HubDatasetMixin
31
+ from .bids.hub import HubDatasetMixin
32
32
  from .registry import register_dataset
33
33
 
34
34
 
@@ -719,8 +719,14 @@ class BaseConcatDataset(ConcatDataset, HubDatasetMixin, Generic[T]):
719
719
  hasattr(self.datasets[0], "raw") or hasattr(self.datasets[0], "windows")
720
720
  ):
721
721
  raise ValueError("dataset should have either raw or windows attribute")
722
+
723
+ # Create path if it doesn't exist
724
+ os.makedirs(path, exist_ok=True)
725
+
722
726
  path_contents = os.listdir(path)
723
- n_sub_dirs = len([os.path.isdir(e) for e in path_contents])
727
+ n_sub_dirs = len(
728
+ [e for e in path_contents if os.path.isdir(os.path.join(path, e))]
729
+ )
724
730
  for i_ds, ds in enumerate(self.datasets):
725
731
  # remove subdirectory from list of untouched files / subdirectories
726
732
  if str(i_ds + offset) in path_contents:
@@ -0,0 +1,54 @@
1
+ # mypy: ignore-errors
2
+ """
3
+ BIDS (Brain Imaging Data Structure) integration for braindecode.
4
+
5
+ This subpackage provides:
6
+ - BIDS dataset loading (BIDSDataset, BIDSEpochsDataset)
7
+ - BIDS-like format utilities for Hub integration
8
+ - Hugging Face Hub push/pull functionality
9
+ - Validation utilities for Hub operations
10
+
11
+ More information on BIDS can be found at https://bids.neuroimaging.io
12
+ """
13
+
14
+ # Authors: Bruno Aristimunha <b.aristimunha@gmail.com>
15
+ # Pierre Guetschel <pierre.guetschel@gmail.com>
16
+ # Kuntal Kokate
17
+ #
18
+ # License: BSD (3-clause)
19
+
20
+ from typing import TYPE_CHECKING
21
+
22
+ # Only import hub at init level (needed by base.py)
23
+ # Other imports are deferred to avoid circular imports
24
+ from .hub import HubDatasetMixin
25
+
26
+ # For static type checkers (mypy), provide explicit imports
27
+ if TYPE_CHECKING:
28
+ from .datasets import BIDSDataset, BIDSEpochsDataset
29
+ from .iterable import BIDSIterableDataset
30
+
31
+
32
+ def __getattr__(name: str):
33
+ """Lazy imports to avoid circular dependencies."""
34
+ if name in ("BIDSDataset", "BIDSEpochsDataset"):
35
+ from .datasets import BIDSDataset, BIDSEpochsDataset
36
+
37
+ return {"BIDSDataset": BIDSDataset, "BIDSEpochsDataset": BIDSEpochsDataset}[
38
+ name
39
+ ]
40
+ elif name == "BIDSIterableDataset":
41
+ from .iterable import BIDSIterableDataset
42
+
43
+ return BIDSIterableDataset
44
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
45
+
46
+
47
+ __all__ = [
48
+ # Dataset classes
49
+ "BIDSDataset",
50
+ "BIDSEpochsDataset",
51
+ "BIDSIterableDataset",
52
+ # Hub integration
53
+ "HubDatasetMixin",
54
+ ]
@@ -1,3 +1,4 @@
1
+ # mypy: ignore-errors
1
2
  """Dataset for loading BIDS.
2
3
 
3
4
  More information on BIDS (Brain Imaging Data Structure) can be found at https://bids.neuroimaging.io
@@ -19,26 +20,19 @@ import numpy as np
19
20
  import pandas as pd
20
21
  from joblib import Parallel, delayed
21
22
 
22
- from .base import BaseConcatDataset, RawDataset, WindowsDataset
23
+ from ..base import BaseConcatDataset, RawDataset, WindowsDataset
23
24
 
24
25
 
25
26
  def _description_from_bids_path(bids_path: mne_bids.BIDSPath) -> dict[str, Any]:
26
- return {
27
- "path": bids_path.fpath,
28
- "subject": bids_path.subject,
29
- "session": bids_path.session,
30
- "task": bids_path.task,
31
- "acquisition": bids_path.acquisition,
32
- "run": bids_path.run,
33
- "processing": bids_path.processing,
34
- "recording": bids_path.recording,
35
- "space": bids_path.space,
36
- "split": bids_path.split,
37
- "description": bids_path.description,
38
- "suffix": bids_path.suffix,
39
- "extension": bids_path.extension,
40
- "datatype": bids_path.datatype,
41
- }
27
+ description = {"path": bids_path.fpath, **bids_path.entities}
28
+ description.update(
29
+ {
30
+ "suffix": bids_path.suffix,
31
+ "extension": bids_path.extension,
32
+ "datatype": bids_path.datatype,
33
+ }
34
+ )
35
+ return description
42
36
 
43
37
 
44
38
  @dataclass
@@ -1,23 +1,35 @@
1
+ # mypy: ignore-errors
1
2
  """
2
- BIDS-like format utilities for Hub integration.
3
+ BIDS-inspired format utilities for Hub integration.
3
4
 
4
- This module provides BIDS-compatible structures for storing preprocessed EEG
5
- data in the derivatives folder format while maintaining efficiency for training.
6
- It leverages mne_bids for BIDS path handling and metadata generation.
5
+ This module provides BIDS-inspired structures for storing EEG data optimized
6
+ for deep learning training. It leverages mne_bids for BIDS path handling and
7
+ metadata generation.
7
8
 
8
- The format follows BIDS derivatives conventions:
9
- - derivatives/<pipeline-name>/
10
- - dataset_description.json
11
- - participants.tsv
9
+ The data is stored in the ``sourcedata/`` directory, which according to BIDS:
10
+ - Is NOT validated by BIDS validators (so .zarr files won't cause errors)
11
+ - Has no naming restrictions ("BIDS does not prescribe a particular naming
12
+ scheme for source data")
13
+ - Is intended for data before file format conversion
14
+
15
+ This approach allows us to use efficient Zarr storage while maintaining
16
+ BIDS-style organization for discoverability.
17
+
18
+ Structure:
19
+ - sourcedata/<pipeline-name>/
20
+ - dataset_description.json (BIDS-style metadata)
21
+ - participants.tsv (BIDS-style metadata)
12
22
  - sub-<label>/
13
23
  - [ses-<label>/]
14
24
  - eeg/
15
- - sub-<label>_[ses-<label>_]task-<label>_events.tsv
16
- - sub-<label>_[ses-<label>_]task-<label>_channels.tsv
17
- - sub-<label>_[ses-<label>_]task-<label>_desc-preproc_eeg.zarr/
25
+ - *_events.tsv (BIDS-style metadata)
26
+ - *_channels.tsv (BIDS-style metadata)
27
+ - *_eeg.json (BIDS-style metadata)
28
+ - *_eeg.zarr/ (Zarr data - efficient for training)
29
+ - dataset.zarr/ (Main data store for training)
18
30
 
19
31
  References:
20
- - BIDS Derivatives: https://bids-specification.readthedocs.io/en/stable/derivatives/
32
+ - BIDS sourcedata: https://bids-specification.readthedocs.io/en/stable/common-principles.html#source-vs-raw-vs-derived-data
21
33
  - BIDS EEG: https://bids-specification.readthedocs.io/en/stable/modality-specific-files/electroencephalography.html
22
34
  """
23
35
 
@@ -30,11 +42,14 @@ from __future__ import annotations
30
42
 
31
43
  import json
32
44
  from pathlib import Path
45
+ from tempfile import TemporaryDirectory
33
46
  from typing import Any, Optional, Union
34
47
 
35
48
  import mne
36
49
  import mne_bids
50
+ import numpy as np
37
51
  import pandas as pd
52
+ from mne_bids.write import _channels_tsv, _sidecar_json
38
53
 
39
54
  import braindecode
40
55
 
@@ -42,6 +57,27 @@ import braindecode
42
57
  DEFAULT_PIPELINE_NAME = "braindecode"
43
58
 
44
59
 
60
+ def _raw_from_info(
61
+ info: "mne.Info",
62
+ bad_channels: Optional[list[str]] = None,
63
+ ) -> "mne.io.RawArray":
64
+ info = info.copy()
65
+ if bad_channels is not None:
66
+ info["bads"] = list(bad_channels)
67
+ data = np.zeros((len(info["ch_names"]), 1), dtype=float)
68
+ raw = mne.io.RawArray(data, info, verbose="error")
69
+ if not raw.filenames or raw.filenames[0] is None:
70
+ raw._filenames = [Path("dummy.fif")]
71
+ return raw
72
+
73
+
74
+ def _read_tsv(writer, *args) -> pd.DataFrame:
75
+ with TemporaryDirectory() as tmpdir, mne.utils.use_log_level("WARNING"):
76
+ tsv_path = Path(tmpdir) / "sidecar.tsv"
77
+ writer(*args, tsv_path, overwrite=True)
78
+ return pd.read_csv(tsv_path, sep="\t")
79
+
80
+
45
81
  def description_to_bids_path(
46
82
  description: pd.Series,
47
83
  root: Union[str, Path],
@@ -363,6 +399,8 @@ def create_channels_tsv(
363
399
  """
364
400
  Create a BIDS-compliant channels.tsv from MNE Info.
365
401
 
402
+ Delegates channel formatting to mne_bids.write._channels_tsv.
403
+
366
404
  Parameters
367
405
  ----------
368
406
  info : mne.Info
@@ -375,72 +413,9 @@ def create_channels_tsv(
375
413
  pd.DataFrame
376
414
  BIDS-compliant channels DataFrame.
377
415
  """
378
- import mne
379
-
380
416
  bad_channels = bad_channels or info.get("bads", [])
381
-
382
- channels_data: dict[str, list[Any]] = {
383
- "name": [],
384
- "type": [],
385
- "units": [],
386
- "sampling_frequency": [],
387
- "low_cutoff": [],
388
- "high_cutoff": [],
389
- "status": [],
390
- "status_description": [],
391
- }
392
-
393
- # MNE channel type to BIDS type mapping
394
- type_mapping = {
395
- "eeg": "EEG",
396
- "ecg": "ECG",
397
- "eog": "EOG",
398
- "emg": "EMG",
399
- "meg": "MEG",
400
- "ref_meg": "MEGREF",
401
- "grad": "MEGGRADAXIAL",
402
- "mag": "MEGMAG",
403
- "stim": "TRIG",
404
- "misc": "MISC",
405
- "bio": "BIO",
406
- }
407
-
408
- sfreq = info["sfreq"]
409
-
410
- # Get filter info if available
411
- highpass = info.get("highpass", "n/a")
412
- lowpass = info.get("lowpass", "n/a")
413
-
414
- for i, ch_name in enumerate(info["ch_names"]):
415
- # Get channel type
416
- ch_type = mne.channel_type(info, i)
417
- bids_type = type_mapping.get(ch_type.lower(), ch_type.upper())
418
-
419
- # Get units (default to µV for EEG)
420
- if bids_type == "EEG":
421
- units = "µV"
422
- elif bids_type in ("MEG", "MEGMAG", "MEGGRADAXIAL"):
423
- units = "fT"
424
- else:
425
- units = "n/a"
426
-
427
- # Check if bad channel
428
- is_bad = ch_name in bad_channels
429
- status = "bad" if is_bad else "good"
430
- status_desc = "n/a"
431
-
432
- channels_data["name"].append(ch_name)
433
- channels_data["type"].append(bids_type)
434
- channels_data["units"].append(units)
435
- channels_data["sampling_frequency"].append(sfreq)
436
- channels_data["low_cutoff"].append(highpass if highpass != 0 else "n/a")
437
- channels_data["high_cutoff"].append(
438
- lowpass if lowpass != float("inf") else "n/a"
439
- )
440
- channels_data["status"].append(status)
441
- channels_data["status_description"].append(status_desc)
442
-
443
- return pd.DataFrame(channels_data)
417
+ raw = _raw_from_info(info, bad_channels)
418
+ return _read_tsv(_channels_tsv, raw)
444
419
 
445
420
 
446
421
  def create_eeg_json_sidecar(
@@ -450,11 +425,16 @@ def create_eeg_json_sidecar(
450
425
  instructions: Optional[str] = None,
451
426
  institution_name: Optional[str] = None,
452
427
  manufacturer: Optional[str] = None,
428
+ recording_duration: Optional[float] = None,
429
+ recording_type: Optional[str] = None,
430
+ epoch_length: Optional[float] = None,
453
431
  extra_metadata: Optional[dict] = None,
454
432
  ) -> dict:
455
433
  """
456
434
  Create a BIDS-compliant EEG sidecar JSON.
457
435
 
436
+ Delegates base JSON creation to mne_bids.write._sidecar_json.
437
+
458
438
  Parameters
459
439
  ----------
460
440
  info : mne.Info
@@ -469,6 +449,14 @@ def create_eeg_json_sidecar(
469
449
  Name of the institution.
470
450
  manufacturer : str | None
471
451
  Manufacturer of the EEG equipment.
452
+ recording_duration : float | None
453
+ Length of the recording in seconds (BIDS RECOMMENDED).
454
+ recording_type : str | None
455
+ Type of recording: "continuous", "epoched", or "discontinuous"
456
+ (BIDS RECOMMENDED).
457
+ epoch_length : float | None
458
+ Duration of individual epochs in seconds. RECOMMENDED if
459
+ recording_type is "epoched".
472
460
  extra_metadata : dict | None
473
461
  Additional metadata.
474
462
 
@@ -477,26 +465,19 @@ def create_eeg_json_sidecar(
477
465
  dict
478
466
  Sidecar JSON content.
479
467
  """
480
- # Count channels by type
481
- ch_types = [info["chs"][i]["kind"] for i in range(len(info["ch_names"]))]
482
- eeg_count = sum(1 for k in ch_types if k == 2) # EEG kind
483
- eog_count = sum(1 for k in ch_types if k == 202) # EOG kind
484
- ecg_count = sum(1 for k in ch_types if k == 201) # ECG kind
485
- emg_count = sum(1 for k in ch_types if k == 302) # EMG kind
486
-
487
- sidecar = {
488
- "TaskName": task_name,
489
- "SamplingFrequency": info["sfreq"],
490
- "EEGChannelCount": eeg_count,
491
- "EOGChannelCount": eog_count,
492
- "ECGChannelCount": ecg_count,
493
- "EMGChannelCount": emg_count,
494
- "PowerLineFrequency": info.get("line_freq", "n/a"),
495
- "SoftwareFilters": {
496
- "HighpassFilter": {"CutoffFrequency": info.get("highpass", "n/a")},
497
- "LowpassFilter": {"CutoffFrequency": info.get("lowpass", "n/a")},
498
- },
499
- }
468
+ raw = _raw_from_info(info)
469
+ manufacturer = manufacturer or "n/a"
470
+ with TemporaryDirectory() as tmpdir, mne.utils.use_log_level("WARNING"):
471
+ sidecar_path = Path(tmpdir) / "eeg.json"
472
+ _sidecar_json(
473
+ raw,
474
+ task_name,
475
+ manufacturer,
476
+ sidecar_path,
477
+ "eeg",
478
+ overwrite=True,
479
+ )
480
+ sidecar = json.loads(sidecar_path.read_text(encoding="utf-8"))
500
481
 
501
482
  if task_description:
502
483
  sidecar["TaskDescription"] = task_description
@@ -504,8 +485,12 @@ def create_eeg_json_sidecar(
504
485
  sidecar["Instructions"] = instructions
505
486
  if institution_name:
506
487
  sidecar["InstitutionName"] = institution_name
507
- if manufacturer:
508
- sidecar["Manufacturer"] = manufacturer
488
+ if recording_duration is not None:
489
+ sidecar["RecordingDuration"] = recording_duration
490
+ if recording_type is not None:
491
+ sidecar["RecordingType"] = recording_type
492
+ if epoch_length is not None:
493
+ sidecar["EpochLength"] = epoch_length
509
494
 
510
495
  if extra_metadata:
511
496
  sidecar.update(extra_metadata)
@@ -519,6 +504,9 @@ def save_bids_sidecar_files(
519
504
  metadata: Optional[pd.DataFrame] = None,
520
505
  sfreq: Optional[float] = None,
521
506
  task_name: str = "unknown",
507
+ recording_duration: Optional[float] = None,
508
+ recording_type: Optional[str] = None,
509
+ epoch_length: Optional[float] = None,
522
510
  ) -> dict[str, Path]:
523
511
  """
524
512
  Save BIDS sidecar files for a recording using mne_bids BIDSPath.
@@ -535,6 +523,14 @@ def save_bids_sidecar_files(
535
523
  Sampling frequency (if not in info).
536
524
  task_name : str
537
525
  Task name for sidecar JSON.
526
+ recording_duration : float | None
527
+ Length of the recording in seconds (BIDS RECOMMENDED).
528
+ recording_type : str | None
529
+ Type of recording: "continuous", "epoched", or "discontinuous"
530
+ (BIDS RECOMMENDED).
531
+ epoch_length : float | None
532
+ Duration of individual epochs in seconds. RECOMMENDED if
533
+ recording_type is "epoched".
538
534
 
539
535
  Returns
540
536
  -------
@@ -568,7 +564,13 @@ def save_bids_sidecar_files(
568
564
  saved_files["channels"] = channels_path.fpath
569
565
 
570
566
  # Save EEG sidecar JSON
571
- sidecar = create_eeg_json_sidecar(info, task_name=task_name)
567
+ sidecar = create_eeg_json_sidecar(
568
+ info,
569
+ task_name=task_name,
570
+ recording_duration=recording_duration,
571
+ recording_type=recording_type,
572
+ epoch_length=epoch_length,
573
+ )
572
574
  sidecar_path = base_path.copy().update(suffix="eeg", extension=".json")
573
575
  with open(sidecar_path.fpath, "w", encoding="utf-8") as f:
574
576
  json.dump(sidecar, f, indent=2)
@@ -577,15 +579,16 @@ def save_bids_sidecar_files(
577
579
  return saved_files
578
580
 
579
581
 
580
- class BIDSDerivativesLayout:
582
+ class BIDSSourcedataLayout:
581
583
  """
582
- Helper class for creating BIDS-like derivatives folder structure.
584
+ Helper class for creating BIDS sourcedata folder structure.
583
585
 
584
- This creates a structure compatible with BIDS derivatives while
585
- storing data in Zarr format for efficient training.
586
+ This creates a structure using the BIDS ``sourcedata/`` directory,
587
+ which is not validated by BIDS validators, allowing us to store
588
+ data in Zarr format for efficient training.
586
589
 
587
590
  Structure:
588
- derivatives/<pipeline>/
591
+ sourcedata/<pipeline>/
589
592
  ├── dataset_description.json
590
593
  ├── participants.tsv
591
594
  ├── sub-<label>/
@@ -604,23 +607,23 @@ class BIDSDerivativesLayout:
604
607
  pipeline_name: str = DEFAULT_PIPELINE_NAME,
605
608
  ):
606
609
  """
607
- Initialize BIDS derivatives layout.
610
+ Initialize BIDS sourcedata layout.
608
611
 
609
612
  Parameters
610
613
  ----------
611
614
  root : str | Path
612
- Root directory for derivatives.
615
+ Root directory for sourcedata.
613
616
  pipeline_name : str
614
617
  Name of the processing pipeline.
615
618
  """
616
619
  self.root = Path(root)
617
620
  self.pipeline_name = pipeline_name
618
- self.derivatives_dir = self.root / "derivatives" / pipeline_name
621
+ self.sourcedata_dir = self.root / "sourcedata" / pipeline_name
619
622
 
620
623
  def create_structure(self) -> Path:
621
- """Create the basic derivatives directory structure."""
622
- self.derivatives_dir.mkdir(parents=True, exist_ok=True)
623
- return self.derivatives_dir
624
+ """Create the basic sourcedata directory structure."""
625
+ self.sourcedata_dir.mkdir(parents=True, exist_ok=True)
626
+ return self.sourcedata_dir
624
627
 
625
628
  def get_bids_path(
626
629
  self,
@@ -650,7 +653,7 @@ class BIDSDerivativesLayout:
650
653
  """
651
654
  return description_to_bids_path(
652
655
  description=description,
653
- root=self.derivatives_dir,
656
+ root=self.sourcedata_dir,
654
657
  datatype="eeg",
655
658
  suffix=suffix,
656
659
  extension=extension,
@@ -664,7 +667,7 @@ class BIDSDerivativesLayout:
664
667
  source_datasets: Optional[list[dict]] = None,
665
668
  ) -> Path:
666
669
  """
667
- Save dataset_description.json for derivatives.
670
+ Save dataset_description.json for sourcedata.
668
671
 
669
672
  Parameters
670
673
  ----------
@@ -679,7 +682,7 @@ class BIDSDerivativesLayout:
679
682
  Path to saved file.
680
683
  """
681
684
  return make_dataset_description(
682
- path=self.derivatives_dir,
685
+ path=self.sourcedata_dir,
683
686
  name=name,
684
687
  pipeline_name=self.pipeline_name,
685
688
  source_datasets=source_datasets,
@@ -707,7 +710,7 @@ class BIDSDerivativesLayout:
707
710
  Path to saved file.
708
711
  """
709
712
  participants_df = create_participants_tsv(descriptions, extra_columns)
710
- participants_path = self.derivatives_dir / "participants.tsv"
713
+ participants_path = self.sourcedata_dir / "participants.tsv"
711
714
  participants_df.to_csv(
712
715
  participants_path, sep="\t", index=False, na_rep="n/a", encoding="utf-8"
713
716
  )