Braindecode 1.8.1.dev183674431__tar.gz → 1.8.1.dev183849953__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 (192) hide show
  1. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/NOTICE.txt +0 -1
  2. {braindecode-1.8.1.dev183674431/braindecode.egg-info → braindecode-1.8.1.dev183849953}/PKG-INFO +1 -5
  3. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/classifier.py +2 -3
  4. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/tuh.py +1 -2
  5. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/functional/__init__.py +0 -2
  6. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/functional/functions.py +0 -18
  7. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/__init__.py +0 -2
  8. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/deep4.py +0 -1
  9. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/labram.py +30 -117
  10. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/luna.py +1 -3
  11. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/summary.csv +0 -1
  12. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/util.py +27 -149
  13. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/blocks.py +6 -57
  14. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/convolution.py +5 -15
  15. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/regressor.py +3 -35
  16. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/training/losses.py +2 -7
  17. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/training/scoring.py +4 -12
  18. braindecode-1.8.1.dev183849953/braindecode/version.py +1 -0
  19. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953/braindecode.egg-info}/PKG-INFO +1 -5
  20. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode.egg-info/SOURCES.txt +0 -2
  21. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode.egg-info/requires.txt +0 -5
  22. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/api.rst +0 -6
  23. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/conf.py +0 -7
  24. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/whats_new.rst +0 -73
  25. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/pyproject.toml +0 -3
  26. braindecode-1.8.1.dev183674431/braindecode/models/diver1.py +0 -945
  27. braindecode-1.8.1.dev183674431/braindecode/version.py +0 -1
  28. braindecode-1.8.1.dev183674431/docs/agent_docs.rst +0 -60
  29. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/LICENSE.txt +0 -0
  30. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/MANIFEST.in +0 -0
  31. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/README.rst +0 -0
  32. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/__init__.py +0 -0
  33. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/augmentation/__init__.py +0 -0
  34. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/augmentation/base.py +0 -0
  35. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/augmentation/functional.py +0 -0
  36. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/augmentation/transforms.py +0 -0
  37. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/__init__.py +0 -0
  38. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/_notebook_viewer.py +0 -0
  39. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/base.py +0 -0
  40. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bbci.py +0 -0
  41. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bcicomp.py +0 -0
  42. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/__init__.py +0 -0
  43. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/datasets.py +0 -0
  44. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/format.py +0 -0
  45. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/hub.py +0 -0
  46. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/hub_format.py +0 -0
  47. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/hub_io.py +0 -0
  48. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/hub_validation.py +0 -0
  49. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/bids/iterable.py +0 -0
  50. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/chb_mit.py +0 -0
  51. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/collate.py +0 -0
  52. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/mne.py +0 -0
  53. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/moabb.py +0 -0
  54. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/nmt.py +0 -0
  55. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/registry.py +0 -0
  56. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/siena.py +0 -0
  57. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/sleep_physio_challe_18.py +0 -0
  58. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/sleep_physionet.py +0 -0
  59. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/utils.py +0 -0
  60. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datasets/xy.py +0 -0
  61. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datautil/__init__.py +0 -0
  62. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datautil/channel_utils.py +0 -0
  63. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datautil/hub_formats.py +0 -0
  64. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datautil/serialization.py +0 -0
  65. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/datautil/util.py +0 -0
  66. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/eegneuralnet.py +0 -0
  67. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/functional/_real_dft.py +0 -0
  68. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/functional/initialization.py +0 -0
  69. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/atcnet.py +0 -0
  70. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/attentionbasenet.py +0 -0
  71. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/attn_sleep.py +0 -0
  72. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/barista.py +0 -0
  73. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/base.py +0 -0
  74. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/bendr.py +0 -0
  75. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/biot.py +0 -0
  76. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/brainbert.py +0 -0
  77. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/brainmodule.py +0 -0
  78. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/brant.py +0 -0
  79. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/cbramod.py +0 -0
  80. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/codebrain.py +0 -0
  81. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/config.py +0 -0
  82. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/contrawr.py +0 -0
  83. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/ctnet.py +0 -0
  84. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/dance.py +0 -0
  85. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/deepsleepnet.py +0 -0
  86. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/dgcnn.py +0 -0
  87. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegconformer.py +0 -0
  88. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegdino.py +0 -0
  89. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eeginception_erp.py +0 -0
  90. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eeginception_mi.py +0 -0
  91. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegitnet.py +0 -0
  92. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegminer.py +0 -0
  93. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegnet.py +0 -0
  94. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegnex.py +0 -0
  95. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegpt.py +0 -0
  96. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegsimpleconv.py +0 -0
  97. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegsym.py +0 -0
  98. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/eegtcnet.py +0 -0
  99. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/emg2qwerty.py +0 -0
  100. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/fbcnet.py +0 -0
  101. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/fblightconvnet.py +0 -0
  102. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/fbmsnet.py +0 -0
  103. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/hybrid.py +0 -0
  104. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/ifnet.py +0 -0
  105. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/interpolated.py +0 -0
  106. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/medformer.py +0 -0
  107. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/meta_neuromotor.py +0 -0
  108. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/mirepnet.py +0 -0
  109. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/mscformer.py +0 -0
  110. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/msvtnet.py +0 -0
  111. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/mvpformer.py +0 -0
  112. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/neuropose.py +0 -0
  113. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/patchedtransformer.py +0 -0
  114. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/reve.py +0 -0
  115. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sccnet.py +0 -0
  116. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sensingdynamics.py +0 -0
  117. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/shallow_fbcsp.py +0 -0
  118. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/signal_jepa.py +0 -0
  119. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sinc_shallow.py +0 -0
  120. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sleep_stager_blanco_2020.py +0 -0
  121. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sleep_stager_chambon_2018.py +0 -0
  122. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sparcnet.py +0 -0
  123. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/sstdpn.py +0 -0
  124. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/steegformer.py +0 -0
  125. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/syncnet.py +0 -0
  126. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/tcformer.py +0 -0
  127. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/tcn.py +0 -0
  128. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/tidnet.py +0 -0
  129. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/tsinception.py +0 -0
  130. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/usleep.py +0 -0
  131. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/vemg2pose.py +0 -0
  132. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/models/zuna.py +0 -0
  133. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/__init__.py +0 -0
  134. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/activation.py +0 -0
  135. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/attention.py +0 -0
  136. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/dance_modules.py +0 -0
  137. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/filter.py +0 -0
  138. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/interpolation.py +0 -0
  139. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/layers.py +0 -0
  140. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/linear.py +0 -0
  141. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/parametrization.py +0 -0
  142. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/stats.py +0 -0
  143. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/util.py +0 -0
  144. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/modules/wrapper.py +0 -0
  145. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/preprocessing/__init__.py +0 -0
  146. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/preprocessing/eegprep_preprocess.py +0 -0
  147. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/preprocessing/mne_preprocess.py +0 -0
  148. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/preprocessing/preprocess.py +0 -0
  149. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/preprocessing/util.py +0 -0
  150. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/preprocessing/windowers.py +0 -0
  151. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/samplers/__init__.py +0 -0
  152. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/samplers/base.py +0 -0
  153. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/samplers/ssl.py +0 -0
  154. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/training/__init__.py +0 -0
  155. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/training/callbacks.py +0 -0
  156. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/util.py +0 -0
  157. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/__init__.py +0 -0
  158. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/activations.py +0 -0
  159. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/attribution.py +0 -0
  160. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/confusion_matrices.py +0 -0
  161. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/frequency.py +0 -0
  162. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/metrics.py +0 -0
  163. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/sanity.py +0 -0
  164. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode/visualization/topology.py +0 -0
  165. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode.egg-info/dependency_links.txt +0 -0
  166. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/braindecode.egg-info/top_level.txt +0 -0
  167. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/Makefile +0 -0
  168. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/_templates/autosummary/class.rst +0 -0
  169. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/_templates/autosummary/class_in_subdir.rst +0 -0
  170. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/_templates/autosummary/function.rst +0 -0
  171. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/_templates/autosummary/function_in_subdir.rst +0 -0
  172. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/cite.rst +0 -0
  173. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/help.rst +0 -0
  174. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/index.rst +0 -0
  175. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/install/install.rst +0 -0
  176. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/install/install_pip.rst +0 -0
  177. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/install/install_source.rst +0 -0
  178. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/attention.rst +0 -0
  179. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/channel.rst +0 -0
  180. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/convolution.rst +0 -0
  181. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/filterbank.rst +0 -0
  182. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/gnn.rst +0 -0
  183. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/interpretable.rst +0 -0
  184. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/lbm.rst +0 -0
  185. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/recurrent.rst +0 -0
  186. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/categorization/spd.rst +0 -0
  187. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/models.rst +0 -0
  188. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/models_categorization.rst +0 -0
  189. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/models_table.rst +0 -0
  190. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/models/models_visualization.rst +0 -0
  191. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/docs/sg_execution_times.rst +0 -0
  192. {braindecode-1.8.1.dev183674431 → braindecode-1.8.1.dev183849953}/setup.cfg +0 -0
@@ -52,7 +52,6 @@ The following components are licensed under the Apache License 2.0:
52
52
  - `braindecode/models/zuna.py`
53
53
  - `braindecode/models/luna.py`
54
54
  - `braindecode/models/brant.py`
55
- - `braindecode/models/diver1.py`
56
55
  - `braindecode/models/mscformer.py`
57
56
 
58
57
  ### USC Academic License Files
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braindecode
3
- Version: 1.8.1.dev183674431
3
+ Version: 1.8.1.dev183849953
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>
@@ -44,8 +44,6 @@ Requires-Dist: huggingface_hub[torch]>=0.20.0; extra == "hub"
44
44
  Requires-Dist: zarr>=3.0; extra == "hub"
45
45
  Provides-Extra: viz
46
46
  Requires-Dist: captum>=0.7.0; extra == "viz"
47
- Provides-Extra: sae
48
- Requires-Dist: sae-lens==6.51.3; extra == "sae"
49
47
  Provides-Extra: tests
50
48
  Requires-Dist: pytest<9.1; extra == "tests"
51
49
  Requires-Dist: pytest-cov; extra == "tests"
@@ -60,8 +58,6 @@ Provides-Extra: typing
60
58
  Requires-Dist: exca>=0.5.10; extra == "typing"
61
59
  Requires-Dist: numpydantic>=1.7; extra == "typing"
62
60
  Provides-Extra: docs
63
- Requires-Dist: pytest<9.1; extra == "docs"
64
- Requires-Dist: sphinx-markdown-builder==0.6.11; extra == "docs"
65
61
  Requires-Dist: sphinx_gallery>=0.17; extra == "docs"
66
62
  Requires-Dist: sphinx_rtd_theme; extra == "docs"
67
63
  Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
@@ -207,11 +207,10 @@ class EEGClassifier(_EEGNeuralNet, NeuralNetClassifier):
207
207
 
208
208
  Returns
209
209
  -------
210
- trial_predictions : np.ndarray | list of np.ndarray
210
+ trial_predictions : np.ndarray
211
211
  3-dimensional array (n_trials x n_classes x n_predictions), where
212
212
  the number of predictions depend on the chosen window size and the
213
- receptive field of the network. If trials have different lengths,
214
- a list with one (n_classes x n_predictions) array per trial.
213
+ receptive field of the network.
215
214
  trial_targets : np.ndarray
216
215
  Ground-truth targets from the dataset in a 2-dimensional array
217
216
  (n_trials x n_targets). Only returned when ``return_targets=True``.
@@ -815,8 +815,7 @@ def _get_header(*args, **kwargs):
815
815
  for paths_dict in [_TUH_EEG_PATHS, _TUH_EEG_ABNORMAL_PATHS, _TUH_EEG_EVENTS_PATHS]:
816
816
  for version_dict in paths_dict.values():
817
817
  all_paths.update(version_dict)
818
- # Mock keys use POSIX separators; pathlib emits backslashes on Windows.
819
- return all_paths[os.fspath(args[0]).replace("\\", "/")]
818
+ return all_paths[args[0]]
820
819
 
821
820
 
822
821
  _TUH_EEG_PATHS = {
@@ -8,7 +8,6 @@ from .functions import (
8
8
  iou_1d,
9
9
  pairwise_iou_1d,
10
10
  plv_time,
11
- rotate_pairs,
12
11
  safe_log,
13
12
  sinusoidal_positional_encoding,
14
13
  square,
@@ -26,7 +25,6 @@ __all__ = [
26
25
  "iou_1d",
27
26
  "pairwise_iou_1d",
28
27
  "plv_time",
29
- "rotate_pairs",
30
28
  "safe_log",
31
29
  "sinusoidal_positional_encoding",
32
30
  "square",
@@ -470,21 +470,3 @@ def sinusoidal_positional_encoding(n_positions: int, dim: int) -> torch.Tensor:
470
470
  # ``.contiguous()`` so an odd-``dim`` truncation owns tight storage -- a
471
471
  # non-contiguous view over the padded width breaks safetensors buffer saving.
472
472
  return pe[:, :dim].contiguous()
473
-
474
-
475
- def rotate_pairs(x: torch.Tensor) -> torch.Tensor:
476
- """Rotate adjacent feature pairs from ``(a, b)`` to ``(-b, a)``.
477
-
478
- Parameters
479
- ----------
480
- x : torch.Tensor
481
- Tensor of shape ``(..., features)`` with an even final dimension.
482
-
483
- Returns
484
- -------
485
- torch.Tensor
486
- Same shape, device and dtype as ``x``. Frequencies, positional indexing
487
- and mixed-precision policy are left to the caller.
488
- """
489
- pairs = x.unflatten(-1, (-1, 2))
490
- return torch.stack((-pairs[..., 1], pairs[..., 0]), dim=-1).flatten(-2)
@@ -18,7 +18,6 @@ from .dance import DANCE
18
18
  from .deep4 import Deep4Net
19
19
  from .deepsleepnet import DeepSleepNet
20
20
  from .dgcnn import DGCNN
21
- from .diver1 import DIVER1
22
21
  from .eegconformer import EEGConformer
23
22
  from .eegdino import EEGDINO
24
23
  from .eeginception_erp import EEGInceptionERP
@@ -102,7 +101,6 @@ __all__ = [
102
101
  "DANCE",
103
102
  "Deep4Net",
104
103
  "DeepSleepNet",
105
- "DIVER1",
106
104
  "BrainModule",
107
105
  "Brant",
108
106
  "EEGConformer",
@@ -215,7 +215,6 @@ class Deep4Net(EEGModuleMixin, nn.Sequential):
215
215
  filter_time_length=filter_time_length,
216
216
  bias_time=True,
217
217
  bias_spat=not self.batch_norm,
218
- stride=(conv_stride, 1),
219
218
  ),
220
219
  )
221
220
  n_filters_conv = self.n_filters_spat
@@ -191,11 +191,6 @@ _LABRAM_TARGET_CHS_INFO = [
191
191
  for ch, loc in _LABRAM_TARGET_CHS_TUPLES
192
192
  ]
193
193
  LABRAM_CHANNEL_ORDER = [ch for ch, _ in _LABRAM_TARGET_CHS_TUPLES]
194
-
195
- #: Absolute time slots of the original LaBraM (``time_embed`` in its
196
- #: ``modeling_finetune.py``), whatever the window length. A window of P patches
197
- #: uses slots 0..P-1, and the released weights hold all 16 of them.
198
- _LABRAM_N_TIME_SLOTS = 16
199
194
  _LABRAM_CANONICAL_INDEX = {n.upper(): i for i, n in enumerate(LABRAM_CHANNEL_ORDER)}
200
195
 
201
196
 
@@ -324,13 +319,7 @@ class Labram(EEGModuleMixin, nn.Module):
324
319
  use_abs_pos_emb : bool (default=True)
325
320
  If True, use absolute position embedding.
326
321
  use_mean_pooling : bool (default=True)
327
- If True, the readout is ``fc_norm`` applied to the mean of the patch
328
- tokens, as in the original fine-tuning. If False, the readout is the
329
- [CLS] token after the final ``norm``; the original pretraining loss
330
- never uses the [CLS] output. A pretraining checkpoint (with ``norm``
331
- and without ``fc_norm`` or head, such as the released weights) loads
332
- into a mean-pooling model as in the original fine-tuning script:
333
- ``norm`` is unused and ``fc_norm`` keeps its initialization.
322
+ If True, use mean pooling.
334
323
  init_scale : float (default=0.001)
335
324
  The initial scale to be used in the parameters of the model.
336
325
  neural_tokenizer : bool (default=True)
@@ -382,7 +371,7 @@ class Labram(EEGModuleMixin, nn.Module):
382
371
  norm_layer: type[nn.Module] = nn.LayerNorm,
383
372
  init_values=0.1,
384
373
  use_abs_pos_emb=True,
385
- use_mean_pooling=True,
374
+ use_mean_pooling=False,
386
375
  init_scale=0.001,
387
376
  neural_tokenizer=True,
388
377
  attn_head_dim=None,
@@ -509,15 +498,8 @@ class Labram(EEGModuleMixin, nn.Module):
509
498
  else:
510
499
  self.position_embedding = None
511
500
 
512
- # The tokenizer keeps the original's absolute time slots, so the
513
- # pretrained slots load at every window length; longer windows get
514
- # extra slots. The decoder mode keeps one slot per patch plus one.
515
- n_patches = self.patch_embed[0].n_patchs
516
- n_time_slots = (
517
- max(_LABRAM_N_TIME_SLOTS, n_patches) if neural_tokenizer else n_patches + 1
518
- )
519
501
  self.temporal_embedding = nn.Parameter(
520
- torch.zeros(1, n_time_slots, self.embed_dim),
502
+ torch.zeros(1, self.patch_embed[0].n_patchs + 1, self.embed_dim),
521
503
  requires_grad=True,
522
504
  )
523
505
  self.pos_drop = nn.Dropout(p=drop_prob)
@@ -656,11 +638,10 @@ class Labram(EEGModuleMixin, nn.Module):
656
638
  temporal = self.embed_dim
657
639
  else:
658
640
  # For neural decoder: input is (batch, n_chans, n_times)
659
- # patch_embed returns one token per temporal patch:
660
- # (batch, n_patches_per_channel, emb_dim)
641
+ # patch_embed returns (batch, n_patchs, emb_dim)
661
642
  x = self.patch_embed(x)
662
- # x shape: (batch, n_patches_per_channel, emb_dim)
663
- batch_size, n_patches_per_channel, temporal = x.shape
643
+ # x shape: (batch, n_patchs, emb_dim)
644
+ batch_size, n_patch, temporal = x.shape
664
645
 
665
646
  # add the [CLS] token to the embedded patch tokens
666
647
  cls_tokens = self.cls_token.expand(batch_size, -1, -1)
@@ -678,13 +659,10 @@ class Labram(EEGModuleMixin, nn.Module):
678
659
  pos_embed_used=pos_embed_used, batch_size=batch_size
679
660
  )
680
661
  else:
681
- # In decoder mode, patch_embed already averages over the grouped
682
- # channel dimension, so the token axis only indexes temporal
683
- # patches.
684
- n_pos = min(
685
- self.position_embedding.shape[1],
686
- n_patches_per_channel + 1,
687
- )
662
+ # In decoder mode, we have different number of patches
663
+ # Adapt position embedding for n_patch patches
664
+ # Use the first n_patch+1 positions from position_embedding
665
+ n_pos = min(self.position_embedding.shape[1], n_patch + 1)
688
666
  pos_embed_used = self.position_embedding[:, :n_pos, :]
689
667
  pos_embed = pos_embed_used.expand(batch_size, -1, -1)
690
668
 
@@ -694,26 +672,23 @@ class Labram(EEGModuleMixin, nn.Module):
694
672
  if self.neural_tokenizer:
695
673
  num_ch = n_input_chans # Use actual input channels
696
674
  time_embed = self._adj_temporal_embedding(
697
- num_ch=num_ch,
698
- batch_size=batch_size,
699
- n_patches=self.patch_embed[0].n_patchs,
675
+ num_ch=num_ch, batch_size=batch_size, dim_embed=temporal
700
676
  )
701
677
  x[:, 1:, :] += time_embed
702
678
  else:
703
- # In decoder mode, patch_embed returns one token per temporal patch,
704
- # so we only need one temporal embedding per time slice.
679
+ # In decoder mode, we have n_patch patches and don't need to expand
680
+ # Just broadcast the temporal embedding
705
681
  if temporal is None:
706
682
  temporal = self.embed_dim
707
683
 
708
- n_time_tokens = min(
709
- n_patches_per_channel, self.temporal_embedding.shape[1] - 1
710
- )
684
+ # Get temporal embeddings for n_patch patches
685
+ n_time_tokens = min(n_patch, self.temporal_embedding.shape[1] - 1)
711
686
  time_embed = self.temporal_embedding[
712
687
  :, 1 : n_time_tokens + 1, :
713
- ] # (1, n_patches_per_channel, emb_dim)
688
+ ] # (1, n_patch, emb_dim)
714
689
  time_embed = time_embed.expand(
715
690
  batch_size, -1, -1
716
- ) # (batch, n_patches_per_channel, emb_dim)
691
+ ) # (batch, n_patch, emb_dim)
717
692
  x[:, 1:, :] += time_embed
718
693
 
719
694
  x = self.pos_drop(x)
@@ -851,20 +826,19 @@ class Labram(EEGModuleMixin, nn.Module):
851
826
  self._update_init_kwargs(n_outputs=n_outputs)
852
827
  self.reset_classifier(n_outputs)
853
828
 
854
- def _adj_temporal_embedding(self, num_ch, batch_size, n_patches):
829
+ def _adj_temporal_embedding(self, num_ch, batch_size, dim_embed=None):
855
830
  """
856
831
  Adjust the dimensions of the time embedding to match the
857
- number of channels and patches.
832
+ number of channels or patches.
858
833
 
859
834
  Parameters
860
835
  ----------
861
836
  num_ch : int
862
- The number of channels.
837
+ The number of channels or number of patches.
863
838
  batch_size : int
864
839
  Batch size of the input data.
865
- n_patches : int
866
- The number of patches per channel. Patch ``p`` uses time slot
867
- ``p``, as in the original implementation.
840
+ dim_embed : int
841
+ The embedding dimension (temporal feature dimension).
868
842
 
869
843
  Returns
870
844
  -------
@@ -872,9 +846,13 @@ class Labram(EEGModuleMixin, nn.Module):
872
846
  The adjusted time embedding to be added across the channels
873
847
  after the [CLS] token. (x[:, 1:, :] += time_embed)
874
848
  """
875
- # Get the temporal embedding: (1, n_time_slots, emb_size)
876
- # Keep the first n_patches slots: (1, n_patches, emb_size)
877
- cut_dimension = n_patches
849
+ if dim_embed is None:
850
+ cut_dimension = self.patch_size
851
+ else:
852
+ cut_dimension = min(dim_embed, self.temporal_embedding.shape[1] - 1)
853
+
854
+ # Get the temporal embedding: (1, temporal_embedding_dim, emb_size)
855
+ # Slice to cut_dimension: (1, cut_dimension, emb_size)
878
856
  temporal_embedding = self.temporal_embedding[:, 0:cut_dimension, :]
879
857
 
880
858
  # Add a new dimension to the time embedding
@@ -891,70 +869,6 @@ class Labram(EEGModuleMixin, nn.Module):
891
869
 
892
870
  return temporal_embedding
893
871
 
894
- def _load_from_state_dict(
895
- self,
896
- state_dict,
897
- prefix,
898
- local_metadata,
899
- strict,
900
- missing_keys,
901
- unexpected_keys,
902
- error_msgs,
903
- ):
904
- # Time slots are absolute positions: take every slot the checkpoint
905
- # holds and keep the model's own values for the others. This loads the
906
- # released 16 slots at any window length, and checkpoints saved when
907
- # the embedding had one slot per patch plus one.
908
- key = prefix + "temporal_embedding"
909
- loaded = state_dict.get(key)
910
- own = self.temporal_embedding
911
- if (
912
- self.neural_tokenizer
913
- and isinstance(loaded, torch.Tensor)
914
- and loaded.dim() == own.dim() == 3
915
- and loaded.shape[0] == own.shape[0]
916
- and loaded.shape[2] == own.shape[2]
917
- and loaded.shape[1] != own.shape[1]
918
- ):
919
- n_copied = min(loaded.shape[1], own.shape[1])
920
- resized = own.detach().clone()
921
- resized[:, :n_copied] = loaded[:, :n_copied].to(resized)
922
- n_used = self.patch_embed[0].n_patchs
923
- if n_copied < n_used:
924
- warn(
925
- f"The checkpoint holds {loaded.shape[1]} time slots but this "
926
- f"model uses {n_used} (one per patch); time slots "
927
- f"{n_copied} to {n_used - 1} keep their initialization.",
928
- UserWarning,
929
- )
930
- state_dict[key] = resized
931
- # A pretraining checkpoint has the per-token final ``norm`` and no
932
- # pooling ``fc_norm`` or head. As in the original fine-tuning script,
933
- # a mean-pooling model leaves that ``norm`` unused and starts
934
- # ``fc_norm`` from its initialization. A checkpoint with a head was
935
- # fine-tuned with its own readout and is not converted.
936
- if (
937
- self.fc_norm is not None
938
- and prefix + "cls_token" in state_dict
939
- and not any(
940
- k.startswith((prefix + "fc_norm.", prefix + "final_layer."))
941
- for k in state_dict
942
- )
943
- ):
944
- for k in [k for k in state_dict if k.startswith(prefix + "norm.")]:
945
- del state_dict[k]
946
- for name, value in self.fc_norm.state_dict().items():
947
- state_dict[prefix + "fc_norm." + name] = value
948
- super()._load_from_state_dict(
949
- state_dict,
950
- prefix,
951
- local_metadata,
952
- strict,
953
- missing_keys,
954
- unexpected_keys,
955
- error_msgs,
956
- )
957
-
958
872
  def _adj_position_embedding(self, pos_embed_used, batch_size):
959
873
  """Copy/pasted from https://github.com/935963004/LaBraM/blob/c431221e6cfd23dbfa9950e0180682fb322b0548/modeling_finetune.py#L358-L362"""
960
874
  input_time_window = self.patch_embed[0].n_patchs
@@ -1087,8 +1001,7 @@ class _PatchEmbed(nn.Module):
1087
1001
  but the original LaBraM expects pre-patched data (Batch, n_channels, n_patches, patch_size).
1088
1002
  This class reshapes the input to the pre-patched format, then applies a 2D
1089
1003
  convolution to project this pre-patched data to the embedding dimension,
1090
- and finally averages over grouped channels to produce one embedding per
1091
- temporal patch.
1004
+ and finally flattens across channels to produce a unified embedding.
1092
1005
 
1093
1006
  Parameters:
1094
1007
  -----------
@@ -22,7 +22,6 @@ import torch.nn as nn
22
22
  import torch.nn.functional as F
23
23
  from einops import rearrange
24
24
 
25
- from braindecode.functional import rotate_pairs
26
25
  from braindecode.models.base import EEGModuleMixin
27
26
  from braindecode.models.util import extract_channel_locations_from_chs_info
28
27
  from braindecode.modules.layers import DropPath
@@ -552,9 +551,8 @@ class _RotarySelfAttentionBlock(nn.Module):
552
551
  positions = torch.arange(seq_len, device=tensor.device, dtype=tensor.dtype)
553
552
  freqs = self.rotary_emb(positions)
554
553
 
555
- # Keep the full-head reshape (including its empty-input boundary).
556
554
  pairs = tensor.reshape(*tensor.shape[:-1], -1, 2)
557
- rotated = rotate_pairs(pairs.flatten(-2))
555
+ rotated = torch.stack((-pairs[..., 1], pairs[..., 0]), dim=-1).flatten(-2)
558
556
  transformed = tensor * freqs.cos() + rotated * freqs.sin()
559
557
  return transformed.to(tensor.dtype)
560
558
 
@@ -58,7 +58,6 @@ LUNA,General,"Prediction, Embedding",128,"n_chans, n_times, sfreq, chs_info",710
58
58
  MEDFormer,General,Prediction,250,"n_chans, n_outputs, n_times",5313924,"MEDFormer(n_chans=22, n_outputs=4, n_times=1000)","Foundation Model,Convolution",EEG
59
59
  REVE,General,Prediction,200,"n_outputs, n_times, n_chans",69481476,"REVE(n_times=1000, n_outputs=4, n_chans=19)","Foundation Model,Attention/Transformer",EEG
60
60
  DGCNN,Emotion Recognition,Prediction,128,"n_chans, n_outputs, n_times, chs_info",1037385,"DGCNN(n_chans=62, n_outputs=4, n_times=128)","Graph Neural Network,Channel",EEG
61
- DIVER1,General,Prediction,500,"chs_info, n_outputs, n_times",12711366,"DIVER1(chs_info=<user>, n_outputs=4, n_times=1000, sfreq=500)","Attention/Transformer,Foundation Model,Channel",iEEG
62
61
  InterpolatedBENDR,General,"Prediction, Embedding",250,"chs_info, n_outputs, n_times",157143101,"InterpolatedBENDR(chs_info=<user>, n_outputs=4, n_times=1000)","Foundation Model,Convolution,Channel",EEG
63
62
  InterpolatedBIOT,"Sleep Staging, Epilepsy",Prediction,200,"chs_info, n_outputs, n_times, sfreq",3184101,"InterpolatedBIOT(chs_info=<user>, n_outputs=5, sfreq=200, n_times=6000)","Foundation Model,Channel",EEG
64
63
  InterpolatedEEGPT,General,Prediction,256,"chs_info, n_outputs, n_times",25323137,"InterpolatedEEGPT(chs_info=<user>, n_outputs=4, n_times=1024)","Foundation Model,Attention/Transformer,Channel",EEG
@@ -21,19 +21,6 @@ from torch import nn
21
21
 
22
22
  from braindecode.util import resolve_montage_name
23
23
 
24
- # Canonical MNE channel-type name for the electrode kinds braindecode models
25
- # tell apart.
26
- _KIND_TO_CH_TYPE = {
27
- FIFF.FIFFV_EEG_CH: "eeg",
28
- FIFF.FIFFV_SEEG_CH: "seeg",
29
- FIFF.FIFFV_DBS_CH: "dbs",
30
- FIFF.FIFFV_ECOG_CH: "ecog",
31
- }
32
-
33
- #: MNE channel types recorded from inside the skull.
34
- INTRACRANIAL_CH_TYPES = frozenset({"seeg", "dbs", "ecog"})
35
-
36
-
37
24
  models_dict = {}
38
25
  # Interpolated models are channel-interpolating wrappers around existing
39
26
  # braindecode backbones (see :func:`braindecode.models.InterpolatedModel`).
@@ -565,11 +552,6 @@ models_mandatory_parameters: list[
565
552
  {"n_chans": 19, "n_times": 6000},
566
553
  ),
567
554
  ("DGCNN", ["n_chans", "n_outputs", "n_times", "chs_info"], None),
568
- (
569
- "DIVER1",
570
- ["chs_info", "n_outputs", "n_times"],
571
- {"sfreq": 500.0},
572
- ),
573
555
  ("EEGDINO", ["n_chans", "n_outputs", "n_times"], None),
574
556
  (
575
557
  "DANCE",
@@ -764,7 +746,6 @@ def get_summary_table(dir_name=None):
764
746
  def extract_channel_locations_from_chs_info(
765
747
  chs_info: Optional[Sequence[Dict[str, Any]]],
766
748
  num_channels: Optional[int] = None,
767
- fill_missing: bool = False,
768
749
  ) -> Optional[np.ndarray]:
769
750
  """Extract 3D channel locations from MNE-style channel information.
770
751
 
@@ -781,31 +762,19 @@ def extract_channel_locations_from_chs_info(
781
762
  num_channels : int or None
782
763
  If specified, only extract the first ``num_channels`` channel locations.
783
764
  If None, extract all available channels.
784
- fill_missing : bool
785
- If False (default), extraction stops at the first channel whose location
786
- is missing or malformed, so the result may be shorter than requested,
787
- and an all-zero montage yields None. If True, each such channel
788
- contributes a row of ``NaN`` instead, an all-zero montage yields all
789
- ``NaN``, and the result always has one row per requested channel.
790
765
 
791
766
  Returns
792
767
  -------
793
768
  channel_locations : np.ndarray of shape (n_channels, 3) or None
794
769
  Array of 3D channel locations in cartesian coordinates. Returns None if
795
- no valid locations are found, unless ``fill_missing=True``, in which
796
- case missing locations are reported as ``NaN`` rows and None is only
797
- returned when ``chs_info`` is None or no channel was requested.
770
+ no valid locations are found.
798
771
 
799
772
  Notes
800
773
  -----
801
774
  - This function handles both 12-element MNE location format (using indices 0:3)
802
775
  and 3-element location format (using directly).
803
- - Invalid or missing locations cause extraction to stop at that point, unless
804
- ``fill_missing=True``.
805
- - An all-zero montage is treated as no montage at all, which is also how
806
- :func:`has_valid_locations` reads it.
807
- - Returns None if no valid locations can be extracted, except with
808
- ``fill_missing=True`` as described above.
776
+ - Invalid or missing locations cause extraction to stop at that point.
777
+ - Returns None if no valid locations can be extracted.
809
778
  - This is a unified utility compatible with models like SignalJEPA and LUNA.
810
779
 
811
780
  Examples
@@ -823,22 +792,26 @@ def extract_channel_locations_from_chs_info(
823
792
  locations = []
824
793
  n_to_extract = num_channels if num_channels is not None else len(chs_info)
825
794
 
826
- for i in range(n_to_extract):
827
- ch_info = chs_info[i] if i < len(chs_info) else None
828
- loc = ch_info.get("loc") if isinstance(ch_info, dict) else None
829
- try:
830
- coordinates = np.asarray(loc, dtype=np.float32)
831
- except (ValueError, TypeError):
832
- coordinates = np.asarray(np.nan, dtype=np.float32)
795
+ for i, ch_info in enumerate(chs_info[:n_to_extract]):
796
+ if not isinstance(ch_info, dict):
797
+ break
833
798
 
834
- if coordinates.ndim == 1 and coordinates.size >= 3:
835
- coordinates = coordinates[:3]
836
- elif fill_missing:
837
- coordinates = np.full(3, np.nan, dtype=np.float32)
838
- else:
799
+ loc = ch_info.get("loc")
800
+ if loc is None:
839
801
  break
840
802
 
841
- locations.append(coordinates)
803
+ try:
804
+ loc_array = np.asarray(loc, dtype=np.float32)
805
+
806
+ # MNE format: 12-element array with electrode position at indices 0:3
807
+ if loc_array.ndim == 1 and loc_array.size >= 3:
808
+ coordinates = loc_array[:3]
809
+ else:
810
+ break
811
+
812
+ locations.append(coordinates)
813
+ except (ValueError, TypeError):
814
+ break
842
815
 
843
816
  if len(locations) == 0:
844
817
  return None
@@ -847,10 +820,7 @@ def extract_channel_locations_from_chs_info(
847
820
 
848
821
  # Check positions are not all zero / degenerate
849
822
  if np.allclose(result, 0):
850
- if not fill_missing:
851
- return None
852
- # An all-zero montage carries no position, just like an absent one
853
- result = np.full_like(result, np.nan)
823
+ return None
854
824
 
855
825
  return result
856
826
 
@@ -958,7 +928,7 @@ def resolve_channel_indices(
958
928
  return cast(list[int], indices)
959
929
 
960
930
 
961
- def positions_from_chs_info(chs_info):
931
+ def positions_from_chs_info(chs_info) -> np.ndarray:
962
932
  """``(n_chans, 2)`` electrode xy normalized to ``[0, 1]`` per axis.
963
933
 
964
934
  Takes the raw 3D sensor coordinates ``ch["loc"][:3]``, keeps ``xy`` and
@@ -970,26 +940,15 @@ def positions_from_chs_info(chs_info):
970
940
 
971
941
  Parameters
972
942
  ----------
973
- chs_info : list of dict or torch.Tensor
943
+ chs_info : list of dict
974
944
  MNE-style channel info dicts, each with a ``"loc"`` array whose first
975
- three entries are the head-frame ``x, y, z`` coordinates, or a floating
976
- coordinate tensor of shape ``(n_chans, 3)`` in consistent units.
945
+ three entries are the head-frame ``x, y, z`` coordinates.
977
946
 
978
947
  Returns
979
948
  -------
980
- numpy.ndarray or torch.Tensor
981
- ``(n_chans, 2)`` float positions in ``[0, 1]``. Dictionary inputs retain
982
- the NumPy float64 result. Tensor inputs preserve device and dtype and
983
- support autograd and TorchScript. This does not return raw xyz or
984
- convert metres to millimetres.
949
+ numpy.ndarray
950
+ ``(n_chans, 2)`` float positions in ``[0, 1]``.
985
951
  """
986
- if isinstance(chs_info, torch.Tensor):
987
- xy = chs_info[:, :2]
988
- # Preserve the floor and backward intermediates at small half spans.
989
- if xy.dtype == torch.float16 or xy.dtype == torch.bfloat16:
990
- xy = xy.float()
991
- mn, mx = xy.amin(dim=0), xy.amax(dim=0)
992
- return ((xy - mn) / (mx - mn).clamp_min(1e-9)).to(chs_info.dtype)
993
952
  xyz = np.array([ch["loc"][:3] for ch in chs_info], dtype=float)
994
953
  xy = xyz[:, :2]
995
954
  mn, mx = xy.min(axis=0), xy.max(axis=0)
@@ -997,20 +956,7 @@ def positions_from_chs_info(chs_info):
997
956
 
998
957
 
999
958
  def has_valid_locations(chs_info) -> bool:
1000
- """Whether a montage has finite, not approximately all-zero locations.
1001
-
1002
- ``chs_info`` accepts MNE channel dictionaries or a coordinate tensor of
1003
- shape ``(n_chans, 3)``. Coordinates retain their input units. The result is
1004
- a montage-wide Python bool, not a per-channel mask; zero rows are allowed
1005
- when another row is nonzero. The all-zero tolerance is ``1e-8``.
1006
- For a TorchScript-compatible per-row check, use :func:`valid_location_mask`.
1007
- """
1008
- if isinstance(chs_info, torch.Tensor):
1009
- return bool(
1010
- chs_info.numel() > 0
1011
- and torch.isfinite(chs_info).all()
1012
- and chs_info.abs().max().item() > 1e-8
1013
- )
959
+ """``True`` if ``chs_info`` carries finite, non-all-zero electrode locations."""
1014
960
  if chs_info is None:
1015
961
  return False
1016
962
  try:
@@ -1024,72 +970,4 @@ def has_valid_locations(chs_info) -> bool:
1024
970
  return True
1025
971
 
1026
972
 
1027
- def valid_location_mask(locations: torch.Tensor) -> torch.Tensor:
1028
- """Flag finite, exactly nonzero coordinate rows without changing their units.
1029
-
1030
- Parameters
1031
- ----------
1032
- locations : torch.Tensor
1033
- Coordinates of shape ``(..., 3)``, in any consistent coordinate frame
1034
- and units (e.g. xyz in metres or millimetres, not normalized xy).
1035
-
1036
- Returns
1037
- -------
1038
- torch.Tensor
1039
- Boolean mask of shape ``(..., 1)`` on the input device. Unlike
1040
- :func:`has_valid_locations`, this tests each row against exact zero,
1041
- not an approximate montage-wide zero. Supports TorchScript.
1042
- """
1043
- return torch.isfinite(locations).all(dim=-1, keepdim=True) & (locations != 0).any(
1044
- dim=-1, keepdim=True
1045
- )
1046
-
1047
-
1048
- def channel_types_from_chs_info(
1049
- chs_info: Optional[Sequence[Dict[str, Any]]],
1050
- num_channels: Optional[int] = None,
1051
- ) -> list[str]:
1052
- """Canonical MNE channel-type name for each channel of ``chs_info``.
1053
-
1054
- Parameters
1055
- ----------
1056
- chs_info : list of dict or None
1057
- MNE-style channel info dicts, typically from ``mne.Info.chs``. Each
1058
- ``"kind"`` entry may be an MNE FIFF integer code or a plain type string.
1059
- num_channels : int or None
1060
- Number of channels to report. Channels beyond ``chs_info`` yield
1061
- ``"unknown"``, so the returned list always has this length. If None, one
1062
- entry per ``chs_info`` channel is returned (empty when it is None).
1063
-
1064
- Returns
1065
- -------
1066
- list of str
1067
- Lowercase channel-type names such as ``"eeg"``, ``"seeg"``, ``"ecog"`` or
1068
- ``"dbs"``, and ``"unknown"`` where the kind is missing or is not one of
1069
- the electrode kinds resolved here.
1070
-
1071
- Notes
1072
- -----
1073
- Only electrode kinds are resolved. An MNE ``"kind"`` code does not identify
1074
- every channel type on its own: code 2 is shared by ``"eeg"`` and ``"csd"``,
1075
- code 1 by ``"grad"`` and ``"mag"``, because MNE disambiguates those with
1076
- ``"unit"`` and ``"coil_type"``. Use :func:`mne.channel_type` with a full
1077
- :class:`mne.Info` when those channel types matter.
1078
- """
1079
- if num_channels is None:
1080
- num_channels = len(chs_info) if chs_info is not None else 0
1081
-
1082
- types = []
1083
- for i in range(num_channels):
1084
- ch_info = chs_info[i] if chs_info is not None and i < len(chs_info) else None
1085
- kind = ch_info.get("kind") if isinstance(ch_info, dict) else None
1086
- if isinstance(kind, str):
1087
- types.append(kind.lower())
1088
- elif isinstance(kind, int):
1089
- types.append(_KIND_TO_CH_TYPE.get(kind, "unknown"))
1090
- else:
1091
- types.append("unknown")
1092
- return types
1093
-
1094
-
1095
973
  _summary_table = get_summary_table()