spikeinterface 0.102.2__tar.gz → 0.103.0__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 (377) hide show
  1. {spikeinterface-0.102.2/src/spikeinterface.egg-info → spikeinterface-0.103.0}/PKG-INFO +18 -15
  2. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/README.md +1 -1
  3. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/pyproject.toml +30 -19
  4. spikeinterface-0.103.0/src/spikeinterface/benchmark/__init__.py +9 -0
  5. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/benchmark/benchmark_base.py +168 -35
  6. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/benchmark/benchmark_clustering.py +22 -16
  7. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/benchmark/benchmark_matching.py +29 -47
  8. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/benchmark/benchmark_merging.py +4 -2
  9. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/benchmark/benchmark_motion_estimation.py +2 -2
  10. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/benchmark/benchmark_motion_interpolation.py +1 -1
  11. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/benchmark/benchmark_peak_detection.py +67 -43
  12. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/benchmark/benchmark_peak_selection.py +2 -2
  13. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/benchmark/benchmark_plot_tools.py +381 -208
  14. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/benchmark/benchmark_sorter.py +6 -66
  15. spikeinterface-0.103.0/src/spikeinterface/benchmark/benchmark_sorter_without_gt.py +210 -0
  16. spikeinterface-0.103.0/src/spikeinterface/benchmark/residual_analysis.py +71 -0
  17. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/comparison/basecomparison.py +1 -1
  18. spikeinterface-0.103.0/src/spikeinterface/comparison/collision.py +242 -0
  19. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/comparison/comparisontools.py +45 -19
  20. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/comparison/hybrid.py +20 -0
  21. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/comparison/multicomparisons.py +0 -57
  22. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/comparison/paircomparisons.py +3 -4
  23. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/__init__.py +15 -8
  24. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/analyzer_extension_core.py +69 -12
  25. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/base.py +1 -5
  26. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/baserecording.py +71 -71
  27. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/baserecordingsnippets.py +1 -48
  28. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/basesnippets.py +75 -13
  29. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/basesorting.py +217 -67
  30. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/binaryrecordingextractor.py +21 -0
  31. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/channelsaggregationrecording.py +26 -33
  32. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/core_tools.py +9 -1
  33. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/frameslicerecording.py +11 -15
  34. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/generate.py +48 -11
  35. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/job_tools.py +26 -18
  36. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/loading.py +29 -3
  37. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/node_pipeline.py +3 -3
  38. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/recording_tools.py +60 -66
  39. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/snippets_tools.py +1 -1
  40. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/sorting_tools.py +380 -10
  41. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/sortinganalyzer.py +303 -107
  42. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/sparsity.py +22 -63
  43. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/template.py +37 -9
  44. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/template_tools.py +32 -20
  45. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/testing.py +40 -9
  46. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/unitsaggregationsorting.py +27 -10
  47. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/waveform_tools.py +86 -33
  48. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/waveforms_extractor_backwards_compatibility.py +6 -7
  49. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/zarrextractors.py +37 -36
  50. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/curation/auto_merge.py +9 -4
  51. spikeinterface-0.103.0/src/spikeinterface/curation/curation_format.py +322 -0
  52. spikeinterface-0.103.0/src/spikeinterface/curation/curation_model.py +409 -0
  53. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/curation/curation_tools.py +2 -2
  54. spikeinterface-0.103.0/src/spikeinterface/curation/sortingview_curation.py +128 -0
  55. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/curation/splitunitsorting.py +1 -1
  56. spikeinterface-0.103.0/src/spikeinterface/exporters/__init__.py +4 -0
  57. spikeinterface-0.103.0/src/spikeinterface/exporters/to_ibl.py +311 -0
  58. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/exporters/to_phy.py +1 -1
  59. spikeinterface-0.103.0/src/spikeinterface/exporters/to_pynapple.py +93 -0
  60. spikeinterface-0.103.0/src/spikeinterface/extractors/__init__.py +64 -0
  61. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/cbin_ibl.py +1 -1
  62. spikeinterface-0.103.0/src/spikeinterface/extractors/extractor_classes.py +206 -0
  63. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/hdsortextractors.py +1 -1
  64. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/iblextractors.py +27 -14
  65. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/klustaextractors.py +1 -1
  66. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/matlabhelpers.py +20 -7
  67. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/mcsh5extractors.py +7 -3
  68. spikeinterface-0.103.0/src/spikeinterface/extractors/neoextractors/__init__.py +105 -0
  69. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/alphaomega.py +0 -1
  70. spikeinterface-0.103.0/src/spikeinterface/extractors/neoextractors/axon.py +66 -0
  71. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/biocam.py +15 -3
  72. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/blackrock.py +11 -8
  73. spikeinterface-0.103.0/src/spikeinterface/extractors/neoextractors/intan.py +211 -0
  74. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/maxwell.py +2 -2
  75. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/neo_utils.py +4 -5
  76. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/neobaseextractor.py +4 -4
  77. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/neuronexus.py +1 -1
  78. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/neuroscope.py +67 -0
  79. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/openephys.py +116 -102
  80. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/spikeglx.py +41 -40
  81. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neuropixels_utils.py +75 -8
  82. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/nwbextractors.py +70 -59
  83. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/phykilosortextractors.py +2 -2
  84. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/shybridextractors.py +21 -15
  85. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/tridesclousextractors.py +0 -1
  86. spikeinterface-0.103.0/src/spikeinterface/extractors/whitematterrecordingextractor.py +95 -0
  87. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/generation/drift_tools.py +1 -1
  88. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/generation/drifting_generator.py +66 -20
  89. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/generation/hybrid_tools.py +4 -2
  90. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/generation/template_database.py +0 -1
  91. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/postprocessing/__init__.py +2 -0
  92. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/postprocessing/amplitude_scalings.py +11 -8
  93. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/postprocessing/correlograms.py +441 -14
  94. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/postprocessing/isi.py +25 -1
  95. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/postprocessing/localization_tools.py +7 -7
  96. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/postprocessing/principal_component.py +6 -2
  97. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/postprocessing/spike_amplitudes.py +26 -32
  98. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/postprocessing/spike_locations.py +15 -1
  99. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/postprocessing/template_metrics.py +24 -5
  100. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/postprocessing/template_similarity.py +65 -7
  101. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/postprocessing/unit_locations.py +25 -1
  102. spikeinterface-0.103.0/src/spikeinterface/preprocessing/__init__.py +55 -0
  103. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/correct_lsb.py +1 -1
  104. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/detect_bad_channels.py +151 -66
  105. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/filter.py +24 -1
  106. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/interpolate_bad_channels.py +60 -1
  107. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/motion.py +291 -113
  108. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/normalize_scale.py +2 -2
  109. spikeinterface-0.103.0/src/spikeinterface/preprocessing/pipeline.py +356 -0
  110. spikeinterface-0.103.0/src/spikeinterface/preprocessing/preprocessing_classes.py +102 -0
  111. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/remove_artifacts.py +1 -1
  112. spikeinterface-0.103.0/src/spikeinterface/preprocessing/scale.py +104 -0
  113. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/silence_periods.py +1 -1
  114. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/whiten.py +1 -1
  115. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/qualitymetrics/misc_metrics.py +180 -18
  116. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/qualitymetrics/pca_metrics.py +1 -23
  117. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/qualitymetrics/quality_metric_calculator.py +28 -0
  118. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/qualitymetrics/quality_metric_list.py +5 -1
  119. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/container_tools.py +0 -1
  120. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/combinato.py +2 -2
  121. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/hdsort.py +1 -1
  122. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/herdingspikes.py +1 -1
  123. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/ironclust.py +1 -1
  124. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/kilosort.py +106 -32
  125. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/kilosort4.py +80 -16
  126. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/kilosortbase.py +1 -1
  127. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/klusta.py +1 -1
  128. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/mountainsort4.py +1 -1
  129. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/mountainsort5.py +1 -1
  130. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/pykilosort.py +1 -1
  131. spikeinterface-0.103.0/src/spikeinterface/sorters/external/rt_sort.py +192 -0
  132. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/spyking_circus.py +1 -1
  133. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/tridesclous.py +1 -1
  134. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/waveclus.py +6 -5
  135. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/waveclus_snippets.py +2 -2
  136. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/yass.py +1 -1
  137. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/internal/simplesorter.py +6 -1
  138. spikeinterface-0.103.0/src/spikeinterface/sorters/internal/spyking_circus2.py +526 -0
  139. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/internal/tridesclous2.py +127 -45
  140. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/launcher.py +59 -55
  141. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/runsorter.py +78 -45
  142. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/sorterlist.py +20 -1
  143. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/utils/__init__.py +1 -1
  144. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/utils/misc.py +13 -18
  145. spikeinterface-0.103.0/src/spikeinterface/sortingcomponents/clustering/__init__.py +5 -0
  146. spikeinterface-0.103.0/src/spikeinterface/sortingcomponents/clustering/circus.py +269 -0
  147. spikeinterface-0.103.0/src/spikeinterface/sortingcomponents/clustering/graph_clustering.py +211 -0
  148. spikeinterface-0.103.0/src/spikeinterface/sortingcomponents/clustering/graph_tools.py +230 -0
  149. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/main.py +2 -0
  150. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/merge.py +84 -4
  151. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/method_list.py +7 -4
  152. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/peak_svd.py +72 -26
  153. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/position_and_features.py +4 -4
  154. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/position_and_pca.py +3 -3
  155. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/random_projections.py +3 -3
  156. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/sliding_hdbscan.py +4 -4
  157. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/sliding_nn.py +1 -1
  158. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/split.py +73 -16
  159. spikeinterface-0.103.0/src/spikeinterface/sortingcomponents/clustering/tdc.py +217 -0
  160. spikeinterface-0.103.0/src/spikeinterface/sortingcomponents/clustering/tools.py +361 -0
  161. spikeinterface-0.103.0/src/spikeinterface/sortingcomponents/matching/__init__.py +5 -0
  162. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/matching/base.py +8 -0
  163. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/matching/circus.py +57 -10
  164. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/matching/main.py +29 -5
  165. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/matching/method_list.py +2 -1
  166. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/matching/naive.py +1 -1
  167. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/matching/tdc.py +7 -3
  168. spikeinterface-0.103.0/src/spikeinterface/sortingcomponents/matching/tools.py +138 -0
  169. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/matching/wobble.py +42 -1
  170. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/motion/motion_interpolation.py +5 -3
  171. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/motion/motion_utils.py +4 -2
  172. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/peak_detection.py +6 -7
  173. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/tools.py +188 -12
  174. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/waveforms/temporal_pca.py +50 -15
  175. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/waveforms/waveform_thresholder.py +1 -1
  176. spikeinterface-0.103.0/src/spikeinterface/widgets/amplitudes.py +198 -0
  177. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/collision.py +22 -11
  178. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/crosscorrelograms.py +1 -1
  179. spikeinterface-0.103.0/src/spikeinterface/widgets/drift_templates.py +136 -0
  180. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/isi_distribution.py +30 -10
  181. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/motion.py +93 -31
  182. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/rasters.py +169 -56
  183. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/sorting_summary.py +1 -1
  184. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/spikes_on_traces.py +20 -4
  185. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/traces.py +34 -23
  186. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/unit_locations.py +29 -8
  187. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/unit_presence.py +23 -11
  188. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/unit_probe_map.py +1 -1
  189. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/unit_waveforms.py +17 -4
  190. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/utils.py +72 -0
  191. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/widget_list.py +8 -0
  192. {spikeinterface-0.102.2 → spikeinterface-0.103.0/src/spikeinterface.egg-info}/PKG-INFO +18 -15
  193. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface.egg-info/SOURCES.txt +15 -4
  194. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface.egg-info/requires.txt +25 -13
  195. spikeinterface-0.102.2/setup.py +0 -7
  196. spikeinterface-0.102.2/src/spikeinterface/benchmark/__init__.py +0 -7
  197. spikeinterface-0.102.2/src/spikeinterface/comparison/collision.py +0 -248
  198. spikeinterface-0.102.2/src/spikeinterface/curation/curation_format.py +0 -367
  199. spikeinterface-0.102.2/src/spikeinterface/curation/sortingview_curation.py +0 -229
  200. spikeinterface-0.102.2/src/spikeinterface/exporters/__init__.py +0 -2
  201. spikeinterface-0.102.2/src/spikeinterface/extractors/__init__.py +0 -9
  202. spikeinterface-0.102.2/src/spikeinterface/extractors/extractorlist.py +0 -144
  203. spikeinterface-0.102.2/src/spikeinterface/extractors/neoextractors/__init__.py +0 -83
  204. spikeinterface-0.102.2/src/spikeinterface/extractors/neoextractors/intan.py +0 -106
  205. spikeinterface-0.102.2/src/spikeinterface/preprocessing/__init__.py +0 -11
  206. spikeinterface-0.102.2/src/spikeinterface/preprocessing/preprocessinglist.py +0 -84
  207. spikeinterface-0.102.2/src/spikeinterface/preprocessing/scale.py +0 -43
  208. spikeinterface-0.102.2/src/spikeinterface/sorters/internal/spyking_circus2.py +0 -427
  209. spikeinterface-0.102.2/src/spikeinterface/sortingcomponents/clustering/__init__.py +0 -3
  210. spikeinterface-0.102.2/src/spikeinterface/sortingcomponents/clustering/circus.py +0 -317
  211. spikeinterface-0.102.2/src/spikeinterface/sortingcomponents/clustering/tdc.py +0 -242
  212. spikeinterface-0.102.2/src/spikeinterface/sortingcomponents/clustering/tools.py +0 -194
  213. spikeinterface-0.102.2/src/spikeinterface/sortingcomponents/matching/__init__.py +0 -3
  214. spikeinterface-0.102.2/src/spikeinterface/sortingcomponents/peak_pipeline.py +0 -45
  215. spikeinterface-0.102.2/src/spikeinterface/widgets/amplitudes.py +0 -149
  216. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/LICENSE +0 -0
  217. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/setup.cfg +0 -0
  218. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/__init__.py +0 -0
  219. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/benchmark/benchmark_peak_localization.py +0 -0
  220. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/benchmark/benchmark_tools.py +0 -0
  221. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/comparison/__init__.py +0 -0
  222. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/comparison/correlogram.py +0 -0
  223. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/comparison/groundtruthstudy.py +0 -0
  224. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/baseevent.py +0 -0
  225. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/binaryfolder.py +0 -0
  226. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/channelslice.py +0 -0
  227. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/datasets.py +0 -0
  228. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/frameslicesorting.py +0 -0
  229. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/globals.py +0 -0
  230. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/motion.py +0 -0
  231. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/npyfoldersnippets.py +0 -0
  232. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/npysnippetsextractor.py +0 -0
  233. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/npzfolder.py +0 -0
  234. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/npzsortingextractor.py +0 -0
  235. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/numpyextractors.py +0 -0
  236. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/old_api_utils.py +0 -0
  237. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/segmentutils.py +0 -0
  238. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/sortingfolder.py +0 -0
  239. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/testing_tools.py +0 -0
  240. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/unitsselectionsorting.py +0 -0
  241. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/core/zarrrecordingextractor.py +0 -0
  242. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/curation/__init__.py +0 -0
  243. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/curation/curationsorting.py +0 -0
  244. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/curation/mergeunitssorting.py +0 -0
  245. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/curation/model_based_curation.py +0 -0
  246. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/curation/remove_duplicated_spikes.py +0 -0
  247. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/curation/remove_excess_spikes.py +0 -0
  248. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/curation/remove_redundant.py +0 -0
  249. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/curation/train_manual_curation.py +0 -0
  250. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/exporters/report.py +0 -0
  251. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/alfsortingextractor.py +0 -0
  252. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/bids.py +0 -0
  253. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/cellexplorersortingextractor.py +0 -0
  254. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/combinatoextractors.py +0 -0
  255. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/herdingspikesextractors.py +0 -0
  256. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/mclustextractors.py +0 -0
  257. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/mdaextractors.py +0 -0
  258. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/axona.py +0 -0
  259. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/ced.py +0 -0
  260. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/edf.py +0 -0
  261. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/mcsraw.py +0 -0
  262. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/mearec.py +0 -0
  263. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/neuralynx.py +0 -0
  264. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/neuroexplorer.py +0 -0
  265. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/nix.py +0 -0
  266. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/plexon.py +0 -0
  267. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/plexon2.py +0 -0
  268. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/spike2.py +0 -0
  269. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/spikegadgets.py +0 -0
  270. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/neoextractors/tdt.py +0 -0
  271. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/sinapsrecordingextractors.py +0 -0
  272. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/spykingcircusextractors.py +0 -0
  273. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/toy_example.py +0 -0
  274. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/waveclussnippetstextractors.py +0 -0
  275. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/waveclustextractors.py +0 -0
  276. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/extractors/yassextractors.py +0 -0
  277. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/full.py +0 -0
  278. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/generation/__init__.py +0 -0
  279. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/generation/noise_tools.py +0 -0
  280. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/generation/splitting_tools.py +0 -0
  281. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/postprocessing/alignsorting.py +0 -0
  282. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/postprocessing/noise_level.py +0 -0
  283. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/align_snippets.py +0 -0
  284. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/astype.py +0 -0
  285. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/average_across_direction.py +0 -0
  286. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/basepreprocessor.py +0 -0
  287. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/clip.py +0 -0
  288. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/common_reference.py +0 -0
  289. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/decimate.py +0 -0
  290. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/deepinterpolation/__init__.py +0 -0
  291. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/deepinterpolation/deepinterpolation.py +0 -0
  292. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/deepinterpolation/generators.py +0 -0
  293. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/deepinterpolation/tf_utils.py +0 -0
  294. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/deepinterpolation/train.py +0 -0
  295. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/depth_order.py +0 -0
  296. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/directional_derivative.py +0 -0
  297. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/filter_gaussian.py +0 -0
  298. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/filter_opencl.py +0 -0
  299. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/highpass_spatial_filter.py +0 -0
  300. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/phase_shift.py +0 -0
  301. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/preprocessing_tools.py +0 -0
  302. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/rectify.py +0 -0
  303. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/resample.py +0 -0
  304. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/unsigned_to_signed.py +0 -0
  305. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/preprocessing/zero_channel_pad.py +0 -0
  306. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/qualitymetrics/__init__.py +0 -0
  307. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/qualitymetrics/utils.py +0 -0
  308. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/__init__.py +0 -0
  309. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/basesorter.py +0 -0
  310. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/__init__.py +0 -0
  311. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/hdsort_master.m +0 -0
  312. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/kilosort2.py +0 -0
  313. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/kilosort2_5.py +0 -0
  314. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/kilosort2_5_master.m +0 -0
  315. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/kilosort2_master.m +0 -0
  316. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/kilosort3.py +0 -0
  317. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/kilosort3_master.m +0 -0
  318. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/kilosort_master.m +0 -0
  319. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/klusta_config_default.prm +0 -0
  320. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/sc_config_default.params +0 -0
  321. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/waveclus_master.m +0 -0
  322. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/waveclus_snippets_master.m +0 -0
  323. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/external/yass_config_default.yaml +0 -0
  324. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/internal/__init__.py +0 -0
  325. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/internal/si_based.py +0 -0
  326. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/utils/constructNPYheader.m +0 -0
  327. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/utils/shellscript.py +0 -0
  328. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sorters/utils/writeNPY.m +0 -0
  329. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/__init__.py +0 -0
  330. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/clean.py +0 -0
  331. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/clustering_tools.py +0 -0
  332. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/dummy.py +0 -0
  333. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/isocut5.py +0 -0
  334. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/position.py +0 -0
  335. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/position_ptp_scaled.py +0 -0
  336. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/clustering/triage.py +0 -0
  337. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/features_from_peaks.py +0 -0
  338. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/motion/__init__.py +0 -0
  339. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/motion/decentralized.py +0 -0
  340. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/motion/dredge.py +0 -0
  341. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/motion/iterative_template.py +0 -0
  342. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/motion/medicine.py +0 -0
  343. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/motion/motion_cleaner.py +0 -0
  344. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/motion/motion_estimation.py +0 -0
  345. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/peak_localization.py +0 -0
  346. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/peak_selection.py +0 -0
  347. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/waveforms/__init__.py +0 -0
  348. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/waveforms/hanning_filter.py +0 -0
  349. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/waveforms/neural_network_denoiser.py +0 -0
  350. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/waveforms/savgol_denoiser.py +0 -0
  351. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/sortingcomponents/waveforms/waveform_utils.py +0 -0
  352. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/__init__.py +0 -0
  353. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/all_amplitudes_distributions.py +0 -0
  354. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/autocorrelograms.py +0 -0
  355. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/base.py +0 -0
  356. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/comparison.py +0 -0
  357. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/gtstudy.py +0 -0
  358. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/metrics.py +0 -0
  359. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/multicomparison.py +0 -0
  360. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/peak_activity.py +0 -0
  361. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/peaks_on_probe.py +0 -0
  362. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/potential_merges.py +0 -0
  363. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/probe_map.py +0 -0
  364. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/quality_metrics.py +0 -0
  365. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/spike_locations.py +0 -0
  366. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/spike_locations_by_time.py +0 -0
  367. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/template_metrics.py +0 -0
  368. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/template_similarity.py +0 -0
  369. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/unit_depths.py +0 -0
  370. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/unit_summary.py +0 -0
  371. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/unit_templates.py +0 -0
  372. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/unit_waveforms_density_map.py +0 -0
  373. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/utils_ipywidgets.py +0 -0
  374. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/utils_matplotlib.py +0 -0
  375. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface/widgets/utils_sortingview.py +0 -0
  376. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/src/spikeinterface.egg-info/dependency_links.txt +0 -0
  377. {spikeinterface-0.102.2 → spikeinterface-0.103.0}/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.102.2
3
+ Version: 0.103.0
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
@@ -22,22 +22,24 @@ Requires-Dist: numpy>=2.0.0; python_version >= "3.13"
22
22
  Requires-Dist: threadpoolctl>=3.0.0
23
23
  Requires-Dist: tqdm
24
24
  Requires-Dist: zarr<3,>=2.18
25
- Requires-Dist: neo>=0.14.0
26
- Requires-Dist: probeinterface>=0.2.23
25
+ Requires-Dist: neo>=0.14.1
26
+ Requires-Dist: probeinterface>=0.3.0
27
27
  Requires-Dist: packaging
28
+ Requires-Dist: pydantic
29
+ Requires-Dist: numcodecs<0.16.0
28
30
  Provides-Extra: extractors
29
31
  Requires-Dist: MEArec>=1.8; extra == "extractors"
30
32
  Requires-Dist: pynwb>=2.6.0; extra == "extractors"
31
33
  Requires-Dist: hdmf-zarr>=0.11.0; extra == "extractors"
32
- Requires-Dist: pyedflib<0.1.39,>=0.1.30; extra == "extractors"
34
+ Requires-Dist: pyedflib>=0.1.30; extra == "extractors"
33
35
  Requires-Dist: sonpy; python_version < "3.10" and extra == "extractors"
34
36
  Requires-Dist: lxml; extra == "extractors"
35
37
  Requires-Dist: scipy; extra == "extractors"
36
- Requires-Dist: ibllib; extra == "extractors"
38
+ Requires-Dist: ibllib>=3.4.1; python_version >= "3.10" and extra == "extractors"
37
39
  Requires-Dist: pymatreader>=0.0.32; extra == "extractors"
38
40
  Requires-Dist: zugbruecke>=0.2; sys_platform != "win32" and extra == "extractors"
39
41
  Provides-Extra: streaming-extractors
40
- Requires-Dist: ibllib; extra == "streaming-extractors"
42
+ Requires-Dist: ibllib>=3.4.1; python_version >= "3.10" and extra == "streaming-extractors"
41
43
  Requires-Dist: pynwb>=2.6.0; extra == "streaming-extractors"
42
44
  Requires-Dist: fsspec; extra == "streaming-extractors"
43
45
  Requires-Dist: aiohttp; extra == "streaming-extractors"
@@ -56,7 +58,7 @@ Requires-Dist: networkx; extra == "full"
56
58
  Requires-Dist: distinctipy; extra == "full"
57
59
  Requires-Dist: matplotlib>=3.6; extra == "full"
58
60
  Requires-Dist: cuda-python; platform_system != "Darwin" and extra == "full"
59
- Requires-Dist: numba; extra == "full"
61
+ Requires-Dist: numba>=0.59; extra == "full"
60
62
  Requires-Dist: skops; extra == "full"
61
63
  Requires-Dist: huggingface_hub; extra == "full"
62
64
  Provides-Extra: widgets
@@ -70,23 +72,24 @@ Requires-Dist: scipy; extra == "qualitymetrics"
70
72
  Requires-Dist: pandas; extra == "qualitymetrics"
71
73
  Requires-Dist: numba; extra == "qualitymetrics"
72
74
  Provides-Extra: test-core
73
- Requires-Dist: pytest; extra == "test-core"
75
+ Requires-Dist: pytest<8.4.0; extra == "test-core"
74
76
  Requires-Dist: pytest-dependency; extra == "test-core"
75
77
  Requires-Dist: psutil; extra == "test-core"
78
+ Requires-Dist: pytest-mock; extra == "test-core"
76
79
  Provides-Extra: test-extractors
77
80
  Requires-Dist: pooch>=1.8.2; extra == "test-extractors"
78
81
  Requires-Dist: datalad>=1.0.2; extra == "test-extractors"
79
82
  Provides-Extra: test-preprocessing
80
- Requires-Dist: ibllib; extra == "test-preprocessing"
83
+ Requires-Dist: ibllib>=3.4.1; python_version >= "3.10" and extra == "test-preprocessing"
81
84
  Requires-Dist: torch; extra == "test-preprocessing"
82
85
  Provides-Extra: test
83
- Requires-Dist: pytest; extra == "test"
86
+ Requires-Dist: pytest<8.4.0; extra == "test"
84
87
  Requires-Dist: pytest-dependency; extra == "test"
85
88
  Requires-Dist: pytest-cov; extra == "test"
86
89
  Requires-Dist: psutil; extra == "test"
87
- Requires-Dist: huggingface_hub; extra == "test"
88
- Requires-Dist: ibllib; extra == "test"
90
+ Requires-Dist: ibllib>=3.4.1; python_version >= "3.10" and extra == "test"
89
91
  Requires-Dist: s3fs; extra == "test"
92
+ Requires-Dist: pynapple; extra == "test"
90
93
  Requires-Dist: numba<0.61.0; python_version < "3.13" and extra == "test"
91
94
  Requires-Dist: numba>=0.61.0; python_version >= "3.13" and extra == "test"
92
95
  Requires-Dist: hdbscan>=0.8.33; extra == "test"
@@ -94,6 +97,7 @@ Requires-Dist: sortingview>=0.12.0; extra == "test"
94
97
  Requires-Dist: torch; extra == "test"
95
98
  Requires-Dist: skops; extra == "test"
96
99
  Requires-Dist: huggingface_hub; extra == "test"
100
+ Requires-Dist: pytest-mock; extra == "test"
97
101
  Provides-Extra: docs
98
102
  Requires-Dist: Sphinx; extra == "docs"
99
103
  Requires-Dist: sphinx_rtd_theme>=1.2; extra == "docs"
@@ -109,8 +113,7 @@ Requires-Dist: numba; extra == "docs"
109
113
  Requires-Dist: networkx; extra == "docs"
110
114
  Requires-Dist: skops; extra == "docs"
111
115
  Requires-Dist: scikit-learn; extra == "docs"
112
- Requires-Dist: pooch>=1.8.2; extra == "docs"
113
- Requires-Dist: datalad>=1.0.2; extra == "docs"
116
+ Requires-Dist: huggingface_hub; extra == "docs"
114
117
  Provides-Extra: dev
115
118
  Requires-Dist: spikeinterface[test]; extra == "dev"
116
119
  Requires-Dist: spikeinterface[test_core]; extra == "dev"
@@ -255,4 +258,4 @@ If you find SpikeInterface useful in your research, please cite:
255
258
  ```
256
259
 
257
260
  Please also cite other relevant papers for the specific components you use.
258
- For a ful list of references, please check the [references](https://spikeinterface.readthedocs.io/en/latest/references.html) page.
261
+ For a full list of references, please check the [references](https://spikeinterface.readthedocs.io/en/latest/references.html) page.
@@ -134,4 +134,4 @@ If you find SpikeInterface useful in your research, please cite:
134
134
  ```
135
135
 
136
136
  Please also cite other relevant papers for the specific components you use.
137
- For a ful list of references, please check the [references](https://spikeinterface.readthedocs.io/en/latest/references.html) page.
137
+ For a full list of references, please check the [references](https://spikeinterface.readthedocs.io/en/latest/references.html) page.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "spikeinterface"
3
- version = "0.102.2"
3
+ version = "0.103.0"
4
4
  authors = [
5
5
  { name="Alessio Buccino", email="alessiop.buccino@gmail.com" },
6
6
  { name="Samuel Garcia", email="sam.garcia.die@gmail.com" },
@@ -25,9 +25,11 @@ dependencies = [
25
25
  "threadpoolctl>=3.0.0",
26
26
  "tqdm",
27
27
  "zarr>=2.18,<3",
28
- "neo>=0.14.0",
29
- "probeinterface>=0.2.23",
28
+ "neo>=0.14.1",
29
+ "probeinterface>=0.3.0",
30
30
  "packaging",
31
+ "pydantic",
32
+ "numcodecs<0.16.0", # For supporting zarr < 3
31
33
  ]
32
34
 
33
35
  [build-system]
@@ -63,17 +65,17 @@ extractors = [
63
65
  "MEArec>=1.8",
64
66
  "pynwb>=2.6.0",
65
67
  "hdmf-zarr>=0.11.0",
66
- "pyedflib>=0.1.30,<0.1.39",
68
+ "pyedflib>=0.1.30",
67
69
  "sonpy;python_version<'3.10'",
68
70
  "lxml", # lxml for neuroscope
69
71
  "scipy",
70
- "ibllib", # streaming IBL
72
+ "ibllib>=3.4.1;python_version>='3.10'", # streaming IBL
71
73
  "pymatreader>=0.0.32", # For cell explorer matlab files
72
74
  "zugbruecke>=0.2; sys_platform!='win32'", # For plexon2
73
75
  ]
74
76
 
75
77
  streaming_extractors = [
76
- "ibllib", # streaming IBL
78
+ "ibllib>=3.4.1;python_version>='3.10'", # streaming IBL
77
79
  # Following dependencies are for streaming with nwb files
78
80
  "pynwb>=2.6.0",
79
81
  "fsspec",
@@ -99,7 +101,7 @@ full = [
99
101
  "distinctipy",
100
102
  "matplotlib>=3.6", # matplotlib.colormaps
101
103
  "cuda-python; platform_system != 'Darwin'",
102
- "numba",
104
+ "numba>=0.59",
103
105
  "skops",
104
106
  "huggingface_hub"
105
107
  ]
@@ -119,7 +121,7 @@ qualitymetrics = [
119
121
  ]
120
122
 
121
123
  test_core = [
122
- "pytest",
124
+ "pytest<8.4.0",
123
125
  "pytest-dependency",
124
126
  "psutil",
125
127
 
@@ -127,6 +129,9 @@ test_core = [
127
129
  # for release we need pypi, so this need to be commented
128
130
  # "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git",
129
131
  # "neo @ git+https://github.com/NeuralEnsemble/python-neo.git",
132
+
133
+ # for slurm jobs,
134
+ "pytest-mock"
130
135
  ]
131
136
 
132
137
  test_extractors = [
@@ -139,30 +144,35 @@ test_extractors = [
139
144
  ]
140
145
 
141
146
  test_preprocessing = [
142
- "ibllib", # for IBL
147
+ "ibllib>=3.4.1;python_version>='3.10'", # streaming IBL
143
148
  "torch",
144
149
  ]
145
150
 
146
151
 
147
152
  test = [
148
- "pytest",
153
+ "pytest<8.4.0",
149
154
  "pytest-dependency",
150
155
  "pytest-cov",
151
156
  "psutil",
152
157
 
153
- "huggingface_hub",
154
-
155
158
  # preprocessing
156
- "ibllib", # for IBL
159
+ "ibllib>=3.4.1;python_version>='3.10'",
157
160
 
158
161
  # streaming templates
159
162
  "s3fs",
160
163
 
161
- # tridesclous
164
+ # exporters
165
+ "pynapple",
166
+
167
+ # tridesclous2
162
168
  "numba<0.61.0;python_version<'3.13'",
163
169
  "numba>=0.61.0;python_version>='3.13'",
164
170
  "hdbscan>=0.8.33", # Previous version had a broken wheel
165
171
 
172
+ # isosplit is needed for trideclous2 noramaly but isosplit is only build until python3.11
173
+ # so lets wait a new build of isosplit6
174
+ # "isosplit6",
175
+
166
176
  # for sortingview backend
167
177
  "sortingview>=0.12.0",
168
178
 
@@ -177,6 +187,9 @@ test = [
177
187
  # for release we need pypi, so this need to be commented
178
188
  # "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git",
179
189
  # "neo @ git+https://github.com/NeuralEnsemble/python-neo.git",
190
+
191
+ # for slurm jobs
192
+ "pytest-mock",
180
193
  ]
181
194
 
182
195
  docs = [
@@ -194,11 +207,9 @@ docs = [
194
207
  "hdbscan>=0.8.33", # For sorters spykingcircus2 + tridesclous
195
208
  "numba", # For many postprocessing functions
196
209
  "networkx",
197
- "skops", # For auotmated curation
198
- "scikit-learn", # For auotmated curation
199
- # Download data
200
- "pooch>=1.8.2",
201
- "datalad>=1.0.2",
210
+ "skops", # For automated curation
211
+ "scikit-learn", # For automated curation
212
+ "huggingface_hub", # For automated curation
202
213
 
203
214
  # for release we need pypi, so this needs to be commented
204
215
  # "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", # We always build from the latest version
@@ -0,0 +1,9 @@
1
+ """
2
+ Module to benchmark:
3
+ * sorters with or without ground-truth
4
+ * some sorting components (clustering, motion, template matching)
5
+ """
6
+
7
+ from .residual_analysis import analyse_residual, make_residual_recording
8
+ from .benchmark_sorter import SorterStudy
9
+ from .benchmark_sorter_without_gt import SorterStudyWithoutGroundTruth
@@ -9,7 +9,8 @@ import numpy as np
9
9
  import time
10
10
 
11
11
 
12
- from spikeinterface.core import SortingAnalyzer
12
+ from spikeinterface.core import SortingAnalyzer, ChannelSparsity, NumpySorting
13
+ from spikeinterface.core import SortingAnalyzer, NumpySorting
13
14
  from spikeinterface.core.job_tools import fix_job_kwargs, split_job_kwargs
14
15
  from spikeinterface import load, create_sorting_analyzer, load_sorting_analyzer
15
16
  from spikeinterface.widgets import get_some_colors
@@ -46,6 +47,7 @@ class BenchmarkStudy:
46
47
  self.levels = None
47
48
  self.colors_by_case = None
48
49
  self.colors_by_levels = {}
50
+ self.labels_by_levels = {}
49
51
  self.scan_folder()
50
52
 
51
53
  @classmethod
@@ -118,12 +120,57 @@ class BenchmarkStudy:
118
120
  if isinstance(data, tuple):
119
121
  # old case : rec + sorting
120
122
  rec, gt_sorting = data
121
- analyzer = create_sorting_analyzer(
122
- gt_sorting, rec, sparse=True, format="binary_folder", folder=local_analyzer_folder
123
- )
124
- analyzer.compute("random_spikes")
125
- analyzer.compute("templates")
126
- analyzer.compute("noise_levels")
123
+
124
+ if gt_sorting is not None:
125
+ if "gt_unit_locations" in gt_sorting.get_property_keys():
126
+ # if real units locations is present then use it for a better sparsity
127
+ # then the real max channel is used
128
+ radius_um = 100.0
129
+ channel_ids = rec.channel_ids
130
+ unit_ids = gt_sorting.unit_ids
131
+ gt_unit_locations = gt_sorting.get_property("gt_unit_locations")
132
+ channel_locations = rec.get_channel_locations()
133
+ max_channel_indices = np.argmin(
134
+ np.linalg.norm(
135
+ gt_unit_locations[:, np.newaxis, :2] - channel_locations[np.newaxis, :], axis=2
136
+ ),
137
+ axis=1,
138
+ )
139
+ mask = np.zeros((unit_ids.size, channel_ids.size), dtype="bool")
140
+ distances = np.linalg.norm(
141
+ channel_locations[:, np.newaxis] - channel_locations[np.newaxis, :], axis=2
142
+ )
143
+ for unit_ind, unit_id in enumerate(unit_ids):
144
+ chan_ind = max_channel_indices[unit_ind]
145
+ (chan_inds,) = np.nonzero(distances[chan_ind, :] <= radius_um)
146
+ mask[unit_ind, chan_inds] = True
147
+ sparsity = ChannelSparsity(mask, unit_ids, channel_ids)
148
+ sparse = False
149
+ else:
150
+ sparse = True
151
+ sparsity = None
152
+
153
+ analyzer = create_sorting_analyzer(
154
+ gt_sorting,
155
+ rec,
156
+ sparse=sparse,
157
+ sparsity=sparsity,
158
+ format="binary_folder",
159
+ folder=local_analyzer_folder,
160
+ )
161
+ analyzer.compute("random_spikes")
162
+ analyzer.compute("templates")
163
+ analyzer.compute("noise_levels")
164
+ else:
165
+ # some study/benchmark has no GT sorting
166
+ # in that case we still need an analyzer for internal API
167
+ gt_sorting = NumpySorting.from_samples_and_labels(
168
+ [np.array([])], [np.array([])], rec.sampling_frequency, unit_ids=None
169
+ )
170
+ analyzer = create_sorting_analyzer(
171
+ gt_sorting, rec, sparse=False, format="binary_folder", folder=local_analyzer_folder
172
+ )
173
+
127
174
  else:
128
175
  # new case : analzyer
129
176
  assert isinstance(data, SortingAnalyzer)
@@ -134,8 +181,6 @@ class BenchmarkStudy:
134
181
  else:
135
182
  analyzer = data
136
183
 
137
- rec, gt_sorting = analyzer.recording, analyzer.sorting
138
-
139
184
  analyzers_path[key] = str(analyzer.folder.resolve())
140
185
 
141
186
  # recordings are pickled
@@ -176,17 +221,15 @@ class BenchmarkStudy:
176
221
  self.levels = self.info["levels"]
177
222
 
178
223
  for key, folder in self.analyzers_path.items():
179
- analyzer = load_sorting_analyzer(folder)
224
+ analyzer = load_sorting_analyzer(folder, load_extensions=False)
180
225
  self.analyzers[key] = analyzer
181
226
  # the sorting is in memory here we take the saved one because comparisons need to pickle it later
182
227
  sorting = load(analyzer.folder / "sorting")
183
- self.datasets[key] = analyzer.recording, sorting
184
-
185
- # for rec_file in (self.folder / "datasets" / "recordings").glob("*.pickle"):
186
- # key = rec_file.stem
187
- # rec = load(rec_file)
188
- # gt_sorting = load(self.folder / f"datasets" / "gt_sortings" / key)
189
- # self.datasets[key] = (rec, gt_sorting)
228
+ if analyzer.has_recording():
229
+ recording = analyzer.recording
230
+ else:
231
+ recording = None
232
+ self.datasets[key] = recording, sorting
190
233
 
191
234
  with open(self.folder / "cases.pickle", "rb") as f:
192
235
  self.cases = pickle.load(f)
@@ -247,6 +290,8 @@ class BenchmarkStudy:
247
290
 
248
291
  for key in job_keys:
249
292
  benchmark = self.create_benchmark(key)
293
+ if verbose:
294
+ print("### Run benchmark", key, "###")
250
295
  t0 = time.perf_counter()
251
296
  benchmark.run(**job_kwargs)
252
297
  t1 = time.perf_counter()
@@ -317,7 +362,7 @@ class BenchmarkStudy:
317
362
  df.index.names = self.levels
318
363
  return df
319
364
 
320
- def get_grouped_keys_mapping(self, levels_to_group_by=None):
365
+ def get_grouped_keys_mapping(self, levels_to_group_by=None, case_keys=None):
321
366
  """
322
367
  Return a dictionary of grouped keys.
323
368
 
@@ -325,6 +370,8 @@ class BenchmarkStudy:
325
370
  ----------
326
371
  levels_to_group_by : list
327
372
  A list of levels to group by.
373
+ case_keys : list
374
+ Optionaly a sub list of case_keys to consider
328
375
 
329
376
  Returns
330
377
  -------
@@ -334,18 +381,19 @@ class BenchmarkStudy:
334
381
  labels : dict
335
382
  A dictionary of labels, with the new keys as keys and the labels as values.
336
383
  """
337
- cases = list(self.cases.keys())
384
+ if case_keys is None:
385
+ case_keys = list(self.cases.keys())
338
386
  if levels_to_group_by is None or self.levels is None:
339
- keys_mapping = {key: [key] for key in cases}
387
+ keys_mapping = {key: [key] for key in case_keys}
340
388
  elif len(self.levels) == 1:
341
- keys_mapping = {key: [key] for key in cases}
389
+ keys_mapping = {key: [key] for key in case_keys}
342
390
  else:
343
391
  study_levels = self.levels
344
392
  assert np.all(
345
393
  [l in study_levels for l in levels_to_group_by]
346
394
  ), f"levels_to_group_by must be in {study_levels}, got {levels_to_group_by}"
347
395
  keys_mapping = {}
348
- for key in cases:
396
+ for key in case_keys:
349
397
  new_key = tuple(key[list(study_levels).index(level)] for level in levels_to_group_by)
350
398
  if len(new_key) == 1:
351
399
  new_key = new_key[0]
@@ -354,13 +402,17 @@ class BenchmarkStudy:
354
402
  keys_mapping[new_key].append(key)
355
403
 
356
404
  if levels_to_group_by is None:
357
- labels = {key: self.cases[key]["label"] for key in cases}
405
+ labels = {key: self.cases[key]["label"] for key in case_keys}
358
406
  else:
359
- key0 = list(keys_mapping.keys())[0]
360
- if isinstance(key0, tuple):
361
- labels = {key: "-".join(key) for key in keys_mapping}
407
+ level_key = tuple(levels_to_group_by) if len(levels_to_group_by) > 1 else levels_to_group_by[0]
408
+ if level_key in self.labels_by_levels:
409
+ labels = self.labels_by_levels[level_key]
362
410
  else:
363
- labels = {key: key for key in keys_mapping}
411
+ key0 = list(keys_mapping.keys())[0]
412
+ if isinstance(key0, tuple):
413
+ labels = {key: "-".join(key) for key in keys_mapping}
414
+ else:
415
+ labels = {key: key for key in keys_mapping}
364
416
 
365
417
  return keys_mapping, labels
366
418
 
@@ -376,12 +428,14 @@ class BenchmarkStudy:
376
428
 
377
429
  job_keys = []
378
430
  for key in case_keys:
431
+ if verbose:
432
+ print("### Compute result", key, "###")
379
433
  benchmark = self.benchmarks[key]
380
434
  assert benchmark is not None
381
435
  benchmark.compute_result(**result_params)
382
436
  benchmark.save_result(self.folder / "results" / self.key_to_str(key))
383
437
 
384
- def create_sorting_analyzer_gt(self, case_keys=None, return_scaled=True, random_params={}, **job_kwargs):
438
+ def create_sorting_analyzer_gt(self, case_keys=None, return_in_uV=True, random_params={}, **job_kwargs):
385
439
  print("###### Study.create_sorting_analyzer_gt() is not used anymore!!!!!!")
386
440
  # if case_keys is None:
387
441
  # case_keys = self.cases.keys()
@@ -396,7 +450,7 @@ class BenchmarkStudy:
396
450
  # folder = base_folder / self.key_to_str(dataset_key)
397
451
  # recording, gt_sorting = self.datasets[dataset_key]
398
452
  # sorting_analyzer = create_sorting_analyzer(
399
- # gt_sorting, recording, format="binary_folder", folder=folder, return_scaled=return_scaled
453
+ # gt_sorting, recording, format="binary_folder", folder=folder, return_in_uV=return_in_uV
400
454
  # )
401
455
  # sorting_analyzer.compute("random_spikes", **random_params)
402
456
  # sorting_analyzer.compute("templates", **job_kwargs)
@@ -431,9 +485,9 @@ class BenchmarkStudy:
431
485
  unit_locations_ext = sorting_analyzer.get_extension("unit_locations")
432
486
  return unit_locations_ext.get_data()
433
487
 
434
- def get_templates(self, key, operator="average"):
488
+ def get_templates(self, key, operator="average", outputs="numpy"):
435
489
  sorting_analyzer = self.get_sorting_analyzer(case_key=key)
436
- templates = sorting_analyzer.get_extenson("templates").get_data(operator=operator)
490
+ templates = sorting_analyzer.get_extension("templates").get_data(operator=operator, outputs=outputs)
437
491
  return templates
438
492
 
439
493
  def compute_metrics(self, case_keys=None, metric_names=["snr", "firing_rate"], force=False, **job_kwargs):
@@ -570,7 +624,10 @@ class Benchmark:
570
624
  elif format == "zarr_templates":
571
625
  self.result[k].to_zarr(folder / k)
572
626
  elif format == "sorting_analyzer":
573
- pass
627
+ analyzer_folder = folder / k
628
+ if analyzer_folder.exists():
629
+ shutil.rmtree(analyzer_folder)
630
+ self.result[k].save_as(format="binary_folder", folder=analyzer_folder)
574
631
  else:
575
632
  raise ValueError(f"Save error {k} {format}")
576
633
 
@@ -600,15 +657,26 @@ class Benchmark:
600
657
  elif format == "sorting":
601
658
  from spikeinterface.core import load_extractor
602
659
 
603
- result[k] = load(folder / k)
660
+ sorting_folder = folder / k
661
+ if sorting_folder.exists():
662
+ result[k] = load(sorting_folder)
604
663
  elif format == "Motion":
605
664
  from spikeinterface.core.motion import Motion
606
665
 
607
- result[k] = Motion.load(folder / k)
666
+ motion_folder = folder / k
667
+ if motion_folder.exists():
668
+ result[k] = Motion.load(motion_folder)
608
669
  elif format == "zarr_templates":
609
670
  from spikeinterface.core.template import Templates
610
671
 
611
- result[k] = Templates.from_zarr(folder / k)
672
+ zarr_folder = folder / k
673
+ if zarr_folder.exists():
674
+
675
+ result[k] = Templates.from_zarr(zarr_folder)
676
+ elif format == "sorting_analyzer":
677
+ analyzer_folder = folder / k
678
+ if analyzer_folder.exists():
679
+ result[k] = load_sorting_analyzer(analyzer_folder)
612
680
 
613
681
  return result
614
682
 
@@ -619,3 +687,68 @@ class Benchmark:
619
687
  def compute_result(self):
620
688
  # run becnhmark result
621
689
  raise NotImplementedError
690
+
691
+
692
+ # Common feature accross some benchmark : sorter + matching
693
+ class MixinStudyUnitCount:
694
+ def get_count_units(self, case_keys=None, well_detected_score=None, redundant_score=None, overmerged_score=None):
695
+ import pandas as pd
696
+
697
+ if case_keys is None:
698
+ case_keys = list(self.cases.keys())
699
+
700
+ if isinstance(case_keys[0], str):
701
+ index = pd.Index(case_keys, name=self.levels)
702
+ else:
703
+ index = pd.MultiIndex.from_tuples(case_keys, names=self.levels)
704
+
705
+ columns = ["num_gt", "num_sorter", "num_well_detected"]
706
+ key0 = case_keys[0]
707
+ comp = self.get_result(key0)["gt_comparison"]
708
+ if comp.exhaustive_gt:
709
+ columns.extend(["num_false_positive", "num_redundant", "num_overmerged", "num_bad"])
710
+ count_units = pd.DataFrame(index=index, columns=columns, dtype=int)
711
+
712
+ for key in case_keys:
713
+ comp = self.get_result(key)["gt_comparison"]
714
+
715
+ gt_sorting = comp.sorting1
716
+ sorting = comp.sorting2
717
+
718
+ count_units.at[key, "num_gt"] = len(gt_sorting.get_unit_ids())
719
+ count_units.at[key, "num_sorter"] = len(sorting.get_unit_ids())
720
+ count_units.at[key, "num_well_detected"] = comp.count_well_detected_units(well_detected_score)
721
+
722
+ if comp.exhaustive_gt:
723
+ count_units.at[key, "num_redundant"] = comp.count_redundant_units(redundant_score)
724
+ count_units.at[key, "num_overmerged"] = comp.count_overmerged_units(overmerged_score)
725
+ count_units.at[key, "num_false_positive"] = comp.count_false_positive_units(redundant_score)
726
+ count_units.at[key, "num_bad"] = comp.count_bad_units()
727
+
728
+ return count_units
729
+
730
+ def get_performance_by_unit(self, case_keys=None):
731
+ import pandas as pd
732
+
733
+ if case_keys is None:
734
+ case_keys = self.cases.keys()
735
+
736
+ perf_by_unit = []
737
+ for key in case_keys:
738
+ comp = self.get_result(key)["gt_comparison"]
739
+
740
+ perf = comp.get_performance(method="by_unit", output="pandas")
741
+
742
+ if isinstance(key, str):
743
+ perf[self.levels] = key
744
+ elif isinstance(key, tuple):
745
+ for col, k in zip(self.levels, key):
746
+ perf[col] = k
747
+
748
+ perf = perf.reset_index()
749
+ perf_by_unit.append(perf)
750
+
751
+ perf_by_unit = pd.concat(perf_by_unit)
752
+ perf_by_unit = perf_by_unit.set_index(self.levels)
753
+ perf_by_unit = perf_by_unit.sort_index()
754
+ return perf_by_unit
@@ -11,7 +11,7 @@ from spikeinterface.widgets import (
11
11
 
12
12
  import numpy as np
13
13
  from spikeinterface.core.job_tools import fix_job_kwargs, split_job_kwargs
14
- from .benchmark_base import Benchmark, BenchmarkStudy
14
+ from .benchmark_base import Benchmark, BenchmarkStudy, MixinStudyUnitCount
15
15
  from spikeinterface.core.sortinganalyzer import create_sorting_analyzer
16
16
  from spikeinterface.core.template_tools import get_template_extremum_channel
17
17
 
@@ -35,8 +35,8 @@ class ClusteringBenchmark(Benchmark):
35
35
  )
36
36
  self.result["peak_labels"] = peak_labels
37
37
 
38
- def compute_result(self, **result_params):
39
- result_params, job_kwargs = split_job_kwargs(result_params)
38
+ def compute_result(self, with_template=False, **job_kwargs):
39
+ # result_params, job_kwargs = split_job_kwargs(result_params)
40
40
  job_kwargs = fix_job_kwargs(job_kwargs)
41
41
  self.noise = self.result["peak_labels"] < 0
42
42
  spikes = self.gt_sorting.to_spike_vector()
@@ -68,19 +68,20 @@ class ClusteringBenchmark(Benchmark):
68
68
  self.result["sliced_gt_sorting"], self.result["clustering"], exhaustive_gt=self.exhaustive_gt
69
69
  )
70
70
 
71
- sorting_analyzer = create_sorting_analyzer(
72
- self.result["sliced_gt_sorting"], self.recording, format="memory", sparse=False, **job_kwargs
73
- )
74
- sorting_analyzer.compute("random_spikes")
75
- ext = sorting_analyzer.compute("templates", **job_kwargs)
76
- self.result["sliced_gt_templates"] = ext.get_data(outputs="Templates")
71
+ if with_template:
72
+ sorting_analyzer = create_sorting_analyzer(
73
+ self.result["sliced_gt_sorting"], self.recording, format="memory", sparse=False, **job_kwargs
74
+ )
75
+ sorting_analyzer.compute("random_spikes")
76
+ ext = sorting_analyzer.compute("templates", **job_kwargs)
77
+ self.result["sliced_gt_templates"] = ext.get_data(outputs="Templates")
77
78
 
78
- sorting_analyzer = create_sorting_analyzer(
79
- self.result["clustering"], self.recording, format="memory", sparse=False, **job_kwargs
80
- )
81
- sorting_analyzer.compute("random_spikes")
82
- ext = sorting_analyzer.compute("templates", **job_kwargs)
83
- self.result["clustering_templates"] = ext.get_data(outputs="Templates")
79
+ sorting_analyzer = create_sorting_analyzer(
80
+ self.result["clustering"], self.recording, format="memory", sparse=False, **job_kwargs
81
+ )
82
+ sorting_analyzer.compute("random_spikes")
83
+ ext = sorting_analyzer.compute("templates", **job_kwargs)
84
+ self.result["clustering_templates"] = ext.get_data(outputs="Templates")
84
85
 
85
86
  _run_key_saved = [("peak_labels", "npy")]
86
87
 
@@ -93,7 +94,7 @@ class ClusteringBenchmark(Benchmark):
93
94
  ]
94
95
 
95
96
 
96
- class ClusteringStudy(BenchmarkStudy):
97
+ class ClusteringStudy(BenchmarkStudy, MixinStudyUnitCount):
97
98
 
98
99
  benchmark_class = ClusteringBenchmark
99
100
 
@@ -196,6 +197,11 @@ class ClusteringStudy(BenchmarkStudy):
196
197
 
197
198
  return plot_performances_vs_depth_and_snr(self, *args, **kwargs)
198
199
 
200
+ def plot_performances_ordered(self, *args, **kwargs):
201
+ from .benchmark_plot_tools import plot_performances_ordered
202
+
203
+ return plot_performances_ordered(self, *args, **kwargs)
204
+
199
205
  def plot_error_metrics(self, metric="cosine", case_keys=None, figsize=(15, 5)):
200
206
 
201
207
  if case_keys is None: