From 8e9051afa54b1272308fe089206b94ca7c33de9e Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Wed, 3 Dec 2025 14:50:54 +0100 Subject: [PATCH 1/5] prepare release v0.103.2 --- doc/releases/0.103.2.rst | 73 ++++++++++++++++++++++++++++++++++ doc/whatisnew.rst | 6 +++ pyproject.toml | 16 ++++---- src/spikeinterface/__init__.py | 4 +- 4 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 doc/releases/0.103.2.rst diff --git a/doc/releases/0.103.2.rst b/doc/releases/0.103.2.rst new file mode 100644 index 0000000000..b3681f4df4 --- /dev/null +++ b/doc/releases/0.103.2.rst @@ -0,0 +1,73 @@ +.. _release0.103.2: + +SpikeInterface 0.103.2 release notes +------------------------------------ + +December 3rd 2025 + +Minor release with bug fixes + +core: + +* Fix probable sharedmem (#4239) +* Fix probable shared mem no clean corretcly (#4234) +* Implementing sparsity for ComputeTemplates (#4212) +* Warn about non-mergeable units instead of raising an error (#4219) + +extractors: + +* Support for using event names as IDs in PL2 files (#4049) + +preprocessing: + +* Add channel_filter parameter for bad channel detection (#4228) + +sorters: + +* Warn about non-binary compatible recordings using KS4 (#4236) +* Deal with batch_downsampling in kilosort4.1.2 (#4206) + +postprocessing: + +* Speedup template_similarity (#4211) + +qualitymetrics: + + +curation: + +* Add `load_curation` function (#4220) +* Add similarity_method param in automerge and fix multi-segment cross-contamination (#4201) + +widgets: + +* Protect unit summary and unit locations plots against NaNs (#4128) + +sortingcomponents: + +* patch for sc2: propagate real ms_before/after to template extension of final analyzer (#4215) +* Speedup template_similarity (#4211) +* Improvement of TDC2, SC2 and ISOSPLIT (#4182) + +documentation: + +* Add additional resources section to Analyze Neuropixels Datasets tuto (#4232) +* Fix `apply_preprocessing_pipeline` name in docs (#4208) +* Tiny doc fixes (#4203) +* Add testing a PR section to docs (#4199) + +continuous integration: + +* Fix no disk space left ci (#4229) + +Contributors: + +* @MGAMZ +* @OookTheLibrarian +* @ShijiMi-Soup +* @alejoe91 +* @chrishalcrow +* @h-mayorquin +* @samuelgarcia +* @tayheau +* @yger diff --git a/doc/whatisnew.rst b/doc/whatisnew.rst index 2aec1d813e..ae45de8403 100644 --- a/doc/whatisnew.rst +++ b/doc/whatisnew.rst @@ -51,6 +51,12 @@ Release notes releases/0.9.1.rst +Version 0.103.2 +=============== + +* Minor release with bug fixes + + Version 0.103.1 =============== diff --git a/pyproject.toml b/pyproject.toml index 788b1aeaf4..11c6e64e6f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -127,8 +127,8 @@ test_core = [ # for github test : probeinterface and neo from master # for release we need pypi, so this need to be commented - "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", - "neo @ git+https://github.com/NeuralEnsemble/python-neo.git", + # "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", + # "neo @ git+https://github.com/NeuralEnsemble/python-neo.git", # for slurm jobs, "pytest-mock" @@ -139,8 +139,8 @@ test_extractors = [ "pooch>=1.8.2", "datalad>=1.0.2", # Commenting out for release - "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", - "neo @ git+https://github.com/NeuralEnsemble/python-neo.git", + # "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", + # "neo @ git+https://github.com/NeuralEnsemble/python-neo.git", ] test_preprocessing = [ @@ -185,8 +185,8 @@ test = [ # for github test : probeinterface and neo from master # for release we need pypi, so this need to be commented - "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", - "neo @ git+https://github.com/NeuralEnsemble/python-neo.git", + # "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", + # "neo @ git+https://github.com/NeuralEnsemble/python-neo.git", # for slurm jobs "pytest-mock", @@ -213,8 +213,8 @@ docs = [ "huggingface_hub", # For automated curation # for release we need pypi, so this needs to be commented - "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", # We always build from the latest version - "neo @ git+https://github.com/NeuralEnsemble/python-neo.git", # We always build from the latest version + # "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", # We always build from the latest version + # "neo @ git+https://github.com/NeuralEnsemble/python-neo.git", # We always build from the latest version ] dev = [ diff --git a/src/spikeinterface/__init__.py b/src/spikeinterface/__init__.py index a184e9f487..f7c43a845f 100644 --- a/src/spikeinterface/__init__.py +++ b/src/spikeinterface/__init__.py @@ -27,5 +27,5 @@ # This flag must be set to False for release # This avoids using versioning that contains ".dev0" (and this is a better choice) # This is mainly useful when using run_sorter in a container and spikeinterface install -DEV_MODE = True -# DEV_MODE = False +# DEV_MODE = True +DEV_MODE = False From b416a872304bca1c621c0837bbbfa73b98bbfc8c Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Wed, 3 Dec 2025 16:29:05 +0100 Subject: [PATCH 2/5] Fix docs --- doc/whatisnew.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/whatisnew.rst b/doc/whatisnew.rst index ae45de8403..2f6181b725 100644 --- a/doc/whatisnew.rst +++ b/doc/whatisnew.rst @@ -8,6 +8,7 @@ Release notes .. toctree:: :maxdepth: 1 + releases/0.103.2.rst releases/0.103.1.rst releases/0.103.0.rst releases/0.102.3.rst From 434a769a18905d543ddcf99c5fa7696ac2a4cc74 Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Fri, 18 Sep 2026 14:28:38 +0200 Subject: [PATCH 3/5] Add missing PR --- doc/releases/0.105.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/releases/0.105.0.rst b/doc/releases/0.105.0.rst index 361e6a4b70..82ce067dc8 100644 --- a/doc/releases/0.105.0.rst +++ b/doc/releases/0.105.0.rst @@ -221,6 +221,7 @@ preprocessing: sorters: +* Save recording_attributes before run_sorter() (#4795) * Only use nonempty main channel indices when making an analyzer from templates (#4763) * Fix encoding error in shellscript on Windows (#4720) * Add ``read_kilosort4_motion`` function (#4518) From 669e51b2a9fbb03160d11e5e5edfe7e4fb56066e Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Fri, 18 Sep 2026 15:39:41 +0200 Subject: [PATCH 4/5] Clean up release notes --- doc/releases/0.105.0.rst | 203 +++++++++++++++++++-------------------- doc/whatisnew.rst | 11 ++- 2 files changed, 108 insertions(+), 106 deletions(-) diff --git a/doc/releases/0.105.0.rst b/doc/releases/0.105.0.rst index 82ce067dc8..4054288a22 100644 --- a/doc/releases/0.105.0.rst +++ b/doc/releases/0.105.0.rst @@ -3,7 +3,7 @@ SpikeInterface 0.105.0 release notes ------------------------------------ -Sept 17th 2026 +Sept 18th 2026 Main changes: @@ -12,116 +12,109 @@ Main changes: * ``main_channel_indices`` and the ``main_channel_id`` sorting property replace ``peak_sign`` across postprocessing and metrics. The main channel is now set once on the analyzer, and sorters such as Kilosort and ``dartsort`` set it directly (#4624, #4672, #4733, #4725) * ``SortingAnalyzer`` gained a ``lazy`` mode, which keeps the spike vector and extension data as memmaps / Zarr arrays and defers loading until first access, and an independent ``read_only`` mode (#4623, #4709, #4713) (see: :doc:`/modules/core`) * Node pipelines can gather results straight to disk with ``GatherToZarr``, so pipeline node extension data no longer has to fit in memory (#4703) -* ``PreprocessingPipeline`` is now built on a subclassable ``BasePipeline`` and takes an ordered *list* of steps, so steps may repeat, and a step can consume an earlier step's output via ``"pipeline[]"`` or ``"pipeline[raw]"`` (#4755) (see: :doc:`/modules/preprocessing`) * Reworked probe handling around ``ProbeGroup``: ``set_probe`` and ``set_probegroup`` now act in place, while the new ``select_channels_with_probe`` and ``select_channels_with_probegroup`` return a new recording (#4465) * Added the ``detect_and_remove_artifacts`` preprocessor, with ``"envelope"`` and ``"saturation"`` detection, a separate ``recording_to_detect``, and ``"zeros"`` / ``"noise"`` / ``"apodization"`` silencing modes (#4539) * Added antialiased decimation (``decimate(..., antialias=True)``) and support for non-integer resampling rates (#4621) -* Overhauled ``Bombcell`` [Fabre]_ curation: all native thresholds are exposed, ``sliding_rp_violation`` is the default refractory-period metric, custom and external metrics are supported, and non-somatic labelling is simplified (#4494, #4493) -* Added ``read_zarr_array`` to read plain, externally generated Zarr arrays as recordings (#4760), and ``zarr_class_info`` provenance so that SpikeInterface Zarr roots are read unambiguously and can be extended by third-party packages (#4467) -* Modularized optional dependencies per module (``spikeinterface[postprocessing]``, ``[curation]``, ``[sortingcomponents]``, ...), with ``full`` as their union (#4541) * Added ``SortingAnalyzer.split_by()`` to split an aggregated analyzer into per-group analyzers (#4660), and ``read_kilosort4_motion`` to build a ``Motion`` object from a Kilosort4 output folder (#4518) * Significant speedups in multi-segment synchrony metrics (#4770), duplicated spike removal (#4614), amplitude scalings (#4764, #4759, #4786), PCA over all spikes (#4488), NWB sorting loading (#4662), spike vector handling (#4618, #4695, #4581), and import time (#4641, #4644, #4650, #4651) -* API and breaking changes: - - * Probe handling is reworked around ``ProbeGroup``, and the internal ``"contact_vector"`` property is gone (#4465). Previously saved objects and folders still load. - - * ``set_probe()`` and ``set_probegroup()`` always act in place and return ``None``. Use ``select_channels_with_probe()`` / ``select_channels_with_probegroup()`` to obtain a new recording (see: :doc:`/modules/core`) - * ``set_probe()`` accepts a single ``Probe`` only; pass a ``ProbeGroup`` to ``set_probegroup()`` - * ``reset_probe()`` --> ``remove_probe()`` - * ``has_3d_locations()`` --> ``is_probe_3d()``, and ``has_channel_location()`` is now equivalent to ``has_probe()`` - * ``get_channel_locations()`` raises when no probe is attached, instead of falling back to a bare ``"location"`` property - - * The main channel of each unit is fixed when the analyzer is created and stored as the ``main_channel_id`` sorting property, so ``peak_sign`` is removed from the API (#4624) - - * ``get_template_extremum_channel()`` --> ``SortingAnalyzer.get_main_channels()``, ``get_template_extremum_channel_peak_shift()`` --> ``get_template_peak_shift_on_main_channel()``, ``get_template_extremum_amplitude()`` --> ``get_template_amplitude_on_main_channel()``. The old names are deprecated shims - * ``peak_sign`` is no longer a valid parameter of ``compute_quality_metrics``, ``compute_template_metrics``, ``compute_spike_amplitudes``, ``compute_spike_locations`` and ``compute_unit_locations``. It is removed from the saved params of older analyzers on load - * ``compute_snrs(sorting_analyzer, unit_ids, peak_sign, peak_mode, ...)`` --> ``compute_snrs(sorting_analyzer, unit_ids, method)``, and the ``snr`` metric params ``peak_sign``/``peak_mode`` --> ``method`` - * ``get_template_amplitudes(..., mode=...)`` --> ``peak_mode=...`` - * ``compute_sparsity()`` and the ``ChannelSparsity.from_*`` constructors take ``peak_sign=None`` / ``amplitude_mode=None`` by default. With an analyzer they must stay ``None``; with a ``Templates`` object they are now mandatory. ``amplitude_mode`` also moved earlier in the positional order of ``compute_sparsity()`` - * ``estimate_sparsity()`` now defaults to ``peak_sign="both"`` instead of ``"neg"``, which changes results silently - * ``peak_sign`` is removed from ``remove_redundant_units()``, ``export_report()`` and ``plot_unit_depths()`` - * ``sorting_to_peaks(sorting, extremum_channel_inds, dtype)`` --> ``sorting_to_peaks(sorting, main_channel_indices, dtype)``, taking an array rather than a dict, and ``SpikeRetriever`` now requires the sorting to carry ``main_channel_id`` - * ``BaseSorting.to_spike_vector()`` gained ``main_channel_indices`` as its third positional parameter - - * The chunking and node pipeline machinery is generalized to any time series (#4472, #4533) - - * ``ChunkRecordingExecutor`` --> ``TimeSeriesChunkExecutor``, whose first argument is ``time_series`` rather than ``recording``, and whose ``run(recording_slices=...)`` --> ``run(slices=...)`` - * ``PipelineNode.get_trace_margin()`` --> ``get_margin()``, ``PipelineNode.compute(traces, ...)`` --> ``compute(chunk, ...)``, and ``PipelineNode`` takes ``time_series`` rather than ``recording`` - * ``run_node_pipeline(recording, ..., recording_slices=...)`` --> ``run_node_pipeline(time_series, ..., slices=...)``, and ``check_for_peak_source`` now defaults to ``False`` - * ``divide_recording_into_chunks`` --> ``divide_time_series_into_chunks``, ``write_binary_recording_file_handle`` --> ``write_binary_file_handle``, ``get_random_recording_slices`` --> ``get_random_sample_slices`` - * ``BaseRecordingSegment`` now derives from ``TimeSeriesSegment``, whose time attributes are private (#4701): use ``get_times_kwargs()``, ``get_start_time()``, ``set_times()`` and ``shift_times()`` instead of ``segment.t_start``, ``segment.time_vector`` and ``segment.sampling_frequency`` - * ``SingleChannelToyDenoiser`` --> ``SingleChannelDenoiser`` (#4673) - - * Saving and serialization are unified on the concrete classes (#4671, #4661, #4664) - - * ``BaseExtractor.save()`` is abstract, and ``BaseExtractor._save()`` is removed, so third-party extractors overriding ``_save`` no longer take part in ``save()``. Use ``Recording.save()``, ``Sorting.save()`` and ``Snippets.save()`` - * ``recording.save(format="binary"|"zarr")`` requires ``folder``, and ``format="nwb"`` is removed - * ``folder_metadata`` is removed from ``to_dict()``, ``dump()``, ``dump_to_json()`` and ``dump_to_pickle()``, and ``load_metadata_from_folder()`` / ``save_metadata_to_folder()`` are removed. ``to_dict()`` also gained ``include_extra_metadata`` in its third positional slot - * ``check_if_memory_serializable()``, ``check_if_json_serializable()`` and ``check_if_pickle_serializable()`` --> ``check_serializability(type)`` - * ``BaseExtractor.load_from_folder()`` is removed; use ``si.load()`` - * ``ZarrRecordingExtractor.write_recording(recording, zarr_path=...)`` --> ``folder_path=...``, and ``add_traces_to_zarr()`` is removed - * ``_get_t_starts()`` --> ``get_segment_t_starts()`` - * ``si.load()`` forwards unknown keyword arguments instead of dropping them, so a bad argument now raises (#4709) - - * ``PreprocessingPipeline`` takes a *list* of ``{"name": ..., "params": ...}`` steps instead of a dictionary (#4755) (see: :doc:`/modules/preprocessing`) - - * ``PreprocessingPipeline.preprocessor_dict`` --> ``.preprocessor_list`` - * ``get_preprocessing_dict_from_analyzer`` / ``get_preprocessing_dict_from_file`` --> ``get_preprocessing_list_from_analyzer`` / ``get_preprocessing_list_from_file`` - * ``apply_preprocessing_pipeline(recording, pipeline_or_dict, ...)`` --> ``apply_preprocessing_pipeline(recording_or_dict, pipeline, ...)``. Passing a dictionary still works, but is deprecated - - * Other signature and naming changes - - * ``parent_recording`` --> ``recording`` in ``ChannelSliceRecording``, ``FrameSliceRecording``, ``depth_order``, ``detect_and_remove_bad_channels`` and ``average_across_direction`` (#4779) - * ``AnalyzerExtension._select_extension_data()`` --> ``_select_units_extension_data()``, with a new ``_select_channels_extension_data()``. This breaks custom ``AnalyzerExtension`` subclasses (#4648) - * ``create_sorting_analyzer()`` gained several parameters between ``folder`` and ``sparse``, so ``sparse`` and ``sparsity`` must now be passed by keyword (#4624, #4623) - * ``NoiseGeneratorRecording`` and ``noise_generator_recording`` moved from ``spikeinterface.core`` to ``spikeinterface.generation`` (#4520). The lightweight ``MockRecording`` replaces the old core class for testing - * ``SortingAnalyzer.select_channels()`` is private (#4712) - * ``resample()``: ``margin_ms`` now defaults to ``None`` rather than ``100.0``, and ``skip_checks`` and ``check_nyquist()`` are removed (#4621, #4499) - * ``read_kilosort_as_analyzer()`` gained ``recording`` as its second positional parameter (#4529), and ``model_based_label_units()`` gained ``unit_ids`` as its second positional parameter (#4716) - * ``run_sorter`` raises an error when channel locations are not unique, suggesting ``run_sorter_by_property`` instead - * ``lazy=True`` no longer makes a ``SortingAnalyzer`` immutable; use ``read_only=True`` for that (#4623, #4713) - * Python packaging: ``numpy>=2.0`` is required on all supported Python versions, the minimum ``neo`` and ``probeinterface`` versions are raised to ``0.14.5`` and ``0.4.0`` (#4593), the ``test``, ``test_core``, ``test_extractors`` and ``test_preprocessing`` extras are replaced by PEP 735 dependency groups, ``sonpy`` is dropped, and the ``pandas<3`` (#4691) and ``scikit-learn<1.8`` (#4780) pins are relaxed - - * Changed results and defaults - - * ``sliding_rp_violation`` values change: the metric now reuses ``compute_correlograms`` and derives refractory-period bins from the actual correlogram bins (#4324), the expected-violations formula is corrected to the [Llobet]_ formulation, which previously overestimated it, and the tested contamination range now includes 35% (#4682) - * Multi-segment ``synchrony_metrics`` were incorrectly grouping equal sample indices across segments, and are now computed per segment (#4770) - * ``estimate_sparsity()`` defaults to ``peak_sign="both"`` (#4624) - * ``amplitude_cutoff`` now prefers ``amplitude_scalings`` over ``spike_amplitudes`` (#4513) - * ``num_depth_bins`` for MEDiCINe motion estimation uses MEDiCINe's own recommended default (#4686) - * Preprocessed traces are rounded, rather than truncated, before being cast to integer dtypes (#4653) - * Amplitudes are scaled to uV using channel offsets in addition to gains (#4765) - * ``get_metrics_extension_data()`` drops duplicated columns when two extensions provide a metric of the same name (#4609) - * Template metrics no longer raise on 3D channel locations; they warn and use the first two dimensions (#4572) - * ``decimate`` emits a ``FutureWarning`` when ``antialias`` is not set explicitly: the default will become ``True`` in a future release (#4621) - - * Removal of previously deprecated features - - * ``curation.auto_label_units()`` --> ``model_based_label_units()`` (#4716) - * the ``load_sync_channel`` argument of ``OpenEphysBinaryRecordingExtractor`` --> ``stream_name`` / ``stream_id`` (#4466) - * the ``num_chan`` argument of ``BinaryRecordingExtractor`` --> ``num_channels`` (#4666) - - * New deprecations, which will be removed in 0.106.0, and which now raise ``FutureWarning`` rather than ``DeprecationWarning`` so that they are visible by default (#4667, #4676): - - * ``BaseSnippets`` - * the ``in_place`` argument of ``set_probe``, as well as its return value - * ``set_channel_locations()`` and ``clear_channel_locations()`` - * ``get_template_extremum_channel()`` --> ``analyzer.get_main_channels()`` - * ``get_template_extremum_channel_peak_shift()`` --> ``get_template_peak_shift_on_main_channel()`` - * ``get_template_extremum_amplitude()`` --> ``get_template_amplitude_on_main_channel()`` - * ``save_to_memory()``, ``save_to_folder()`` and ``save_to_zarr()`` --> ``save(format=...)`` - * the ``"npz_folder"`` save format and ``NpzFolderSorting.write_sorting()`` --> ``"numpy_folder"`` (reading ``npz_folder`` is still supported) - * the ``extremum_channel_inds`` argument of ``SpikeRetriever`` --> ``main_channel_ids`` from the sorting - * passing sparsity and job arguments as loose keyword arguments to ``create_sorting_analyzer`` --> ``sparsity_kwargs`` and ``job_kwargs`` dictionaries - * the ``input_data`` argument of ``model_based_label_units`` --> ``metrics`` - * ``split_non_somatic_good_mua`` and ``label_non_somatic`` in Bombcell curation --> ``split_non_somatic`` - * computing ``amplitude_cutoff`` without the ``amplitude_scalings`` extension (#4513) - - * Passing a dictionary to ``apply_preprocessing_pipeline`` is deprecated and will be removed in 0.107.0 (#4755) - - * Items deprecated during the 0.104 cycle, such as ``return_scaled``, the ``spikeinterface.qualitymetrics`` and ``spikeinterface.postprocessing.template_metrics`` modules, ``CurationModel``, ``get_potential_auto_merge()``, ``get_default_qm_params``, ``get_default_tm_params``, the ``sorting`` and ``sorting_analyzer`` arguments of several widgets, and the ``sortingview`` backend, are still deprecated and still warn. They have not been removed yet. - +API and breaking changes: + +Despite this long list of breaking changes, we have worked hard to try and preserve backwards compatibility for any objects saved using older versions of SpikeInterface. If you cannot load an object saved with an older version of SpikeInterface, please raise an issue. + + * Probe handling is reworked around ``ProbeGroup``, and the internal ``"contact_vector"`` property is gone (#4465). Previously saved objects and folders still load. + + * ``set_probe()`` and ``set_probegroup()`` always act in place and return ``None``. Use ``select_channels_with_probe()`` / ``select_channels_with_probegroup()`` to obtain a new recording (see: :doc:`/modules/core`) + * ``set_probe()`` accepts a single ``Probe`` only; pass a ``ProbeGroup`` to ``set_probegroup()`` + * ``reset_probe()`` --> ``remove_probe()`` + * ``has_3d_locations()`` --> ``is_probe_3d()``, and ``has_channel_location()`` is now equivalent to ``has_probe()`` + * ``get_channel_locations()`` raises when no probe is attached, instead of falling back to a bare ``"location"`` property + + * The main channel of each unit is fixed when the analyzer is created and stored as the ``main_channel_id`` sorting property. ``peak_sign`` is also decided when the analyzer is created, and so is removed from the API (#4624) + + * ``get_template_extremum_channel()`` --> ``SortingAnalyzer.get_main_channels()``, ``get_template_extremum_channel_peak_shift()`` --> ``get_template_peak_shift_on_main_channel()``, ``get_template_extremum_amplitude()`` --> ``get_template_amplitude_on_main_channel()``. The old names are deprecated shims + * ``peak_sign`` is no longer a valid parameter of ``compute_quality_metrics``, ``compute_template_metrics``, ``compute_spike_amplitudes``, ``compute_spike_locations`` and ``compute_unit_locations``. It is removed from the saved params of older analyzers on load + * ``compute_snrs(sorting_analyzer, unit_ids, peak_sign, peak_mode, ...)`` --> ``compute_snrs(sorting_analyzer, unit_ids, method)``, and the ``snr`` metric params ``peak_sign``/``peak_mode`` --> ``method`` + * ``get_template_amplitudes(..., mode=...)`` --> ``peak_mode=...`` + * ``compute_sparsity()`` and the ``ChannelSparsity.from_*`` constructors take ``peak_sign=None`` / ``amplitude_mode=None`` by default. With an analyzer they must stay ``None``; with a ``Templates`` object they are now mandatory. ``amplitude_mode`` also moved earlier in the positional order of ``compute_sparsity()`` + * ``estimate_sparsity()`` now defaults to ``peak_sign="both"`` instead of ``"neg"``, which changes results silently + * ``peak_sign`` is removed from ``remove_redundant_units()``, ``export_report()`` and ``plot_unit_depths()`` + * ``sorting_to_peaks(sorting, extremum_channel_inds, dtype)`` --> ``sorting_to_peaks(sorting, main_channel_indices, dtype)``, taking an array rather than a dict, and ``SpikeRetriever`` now requires the sorting to carry ``main_channel_id`` + * ``BaseSorting.to_spike_vector()`` gained ``main_channel_indices`` as its third positional parameter + + * The chunking and node pipeline machinery is generalized to any time series (#4472, #4533) + + * ``ChunkRecordingExecutor`` --> ``TimeSeriesChunkExecutor``, whose first argument is ``time_series`` rather than ``recording``, and whose ``run(recording_slices=...)`` --> ``run(slices=...)`` + * ``PipelineNode.get_trace_margin()`` --> ``get_margin()``, ``PipelineNode.compute(traces, ...)`` --> ``compute(chunk, ...)``, and ``PipelineNode`` takes ``time_series`` rather than ``recording`` + * ``run_node_pipeline(recording, ..., recording_slices=...)`` --> ``run_node_pipeline(time_series, ..., slices=...)``, and ``check_for_peak_source`` now defaults to ``False`` + * ``divide_recording_into_chunks`` --> ``divide_time_series_into_chunks``, ``write_binary_recording_file_handle`` --> ``write_binary_file_handle``, ``get_random_recording_slices`` --> ``get_random_sample_slices`` + * ``BaseRecordingSegment`` now derives from ``TimeSeriesSegment``, whose time attributes are private (#4701): use ``get_times_kwargs()``, ``get_start_time()``, ``set_times()`` and ``shift_times()`` instead of ``segment.t_start``, ``segment.time_vector`` and ``segment.sampling_frequency`` + + * Saving and serialization are unified on the concrete classes (#4671, #4661, #4664) + + * ``BaseExtractor.save()`` is abstract, and ``BaseExtractor._save()`` is removed, so third-party extractors overriding ``_save`` no longer take part in ``save()``. Use ``Recording.save()``, ``Sorting.save()`` and ``Snippets.save()`` + * ``folder_metadata`` is removed from ``to_dict()``, ``dump()``, ``dump_to_json()`` and ``dump_to_pickle()``, and ``load_metadata_from_folder()`` / ``save_metadata_to_folder()`` are removed. ``to_dict()`` also gained ``include_extra_metadata`` in its third positional slot + * ``check_if_memory_serializable()``, ``check_if_json_serializable()`` and ``check_if_pickle_serializable()`` --> ``check_serializability(type)`` + * ``BaseExtractor.load_from_folder()`` is removed; use ``si.load()`` + * ``ZarrRecordingExtractor.write_recording(recording, zarr_path=...)`` --> ``folder_path=...``, and ``add_traces_to_zarr()`` is removed + * ``_get_t_starts()`` --> ``get_segment_t_starts()`` + * ``si.load()`` forwards unknown keyword arguments instead of dropping them, so a bad argument now raises (#4709) + + * ``PreprocessingPipeline`` takes a *list* of ``{"name": ..., "params": ...}`` steps instead of a dictionary (#4755) (see: :doc:`/modules/preprocessing`) + + * ``PreprocessingPipeline.preprocessor_dict`` --> ``.preprocessor_list`` + * ``get_preprocessing_dict_from_analyzer`` / ``get_preprocessing_dict_from_file`` --> ``get_preprocessing_list_from_analyzer`` / ``get_preprocessing_list_from_file`` + * ``apply_preprocessing_pipeline(recording, pipeline_or_dict, ...)`` --> ``apply_preprocessing_pipeline(recording_or_dict, pipeline, ...)``. Passing a dictionary still works, but is deprecated + + * Other signature and naming changes + + * ``parent_recording`` --> ``recording`` in ``ChannelSliceRecording``, ``FrameSliceRecording``, ``depth_order``, ``detect_and_remove_bad_channels`` and ``average_across_direction`` (#4779) + * ``AnalyzerExtension._select_extension_data()`` --> ``_select_units_extension_data()``, with a new ``_select_channels_extension_data()``. This breaks custom ``AnalyzerExtension`` subclasses (#4648) + * ``create_sorting_analyzer()`` gained several parameters between ``folder`` and ``sparse``, so ``sparse`` and ``sparsity`` must now be passed by keyword (#4624, #4623) + * ``NoiseGeneratorRecording`` and ``noise_generator_recording`` moved from ``spikeinterface.core`` to ``spikeinterface.generation`` (#4520). The lightweight ``MockRecording`` replaces the old core class for testing + * ``resample()``: ``margin_ms`` now defaults to ``None`` rather than ``100.0``, and ``skip_checks`` and ``check_nyquist()`` are removed (#4621, #4499) + * ``read_kilosort_as_analyzer()`` gained ``recording`` as its second positional parameter (#4529), and ``model_based_label_units()`` gained ``unit_ids`` as its second positional parameter (#4716) + * ``run_sorter`` raises an error when channel locations are not unique, suggesting ``run_sorter_by_property`` instead + * Python packaging: ``numpy>=2.0`` is required on all supported Python versions, the minimum ``neo`` and ``probeinterface`` versions are raised to ``0.14.5`` and ``0.4.0`` (#4593), the ``test``, ``test_core``, ``test_extractors`` and ``test_preprocessing`` extras are replaced by PEP 735 dependency groups, ``sonpy`` is dropped, and the ``pandas<3`` (#4691) and ``scikit-learn<1.8`` (#4780) pins are relaxed + + * Changed results and defaults + + * ``sliding_rp_violation`` values change: the metric now reuses ``compute_correlograms`` and derives refractory-period bins from the actual correlogram bins (#4324), the expected-violations formula is corrected to the [Llobet]_ formulation, which previously overestimated it, and the tested contamination range now includes 35% (#4682) + * Multi-segment ``synchrony_metrics`` were incorrectly grouping equal sample indices across segments, and are now computed per segment (#4770) + * ``estimate_sparsity()`` defaults to ``peak_sign="both"`` (#4624) + * ``amplitude_cutoff`` now prefers ``amplitude_scalings`` over ``spike_amplitudes`` (#4513) + * ``num_depth_bins`` for MEDiCINe motion estimation uses MEDiCINe's own recommended default (#4686) + * Preprocessed traces are rounded, rather than truncated, before being cast to integer dtypes (#4653) + * Amplitudes are scaled to uV using channel offsets in addition to gains (#4765) + * ``get_metrics_extension_data()`` drops duplicated columns when two extensions provide a metric of the same name (#4609) + * Template metrics no longer raise on 3D channel locations; they warn and use the first two dimensions (#4572) + * ``decimate`` emits a ``FutureWarning`` when ``antialias`` is not set explicitly: the default will become ``True`` in a future release (#4621) + + * Removal of previously deprecated features + + * ``curation.auto_label_units()`` --> ``model_based_label_units()`` (#4716) + * the ``load_sync_channel`` argument of ``OpenEphysBinaryRecordingExtractor`` --> ``stream_name`` / ``stream_id`` (#4466) + * the ``num_chan`` argument of ``BinaryRecordingExtractor`` --> ``num_channels`` (#4666) + + * New deprecations, which will be removed in 0.106.0, and which now raise ``FutureWarning`` rather than ``DeprecationWarning`` so that they are visible by default (#4667, #4676): + + * ``BaseSnippets`` + * the ``in_place`` argument of ``set_probe``, as well as its return value + * ``set_channel_locations()`` and ``clear_channel_locations()`` + * ``get_template_extremum_channel()`` --> ``analyzer.get_main_channels()`` + * ``get_template_extremum_channel_peak_shift()`` --> ``get_template_peak_shift_on_main_channel()`` + * ``get_template_extremum_amplitude()`` --> ``get_template_amplitude_on_main_channel()`` + * ``save_to_memory()``, ``save_to_folder()`` and ``save_to_zarr()`` --> ``save(format=...)`` + * the ``"npz_folder"`` save format and ``NpzFolderSorting.write_sorting()`` --> ``"numpy_folder"`` (reading ``npz_folder`` is still supported) + * the ``extremum_channel_inds`` argument of ``SpikeRetriever`` --> ``main_channel_ids`` from the sorting + * passing sparsity and job arguments as loose keyword arguments to ``create_sorting_analyzer`` --> ``sparsity_kwargs`` and ``job_kwargs`` dictionaries + * the ``input_data`` argument of ``model_based_label_units`` --> ``metrics`` + * ``split_non_somatic_good_mua`` and ``label_non_somatic`` in Bombcell curation --> ``split_non_somatic`` + * computing ``amplitude_cutoff`` without the ``amplitude_scalings`` extension (#4513) + + * Passing a dictionary to ``apply_preprocessing_pipeline`` is deprecated and will be removed in 0.107.0 (#4755) + + * Items deprecated during the 0.104 cycle, such as ``return_scaled``, the ``spikeinterface.qualitymetrics`` and ``spikeinterface.postprocessing.template_metrics`` modules, ``CurationModel``, ``get_potential_auto_merge()``, ``get_default_qm_params``, ``get_default_tm_params``, the ``sorting`` and ``sorting_analyzer`` arguments of several widgets, are removed. core: diff --git a/doc/whatisnew.rst b/doc/whatisnew.rst index 2913038088..9d79a612c4 100644 --- a/doc/whatisnew.rst +++ b/doc/whatisnew.rst @@ -66,7 +66,16 @@ Release notes Version 0.105.0 =============== -... +* Added ``dartsort`` [Boussard2023]_ as an external sorter, run with ``run_sorter("dartsort")`` (#2125) +* Generalized the chunking machinery: the recording-specific chunking code is now a reusable ``TimeSeries`` base class, plus ``TimeSeriesChunkExecutor``, so that any object chunkable along the time axis reuses the same parallelization and time handling (#4472, #4533) +* ``main_channel_indices`` and the ``main_channel_id`` sorting property replace ``peak_sign`` across postprocessing and metrics. The main channel is now set once on the analyzer, and sorters such as Kilosort and ``dartsort`` set it directly (#4624, #4672, #4733, #4725) +* ``SortingAnalyzer`` gained a ``lazy`` mode, which keeps the spike vector and extension data as memmaps / Zarr arrays and defers loading until first access, and an independent ``read_only`` mode (#4623, #4709, #4713) (see: :doc:`/modules/core`) +* Node pipelines can gather results straight to disk with ``GatherToZarr``, so pipeline node extension data no longer has to fit in memory (#4703) +* Reworked probe handling around ``ProbeGroup``: ``set_probe`` and ``set_probegroup`` now act in place, while the new ``select_channels_with_probe`` and ``select_channels_with_probegroup`` return a new recording (#4465) +* Added the ``detect_and_remove_artifacts`` preprocessor, with ``"envelope"`` and ``"saturation"`` detection, a separate ``recording_to_detect``, and ``"zeros"`` / ``"noise"`` / ``"apodization"`` silencing modes (#4539) +* Added antialiased decimation (``decimate(..., antialias=True)``) and support for non-integer resampling rates (#4621) +* Added ``SortingAnalyzer.split_by()`` to split an aggregated analyzer into per-group analyzers (#4660), and ``read_kilosort4_motion`` to build a ``Motion`` object from a Kilosort4 output folder (#4518) +* Significant speedups in multi-segment synchrony metrics (#4770), duplicated spike removal (#4614), amplitude scalings (#4764, #4759, #4786), PCA over all spikes (#4488), NWB sorting loading (#4662), spike vector handling (#4618, #4695, #4581), and import time (#4641, #4644, #4650, #4651) Versions 0.104.1/9 ================== From be3937b58569c9a68892068b78c15a6b3a1ae407 Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Fri, 18 Sep 2026 16:57:19 +0200 Subject: [PATCH 5/5] Apply suggestion from @alejoe91 --- doc/releases/0.105.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/releases/0.105.0.rst b/doc/releases/0.105.0.rst index 4054288a22..ac9776336b 100644 --- a/doc/releases/0.105.0.rst +++ b/doc/releases/0.105.0.rst @@ -3,7 +3,7 @@ SpikeInterface 0.105.0 release notes ------------------------------------ -Sept 18th 2026 +Sept 21st 2026 Main changes: