Skip to content

Commit c5cb501

Browse files
authored
Merge branch 'main' into append-concat
2 parents 9ec85fe + 6b75bd3 commit c5cb501

21 files changed

Lines changed: 701 additions & 256 deletions

doc/modules/sorters.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ Here is the list of external sorters accessible using the run_sorter wrapper:
469469
* **Klusta** :code:`run_sorter(sorter_name='klusta')`
470470
* **Mountainsort4** :code:`run_sorter(sorter_name='mountainsort4')`
471471
* **Mountainsort5** :code:`run_sorter(sorter_name='mountainsort5')`
472+
* **RT-Sort** :code:`run_sorter(sorter_name='rt-sort')`
472473
* **SpyKING Circus** :code:`run_sorter(sorter_name='spykingcircus')`
473474
* **Tridesclous** :code:`run_sorter(sorter_name='tridesclous')`
474475
* **Wave clus** :code:`run_sorter(sorter_name='waveclus')`

doc/references.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ please include the appropriate citation for the :code:`sorter_name` parameter yo
4343
- :code:`herdingspikes` [Muthmann]_ [Hilgen]_
4444
- :code:`kilosort` [Pachitariu]_
4545
- :code:`mountainsort` [Chung]_
46+
- :code:`rt-sort` [van_der_Molen]_
4647
- :code:`spykingcircus` [Yger]_
4748
- :code:`wavclus` [Chaure]_
4849
- :code:`yass` [Lee]_
@@ -154,6 +155,8 @@ References
154155
155156
.. [UMS] `UltraMegaSort2000 - Spike sorting and quality metrics for extracellular spike data. 2011. <https://github.com/danamics/UMS2K>`_
156157
158+
.. [van_der_Molen] `RT-Sort: An action potential propagation-based algorithm for real time spike detection and sorting with millisecond latencies. 2024. <https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0312438>`_
159+
157160
.. [Varol] `Decentralized Motion Inference and Registration of Neuropixel Data. 2021. <https://ieeexplore.ieee.org/document/9414145>`_
158161
159162
.. [Watters] `MEDiCINe: Motion Correction for Neural Electrophysiology Recordings. 2025. <https://www.eneuro.org/content/12/3/ENEURO.0529-24.2025>`_

installation_tips/README.md

Lines changed: 78 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,105 @@
11
## Installation tips
22

3-
If you are not (yet) an expert in Python installations (conda vs pip, mananging environements, etc.),
4-
here we propose a simple recipe to install `spikeinterface` and several sorters inside an anaconda
5-
environment for windows/mac users.
6-
7-
This environment will install:
8-
* spikeinterface full option
3+
If you are not (yet) an expert in Python installations, the first major hurdle is choosing the installation procedure.
4+
5+
Some key concepts you need to know before starting:
6+
* Python itself can be distributed and installed many, many ways.
7+
* Python itself does not contain many features for scientific computing, so you need to install "packages". For example
8+
numpy, scipy, matplotlib, spikeinterface, ... These are all examples of Python packages that aid in scientific computation.
9+
* All of these packages have their own dependencies which requires figuring out which versions of the dependencies work for
10+
the combination of packages you as the user want to use.
11+
* Packages can be distributed and installed in several ways (pip, conda, uv, mamba, ...) and luckily these methods of installation
12+
typically take care of solving the dependencies for you!
13+
* Installing many packages at once is challenging (because of their dependency graphs) so you need to do it in an "isolated environment" to not destroy any previous installation. You need to see an "environment" as a sub-installation in a dedicated folder.
14+
15+
Choosing the installer + an environment manager + a package installer is a nightmare for beginners.
16+
17+
The main options are:
18+
* use "uv", a new, fast and simple package manager. We recommend this for beginners on every operating system.
19+
* use "anaconda" (or its flavors-mamba, miniconda), which does everything. Used to be very popular but theses days it is becoming
20+
harder to use because it is slow by default and has relatively strict licensing on the default channel (not always free anymore).
21+
You need to play with "community channels" to make it free again, which is complicated for beginners.
22+
This way is better for users in organizations that have specific licensing agrees with anaconda already in place.
23+
* use Python from the system or Python.org + venv + pip: good and simple idea for Linux users, but does require familiarity with
24+
the Python ecosystem (so good for intermediate users).
25+
26+
Here we propose a step by step recipe for beginners based on [**"uv"**](https://github.com/astral-sh/uv).
27+
We used to recommend installing with anaconda. It will be kept here for a while but we do not recommend it anymore.
28+
29+
30+
This recipe will install:
31+
* spikeinterface `full` option
932
* spikeinterface-gui
10-
* phy
11-
* tridesclous
33+
* kilosort4
1234

13-
Kilosort, Ironclust and HDSort are MATLAB based and need to be installed from source.
35+
into our uv venv environment.
1436

15-
### Quick installation
1637

17-
Steps:
38+
### Quick installation using "uv" (recommended)
1839

19-
1. Download anaconda individual edition [here](https://www.anaconda.com/download)
20-
2. Run the installer. Check the box “Add anaconda3 to my Path environment variable”. It makes life easier for beginners.
21-
3. Download with right click + save the file corresponding to your OS, and put it in "Documents" folder
22-
* [`full_spikeinterface_environment_windows.yml`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/main/installation_tips/full_spikeinterface_environment_windows.yml)
23-
* [`full_spikeinterface_environment_mac.yml`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/main/installation_tips/full_spikeinterface_environment_mac.yml)
24-
4. Then open the "Anaconda Command Prompt" (if Windows, search in your applications) or the Terminal (for Mac users)
25-
5. If not in the "Documents" folder type `cd Documents`
26-
6. Then run this depending on your OS:
27-
* `conda env create --file full_spikeinterface_environment_windows.yml`
28-
* `conda env create --file full_spikeinterface_environment_mac.yml`
40+
1. On macOS and Linux. Open a terminal and do
41+
`curl -LsSf https://astral.sh/uv/install.sh | sh`
42+
2. On Windows. Open an instance of the Powershell (Windows has many options this is the recommended one from uv)
43+
`powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"`
44+
3. Exit the session and log in again.
45+
4. Download with right click and save this file in your "Documents" folder:
46+
* [`beginner_requirements_stable.txt`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/main/installation_tips/beginner_requirements_stable.txt) for stable release
47+
5. Open terminal or powershell and run:
48+
6. `uv venv si_env --python 3.12`
49+
7. Activate your virtual environment by running:
50+
- For Mac/Linux: `source si_env/bin/activate` (you should see `(si_env)` in your terminal)
51+
- For Windows: `si_env\Scripts\activate`
52+
8. Run `uv pip install -r Documents/beginner_requirements_stable.txt`
2953

3054

31-
Done! Before running a spikeinterface script you will need to "select" this "environment" with `conda activate si_env`.
55+
## Installing before release (from source)
3256

33-
Note for **linux** users : this conda recipe should work but we recommend strongly to use **pip + virtualenv**.
57+
Some tools in the spikeinteface ecosystem are getting regular bug fixes (spikeinterface, spikeinterface-gui, probeinterface, neo).
58+
We are making releases 2 to 4 times a year. In between releases if you want to install from source you can use the `beginner_requirements_rolling.txt` file to create the environment instead of the `beginner_requirements_stable.txt` file. This will install the packages of the ecosystem from source.
59+
This is a good way to test if a patch fixes your issue.
3460

3561

3662
### Check the installation
3763

38-
3964
If you want to test the spikeinterface install you can:
4065

4166
1. Download with right click + save the file [`check_your_install.py`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/main/installation_tips/check_your_install.py)
4267
and put it into the "Documents" folder
43-
44-
2. Open the Anaconda Command Prompt (Windows) or Terminal (Mac)
45-
3. If not in your "Documents" folder type `cd Documents`
46-
4. Run this:
47-
```
48-
conda activate si_env
49-
python check_your_install.py
50-
```
51-
5. If a windows user to clean-up you will also need to right click + save [`cleanup_for_windows.py`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/main/installation_tips/cleanup_for_windows.py)
52-
Then transfer `cleanup_for_windows.py` into your "Documents" folder. Finally run :
68+
2. Open the CMD Prompt (Windows)[^1] or Terminal (Mac/Linux)
69+
3. Activate your si_env : `source si_env/bin/activate` (Max/Linux), `si_env\Scripts\activate` (Windows)
70+
4. Go to your "Documents" folder with `cd Documents` or the place where you downloaded the `check_your_install.py`
71+
5. Run `python check_your_install.py`
72+
6. If you are a Windows user, you should also right click + save [`cleanup_for_windows.py`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/main/installation_tips/cleanup_for_windows.py). Then transfer `cleanup_for_windows.py` into your "Documents" folder and finally run:
5373
```
5474
python cleanup_for_windows.py
5575
```
5676

57-
This script tests the following:
77+
This script tests the following steps:
5878
* importing spikeinterface
59-
* running tridesclous
60-
* running spyking-circus (not on mac)
61-
* running herdingspikes (not on windows)
79+
* running tridesclous2
80+
* running kilosort4
6281
* opening the spikeinterface-gui
63-
* exporting to Phy
6482

6583

66-
## Installing before release
84+
### Legacy installation using Anaconda (not recommended anymore)
85+
86+
Steps:
87+
88+
1. Download Anaconda individual edition [here](https://www.anaconda.com/download)
89+
2. Run the installer. Check the box “Add anaconda3 to my Path environment variable”. It makes life easier for beginners.
90+
3. Download with right click + save the environment YAML file ([`beginner_conda_env_stable.yml`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/main/installation_tips/beginner_conda_env_stable.yml)) and put it in "Documents" folder
91+
4. Then open the "Anaconda Command Prompt" (if Windows, search in your applications) or the Terminal (for Mac users)
92+
5. If not in the "Documents" folder type `cd Documents`
93+
6. Run this command to create the environment:
94+
```bash
95+
conda env create --file beginner_conda_env_stable.yml
96+
```
97+
98+
Done! Before running a spikeinterface script you will need to "select" this "environment" with `conda activate si_env`.
99+
100+
Note for **Linux** users: this conda recipe should work but we recommend strongly to use **pip + virtualenv**.
101+
102+
67103

68-
Some tools in the spikeinteface ecosystem are getting regular bug fixes (spikeinterface, spikeinterface-gui, probeinterface, python-neo, sortingview).
69-
We are making releases 2 to 4 times a year. In between releases if you want to install from source you can use the `full_spikeinterface_environment_rolling_updates.yml` file to create the environment. This will install the packages of the ecosystem from source.
70-
This is a good way to test if patch fix your issue.
104+
[^1]: Although uv installation instructions are for the Powershell, our sorter scripts are for the CMD Prompt. After the initial installation with Powershell, any session that will have sorting requires the CMD Prompt. If you do not
105+
plan to spike sort in a session either shell could be used.

installation_tips/full_spikeinterface_environment_linux_dandi.yml renamed to installation_tips/beginner_conda_env_stable.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ channels:
33
- conda-forge
44
- defaults
55
dependencies:
6-
- python=3.11
6+
- python=3.12
77
- pip
88
- numpy
99
- scipy
@@ -13,7 +13,7 @@ dependencies:
1313
- h5py
1414
- pandas
1515
- xarray
16-
- zarr
16+
- zarr<3
1717
- scikit-learn
1818
- hdbscan
1919
- networkx
@@ -30,8 +30,6 @@ dependencies:
3030
- libxcb
3131
- pip:
3232
- ephyviewer
33-
- MEArec
3433
- spikeinterface[full,widgets]
3534
- spikeinterface-gui
36-
- tridesclous
37-
# - phy==2.0b5
35+
- kilosort>4.0.30
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
https://github.com/NeuralEnsemble/python-neo/archive/master.zip
2+
https://github.com/SpikeInterface/probeinterface/archive/main.zip
3+
https://github.com/SpikeInterface/spikeinterface/archive/main.zip[full,widgets]
4+
https://github.com/SpikeInterface/spikeinterface-gui/archive/main.zip
5+
jupyterlab
6+
PySide6<6.8
7+
hdbscan
8+
pyqtgraph
9+
ephyviewer
10+
kilosort>4.0.30
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
spikeinterface[full,widgets]
2+
jupyterlab
3+
PySide6<6.8
4+
hdbscan
5+
pyqtgraph
6+
ephyviewer
7+
spikeinterface-gui
8+
kilosort>4.0.30

installation_tips/check_your_install.py

Lines changed: 43 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,115 @@
11
from pathlib import Path
22
import platform
3-
import os
43
import shutil
54
import argparse
5+
import warnings
6+
7+
warnings.filterwarnings("ignore")
8+
9+
10+
job_kwargs = dict(n_jobs=-1, progress_bar=False, chunk_duration="1s")
11+
612

713
def check_import_si():
814
import spikeinterface as si
915

16+
1017
def check_import_si_full():
1118
import spikeinterface.full as si
1219

1320

1421
def _create_recording():
1522
import spikeinterface.full as si
16-
rec, sorting = si.toy_example(num_segments=1, duration=200, seed=1, num_channels=16, num_columns=2)
17-
rec.save(folder='./toy_example_recording')
23+
24+
rec, _ = si.generate_ground_truth_recording(
25+
durations=[200.0], sampling_frequency=30_000.0, num_channels=16, num_units=10, seed=2205
26+
)
27+
rec.save(folder="./toy_example_recording", verbose=False, **job_kwargs)
1828

1929

2030
def _run_one_sorter_and_analyzer(sorter_name):
21-
job_kwargs = dict(n_jobs=-1, progress_bar=True, chunk_duration="1s")
2231
import spikeinterface.full as si
23-
recording = si.load_extractor('./toy_example_recording')
24-
sorting = si.run_sorter(sorter_name, recording, folder=f'./sorter_with_{sorter_name}', verbose=False)
2532

26-
sorting_analyzer = si.create_sorting_analyzer(sorting, recording,
27-
format="binary_folder", folder=f"./analyzer_with_{sorter_name}",
28-
**job_kwargs)
33+
si.set_global_job_kwargs(**job_kwargs)
34+
35+
recording = si.load("./toy_example_recording")
36+
sorting = si.run_sorter(sorter_name, recording, folder=f"./sorter_with_{sorter_name}", verbose=False)
37+
38+
sorting_analyzer = si.create_sorting_analyzer(
39+
sorting, recording, format="binary_folder", folder=f"./analyzer_with_{sorter_name}"
40+
)
2941
sorting_analyzer.compute("random_spikes", method="uniform", max_spikes_per_unit=500)
30-
sorting_analyzer.compute("waveforms", **job_kwargs)
42+
sorting_analyzer.compute("waveforms")
3143
sorting_analyzer.compute("templates")
3244
sorting_analyzer.compute("noise_levels")
3345
sorting_analyzer.compute("unit_locations", method="monopolar_triangulation")
34-
sorting_analyzer.compute("correlograms", window_ms=100, bin_ms=5.)
35-
sorting_analyzer.compute("principal_components", n_components=3, mode='by_channel_global', whiten=True, **job_kwargs)
46+
sorting_analyzer.compute("correlograms", window_ms=100, bin_ms=5.0)
47+
sorting_analyzer.compute("principal_components", n_components=3, mode="by_channel_global", whiten=True)
3648
sorting_analyzer.compute("quality_metrics", metric_names=["snr", "firing_rate"])
3749

3850

39-
def run_tridesclous():
40-
_run_one_sorter_and_analyzer('tridesclous')
41-
4251
def run_tridesclous2():
43-
_run_one_sorter_and_analyzer('tridesclous2')
52+
_run_one_sorter_and_analyzer("tridesclous2")
4453

4554

55+
def run_kilosort4():
56+
_run_one_sorter_and_analyzer("kilosort4")
57+
4658

4759
def open_sigui():
4860
import spikeinterface.full as si
49-
import spikeinterface_gui
50-
app = spikeinterface_gui.mkQApp()
51-
52-
sorter_name = "tridesclous2"
53-
folder = f"./analyzer_with_{sorter_name}"
54-
analyzer = si.load_sorting_analyzer(folder)
61+
from spikeinterface_gui import run_mainwindow
5562

56-
win = spikeinterface_gui.MainWindow(analyzer)
57-
win.show()
58-
app.exec_()
59-
60-
def export_to_phy():
61-
import spikeinterface.full as si
6263
sorter_name = "tridesclous2"
6364
folder = f"./analyzer_with_{sorter_name}"
6465
analyzer = si.load_sorting_analyzer(folder)
6566

66-
phy_folder = "./phy_example"
67-
si.export_to_phy(analyzer, output_folder=phy_folder, verbose=False)
68-
69-
70-
def open_phy():
71-
os.system("phy template-gui ./phy_example/params.py")
67+
win = run_mainwindow(analyzer, start_app=True)
7268

7369

7470
def _clean():
7571
# clean
7672
folders = [
7773
"./toy_example_recording",
78-
"./sorter_with_tridesclous",
79-
"./analyzer_with_tridesclous",
8074
"./sorter_with_tridesclous2",
8175
"./analyzer_with_tridesclous2",
82-
"./phy_example"
76+
"./sorter_with_kilosort4",
77+
"./analyzer_with_kilosort4",
8378
]
8479
for folder in folders:
8580
if Path(folder).exists():
8681
shutil.rmtree(folder)
8782

83+
8884
parser = argparse.ArgumentParser()
8985
# add ci flag so that gui will not be used in ci
9086
# end user can ignore
91-
parser.add_argument('--ci', action='store_false')
87+
parser.add_argument("--ci", action="store_false")
9288

93-
if __name__ == '__main__':
89+
if __name__ == "__main__":
9490

9591
args = parser.parse_args()
9692

9793
_clean()
9894
_create_recording()
9995

10096
steps = [
101-
('Import spikeinterface', check_import_si),
102-
('Import spikeinterface.full', check_import_si_full),
103-
('Run tridesclous', run_tridesclous),
104-
('Run tridesclous2', run_tridesclous2),
105-
]
97+
("Import spikeinterface", check_import_si),
98+
("Import spikeinterface.full", check_import_si_full),
99+
("Run tridesclous2", run_tridesclous2),
100+
("Run kilosort4", run_kilosort4),
101+
]
106102

107103
# backwards logic because default is True for end-user
108104
if args.ci:
109-
steps.append(('Open spikeinterface-gui', open_sigui))
110-
111-
steps.append(('Export to phy', export_to_phy)),
112-
# phy is removed from the env because it force a pip install PyQt5
113-
# which break the conda env
114-
# ('Open phy', open_phy),
115-
116-
# if platform.system() == "Windows":
117-
# pass
118-
# elif platform.system() == "Darwin":
119-
# pass
120-
# else:
121-
# pass
105+
steps.append(("Open spikeinterface-gui", open_sigui))
122106

123107
for label, func in steps:
124108
try:
125109
func()
126-
done = '...OK'
110+
done = "...OK"
127111
except Exception as err:
128-
done = f'...Fail, Error: {err}'
112+
done = f"...Fail, Error: {err}"
129113
print(label, done)
130114

131115
if platform.system() == "Windows":

0 commit comments

Comments
 (0)