braindecode 1.3.2.dev173417708__tar.gz → 1.3.2.dev173801889__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 (163) hide show
  1. {braindecode-1.3.2.dev173417708/braindecode.egg-info → braindecode-1.3.2.dev173801889}/PKG-INFO +1 -1
  2. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/base.py +150 -2
  3. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/bids/hub.py +161 -76
  4. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/bids/hub_io.py +29 -6
  5. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datautil/hub_formats.py +16 -3
  6. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/__init__.py +2 -0
  7. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/base.py +28 -17
  8. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/bendr.py +69 -19
  9. braindecode-1.3.2.dev173801889/braindecode/models/dgcnn.py +500 -0
  10. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/eegsym.py +1 -1
  11. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/sstdpn.py +1 -1
  12. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/summary.csv +1 -0
  13. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/util.py +13 -11
  14. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/modules/attention.py +2 -1
  15. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/preprocessing/mne_preprocess.py +2 -1
  16. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/preprocessing/preprocess.py +62 -32
  17. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/util.py +34 -4
  18. braindecode-1.3.2.dev173801889/braindecode/version.py +1 -0
  19. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889/braindecode.egg-info}/PKG-INFO +1 -1
  20. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode.egg-info/SOURCES.txt +1 -0
  21. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/api.rst +11 -9
  22. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/conf.py +18 -6
  23. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/models/categorization/gnn.rst +9 -1
  24. braindecode-1.3.2.dev173801889/docs/models/categorization/spd.rst +103 -0
  25. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/models/models_categorization.rst +59 -60
  26. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/whats_new.rst +37 -4
  27. braindecode-1.3.2.dev173417708/braindecode/version.py +0 -1
  28. braindecode-1.3.2.dev173417708/docs/models/categorization/spd.rst +0 -35
  29. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/LICENSE.txt +0 -0
  30. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/MANIFEST.in +0 -0
  31. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/NOTICE.txt +0 -0
  32. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/README.rst +0 -0
  33. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/__init__.py +0 -0
  34. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/augmentation/__init__.py +0 -0
  35. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/augmentation/base.py +0 -0
  36. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/augmentation/functional.py +0 -0
  37. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/augmentation/transforms.py +0 -0
  38. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/classifier.py +0 -0
  39. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/__init__.py +0 -0
  40. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/bbci.py +0 -0
  41. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/bcicomp.py +0 -0
  42. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/bids/__init__.py +0 -0
  43. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/bids/datasets.py +0 -0
  44. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/bids/format.py +0 -0
  45. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/bids/hub_format.py +0 -0
  46. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/bids/hub_validation.py +0 -0
  47. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/bids/iterable.py +0 -0
  48. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/chb_mit.py +0 -0
  49. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/mne.py +0 -0
  50. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/moabb.py +0 -0
  51. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/nmt.py +0 -0
  52. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/registry.py +0 -0
  53. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/siena.py +0 -0
  54. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  55. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/sleep_physionet.py +0 -0
  56. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/tuh.py +0 -0
  57. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/utils.py +0 -0
  58. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datasets/xy.py +0 -0
  59. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datautil/__init__.py +0 -0
  60. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datautil/channel_utils.py +0 -0
  61. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datautil/serialization.py +0 -0
  62. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/datautil/util.py +0 -0
  63. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/eegneuralnet.py +0 -0
  64. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/functional/__init__.py +0 -0
  65. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/functional/functions.py +0 -0
  66. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/functional/initialization.py +0 -0
  67. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/atcnet.py +0 -0
  68. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/attentionbasenet.py +0 -0
  69. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/attn_sleep.py +0 -0
  70. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/biot.py +0 -0
  71. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/brainmodule.py +0 -0
  72. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/cbramod.py +0 -0
  73. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/config.py +0 -0
  74. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/contrawr.py +0 -0
  75. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/ctnet.py +0 -0
  76. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/deep4.py +0 -0
  77. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/deepsleepnet.py +0 -0
  78. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/eegconformer.py +0 -0
  79. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/eeginception_erp.py +0 -0
  80. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/eeginception_mi.py +0 -0
  81. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/eegitnet.py +0 -0
  82. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/eegminer.py +0 -0
  83. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/eegnet.py +0 -0
  84. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/eegnex.py +0 -0
  85. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/eegpt.py +0 -0
  86. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/eegsimpleconv.py +0 -0
  87. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/eegtcnet.py +0 -0
  88. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/fbcnet.py +0 -0
  89. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/fblightconvnet.py +0 -0
  90. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/fbmsnet.py +0 -0
  91. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/hybrid.py +0 -0
  92. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/ifnet.py +0 -0
  93. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/labram.py +0 -0
  94. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/luna.py +0 -0
  95. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/medformer.py +0 -0
  96. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/msvtnet.py +0 -0
  97. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/patchedtransformer.py +0 -0
  98. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/reve.py +0 -0
  99. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/sccnet.py +0 -0
  100. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/shallow_fbcsp.py +0 -0
  101. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/signal_jepa.py +0 -0
  102. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/sinc_shallow.py +0 -0
  103. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  104. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  105. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/sparcnet.py +0 -0
  106. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/syncnet.py +0 -0
  107. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/tcn.py +0 -0
  108. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/tidnet.py +0 -0
  109. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/tsinception.py +0 -0
  110. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/models/usleep.py +0 -0
  111. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/modules/__init__.py +0 -0
  112. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/modules/activation.py +0 -0
  113. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/modules/blocks.py +0 -0
  114. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/modules/convolution.py +0 -0
  115. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/modules/filter.py +0 -0
  116. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/modules/layers.py +0 -0
  117. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/modules/linear.py +0 -0
  118. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/modules/parametrization.py +0 -0
  119. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/modules/stats.py +0 -0
  120. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/modules/util.py +0 -0
  121. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/modules/wrapper.py +0 -0
  122. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/preprocessing/__init__.py +0 -0
  123. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
  124. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/preprocessing/util.py +0 -0
  125. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/preprocessing/windowers.py +0 -0
  126. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/regressor.py +0 -0
  127. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/samplers/__init__.py +0 -0
  128. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/samplers/base.py +0 -0
  129. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/samplers/ssl.py +0 -0
  130. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/training/__init__.py +0 -0
  131. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/training/callbacks.py +0 -0
  132. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/training/losses.py +0 -0
  133. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/training/scoring.py +0 -0
  134. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/visualization/__init__.py +0 -0
  135. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/visualization/confusion_matrices.py +0 -0
  136. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode/visualization/gradients.py +0 -0
  137. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode.egg-info/dependency_links.txt +0 -0
  138. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode.egg-info/requires.txt +0 -0
  139. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/braindecode.egg-info/top_level.txt +0 -0
  140. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/Makefile +0 -0
  141. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/_templates/autosummary/class.rst +0 -0
  142. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
  143. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/_templates/autosummary/function.rst +0 -0
  144. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
  145. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/cite.rst +0 -0
  146. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/help.rst +0 -0
  147. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/index.rst +0 -0
  148. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/install/install.rst +0 -0
  149. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/install/install_pip.rst +0 -0
  150. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/install/install_source.rst +0 -0
  151. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/models/categorization/attention.rst +0 -0
  152. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/models/categorization/channel.rst +0 -0
  153. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/models/categorization/convolution.rst +0 -0
  154. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/models/categorization/filterbank.rst +0 -0
  155. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/models/categorization/interpretable.rst +0 -0
  156. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/models/categorization/lbm.rst +0 -0
  157. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/models/categorization/recurrent.rst +0 -0
  158. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/models/models.rst +0 -0
  159. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/models/models_table.rst +0 -0
  160. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/models/models_visualization.rst +0 -0
  161. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/docs/sg_execution_times.rst +0 -0
  162. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/pyproject.toml +0 -0
  163. {braindecode-1.3.2.dev173417708 → braindecode-1.3.2.dev173801889}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.3.2.dev173417708
3
+ Version: 1.3.2.dev173801889
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>
@@ -579,6 +579,89 @@ class EEGWindowsDataset(RecordDataset):
579
579
  self.metadata,
580
580
  )
581
581
 
582
+ def to_epochs_dataset(self) -> WindowsDataset:
583
+ """Converts this :class:`EEGWindowsDataset` to :class:`WindowsDataset` with ``mne.Epochs``.
584
+
585
+ In Braindecode, the data can either be stored as ``mne.io.Raw`` (in :class:`EEGWindowsDataset`)
586
+ or as ``mne.Epochs`` (in :class:`WindowsDataset`). This function converts from the first type to the second,
587
+ which can be useful for reducing disk space when you want to save a dataset.
588
+
589
+ Returns
590
+ -------
591
+ WindowsDataset
592
+ A new :class:`WindowsDataset` with ``mne.Epochs``.
593
+
594
+ Raises
595
+ ------
596
+ ValueError
597
+ If the dataset is not compatible with conversion. This includes:
598
+ - If targets are not obtained from metadata
599
+ - If windows have inconsistent sizes or there are no windows to convert
600
+ - If raw.first_samp!=0 (not supported for simplicity)
601
+ """
602
+ # Check the targets:
603
+ if self.targets_from != "metadata":
604
+ raise ValueError(
605
+ "to_epochs_dataset only works if targets are obtained from metadata."
606
+ )
607
+
608
+ # Check and get window sizes:
609
+ i_start_in_trial = self.crop_inds[:, 1]
610
+ i_stop_in_trial = self.crop_inds[:, 2]
611
+ sizes = np.unique(i_stop_in_trial - i_start_in_trial)
612
+ if len(sizes) > 1:
613
+ raise ValueError("Windows have inconsistent sizes.")
614
+ if len(sizes) != 1:
615
+ raise ValueError("No windows to convert.")
616
+ input_window_seconds = (sizes[0] - 1) / self.raw.info["sfreq"]
617
+
618
+ # Check raw.first_samp:
619
+ if self.raw.first_samp != 0:
620
+ raise ValueError(
621
+ f"to_epochs_dataset only works if raw.first_samp is 0, found {self.raw.first_samp=}"
622
+ )
623
+
624
+ # Create events and epochs:
625
+ events = np.zeros((len(self), 3), dtype=int)
626
+ events[:, 0] = i_start_in_trial
627
+ events[:, 2] = 1
628
+ epochs = mne.Epochs(
629
+ raw=self.raw,
630
+ events=events,
631
+ event_id={"window": 1},
632
+ tmin=0,
633
+ tmax=input_window_seconds,
634
+ metadata=self.metadata.copy(),
635
+ baseline=None,
636
+ )
637
+ # we skip dropping bads to be consistent with EEGWindowsDataset:
638
+ epochs._bad_dropped = True
639
+
640
+ # Populate new WindowsDataset:
641
+ windows = WindowsDataset(
642
+ epochs,
643
+ description=self.description,
644
+ transform=self.transform,
645
+ targets_from=self.targets_from,
646
+ last_target_only=self.last_target_only,
647
+ )
648
+
649
+ window_kwargs = list(getattr(self, "window_kwargs", []))
650
+ window_kwargs.append((self.to_epochs_dataset.__name__, {}))
651
+ setattr(windows, "window_kwargs", window_kwargs)
652
+ if hasattr(self, "raw_preproc_kwargs"):
653
+ setattr(
654
+ windows, "raw_preproc_kwargs", list(getattr(self, "raw_preproc_kwargs"))
655
+ )
656
+ if hasattr(self, "window_preproc_kwargs"):
657
+ setattr(
658
+ windows,
659
+ "window_preproc_kwargs",
660
+ list(getattr(self, "window_preproc_kwargs")),
661
+ )
662
+
663
+ return windows
664
+
582
665
 
583
666
  @register_dataset
584
667
  class WindowsDataset(RecordDataset):
@@ -617,6 +700,15 @@ class WindowsDataset(RecordDataset):
617
700
  last_target_only: bool = True,
618
701
  ):
619
702
  super().__init__(description, transform)
703
+ self._fast_disk = self._can_use_fast_get_epoch_from_raw(windows)
704
+ if not (self._fast_disk or windows.preload):
705
+ warnings.warn(
706
+ "The provided mne.Epochs object does not meet the requirements for "
707
+ "fast epoch access. This may lead to slow data loading from disk. "
708
+ "Consider preloading the epochs or checking the conditions in "
709
+ "WindowsDataset._can_use_fast_get_epoch_from_raw.",
710
+ UserWarning,
711
+ )
620
712
  self.windows = windows
621
713
  self.last_target_only = last_target_only
622
714
  if targets_from not in ("metadata", "channels"):
@@ -633,6 +725,20 @@ class WindowsDataset(RecordDataset):
633
725
  self.raw_preproc_kwargs: list[dict[str, Any]] = []
634
726
  self.window_preproc_kwargs: list[dict[str, Any]] = []
635
727
 
728
+ @staticmethod
729
+ def _can_use_fast_get_epoch_from_raw(epochs: mne.BaseEpochs) -> bool:
730
+ """Check if we can use the fast _get_epoch_from_raw method,
731
+ or if we need to use the slow get_data method."""
732
+ return (
733
+ not epochs.preload
734
+ and epochs._bad_dropped
735
+ and epochs.detrend is None
736
+ and not epochs._do_baseline # baseline is None
737
+ and (epochs._decim == 1)
738
+ and epochs._offset is None
739
+ and epochs._projector is None
740
+ )
741
+
636
742
  def __getitem__(self, index: int):
637
743
  """Get a window and its target.
638
744
 
@@ -650,7 +756,10 @@ class WindowsDataset(RecordDataset):
650
756
  np.ndarray
651
757
  Crop indices.
652
758
  """
653
- X = self.windows.get_data(item=index)[0].astype("float32")
759
+ if self._fast_disk:
760
+ X = self.windows._get_epoch_from_raw(index).astype("float32")
761
+ else:
762
+ X = self.windows.get_data(item=index)[0].astype("float32")
654
763
  if self.transform is not None:
655
764
  X = self.transform(X)
656
765
  if self.targets_from == "metadata":
@@ -706,7 +815,9 @@ class BaseConcatDataset(ConcatDataset, HubDatasetMixin, Generic[T]):
706
815
 
707
816
  def __init__(
708
817
  self,
709
- list_of_ds: list[T | BaseConcatDataset[T]],
818
+ list_of_ds: (
819
+ list[T] | list[BaseConcatDataset[T]] | list[T | BaseConcatDataset[T]]
820
+ ),
710
821
  target_transform: Callable | None = None,
711
822
  *,
712
823
  lazy: bool = False,
@@ -1283,3 +1394,40 @@ class BaseConcatDataset(ConcatDataset, HubDatasetMixin, Generic[T]):
1283
1394
 
1284
1395
  def _repr_html_(self):
1285
1396
  return self._build_repr().to_html()
1397
+
1398
+ def to_epochs_dataset(self) -> BaseConcatDataset[WindowsDataset]:
1399
+ """Converts this :class:`BaseConcatDataset` such that all datasets are :class:`WindowsDataset` with ``mne.Epochs``.
1400
+
1401
+ In Braindecode, the data can either be stored as ``mne.io.Raw`` (in :class:`EEGWindowsDataset`)
1402
+ or as ``mne.Epochs`` (in :class:`WindowsDataset`). This function converts all the underlying datasets to
1403
+ :class:`WindowsDataset` with ``mne.Epochs``.
1404
+ This can be useful for reducing disk space when you want to save a dataset.
1405
+
1406
+ Returns
1407
+ -------
1408
+ BaseConcatDataset[WindowsDataset]
1409
+ A new :class:`BaseConcatDataset` where all datasets are :class:`WindowsDataset` with ``mne.Epochs``.
1410
+
1411
+ Raises
1412
+ ------
1413
+ ValueError
1414
+ If any of the underlying datasets is a :class:`RawDataset` or any other type that is not
1415
+ :class:`EEGWindowsDataset` or :class:`WindowsDataset`, as they cannot be converted to epochs.
1416
+ """
1417
+ datasets = self.datasets
1418
+ if not all(
1419
+ isinstance(ds, (EEGWindowsDataset, WindowsDataset)) for ds in datasets
1420
+ ):
1421
+ raise ValueError(
1422
+ "All datasets must be EEGWindowsDataset or WindowsDataset to convert to WindowsDataset."
1423
+ )
1424
+ new_datasets: list[WindowsDataset] = []
1425
+ for ds in datasets:
1426
+ if isinstance(ds, EEGWindowsDataset):
1427
+ new_ds = ds.to_epochs_dataset()
1428
+ new_datasets.append(new_ds)
1429
+ elif isinstance(ds, WindowsDataset):
1430
+ new_datasets.append(ds)
1431
+ return BaseConcatDataset(
1432
+ new_datasets, target_transform=self.target_transform, lazy=self._lazy
1433
+ )
@@ -27,6 +27,7 @@ The format follows a BIDS-inspired sourcedata structure:
27
27
  #
28
28
  # License: BSD (3-clause)
29
29
 
30
+ import contextlib
30
31
  import json
31
32
  import logging
32
33
  import tempfile
@@ -69,6 +70,8 @@ huggingface_hub = _soft_import(
69
70
 
70
71
  log = logging.getLogger(__name__)
71
72
 
73
+ _LOCK_FILE = "format_info.json"
74
+
72
75
 
73
76
  class HubDatasetMixin:
74
77
  """
@@ -84,7 +87,6 @@ class HubDatasetMixin:
84
87
  >>> dataset = NMT(path=path, preload=True)
85
88
  >>> dataset.push_to_hub(
86
89
  ... repo_id="username/nmt-dataset",
87
- ... commit_message="Add NMT dataset"
88
90
  ... )
89
91
  >>>
90
92
  >>> # Load dataset from Hub
@@ -96,13 +98,14 @@ class HubDatasetMixin:
96
98
  def push_to_hub(
97
99
  self,
98
100
  repo_id: str,
99
- commit_message: Optional[str] = None,
100
101
  private: bool = False,
101
102
  token: Optional[str] = None,
102
- create_pr: bool = False,
103
103
  compression: str = "blosc",
104
104
  compression_level: int = 5,
105
105
  pipeline_name: str = "braindecode",
106
+ chunk_size: int = 5_000_000,
107
+ local_cache_dir: str | Path | None = None,
108
+ **kwargs,
106
109
  ) -> str:
107
110
  """
108
111
  Upload the dataset to the Hugging Face Hub in BIDS-like Zarr format.
@@ -116,20 +119,41 @@ class HubDatasetMixin:
116
119
  ----------
117
120
  repo_id : str
118
121
  Repository ID on the Hugging Face Hub (e.g., "username/dataset-name").
119
- commit_message : str | None
120
- Commit message. If None, a default message is generated.
121
122
  private : bool, default=False
122
123
  Whether to create a private repository.
123
124
  token : str | None
124
125
  Hugging Face API token. If None, uses cached token.
125
- create_pr : bool, default=False
126
- Whether to create a Pull Request instead of directly committing.
127
126
  compression : str, default="blosc"
128
127
  Compression algorithm for Zarr. Options: "blosc", "zstd", "gzip", None.
129
128
  compression_level : int, default=5
130
129
  Compression level (0-9). Level 5 provides optimal balance.
131
130
  pipeline_name : str, default="braindecode"
132
131
  Name of the processing pipeline for BIDS sourcedata.
132
+ chunk_size : int, default=5_000_000
133
+ Number of samples per chunk in Zarr along the time/window dimension.
134
+ Larger chunk sizes create fewer but larger chunks/files. This parameter
135
+ is used for both continuous data (e.g., RawDataset, EEGWindowsDataset)
136
+ and pre-cut windows (WindowsDataset). For WindowsDataset, multiple
137
+ windows may be stored in a single chunk depending on their duration
138
+ and the chosen ``chunk_size``.
139
+ local_cache_dir : str | Path | None
140
+ Local directory to use for temporary files during upload. If None, uses
141
+ the system temp directory and cleans it up after upload. If provided,
142
+ the directory is used as a persistent cache:
143
+
144
+ - If the directory is empty (or does not exist), the cache is built
145
+ there and a lock file (``format_info.json``) is written once
146
+ the cache is complete, before the upload starts. The file
147
+ contains the zarr conversion parameters as JSON.
148
+ - If the lock file is present and its JSON parameters match the
149
+ current call, cache creation is skipped and the upload resumes
150
+ directly (useful for retrying interrupted uploads).
151
+ - If the lock file is present but its JSON parameters differ from
152
+ the current call, a ``ValueError`` is raised.
153
+ - If the directory is non-empty but the lock file is absent, a
154
+ ``ValueError`` is raised listing the files found.
155
+ **kwargs
156
+ Additional arguments passed to huggingface_hub.upload_large_folder().
133
157
 
134
158
  Returns
135
159
  -------
@@ -149,7 +173,6 @@ class HubDatasetMixin:
149
173
  >>> # Upload with BIDS-like structure
150
174
  >>> url = dataset.push_to_hub(
151
175
  ... repo_id="myusername/nmt-dataset",
152
- ... commit_message="Upload NMT EEG dataset"
153
176
  ... )
154
177
  """
155
178
  if huggingface_hub is False or zarr is False:
@@ -159,13 +182,12 @@ class HubDatasetMixin:
159
182
  )
160
183
 
161
184
  # Create API instance
162
- _ = huggingface_hub.HfApi(token=token)
185
+ hf_api = huggingface_hub.HfApi(token=token)
163
186
 
164
187
  # Create repository if it doesn't exist
165
188
  try:
166
- huggingface_hub.create_repo(
189
+ hf_api.create_repo(
167
190
  repo_id=repo_id,
168
- token=token,
169
191
  private=private,
170
192
  repo_type="dataset",
171
193
  exist_ok=True,
@@ -173,74 +195,68 @@ class HubDatasetMixin:
173
195
  except Exception as e:
174
196
  raise RuntimeError(f"Failed to create repository: {e}")
175
197
 
176
- # Create a temporary directory for upload
177
- with tempfile.TemporaryDirectory() as tmpdir:
178
- tmp_path = Path(tmpdir)
179
-
180
- # Create BIDS-like sourcedata structure
181
- log.info("Creating BIDS-like sourcedata structure...")
182
- bids_layout = hub_format.BIDSSourcedataLayout(
183
- tmp_path, pipeline_name=pipeline_name
184
- )
185
- sourcedata_dir = bids_layout.create_structure()
186
-
187
- # Save dataset_description.json
188
- bids_layout.save_dataset_description()
189
-
190
- # Save participants.tsv
191
- descriptions = [ds.description for ds in self.datasets]
192
- bids_layout.save_participants(descriptions)
193
-
194
- # Save BIDS sidecar files for each recording
195
- self._save_bids_sidecar_files(bids_layout)
196
-
197
- # Convert dataset to Zarr format inside sourcedata
198
- log.info("Converting dataset to Zarr format...")
199
- dataset_path = sourcedata_dir / "dataset.zarr"
200
-
201
- self._convert_to_zarr_inline(
202
- dataset_path,
203
- compression,
204
- compression_level,
205
- )
206
-
207
- # Save dataset metadata (README.md)
208
- self._save_dataset_card(tmp_path)
209
-
210
- # Save format info
211
- format_info_path = tmp_path / "format_info.json"
212
- with open(format_info_path, "w", encoding="utf-8") as f:
213
- format_info = self._get_format_info_inline()
214
- json.dump(
215
- {
216
- "format": "zarr",
217
- "pipeline_name": pipeline_name,
218
- "compression": compression,
219
- "compression_level": compression_level,
220
- "braindecode_version": braindecode.__version__,
221
- **format_info,
222
- },
223
- f,
224
- indent=2,
225
- )
198
+ format_info = self._get_format_info_inline()
199
+ format_info_lock = {
200
+ "format": "zarr",
201
+ "pipeline_name": pipeline_name,
202
+ "compression": compression,
203
+ "compression_level": compression_level,
204
+ "chunk_size": chunk_size,
205
+ "braindecode_version": braindecode.__version__,
206
+ **format_info,
207
+ }
226
208
 
227
- # Default commit message
228
- if commit_message is None:
229
- commit_message = (
230
- f"Upload EEG dataset in BIDS-like "
231
- f"Zarr format ({len(self.datasets)} recordings)"
232
- )
209
+ # Determine upload directory and whether to build the cache
210
+ with contextlib.ExitStack() as stack:
211
+ if local_cache_dir is None:
212
+ tmpdir = stack.enter_context(tempfile.TemporaryDirectory())
213
+ tmp_path = Path(tmpdir)
214
+ build_cache = True
215
+ else:
216
+ tmp_path = Path(local_cache_dir)
217
+ lock_path = tmp_path / _LOCK_FILE
218
+ if lock_path.exists():
219
+ with open(lock_path, "r", encoding="utf-8") as _f:
220
+ _lock_params = json.load(_f)
221
+ if _lock_params != format_info_lock:
222
+ raise ValueError(
223
+ f"Lock file found at '{lock_path}' but its "
224
+ f"parameters {_lock_params} differ from the "
225
+ f"current call parameters {format_info_lock}. "
226
+ "Provide an empty directory or match the "
227
+ "original parameters."
228
+ )
229
+ log.info(
230
+ f"Lock file found at '{lock_path}', skipping cache "
231
+ "creation and resuming upload."
232
+ )
233
+ build_cache = False
234
+ else:
235
+ if tmp_path.exists():
236
+ existing = list(tmp_path.iterdir())
237
+ if existing:
238
+ entries = ", ".join(p.name for p in existing)
239
+ raise ValueError(
240
+ f"local_cache_dir '{tmp_path}' is not empty and "
241
+ f"has no lock file. Found: {entries}. Provide an "
242
+ "empty directory or one previously prepared by "
243
+ "push_to_hub()."
244
+ )
245
+ else:
246
+ tmp_path.mkdir(parents=True)
247
+ build_cache = True
248
+
249
+ if build_cache:
250
+ self._build_local_cache(tmp_path, format_info_lock)
233
251
 
234
252
  # Upload folder to Hub
235
253
  log.info(f"Uploading to Hugging Face Hub ({repo_id})...")
236
254
  try:
237
- url = huggingface_hub.upload_folder(
255
+ url = hf_api.upload_large_folder(
238
256
  repo_id=repo_id,
239
257
  folder_path=str(tmp_path),
240
258
  repo_type="dataset",
241
- commit_message=commit_message,
242
- token=token,
243
- create_pr=create_pr,
259
+ **kwargs,
244
260
  )
245
261
  log.info(f"Dataset uploaded successfully to {repo_id}")
246
262
  log.info(f"URL: https://huggingface.co/datasets/{repo_id}")
@@ -248,6 +264,55 @@ class HubDatasetMixin:
248
264
  except Exception as e:
249
265
  raise RuntimeError(f"Failed to upload dataset: {e}")
250
266
 
267
+ def _build_local_cache(
268
+ self,
269
+ tmp_path,
270
+ format_info_lock,
271
+ ):
272
+ """Build the local cache directory with the dataset in Zarr format and BIDS-like structure.
273
+ This folder will be uploaded to the Hub"""
274
+ compression = format_info_lock["compression"]
275
+ compression_level = format_info_lock["compression_level"]
276
+ pipeline_name = format_info_lock["pipeline_name"]
277
+ chunk_size = format_info_lock["chunk_size"]
278
+
279
+ # Create BIDS-like sourcedata structure
280
+ log.info("Creating BIDS-like sourcedata structure...")
281
+ bids_layout = hub_format.BIDSSourcedataLayout(
282
+ tmp_path, pipeline_name=pipeline_name
283
+ )
284
+ sourcedata_dir = bids_layout.create_structure()
285
+
286
+ # Save dataset_description.json
287
+ bids_layout.save_dataset_description()
288
+
289
+ # Save participants.tsv
290
+ descriptions = [ds.description for ds in self.datasets]
291
+ bids_layout.save_participants(descriptions)
292
+
293
+ # Save BIDS sidecar files for each recording
294
+ self._save_bids_sidecar_files(bids_layout)
295
+
296
+ # Convert dataset to Zarr format inside sourcedata
297
+ log.info("Converting dataset to Zarr format...")
298
+ dataset_path = sourcedata_dir / "dataset.zarr"
299
+
300
+ self._convert_to_zarr_inline(
301
+ dataset_path,
302
+ compression,
303
+ compression_level,
304
+ chunk_size,
305
+ )
306
+
307
+ # Save dataset metadata (README.md)
308
+ self._save_dataset_card(tmp_path)
309
+
310
+ # Save format info
311
+ # This marks the cache as complete
312
+ format_info_path = tmp_path / _LOCK_FILE
313
+ with open(format_info_path, "w", encoding="utf-8") as f:
314
+ json.dump(format_info_lock, f, indent=2)
315
+
251
316
  def _save_dataset_card(self, path: Path, bids_inspired: bool = True) -> None:
252
317
  """Generate and save a dataset card (README.md) with metadata.
253
318
 
@@ -465,7 +530,7 @@ class HubDatasetMixin:
465
530
  )
466
531
 
467
532
  # Load format info
468
- format_info_path = Path(dataset_dir) / "format_info.json"
533
+ format_info_path = Path(dataset_dir) / _LOCK_FILE
469
534
  if format_info_path.exists():
470
535
  with open(format_info_path, "r") as f:
471
536
  format_info = json.load(f)
@@ -595,6 +660,7 @@ class HubDatasetMixin:
595
660
  output_path: Path,
596
661
  compression: str,
597
662
  compression_level: int,
663
+ chunk_size: int = 5_000_000,
598
664
  ) -> None:
599
665
  """Convert dataset to Zarr format (inline implementation)."""
600
666
 
@@ -660,7 +726,14 @@ class HubDatasetMixin:
660
726
 
661
727
  # Save using inlined function
662
728
  _save_windows_to_zarr(
663
- grp, data, metadata, description, info_dict, compressor, target_name
729
+ grp,
730
+ data,
731
+ metadata,
732
+ description,
733
+ info_dict,
734
+ compressor,
735
+ target_name,
736
+ chunk_size,
664
737
  )
665
738
 
666
739
  elif dataset_type == "EEGWindowsDataset":
@@ -682,6 +755,7 @@ class HubDatasetMixin:
682
755
  targets_from,
683
756
  last_target_only,
684
757
  compressor,
758
+ chunk_size,
685
759
  )
686
760
 
687
761
  elif dataset_type == "RawDataset":
@@ -693,7 +767,13 @@ class HubDatasetMixin:
693
767
 
694
768
  # Save using inlined function
695
769
  _save_raw_to_zarr(
696
- grp, raw, description, info_dict, target_name, compressor
770
+ grp,
771
+ raw,
772
+ description,
773
+ info_dict,
774
+ target_name,
775
+ compressor,
776
+ chunk_size,
697
777
  )
698
778
 
699
779
  def _get_format_info_inline(self):
@@ -765,11 +845,16 @@ class HubDatasetMixin:
765
845
 
766
846
  # Convert to MNE objects and create dataset
767
847
  info = 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)
768
853
  events = np.column_stack(
769
854
  [
770
- metadata["i_start_in_trial"].values,
855
+ metadata["i_start_in_trial"].values.astype(int),
771
856
  np.zeros(len(metadata), dtype=int),
772
- metadata["target"].values,
857
+ event_ids,
773
858
  ]
774
859
  )
775
860
  epochs = mne.EpochsArray(data, info, events=events, metadata=metadata)
@@ -45,16 +45,25 @@ def _restore_nan_from_json(obj):
45
45
 
46
46
 
47
47
  def _save_windows_to_zarr(
48
- grp, data, metadata, description, info, compressor, target_name
48
+ grp, data, metadata, description, info, compressor, target_name, chunk_size
49
49
  ):
50
50
  """Save windowed data to Zarr group (low-level function)."""
51
51
  data_array = data.astype(np.float32)
52
52
  compressors_list = [compressor] if compressor is not None else None
53
53
 
54
+ max_windows_per_chunk = max(
55
+ 1, chunk_size // (data_array.shape[1] * data_array.shape[2])
56
+ )
57
+ n_windows_per_chunk = min(data_array.shape[0], max_windows_per_chunk)
58
+
54
59
  grp.create_array(
55
60
  "data",
56
61
  data=data_array,
57
- chunks=(1, data_array.shape[1], data_array.shape[2]),
62
+ chunks=(
63
+ n_windows_per_chunk,
64
+ data_array.shape[1],
65
+ data_array.shape[2],
66
+ ),
58
67
  compressors=compressors_list,
59
68
  )
60
69
 
@@ -70,17 +79,28 @@ def _save_windows_to_zarr(
70
79
 
71
80
 
72
81
  def _save_eegwindows_to_zarr(
73
- grp, raw, metadata, description, info, targets_from, last_target_only, compressor
82
+ grp,
83
+ raw,
84
+ metadata,
85
+ description,
86
+ info,
87
+ targets_from,
88
+ last_target_only,
89
+ compressor,
90
+ chunk_size,
74
91
  ):
75
92
  """Save EEG continuous raw data to Zarr group (low-level function)."""
76
93
  continuous_data = raw.get_data()
77
94
  continuous_float = continuous_data.astype(np.float32)
78
95
  compressors_list = [compressor] if compressor is not None else None
79
96
 
97
+ max_samples_per_chunk = max(1, chunk_size // continuous_float.shape[0])
98
+ n_samples_per_chunk = min(continuous_float.shape[1], max_samples_per_chunk)
99
+
80
100
  grp.create_array(
81
101
  "data",
82
102
  data=continuous_float,
83
- chunks=(continuous_float.shape[0], min(10000, continuous_float.shape[1])),
103
+ chunks=(continuous_float.shape[0], n_samples_per_chunk),
84
104
  compressors=compressors_list,
85
105
  )
86
106
 
@@ -143,16 +163,19 @@ def _load_eegwindows_from_zarr(grp, preload):
143
163
  return data, metadata, description, info_dict, targets_from, last_target_only
144
164
 
145
165
 
146
- def _save_raw_to_zarr(grp, raw, description, info, target_name, compressor):
166
+ def _save_raw_to_zarr(grp, raw, description, info, target_name, compressor, chunk_size):
147
167
  """Save RawDataset continuous raw data to Zarr group (low-level function)."""
148
168
  continuous_data = raw.get_data()
149
169
  continuous_float = continuous_data.astype(np.float32)
150
170
  compressors_list = [compressor] if compressor is not None else None
151
171
 
172
+ max_samples_per_chunk = max(1, chunk_size // continuous_float.shape[0])
173
+ n_samples_per_chunk = min(continuous_float.shape[1], max_samples_per_chunk)
174
+
152
175
  grp.create_array(
153
176
  "data",
154
177
  data=continuous_float,
155
- chunks=(continuous_float.shape[0], min(10000, continuous_float.shape[1])),
178
+ chunks=(continuous_float.shape[0], n_samples_per_chunk),
156
179
  compressors=compressors_list,
157
180
  )
158
181