Skip to content

Commit cc440d0

Browse files
authored
Merge branch 'main' into random_spike_selection_new_methods
2 parents 88f32f2 + 5a58beb commit cc440d0

File tree

13 files changed

+294
-113
lines changed

13 files changed

+294
-113
lines changed

.github/scripts/determine_testing_environment.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
sorters_external_changed = True
7878
elif "internal" in changed_file.parts:
7979
sorters_internal_changed = True
80+
sorters_changed = True
8081
else:
8182
sorters_changed = True
8283
elif ".github" in changed_file.parts:

README.md

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,8 @@
4343
</tr>
4444
</table>
4545

46-
[![Twitter](https://img.shields.io/badge/@spikeinterface-%231DA1F2.svg?style=for-the-badge&logo=Twitter&logoColor=white)](https://twitter.com/spikeinterface) [![Mastodon](https://img.shields.io/badge/-@spikeinterface-%232B90D9?style=for-the-badge&logo=mastodon&logoColor=white)](https://fosstodon.org/@spikeinterface)
47-
4846

49-
> :rocket::rocket::rocket:
50-
> **New features!**: after months of development and testing, we are happy to announce that
51-
> the latest release (0.101.0) includes a major API improvement: the `SortingAnalyzer`!
52-
> To read more about why we did this, checkout the
53-
> [SpikeInterface Enhancement Proposal](https://github.com/SpikeInterface/spikeinterface/issues/2282).
54-
> Please follow this guide to transition from the old API to the new one:
55-
> [Updating from legacy](https://spikeinterface.readthedocs.io/en/0.101.0/tutorials/waveform_extractor_to_sorting_analyzer.html).
47+
[![Twitter](https://img.shields.io/badge/@spikeinterface-%231DA1F2.svg?style=for-the-badge&logo=Twitter&logoColor=white)](https://twitter.com/spikeinterface) [![Mastodon](https://img.shields.io/badge/-@spikeinterface-%232B90D9?style=for-the-badge&logo=mastodon&logoColor=white)](https://fosstodon.org/@spikeinterface)
5648

5749

5850
SpikeInterface is a Python framework designed to unify preexisting spike sorting technologies into a single code base.
@@ -64,14 +56,19 @@ With SpikeInterface, users can:
6456

6557
- read/write many extracellular file formats.
6658
- pre-process extracellular recordings.
67-
- run many popular, semi-automatic spike sorters (also in Docker/Singularity containers).
68-
- post-process sorted datasets.
59+
- run many popular, semi-automatic spike sorters (kilosort1-4, mountainsort4-5, spykingcircus,
60+
tridesclous, ironclust, herdingspikes, yass, waveclus)
61+
- run sorters developed in house (lupin, spkykingcicus2, tridesclous2, simple) that compete with kilosort4
62+
- run theses polar sorters without installation using containers (Docker/Singularity).
63+
- post-process sorted datasets using th SortingAnalyzer
6964
- compare and benchmark spike sorting outputs.
7065
- compute quality metrics to validate and curate spike sorting outputs.
7166
- visualize recordings and spike sorting outputs in several ways (matplotlib, sortingview, jupyter, ephyviewer)
7267
- export a report and/or export to phy
73-
- offer a powerful Qt-based viewer in a separate package [spikeinterface-gui](https://github.com/SpikeInterface/spikeinterface-gui)
68+
- curate your sorting with several strategies (ml-based, metrics based, manual, ...)
69+
- offer a powerful Qt-based or we-based viewer in a separate package [spikeinterface-gui](https://github.com/SpikeInterface/spikeinterface-gui) for manual curation that replace phy.
7470
- have powerful sorting components to build your own sorter.
71+
- have a full motion/drift correction framework
7572

7673

7774
## Documentation

doc/get_started/install_sorters.rst

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ working not only at peak times but at all times, recovering more spikes close to
284284

285285
pip install hdbscan
286286
pip install spikeinterface
287-
pip install numba (or conda install numba as recommended by conda authors)
287+
pip install numba (or conda install numba as recommended by conda authors)
288288

289289

290290
Tridesclous2
@@ -294,11 +294,25 @@ This is an upgraded version of Tridesclous, natively written in SpikeInterface.
294294

295295

296296
* Python
297-
* Requires: HDBSCAN and Numba
297+
* Requires: Numba
298298
* Authors: Samuel Garcia
299299
* Installation::
300300

301-
pip install hdbscan
301+
pip install spikeinterface
302+
pip install numba
303+
304+
305+
Lupin
306+
^^^^^
307+
308+
This is a representative spike sorting pipeline, natively written in SpikeInterface.
309+
310+
311+
* Python
312+
* Requires: Numba
313+
* Authors: Samuel Garcia & Pierre Yger
314+
* Installation::
315+
302316
pip install spikeinterface
303317
pip install numba
304318

doc/how_to/analyze_neuropixels.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ pipeline, in SpikeInterface this is dead-simple: one function.
516516
- most of sorters are wrapped from external tools (kilosort,
517517
kisolort2.5, spykingcircus, montainsort4 …) that often also need
518518
other requirements (e.g., MATLAB, CUDA)
519-
- some sorters are internally developed (spyekingcircus2)
519+
- some sorters are internally developed (spykingcircus2, tridesclous2, lupin)
520520
- external sorter can be run inside a container (docker, singularity)
521521
WITHOUT pre-installation
522522

doc/index.rst

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,6 @@ SpikeInterface is a Python module to analyze extracellular electrophysiology dat
77
With a few lines of code, SpikeInterface enables you to load and pre-process the recording, run several
88
state-of-the-art spike sorters, post-process and curate the output, compute quality metrics, and visualize the results.
99

10-
.. warning::
11-
12-
Version 0.101.0 introduces a major API improvement: the :code:`SortingAnalyzer`.
13-
To read more about the motivations, checkout the
14-
`enhancement proposal <https://github.com/SpikeInterface/spikeinterface/issues/2282>`_.
15-
Learn how to :ref:`update your code here <tutorials/waveform_extractor_to_sorting_analyzer:From WaveformExtractor to SortingAnalyzer>`
16-
and read more about the :code:`SortingAnalyzer`, please refer to the
17-
:ref:`core <modules/core:SortingAnalyzer>` and :ref:`postprocessing <modules/postprocessing:Postprocessing module>` module
18-
documentation.
19-
20-
2110

2211
Overview of SpikeInterface modules
2312
----------------------------------
@@ -30,16 +19,23 @@ SpikeInterface is made of several modules to deal with different aspects of the
3019

3120
- read/write many extracellular file formats.
3221
- pre-process extracellular recordings.
33-
- run many popular, semi-automatic spike sorters (also in Docker/Singularity containers).
34-
- post-process spike sorted data.
22+
- run many popular, semi-automatic spike sorters (kilosort1-4, mountainsort4-5, spykingcircus,
23+
tridesclous, ironclust, herdingspikes, yass, waveclus)
24+
- run sorters developed in house (lupin, spkykingcicus2, tridesclous2, simple) that compete with
25+
kilosort4
26+
- run theses polar sorters without installation using containers (Docker/Singularity).
27+
- post-process sorted datasets using th SortingAnalyzer
3528
- compare and benchmark spike sorting outputs.
3629
- compute quality metrics to validate and curate spike sorting outputs.
37-
- visualize recordings and spike sorting outputs.
38-
- export a report and/or export to Phy.
39-
- offer a powerful Qt-based viewer in a separate package `spikeinterface-gui <https://github.com/SpikeInterface/spikeinterface-gui>`_
40-
- have some powerful sorting components to build your own sorter.
30+
- visualize recordings and spike sorting outputs in several ways (matplotlib, sortingview, jupyter, ephyviewer)
31+
- export a report and/or export to phy
32+
- curate your sorting with several strategies (ml-based, metrics based, manual, ...)
33+
- offer a powerful Qt-based or we-based viewer in a separate package `spikeinterface-gui <https://github.com/SpikeInterface/spikeinterface-gui>`_ for manual curation that replace phy.
34+
- have powerful sorting components to build your own sorter.
4135
- have a full motion/drift correction framework (See :ref:`motion_correction`)
4236

37+
38+
4339
.. toctree::
4440
:maxdepth: 1
4541
:caption: Contents:

doc/modules/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Modules documentation
88
extractors
99
preprocessing
1010
sorters
11+
sorters_internal
1112
postprocessing
1213
metrics
1314
comparison

doc/modules/sorters.rst

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ Kilosort, Mountainsort, etc. (see :ref:`compatible-sorters`). All these sorter c
88
from the :py:class:`~spikeinterface.sorters.BaseSorter` class, which provides the common tools to
99
run spike sorters.
1010

11-
On the other hand SpikeInterface directly implements some internal sorters (**spykingcircus2**)
11+
On the other hand SpikeInterface directly implements some internal sorters
1212
that do not depend on external tools, but depend on the :py:mod:`spikeinterface.sortingcomponents`
13-
module. **Note that internal sorters are currently experimental and under development**.
13+
module. Check the :ref:`internal_sorters` page for more details on internal sorters and their
14+
strategies.
1415

1516
A drawback of using external sorters is the separate installation of these tools. Sometimes they need MATLAB,
1617
specific versions of CUDA, specific gcc versions or outdated versions of
@@ -322,15 +323,12 @@ an :code:`engine` that supports parallel processing (such as :code:`joblib` or :
322323
:py:func:`~spikeinterface.sorters.run_sorters` has several "engines" available to launch the computation:
323324

324325
* "loop": sequential
325-
* "joblib": in parallel
326326
* "slurm": in parallel, using the SLURM job manager
327327

328328
.. code-block:: python
329329
330330
run_sorter_jobs(job_list=job_list, engine='loop')
331331
332-
run_sorter_jobs(job_list=job_list, engine='joblib', engine_kwargs={'n_jobs': 2})
333-
334332
run_sorter_jobs(job_list=job_list, engine='slurm', engine_kwargs={'cpus_per_task': 10, 'mem': '5G'})
335333
336334
@@ -343,6 +341,7 @@ Alternatively, for long silicon probes, such as Neuropixels, one could think of
343341
separately, for example using a different sorter for the hippocampus, the thalamus, or the cerebellum.
344342
Running spike sorting by group is indeed a very common need.
345343

344+
346345
A :py:class:`~spikeinterface.core.BaseRecording` object has the ability to split itself into a dictionary of
347346
sub-recordings given a certain property (see :py:meth:`~spikeinterface.core.BaseRecording.split_by`).
348347
The :py:func:`~spikeinterface.sorters.run_sorter` method can accept the dictionary which is returned
@@ -404,10 +403,10 @@ In this example, we create a 16-channel recording with 4 tetrodes:
404403
sorting = run_sorter(sorter_name='kilosort2', recording=recording, folder=f"folder_KS2_group{group}")
405404
sortings[group] = sorting
406405
407-
Read more about preprocessing and sorting by group in our How To, :ref:`recording-by-channel-group`.
408406
409-
Note: you can feed the dict of sortings and dict of recordings directly to :code:`create_sorting_analyzer` to make
410-
a SortingAnalyzer from the split data: :ref:`read more <process_by_group>`.
407+
.. note::
408+
409+
Read more about preprocessing and sorting by group in our How To, :ref:`process_by_group`.
411410

412411

413412
Handling multi-segment recordings
@@ -447,11 +446,14 @@ do not handle multi-segment, and in that case we will use the
447446
448447
# Case 2: the sorter DOES NOT handle multi-segment objects
449448
# The `concatenate_recordings()` mimics a mono-segment object that concatenates all segments
450-
multirecording = si.concatenate_recordings(recordings_list)
451-
# multirecording has 1 segment of 40s each
449+
recording_concat = si.concatenate_recordings(recordings_list)
450+
# recording_concat has 1 segment of 40s each
452451
453452
# run mountainsort4 in mono-segment mode
454-
multisorting = si.run_sorter(sorter_name='mountainsort4', recording=multirecording)
453+
sorting_concat = si.run_sorter(sorter_name='mountainsort4', recording=recording_concat)
454+
455+
# split sorting back to multi-segment using concatenation info
456+
multisorting = si.split_sorting(sorting_concat, recording_concat)
455457
456458
See also the :ref:`multi_seg` section.
457459

@@ -485,11 +487,12 @@ Here is the list of external sorters accessible using the run_sorter wrapper:
485487
* **Combinato** :code:`run_sorter(sorter_name='combinato')`
486488
* **HDSort** :code:`run_sorter(sorter_name='hdsort')`
487489

488-
Here is a list of internal sorter based on `spikeinterface.sortingcomponents`; they are totally
489-
experimental for now:
490+
Here is a list of internal sorter based on :py:mod:`spikeinterface.sortingcomponents`:
490491

492+
* **Lupin** :code:`run_sorter(sorter_name='lupin')`
491493
* **Spyking Circus2** :code:`run_sorter(sorter_name='spykingcircus2')`
492494
* **Tridesclous2** :code:`run_sorter(sorter_name='tridesclous2')`
495+
* **Simple** :code:`run_sorter(sorter_name='simple')`
493496

494497
Here is the list of legacy sorters that are no longer supported, but can still be run
495498
with an older version of SpikeInterface:
@@ -546,8 +549,10 @@ Internal sorters
546549
In 2022, we started the :py:mod:`spikeinterface.sortingcomponents` module to break into components a sorting pipeline.
547550
These components can be gathered to create a new sorter. We already have 2 sorters to showcase this new module:
548551

549-
* :code:`spykingcircus2` (experimental, but ready to be tested)
550-
* :code:`tridesclous2` (experimental, not ready to be used)
552+
* :code:`spykingcircus2`
553+
* :code:`tridesclous2`
554+
* :code:`lupin`
555+
* :code:`simple`
551556

552557
There are some benefits of using these sorters:
553558
* they directly handle SpikeInterface objects, so they do not need any data copy.
@@ -560,7 +565,13 @@ From the user's perspective, they behave exactly like the external sorters:
560565
561566
sorting = run_sorter(sorter_name="spykingcircus2", recording=recording, folder="/tmp/folder")
562567
563-
Read more in the :ref:`sorting-components-module` docs.
568+
These sorters are based on the :py:mod:`spikeinterface.sortingcomponents`, allowing fast and modular implementations
569+
of various algorithms often encountered in spike-sorting.
570+
571+
Please go to :ref:`internal_sorters` for more details on how they work.
572+
573+
Read more in the :ref:`sorting-components-module` docs for more low level details on components.
574+
564575

565576
Contributing
566577
------------

doc/modules/sorters_internal.rst

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
.. _internal_sorters:
2+
3+
Internal sorters
4+
================
5+
6+
:py:mod:`spikeinterface.sortingcomponents` implement algorithms to break a sorting pipeline
7+
into individual components. With this components it is easy to develop a new sorter.
8+
9+
These components and sorters havs been benchmarked [here](https://github.com/samuelgarcia/sorting_components_benchmark_paper).
10+
11+
12+
At the moment, there are 4 internal sorters implemented in ``spikeinterface``:
13+
14+
* :code:`lupin`
15+
* :code:`spykingcircus2`
16+
* :code:`tridesclous2`
17+
* :code:`simple`
18+
19+
20+
Lupin
21+
-----
22+
23+
Lupin is components-based sorters, it combine components that give the best reults on benchmarks
24+
for each steps. It is theorically the "best" sorter that ``spikeinterface`` can offer internally.
25+
26+
Lupin components are:
27+
* preprocessing (filtering, CMR, whitening)
28+
* the *DREDGE* motion correction algorithm (optional)
29+
* peak detection with *matched filtering*
30+
* iterative splits for clustering *Iter-ISOPLIT*
31+
* augmented matching pursuit for the spike deconvolution with *Wobble*
32+
33+
34+
Some notes on this algorithm and related parameters:
35+
* waveforms size is different for clustering and template matching:
36+
``clustering_ms_before``, ``clustering_ms_after``, ``ms_before``, ``ms_after``
37+
* the filtering is quite smooth by default to filter out high-frequency noise: ``freq_max=7000``
38+
* ``n_pca_features`` can impact the clustering step
39+
* there is a cleaning step before the template matching using ``template_sparsify_threshold``,
40+
``template_min_snr_ptp``, ``template_max_jitter_ms``, and ``min_firing_rate``. This step can have a substantial impact on the result.
41+
* Lupin is a bit slower than ``tridesclous2`` and ``spkykingcircus2``, but more accurate!
42+
43+
SpyKING-CIRCUS 2
44+
----------------
45+
46+
This is an updated version of SpyKING-CIRCUS [Yger2018]_ based on the modular
47+
components. In summary, this spike sorting pipeline uses optionaly the DREDGE motion
48+
correction algorithm before filtering and whitening the data. On these whitened data, the chains of components
49+
that are used are: matched filtering for peak detection, iterative splits for clustering (Iter-HDBSCAN),
50+
and orthogonal matching pursuit for template reconstruction (Circus-OMP).
51+
52+
SpyKING-CIRCUS 2 components are:
53+
* preprocessing (filtering, CMR, whitening)
54+
* the *DREDGE* motion correction algorithm (optional)
55+
* peak detection with *matched filtering*
56+
* iterative splits for clustering *Iter-HDBSCAN*
57+
* orthogonal matching pursuit for the spike deconvolution with *Circus-OMP*
58+
59+
TriDesClous 2
60+
-------------
61+
62+
This is an updated version of TriDesClous based on the modular components.
63+
It is not as good as ``Lupin`` in terms of performance, but it's way faster.
64+
This is sorter is a good choice for a very fast exploration of a dataset.
65+
66+
TriDesClous 2 components are:
67+
* preprocessing (filtering, CMR) but no whitening
68+
* the *DREDGE* motion correction algorithm (optional)
69+
* peak detection with *locally_exlusive*
70+
* iterative splits for clustering *Iter-ISOPLIT*
71+
* fast template matching using the *TDC-peeler*
72+
73+
74+
Simple
75+
------
76+
77+
This is a simple sorter that **does not use the template matching**.
78+
It can be seen as an "old school" sorter with only peak detection, feature reduction (svd) and
79+
clustering.
80+
Using this sorter can be very useful on mono channel and tetrode datasets.
81+
Very often on 1-4 channel dataset when the SNR is too small then template matching is an overkill
82+
feature that gives worse results.
83+
84+
The clustering step is quite flexible and several algorithms can be tested (k-means, isosplit, hdbscan, ...)

doc/references.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ please include the appropriate citation for the :code:`sorter_name` parameter yo
4444
- :code:`kilosort` [Pachitariu]_
4545
- :code:`mountainsort` [Chung]_
4646
- :code:`rtsort` [van_der_Molen]_
47-
- :code:`spykingcircus` [Yger]_
47+
- :code:`spykingcircus` [Yger2018]_
4848
- :code:`wavclus` [Chaure]_
4949
- :code:`yass` [Lee]_
5050

@@ -178,6 +178,6 @@ References
178178
179179
.. [Windolf_b] `DREDge: robust motion correction for high-density extracellular recordings across species. 2023 <https://www.biorxiv.org/content/10.1101/2023.10.24.563768v1>`_
180180
181-
.. [Yger] `A spike sorting toolbox for up to thousands of electrodes validated with ground truth recordings in vitro and in vivo. 2018. <https://pubmed.ncbi.nlm.nih.gov/29557782/>`_
181+
.. [Yger2018] `A spike sorting toolbox for up to thousands of electrodes validated with ground truth recordings in vitro and in vivo. 2018. <https://pubmed.ncbi.nlm.nih.gov/29557782/>`_
182182
183183
.. [Scopin2024] `Localization of neurons from extracellular footprints <https://doi.org/10.1016/j.jneumeth.2024.110297>`_

0 commit comments

Comments
 (0)