Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8793229
wip: start big metric refactoring
alejoe91 Oct 8, 2025
f71ae91
wip
alejoe91 Oct 8, 2025
b7445be
template metrics done!
alejoe91 Oct 9, 2025
83b8de2
remove template_metrics_old
alejoe91 Oct 9, 2025
a38cfa2
wip quality metrics
alejoe91 Oct 10, 2025
bbdd974
wip
alejoe91 Oct 13, 2025
bf4e24c
Fix metric dtypes and template metric tests
alejoe91 Oct 14, 2025
50bf11f
update tests
alejoe91 Oct 21, 2025
983e5d5
Fix (core) tests
alejoe91 Oct 22, 2025
e4f2cfe
Remove pandas from template tests
alejoe91 Oct 22, 2025
6602f17
Add metrics_to_compute params (but need to check behavior)
alejoe91 Oct 22, 2025
5c55124
Fix markers and start docs refactor
alejoe91 Oct 23, 2025
13e1ef9
Clean up CI and [metrics] install
alejoe91 Oct 23, 2025
5ee3085
Update src/spikeinterface/core/sortinganalyzer.py
alejoe91 Oct 23, 2025
0b4aa0e
Fixes after code review
alejoe91 Oct 23, 2025
cdc4e18
wip docs
alejoe91 Oct 23, 2025
79461b5
more docs!
alejoe91 Oct 23, 2025
07ba325
debug pca tests
alejoe91 Oct 23, 2025
f2c2449
Merge branch 'main' of github.com:SpikeInterface/spikeinterface into …
alejoe91 Oct 30, 2025
40b9d00
handle deprecated modules
alejoe91 Oct 30, 2025
420e879
Use explicit get_*_params functions
alejoe91 Oct 30, 2025
daed30e
Remove comment
alejoe91 Oct 30, 2025
26791f4
wip: fix required extensions and tests
alejoe91 Oct 30, 2025
b10dcea
Remove _set_data
alejoe91 Oct 30, 2025
fc02101
Add common _cast_metrics and fix most tests
alejoe91 Oct 30, 2025
6adef7e
expose seed param for nn_advanced
alejoe91 Oct 30, 2025
206412a
Fix curation tests
alejoe91 Oct 31, 2025
8b66f51
Fix docs
alejoe91 Oct 31, 2025
415e642
Update overview diagram
alejoe91 Oct 31, 2025
f3eb9c6
Compute spike amplitudes for IBL export tests
alejoe91 Oct 31, 2025
90300a1
Unify mahlanobis metrics in docs
alejoe91 Oct 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/scripts/determine_testing_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
plexon2_changed = False
preprocessing_changed = False
postprocessing_changed = False
qualitymetrics_changed = False
metrics_changed = False
sorters_changed = False
sorters_external_changed = False
sorters_internal_changed = False
Expand Down Expand Up @@ -58,8 +58,8 @@
preprocessing_changed = True
elif "postprocessing" in changed_file.parts:
postprocessing_changed = True
elif "qualitymetrics" in changed_file.parts:
qualitymetrics_changed = True
elif "metrics" in changed_file.parts:
metrics_changed = True
elif "comparison" in changed_file.parts:
comparison_changed = True
elif "curation" in changed_file.parts:
Expand Down Expand Up @@ -89,12 +89,12 @@
run_extractor_tests = run_everything or extractors_changed or plexon2_changed
run_preprocessing_tests = run_everything or preprocessing_changed
run_postprocessing_tests = run_everything or postprocessing_changed
run_qualitymetrics_tests = run_everything or qualitymetrics_changed
run_metrics_tests = run_everything or metrics_changed
run_curation_tests = run_everything or curation_changed
run_sortingcomponents_tests = run_everything or sortingcomponents_changed

run_comparison_test = run_everything or run_generation_tests or comparison_changed
run_widgets_test = run_everything or run_qualitymetrics_tests or run_preprocessing_tests or widgets_changed
run_widgets_test = run_everything or run_metrics_tests or run_preprocessing_tests or widgets_changed
run_exporters_test = run_everything or run_widgets_test or exporters_changed

run_sorters_test = run_everything or sorters_changed
Expand All @@ -109,7 +109,7 @@
"RUN_EXTRACTORS_TESTS": run_extractor_tests,
"RUN_PREPROCESSING_TESTS": run_preprocessing_tests,
"RUN_POSTPROCESSING_TESTS": run_postprocessing_tests,
"RUN_QUALITYMETRICS_TESTS": run_qualitymetrics_tests,
"RUN_METRICS_TESTS": run_metrics_tests,
"RUN_CURATION_TESTS": run_curation_tests,
"RUN_SORTINGCOMPONENTS_TESTS": run_sortingcomponents_tests,
"RUN_GENERATION_TESTS": run_generation_tests,
Expand Down
2 changes: 1 addition & 1 deletion .github/scripts/import_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"import spikeinterface",
"import spikeinterface.core",
"import spikeinterface.extractors",
"import spikeinterface.qualitymetrics",
"import spikeinterface.metrics",
"import spikeinterface.preprocessing",
"import spikeinterface.comparison",
"import spikeinterface.postprocessing",
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/all-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
echo "RUN_EXTRACTORS_TESTS=${RUN_EXTRACTORS_TESTS}"
echo "RUN_PREPROCESSING_TESTS=${RUN_PREPROCESSING_TESTS}"
echo "RUN_POSTPROCESSING_TESTS=${RUN_POSTPROCESSING_TESTS}"
echo "RUN_QUALITYMETRICS_TESTS=${RUN_QUALITYMETRICS_TESTS}"
echo "RUN_METRICS_TESTS=${RUN_METRICS_TESTS}"
echo "RUN_CURATION_TESTS=${RUN_CURATION_TESTS}"
echo "RUN_SORTINGCOMPONENTS_TESTS=${RUN_SORTINGCOMPONENTS_TESTS}"
echo "RUN_GENERATION_TESTS=${RUN_GENERATION_TESTS}"
Expand Down Expand Up @@ -164,13 +164,13 @@ jobs:
pip list
./.github/run_tests.sh postprocessing --no-virtual-env

- name: Test quality metrics
- name: Test metrics
shell: bash
if: env.RUN_QUALITYMETRICS_TESTS == 'true'
if: env.RUN_METRICS_TESTS == 'true'
run: |
pip install -e .[qualitymetrics]
pip install -e .[metrics]
pip list
./.github/run_tests.sh qualitymetrics --no-virtual-env
./.github/run_tests.sh metrics --no-virtual-env

- name: Test comparison
shell: bash
Expand Down
35 changes: 23 additions & 12 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -226,19 +226,31 @@ spikeinterface.postprocessing
.. autofunction:: compute_correlograms
.. autofunction:: compute_acgs_3d
.. autofunction:: compute_isi_histograms
.. autofunction:: get_template_metric_names
.. autofunction:: align_sorting


spikeinterface.qualitymetrics
-----------------------------
spikeinterface.metrics
----------------------

.. automodule:: spikeinterface.qualitymetrics
.. automodule:: spikeinterface.metrics.quality

.. autofunction:: compute_quality_metrics
.. autofunction:: get_quality_metric_list
.. autofunction:: get_quality_pca_metric_list
.. autofunction:: get_default_qm_params
.. autofunction:: get_default_quality_metrics_params

.. automodule:: spikeinterface.metrics.template

.. autofunction:: compute_template_metrics
.. autofunction:: get_template_metric_list
.. autofunction:: get_default_template_metrics_params
.. autofunction:: get_single_channel_template_metric_names
.. autofunction:: get_multi_channel_template_metric_names

.. automodule:: spikeinterface.metrics.spiketrain

.. autofunction:: get_spiketrain_metric_list
.. autofunction:: get_default_spiketrain_metrics_params


spikeinterface.sorters
Expand Down Expand Up @@ -397,7 +409,7 @@ spikeinterface.generation
Core
~~~~

.. currentmodule:: spikeinterface.generation
.. automodule:: spikeinterface.generation

.. autofunction:: generate_recording
.. autofunction:: generate_sorting
Expand All @@ -418,7 +430,8 @@ Core
Drift
~~~~~

.. currentmodule:: spikeinterface.generation
.. automodule:: spikeinterface.generation
:noindex:

.. autofunction:: generate_drifting_recording
.. autofunction:: generate_displacement_vector
Expand All @@ -432,7 +445,8 @@ Drift
Hybrid
~~~~~~

.. currentmodule:: spikeinterface.generation
.. automodule:: spikeinterface.generation
:noindex:

.. autofunction:: generate_hybrid_recording
.. autofunction:: estimate_templates_from_recording
Expand All @@ -448,7 +462,7 @@ Hybrid
Noise
~~~~~

.. currentmodule:: spikeinterface.generation
.. automodule:: spikeinterface.generation

.. autofunction:: generate_noise

Expand Down Expand Up @@ -505,9 +519,6 @@ spikeinterface.benchmark
.. automodule:: spikeinterface.benchmark.benchmark_peak_localization

.. autoclass:: PeakLocalizationStudy

.. automodule:: spikeinterface.benchmark.benchmark_peak_localization

.. autoclass:: UnitLocalizationStudy

.. automodule:: spikeinterface.benchmark.benchmark_motion_estimation
Expand Down
6 changes: 3 additions & 3 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
'../examples/tutorials/core/analyzer_some_units',
'../examples/tutorials/core/analyzer.zarr',
'../examples/tutorials/curation/my_folder',
'../examples/tutorials/qualitymetrics/curated_sorting',
'../examples/tutorials/qualitymetrics/clean_analyzer.zarr',
'../examples/tutorials/metrics/curated_sorting',
'../examples/tutorials/metrics/clean_analyzer.zarr',
'../examples/tutorials/widgets/waveforms_mearec',

]
Expand Down Expand Up @@ -129,7 +129,7 @@
'../examples/tutorials/core',
'../examples/tutorials/extractors',
'../examples/tutorials/curation',
'../examples/tutorials/qualitymetrics',
'../examples/tutorials/metrics',
'../examples/tutorials/comparison',
'../examples/tutorials/widgets',
'../examples/tutorials/forhowto',
Expand Down
6 changes: 3 additions & 3 deletions doc/get_started/import.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ to import the :code:`core` module followed by:
import spikeinterface.extractors as se
import spikeinterface.preprocessing as spre
import spikeinterface.sorters as ss
import spikinterface.postprocessing as spost
import spikeinterface.qualitymetrics as sqm
import spikeinterface.postprocessing as spost
import spikeinterface.metrics as sm
import spikeinterface.exporters as sexp
import spikeinterface.comparsion as scmp
import spikeinterface.comparison as scmp
import spikeinterface.curation as scur
import spikeinterface.sortingcomponents as sc
import spikeinterface.widgets as sw
Expand Down
4 changes: 2 additions & 2 deletions doc/get_started/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ We need to import one by one different submodules separately
import spikeinterface.preprocessing as spre
import spikeinterface.sorters as ss
import spikeinterface.postprocessing as spost
import spikeinterface.qualitymetrics as sqm
import spikeinterface.metrics.quality as sqm
import spikeinterface.comparison as sc
import spikeinterface.exporters as sexp
import spikeinterface.curation as scur
Expand Down Expand Up @@ -627,7 +627,7 @@ compute quality metrics (some quality metrics require certain extensions

.. code:: ipython3

qm_params = sqm.get_default_qm_params()
qm_params = sqm.get_default_quality_metrics_params()
pprint(qm_params)


Expand Down
19 changes: 5 additions & 14 deletions doc/how_to/analyze_neuropixels.rst
Original file line number Diff line number Diff line change
Expand Up @@ -699,15 +699,14 @@ make a copy of the analyzer and all computed extensions.
Quality metrics
---------------

We have a single function ``compute_quality_metrics(SortingAnalyzer)``
that returns a ``pandas.Dataframe`` with the desired metrics.
The ``analyzer.compute("quality_metrics").get_data()`` returns a ``pandas.Dataframe`` with the desired metrics.

Note that this function is also an extension and so can be saved. And so
this is equivalent to do :
this is equivalent to do:
``metrics = analyzer.compute("quality_metrics").get_data()``

Please visit the `metrics
documentation <https://spikeinterface.readthedocs.io/en/latest/modules/qualitymetrics.html>`__
documentation <https://spikeinterface.readthedocs.io/en/latest/modules/metrics/quality.html>`__
for more information and a list of all supported metrics.

Some metrics are based on PCA (like
Expand All @@ -721,20 +720,12 @@ PCA for their computation. This can be achieved with:
metric_names=['firing_rate', 'presence_ratio', 'snr', 'isi_violation', 'amplitude_cutoff']


# metrics = analyzer.compute("quality_metrics").get_data()
# equivalent to
metrics = si.compute_quality_metrics(analyzer, metric_names=metric_names)
metrics_ext = analyzer.compute("quality_metrics", metric_names=metric_names)
metrics = metrics_ext.get_data()

metrics


.. parsed-literal::

/home/samuel.garcia/Documents/SpikeInterface/spikeinterface/src/spikeinterface/qualitymetrics/misc_metrics.py:846: UserWarning: Some units have too few spikes : amplitude_cutoff is set to NaN
warnings.warn(f"Some units have too few spikes : amplitude_cutoff is set to NaN")




.. raw:: html

Expand Down
Binary file modified doc/images/overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion doc/modules/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Modules documentation
preprocessing
sorters
postprocessing
qualitymetrics
metrics
comparison
exporters
widgets
Expand Down
19 changes: 19 additions & 0 deletions doc/modules/metrics.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Metrics
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Metrics
Metrics module
--------------

-------

The :py:mod:`~spikeinterface.metrics` module includes functions to compute various metrics related to spike sorting.

Currently, it contains the following submodules:

- **template metrics**: Computes commonly used waveform/template metrics.
- **quality metrics**: Computes a variety of quality metrics to assess the goodness of spike sorting outputs.
- **spiketrain metrics**: Computes metrics based on spike train statistics and correlogram shapes.


.. toctree::
:caption: Metrics submodules
:maxdepth: 1

metrics/template_metrics
metrics/quality_metrics
metrics/spiketrain_metrics
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Quality Metrics module
======================

Quality metrics allows one to quantitatively assess the *goodness* of a spike sorting output.
The :py:mod:`~spikeinterface.qualitymetrics` module includes functions to compute a large variety of available metrics.
The :py:mod:`~spikeinterface.metrics.quality` module includes functions to compute a large variety of available metrics.
All of the metrics currently implemented in spikeInterface are *per unit* (pairwise metrics do appear in the literature).

Each metric aims to identify some quality of the unit.
Expand All @@ -12,7 +12,7 @@ Completeness metrics (or 'false negative'/'type II' metrics) aim to identify whe
Examples include: presence ratio, amplitude cutoff, NN-miss rate.
Drift metrics aim to identify changes in waveforms which occur when spike sorters fail to successfully track neurons in the case of electrode drift.

The quality metrics are saved as an extension of a :doc:`SortingAnalyzer <postprocessing>`. Some metrics can only be computed if certain extensions have been computed first. For example the drift metrics can only be computed the spike locations extension has been computed. By default, as many metrics as possible are computed. Which ones are computed depends on which other extensions have
The quality metrics are saved as an extension of a :doc:`SortingAnalyzer <../postprocessing>`. Some metrics can only be computed if certain extensions have been computed first. For example the drift metrics can only be computed the spike locations extension has been computed. By default, as many metrics as possible are computed. Which ones are computed depends on which other extensions have
been computed.

In detail, the default metrics are (click on each metric to find out more about them!):
Expand Down Expand Up @@ -69,7 +69,7 @@ You can compute the default metrics using the following code snippet:

Some metrics are very slow to compute when the number of units it large. So by default, the following metrics are not computed:

- The ``nn_noise_overlap`` from :doc:`qualitymetrics/nearest_neighbor`
- The ``nn_advanced`` from :doc:`qualitymetrics/nearest_neighbor`

Some metrics make use of :ref:`principal component analysis <postprocessing_principal_components>` (PCA) to reduce the dimensionality of computations.
Various approaches to computing the principal components are possible, and choice should be carefully considered in relation to the recording equipment used.
Expand All @@ -94,7 +94,7 @@ To save the result in your analyzer, you can use the ``compute`` method:
}
)

Note that if you request a specific metric using ``metric_names`` and you do not have the required extension computed, this will error.
Note that if you request a specific metric using ``metric_names`` and you do not have the required extension computed, the metric will be skipped.

For more information about quality metrics, check out this excellent
`documentation <https://allensdk.readthedocs.io/en/latest/_static/examples/nb/ecephys_quality_metrics.html>`_
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Example code

.. code-block:: python

import spikeinterface.qualitymetrics as sqm
import spikeinterface.metrics.quality as sqm

# Combine sorting and recording into a sorting_analyzer
# It is also recommended to run sorting_analyzer.compute(input="spike_amplitudes")
Expand All @@ -34,7 +34,7 @@ Example code
Reference
---------

.. autofunction:: spikeinterface.qualitymetrics.misc_metrics.compute_amplitude_cutoffs
.. autofunction:: spikeinterface.metrics.quality.misc_metrics.compute_amplitude_cutoffs


Links to original implementations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Example code

.. code-block:: python

import spikeinterface.qualitymetrics as sqm
import spikeinterface.metrics.quality as sqm

# Combine a sorting and recording into a sorting_analyzer
# It is required to run sorting_analyzer.compute(input="spike_amplitudes") or
Expand All @@ -46,7 +46,7 @@ Example code
References
----------

.. autofunction:: spikeinterface.qualitymetrics.misc_metrics.compute_amplitude_cv_metrics
.. autofunction:: spikeinterface.metrics.quality.misc_metrics.compute_amplitude_cv_metrics


Literature
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Example code

.. code-block:: python

import spikeinterface.qualitymetrics as sqm
import spikeinterface.metrics.quality as sqm

# It is also recommended to run sorting_analyzer.compute(input="spike_amplitudes")
# in order to use amplitude values from all spikes.
Expand All @@ -31,7 +31,7 @@ Example code
Reference
---------

.. autofunction:: spikeinterface.qualitymetrics.misc_metrics.compute_amplitude_medians
.. autofunction:: spikeinterface.metrics.quality.misc_metrics.compute_amplitude_medians


Links to original implementations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ Example code

.. code-block:: python

import spikeinterface.qualitymetrics as sqm
import spikeinterface.metrics.quality as sqm

d_prime = sqm.lda_metrics(all_pcs=all_pcs, all_labels=all_labels, this_unit_id=0)


Reference
---------

.. autofunction:: spikeinterface.qualitymetrics.pca_metrics.lda_metrics
.. autofunction:: spikeinterface.metrics.quality.pca_metrics.lda_metrics


Literature
Expand Down
Loading