Braindecode 1.3.2.dev182321725__tar.gz → 1.3.2.dev182822510__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 (161) hide show
  1. {braindecode-1.3.2.dev182321725/braindecode.egg-info → braindecode-1.3.2.dev182822510}/PKG-INFO +1 -1
  2. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/base.py +27 -1
  3. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/bids/hub.py +143 -73
  4. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/bids/hub_io.py +12 -4
  5. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/mne.py +48 -4
  6. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datautil/hub_formats.py +8 -1
  7. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/preprocessing/windowers.py +312 -78
  8. braindecode-1.3.2.dev182822510/braindecode/version.py +1 -0
  9. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/visualization/gradients.py +7 -7
  10. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510/braindecode.egg-info}/PKG-INFO +1 -1
  11. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/whats_new.rst +16 -1
  12. braindecode-1.3.2.dev182321725/braindecode/version.py +0 -1
  13. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/LICENSE.txt +0 -0
  14. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/MANIFEST.in +0 -0
  15. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/NOTICE.txt +0 -0
  16. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/README.rst +0 -0
  17. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/__init__.py +0 -0
  18. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/augmentation/__init__.py +0 -0
  19. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/augmentation/base.py +0 -0
  20. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/augmentation/functional.py +0 -0
  21. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/augmentation/transforms.py +0 -0
  22. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/classifier.py +0 -0
  23. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/__init__.py +0 -0
  24. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/bbci.py +0 -0
  25. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/bcicomp.py +0 -0
  26. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/bids/__init__.py +0 -0
  27. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/bids/datasets.py +0 -0
  28. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/bids/format.py +0 -0
  29. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/bids/hub_format.py +0 -0
  30. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/bids/hub_validation.py +0 -0
  31. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/bids/iterable.py +0 -0
  32. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/chb_mit.py +0 -0
  33. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/moabb.py +0 -0
  34. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/nmt.py +0 -0
  35. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/registry.py +0 -0
  36. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/siena.py +0 -0
  37. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  38. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/sleep_physionet.py +0 -0
  39. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/tuh.py +0 -0
  40. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/utils.py +0 -0
  41. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datasets/xy.py +0 -0
  42. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datautil/__init__.py +0 -0
  43. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datautil/channel_utils.py +0 -0
  44. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datautil/serialization.py +0 -0
  45. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/datautil/util.py +0 -0
  46. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/eegneuralnet.py +0 -0
  47. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/functional/__init__.py +0 -0
  48. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/functional/functions.py +0 -0
  49. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/functional/initialization.py +0 -0
  50. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/__init__.py +0 -0
  51. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/atcnet.py +0 -0
  52. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/attentionbasenet.py +0 -0
  53. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/attn_sleep.py +0 -0
  54. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/base.py +0 -0
  55. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/bendr.py +0 -0
  56. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/biot.py +0 -0
  57. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/brainmodule.py +0 -0
  58. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/cbramod.py +0 -0
  59. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/config.py +0 -0
  60. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/contrawr.py +0 -0
  61. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/ctnet.py +0 -0
  62. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/deep4.py +0 -0
  63. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/deepsleepnet.py +0 -0
  64. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/eegconformer.py +0 -0
  65. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/eeginception_erp.py +0 -0
  66. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/eeginception_mi.py +0 -0
  67. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/eegitnet.py +0 -0
  68. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/eegminer.py +0 -0
  69. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/eegnet.py +0 -0
  70. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/eegnex.py +0 -0
  71. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/eegpt.py +0 -0
  72. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/eegsimpleconv.py +0 -0
  73. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/eegsym.py +0 -0
  74. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/eegtcnet.py +0 -0
  75. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/fbcnet.py +0 -0
  76. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/fblightconvnet.py +0 -0
  77. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/fbmsnet.py +0 -0
  78. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/hybrid.py +0 -0
  79. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/ifnet.py +0 -0
  80. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/labram.py +0 -0
  81. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/luna.py +0 -0
  82. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/medformer.py +0 -0
  83. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/msvtnet.py +0 -0
  84. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/patchedtransformer.py +0 -0
  85. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/reve.py +0 -0
  86. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/sccnet.py +0 -0
  87. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/shallow_fbcsp.py +0 -0
  88. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/signal_jepa.py +0 -0
  89. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/sinc_shallow.py +0 -0
  90. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  91. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  92. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/sparcnet.py +0 -0
  93. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/sstdpn.py +0 -0
  94. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/summary.csv +0 -0
  95. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/syncnet.py +0 -0
  96. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/tcn.py +0 -0
  97. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/tidnet.py +0 -0
  98. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/tsinception.py +0 -0
  99. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/usleep.py +0 -0
  100. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/models/util.py +0 -0
  101. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/modules/__init__.py +0 -0
  102. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/modules/activation.py +0 -0
  103. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/modules/attention.py +0 -0
  104. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/modules/blocks.py +0 -0
  105. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/modules/convolution.py +0 -0
  106. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/modules/filter.py +0 -0
  107. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/modules/layers.py +0 -0
  108. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/modules/linear.py +0 -0
  109. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/modules/parametrization.py +0 -0
  110. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/modules/stats.py +0 -0
  111. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/modules/util.py +0 -0
  112. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/modules/wrapper.py +0 -0
  113. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/preprocessing/__init__.py +0 -0
  114. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
  115. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/preprocessing/mne_preprocess.py +0 -0
  116. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/preprocessing/preprocess.py +0 -0
  117. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/preprocessing/util.py +0 -0
  118. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/regressor.py +0 -0
  119. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/samplers/__init__.py +0 -0
  120. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/samplers/base.py +0 -0
  121. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/samplers/ssl.py +0 -0
  122. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/training/__init__.py +0 -0
  123. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/training/callbacks.py +0 -0
  124. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/training/losses.py +0 -0
  125. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/training/scoring.py +0 -0
  126. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/util.py +0 -0
  127. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/visualization/__init__.py +0 -0
  128. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode/visualization/confusion_matrices.py +0 -0
  129. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode.egg-info/SOURCES.txt +0 -0
  130. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode.egg-info/dependency_links.txt +0 -0
  131. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode.egg-info/requires.txt +0 -0
  132. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/braindecode.egg-info/top_level.txt +0 -0
  133. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/Makefile +0 -0
  134. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/_templates/autosummary/class.rst +0 -0
  135. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
  136. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/_templates/autosummary/function.rst +0 -0
  137. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
  138. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/api.rst +0 -0
  139. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/cite.rst +0 -0
  140. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/conf.py +0 -0
  141. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/help.rst +0 -0
  142. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/index.rst +0 -0
  143. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/install/install.rst +0 -0
  144. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/install/install_pip.rst +0 -0
  145. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/install/install_source.rst +0 -0
  146. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/models/categorization/attention.rst +0 -0
  147. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/models/categorization/channel.rst +0 -0
  148. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/models/categorization/convolution.rst +0 -0
  149. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/models/categorization/filterbank.rst +0 -0
  150. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/models/categorization/gnn.rst +0 -0
  151. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/models/categorization/interpretable.rst +0 -0
  152. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/models/categorization/lbm.rst +0 -0
  153. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/models/categorization/recurrent.rst +0 -0
  154. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/models/categorization/spd.rst +0 -0
  155. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/models/models.rst +0 -0
  156. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/models/models_categorization.rst +0 -0
  157. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/models/models_table.rst +0 -0
  158. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/models/models_visualization.rst +0 -0
  159. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/docs/sg_execution_times.rst +0 -0
  160. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/pyproject.toml +0 -0
  161. {braindecode-1.3.2.dev182321725 → braindecode-1.3.2.dev182822510}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.3.2.dev182321725
3
+ Version: 1.3.2.dev182822510
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>
@@ -617,6 +617,15 @@ class WindowsDataset(RecordDataset):
617
617
  last_target_only: bool = True,
618
618
  ):
619
619
  super().__init__(description, transform)
620
+ self._fast_disk = self._can_use_fast_get_epoch_from_raw(windows)
621
+ if not (self._fast_disk or windows.preload):
622
+ warnings.warn(
623
+ "The provided mne.Epochs object does not meet the requirements for "
624
+ "fast epoch access. This may lead to slow data loading from disk. "
625
+ "Consider preloading the epochs or checking the conditions in "
626
+ "WindowsDataset._can_use_fast_get_epoch_from_raw.",
627
+ UserWarning,
628
+ )
620
629
  self.windows = windows
621
630
  self.last_target_only = last_target_only
622
631
  if targets_from not in ("metadata", "channels"):
@@ -633,6 +642,20 @@ class WindowsDataset(RecordDataset):
633
642
  self.raw_preproc_kwargs: list[dict[str, Any]] = []
634
643
  self.window_preproc_kwargs: list[dict[str, Any]] = []
635
644
 
645
+ @staticmethod
646
+ def _can_use_fast_get_epoch_from_raw(epochs: mne.BaseEpochs) -> bool:
647
+ """Check if we can use the fast _get_epoch_from_raw method,
648
+ or if we need to use the slow get_data method."""
649
+ return (
650
+ not epochs.preload
651
+ and epochs._bad_dropped
652
+ and epochs.detrend is None
653
+ and not epochs._do_baseline # baseline is None
654
+ and (epochs._decim == 1)
655
+ and epochs._offset is None
656
+ and epochs._projector is None
657
+ )
658
+
636
659
  def __getitem__(self, index: int):
637
660
  """Get a window and its target.
638
661
 
@@ -650,7 +673,10 @@ class WindowsDataset(RecordDataset):
650
673
  np.ndarray
651
674
  Crop indices.
652
675
  """
653
- X = self.windows.get_data(item=index)[0].astype("float32")
676
+ if self._fast_disk:
677
+ X = self.windows._get_epoch_from_raw(index).astype("float32")
678
+ else:
679
+ X = self.windows.get_data(item=index)[0].astype("float32")
654
680
  if self.transform is not None:
655
681
  X = self.transform(X)
656
682
  if self.targets_from == "metadata":
@@ -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 = 10000,
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,38 @@ 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=10000
133
+ Number of samples per chunk in Zarr. Larger chunk size will create fewer
134
+ but larger files. Only used for RawDataset and EEGWindowsDataset (continuous data).
135
+ With WindowsDataset (pre-cut epochs), each window is saved as a separate chunk.
136
+ local_cache_dir : str | Path | None
137
+ Local directory to use for temporary files during upload. If None, uses
138
+ the system temp directory and cleans it up after upload. If provided,
139
+ the directory is used as a persistent cache:
140
+
141
+ - If the directory is empty (or does not exist), the cache is built
142
+ there and a lock file (``format_info.json``) is written once
143
+ the cache is complete, before the upload starts. The file
144
+ contains the zarr conversion parameters as JSON.
145
+ - If the lock file is present and its JSON parameters match the
146
+ current call, cache creation is skipped and the upload resumes
147
+ directly (useful for retrying interrupted uploads).
148
+ - If the lock file is present but its JSON parameters differ from
149
+ the current call, a ``ValueError`` is raised.
150
+ - If the directory is non-empty but the lock file is absent, a
151
+ ``ValueError`` is raised listing the files found.
152
+ **kwargs
153
+ Additional arguments passed to huggingface_hub.upload_large_folder().
133
154
 
134
155
  Returns
135
156
  -------
@@ -149,7 +170,6 @@ class HubDatasetMixin:
149
170
  >>> # Upload with BIDS-like structure
150
171
  >>> url = dataset.push_to_hub(
151
172
  ... repo_id="myusername/nmt-dataset",
152
- ... commit_message="Upload NMT EEG dataset"
153
173
  ... )
154
174
  """
155
175
  if huggingface_hub is False or zarr is False:
@@ -159,13 +179,12 @@ class HubDatasetMixin:
159
179
  )
160
180
 
161
181
  # Create API instance
162
- _ = huggingface_hub.HfApi(token=token)
182
+ hf_api = huggingface_hub.HfApi(token=token)
163
183
 
164
184
  # Create repository if it doesn't exist
165
185
  try:
166
- huggingface_hub.create_repo(
186
+ hf_api.create_repo(
167
187
  repo_id=repo_id,
168
- token=token,
169
188
  private=private,
170
189
  repo_type="dataset",
171
190
  exist_ok=True,
@@ -173,74 +192,68 @@ class HubDatasetMixin:
173
192
  except Exception as e:
174
193
  raise RuntimeError(f"Failed to create repository: {e}")
175
194
 
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
- )
195
+ format_info = self._get_format_info_inline()
196
+ format_info_lock = {
197
+ "format": "zarr",
198
+ "pipeline_name": pipeline_name,
199
+ "compression": compression,
200
+ "compression_level": compression_level,
201
+ "chunk_size": chunk_size,
202
+ "braindecode_version": braindecode.__version__,
203
+ **format_info,
204
+ }
226
205
 
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
- )
206
+ # Determine upload directory and whether to build the cache
207
+ with contextlib.ExitStack() as stack:
208
+ if local_cache_dir is None:
209
+ tmpdir = stack.enter_context(tempfile.TemporaryDirectory())
210
+ tmp_path = Path(tmpdir)
211
+ build_cache = True
212
+ else:
213
+ tmp_path = Path(local_cache_dir)
214
+ lock_path = tmp_path / _LOCK_FILE
215
+ if lock_path.exists():
216
+ with open(lock_path, "r", encoding="utf-8") as _f:
217
+ _lock_params = json.load(_f)
218
+ if _lock_params != format_info_lock:
219
+ raise ValueError(
220
+ f"Lock file found at '{lock_path}' but its "
221
+ f"parameters {_lock_params} differ from the "
222
+ f"current call parameters {format_info_lock}. "
223
+ "Provide an empty directory or match the "
224
+ "original parameters."
225
+ )
226
+ log.info(
227
+ f"Lock file found at '{lock_path}', skipping cache "
228
+ "creation and resuming upload."
229
+ )
230
+ build_cache = False
231
+ else:
232
+ if tmp_path.exists():
233
+ existing = list(tmp_path.iterdir())
234
+ if existing:
235
+ entries = ", ".join(p.name for p in existing)
236
+ raise ValueError(
237
+ f"local_cache_dir '{tmp_path}' is not empty and "
238
+ f"has no lock file. Found: {entries}. Provide an "
239
+ "empty directory or one previously prepared by "
240
+ "push_to_hub()."
241
+ )
242
+ else:
243
+ tmp_path.mkdir(parents=True)
244
+ build_cache = True
245
+
246
+ if build_cache:
247
+ self._build_local_cache(tmp_path, format_info_lock)
233
248
 
234
249
  # Upload folder to Hub
235
250
  log.info(f"Uploading to Hugging Face Hub ({repo_id})...")
236
251
  try:
237
- url = huggingface_hub.upload_folder(
252
+ url = hf_api.upload_large_folder(
238
253
  repo_id=repo_id,
239
254
  folder_path=str(tmp_path),
240
255
  repo_type="dataset",
241
- commit_message=commit_message,
242
- token=token,
243
- create_pr=create_pr,
256
+ **kwargs,
244
257
  )
245
258
  log.info(f"Dataset uploaded successfully to {repo_id}")
246
259
  log.info(f"URL: https://huggingface.co/datasets/{repo_id}")
@@ -248,6 +261,55 @@ class HubDatasetMixin:
248
261
  except Exception as e:
249
262
  raise RuntimeError(f"Failed to upload dataset: {e}")
250
263
 
264
+ def _build_local_cache(
265
+ self,
266
+ tmp_path,
267
+ format_info_lock,
268
+ ):
269
+ """Build the local cache directory with the dataset in Zarr format and BIDS-like structure.
270
+ This folder will be uploaded to the Hub"""
271
+ compression = format_info_lock["compression"]
272
+ compression_level = format_info_lock["compression_level"]
273
+ pipeline_name = format_info_lock["pipeline_name"]
274
+ chunk_size = format_info_lock["chunk_size"]
275
+
276
+ # Create BIDS-like sourcedata structure
277
+ log.info("Creating BIDS-like sourcedata structure...")
278
+ bids_layout = hub_format.BIDSSourcedataLayout(
279
+ tmp_path, pipeline_name=pipeline_name
280
+ )
281
+ sourcedata_dir = bids_layout.create_structure()
282
+
283
+ # Save dataset_description.json
284
+ bids_layout.save_dataset_description()
285
+
286
+ # Save participants.tsv
287
+ descriptions = [ds.description for ds in self.datasets]
288
+ bids_layout.save_participants(descriptions)
289
+
290
+ # Save BIDS sidecar files for each recording
291
+ self._save_bids_sidecar_files(bids_layout)
292
+
293
+ # Convert dataset to Zarr format inside sourcedata
294
+ log.info("Converting dataset to Zarr format...")
295
+ dataset_path = sourcedata_dir / "dataset.zarr"
296
+
297
+ self._convert_to_zarr_inline(
298
+ dataset_path,
299
+ compression,
300
+ compression_level,
301
+ chunk_size,
302
+ )
303
+
304
+ # Save dataset metadata (README.md)
305
+ self._save_dataset_card(tmp_path)
306
+
307
+ # Save format info
308
+ # This marks the cache as complete
309
+ format_info_path = tmp_path / _LOCK_FILE
310
+ with open(format_info_path, "w", encoding="utf-8") as f:
311
+ json.dump(format_info_lock, f, indent=2)
312
+
251
313
  def _save_dataset_card(self, path: Path, bids_inspired: bool = True) -> None:
252
314
  """Generate and save a dataset card (README.md) with metadata.
253
315
 
@@ -465,7 +527,7 @@ class HubDatasetMixin:
465
527
  )
466
528
 
467
529
  # Load format info
468
- format_info_path = Path(dataset_dir) / "format_info.json"
530
+ format_info_path = Path(dataset_dir) / _LOCK_FILE
469
531
  if format_info_path.exists():
470
532
  with open(format_info_path, "r") as f:
471
533
  format_info = json.load(f)
@@ -595,6 +657,7 @@ class HubDatasetMixin:
595
657
  output_path: Path,
596
658
  compression: str,
597
659
  compression_level: int,
660
+ chunk_size: int = 10000,
598
661
  ) -> None:
599
662
  """Convert dataset to Zarr format (inline implementation)."""
600
663
 
@@ -682,6 +745,7 @@ class HubDatasetMixin:
682
745
  targets_from,
683
746
  last_target_only,
684
747
  compressor,
748
+ chunk_size,
685
749
  )
686
750
 
687
751
  elif dataset_type == "RawDataset":
@@ -693,7 +757,13 @@ class HubDatasetMixin:
693
757
 
694
758
  # Save using inlined function
695
759
  _save_raw_to_zarr(
696
- grp, raw, description, info_dict, target_name, compressor
760
+ grp,
761
+ raw,
762
+ description,
763
+ info_dict,
764
+ target_name,
765
+ compressor,
766
+ chunk_size,
697
767
  )
698
768
 
699
769
  def _get_format_info_inline(self):
@@ -70,7 +70,15 @@ def _save_windows_to_zarr(
70
70
 
71
71
 
72
72
  def _save_eegwindows_to_zarr(
73
- grp, raw, metadata, description, info, targets_from, last_target_only, compressor
73
+ grp,
74
+ raw,
75
+ metadata,
76
+ description,
77
+ info,
78
+ targets_from,
79
+ last_target_only,
80
+ compressor,
81
+ chunk_size,
74
82
  ):
75
83
  """Save EEG continuous raw data to Zarr group (low-level function)."""
76
84
  continuous_data = raw.get_data()
@@ -80,7 +88,7 @@ def _save_eegwindows_to_zarr(
80
88
  grp.create_array(
81
89
  "data",
82
90
  data=continuous_float,
83
- chunks=(continuous_float.shape[0], min(10000, continuous_float.shape[1])),
91
+ chunks=(continuous_float.shape[0], min(chunk_size, continuous_float.shape[1])),
84
92
  compressors=compressors_list,
85
93
  )
86
94
 
@@ -143,7 +151,7 @@ def _load_eegwindows_from_zarr(grp, preload):
143
151
  return data, metadata, description, info_dict, targets_from, last_target_only
144
152
 
145
153
 
146
- def _save_raw_to_zarr(grp, raw, description, info, target_name, compressor):
154
+ def _save_raw_to_zarr(grp, raw, description, info, target_name, compressor, chunk_size):
147
155
  """Save RawDataset continuous raw data to Zarr group (low-level function)."""
148
156
  continuous_data = raw.get_data()
149
157
  continuous_float = continuous_data.astype(np.float32)
@@ -152,7 +160,7 @@ def _save_raw_to_zarr(grp, raw, description, info, target_name, compressor):
152
160
  grp.create_array(
153
161
  "data",
154
162
  data=continuous_float,
155
- chunks=(continuous_float.shape[0], min(10000, continuous_float.shape[1])),
163
+ chunks=(continuous_float.shape[0], min(chunk_size, continuous_float.shape[1])),
156
164
  compressors=compressors_list,
157
165
  )
158
166
 
@@ -100,6 +100,11 @@ def create_from_mne_epochs(
100
100
  window_size_samples: int,
101
101
  window_stride_samples: int,
102
102
  drop_last_window: bool,
103
+ descriptions: list[dict | pd.Series] | None = None,
104
+ mapping: dict[str | int, int] | None = None,
105
+ preload: bool = False,
106
+ picks: str | list | slice | None = None,
107
+ drop_bad_windows: bool = True,
103
108
  ) -> BaseConcatDataset:
104
109
  """Create WindowsDatasets from mne.Epochs.
105
110
 
@@ -114,6 +119,25 @@ def create_from_mne_epochs(
114
119
  drop_last_window : bool
115
120
  whether or not have a last overlapping window, when
116
121
  windows do not equally divide the continuous signal
122
+ descriptions : array-like | None
123
+ list of dicts or pandas.Series with additional information about
124
+ the epochs. If None, no description is added. Length must match
125
+ ``list_of_epochs``. Each description is applied to all windows
126
+ generated from the corresponding Epochs object.
127
+ mapping : dict(str | int: int) | None
128
+ Mapping from event description to target value. Keys can be
129
+ integers (matching ``epochs.events[:, 2]``) or their string
130
+ representations. If None, targets are set to the raw integer
131
+ event codes. If a mapping is provided and an event code is not
132
+ found in the mapping, the original event code is kept as-is.
133
+ preload : bool
134
+ if True, preload the data of the Epochs objects.
135
+ picks : str | list | slice | None
136
+ channels to include. If None, all available channels are used.
137
+ drop_bad_windows : bool
138
+ If True, call `.drop_bad()` on the resulting mne.Epochs object.
139
+ This allows identifying windows that fall outside of the valid
140
+ signal range. Defaults to True.
117
141
 
118
142
  Returns
119
143
  -------
@@ -126,8 +150,15 @@ def create_from_mne_epochs(
126
150
 
127
151
  _check_windowing_arguments(0, 0, window_size_samples, window_stride_samples)
128
152
 
153
+ if descriptions is not None:
154
+ if len(descriptions) != len(list_of_epochs):
155
+ raise ValueError(
156
+ f"length of 'list_of_epochs' ({len(list_of_epochs)}) and "
157
+ f"'descriptions' ({len(descriptions)}) has to match"
158
+ )
159
+
129
160
  list_of_windows_ds = []
130
- for epochs in list_of_epochs:
161
+ for i, epochs in enumerate(list_of_epochs):
131
162
  event_descriptions = epochs.events[:, 2]
132
163
  original_trial_starts = epochs.events[:, 0]
133
164
  stop = len(epochs.times) - window_size_samples
@@ -142,6 +173,15 @@ def create_from_mne_epochs(
142
173
  fake_events = [[start, window_size_samples, -1] for start in starts]
143
174
 
144
175
  for trial_i, trial in enumerate(epochs):
176
+ # resolve target using mapping if provided
177
+ event_code = event_descriptions[trial_i]
178
+ if mapping is not None:
179
+ target = mapping.get(
180
+ event_code, mapping.get(str(event_code), event_code)
181
+ )
182
+ else:
183
+ target = event_code
184
+
145
185
  metadata = pd.DataFrame(
146
186
  {
147
187
  "i_window_in_trial": np.arange(len(fake_events)),
@@ -149,7 +189,7 @@ def create_from_mne_epochs(
149
189
  "i_stop_in_trial": starts
150
190
  + original_trial_starts[trial_i]
151
191
  + window_size_samples,
152
- "target": len(fake_events) * [event_descriptions[trial_i]],
192
+ "target": len(fake_events) * [target],
153
193
  }
154
194
  )
155
195
  # window size - 1, since tmax is inclusive
@@ -160,11 +200,15 @@ def create_from_mne_epochs(
160
200
  tmin=0,
161
201
  tmax=(window_size_samples - 1) / epochs.info["sfreq"],
162
202
  metadata=metadata,
203
+ preload=preload,
204
+ picks=picks,
163
205
  )
164
206
 
165
- mne_epochs.drop_bad(reject=None, flat=None)
207
+ if drop_bad_windows:
208
+ mne_epochs.drop_bad(reject=None, flat=None)
166
209
 
167
- windows_ds = WindowsDataset(mne_epochs)
210
+ desc = descriptions[i] if descriptions is not None else None
211
+ windows_ds = WindowsDataset(mne_epochs, description=desc)
168
212
  list_of_windows_ds.append(windows_ds)
169
213
 
170
214
  return BaseConcatDataset(list_of_windows_ds)
@@ -36,6 +36,7 @@ def convert_to_zarr(
36
36
  output_path: Union[str, Path],
37
37
  compression: str = "blosc",
38
38
  compression_level: int = 5,
39
+ chunk_size: int = 10000,
39
40
  overwrite: bool = False,
40
41
  ) -> Path:
41
42
  """Convert BaseConcatDataset to Zarr format.
@@ -58,6 +59,10 @@ def convert_to_zarr(
58
59
  blosc uses zstd codec by default, providing best balance of speed and compression.
59
60
  compression_level : int, default=5
60
61
  Compression level (0-9). Level 5 provides optimal balance based on benchmarks.
62
+ chunk_size : int, default=10000
63
+ Number of samples per chunk in Zarr. Larger chunk size will create fewer
64
+ but larger files. Only used for RawDataset and EEGWindowsDataset (continuous data).
65
+ With WindowsDataset (pre-cut epochs), each window is saved as a separate chunk.
61
66
  overwrite : bool, default=False
62
67
  Whether to overwrite existing directory.
63
68
 
@@ -96,7 +101,9 @@ def convert_to_zarr(
96
101
  shutil.rmtree(output_path)
97
102
 
98
103
  # Delegate to HubDatasetMixin method
99
- dataset._convert_to_zarr_inline(output_path, compression, compression_level)
104
+ dataset._convert_to_zarr_inline(
105
+ output_path, compression, compression_level, chunk_size
106
+ )
100
107
 
101
108
  return output_path
102
109