braindecode 1.8.0.dev1122__tar.gz → 1.8.0.dev1128__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 (179) hide show
  1. {braindecode-1.8.0.dev1122/braindecode.egg-info → braindecode-1.8.0.dev1128}/PKG-INFO +1 -1
  2. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/bids/hub.py +90 -25
  3. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/bids/hub_io.py +67 -5
  4. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/base.py +40 -1
  5. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/samplers/base.py +40 -2
  6. braindecode-1.8.0.dev1128/braindecode/version.py +1 -0
  7. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128/braindecode.egg-info}/PKG-INFO +1 -1
  8. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/whats_new.rst +33 -0
  9. braindecode-1.8.0.dev1122/braindecode/version.py +0 -1
  10. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/LICENSE.txt +0 -0
  11. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/MANIFEST.in +0 -0
  12. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/NOTICE.txt +0 -0
  13. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/README.rst +0 -0
  14. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/__init__.py +0 -0
  15. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/augmentation/__init__.py +0 -0
  16. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/augmentation/base.py +0 -0
  17. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/augmentation/functional.py +0 -0
  18. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/augmentation/transforms.py +0 -0
  19. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/classifier.py +0 -0
  20. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/__init__.py +0 -0
  21. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/base.py +0 -0
  22. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/bbci.py +0 -0
  23. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/bcicomp.py +0 -0
  24. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/bids/__init__.py +0 -0
  25. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/bids/datasets.py +0 -0
  26. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/bids/format.py +0 -0
  27. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/bids/hub_format.py +0 -0
  28. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/bids/hub_validation.py +0 -0
  29. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/bids/iterable.py +0 -0
  30. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/chb_mit.py +0 -0
  31. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/collate.py +0 -0
  32. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/mne.py +0 -0
  33. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/moabb.py +0 -0
  34. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/nmt.py +0 -0
  35. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/registry.py +0 -0
  36. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/siena.py +0 -0
  37. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  38. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/sleep_physionet.py +0 -0
  39. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/tuh.py +0 -0
  40. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/utils.py +0 -0
  41. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datasets/xy.py +0 -0
  42. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datautil/__init__.py +0 -0
  43. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datautil/channel_utils.py +0 -0
  44. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datautil/hub_formats.py +0 -0
  45. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datautil/serialization.py +0 -0
  46. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/datautil/util.py +0 -0
  47. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/eegneuralnet.py +0 -0
  48. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/functional/__init__.py +0 -0
  49. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/functional/functions.py +0 -0
  50. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/functional/initialization.py +0 -0
  51. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/__init__.py +0 -0
  52. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/atcnet.py +0 -0
  53. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/attentionbasenet.py +0 -0
  54. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/attn_sleep.py +0 -0
  55. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/bendr.py +0 -0
  56. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/biot.py +0 -0
  57. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/brainmodule.py +0 -0
  58. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/cbramod.py +0 -0
  59. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/codebrain.py +0 -0
  60. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/config.py +0 -0
  61. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/contrawr.py +0 -0
  62. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/ctnet.py +0 -0
  63. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/dance.py +0 -0
  64. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/deep4.py +0 -0
  65. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/deepsleepnet.py +0 -0
  66. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/dgcnn.py +0 -0
  67. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/eegconformer.py +0 -0
  68. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/eegdino.py +0 -0
  69. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/eeginception_erp.py +0 -0
  70. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/eeginception_mi.py +0 -0
  71. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/eegitnet.py +0 -0
  72. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/eegminer.py +0 -0
  73. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/eegnet.py +0 -0
  74. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/eegnex.py +0 -0
  75. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/eegpt.py +0 -0
  76. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/eegsimpleconv.py +0 -0
  77. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/eegsym.py +0 -0
  78. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/eegtcnet.py +0 -0
  79. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/emg2qwerty.py +0 -0
  80. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/fbcnet.py +0 -0
  81. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/fblightconvnet.py +0 -0
  82. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/fbmsnet.py +0 -0
  83. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/hybrid.py +0 -0
  84. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/ifnet.py +0 -0
  85. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/interpolated.py +0 -0
  86. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/labram.py +0 -0
  87. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/luna.py +0 -0
  88. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/medformer.py +0 -0
  89. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/meta_neuromotor.py +0 -0
  90. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/msvtnet.py +0 -0
  91. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/mvpformer.py +0 -0
  92. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/patchedtransformer.py +0 -0
  93. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/reve.py +0 -0
  94. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/sccnet.py +0 -0
  95. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/shallow_fbcsp.py +0 -0
  96. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/signal_jepa.py +0 -0
  97. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/sinc_shallow.py +0 -0
  98. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  99. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  100. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/sparcnet.py +0 -0
  101. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/sstdpn.py +0 -0
  102. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/steegformer.py +0 -0
  103. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/summary.csv +0 -0
  104. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/syncnet.py +0 -0
  105. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/tcformer.py +0 -0
  106. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/tcn.py +0 -0
  107. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/tidnet.py +0 -0
  108. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/tsinception.py +0 -0
  109. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/usleep.py +0 -0
  110. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/util.py +0 -0
  111. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/models/zuna.py +0 -0
  112. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/__init__.py +0 -0
  113. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/activation.py +0 -0
  114. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/attention.py +0 -0
  115. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/blocks.py +0 -0
  116. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/convolution.py +0 -0
  117. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/dance_modules.py +0 -0
  118. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/filter.py +0 -0
  119. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/interpolation.py +0 -0
  120. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/layers.py +0 -0
  121. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/linear.py +0 -0
  122. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/parametrization.py +0 -0
  123. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/stats.py +0 -0
  124. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/util.py +0 -0
  125. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/modules/wrapper.py +0 -0
  126. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/preprocessing/__init__.py +0 -0
  127. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
  128. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/preprocessing/mne_preprocess.py +0 -0
  129. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/preprocessing/preprocess.py +0 -0
  130. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/preprocessing/util.py +0 -0
  131. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/preprocessing/windowers.py +0 -0
  132. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/regressor.py +0 -0
  133. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/samplers/__init__.py +0 -0
  134. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/samplers/ssl.py +0 -0
  135. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/training/__init__.py +0 -0
  136. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/training/callbacks.py +0 -0
  137. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/training/losses.py +0 -0
  138. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/training/scoring.py +0 -0
  139. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/util.py +0 -0
  140. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/visualization/__init__.py +0 -0
  141. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/visualization/attribution.py +0 -0
  142. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/visualization/confusion_matrices.py +0 -0
  143. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/visualization/frequency.py +0 -0
  144. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/visualization/metrics.py +0 -0
  145. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/visualization/sanity.py +0 -0
  146. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode/visualization/topology.py +0 -0
  147. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode.egg-info/SOURCES.txt +0 -0
  148. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode.egg-info/dependency_links.txt +0 -0
  149. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode.egg-info/requires.txt +0 -0
  150. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/braindecode.egg-info/top_level.txt +0 -0
  151. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/Makefile +0 -0
  152. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/_templates/autosummary/class.rst +0 -0
  153. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
  154. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/_templates/autosummary/function.rst +0 -0
  155. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
  156. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/api.rst +0 -0
  157. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/cite.rst +0 -0
  158. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/conf.py +0 -0
  159. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/help.rst +0 -0
  160. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/index.rst +0 -0
  161. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/install/install.rst +0 -0
  162. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/install/install_pip.rst +0 -0
  163. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/install/install_source.rst +0 -0
  164. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/models/categorization/attention.rst +0 -0
  165. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/models/categorization/channel.rst +0 -0
  166. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/models/categorization/convolution.rst +0 -0
  167. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/models/categorization/filterbank.rst +0 -0
  168. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/models/categorization/gnn.rst +0 -0
  169. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/models/categorization/interpretable.rst +0 -0
  170. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/models/categorization/lbm.rst +0 -0
  171. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/models/categorization/recurrent.rst +0 -0
  172. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/models/categorization/spd.rst +0 -0
  173. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/models/models.rst +0 -0
  174. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/models/models_categorization.rst +0 -0
  175. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/models/models_table.rst +0 -0
  176. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/models/models_visualization.rst +0 -0
  177. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/docs/sg_execution_times.rst +0 -0
  178. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/pyproject.toml +0 -0
  179. {braindecode-1.8.0.dev1122 → braindecode-1.8.0.dev1128}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.8.0.dev1122
3
+ Version: 1.8.0.dev1128
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>
@@ -28,6 +28,7 @@ The format follows a BIDS-inspired sourcedata structure:
28
28
  # License: BSD (3-clause)
29
29
 
30
30
  import contextlib
31
+ import copy
31
32
  import json
32
33
  import logging
33
34
  import tempfile
@@ -56,6 +57,7 @@ from .hub_io import (
56
57
  _load_eegwindows_from_zarr,
57
58
  _load_raw_from_zarr,
58
59
  _load_windows_from_zarr,
60
+ _prepare_info_for_json,
59
61
  _save_eegwindows_to_zarr,
60
62
  _save_raw_to_zarr,
61
63
  _save_windows_to_zarr,
@@ -72,6 +74,33 @@ log = logging.getLogger(__name__)
72
74
  _LOCK_FILE = "format_info.json"
73
75
 
74
76
 
77
+ def _normalize_kwargs_for_json(value, field_name):
78
+ """Return one preprocessing-kwargs value as native strict JSON."""
79
+
80
+ def _convert(obj):
81
+ if isinstance(obj, np.ndarray):
82
+ return _convert(obj.tolist())
83
+ if isinstance(obj, dict):
84
+ return {key: _convert(item) for key, item in obj.items()}
85
+ if isinstance(obj, (list, tuple)):
86
+ return [_convert(item) for item in obj]
87
+ if isinstance(obj, np.generic):
88
+ return _convert(obj.item())
89
+ return obj
90
+
91
+ try:
92
+ converted = _convert(value)
93
+ if isinstance(converted, str):
94
+ raise ValueError(
95
+ "a root string is ambiguous with the legacy encoded format"
96
+ )
97
+ return json.loads(json.dumps(converted, allow_nan=False))
98
+ except (OverflowError, RecursionError, TypeError, ValueError) as error:
99
+ raise ValueError(
100
+ f"{field_name} must contain only finite JSON-serializable values"
101
+ ) from error
102
+
103
+
75
104
  class HubDatasetMixin:
76
105
  """
77
106
  Mixin class for Hugging Face Hub integration with EEG datasets.
@@ -685,14 +714,57 @@ class HubDatasetMixin:
685
714
  f"{output_path} already exists. Set overwrite=True to replace it."
686
715
  )
687
716
 
688
- # Create zarr store (zarr v3 API)
689
- root = zarr.open(str(output_path), mode="w")
690
-
691
717
  # Validate uniformity across all datasets using shared validation
692
718
  dataset_type, _, _ = hub_validation.validate_dataset_uniformity(self.datasets)
693
719
 
694
- # Keep reference to first dataset for preprocessing kwargs
695
- first_ds = self.datasets[0]
720
+ # Normalize every JSON value before opening the output store. The cached
721
+ # values below are the exact values handed to the write helpers.
722
+ prepared_infos = []
723
+ for ds in self.datasets:
724
+ if dataset_type == "WindowsDataset":
725
+ info = ds.windows.info
726
+ elif dataset_type in ("EEGWindowsDataset", "RawDataset"):
727
+ info = ds.raw.info
728
+ prepared_infos.append(_prepare_info_for_json(info.to_json_dict()))
729
+
730
+ prepared_kwargs = {}
731
+ for kwarg_name in [
732
+ "raw_preproc_kwargs",
733
+ "window_kwargs",
734
+ "window_preproc_kwargs",
735
+ ]:
736
+ expected_present = hasattr(self.datasets[0], kwarg_name)
737
+ expected_value = None
738
+ expected_token = None
739
+ for i_ds, ds in enumerate(self.datasets):
740
+ present = hasattr(ds, kwarg_name)
741
+ if present != expected_present:
742
+ raise ValueError(
743
+ f"{kwarg_name} on dataset {i_ds} has inconsistent presence; "
744
+ "the Zarr format stores one global value"
745
+ )
746
+ if not present:
747
+ continue
748
+ value = _normalize_kwargs_for_json(
749
+ getattr(ds, kwarg_name), f"{kwarg_name} on dataset {i_ds}"
750
+ )
751
+ value_token = json.dumps(
752
+ value, sort_keys=True, separators=(",", ":"), allow_nan=False
753
+ )
754
+ if i_ds == 0:
755
+ expected_value = value
756
+ expected_token = value_token
757
+ elif value_token != expected_token:
758
+ raise ValueError(
759
+ f"{kwarg_name} on dataset {i_ds} differs from dataset 0; "
760
+ "the Zarr format stores one global value"
761
+ )
762
+ if expected_present:
763
+ prepared_kwargs[kwarg_name] = expected_value
764
+
765
+ # Create compressor and zarr store (zarr v3 API) only after preflight.
766
+ compressor = _create_compressor(compression, compression_level)
767
+ root = zarr.open(str(output_path), mode="w")
696
768
 
697
769
  # Store global metadata
698
770
  root.attrs["n_datasets"] = len(self.datasets)
@@ -706,21 +778,10 @@ class HubDatasetMixin:
706
778
  root.attrs["zarr_version"] = zarr.__version__
707
779
  root.attrs["scipy_version"] = scipy.__version__
708
780
 
709
- # Save preprocessing kwargs (check first dataset, assuming uniform preprocessing)
710
- # These are typically set by windowing functions on individual datasets
711
- for kwarg_name in [
712
- "raw_preproc_kwargs",
713
- "window_kwargs",
714
- "window_preproc_kwargs",
715
- ]:
716
- # Check first dataset for these attributes
717
- if hasattr(first_ds, kwarg_name):
718
- kwargs = getattr(first_ds, kwarg_name)
719
- if kwargs:
720
- root.attrs[kwarg_name] = json.dumps(kwargs)
721
-
722
- # Create compressor
723
- compressor = _create_compressor(compression, compression_level)
781
+ # Save preprocessing kwargs from the preflight cache. These are
782
+ # typically set by windowing functions on individual datasets.
783
+ for kwarg_name, kwargs in prepared_kwargs.items():
784
+ root.attrs[kwarg_name] = kwargs
724
785
 
725
786
  # Save each recording
726
787
  for i_ds, ds in enumerate(self.datasets):
@@ -731,7 +792,7 @@ class HubDatasetMixin:
731
792
  data = ds.windows.get_data()
732
793
  metadata = ds.windows.metadata
733
794
  description = ds.description
734
- info_dict = ds.windows.info.to_json_dict()
795
+ info_dict = prepared_infos[i_ds]
735
796
  target_name = ds.target_name if hasattr(ds, "target_name") else None
736
797
 
737
798
  # Save using inlined function
@@ -750,7 +811,7 @@ class HubDatasetMixin:
750
811
  raw = ds.raw
751
812
  metadata = ds.metadata
752
813
  description = ds.description
753
- info_dict = ds.raw.info.to_json_dict()
814
+ info_dict = prepared_infos[i_ds]
754
815
  targets_from = ds.targets_from
755
816
  last_target_only = ds.last_target_only
756
817
 
@@ -771,7 +832,7 @@ class HubDatasetMixin:
771
832
  # Get continuous raw data from RawDataset
772
833
  raw = ds.raw
773
834
  description = ds.description
774
- info_dict = ds.raw.info.to_json_dict()
835
+ info_dict = prepared_infos[i_ds]
775
836
  target_name = ds.target_name if hasattr(ds, "target_name") else None
776
837
 
777
838
  # Save using inlined function
@@ -956,10 +1017,14 @@ class HubDatasetMixin:
956
1017
  "window_preproc_kwargs",
957
1018
  ]:
958
1019
  if kwarg_name in root.attrs:
959
- kwargs = json.loads(root.attrs[kwarg_name])
1020
+ kwargs = root.attrs[kwarg_name]
1021
+ if isinstance(kwargs, str):
1022
+ # Stores written by older braindecode versions kept
1023
+ # these attributes as double-encoded JSON strings.
1024
+ kwargs = json.loads(kwargs)
960
1025
  # Set on each individual dataset (where they were originally stored)
961
1026
  for ds in datasets:
962
- setattr(ds, kwarg_name, kwargs)
1027
+ setattr(ds, kwarg_name, copy.deepcopy(kwargs))
963
1028
 
964
1029
  return concat_ds
965
1030
 
@@ -8,6 +8,7 @@ These functions keep the Zarr serialization details isolated from hub.py.
8
8
  from __future__ import annotations
9
9
 
10
10
  import json
11
+ from numbers import Real
11
12
  from pathlib import Path
12
13
 
13
14
  import numpy as np
@@ -17,17 +18,78 @@ from mne.utils import _soft_import
17
18
  zarr = _soft_import("zarr", purpose="hugging face integration", strict=False)
18
19
 
19
20
 
21
+ def _is_non_bool_real(value):
22
+ return not isinstance(value, (bool, np.bool_)) and isinstance(
23
+ value, (Real, np.integer, np.floating)
24
+ )
25
+
26
+
27
+ def _prepare_info_for_json(obj, path="info", *, _in_numeric_sequence=False):
28
+ """Normalize an MNE Info value to strict JSON without losing sequence NaNs."""
29
+ if isinstance(obj, np.ndarray):
30
+ obj = obj.tolist()
31
+
32
+ if isinstance(obj, dict):
33
+ return {
34
+ key: _prepare_info_for_json(value, f"{path}.{key}")
35
+ for key, value in obj.items()
36
+ }
37
+
38
+ if isinstance(obj, (list, tuple)):
39
+ values = list(obj)
40
+ has_none = any(value is None for value in values)
41
+ has_number = any(_is_non_bool_real(value) for value in values)
42
+ all_none = bool(values) and all(value is None for value in values)
43
+ if all_none or (has_none and has_number):
44
+ raise ValueError(
45
+ f"{path} is ambiguous: numeric sequences cannot contain JSON null"
46
+ )
47
+
48
+ is_numeric_sequence = bool(values) and all(
49
+ _is_non_bool_real(value) for value in values
50
+ )
51
+ return [
52
+ _prepare_info_for_json(
53
+ value,
54
+ f"{path}[{index}]",
55
+ _in_numeric_sequence=is_numeric_sequence,
56
+ )
57
+ for index, value in enumerate(values)
58
+ ]
59
+
60
+ if isinstance(obj, (bool, np.bool_)):
61
+ return bool(obj)
62
+ if isinstance(obj, (int, np.integer)):
63
+ return int(obj)
64
+ if _is_non_bool_real(obj):
65
+ value = float(obj)
66
+ if np.isnan(value):
67
+ if _in_numeric_sequence:
68
+ return None
69
+ raise ValueError(f"{path} contains unsupported NaN")
70
+ if np.isposinf(value):
71
+ raise ValueError(f"{path} contains positive infinity")
72
+ if np.isneginf(value):
73
+ raise ValueError(f"{path} contains negative infinity")
74
+ return value
75
+ if obj is None or isinstance(obj, str):
76
+ return obj
77
+ raise ValueError(f"{path} contains a non-JSON-serializable value")
78
+
79
+
20
80
  def _restore_nan_from_json(obj):
21
- """Restore NaN values from None in legacy zarr stores.
81
+ """Restore NaN values from None in JSON-loaded attributes.
22
82
 
23
- Datasets saved before zarr v3 native NaN support used
24
- ``_sanitize_for_json`` to convert NaN/Inf None. This restores them
25
- on load so ``mne.Info.from_json_dict`` gets proper NaN arrays.
83
+ JSON null is reserved for NaN only in non-boolean numeric sequences.
84
+ All-null lists are therefore the representation of validated all-NaN
85
+ sequences, while ordinary null values elsewhere remain unchanged.
26
86
  """
27
87
  if isinstance(obj, dict):
28
88
  return {k: _restore_nan_from_json(v) for k, v in obj.items()}
29
89
  if isinstance(obj, list):
30
- if len(obj) > 0 and all(isinstance(x, (int, float, type(None))) for x in obj):
90
+ if len(obj) > 0 and all(
91
+ value is None or _is_non_bool_real(value) for value in obj
92
+ ):
31
93
  return [np.nan if x is None else x for x in obj]
32
94
  return [_restore_nan_from_json(v) for v in obj]
33
95
  return obj
@@ -198,7 +198,34 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
198
198
  See :ref:`load-pretrained-models` for a complete tutorial.
199
199
  """
200
200
 
201
+ #: Attributes that :func:`torch.jit.script` must not introspect. The
202
+ #: signal-related properties raise :class:`ValueError` when their value was
203
+ #: neither given nor inferable, and ``mapping`` carries a postponed
204
+ #: annotation TorchScript cannot resolve. Either one aborts scripting
205
+ #: before ``forward`` is ever compiled.
206
+ __jit_ignored_attributes__ = [
207
+ *sorted(_EEG_PARAMS),
208
+ "_chs_info",
209
+ "input_shape",
210
+ "mapping",
211
+ ]
212
+ #: Rich MNE channel dictionaries are intentionally unavailable in scripted
213
+ #: forwards; they remain unchanged on eager models and in saved configs.
214
+ __jit_unused_properties__ = ["chs_info"]
215
+
201
216
  def __init_subclass__(cls, **kwargs):
217
+ # TorchScript only honours ``__jit_ignored_attributes__`` for
218
+ # properties defined directly on the concrete class: it collects them
219
+ # with ``vars(type(module))``, which skips inherited ones. Rebinding
220
+ # the very same property objects on each subclass makes them visible
221
+ # there without changing any runtime behaviour.
222
+ for name in cls.__jit_ignored_attributes__:
223
+ if name in cls.__dict__:
224
+ continue
225
+ prop = getattr(cls, name, None)
226
+ if isinstance(prop, property):
227
+ setattr(cls, name, prop)
228
+
202
229
  # Append model-specific Hub integration notes to the docstring.
203
230
  # This runs before the metaclass __init__, so the Hub notes will
204
231
  # be included in the docstring that the metaclass processes.
@@ -286,6 +313,12 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
286
313
  self._chs_info = chs_info # type: ignore[assignment]
287
314
  self._n_outputs = n_outputs # type: ignore[assignment]
288
315
  self._n_chans = n_chans # type: ignore[assignment]
316
+ # TorchScript cannot represent the rich MNE dictionaries in _chs_info.
317
+ # Keep the original eager state above and expose only the derived scalar
318
+ # to scripted signal-property getters.
319
+ self._n_chans_for_jit = (
320
+ len(chs_info) if n_chans is None and chs_info is not None else n_chans
321
+ )
289
322
  self._n_times = n_times # type: ignore[assignment]
290
323
  self._sfreq = sfreq # type: ignore[assignment]
291
324
 
@@ -310,6 +343,12 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
310
343
 
311
344
  @property
312
345
  def n_chans(self) -> int:
346
+ if torch.jit.is_scripting():
347
+ if self._n_chans_for_jit is None:
348
+ raise ValueError(
349
+ "n_chans could not be inferred. Either specify n_chans or chs_info."
350
+ )
351
+ return self._n_chans_for_jit
313
352
  if self._n_chans is None and self._chs_info is not None:
314
353
  return len(self._chs_info)
315
354
  elif self._n_chans is None:
@@ -319,7 +358,7 @@ class EEGModuleMixin(_BaseHubMixin, metaclass=_BraindecodeDocstringMeta):
319
358
  return self._n_chans
320
359
 
321
360
  @property
322
- def chs_info(self) -> list[str]:
361
+ def chs_info(self) -> list[dict]:
323
362
  if self._chs_info is None:
324
363
  raise ValueError("chs_info not specified.")
325
364
  return self._chs_info
@@ -5,6 +5,7 @@ Sampler classes.
5
5
  # Authors: Hubert Banville <hubert.jbanville@gmail.com>
6
6
  # Theo Gnassounou <>
7
7
  # Young Truong <dt.young112@gmail.com>
8
+ # Sarthak Tayal <sarthaktayal2@gmail.com>
8
9
  #
9
10
  # License: BSD (3-clause)
10
11
 
@@ -219,6 +220,9 @@ class DistributedRecordingSampler(DistributedSampler):
219
220
  class SequenceSampler(RecordingSampler):
220
221
  """Sample sequences of consecutive windows.
221
222
 
223
+ Recordings holding fewer than ``n_windows`` windows cannot contain a full
224
+ sequence and contribute none.
225
+
222
226
  Parameters
223
227
  ----------
224
228
  metadata : pd.DataFrame
@@ -227,7 +231,7 @@ class SequenceSampler(RecordingSampler):
227
231
  Number of consecutive windows in a sequence.
228
232
  n_windows_stride : int
229
233
  Number of windows between two consecutive sequences.
230
- random : bool
234
+ randomize : bool
231
235
  If True, sample sequences randomly. If False, sample sequences in
232
236
  order.
233
237
  random_state : np.random.RandomState | int | None
@@ -269,7 +273,10 @@ class SequenceSampler(RecordingSampler):
269
273
  .apply(lambda x: x[: end_offset : self.n_windows_stride])
270
274
  .values
271
275
  )
272
- file_ids = [[i] * len(inds) for i, inds in enumerate(start_inds)]
276
+ # a typed array keeps the ids integer when a recording yields no sequence
277
+ file_ids = [
278
+ np.full(len(inds), i, dtype=np.int64) for i, inds in enumerate(start_inds)
279
+ ]
273
280
  return np.concatenate(start_inds), np.concatenate(file_ids)
274
281
 
275
282
  def __len__(self):
@@ -296,6 +303,10 @@ class BalancedSequenceSampler(RecordingSampler):
296
303
  3. Sample a window of the corresponding class in the selected recording.
297
304
  4. Extract a sequence of windows around the sampled window.
298
305
 
306
+ Recordings holding fewer than ``n_windows`` windows cannot contain a full
307
+ sequence and are left out of step 1, as they are in
308
+ :class:`SequenceSampler`.
309
+
299
310
  Parameters
300
311
  ----------
301
312
  metadata : pd.DataFrame
@@ -322,6 +333,33 @@ class BalancedSequenceSampler(RecordingSampler):
322
333
  self.n_windows = n_windows
323
334
  self.n_sequences = n_sequences
324
335
  self.info_class = self._init_info(metadata, required_keys=["target"])
336
+ self.long_enough_recordings = self._find_long_enough_recordings()
337
+
338
+ def _find_long_enough_recordings(self):
339
+ """Return the indices of the recordings that can hold a full sequence.
340
+
341
+ Returns
342
+ -------
343
+ np.ndarray :
344
+ Array of recording indices holding at least ``n_windows`` windows.
345
+ """
346
+ n_windows_per_rec = self.info["index"].apply(len).to_numpy()
347
+ if n_windows_per_rec.size == 0:
348
+ raise ValueError("Cannot build sequences from empty metadata.")
349
+
350
+ long_enough = np.flatnonzero(n_windows_per_rec >= self.n_windows)
351
+ if len(long_enough) == 0:
352
+ raise ValueError(
353
+ f"No recording holds enough windows to build a sequence of "
354
+ f"{self.n_windows} windows. The longest recording has "
355
+ f"{n_windows_per_rec.max()} windows. Reduce n_windows to at "
356
+ f"most that value."
357
+ )
358
+ return long_enough
359
+
360
+ def sample_recording(self):
361
+ """Return a random recording index among the ones long enough."""
362
+ return self.rng.choice(self.long_enough_recordings)
325
363
 
326
364
  def sample_class(self, rec_ind=None):
327
365
  """Return a random class.
@@ -0,0 +1 @@
1
+ __version__ = "1.8.0.dev1128"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.8.0.dev1122
3
+ Version: 1.8.0.dev1128
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>
@@ -28,6 +28,14 @@ Current 1.8.0 (GitHub)
28
28
  Enhancements
29
29
  ============
30
30
 
31
+ - Models with TorchScript-compatible forward paths can now be passed straight
32
+ to :func:`torch.jit.script`, without first being rebuilt as a plain
33
+ :class:`torch.nn.Module`.
34
+ :class:`braindecode.models.base.EEGModuleMixin` hides its signal-related
35
+ properties and the ``mapping`` attribute from TorchScript introspection, so
36
+ scripting reaches ``forward`` instead of failing on the class attributes.
37
+ (:gh:`1115` by `Aditya Singh`_)
38
+
31
39
  - Add a transfer-learning tutorial illustrating the TUAB-to-NMT pathology
32
40
  workflow with offline synthetic recordings
33
41
  (:gh:`580` by `Mohammad Javad D`_ and `Bruno Aristimunha`_).
@@ -82,6 +90,29 @@ Bug fixes
82
90
  - Keep :class:`braindecode.preprocessing.EEGPrep` compatible with EEGPrep 0.3,
83
91
  which no longer exposes the ``eegprep.utils`` namespace used for sampling-rate
84
92
  validation (:gh:`1123` by `Bruno Aristimunha`_).
93
+ - Write strict JSON in Hub dataset stores while preserving NaNs in numeric MNE
94
+ ``Info`` sequences. Unsupported scalar NaNs and infinities are rejected
95
+ before store creation, and preprocessing kwargs are stored as native strict
96
+ JSON while legacy string values remain readable (:gh:`1128` by `Azra Bano`_).
97
+
98
+ - Leave recordings shorter than ``n_windows`` out of the draw in
99
+ :class:`braindecode.samplers.BalancedSequenceSampler` instead of failing on
100
+ them. Such a recording holds no valid sequence start, which made the sampling
101
+ range empty and raised ``ValueError: high <= 0`` on the first sequence that
102
+ landed there. :class:`braindecode.samplers.SequenceSampler` already skips
103
+ those recordings. A clear error now names the longest recording when none of
104
+ them can hold a sequence (:gh:`1125` by `Sarthak Tayal`_).
105
+
106
+ - Keep ``file_ids`` of :class:`braindecode.samplers.SequenceSampler` integer.
107
+ The ids were built from untyped lists, so an empty list coming from a
108
+ recording too short for a sequence turned the concatenated array into
109
+ ``float64``, against the documented dtype and unusable as an index
110
+ (:gh:`1125` by `Sarthak Tayal`_).
111
+
112
+ - Document the ``randomize`` parameter of
113
+ :class:`braindecode.samplers.SequenceSampler` under its own name. The
114
+ docstring described it as ``random``, which no signature accepts
115
+ (:gh:`1125` by `Sarthak Tayal`_).
85
116
 
86
117
  Code health
87
118
  ============
@@ -1593,3 +1624,5 @@ Authors
1593
1624
  .. _Fashad Ahmed: https://github.com/Fashad-Ahmed
1594
1625
  .. _Bhargav Kowshik: https://github.com/bkowshik
1595
1626
  .. _Jon Huml: https://github.com/jonathanhuml
1627
+ .. _Azra Bano: https://github.com/azrabano23
1628
+ .. _Aditya Singh: https://github.com/adityasingh2400
@@ -1 +0,0 @@
1
- __version__ = "1.8.0.dev1122"