Braindecode 1.3.2.dev170355810__tar.gz → 1.3.2.dev170805792__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 (164) hide show
  1. {braindecode-1.3.2.dev170355810/braindecode.egg-info → braindecode-1.3.2.dev170805792}/PKG-INFO +3 -3
  2. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/augmentation/transforms.py +6 -4
  3. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/base.py +266 -30
  4. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/bids/hub.py +69 -33
  5. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/bids/hub_io.py +21 -44
  6. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/__init__.py +4 -0
  7. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/base.py +293 -104
  8. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/bendr.py +86 -25
  9. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/biot.py +23 -5
  10. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/cbramod.py +28 -6
  11. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/config.py +29 -29
  12. braindecode-1.3.2.dev170805792/braindecode/models/deepsleepnet.py +477 -0
  13. braindecode-1.3.2.dev170805792/braindecode/models/dgcnn.py +500 -0
  14. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/eeginception_mi.py +2 -1
  15. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/eegitnet.py +4 -3
  16. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/eegpt.py +15 -2
  17. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/eegsym.py +1 -1
  18. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/labram.py +15 -1
  19. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/luna.py +11 -21
  20. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/patchedtransformer.py +5 -3
  21. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/reve.py +59 -23
  22. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/shallow_fbcsp.py +16 -8
  23. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/signal_jepa.py +63 -13
  24. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/sstdpn.py +1 -1
  25. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/summary.csv +1 -0
  26. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/util.py +147 -14
  27. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/modules/__init__.py +2 -1
  28. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/modules/activation.py +20 -0
  29. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/modules/attention.py +2 -1
  30. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/preprocessing/mne_preprocess.py +2 -1
  31. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/preprocessing/preprocess.py +61 -31
  32. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/util.py +34 -4
  33. braindecode-1.3.2.dev170805792/braindecode/version.py +1 -0
  34. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792/braindecode.egg-info}/PKG-INFO +3 -3
  35. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode.egg-info/SOURCES.txt +1 -0
  36. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode.egg-info/requires.txt +2 -2
  37. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/api.rst +11 -9
  38. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/conf.py +18 -13
  39. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/models/categorization/gnn.rst +9 -1
  40. braindecode-1.3.2.dev170805792/docs/models/categorization/spd.rst +103 -0
  41. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/models/models_categorization.rst +60 -60
  42. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/whats_new.rst +108 -6
  43. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/pyproject.toml +11 -2
  44. braindecode-1.3.2.dev170355810/braindecode/models/deepsleepnet.py +0 -417
  45. braindecode-1.3.2.dev170355810/braindecode/version.py +0 -1
  46. braindecode-1.3.2.dev170355810/docs/models/categorization/spd.rst +0 -35
  47. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/LICENSE.txt +0 -0
  48. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/MANIFEST.in +0 -0
  49. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/NOTICE.txt +0 -0
  50. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/README.rst +0 -0
  51. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/__init__.py +0 -0
  52. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/augmentation/__init__.py +0 -0
  53. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/augmentation/base.py +0 -0
  54. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/augmentation/functional.py +0 -0
  55. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/classifier.py +0 -0
  56. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/__init__.py +0 -0
  57. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/bbci.py +0 -0
  58. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/bcicomp.py +0 -0
  59. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/bids/__init__.py +0 -0
  60. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/bids/datasets.py +0 -0
  61. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/bids/format.py +0 -0
  62. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/bids/hub_format.py +0 -0
  63. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/bids/hub_validation.py +0 -0
  64. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/bids/iterable.py +0 -0
  65. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/chb_mit.py +0 -0
  66. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/mne.py +0 -0
  67. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/moabb.py +0 -0
  68. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/nmt.py +0 -0
  69. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/registry.py +0 -0
  70. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/siena.py +0 -0
  71. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  72. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/sleep_physionet.py +0 -0
  73. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/tuh.py +0 -0
  74. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/utils.py +0 -0
  75. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datasets/xy.py +0 -0
  76. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datautil/__init__.py +0 -0
  77. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datautil/channel_utils.py +0 -0
  78. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datautil/hub_formats.py +0 -0
  79. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datautil/serialization.py +0 -0
  80. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/datautil/util.py +0 -0
  81. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/eegneuralnet.py +0 -0
  82. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/functional/__init__.py +0 -0
  83. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/functional/functions.py +0 -0
  84. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/functional/initialization.py +0 -0
  85. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/atcnet.py +0 -0
  86. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/attentionbasenet.py +0 -0
  87. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/attn_sleep.py +0 -0
  88. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/brainmodule.py +0 -0
  89. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/contrawr.py +0 -0
  90. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/ctnet.py +0 -0
  91. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/deep4.py +0 -0
  92. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/eegconformer.py +0 -0
  93. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/eeginception_erp.py +0 -0
  94. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/eegminer.py +0 -0
  95. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/eegnet.py +0 -0
  96. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/eegnex.py +0 -0
  97. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/eegsimpleconv.py +0 -0
  98. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/eegtcnet.py +0 -0
  99. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/fbcnet.py +0 -0
  100. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/fblightconvnet.py +0 -0
  101. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/fbmsnet.py +0 -0
  102. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/hybrid.py +0 -0
  103. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/ifnet.py +0 -0
  104. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/medformer.py +0 -0
  105. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/msvtnet.py +0 -0
  106. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/sccnet.py +0 -0
  107. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/sinc_shallow.py +0 -0
  108. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  109. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  110. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/sparcnet.py +0 -0
  111. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/syncnet.py +0 -0
  112. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/tcn.py +0 -0
  113. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/tidnet.py +0 -0
  114. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/tsinception.py +0 -0
  115. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/models/usleep.py +0 -0
  116. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/modules/blocks.py +0 -0
  117. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/modules/convolution.py +0 -0
  118. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/modules/filter.py +0 -0
  119. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/modules/layers.py +0 -0
  120. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/modules/linear.py +0 -0
  121. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/modules/parametrization.py +0 -0
  122. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/modules/stats.py +0 -0
  123. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/modules/util.py +0 -0
  124. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/modules/wrapper.py +0 -0
  125. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/preprocessing/__init__.py +0 -0
  126. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
  127. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/preprocessing/util.py +0 -0
  128. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/preprocessing/windowers.py +0 -0
  129. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/regressor.py +0 -0
  130. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/samplers/__init__.py +0 -0
  131. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/samplers/base.py +0 -0
  132. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/samplers/ssl.py +0 -0
  133. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/training/__init__.py +0 -0
  134. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/training/callbacks.py +0 -0
  135. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/training/losses.py +0 -0
  136. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/training/scoring.py +0 -0
  137. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/visualization/__init__.py +0 -0
  138. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/visualization/confusion_matrices.py +0 -0
  139. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode/visualization/gradients.py +0 -0
  140. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode.egg-info/dependency_links.txt +0 -0
  141. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/braindecode.egg-info/top_level.txt +0 -0
  142. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/Makefile +0 -0
  143. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/_templates/autosummary/class.rst +0 -0
  144. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
  145. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/_templates/autosummary/function.rst +0 -0
  146. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
  147. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/cite.rst +0 -0
  148. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/help.rst +0 -0
  149. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/index.rst +0 -0
  150. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/install/install.rst +0 -0
  151. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/install/install_pip.rst +0 -0
  152. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/install/install_source.rst +0 -0
  153. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/models/categorization/attention.rst +0 -0
  154. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/models/categorization/channel.rst +0 -0
  155. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/models/categorization/convolution.rst +0 -0
  156. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/models/categorization/filterbank.rst +0 -0
  157. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/models/categorization/interpretable.rst +0 -0
  158. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/models/categorization/lbm.rst +0 -0
  159. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/models/categorization/recurrent.rst +0 -0
  160. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/models/models.rst +0 -0
  161. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/models/models_table.rst +0 -0
  162. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/models/models_visualization.rst +0 -0
  163. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/docs/sg_execution_times.rst +0 -0
  164. {braindecode-1.3.2.dev170355810 → braindecode-1.3.2.dev170805792}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.3.2.dev170355810
3
+ Version: 1.3.2.dev170805792
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>
@@ -22,7 +22,7 @@ Requires-Python: >=3.11
22
22
  Description-Content-Type: text/x-rst
23
23
  License-File: LICENSE.txt
24
24
  License-File: NOTICE.txt
25
- Requires-Dist: torch>=2.2
25
+ Requires-Dist: torch>=2.0
26
26
  Requires-Dist: torchaudio>=2.0
27
27
  Requires-Dist: mne>=1.11.0
28
28
  Requires-Dist: pandas<3.0.0
@@ -35,7 +35,7 @@ Requires-Dist: wfdb
35
35
  Requires-Dist: linear_attention_transformer
36
36
  Requires-Dist: docstring_inheritance
37
37
  Requires-Dist: rotary_embedding_torch
38
- Requires-Dist: pandas<3.0.0
38
+ Requires-Dist: pydantic>=2.0
39
39
  Provides-Extra: moabb
40
40
  Requires-Dist: moabb>=1.4.3; extra == "moabb"
41
41
  Provides-Extra: eegprep
@@ -2,6 +2,7 @@
2
2
  # Alexandre Gramfort <alexandre.gramfort@inria.fr>
3
3
  # Gustavo Rodrigues <gustavenrique01@gmail.com>
4
4
  # Bruna Lopes <brunajaflopes@gmail.com>
5
+ # Sarthak Tayal <sarthaktayal2@gmail.com>
5
6
  #
6
7
  # License: BSD (3-clause)
7
8
 
@@ -557,8 +558,9 @@ class BandstopFilter(Transform):
557
558
  f" Nyquist frequency ({nyq} Hz)."
558
559
  f" Falling back to max_freq = {nyq}."
559
560
  )
560
- assert bandwidth < max_freq, (
561
- f"`bandwidth` needs to be smaller than max_freq={max_freq}"
561
+ assert bandwidth < max_freq - 2, (
562
+ f"`bandwidth` needs to be smaller than max_freq - 2={max_freq - 2} "
563
+ f"to allow valid notch frequency sampling with 1 Hz transition bands."
562
564
  )
563
565
 
564
566
  # override bandwidth value when a magnitude is passed
@@ -600,8 +602,8 @@ class BandstopFilter(Transform):
600
602
 
601
603
  # Prevents transitions from going below 0 and above max_freq
602
604
  notched_freqs = self.rng.uniform(
603
- low=1 + 2 * self.bandwidth,
604
- high=self.max_freq - 1 - 2 * self.bandwidth,
605
+ low=1 + self.bandwidth / 2,
606
+ high=self.max_freq - 1 - self.bandwidth / 2,
605
607
  size=X.shape[0],
606
608
  )
607
609
  return {
@@ -20,18 +20,24 @@ from abc import abstractmethod
20
20
  from collections import Counter
21
21
  from collections.abc import Callable
22
22
  from glob import glob
23
+ from pathlib import Path
23
24
  from typing import Any, Generic, Iterable, no_type_check
24
25
 
26
+ import mne
25
27
  import mne.io
26
28
  import numpy as np
27
29
  import pandas as pd
30
+ from mne.utils import _soft_import
28
31
  from mne.utils.docs import deprecated
29
32
  from torch.utils.data import ConcatDataset, Dataset, IterableDataset
30
33
  from typing_extensions import TypeVar
31
34
 
32
35
  from .bids.hub import HubDatasetMixin
36
+ from .bids.hub_io import _restore_nan_from_json
33
37
  from .registry import register_dataset
34
38
 
39
+ zarr = _soft_import("zarr", purpose="lazy loading from Zarr", strict=False)
40
+
35
41
 
36
42
  def _create_description(description) -> pd.Series:
37
43
  if description is not None:
@@ -176,14 +182,11 @@ def _concat_metadata_summary(datasets):
176
182
 
177
183
 
178
184
  def _channel_info(mne_obj):
179
- """Extract channel summary from an mne object.
180
-
181
- Returns (n_ch, type_str, sfreq).
182
- """
183
- info = mne_obj.info
185
+ """Extract (n_ch, type_str, sfreq) from an mne object or mne.Info."""
186
+ info = mne_obj if isinstance(mne_obj, mne.Info) else mne_obj.info
184
187
  n_ch = info["nchan"]
185
188
  sfreq = info["sfreq"]
186
- ch_types = mne_obj.get_channel_types()
189
+ ch_types = info.get_channel_types()
187
190
  type_counts = Counter(ch_types)
188
191
  type_str = ", ".join(f"{cnt} {t.upper()}" for t, cnt in sorted(type_counts.items()))
189
192
  return n_ch, type_str, sfreq
@@ -294,6 +297,88 @@ def _build_windowed_repr(
294
297
  return b
295
298
 
296
299
 
300
+ def _zarr_to_memmap(zarr_path, group_name):
301
+ """Decompress a zarr array to a float64 ``.npy`` memmap (one-time, atomic).
302
+
303
+ Saved as float64 so MNE objects can wrap the memmap zero-copy
304
+ (MNE requires float64 internally). Copy-on-write mode (``'c'``)
305
+ means preprocessing writes go to RAM, the file stays untouched.
306
+ """
307
+ zarr_p = Path(zarr_path)
308
+ cache_dir = zarr_p.parent / f".{zarr_p.name}_memmap"
309
+ npy_path = cache_dir / f"{group_name}.npy"
310
+
311
+ if not npy_path.exists():
312
+ arr = zarr.open(zarr_path, mode="r")[group_name]["data"]
313
+ cache_dir.mkdir(parents=True, exist_ok=True)
314
+ tmp_path = cache_dir / f"{group_name}.{os.getpid()}.tmp.npy"
315
+ # Write chunk-by-chunk to avoid materializing the full array in RAM
316
+ mm = np.lib.format.open_memmap(
317
+ tmp_path, mode="w+", dtype=np.float64, shape=arr.shape
318
+ )
319
+ chunk0 = arr.chunks[0] if hasattr(arr, "chunks") else arr.shape[0]
320
+ for start in range(0, arr.shape[0], chunk0):
321
+ end = min(start + chunk0, arr.shape[0])
322
+ mm[start:end] = np.asarray(arr[start:end], dtype=np.float64)
323
+ mm.flush()
324
+ del mm
325
+ try:
326
+ tmp_path.rename(npy_path)
327
+ except OSError:
328
+ tmp_path.unlink(missing_ok=True)
329
+
330
+ return npy_path
331
+
332
+
333
+ class _ZarrMixin:
334
+ """Zarr-to-memmap lazy loading with MNE compatibility.
335
+
336
+ Decompresses zarr to float64 ``.npy`` memmaps on first access.
337
+ MNE objects (``raw``/``windows``) are reconstructed lazily on first
338
+ property access, backed by copy-on-write memmaps so preprocessing
339
+ writes go to RAM while the file stays untouched.
340
+ """
341
+
342
+ _zarr_data = None
343
+
344
+ def _open_zarr(self):
345
+ npy_path = _zarr_to_memmap(self._zarr_path, self._group_name)
346
+ # 'c' = copy-on-write: reads from file, writes to RAM
347
+ self._zarr_data = np.load(npy_path, mmap_mode="c")
348
+
349
+ def _make_mne_info(self):
350
+ """Reconstruct ``mne.Info`` from stored dict (no data I/O)."""
351
+ return mne.Info.from_json_dict(_restore_nan_from_json(self._info_dict))
352
+
353
+ @classmethod
354
+ def _init_zarr_base(cls, zarr_path, group_name, description, info_dict, transform):
355
+ """Shared ``_from_zarr`` preamble: create instance with zarr attrs."""
356
+ if zarr is False:
357
+ raise ImportError("zarr is required: pip install braindecode[hub]")
358
+ obj = object.__new__(cls)
359
+ RecordDataset.__init__(obj, description, transform)
360
+ obj._zarr_path = Path(zarr_path)
361
+ obj._group_name = group_name
362
+ obj._info_dict = info_dict
363
+ return obj
364
+
365
+ def __getstate__(self):
366
+ state = self.__dict__.copy()
367
+ state.pop("_zarr_data", None)
368
+ # Drop lazily-constructed mne objects; they'll be rebuilt from memmap
369
+ if hasattr(self, "_zarr_path"):
370
+ state.pop("_raw", None)
371
+ state.pop("_windows", None)
372
+ return state
373
+
374
+ def __setstate__(self, state):
375
+ self.__dict__.update(state)
376
+ if hasattr(self, "_zarr_path"):
377
+ self._open_zarr()
378
+ else:
379
+ self._zarr_data = None
380
+
381
+
297
382
  class RecordDataset(Dataset[tuple[np.ndarray, int | str, tuple[int, int, int]]]):
298
383
  def __init__(
299
384
  self,
@@ -361,7 +446,7 @@ T = TypeVar("T", bound=RecordDataset)
361
446
 
362
447
 
363
448
  @register_dataset
364
- class RawDataset(RecordDataset):
449
+ class RawDataset(_ZarrMixin, RecordDataset):
365
450
  """Returns samples from an mne.io.Raw object along with a target.
366
451
 
367
452
  Dataset which serves samples from an mne.io.Raw object along with a target.
@@ -395,8 +480,43 @@ class RawDataset(RecordDataset):
395
480
  self.target_name = self._target_name(target_name)
396
481
  self.raw_preproc_kwargs: list[dict[str, Any]] = []
397
482
 
483
+ @classmethod
484
+ def _from_zarr(
485
+ cls,
486
+ zarr_path,
487
+ group_name,
488
+ description,
489
+ info_dict,
490
+ target_name=None,
491
+ transform=None,
492
+ ):
493
+ """Create a lazy Zarr-backed RawDataset (internal API)."""
494
+ obj = cls._init_zarr_base(
495
+ zarr_path, group_name, description, info_dict, transform
496
+ )
497
+ obj._raw = None
498
+ obj.target_name = cls._target_name(obj, target_name)
499
+ obj.raw_preproc_kwargs = []
500
+ obj._open_zarr()
501
+ return obj
502
+
503
+ @property
504
+ def raw(self):
505
+ if self._raw is None and self._zarr_data is not None:
506
+ self._raw = mne.io.RawArray(self._zarr_data, self._make_mne_info())
507
+ return self._raw
508
+
509
+ @raw.setter
510
+ def raw(self, value):
511
+ self._raw = value
512
+
398
513
  def __getitem__(self, index):
399
- X = self.raw[:, index][0]
514
+ if self._zarr_data is not None:
515
+ X = np.array(self._zarr_data[:, index], dtype="float32")
516
+ if X.ndim == 1:
517
+ X = X[:, np.newaxis]
518
+ else:
519
+ X = self._raw[:, index][0]
400
520
  y = None
401
521
  if self.target_name is not None:
402
522
  y = self.description[self.target_name]
@@ -407,13 +527,19 @@ class RawDataset(RecordDataset):
407
527
  return X, y
408
528
 
409
529
  def __len__(self):
410
- return len(self.raw)
530
+ if self._raw is not None:
531
+ return len(self._raw)
532
+ return self._zarr_data.shape[1]
411
533
 
412
534
  def _build_repr(self):
413
535
  b = _ReprBuilder(type(self).__name__)
414
- n_ch, type_str, sfreq = _channel_info(self.raw)
415
- n_times = len(self.raw.times)
416
- duration = n_times / sfreq
536
+ if self._raw is not None:
537
+ n_ch, type_str, sfreq = _channel_info(self._raw)
538
+ n_times = len(self._raw.times)
539
+ else:
540
+ n_ch, type_str, sfreq = _channel_info(self._make_mne_info())
541
+ n_times = self._zarr_data.shape[1]
542
+ duration = n_times / sfreq if sfreq > 0 else 0
417
543
  b.add_header(f"{n_ch} ch ({type_str})", "Channels", f"{n_ch} ({type_str})")
418
544
  b.add_header(f"{sfreq:.1f} Hz", "Sfreq", f"{sfreq:.1f} Hz")
419
545
  b.add_header(
@@ -424,6 +550,8 @@ class RawDataset(RecordDataset):
424
550
  if self.description is not None:
425
551
  desc_items = ", ".join(f"{k}={v}" for k, v in self.description.items())
426
552
  b.add_row("description", desc_items)
553
+ if self._zarr_data is not None:
554
+ b.add_footnote("Data loaded lazily from Zarr")
427
555
  return b
428
556
 
429
557
  def _target_name(self, target_name):
@@ -464,7 +592,7 @@ class BaseDataset(RawDataset):
464
592
 
465
593
 
466
594
  @register_dataset
467
- class EEGWindowsDataset(RecordDataset):
595
+ class EEGWindowsDataset(_ZarrMixin, RecordDataset):
468
596
  """Returns windows from an mne.Raw object, its window indices, along with a target.
469
597
 
470
598
  Dataset which serves windows from an mne.Epochs object along with their
@@ -521,6 +649,47 @@ class EEGWindowsDataset(RecordDataset):
521
649
  self.y = metadata.loc[:, "target"].to_list()
522
650
  self.raw_preproc_kwargs: list[dict[str, Any]] = []
523
651
 
652
+ @classmethod
653
+ def _from_zarr(
654
+ cls,
655
+ zarr_path,
656
+ group_name,
657
+ metadata,
658
+ description,
659
+ info_dict,
660
+ targets_from="metadata",
661
+ last_target_only=True,
662
+ transform=None,
663
+ ):
664
+ """Create a lazy Zarr-backed EEGWindowsDataset (internal API)."""
665
+ obj = cls._init_zarr_base(
666
+ zarr_path, group_name, description, info_dict, transform
667
+ )
668
+ obj._raw = None
669
+ obj.metadata = metadata
670
+ obj.last_target_only = last_target_only
671
+ if targets_from not in ("metadata", "channels"):
672
+ raise ValueError("Wrong value for parameter `targets_from`.")
673
+ obj.targets_from = targets_from
674
+ obj.crop_inds = metadata.loc[
675
+ :, ["i_window_in_trial", "i_start_in_trial", "i_stop_in_trial"]
676
+ ].to_numpy()
677
+ if obj.targets_from == "metadata":
678
+ obj.y = metadata.loc[:, "target"].to_list()
679
+ obj.raw_preproc_kwargs = []
680
+ obj._open_zarr()
681
+ return obj
682
+
683
+ @property
684
+ def raw(self):
685
+ if self._raw is None and self._zarr_data is not None:
686
+ self._raw = mne.io.RawArray(self._zarr_data, self._make_mne_info())
687
+ return self._raw
688
+
689
+ @raw.setter
690
+ def raw(self, value):
691
+ self._raw = value
692
+
524
693
  def __getitem__(self, index: int):
525
694
  """Get a window and its target.
526
695
 
@@ -544,11 +713,13 @@ class EEGWindowsDataset(RecordDataset):
544
713
  crop_inds = self.crop_inds[index].tolist()
545
714
 
546
715
  i_window_in_trial, i_start, i_stop = crop_inds
547
- X = self.raw._getitem((slice(None), slice(i_start, i_stop)), return_times=False)
548
- X = X.astype("float32")
549
- # ensure we don't give the user the option
550
- # to accidentally modify the underlying array
551
- X = X.copy()
716
+ if self._zarr_data is not None:
717
+ X = self._zarr_data[:, i_start:i_stop]
718
+ else:
719
+ X = self.raw._getitem(
720
+ (slice(None), slice(i_start, i_stop)), return_times=False
721
+ )
722
+ X = np.array(X, dtype="float32")
552
723
  if self.transform is not None:
553
724
  X = self.transform(X)
554
725
  if self.targets_from == "metadata":
@@ -559,10 +730,7 @@ class EEGWindowsDataset(RecordDataset):
559
730
  y = X[misc_mask, -1]
560
731
  else:
561
732
  y = X[misc_mask, :]
562
- # ensure we don't give the user the option
563
- # to accidentally modify the underlying array
564
733
  y = y.copy()
565
- # remove the target channels from raw
566
734
  X = X[~misc_mask, :]
567
735
  return X, y, crop_inds
568
736
 
@@ -570,10 +738,11 @@ class EEGWindowsDataset(RecordDataset):
570
738
  return len(self.crop_inds)
571
739
 
572
740
  def _build_repr(self):
741
+ mne_obj = self._raw if self._raw is not None else self._make_mne_info()
573
742
  return _build_windowed_repr(
574
743
  type(self).__name__,
575
744
  len(self),
576
- self.raw,
745
+ mne_obj,
577
746
  self.crop_inds,
578
747
  self.description,
579
748
  self.metadata,
@@ -664,7 +833,7 @@ class EEGWindowsDataset(RecordDataset):
664
833
 
665
834
 
666
835
  @register_dataset
667
- class WindowsDataset(RecordDataset):
836
+ class WindowsDataset(_ZarrMixin, RecordDataset):
668
837
  """Returns windows from an mne.Epochs object along with a target.
669
838
 
670
839
  Dataset which serves windows from an mne.Epochs object along with their
@@ -717,6 +886,7 @@ class WindowsDataset(RecordDataset):
717
886
 
718
887
  metadata = self.windows.metadata
719
888
  assert metadata is not None, "WindowsDataset requires windows with metadata."
889
+ self.metadata = metadata
720
890
  self.crop_inds = metadata.loc[
721
891
  :, ["i_window_in_trial", "i_start_in_trial", "i_stop_in_trial"]
722
892
  ].to_numpy()
@@ -725,6 +895,67 @@ class WindowsDataset(RecordDataset):
725
895
  self.raw_preproc_kwargs: list[dict[str, Any]] = []
726
896
  self.window_preproc_kwargs: list[dict[str, Any]] = []
727
897
 
898
+ @classmethod
899
+ def _from_zarr(
900
+ cls,
901
+ zarr_path,
902
+ group_name,
903
+ metadata,
904
+ description,
905
+ info_dict,
906
+ target_name=None,
907
+ transform=None,
908
+ targets_from="metadata",
909
+ last_target_only=True,
910
+ ):
911
+ """Create a lazy Zarr-backed WindowsDataset (internal API)."""
912
+ obj = cls._init_zarr_base(
913
+ zarr_path, group_name, description, info_dict, transform
914
+ )
915
+ obj._windows = None
916
+ obj.target_name = target_name
917
+ obj._fast_disk = False
918
+ obj.last_target_only = last_target_only
919
+ if targets_from not in ("metadata", "channels"):
920
+ raise ValueError("Wrong value for parameter `targets_from`.")
921
+ obj.targets_from = targets_from
922
+ obj.metadata = metadata
923
+ obj.crop_inds = metadata.loc[
924
+ :, ["i_window_in_trial", "i_start_in_trial", "i_stop_in_trial"]
925
+ ].to_numpy()
926
+ if obj.targets_from == "metadata":
927
+ obj.y = metadata.loc[:, "target"].to_list()
928
+ obj.raw_preproc_kwargs = []
929
+ obj.window_preproc_kwargs = []
930
+ obj._open_zarr()
931
+ return obj
932
+
933
+ @property
934
+ def windows(self):
935
+ if self._windows is None and self._zarr_data is not None:
936
+ info = self._make_mne_info()
937
+ targets = self.metadata["target"].values
938
+ event_ids = (
939
+ targets
940
+ if np.issubdtype(targets.dtype, np.integer)
941
+ else np.ones(len(self.metadata), dtype=int)
942
+ )
943
+ events = np.column_stack(
944
+ [
945
+ self.metadata["i_start_in_trial"].values.astype(int),
946
+ np.zeros(len(self.metadata), dtype=int),
947
+ event_ids,
948
+ ]
949
+ )
950
+ self._windows = mne.EpochsArray(
951
+ self._zarr_data, info, events=events, metadata=self.metadata
952
+ )
953
+ return self._windows
954
+
955
+ @windows.setter
956
+ def windows(self, value):
957
+ self._windows = value
958
+
728
959
  @staticmethod
729
960
  def _can_use_fast_get_epoch_from_raw(epochs: mne.BaseEpochs) -> bool:
730
961
  """Check if we can use the fast _get_epoch_from_raw method,
@@ -756,7 +987,9 @@ class WindowsDataset(RecordDataset):
756
987
  np.ndarray
757
988
  Crop indices.
758
989
  """
759
- if self._fast_disk:
990
+ if self._zarr_data is not None:
991
+ X = self._zarr_data[index].astype("float32")
992
+ elif self._fast_disk:
760
993
  X = self.windows._get_epoch_from_raw(index).astype("float32")
761
994
  else:
762
995
  X = self.windows.get_data(item=index)[0].astype("float32")
@@ -770,7 +1003,6 @@ class WindowsDataset(RecordDataset):
770
1003
  y = X[misc_mask, -1]
771
1004
  else:
772
1005
  y = X[misc_mask, :]
773
- # remove the target channels from raw
774
1006
  X = X[~misc_mask, :]
775
1007
  # necessary to cast as list to get list of three tensors from batch,
776
1008
  # otherwise get single 2d-tensor...
@@ -778,16 +1010,20 @@ class WindowsDataset(RecordDataset):
778
1010
  return X, y, crop_inds
779
1011
 
780
1012
  def __len__(self) -> int:
781
- return len(self.windows.events)
1013
+ if self._windows is not None:
1014
+ return len(self._windows.events)
1015
+ return len(self.crop_inds)
782
1016
 
783
1017
  def _build_repr(self):
1018
+ mne_obj = self._windows if self._windows is not None else self._make_mne_info()
1019
+ md = self._windows.metadata if self._windows is not None else self.metadata
784
1020
  return _build_windowed_repr(
785
1021
  type(self).__name__,
786
1022
  len(self),
787
- self.windows,
1023
+ mne_obj,
788
1024
  self.crop_inds,
789
1025
  self.description,
790
- self.windows.metadata,
1026
+ md,
791
1027
  )
792
1028
 
793
1029
 
@@ -1014,8 +1250,8 @@ class BaseConcatDataset(ConcatDataset, HubDatasetMixin, Generic[T]):
1014
1250
 
1015
1251
  all_dfs = list()
1016
1252
  for ds in self.datasets:
1017
- if hasattr(ds, "windows"):
1018
- df = ds.windows.metadata
1253
+ if hasattr(ds, "_windows") and ds._windows is not None:
1254
+ df = ds._windows.metadata
1019
1255
  else:
1020
1256
  df = ds.metadata
1021
1257
  for k, v in ds.description.items():
@@ -39,7 +39,6 @@ import mne
39
39
  import numpy as np
40
40
  import pandas as pd
41
41
  import scipy
42
- from mne._fiff.meas_info import Info
43
42
  from mne.utils import _soft_import
44
43
 
45
44
  if TYPE_CHECKING:
@@ -733,7 +732,6 @@ class HubDatasetMixin:
733
732
  info_dict,
734
733
  compressor,
735
734
  target_name,
736
- chunk_size,
737
735
  )
738
736
 
739
737
  elif dataset_type == "EEGWindowsDataset":
@@ -836,6 +834,7 @@ class HubDatasetMixin:
836
834
  datasets = []
837
835
  for i_ds in range(n_datasets):
838
836
  grp = root[f"recording_{i_ds}"]
837
+ group_name = f"recording_{i_ds}"
839
838
 
840
839
  if dataset_type == "WindowsDataset":
841
840
  # Load using inlined function
@@ -843,19 +842,36 @@ class HubDatasetMixin:
843
842
  _load_windows_from_zarr(grp, preload)
844
843
  )
845
844
 
846
- # Convert to MNE objects and create dataset
847
- info = Info.from_json_dict(info_dict)
848
- events = np.column_stack(
849
- [
850
- metadata["i_start_in_trial"].values,
851
- np.zeros(len(metadata), dtype=int),
852
- metadata["target"].values,
853
- ]
854
- )
855
- epochs = mne.EpochsArray(data, info, events=events, metadata=metadata)
856
- ds = WindowsDataset(epochs, description)
857
- if target_name is not None:
858
- ds.target_name = target_name
845
+ if preload:
846
+ # Convert to MNE objects and create dataset
847
+ info = mne.Info.from_json_dict(info_dict)
848
+ targets = metadata["target"].values
849
+ if np.issubdtype(targets.dtype, np.integer):
850
+ event_ids = targets
851
+ else:
852
+ event_ids = np.ones(len(metadata), dtype=int)
853
+ events = np.column_stack(
854
+ [
855
+ metadata["i_start_in_trial"].values.astype(int),
856
+ np.zeros(len(metadata), dtype=int),
857
+ event_ids,
858
+ ]
859
+ )
860
+ epochs = mne.EpochsArray(
861
+ data, info, events=events, metadata=metadata
862
+ )
863
+ ds = WindowsDataset(epochs, description)
864
+ if target_name is not None:
865
+ ds.target_name = target_name
866
+ else:
867
+ ds = WindowsDataset._from_zarr(
868
+ zarr_path=input_path,
869
+ group_name=group_name,
870
+ metadata=metadata,
871
+ description=description,
872
+ info_dict=info_dict,
873
+ target_name=target_name,
874
+ )
859
875
 
860
876
  elif dataset_type == "EEGWindowsDataset":
861
877
  # Load using inlined function
@@ -868,17 +884,28 @@ class HubDatasetMixin:
868
884
  last_target_only,
869
885
  ) = _load_eegwindows_from_zarr(grp, preload)
870
886
 
871
- # Convert to MNE objects and create dataset
872
- # Data is already in continuous format [n_channels, n_timepoints]
873
- info = Info.from_json_dict(info_dict)
874
- raw = mne.io.RawArray(data, info)
875
- ds = EEGWindowsDataset(
876
- raw=raw,
877
- metadata=metadata,
878
- description=description,
879
- targets_from=targets_from,
880
- last_target_only=last_target_only,
881
- )
887
+ if preload:
888
+ # Convert to MNE objects and create dataset
889
+ # Data is already in continuous format [n_channels, n_timepoints]
890
+ info = mne.Info.from_json_dict(info_dict)
891
+ raw = mne.io.RawArray(data, info)
892
+ ds = EEGWindowsDataset(
893
+ raw=raw,
894
+ metadata=metadata,
895
+ description=description,
896
+ targets_from=targets_from,
897
+ last_target_only=last_target_only,
898
+ )
899
+ else:
900
+ ds = EEGWindowsDataset._from_zarr(
901
+ zarr_path=input_path,
902
+ group_name=group_name,
903
+ metadata=metadata,
904
+ description=description,
905
+ info_dict=info_dict,
906
+ targets_from=targets_from,
907
+ last_target_only=last_target_only,
908
+ )
882
909
 
883
910
  elif dataset_type == "RawDataset":
884
911
  # Load using inlined function
@@ -886,13 +913,22 @@ class HubDatasetMixin:
886
913
  grp, preload
887
914
  )
888
915
 
889
- # Convert to MNE objects and create dataset
890
- # Data is in continuous format [n_channels, n_timepoints]
891
- info = Info.from_json_dict(info_dict)
892
- raw = mne.io.RawArray(data, info)
893
- ds = RawDataset(raw, description)
894
- if target_name is not None:
895
- ds.target_name = target_name
916
+ if preload:
917
+ # Convert to MNE objects and create dataset
918
+ # Data is in continuous format [n_channels, n_timepoints]
919
+ info = mne.Info.from_json_dict(info_dict)
920
+ raw = mne.io.RawArray(data, info)
921
+ ds = RawDataset(raw, description)
922
+ if target_name is not None:
923
+ ds.target_name = target_name
924
+ else:
925
+ ds = RawDataset._from_zarr(
926
+ zarr_path=input_path,
927
+ group_name=group_name,
928
+ description=description,
929
+ info_dict=info_dict,
930
+ target_name=target_name,
931
+ )
896
932
 
897
933
  else:
898
934
  raise ValueError(f"Unsupported dataset_type: {dataset_type}")