spikeinterface 0.103.1__tar.gz → 0.103.2__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 (360) hide show
  1. {spikeinterface-0.103.1/src/spikeinterface.egg-info → spikeinterface-0.103.2}/PKG-INFO +2 -2
  2. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/pyproject.toml +2 -2
  3. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/benchmark_base.py +1 -1
  4. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/analyzer_extension_core.py +12 -4
  5. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/base.py +1 -1
  6. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/sortinganalyzer.py +38 -13
  7. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/sparsity.py +12 -0
  8. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/template_tools.py +0 -1
  9. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/waveform_tools.py +50 -9
  10. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/__init__.py +1 -1
  11. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/auto_merge.py +26 -8
  12. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/curation_format.py +26 -0
  13. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/model_based_curation.py +1 -6
  14. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/neobaseextractor.py +13 -5
  15. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/plexon2.py +8 -2
  16. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/generation/drift_tools.py +2 -0
  17. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/postprocessing/template_similarity.py +18 -9
  18. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/detect_bad_channels.py +20 -1
  19. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/kilosort4.py +29 -3
  20. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/pykilosort.py +1 -1
  21. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/internal/spyking_circus2.py +5 -1
  22. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/tools.py +6 -1
  23. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/unit_locations.py +16 -8
  24. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/unit_summary.py +7 -0
  25. {spikeinterface-0.103.1 → spikeinterface-0.103.2/src/spikeinterface.egg-info}/PKG-INFO +2 -2
  26. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/LICENSE +0 -0
  27. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/README.md +0 -0
  28. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/setup.cfg +0 -0
  29. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/__init__.py +0 -0
  30. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/__init__.py +0 -0
  31. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/benchmark_clustering.py +0 -0
  32. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/benchmark_matching.py +0 -0
  33. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/benchmark_merging.py +0 -0
  34. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/benchmark_motion_estimation.py +0 -0
  35. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/benchmark_motion_interpolation.py +0 -0
  36. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/benchmark_peak_detection.py +0 -0
  37. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/benchmark_peak_localization.py +0 -0
  38. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/benchmark_peak_selection.py +0 -0
  39. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/benchmark_plot_tools.py +0 -0
  40. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/benchmark_sorter.py +0 -0
  41. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/benchmark_sorter_without_gt.py +0 -0
  42. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/benchmark_tools.py +0 -0
  43. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/benchmark/residual_analysis.py +0 -0
  44. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/comparison/__init__.py +0 -0
  45. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/comparison/basecomparison.py +0 -0
  46. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/comparison/collision.py +0 -0
  47. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/comparison/comparisontools.py +0 -0
  48. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/comparison/correlogram.py +0 -0
  49. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/comparison/groundtruthstudy.py +0 -0
  50. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/comparison/hybrid.py +0 -0
  51. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/comparison/multicomparisons.py +0 -0
  52. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/comparison/paircomparisons.py +0 -0
  53. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/__init__.py +0 -0
  54. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/baseevent.py +0 -0
  55. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/baserecording.py +0 -0
  56. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/baserecordingsnippets.py +0 -0
  57. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/basesnippets.py +0 -0
  58. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/basesorting.py +0 -0
  59. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/binaryfolder.py +0 -0
  60. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/binaryrecordingextractor.py +0 -0
  61. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/channelsaggregationrecording.py +0 -0
  62. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/channelslice.py +0 -0
  63. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/core_tools.py +0 -0
  64. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/datasets.py +0 -0
  65. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/frameslicerecording.py +0 -0
  66. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/frameslicesorting.py +0 -0
  67. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/generate.py +0 -0
  68. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/globals.py +0 -0
  69. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/job_tools.py +0 -0
  70. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/loading.py +0 -0
  71. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/motion.py +0 -0
  72. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/node_pipeline.py +0 -0
  73. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/npyfoldersnippets.py +0 -0
  74. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/npysnippetsextractor.py +0 -0
  75. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/npzfolder.py +0 -0
  76. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/npzsortingextractor.py +0 -0
  77. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/numpyextractors.py +0 -0
  78. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/old_api_utils.py +0 -0
  79. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/recording_tools.py +0 -0
  80. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/segmentutils.py +0 -0
  81. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/snippets_tools.py +0 -0
  82. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/sorting_tools.py +0 -0
  83. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/sortingfolder.py +0 -0
  84. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/template.py +0 -0
  85. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/testing.py +0 -0
  86. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/testing_tools.py +0 -0
  87. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/unitsaggregationsorting.py +0 -0
  88. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/unitsselectionsorting.py +0 -0
  89. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/waveforms_extractor_backwards_compatibility.py +0 -0
  90. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/zarrextractors.py +0 -0
  91. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/core/zarrrecordingextractor.py +0 -0
  92. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/curation_model.py +0 -0
  93. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/curation_tools.py +0 -0
  94. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/curationsorting.py +0 -0
  95. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/mergeunitssorting.py +0 -0
  96. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/remove_duplicated_spikes.py +0 -0
  97. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/remove_excess_spikes.py +0 -0
  98. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/remove_redundant.py +0 -0
  99. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/sortingview_curation.py +0 -0
  100. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/splitunitsorting.py +0 -0
  101. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/curation/train_manual_curation.py +0 -0
  102. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/exporters/__init__.py +0 -0
  103. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/exporters/report.py +0 -0
  104. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/exporters/to_ibl.py +0 -0
  105. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/exporters/to_phy.py +0 -0
  106. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/exporters/to_pynapple.py +0 -0
  107. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/__init__.py +0 -0
  108. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/alfsortingextractor.py +0 -0
  109. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/bids.py +0 -0
  110. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/cbin_ibl.py +0 -0
  111. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/cellexplorersortingextractor.py +0 -0
  112. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/combinatoextractors.py +0 -0
  113. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/extractor_classes.py +0 -0
  114. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/hdsortextractors.py +0 -0
  115. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/herdingspikesextractors.py +0 -0
  116. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/iblextractors.py +0 -0
  117. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/klustaextractors.py +0 -0
  118. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/matlabhelpers.py +0 -0
  119. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/mclustextractors.py +0 -0
  120. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/mcsh5extractors.py +0 -0
  121. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/mdaextractors.py +0 -0
  122. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/__init__.py +0 -0
  123. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/alphaomega.py +0 -0
  124. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/axon.py +0 -0
  125. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/axona.py +0 -0
  126. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/biocam.py +0 -0
  127. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/blackrock.py +0 -0
  128. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/ced.py +0 -0
  129. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/edf.py +0 -0
  130. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/intan.py +0 -0
  131. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/maxwell.py +0 -0
  132. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/mcsraw.py +0 -0
  133. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/mearec.py +0 -0
  134. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/neo_utils.py +0 -0
  135. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/neuralynx.py +0 -0
  136. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/neuroexplorer.py +0 -0
  137. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/neuronexus.py +0 -0
  138. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/neuroscope.py +0 -0
  139. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/nix.py +0 -0
  140. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/openephys.py +0 -0
  141. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/plexon.py +0 -0
  142. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/spike2.py +0 -0
  143. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/spikegadgets.py +0 -0
  144. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/spikeglx.py +0 -0
  145. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neoextractors/tdt.py +0 -0
  146. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/neuropixels_utils.py +0 -0
  147. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/nwbextractors.py +0 -0
  148. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/phykilosortextractors.py +0 -0
  149. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/shybridextractors.py +0 -0
  150. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/sinapsrecordingextractors.py +0 -0
  151. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/spykingcircusextractors.py +0 -0
  152. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/toy_example.py +0 -0
  153. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/tridesclousextractors.py +0 -0
  154. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/waveclussnippetstextractors.py +0 -0
  155. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/waveclustextractors.py +0 -0
  156. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/whitematterrecordingextractor.py +0 -0
  157. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/extractors/yassextractors.py +0 -0
  158. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/full.py +0 -0
  159. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/generation/__init__.py +0 -0
  160. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/generation/drifting_generator.py +0 -0
  161. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/generation/hybrid_tools.py +0 -0
  162. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/generation/noise_tools.py +0 -0
  163. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/generation/splitting_tools.py +0 -0
  164. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/generation/template_database.py +0 -0
  165. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/postprocessing/__init__.py +0 -0
  166. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/postprocessing/alignsorting.py +0 -0
  167. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/postprocessing/amplitude_scalings.py +0 -0
  168. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/postprocessing/correlograms.py +0 -0
  169. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/postprocessing/isi.py +0 -0
  170. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/postprocessing/localization_tools.py +0 -0
  171. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/postprocessing/noise_level.py +0 -0
  172. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/postprocessing/principal_component.py +0 -0
  173. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/postprocessing/spike_amplitudes.py +0 -0
  174. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/postprocessing/spike_locations.py +0 -0
  175. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/postprocessing/template_metrics.py +0 -0
  176. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/postprocessing/unit_locations.py +0 -0
  177. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/__init__.py +0 -0
  178. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/align_snippets.py +0 -0
  179. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/astype.py +0 -0
  180. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/average_across_direction.py +0 -0
  181. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/basepreprocessor.py +0 -0
  182. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/clip.py +0 -0
  183. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/common_reference.py +0 -0
  184. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/correct_lsb.py +0 -0
  185. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/decimate.py +0 -0
  186. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/deepinterpolation/__init__.py +0 -0
  187. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/deepinterpolation/deepinterpolation.py +0 -0
  188. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/deepinterpolation/generators.py +0 -0
  189. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/deepinterpolation/tf_utils.py +0 -0
  190. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/deepinterpolation/train.py +0 -0
  191. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/depth_order.py +0 -0
  192. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/directional_derivative.py +0 -0
  193. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/filter.py +0 -0
  194. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/filter_gaussian.py +0 -0
  195. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/filter_opencl.py +0 -0
  196. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/highpass_spatial_filter.py +0 -0
  197. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/interpolate_bad_channels.py +0 -0
  198. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/motion.py +0 -0
  199. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/normalize_scale.py +0 -0
  200. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/phase_shift.py +0 -0
  201. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/pipeline.py +0 -0
  202. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/preprocessing_classes.py +0 -0
  203. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/preprocessing_tools.py +0 -0
  204. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/rectify.py +0 -0
  205. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/remove_artifacts.py +0 -0
  206. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/resample.py +0 -0
  207. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/scale.py +0 -0
  208. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/silence_periods.py +0 -0
  209. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/unsigned_to_signed.py +0 -0
  210. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/whiten.py +0 -0
  211. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/preprocessing/zero_channel_pad.py +0 -0
  212. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/qualitymetrics/__init__.py +0 -0
  213. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/qualitymetrics/misc_metrics.py +0 -0
  214. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/qualitymetrics/pca_metrics.py +0 -0
  215. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/qualitymetrics/quality_metric_calculator.py +0 -0
  216. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/qualitymetrics/quality_metric_list.py +0 -0
  217. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/qualitymetrics/utils.py +0 -0
  218. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/__init__.py +0 -0
  219. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/basesorter.py +0 -0
  220. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/container_tools.py +0 -0
  221. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/__init__.py +0 -0
  222. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/combinato.py +0 -0
  223. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/hdsort.py +0 -0
  224. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/hdsort_master.m +0 -0
  225. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/herdingspikes.py +0 -0
  226. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/ironclust.py +0 -0
  227. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/kilosort.py +0 -0
  228. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/kilosort2.py +0 -0
  229. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/kilosort2_5.py +0 -0
  230. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/kilosort2_5_master.m +0 -0
  231. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/kilosort2_master.m +0 -0
  232. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/kilosort3.py +0 -0
  233. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/kilosort3_master.m +0 -0
  234. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/kilosort_master.m +0 -0
  235. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/kilosortbase.py +0 -0
  236. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/klusta.py +0 -0
  237. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/klusta_config_default.prm +0 -0
  238. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/mountainsort4.py +0 -0
  239. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/mountainsort5.py +0 -0
  240. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/rt_sort.py +0 -0
  241. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/sc_config_default.params +0 -0
  242. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/spyking_circus.py +0 -0
  243. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/tridesclous.py +0 -0
  244. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/waveclus.py +0 -0
  245. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/waveclus_master.m +0 -0
  246. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/waveclus_snippets.py +0 -0
  247. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/waveclus_snippets_master.m +0 -0
  248. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/yass.py +0 -0
  249. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/external/yass_config_default.yaml +0 -0
  250. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/internal/__init__.py +0 -0
  251. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/internal/si_based.py +0 -0
  252. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/internal/simplesorter.py +0 -0
  253. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/internal/tridesclous2.py +0 -0
  254. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/launcher.py +0 -0
  255. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/runsorter.py +0 -0
  256. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/sorterlist.py +0 -0
  257. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/utils/__init__.py +0 -0
  258. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/utils/constructNPYheader.m +0 -0
  259. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/utils/misc.py +0 -0
  260. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/utils/shellscript.py +0 -0
  261. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sorters/utils/writeNPY.m +0 -0
  262. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/__init__.py +0 -0
  263. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/__init__.py +0 -0
  264. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/cleaning_tools.py +0 -0
  265. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/dummy.py +0 -0
  266. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/graph_clustering.py +0 -0
  267. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/graph_tools.py +0 -0
  268. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/isosplit_isocut.py +0 -0
  269. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/iterative_hdbscan.py +0 -0
  270. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/iterative_isosplit.py +0 -0
  271. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/itersplit_tools.py +0 -0
  272. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/main.py +0 -0
  273. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/merging_tools.py +0 -0
  274. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/method_list.py +0 -0
  275. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/positions.py +0 -0
  276. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/random_projections.py +0 -0
  277. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/clustering/tools.py +0 -0
  278. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/matching/__init__.py +0 -0
  279. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/matching/base.py +0 -0
  280. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/matching/circus.py +0 -0
  281. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/matching/main.py +0 -0
  282. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/matching/method_list.py +0 -0
  283. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/matching/nearest.py +0 -0
  284. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/matching/tdc_peeler.py +0 -0
  285. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/matching/wobble.py +0 -0
  286. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/motion/__init__.py +0 -0
  287. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/motion/decentralized.py +0 -0
  288. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/motion/dredge.py +0 -0
  289. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/motion/iterative_template.py +0 -0
  290. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/motion/medicine.py +0 -0
  291. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/motion/motion_cleaner.py +0 -0
  292. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/motion/motion_estimation.py +0 -0
  293. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/motion/motion_interpolation.py +0 -0
  294. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/motion/motion_utils.py +0 -0
  295. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_detection/__init__.py +0 -0
  296. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_detection/by_channel.py +0 -0
  297. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_detection/iterative.py +0 -0
  298. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_detection/locally_exclusive.py +0 -0
  299. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_detection/main.py +0 -0
  300. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_detection/matched_filtering.py +0 -0
  301. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_detection/method_list.py +0 -0
  302. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_localization/__init__.py +0 -0
  303. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_localization/base.py +0 -0
  304. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_localization/center_of_mass.py +0 -0
  305. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_localization/grid.py +0 -0
  306. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_localization/main.py +0 -0
  307. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_localization/method_list.py +0 -0
  308. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_localization/monopolar.py +0 -0
  309. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/peak_selection.py +0 -0
  310. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/waveforms/__init__.py +0 -0
  311. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/waveforms/features_from_peaks.py +0 -0
  312. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/waveforms/hanning_filter.py +0 -0
  313. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/waveforms/neural_network_denoiser.py +0 -0
  314. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/waveforms/peak_svd.py +0 -0
  315. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/waveforms/savgol_denoiser.py +0 -0
  316. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/waveforms/temporal_pca.py +0 -0
  317. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/waveforms/waveform_thresholder.py +0 -0
  318. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/sortingcomponents/waveforms/waveform_utils.py +0 -0
  319. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/__init__.py +0 -0
  320. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/all_amplitudes_distributions.py +0 -0
  321. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/amplitudes.py +0 -0
  322. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/autocorrelograms.py +0 -0
  323. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/base.py +0 -0
  324. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/collision.py +0 -0
  325. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/comparison.py +0 -0
  326. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/crosscorrelograms.py +0 -0
  327. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/drift_templates.py +0 -0
  328. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/gtstudy.py +0 -0
  329. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/isi_distribution.py +0 -0
  330. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/metrics.py +0 -0
  331. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/motion.py +0 -0
  332. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/multicomparison.py +0 -0
  333. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/peak_activity.py +0 -0
  334. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/peaks_on_probe.py +0 -0
  335. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/potential_merges.py +0 -0
  336. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/probe_map.py +0 -0
  337. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/quality_metrics.py +0 -0
  338. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/rasters.py +0 -0
  339. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/sorting_summary.py +0 -0
  340. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/spike_locations.py +0 -0
  341. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/spike_locations_by_time.py +0 -0
  342. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/spikes_on_traces.py +0 -0
  343. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/template_metrics.py +0 -0
  344. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/template_similarity.py +0 -0
  345. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/traces.py +0 -0
  346. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/unit_depths.py +0 -0
  347. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/unit_presence.py +0 -0
  348. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/unit_probe_map.py +0 -0
  349. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/unit_templates.py +0 -0
  350. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/unit_waveforms.py +0 -0
  351. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/unit_waveforms_density_map.py +0 -0
  352. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/utils.py +0 -0
  353. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/utils_ipywidgets.py +0 -0
  354. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/utils_matplotlib.py +0 -0
  355. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/utils_sortingview.py +0 -0
  356. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface/widgets/widget_list.py +0 -0
  357. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface.egg-info/SOURCES.txt +0 -0
  358. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface.egg-info/dependency_links.txt +0 -0
  359. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface.egg-info/requires.txt +0 -0
  360. {spikeinterface-0.103.1 → spikeinterface-0.103.2}/src/spikeinterface.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spikeinterface
3
- Version: 0.103.1
3
+ Version: 0.103.2
4
4
  Summary: Python toolkit for analysis, visualization, and comparison of spike sorting output
5
5
  Author-email: Alessio Buccino <alessiop.buccino@gmail.com>, Samuel Garcia <sam.garcia.die@gmail.com>
6
6
  Project-URL: homepage, https://github.com/SpikeInterface/spikeinterface
@@ -14,7 +14,7 @@ Classifier: Operating System :: POSIX :: Linux
14
14
  Classifier: Operating System :: Microsoft :: Windows
15
15
  Classifier: Operating System :: MacOS
16
16
  Classifier: Operating System :: OS Independent
17
- Requires-Python: <3.14,>=3.9
17
+ Requires-Python: >=3.9
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
20
  Requires-Dist: numpy>=1.20; python_version < "3.13"
@@ -1,13 +1,13 @@
1
1
  [project]
2
2
  name = "spikeinterface"
3
- version = "0.103.1"
3
+ version = "0.103.2"
4
4
  authors = [
5
5
  { name="Alessio Buccino", email="alessiop.buccino@gmail.com" },
6
6
  { name="Samuel Garcia", email="sam.garcia.die@gmail.com" },
7
7
  ]
8
8
  description = "Python toolkit for analysis, visualization, and comparison of spike sorting output"
9
9
  readme = "README.md"
10
- requires-python = ">=3.9,<3.14"
10
+ requires-python = ">=3.9"
11
11
  classifiers = [
12
12
  "Programming Language :: Python :: 3 :: Only",
13
13
  "License :: OSI Approved :: MIT License",
@@ -431,7 +431,7 @@ class BenchmarkStudy:
431
431
  if verbose:
432
432
  print("### Compute result", key, "###")
433
433
  benchmark = self.benchmarks[key]
434
- assert benchmark is not None
434
+ assert benchmark is not None, f"Benchmkark for key {key} has not been run yet!"
435
435
  benchmark.compute_result(**result_params)
436
436
  benchmark.save_result(self.folder / "results" / self.key_to_str(key))
437
437
 
@@ -437,6 +437,7 @@ class ComputeTemplates(AnalyzerExtension):
437
437
  return_in_uV = self.sorting_analyzer.return_in_uV
438
438
 
439
439
  return_std = "std" in self.params["operators"]
440
+ sparsity_mask = None if self.sparsity is None else self.sparsity.mask
440
441
  output = estimate_templates_with_accumulator(
441
442
  recording,
442
443
  some_spikes,
@@ -445,17 +446,24 @@ class ComputeTemplates(AnalyzerExtension):
445
446
  self.nafter,
446
447
  return_in_uV=return_in_uV,
447
448
  return_std=return_std,
449
+ sparsity_mask=sparsity_mask,
448
450
  verbose=verbose,
449
451
  **job_kwargs,
450
452
  )
451
453
 
452
- # Output of estimate_templates_with_accumulator is either (templates,) or (templates, stds)
453
454
  if return_std:
454
455
  templates, stds = output
455
- self.data["average"] = templates
456
- self.data["std"] = stds
456
+ data = dict(average=templates, std=stds)
457
457
  else:
458
- self.data["average"] = output
458
+ templates = output
459
+ data = dict(average=templates)
460
+
461
+ if self.sparsity is not None:
462
+ # make average and std dense again
463
+ for k, arr in data.items():
464
+ dense_arr = self.sparsity.densify_templates(arr)
465
+ data[k] = dense_arr
466
+ self.data.update(data)
459
467
 
460
468
  def _compute_and_append_from_waveforms(self, operators):
461
469
  if not self.sorting_analyzer.has_extension("waveforms"):
@@ -879,7 +879,7 @@ class BaseExtractor:
879
879
  self,
880
880
  name: str | None = None,
881
881
  folder: str | Path | None = None,
882
- overwrite: str = False,
882
+ overwrite: bool = False,
883
883
  verbose: bool = True,
884
884
  **save_kwargs,
885
885
  ):
@@ -1023,7 +1023,7 @@ class SortingAnalyzer:
1023
1023
  # merge units
1024
1024
  all_unit_ids = unit_ids
1025
1025
  sparsity_mask = np.zeros((len(all_unit_ids), self.sparsity.mask.shape[1]), dtype=bool)
1026
- mergeable, masks = self.are_units_mergeable(
1026
+ _, masks = self.are_units_mergeable(
1027
1027
  merge_unit_groups,
1028
1028
  sparsity_overlap=sparsity_overlap,
1029
1029
  merging_mode=merging_mode,
@@ -1033,14 +1033,7 @@ class SortingAnalyzer:
1033
1033
  for unit_index, unit_id in enumerate(all_unit_ids):
1034
1034
  if unit_id in merge_new_unit_ids:
1035
1035
  merge_unit_group = tuple(merge_unit_groups[merge_new_unit_ids.index(unit_id)])
1036
- if not mergeable[merge_unit_group]:
1037
- raise Exception(
1038
- f"The sparsity of {merge_unit_group} do not overlap enough for a soft merge using "
1039
- f"a sparsity threshold of {sparsity_overlap}. You can either lower the threshold or use "
1040
- "a hard merge."
1041
- )
1042
- else:
1043
- sparsity_mask[unit_index] = masks[merge_unit_group]
1036
+ sparsity_mask[unit_index] = masks[merge_unit_group]
1044
1037
  else:
1045
1038
  # This means that the unit is already in the previous sorting
1046
1039
  index = self.sorting.id_to_index(unit_id)
@@ -1271,6 +1264,7 @@ class SortingAnalyzer:
1271
1264
  censor_ms: float | None = None,
1272
1265
  merging_mode: str = "soft",
1273
1266
  sparsity_overlap: float = 0.75,
1267
+ raise_error_if_overlap_fails: bool = True,
1274
1268
  new_id_strategy: str = "append",
1275
1269
  return_new_unit_ids: bool = False,
1276
1270
  format: str = "memory",
@@ -1300,7 +1294,10 @@ class SortingAnalyzer:
1300
1294
  reloading waveforms if needed
1301
1295
  sparsity_overlap : float, default 0.75
1302
1296
  The percentage of overlap that units should share in order to accept merges. If this criteria is not
1303
- achieved, soft merging will not be possible and an error will be raised
1297
+ achieved for a pair of units, soft merging will not be applied to them.
1298
+ raise_error_if_overlap_fails : bool, default: True
1299
+ If True and `sparsity_overlap` fails for any unit merges, this will raise an error. If False, units which fail the
1300
+ `sparsity_overlap` threshold will be skipped in the merge.
1304
1301
  new_id_strategy : "append" | "take_first", default: "append"
1305
1302
  The strategy that should be used, if `new_unit_ids` is None, to create new unit_ids.
1306
1303
 
@@ -1333,15 +1330,43 @@ class SortingAnalyzer:
1333
1330
  if len(units) < 2:
1334
1331
  raise ValueError("Merging requires at least two units to merge")
1335
1332
 
1333
+ # remove units which do not pass the sparsity threshold
1334
+ if self.sparsity is not None and merging_mode == "soft":
1335
+
1336
+ mergeable = self.are_units_mergeable(
1337
+ merge_unit_groups,
1338
+ sparsity_overlap=sparsity_overlap,
1339
+ merging_mode=merging_mode,
1340
+ return_masks=False,
1341
+ )
1342
+
1343
+ mergeable_unit_groups = []
1344
+ unmergeable_unit_groups = []
1345
+ for merge_unit_group, mergeable in zip(merge_unit_groups, mergeable.values()):
1346
+ if mergeable:
1347
+ mergeable_unit_groups.append(merge_unit_group)
1348
+ else:
1349
+ unmergeable_unit_groups.append(merge_unit_group)
1350
+
1351
+ if len(unmergeable_unit_groups) > 0:
1352
+ if raise_error_if_overlap_fails:
1353
+ error_message = f"The sparsity of the units in the merge groups {unmergeable_unit_groups} do not overlap enough for a soft merge using a sparsity threshold of {sparsity_overlap}. Either lower your `sparsity_overlap` or use the flag `raise_error_if_overlap_fails = False` to skip these units in your merge."
1354
+ raise Exception(error_message)
1355
+ else:
1356
+ warning_message = f"The sparsity of the units in the merge groups {unmergeable_unit_groups} do not overlap enough for a soft merge using a sparsity threshold of {sparsity_overlap}. They will not be merged."
1357
+ warnings.warn(warning_message)
1358
+ else:
1359
+ mergeable_unit_groups = merge_unit_groups
1360
+
1336
1361
  new_unit_ids = generate_unit_ids_for_merge_group(
1337
- self.unit_ids, merge_unit_groups, new_unit_ids, new_id_strategy
1362
+ self.unit_ids, mergeable_unit_groups, new_unit_ids, new_id_strategy
1338
1363
  )
1339
- all_unit_ids = _get_ids_after_merging(self.unit_ids, merge_unit_groups, new_unit_ids=new_unit_ids)
1364
+ all_unit_ids = _get_ids_after_merging(self.unit_ids, mergeable_unit_groups, new_unit_ids=new_unit_ids)
1340
1365
 
1341
1366
  new_analyzer = self._save_or_select_or_merge_or_split(
1342
1367
  format=format,
1343
1368
  folder=folder,
1344
- merge_unit_groups=merge_unit_groups,
1369
+ merge_unit_groups=mergeable_unit_groups,
1345
1370
  unit_ids=all_unit_ids,
1346
1371
  censor_ms=censor_ms,
1347
1372
  merging_mode=merging_mode,
@@ -247,6 +247,18 @@ class ChannelSparsity:
247
247
 
248
248
  return sparse_templates
249
249
 
250
+ def densify_templates(self, templates_array: np.ndarray) -> np.ndarray:
251
+ assert templates_array.shape[0] == self.num_units
252
+
253
+ densified_shape = (self.num_units, templates_array.shape[1], self.num_channels)
254
+ dense_templates = np.zeros(shape=densified_shape, dtype=templates_array.dtype)
255
+ for unit_index, unit_id in enumerate(self.unit_ids):
256
+ sparse_template = templates_array[unit_index, ...]
257
+ dense_template = self.densify_waveforms(waveforms=sparse_template[np.newaxis, :, :], unit_id=unit_id)
258
+ dense_templates[unit_index, :, :] = dense_template
259
+
260
+ return dense_templates
261
+
250
262
  @classmethod
251
263
  def from_unit_id_to_channel_ids(cls, unit_id_to_channel_ids, unit_ids, channel_ids):
252
264
  """
@@ -44,7 +44,6 @@ def get_dense_templates_array(one_object: Templates | SortingAnalyzer, return_in
44
44
  raise ValueError("SortingAnalyzer need extension 'templates' to be computed to retrieve templates")
45
45
  else:
46
46
  raise ValueError("Input should be Templates or SortingAnalyzer")
47
-
48
47
  return templates_array
49
48
 
50
49
 
@@ -505,7 +505,11 @@ def extract_waveforms_to_single_buffer(
505
505
 
506
506
  n_samples = nbefore + nafter
507
507
 
508
- dtype = np.dtype(dtype)
508
+ if dtype is None:
509
+ dtype = recording.get_dtype()
510
+ else:
511
+ dtype = np.dtype(dtype)
512
+
509
513
  if mode == "shared_memory":
510
514
  assert file_path is None
511
515
  else:
@@ -537,7 +541,7 @@ def extract_waveforms_to_single_buffer(
537
541
 
538
542
  job_kwargs = fix_job_kwargs(job_kwargs)
539
543
 
540
- if num_spikes > 0:
544
+ if num_spikes > 0 and num_chans > 0:
541
545
  # and run
542
546
  func = _worker_distribute_single_buffer
543
547
  init_func = _init_worker_distribute_single_buffer
@@ -564,11 +568,14 @@ def extract_waveforms_to_single_buffer(
564
568
  return all_waveforms
565
569
  elif mode == "shared_memory":
566
570
  if copy:
571
+ wf_out = all_waveforms.copy()
572
+ del all_waveforms
567
573
  if shm is not None:
568
574
  # release all sharedmem buffer
569
575
  # empty array have None
576
+ shm.close()
570
577
  shm.unlink()
571
- return all_waveforms.copy()
578
+ return wf_out
572
579
  else:
573
580
  return all_waveforms, wf_array_info
574
581
 
@@ -744,12 +751,13 @@ def estimate_templates(
744
751
  operator: str = "average",
745
752
  return_scaled=None,
746
753
  return_in_uV=True,
754
+ sparsity_mask=None,
747
755
  job_name=None,
748
756
  **job_kwargs,
749
757
  ):
750
758
  """
751
759
  Estimate dense templates with "average" or "median".
752
- If "average" internally estimate_templates_with_accumulator() is used to saved memory/
760
+ If "average" internally estimate_templates_with_accumulator() is used to saved memory.
753
761
 
754
762
  Parameters
755
763
  ----------
@@ -770,6 +778,8 @@ def estimate_templates(
770
778
  return_in_uV : bool, default: True
771
779
  If True and the recording has scaling (gain_to_uV and offset_to_uV properties),
772
780
  traces are scaled to uV
781
+ sparsity_mask: None or array of bool, default: None
782
+ If not None shape must be must be (len(unit_ids), len(channel_ids))
773
783
 
774
784
  Returns
775
785
  -------
@@ -791,7 +801,15 @@ def estimate_templates(
791
801
 
792
802
  if operator == "average":
793
803
  templates_array = estimate_templates_with_accumulator(
794
- recording, spikes, unit_ids, nbefore, nafter, return_in_uV=return_in_uV, job_name=job_name, **job_kwargs
804
+ recording,
805
+ spikes,
806
+ unit_ids,
807
+ nbefore,
808
+ nafter,
809
+ return_in_uV=return_in_uV,
810
+ sparsity_mask=sparsity_mask,
811
+ job_name=job_name,
812
+ **job_kwargs,
795
813
  )
796
814
  elif operator == "median":
797
815
  all_waveforms, wf_array_info = extract_waveforms_to_single_buffer(
@@ -802,6 +820,8 @@ def estimate_templates(
802
820
  nafter,
803
821
  mode="shared_memory",
804
822
  return_in_uV=return_in_uV,
823
+ dtype="float32",
824
+ sparsity_mask=sparsity_mask,
805
825
  copy=False,
806
826
  **job_kwargs,
807
827
  )
@@ -812,6 +832,8 @@ def estimate_templates(
812
832
  wfs = all_waveforms[spikes["unit_index"] == unit_index]
813
833
  templates_array[unit_index, :, :] = np.median(wfs, axis=0)
814
834
  # release shared memory after the median
835
+ del all_waveforms
836
+ wf_array_info["shm"].close()
815
837
  wf_array_info["shm"].unlink()
816
838
 
817
839
  else:
@@ -828,6 +850,7 @@ def estimate_templates_with_accumulator(
828
850
  nafter: int,
829
851
  return_scaled=None,
830
852
  return_in_uV=True,
853
+ sparsity_mask=None,
831
854
  job_name=None,
832
855
  return_std: bool = False,
833
856
  verbose: bool = False,
@@ -859,6 +882,8 @@ def estimate_templates_with_accumulator(
859
882
  return_in_uV : bool, default: True
860
883
  If True and the recording has scaling (gain_to_uV and offset_to_uV properties),
861
884
  traces are scaled to uV
885
+ sparsity_mask: None or array of bool, default: None
886
+ If not None shape must be must be (len(unit_ids), len(channel_ids))
862
887
  return_std: bool, default: False
863
888
  If True, the standard deviation is also computed.
864
889
 
@@ -882,10 +907,14 @@ def estimate_templates_with_accumulator(
882
907
  job_kwargs = fix_job_kwargs(job_kwargs)
883
908
  num_worker = job_kwargs["n_jobs"]
884
909
 
885
- num_chans = recording.get_num_channels()
910
+ if sparsity_mask is None:
911
+ num_chans = int(recording.get_num_channels())
912
+ else:
913
+ num_chans = int(max(np.sum(sparsity_mask, axis=1))) # This is a numpy scalar, so we cast to int
886
914
  num_units = len(unit_ids)
887
915
 
888
916
  shape = (num_worker, num_units, nbefore + nafter, num_chans)
917
+
889
918
  dtype = np.dtype("float32")
890
919
  waveform_accumulator_per_worker, shm = make_shared_array(shape, dtype)
891
920
  shm_name = shm.name
@@ -909,6 +938,7 @@ def estimate_templates_with_accumulator(
909
938
  nbefore,
910
939
  nafter,
911
940
  return_in_uV,
941
+ sparsity_mask,
912
942
  )
913
943
 
914
944
  if job_name is None:
@@ -965,6 +995,7 @@ def _init_worker_estimate_templates(
965
995
  nbefore,
966
996
  nafter,
967
997
  return_in_uV,
998
+ sparsity_mask,
968
999
  ):
969
1000
  worker_dict = {}
970
1001
  worker_dict["recording"] = recording
@@ -972,6 +1003,7 @@ def _init_worker_estimate_templates(
972
1003
  worker_dict["nbefore"] = nbefore
973
1004
  worker_dict["nafter"] = nafter
974
1005
  worker_dict["return_in_uV"] = return_in_uV
1006
+ worker_dict["sparsity_mask"] = sparsity_mask
975
1007
 
976
1008
  from multiprocessing.shared_memory import SharedMemory
977
1009
  import multiprocessing
@@ -1009,6 +1041,7 @@ def _worker_estimate_templates(segment_index, start_frame, end_frame, worker_dic
1009
1041
  waveform_squared_accumulator_per_worker = worker_dict.get("waveform_squared_accumulator_per_worker", None)
1010
1042
  worker_index = worker_dict["worker_index"]
1011
1043
  return_in_uV = worker_dict["return_in_uV"]
1044
+ sparsity_mask = worker_dict["sparsity_mask"]
1012
1045
 
1013
1046
  seg_size = recording.get_num_samples(segment_index=segment_index)
1014
1047
 
@@ -1040,6 +1073,14 @@ def _worker_estimate_templates(segment_index, start_frame, end_frame, worker_dic
1040
1073
  unit_index = spikes[spike_index]["unit_index"]
1041
1074
  wf = traces[sample_index - start - nbefore : sample_index - start + nafter, :]
1042
1075
 
1043
- waveform_accumulator_per_worker[worker_index, unit_index, :, :] += wf
1044
- if waveform_squared_accumulator_per_worker is not None:
1045
- waveform_squared_accumulator_per_worker[worker_index, unit_index, :, :] += wf**2
1076
+ if sparsity_mask is None:
1077
+ waveform_accumulator_per_worker[worker_index, unit_index, :, :] += wf
1078
+ if waveform_squared_accumulator_per_worker is not None:
1079
+ waveform_squared_accumulator_per_worker[worker_index, unit_index, :, :] += wf**2
1080
+
1081
+ else:
1082
+ mask = sparsity_mask[unit_index, :]
1083
+ wf = wf[:, mask]
1084
+ waveform_accumulator_per_worker[worker_index, unit_index, :, : wf.shape[1]] += wf
1085
+ if waveform_squared_accumulator_per_worker is not None:
1086
+ waveform_squared_accumulator_per_worker[worker_index, unit_index, :, : wf.shape[1]] += wf**2
@@ -16,7 +16,7 @@ from .mergeunitssorting import MergeUnitsSorting, merge_units_sorting
16
16
  from .splitunitsorting import SplitUnitSorting, split_unit_sorting
17
17
 
18
18
  # curation format
19
- from .curation_format import validate_curation_dict, curation_label_to_dataframe, apply_curation
19
+ from .curation_format import validate_curation_dict, curation_label_to_dataframe, apply_curation, load_curation
20
20
 
21
21
  from .sortingview_curation import apply_sortingview_curation
22
22
 
@@ -74,7 +74,7 @@ _default_step_params = {
74
74
  "sigma_smooth_ms": 0.6,
75
75
  "adaptative_window_thresh": 0.5,
76
76
  },
77
- "template_similarity": {"template_diff_thresh": 0.25},
77
+ "template_similarity": {"similarity_method": "l1", "template_diff_thresh": 0.25},
78
78
  "presence_distance": {"presence_distance_thresh": 100},
79
79
  "knn": {"k_nn": 10},
80
80
  "cross_contamination": {
@@ -310,7 +310,13 @@ def compute_merge_unit_groups(
310
310
  # STEP : check if potential merge with CC also have template similarity
311
311
  elif step == "template_similarity":
312
312
  template_similarity_ext = sorting_analyzer.get_extension("template_similarity")
313
- templates_similarity = template_similarity_ext.get_data()
313
+ if template_similarity_ext.params["method"] == params["similarity_method"]:
314
+ templates_similarity = template_similarity_ext.get_data()
315
+ else:
316
+ template_similarity_ext = sorting_analyzer.compute(
317
+ "template_similarity", method=params["similarity_method"], save=False
318
+ )
319
+ templates_similarity = template_similarity_ext.get_data()
314
320
  templates_diff = 1 - templates_similarity
315
321
  pair_mask = pair_mask & (templates_diff < params["template_diff_thresh"])
316
322
  outs["templates_diff"] = templates_diff
@@ -1057,17 +1063,29 @@ def compute_cross_contaminations(analyzer, pair_mask, cc_thresh, refractory_peri
1057
1063
  CC = np.zeros((n, n), dtype=np.float32)
1058
1064
  p_values = np.zeros((n, n), dtype=np.float32)
1059
1065
 
1060
- for unit_ind1 in range(len(unit_ids)):
1066
+ if sorting.get_num_segments() > 1:
1067
+ # for multi-segment sortings, we need to concatenate segments,
1068
+ from spikeinterface import concatenate_sortings, select_segment_sorting
1069
+
1070
+ sorting_list = []
1071
+ total_samples_list = []
1072
+ for segment_index in range(sorting.get_num_segments()):
1073
+ sorting_list.append(select_segment_sorting(sorting, segment_index))
1074
+ total_samples_list.append(analyzer.get_num_samples(segment_index))
1075
+ # concatenate segments
1076
+ sorting_concat = concatenate_sortings(sorting_list=sorting_list, total_samples_list=total_samples_list)
1077
+ else:
1078
+ sorting_concat = sorting
1061
1079
 
1080
+ for unit_ind1 in range(len(unit_ids)):
1062
1081
  unit_id1 = unit_ids[unit_ind1]
1063
- spike_train1 = np.array(sorting.get_unit_spike_train(unit_id1))
1064
-
1082
+ spike_train1 = np.array(sorting_concat.get_unit_spike_train(unit_id1))
1065
1083
  for unit_ind2 in range(unit_ind1 + 1, len(unit_ids)):
1066
1084
  if not pair_mask[unit_ind1, unit_ind2]:
1067
1085
  continue
1068
1086
 
1069
1087
  unit_id2 = unit_ids[unit_ind2]
1070
- spike_train2 = np.array(sorting.get_unit_spike_train(unit_id2))
1088
+ spike_train2 = np.array(sorting_concat.get_unit_spike_train(unit_id2))
1071
1089
  # Compuyting the cross-contamination difference
1072
1090
  if contaminations is not None:
1073
1091
  C1 = contaminations[unit_ind1]
@@ -1194,8 +1212,8 @@ def presence_distance(sorting, unit1, unit2, bin_duration_s=2, bins=None, num_sa
1194
1212
  ns = num_samples[segment_index]
1195
1213
  bins = np.arange(0, ns, bin_size)
1196
1214
 
1197
- st1 = sorting.get_unit_spike_train(unit_id=unit1)
1198
- st2 = sorting.get_unit_spike_train(unit_id=unit2)
1215
+ st1 = sorting.get_unit_spike_train(unit_id=unit1, segment_index=segment_index)
1216
+ st2 = sorting.get_unit_spike_train(unit_id=unit2, segment_index=segment_index)
1199
1217
 
1200
1218
  h1, _ = np.histogram(st1, bins)
1201
1219
  h1 = h1.astype(float)
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from pathlib import Path
4
+ import json
3
5
  import numpy as np
4
6
  from itertools import chain
5
7
 
@@ -141,6 +143,7 @@ def apply_curation(
141
143
  new_id_strategy: str = "append",
142
144
  merging_mode: str = "soft",
143
145
  sparsity_overlap: float = 0.75,
146
+ raise_error_if_overlap_fails: bool = True,
144
147
  verbose: bool = False,
145
148
  **job_kwargs,
146
149
  ):
@@ -179,6 +182,9 @@ def apply_curation(
179
182
  sparsity_overlap : float, default 0.75
180
183
  The percentage of overlap that units should share in order to accept merges. If this criteria is not
181
184
  achieved, soft merging will not be possible and an error will be raised. This is for use with a SortingAnalyzer input.
185
+ raise_error_if_overlap_fails : bool, default: True
186
+ If True and `sparsity_overlap` fails for any unit merges, this will raise an error. If False, units which fail the
187
+ `sparsity_overlap` threshold will be skipped in the merge.
182
188
  verbose : bool, default: False
183
189
  If True, output is verbose
184
190
  **job_kwargs : dict
@@ -232,6 +238,7 @@ def apply_curation(
232
238
  censor_ms=censor_ms,
233
239
  merging_mode=merging_mode,
234
240
  sparsity_overlap=sparsity_overlap,
241
+ raise_error_if_overlap_fails=raise_error_if_overlap_fails,
235
242
  new_id_strategy=new_id_strategy,
236
243
  return_new_unit_ids=True,
237
244
  format="memory",
@@ -271,3 +278,22 @@ def apply_curation(
271
278
  )
272
279
 
273
280
  return curated_sorting_or_analyzer
281
+
282
+
283
+ def load_curation(curation_path: str | Path) -> CurationModel:
284
+ """
285
+ Loads a curation from a local json file.
286
+
287
+ Parameters
288
+ ----------
289
+ curation_path : str or Path
290
+ The path to the curation json file
291
+
292
+ Returns
293
+ -------
294
+ curation_model : CurationModel
295
+ A CurationModel object
296
+ """
297
+ with open(curation_path) as f:
298
+ curation_dict = json.load(f)
299
+ return CurationModel(**curation_dict)
@@ -188,14 +188,9 @@ class ModelBasedClassification:
188
188
  else:
189
189
  warnings.warn(warning_message)
190
190
 
191
- def _export_to_phy(self, classified_units):
191
+ def _export_to_phy(self, classified_df):
192
192
  """Export the classified units to Phy as cluster_prediction.tsv file"""
193
193
 
194
- import pandas as pd
195
-
196
- # Create a new DataFrame with unit_id, prediction, and probability columns from dict {unit_id: (prediction, probability)}
197
- classified_df = pd.DataFrame.from_dict(classified_units, orient="index", columns=["prediction", "probability"])
198
-
199
194
  # Export to Phy format
200
195
  try:
201
196
  sorting_path = self.sorting_analyzer.sorting.get_annotation("phy_folder")
@@ -665,14 +665,20 @@ _neo_event_dtype = np.dtype([("time", "float64"), ("duration", "float64"), ("lab
665
665
  class NeoBaseEventExtractor(_NeoBaseExtractor, BaseEvent):
666
666
  handle_event_frame_directly = False
667
667
 
668
- def __init__(self, block_index=None, **neo_kwargs):
668
+ def __init__(self, block_index=None, use_names_as_ids: bool = False, **neo_kwargs):
669
669
  _NeoBaseExtractor.__init__(self, block_index, **neo_kwargs)
670
670
 
671
671
  # TODO load feature from neo array_annotations
672
672
 
673
673
  event_channels = self.neo_reader.header["event_channels"]
674
674
 
675
- channel_ids = event_channels["id"]
675
+ if use_names_as_ids:
676
+ channel_ids = event_channels["name"]
677
+ assert (
678
+ event_channels.size == np.unique(channel_ids).size
679
+ ), "use_name_as_ids=True is not possible, channel names are not unique"
680
+ else:
681
+ channel_ids = event_channels["id"]
676
682
 
677
683
  BaseEvent.__init__(self, channel_ids, structured_dtype=_neo_event_dtype)
678
684
 
@@ -684,21 +690,23 @@ class NeoBaseEventExtractor(_NeoBaseExtractor, BaseEvent):
684
690
  else:
685
691
  t_start = self.neo_reader.get_signal_t_start(self.block_index, segment_index, stream_index=0)
686
692
 
687
- event_segment = NeoEventSegment(self.neo_reader, self.block_index, segment_index, t_start)
693
+ event_segment = NeoEventSegment(self.neo_reader, self.block_index, segment_index, t_start, use_names_as_ids)
688
694
  self.add_event_segment(event_segment)
689
695
 
690
696
 
691
697
  class NeoEventSegment(BaseEventSegment):
692
- def __init__(self, neo_reader, block_index, segment_index, t_start):
698
+ def __init__(self, neo_reader, block_index, segment_index, t_start, use_names_as_ids):
693
699
  BaseEventSegment.__init__(self)
694
700
  self.neo_reader = neo_reader
695
701
  self.segment_index = segment_index
696
702
  self.block_index = block_index
697
703
  self._t_start = t_start
698
704
  self._natural_ids = None
705
+ self.use_names_as_ids = use_names_as_ids
699
706
 
700
707
  def get_events(self, channel_id, start_time, end_time):
701
- channel_index = list(self.neo_reader.header["event_channels"]["id"]).index(channel_id)
708
+ id_or_name = "name" if self.use_names_as_ids else "id"
709
+ channel_index = list(self.neo_reader.header["event_channels"][id_or_name]).index(channel_id)
702
710
 
703
711
  event_timestamps, event_duration, event_labels = self.neo_reader.get_event_timestamps(
704
712
  block_index=self.block_index, seg_index=self.segment_index, event_channel_index=channel_index
@@ -118,14 +118,20 @@ class Plexon2EventExtractor(NeoBaseEventExtractor):
118
118
  Parameters
119
119
  ----------
120
120
  folder_path : str
121
+ Path to the .pl2 file.
122
+ block_index : int, default: None
123
+ Block index to read from, by default None.
124
+ use_names_as_ids : bool, default: False
125
+ If True, use channel names as identifiers instead of channel IDs.
126
+ Channel names must be unique when this option is enabled.
121
127
 
122
128
  """
123
129
 
124
130
  NeoRawIOClass = "Plexon2RawIO"
125
131
 
126
- def __init__(self, folder_path, block_index=None):
132
+ def __init__(self, folder_path, block_index=None, use_names_as_ids=False):
127
133
  neo_kwargs = self.map_to_neo_kwargs(folder_path)
128
- NeoBaseEventExtractor.__init__(self, block_index=block_index, **neo_kwargs)
134
+ NeoBaseEventExtractor.__init__(self, block_index=block_index, use_names_as_ids=use_names_as_ids, **neo_kwargs)
129
135
 
130
136
  @classmethod
131
137
  def map_to_neo_kwargs(cls, folder_path):
@@ -7,6 +7,8 @@ import numpy as np
7
7
  from numpy.typing import ArrayLike
8
8
  from spikeinterface.core import BaseRecording, BaseRecordingSegment, BaseSorting, Templates
9
9
 
10
+ from probeinterface import Probe
11
+
10
12
 
11
13
  def interpolate_templates(templates_array, source_locations, dest_locations, interpolation_method="cubic"):
12
14
  """