Skip to content

Commit edbd531

Browse files
authored
Merge branch 'main' into fast-correlogram-merge
2 parents 9e7d3a2 + cbe5471 commit edbd531

78 files changed

Lines changed: 2306 additions & 771 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/full-test-with-codecov.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
- uses: actions/checkout@v4
2424
- uses: actions/setup-python@v5
2525
with:
26-
python-version: '3.10'
26+
python-version: '3.12'
2727
- name: Get ephy_testing_data current head hash
2828
# the key depends on the last comit repo https://gin.g-node.org/NeuralEnsemble/ephy_testing_data.git
2929
id: vars

doc/conf.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@
119119

120120
# for sphinx gallery plugin
121121
sphinx_gallery_conf = {
122-
'only_warn_on_example_error': True,
122+
# This is the default but including here explicitly. Should build all docs and fail on gallery failures only.
123+
# other option would be abort_on_example_error, but this fails on first failure. So we decided against this.
124+
'only_warn_on_example_error': False,
123125
'examples_dirs': ['../examples/tutorials'],
124126
'gallery_dirs': ['tutorials' ], # path where to save gallery generated examples
125127
'subsection_order': ExplicitOrder([

doc/development/development.rst

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ for the :code:`spikeinterface.extractors` module, you can use the following comm
6161
6262
The markers are located in the :code:`pyproject.toml` file in the root of the repository.
6363

64-
Note that you should install the package before running the tests. You can do this by running the following command:
64+
Note that you should install spikeinterface before running the tests. You can do this by running the following command:
6565

6666
.. code-block:: bash
6767
@@ -72,7 +72,7 @@ You can change the :code:`[test,extractors,full]` to install only the dependenci
7272
The specific environment for the CI is specified in the :code:`.github/actions/build-test-environment/action.yml` and you can
7373
find the full tests in the :code:`.github/workflows/full_test.yml` file.
7474

75-
The extractor tests require datalad for some of the tests. Here are instructions for installing datalad:
75+
Some of the extractor tests require datalad. Here are instructions for installing datalad:
7676

7777
Installing Datalad
7878
------------------
@@ -87,13 +87,13 @@ Stylistic conventions
8787

8888
SpikeInterface maintains a consistent coding style across the project. This helps to ensure readability and
8989
maintainability of the code, making it easier for contributors to collaborate. To facilitate code style
90-
for the developer we use the follwing tools and conventions:
90+
for the developer we use the following tools and conventions:
9191

9292

9393
Install Black and pre-commit
9494
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9595

96-
We use the python formatter Black, with defaults set in the :code:`pyproject.toml`. This allows for
96+
We use the Python formatter Black, with defaults set in the :code:`pyproject.toml`. This allows for
9797
easy local formatting of code.
9898

9999
To install Black, you can use pip, the Python package installer. Run the following command in your terminal:
@@ -218,7 +218,7 @@ Adding new documentation
218218

219219
Documentation can be added as a
220220
`sphinx-gallery <https://sphinx-gallery.github.io/stable/index.html>`_
221-
python file ('tutorials')
221+
Python file ('tutorials')
222222
or a
223223
`sphinx rst <https://sphinx-tutorial.readthedocs.io/step-1/>`_
224224
file (all other sections).
@@ -242,7 +242,7 @@ To run code coverage locally, you can use the following command:
242242
243243
This will run the tests and generate a report in the :code:`htmlcov` folder. You can open the :code:`index.html` file in your browser to see the report.
244244

245-
Note, however, that the running time of the command above will be slow. If you want to run the tests for a specific module, you can use the following command:
245+
Note, however, that the running time of the command above will be quite long. If you want to run the tests for a specific module, you can use the following command:
246246

247247
.. code-block:: bash
248248
@@ -252,21 +252,21 @@ Implement a new extractor
252252
-------------------------
253253

254254
SpikeInterface already supports over 30 file formats, but the acquisition system you use might not be among the
255-
supported formats list (***ref***). Most of the extractors rely on the `NEO <https://github.com/NeuralEnsemble/python-neo>`_
255+
supported formats list (****ref****). Most of the extractors rely on the `NEO <https://github.com/NeuralEnsemble/python-neo>`_
256256
package to read information from files.
257257
Therefore, to implement a new extractor to handle the unsupported format, we recommend making a new :code:`neo.rawio.BaseRawIO` class (see `example <https://github.com/NeuralEnsemble/python-neo/blob/master/neo/rawio/examplerawio.py#L44>`_).
258258
Once that is done, the new class can be easily wrapped into SpikeInterface as an extension of the
259259
:py:class:`~spikeinterface.extractors.neoextractors.neobaseextractors.NeoBaseRecordingExtractor`
260260
(for :py:class:`~spikeinterface.core.BaseRecording` objects) or
261261
:py:class:`~spikeinterface.extractors.neoextractors.neobaseextractors.NeoBaseRecordingExtractor`
262262
(for :py:class:`~spikeinterface.core.BaseSorting` objects) or with a few lines of
263-
code (e.g., see reader for `SpikeGLX <https://github.com/SpikeInterface/spikeinterface/blob/0.96.1/spikeinterface/extractors/neoextractors/spikeglx.py>`_
264-
or `Neuralynx <https://github.com/SpikeInterface/spikeinterface/blob/0.96.1/spikeinterface/extractors/neoextractors/neuralynx.py>`_).
263+
code (e.g., see reader for `SpikeGLX <https://github.com/SpikeInterface/spikeinterface/blob/main/src/spikeinterface/extractors/neoextractors/spikeglx.py>`_
264+
or `Neuralynx <https://github.com/SpikeInterface/spikeinterface/blob/main/src/spikeinterface/extractors/neoextractors/neuralynx.py>`_).
265265

266-
**NOTE:** implementing a `neo.rawio` Class is not required, but recommended. Several extractors (especially) for :code:`Sorting`
266+
**NOTE:** implementing a `neo.rawio` class is not required, but recommended. Several extractors (especially) for :code:`Sorting`
267267
objects are implemented directly in SpikeInterface and inherit from the base classes.
268-
As examples, see the `CompressedBinaryIblExtractor <https://github.com/SpikeInterface/spikeinterface/blob/0.96.1/spikeinterface/extractors/cbin_ibl.py>`_
269-
for a :py:class:`~spikeinterface.core.BaseRecording` object, or the `SpykingCircusSortingExtractor <https://github.com/SpikeInterface/spikeinterface/blob/0.96.1/spikeinterface/extractors/spykingcircusextractors.py>`_
268+
As examples, see the `IblRecordingExtractor <https://github.com/SpikeInterface/spikeinterface/blob/main/src/spikeinterface/extractors/iblextractors.py>`_
269+
for a :py:class:`~spikeinterface.core.BaseRecording` object, or the `SpykingCircusSortingExtractor <https://github.com/SpikeInterface/spikeinterface/blob/main/src/spikeinterface/extractors/spykingcircusextractors.py>`_
270270
for a a :py:class:`~spikeinterface.core.BaseSorting` object.
271271

272272

@@ -309,7 +309,7 @@ Then, you can start creating a new class:
309309
310310
class MySpikeSorter(BaseSorter):
311311
"""
312-
Brief description (optional)
312+
Brief description
313313
"""
314314
315315
sorter_name = 'myspikesorter'
@@ -367,7 +367,7 @@ Now you can start filling out the required methods:
367367
def _check_apply_filter_in_params(cls, params):
368368
return False
369369
370-
#  optional
370+
# optional
371371
# can be implemented in subclass to check if the filter will be applied
372372
373373
@@ -388,10 +388,12 @@ Now you can start filling out the required methods:
388388
return sorting
389389
390390
When your spike sorter class is implemented, you have to add it to the list of available spike sorters in the
391-
`sorterlist.py`. Then you need to write a test in **tests/test_myspikesorter.py**. In order to be tested, you can
392-
install the required packages by changing the **pyproject.toml**. Note that MATLAB based tests cannot be run at the moment,
393-
but we recommend testing the implementation locally.
391+
`sorterlist.py <https://github.com/SpikeInterface/spikeinterface/blob/main/src/spikeinterface/sorters/sorterlist.py>`_ .
392+
Then you need to write a test in **tests/test_myspikesorter.py**. In order to be tested, you can
393+
install the required packages by changing the `pyproject.toml <https://github.com/SpikeInterface/spikeinterface/blob/main/pyproject.toml>`_.
394+
Note that MATLAB based tests cannot be run at the moment,but we recommend testing the implementation locally.
394395

395-
After this you need to add a block in **doc/sorters_info.rst** to describe your sorter.
396+
After this you need to add a block in `Install Sorters <https://github.com/SpikeInterface/spikeinterface/blob/main/doc/get_started/install_sorters.rst>`_
397+
to describe your sorter.
396398

397399
Finally, make a pull request so we can review the code and incorporate into the sorters module of SpikeInterface!

doc/get_started/quickstart.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ available parameters are dictionaries and can be accessed with:
287287
'detect_threshold': 5,
288288
'freq_max': 5000.0,
289289
'freq_min': 400.0,
290-
'max_threads_per_process': 1,
290+
'max_threads_per_worker': 1,
291291
'mp_context': None,
292292
'n_jobs': 20,
293293
'nested_params': None,

doc/how_to/benchmark_with_hybrid_recordings.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2531,9 +2531,8 @@ Although non of the sorters find all units perfectly, ``Kilosort2.5``,
25312531
``Kilosort4``, and ``SpyKING CIRCUS 2`` all find around 10-12 hybrid
25322532
units with accuracy greater than 80%. ``Kilosort4`` has a better overall
25332533
curve, being able to find almost all units with an accuracy above 50%.
2534-
``Kilosort2.5`` performs well when looking at precision (finding all
2535-
spikes in a hybrid unit), at the cost of lower recall (finding spikes
2536-
when it shouldn’t).
2534+
``Kilosort2.5`` performs well when looking at precision (not finding spikes
2535+
when it shouldn’t), but it has a lower recall (finding all spikes in the ground truth).
25372536

25382537
In this example, we showed how to:
25392538

examples/how_to/benchmark_with_hybrid_recordings.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,8 @@
276276
# From the performance plots, we can see that there is no clear "winner", but `Kilosort3` definitely performs worse than the other options.
277277
#
278278
# Although non of the sorters find all units perfectly, `Kilosort2.5`, `Kilosort4`, and `SpyKING CIRCUS 2` all find around 10-12 hybrid units with accuracy greater than 80%.
279-
# `Kilosort4` has a better overall curve, being able to find almost all units with an accuracy above 50%. `Kilosort2.5` performs well when looking at precision (finding all spikes in a hybrid unit), at the cost of lower recall (finding spikes when it shouldn't).
279+
# `Kilosort4` has a better overall curve, being able to find almost all units with an accuracy above 50%. `Kilosort2.5` performs well when looking at precision (not finding spikes
280+
# when it shouldn’t), but it has a lower recall (finding all spikes in the ground truth).
280281
#
281282
#
282283
# In this example, we showed how to:

examples/tutorials/curation/plot_1_automated_curation.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,8 @@ def calculate_moving_avg(label_df, confidence_label, window_size):
209209
# trained on real data.
210210
#
211211
# For example, the following classifiers are trained on Neuropixels data from 11 mice recorded in
212-
# V1,SC and ALM: https://huggingface.co/AnoushkaJain3/noise_neural_classifier/ and
213-
# https://huggingface.co/AnoushkaJain3/sua_mua_classifier/ . One will classify units into
212+
# V1,SC and ALM: https://huggingface.co/SpikeInterface/UnitRefine_noise_neural_classifier/ and
213+
# https://huggingface.co/SpikeInterface/UnitRefine_sua_mua_classifier/. One will classify units into
214214
# `noise` or `not-noise` and the other will classify the `not-noise` units into single
215215
# unit activity (sua) units and multi-unit activity (mua) units.
216216
#
@@ -221,8 +221,8 @@ def calculate_moving_avg(label_df, confidence_label, window_size):
221221

222222
# Apply the noise/not-noise model
223223
noise_neuron_labels = sc.auto_label_units(
224-
sorting_analyzer = sorting_analyzer,
225-
repo_id = "AnoushkaJain3/noise_neural_classifier",
224+
sorting_analyzer=sorting_analyzer,
225+
repo_id="SpikeInterface/UnitRefine_noise_neural_classifier",
226226
trust_model=True,
227227
)
228228

@@ -231,8 +231,8 @@ def calculate_moving_avg(label_df, confidence_label, window_size):
231231

232232
# Apply the sua/mua model
233233
sua_mua_labels = sc.auto_label_units(
234-
sorting_analyzer = analyzer_neural,
235-
repo_id = "AnoushkaJain3/sua_mua_classifier",
234+
sorting_analyzer=analyzer_neural,
235+
repo_id="SpikeInterface/UnitRefine_sua_mua_classifier",
236236
trust_model=True,
237237
)
238238

pyproject.toml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ authors = [
77
]
88
description = "Python toolkit for analysis, visualization, and comparison of spike sorting output"
99
readme = "README.md"
10-
requires-python = ">=3.9,<3.13" # Only numpy 2.1 supported on python 3.13 for windows. We need to wait for fix on neo
10+
requires-python = ">=3.9,<3.13"
1111
classifiers = [
1212
"Programming Language :: Python :: 3 :: Only",
1313
"License :: OSI Approved :: MIT License",
@@ -20,11 +20,11 @@ classifiers = [
2020

2121

2222
dependencies = [
23-
"numpy>=1.20, <2.0", # 1.20 np.ptp, 1.26 might be necessary for avoiding pickling errors when numpy >2.0
23+
"numpy>=1.20",
2424
"threadpoolctl>=3.0.0",
2525
"tqdm",
26-
"zarr>=2.16,<2.18",
27-
"neo>=0.13.0",
26+
"zarr>=2.18,<3",
27+
"neo>=0.14.0",
2828
"probeinterface>=0.2.23",
2929
"packaging",
3030
]
@@ -61,8 +61,8 @@ changelog = "https://spikeinterface.readthedocs.io/en/latest/whatisnew.html"
6161
extractors = [
6262
"MEArec>=1.8",
6363
"pynwb>=2.6.0",
64-
"hdmf-zarr>=0.5.0",
65-
"pyedflib>=0.1.30",
64+
"hdmf-zarr>=0.11.0",
65+
"pyedflib>=0.1.30,<0.1.39",
6666
"sonpy;python_version<'3.10'",
6767
"lxml", # lxml for neuroscope
6868
"scipy",
@@ -80,7 +80,7 @@ streaming_extractors = [
8080
"fsspec",
8181
"aiohttp",
8282
"requests",
83-
"hdmf-zarr>=0.5.0",
83+
"hdmf-zarr>=0.11.0",
8484
"remfile",
8585
"s3fs"
8686
]

readthedocs.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
version: 2
22

3+
sphinx:
4+
# Path to your Sphinx configuration file.
5+
configuration: doc/conf.py
6+
37
build:
48
os: ubuntu-22.04
59
tools:

src/spikeinterface/benchmark/benchmark_base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from spikeinterface.core import SortingAnalyzer
1313

14-
from spikeinterface import load_extractor, create_sorting_analyzer, load_sorting_analyzer
14+
from spikeinterface import load, create_sorting_analyzer, load_sorting_analyzer
1515
from spikeinterface.widgets import get_some_colors
1616

1717

@@ -150,13 +150,13 @@ def scan_folder(self):
150150
analyzer = load_sorting_analyzer(folder)
151151
self.analyzers[key] = analyzer
152152
# the sorting is in memory here we take the saved one because comparisons need to pickle it later
153-
sorting = load_extractor(analyzer.folder / "sorting")
153+
sorting = load(analyzer.folder / "sorting")
154154
self.datasets[key] = analyzer.recording, sorting
155155

156156
# for rec_file in (self.folder / "datasets" / "recordings").glob("*.pickle"):
157157
# key = rec_file.stem
158-
# rec = load_extractor(rec_file)
159-
# gt_sorting = load_extractor(self.folder / f"datasets" / "gt_sortings" / key)
158+
# rec = load(rec_file)
159+
# gt_sorting = load(self.folder / f"datasets" / "gt_sortings" / key)
160160
# self.datasets[key] = (rec, gt_sorting)
161161

162162
with open(self.folder / "cases.pickle", "rb") as f:
@@ -428,7 +428,7 @@ def load_folder(cls, folder):
428428
elif format == "sorting":
429429
from spikeinterface.core import load_extractor
430430

431-
result[k] = load_extractor(folder / k)
431+
result[k] = load(folder / k)
432432
elif format == "Motion":
433433
from spikeinterface.sortingcomponents.motion import Motion
434434

0 commit comments

Comments
 (0)