Skip to content
Open
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
e1817f2
Initial dartsort wrapper implementation.
samuelgarcia Oct 24, 2023
e013256
Merge branch 'main' of github.com:SpikeInterface/spikeinterface into …
samuelgarcia Feb 11, 2026
86800eb
wip
samuelgarcia Feb 11, 2026
c60b6a6
wip dartsort wrapper
samuelgarcia Feb 12, 2026
2b76ead
output of darsort
samuelgarcia Feb 12, 2026
d445917
debug darsort output structure
samuelgarcia Feb 13, 2026
5df983f
Merge branch 'main' of github.com:SpikeInterface/spikeinterface into …
samuelgarcia Apr 20, 2026
186d133
Merge branch 'main' of github.com:SpikeInterface/spikeinterface into …
samuelgarcia Apr 23, 2026
a25835c
Improve backward compatibility for dartsort after the chunkable PR (4…
samuelgarcia Apr 23, 2026
a275086
Merge branch 'backward_compatibility_get_chunk_with_margin' of github…
samuelgarcia Apr 23, 2026
2e679d0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 23, 2026
ed6c7e5
oups
samuelgarcia Apr 23, 2026
d8b658a
Merge branch 'backward_compatibility_get_chunk_with_margin' of github…
samuelgarcia Apr 23, 2026
8de0656
oups
samuelgarcia Apr 23, 2026
23a5775
Merge branch 'backward_compatibility_get_chunk_with_margin' of github…
samuelgarcia Apr 23, 2026
b5ee39a
Merge branch 'main' of github.com:SpikeInterface/spikeinterface into …
samuelgarcia Jun 3, 2026
6e69d6c
Merge branch 'main' of github.com:SpikeInterface/spikeinterface into …
samuelgarcia Jul 6, 2026
5c4ae84
Merge branch 'main' of github.com:SpikeInterface/spikeinterface into …
samuelgarcia Aug 17, 2026
a8424ac
Merge branch 'main' of github.com:SpikeInterface/spikeinterface into …
samuelgarcia Sep 8, 2026
1e7953a
clean dartsort wrapper
samuelgarcia Sep 8, 2026
d1033c0
Update src/spikeinterface/sorters/external/dartsort.py
samuelgarcia Sep 8, 2026
91612fe
Apply batched suggestions from code review
samuelgarcia Sep 8, 2026
d9c991f
Merge branch 'main' into dartsort_wrapper
samuelgarcia Sep 8, 2026
bc37b37
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 8, 2026
fb615ae
add dartsort docs
chrishalcrow Sep 8, 2026
ba4065c
Update src/spikeinterface/sorters/external/dartsort.py
chrishalcrow Sep 10, 2026
04792b5
Merge branch 'main' into dartsort_wrapper
chrishalcrow Sep 10, 2026
ffeb1a5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 10, 2026
669bec6
fix: use np.bincount for mode
alejoe91 Sep 10, 2026
bb333ef
fix: use sorting.save instead of write_sorting to preserve main_chann…
alejoe91 Sep 10, 2026
e071063
update dartsort refereces and docs
alejoe91 Sep 10, 2026
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Please [Star](https://github.com/SpikeInterface/spikeinterface/stargazers) the p

SpikeInterface is a Python package designed to unify preexisting spike sorting technologies into a single code base. If you use SpikeInterface, you are also using code and ideas from many other projects. Our codebase would be tiny without the amazing algorithms and formats that we interface with. See them all, and how to cite them, on our [references page](https://spikeinterface.readthedocs.io/en/latest/references.html). In the past year, we have added support for the following tools:

- dartsort [DARTsort: A modular drift tracking spike sorter for high-density multi-electrode probes](https://www.biorxiv.org/content/10.1101/2023.08.11.553023v1) ([docs](https://spikeinterface.readthedocs.io/en/stable/modules/sorters.html#supported-spike-sorters))
- Bombcell [Bombcell: automated curation and cell classification of spike-sorted electrophysiology data](https://doi.org/10.5281/zenodo.8172822>) ([docs](https://spikeinterface.readthedocs.io/en/latest/how_to/auto_label_units.html#bombcell))
- SLAy. [SLAy-ing oversplitting errors in high-density electrophysiology spike sorting](https://www.biorxiv.org/content/10.1101/2025.06.20.660590v2) ([docs](https://spikeinterface.readthedocs.io/en/latest/modules/curation.html#auto-merging-units))
- Lupin, Spykingcircus2 and Tridesclous2. [Opening the black box: a modular approach to spike sorting](https://www.biorxiv.org/content/10.64898/2026.01.23.701239v1) ([docs](https://spikeinterface.readthedocs.io/en/stable/modules/sorters.html#supported-spike-sorters))
Expand Down
1 change: 1 addition & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ amazing algorithms and formats that we interface with. See them all, and how to
`references page <https://spikeinterface.readthedocs.io/en/latest/references.html>`_. In the past year, we have added support
for the following tools:

- *dartsort*. `DARTsort: A modular drift tracking spike sorter for high-density multi-electrode probes <https://www.biorxiv.org/content/10.1101/2023.08.11.553023v1>`_ (`docs <https://spikeinterface.readthedocs.io/en/stable/modules/sorters.html#supported-spike-sorters>`_)
- Bombcell. `Bombcell: automated curation and cell classification of spike-sorted electrophysiology data. <https://doi.org/10.5281/zenodo.8172822>`_ (`docs <https://spikeinterface.readthedocs.io/en/latest/how_to/auto_label_units.html#bombcell>`_)
- SLAy. `SLAy-ing oversplitting errors in high-density electrophysiology spike sorting <https://www.biorxiv.org/content/10.1101/2025.06.20.660590v2>`_ (`docs <https://spikeinterface.readthedocs.io/en/latest/modules/curation.html#auto-merging-units>`_)
- Lupin, Spykingcicus2 and Tridesclous2. `Opening the black box: a modular approach to spike sorting <https://www.biorxiv.org/content/10.64898/2026.01.23.701239v1>`_ (`docs <https://spikeinterface.readthedocs.io/en/stable/modules/sorters.html#supported-spike-sorters>`_)
Expand Down
1 change: 1 addition & 0 deletions doc/modules/sorters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ versions.

Here is the list of external sorters accessible using the run_sorter wrapper:

* **dartsort** :code:`run_sorter(sorter_name='dartsort')`
* **HerdingSpikes2** :code:`run_sorter(sorter_name='herdingspikes')`
* **IronClust** :code:`run_sorter(sorter_name='ironclust')`
* **Kilosort** :code:`run_sorter(sorter_name='kilosort')`
Expand Down
3 changes: 3 additions & 0 deletions doc/references.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ If you use one of the following spike sorting algorithms (i.e. you use the :code
please include the appropriate citation for the :code:`sorter_name` parameter you use:
*Note: unless otherwise stated, the reference given is to be used for all versions of the sorter*

- :code:`dartsort` [Boussard2023]_
- :code:`combinato` [Niediek]_
- :code:`hdsort` [Diggelmann]_
- :code:`herdingspikes` [Muthmann]_ [Hilgen]_
Expand Down Expand Up @@ -110,6 +111,8 @@ References

.. [Boussard] `Three-dimensional spike localization and imporved motion correction for Neuropixels recordings. 2021 <https://www.biorxiv.org/content/10.1101/2021.11.05.467503v1>`_

.. [Boussard2023] `DARTsort: A modular drift tracking spike sorter for high-density multi-electrode probes. 2023 <https://www.biorxiv.org/content/10.1101/2023.08.11.553023v1>`_

.. [Buccino] `SpikeInterface, a unified framework for spike sorting. 2020. <https://pubmed.ncbi.nlm.nih.gov/33170122/>`_

.. [Buzsáki] `The Log-Dynamic Brain: How Skewed Distributions Affect Network Operations. 2014. <https://pubmed.ncbi.nlm.nih.gov/24569488/>`_
Expand Down
104 changes: 104 additions & 0 deletions src/spikeinterface/sorters/external/dartsort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
from pathlib import Path

import numpy as np

from ..basesorter import BaseSorter
from ...core import load


class DartsortSorter(BaseSorter):
"""Dartsort wrapper"""

sorter_name = "dartsort"
requires_locations = False
compatible_with_parallel = {"loky": False, "multiprocessing": False, "threading": False}
sorter_description = """dartsort is a modular, drift-aware spike sorter developed in the Paninski lab. For installation and documentation, see https://dartsort.github.io"""
installation_mesg = """\nTo use dartsort run:\n
>>> pip install dartsort

More information about installing dartsort at:
* https://dartsort.github.io
"""

_default_params = {}

_params_description = {}

@classmethod
def _dynamic_params(cls):
from dartsort import DARTsortUserConfig
from pydantic import RootModel

# the trick is to transform the DARTsortUserConfig (a pydantic.dataclass) into a pydantic model
Model = RootModel[DARTsortUserConfig]
# so we can dump to dict
cfg = Model(DARTsortUserConfig())
default_params = cfg.model_dump(mode="python")
# and retrieve properties
schema = Model.model_json_schema()
default_params_descriptions = {}
for k, props in schema["$defs"]["DARTsortUserConfig"]["properties"].items():
default_params_descriptions[k] = props["title"]

return default_params, default_params_descriptions

@classmethod
def is_installed(cls):
try:
import dartsort

HAVE_DARTSORT = True
except ImportError:
HAVE_DARTSORT = False

return HAVE_DARTSORT

@staticmethod
def get_sorter_version():
import dartsort

if hasattr(dartsort, "__version__"):
return dartsort.__version__
return "unknown"

@classmethod
def _setup_recording(cls, recording, sorter_output_folder, params, verbose):
pass

@classmethod
def _run_from_folder(cls, sorter_output_folder, params, verbose):
from dartsort import dartsort as dartsort_main
from dartsort import DARTsortUserConfig

recording = cls.load_recording_from_folder(sorter_output_folder.parent, with_warnings=False)

# Dartsort can be given the motion object optionaly
motion = params.pop("motion", None)

# dartsort config are set using dataclass we need to map this
cfg = DARTsortUserConfig(**params)

ret = dartsort_main(
Comment thread
samuelgarcia marked this conversation as resolved.
recording,
sorter_output_folder,
cfg,
motion=motion,
)
# the DARTsortSorting is not the spikeinterface sorting
dartsort_sorting = ret["sorting"]
sorting = dartsort_sorting.to_numpy_sorting()

Comment thread
chrishalcrow marked this conversation as resolved.
# Add main_channel_id property by taking mode of channels from spikes
labels = dartsort_sorting.labels
spike_channels = dartsort_sorting.channels
main_channel_indices = [np.bincount(spike_channels[labels == unit_id]).argmax() for unit_id in sorting.unit_ids]
main_channel_ids = recording.channel_ids[main_channel_indices]
sorting.set_property("main_channel_id", main_channel_ids)
# We save to the final_darsort_sorting folder to propagate the main_channel_id property
sorting.save(folder=sorter_output_folder / "final_darsort_sorting")

@classmethod
def _get_result_from_folder(cls, sorter_output_folder):
sorter_output_folder = Path(sorter_output_folder)
sorting = load(sorter_output_folder / "final_darsort_sorting")
return sorting
19 changes: 19 additions & 0 deletions src/spikeinterface/sorters/external/tests/test_dartsort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import unittest
import pytest

from spikeinterface.sorters import DartsortSorter
from spikeinterface.sorters.tests.common_tests import SorterCommonTestSuite


@pytest.mark.skipif(not DartsortSorter.is_installed(), reason="dartsort not installed")
class DartsortCommonTestSuite(SorterCommonTestSuite, unittest.TestCase):
SorterClass = DartsortSorter


if __name__ == "__main__":
from pathlib import Path

test = DartsortCommonTestSuite()
test.cache_folder = Path(__file__).resolve().parents[4] / "cache_folder" / "sorters"
test.setUp()
test.test_with_run()
2 changes: 2 additions & 0 deletions src/spikeinterface/sorters/sorterlist.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .external.combinato import CombinatoSorter
from .external.dartsort import DartsortSorter
from .external.hdsort import HDSortSorter
from .external.herdingspikes import HerdingspikesSorter
from .external.ironclust import IronClustSorter
Expand Down Expand Up @@ -27,6 +28,7 @@
sorter_full_list = [
# external
CombinatoSorter,
DartsortSorter,
HDSortSorter,
HerdingspikesSorter,
IronClustSorter,
Expand Down
Loading