From 9a483f05d02efeb1ea0df7565271a1ebefec2d06 Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Thu, 17 Sep 2026 17:01:30 +0200 Subject: [PATCH 1/7] remove 0.105.0 deprecations --- doc/api.rst | 1 - src/spikeinterface/core/baserecording.py | 14 -- src/spikeinterface/core/basesnippets.py | 28 --- src/spikeinterface/core/basesorting.py | 2 +- .../core/channelsaggregationrecording.py | 18 +- src/spikeinterface/core/recording_tools.py | 38 +--- src/spikeinterface/core/sortinganalyzer.py | 26 +-- src/spikeinterface/core/testing.py | 12 -- src/spikeinterface/core/waveform_tools.py | 52 +---- src/spikeinterface/curation/__init__.py | 1 - src/spikeinterface/curation/auto_merge.py | 193 ------------------ src/spikeinterface/curation/curation_model.py | 9 - src/spikeinterface/extractors/__init__.py | 3 +- .../extractors/neoextractors/openephys.py | 16 +- .../metrics/quality/quality_metrics.py | 10 - .../metrics/template/template_metrics.py | 32 --- .../postprocessing/template_metrics.py | 26 --- src/spikeinterface/qualitymetrics/__init__.py | 10 - .../sortingcomponents/matching/main.py | 12 +- .../sortingcomponents/peak_detection/main.py | 22 +- .../peak_localization/main.py | 17 +- .../widgets/isi_distribution.py | 8 - .../widgets/potential_merges.py | 2 +- src/spikeinterface/widgets/rasters.py | 12 -- .../widgets/spikes_on_traces.py | 11 - src/spikeinterface/widgets/traces.py | 11 - src/spikeinterface/widgets/unit_presence.py | 8 - src/spikeinterface/widgets/utils_figpack.py | 2 +- 28 files changed, 28 insertions(+), 568 deletions(-) delete mode 100644 src/spikeinterface/postprocessing/template_metrics.py delete mode 100644 src/spikeinterface/qualitymetrics/__init__.py diff --git a/doc/api.rst b/doc/api.rst index 77a44d5294..103619a8eb 100755 --- a/doc/api.rst +++ b/doc/api.rst @@ -439,7 +439,6 @@ Deprecated :noindex: .. autofunction:: apply_sortingview_curation - .. autofunction:: get_potential_auto_merge .. autoclass:: CurationSorting .. autoclass:: MergeUnitsSorting .. autoclass:: SplitUnitSorting diff --git a/src/spikeinterface/core/baserecording.py b/src/spikeinterface/core/baserecording.py index 3ddefb53b8..2358df456b 100644 --- a/src/spikeinterface/core/baserecording.py +++ b/src/spikeinterface/core/baserecording.py @@ -236,7 +236,6 @@ def get_traces( end_frame: int | None = None, channel_ids: list | np.ndarray | tuple | None = None, order: Literal["C", "F"] | None = None, - return_scaled: bool | None = None, return_in_uV: bool = False, ) -> np.ndarray: """Returns traces from recording. @@ -253,10 +252,6 @@ def get_traces( The channel ids. If None, all channels are used, default: None order : "C" | "F" | None, default: None The order of the traces ("C" | "F"). If None, traces are returned as they are - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. - If True and the recording has scaling (gain_to_uV and offset_to_uV properties), - traces are scaled to uV return_in_uV : bool, default: False If True and the recording has scaling (gain_to_uV and offset_to_uV properties), traces are scaled to uV @@ -282,15 +277,6 @@ def get_traces( assert order in ["C", "F"] traces = np.asanyarray(traces, order=order) - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warnings.warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - stacklevel=2, - ) - return_in_uV = return_scaled - if return_in_uV: if not self.has_scaleable_traces(): if self._dtype.kind == "f": diff --git a/src/spikeinterface/core/basesnippets.py b/src/spikeinterface/core/basesnippets.py index 5b38c47791..7678f0323b 100644 --- a/src/spikeinterface/core/basesnippets.py +++ b/src/spikeinterface/core/basesnippets.py @@ -93,7 +93,6 @@ def get_snippets( indices=None, segment_index: int | None = None, channel_ids: list | None = None, - return_scaled: bool | None = None, return_in_uV: bool = False, ): """ @@ -107,10 +106,6 @@ def get_snippets( The segment index to get snippets from. If snippets is multi-segment, it is required. channel_ids : list | None, default: None The channel ids. If None, all channels are used. - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. - If True and the snippets has scaling (gain_to_uV and offset_to_uV properties), - snippets are scaled to uV return_in_uV : bool, default: False If True and the snippets has scaling (gain_to_uV and offset_to_uV properties), snippets are scaled to uV @@ -125,15 +120,6 @@ def get_snippets( channel_indices = self.ids_to_indices(channel_ids, prefer_slice=True) wfs = spts.get_snippets(indices, channel_indices=channel_indices) - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - stacklevel=2, - ) - return_in_uV = return_scaled - if return_in_uV: if not self.has_scaleable_traces(): raise ValueError( @@ -153,7 +139,6 @@ def get_snippets_from_frames( start_frame: int | None = None, end_frame: int | None = None, channel_ids: list | None = None, - return_scaled: bool | None = None, return_in_uV: bool = False, ): """ @@ -169,10 +154,6 @@ def get_snippets_from_frames( The end frame. If None, the number of samples in the segment is used. channel_ids : list | None, default: None The channel ids. If None, all channels are used. - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. - If True and the snippets has scaling (gain_to_uV and offset_to_uV properties), - snippets are scaled to uV return_in_uV : bool, default: False If True and the snippets has scaling (gain_to_uV and offset_to_uV properties), snippets are scaled to uV @@ -186,15 +167,6 @@ def get_snippets_from_frames( spts = self._snippets_segments[segment_index] indices = spts.frames_to_indices(start_frame, end_frame) - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - stacklevel=2, - ) - return_in_uV = return_scaled - return self.get_snippets(indices, channel_ids=channel_ids, return_in_uV=return_in_uV) def select_channels(self, channel_ids: list | np.ndarray | tuple) -> "BaseSnippets": diff --git a/src/spikeinterface/core/basesorting.py b/src/spikeinterface/core/basesorting.py index 79e07d8cb4..e3bbf68424 100644 --- a/src/spikeinterface/core/basesorting.py +++ b/src/spikeinterface/core/basesorting.py @@ -1024,7 +1024,7 @@ def to_spike_vector( warnings.warn( "Sorting.to_spike_vector() with extremum_channel_inds is deprecated. " "Use main_channel_indices instead" - "This will be removed in 0.016.0" + "This will be removed in 0.106.0" ) main_channel_indices = np.array([extremum_channel_inds[unit_id] for unit_id in self.unit_ids]) diff --git a/src/spikeinterface/core/channelsaggregationrecording.py b/src/spikeinterface/core/channelsaggregationrecording.py index bd60602754..2217eec0c0 100644 --- a/src/spikeinterface/core/channelsaggregationrecording.py +++ b/src/spikeinterface/core/channelsaggregationrecording.py @@ -15,18 +15,16 @@ class ChannelsAggregationRecording(BaseRecording): Do not use this class directly but use `si.aggregate_channels(...)` - """ - - def __init__(self, recording_list_or_dict=None, renamed_channel_ids=None, recording_list=None): + Parameters + ---------- + recording_list_or_dict : list or dict + The list or dictionary of recordings to aggregate. + renamed_channel_ids : list, optional + The new channel ids for the aggregated recording. If None, default unique consecutive ids are used. - if recording_list is not None: - warnings.warn( - "`recording_list` is deprecated and will be removed in 0.105.0. Please use `recording_list_or_dict` instead.", - category=FutureWarning, - stacklevel=2, - ) - recording_list_or_dict = recording_list + """ + def __init__(self, recording_list_or_dict=None, renamed_channel_ids=None): if isinstance(recording_list_or_dict, dict): recording_list = list(recording_list_or_dict.values()) recording_ids = list(recording_list_or_dict.keys()) diff --git a/src/spikeinterface/core/recording_tools.py b/src/spikeinterface/core/recording_tools.py index b20b543538..09d0ce0deb 100644 --- a/src/spikeinterface/core/recording_tools.py +++ b/src/spikeinterface/core/recording_tools.py @@ -264,7 +264,6 @@ def write_to_h5_dataset_format( chunk_size=None, chunk_memory="500M", verbose=False, - return_scaled=None, return_in_uV=False, ): """ @@ -297,8 +296,6 @@ def write_to_h5_dataset_format( Chunk size in bytes must end with "k", "M" or "G" verbose : bool, default: False If True, output is verbose (when chunks are used) - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. return_in_uV : bool, default: False If True and the recording has scaling (gain_to_uV and offset_to_uV properties), traces are dumped to uV @@ -340,14 +337,6 @@ def write_to_h5_dataset_format( chunk_size = ensure_chunk_size(recording, chunk_size=chunk_size, chunk_memory=chunk_memory, n_jobs=1) if chunk_size is None: - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warnings.warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - ) - return_in_uV = return_scaled - traces = recording.get_traces(return_in_uV=return_in_uV) if dtype is not None: traces = traces.astype(dtype_file, copy=False) @@ -392,9 +381,7 @@ def write_to_h5_dataset_format( return save_path -def get_random_data_chunks( - recording, return_scaled=None, return_in_uV=False, concatenated=True, **random_slices_kwargs -): +def get_random_data_chunks(recording, return_in_uV=False, concatenated=True, **random_slices_kwargs): """ Extract random chunks across segments. @@ -408,8 +395,6 @@ def get_random_data_chunks( ---------- recording : BaseRecording The recording to get random chunks from - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. return_in_uV : bool, default: False If True and the recording has scaling (gain_to_uV and offset_to_uV properties), traces are scaled to uV @@ -426,15 +411,6 @@ def get_random_data_chunks( chunk_list : np.ndarray | list of np.array Array of concatenate chunks per segment """ - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warnings.warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - stacklevel=2, - ) - return_in_uV = return_scaled - return get_chunks( recording, concatenated=concatenated, @@ -525,7 +501,6 @@ def _noise_level_chunk_init(recording, return_in_uV, method): def get_noise_levels( recording: "BaseRecording", - return_scaled: bool | None = None, return_in_uV: bool = True, method: Literal["mad", "std", "rms"] = "mad", force_recompute: bool = False, @@ -548,8 +523,6 @@ def get_noise_levels( recording : BaseRecording The recording extractor to get noise levels - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. return_in_uV : bool, default: True If True, returned noise levels are scaled to uV method : "mad" | "std" | "rms", default: "mad" @@ -567,15 +540,6 @@ def get_noise_levels( noise_levels : array Noise levels for each channel """ - - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warnings.warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - ) - return_in_uV = return_scaled - if return_in_uV: key = f"noise_level_{method}_scaled" else: diff --git a/src/spikeinterface/core/sortinganalyzer.py b/src/spikeinterface/core/sortinganalyzer.py index f682cb5de3..18583b0de3 100644 --- a/src/spikeinterface/core/sortinganalyzer.py +++ b/src/spikeinterface/core/sortinganalyzer.py @@ -61,7 +61,6 @@ def create_sorting_analyzer( sparse: bool = True, sparsity: ChannelSparsity | None = None, set_sparsity_by_dict_key: bool = False, - return_scaled: bool | None = None, return_in_uV: bool = True, overwrite: bool = False, backend_options: dict[str, Any] | None = None, @@ -118,14 +117,9 @@ def create_sorting_analyzer( set_sparsity_by_dict_key : bool, default: False If True and passing recording and sorting dicts, will set the sparsity based on the dict keys, and other `sparsity_kwargs` are overwritten. If False, use other sparsity settings. - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. - All extensions that play with traces will use this global return_in_uV : "waveforms", "noise_levels", "templates". - This prevent return_in_uV being differents from different extensions and having wrong snr for instance. - return_in_uV : bool, default: None + return_in_uV : bool, default: True If True, all extensions that play with traces will use this global return_in_uV : "waveforms", "noise_levels", "templates". This prevent return_in_uV being differents from different extensions and having wrong snr for instance. - If None, use return_scaled value. overwrite: bool, default: False If True, overwrite the folder if it already exists. backend_options : dict | None, default: None @@ -269,7 +263,6 @@ def create_sorting_analyzer( sparse=sparse, sparsity=sparsity, main_channel_indices=main_channel_indices, - return_scaled=return_scaled, return_in_uV=return_in_uV, overwrite=overwrite, backend_options=backend_options, @@ -329,15 +322,6 @@ def create_sorting_analyzer( else: sparsity = None - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warnings.warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - stacklevel=2, - ) - return_in_uV = return_scaled if return_in_uV is None else return_in_uV - # Handle return_in_uV parameter for recordings without scaling if return_in_uV and not recording.has_scaleable_traces() and recording.get_dtype().kind == "i": warnings.warn("create_sorting_analyzer: recording does not have scaling to uV, forcing return_in_uV=False") @@ -526,7 +510,6 @@ def create( folder: str | Path | None = None, lazy: bool = False, sparsity: ChannelSparsity | None = None, - return_scaled: bool | None = None, return_in_uV: bool = True, peak_sign: PeakSignType = "both", peak_mode: PeakModeType = "extremum", @@ -536,13 +519,6 @@ def create( assert ( main_channel_indices is not None ), "To create a SortingAnalyzer you need to specify the main_channel_indices" - if return_scaled is not None: - warnings.warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - stacklevel=2, - ) - return_in_uV = return_scaled if return_in_uV is None else return_in_uV # some checks if sorting.sampling_frequency != recording.sampling_frequency: diff --git a/src/spikeinterface/core/testing.py b/src/spikeinterface/core/testing.py index 2feee7792e..6ad7458c37 100644 --- a/src/spikeinterface/core/testing.py +++ b/src/spikeinterface/core/testing.py @@ -14,7 +14,6 @@ def check_sorted_arrays_equal(a1, a2): def check_recordings_equal( RX1: BaseRecording, RX2: BaseRecording, - return_scaled=None, return_in_uV=True, force_dtype=None, check_annotations: bool = False, @@ -29,9 +28,6 @@ def check_recordings_equal( First recording RX2 : BaseRecording Second recording - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. - If True, compare scaled traces return_in_uV : bool, default: True If True, compare scaled traces. force_dtype : dtype, default: None @@ -41,14 +37,6 @@ def check_recordings_equal( check_properties : bool, default: False If True, check properties """ - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warnings.warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - stacklevel=2, - ) - return_in_uV = return_scaled assert RX1.get_num_segments() == RX2.get_num_segments() for segment_idx in range(RX1.get_num_segments()): diff --git a/src/spikeinterface/core/waveform_tools.py b/src/spikeinterface/core/waveform_tools.py index 942d1b9cb4..9fedc89324 100644 --- a/src/spikeinterface/core/waveform_tools.py +++ b/src/spikeinterface/core/waveform_tools.py @@ -29,7 +29,6 @@ def extract_waveforms_to_buffers( nbefore, nafter, mode="memmap", - return_scaled=None, return_in_uV=True, folder=None, dtype=None, @@ -62,8 +61,6 @@ def extract_waveforms_to_buffers( N samples after spike mode: "memmap" | "shared_memory", default: "memmap" The mode to use for the buffer - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. return_in_uV : bool, default: True If True and the recording has scaling (gain_to_uV and offset_to_uV properties), traces are scaled to uV @@ -89,15 +86,6 @@ def extract_waveforms_to_buffers( Optionally return in case of shared_memory if copy=False. Dictionary to "construct" array in workers process (memmap file or sharemem info) """ - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warnings.warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - stacklevel=2, - ) - return_in_uV = return_scaled - job_kwargs = fix_job_kwargs(job_kwargs) if dtype is None: @@ -425,7 +413,6 @@ def extract_waveforms_to_single_buffer( nbefore, nafter, mode="memmap", - return_scaled=None, return_in_uV=True, file_path=None, dtype=None, @@ -467,8 +454,6 @@ def extract_waveforms_to_single_buffer( N samples after spike mode: "memmap" | "shared_memory", default: "memmap" The mode to use for the buffer - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. return_in_uV : bool, default: False If True and the recording has scaling (gain_to_uV and offset_to_uV properties), traces are scaled to uV @@ -497,16 +482,6 @@ def extract_waveforms_to_single_buffer( Optionally return in case of shared_memory if copy=False. Dictionary to "construct" array in workers process (memmap file or sharemem info) """ - - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warnings.warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - stacklevel=2, - ) - return_in_uV = return_scaled - n_samples = nbefore + nafter if dtype is None: @@ -755,7 +730,6 @@ def estimate_templates( nbefore: int, nafter: int, operator: str = "average", - return_scaled=None, return_in_uV=True, sparsity_mask=None, job_name=None, @@ -773,14 +747,12 @@ def estimate_templates( spikes: 1d numpy array with several fields Spikes handled as a unique vector. This vector can be obtained with: `spikes = sorting.to_spike_vector()` - unit_ids: list ot numpy + unit_ids: list or numpy.ndarray List of unit_ids nbefore: int Number of samples to cut out before a spike nafter: int Number of samples to cut out after a spike - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. return_in_uV : bool, default: True If True and the recording has scaling (gain_to_uV and offset_to_uV properties), traces are scaled to uV @@ -793,15 +765,6 @@ def estimate_templates( The average templates with shape (num_units, nbefore + nafter, num_channels) """ - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warnings.warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - stacklevel=2, - ) - return_in_uV = return_scaled - if job_name is None: job_name = "estimate_templates" @@ -854,7 +817,6 @@ def estimate_templates_with_accumulator( unit_ids: list | np.ndarray, nbefore: int, nafter: int, - return_scaled=None, return_in_uV=True, sparsity_mask=None, job_name=None, @@ -883,8 +845,6 @@ def estimate_templates_with_accumulator( Number of samples to cut out before a spike nafter: int Number of samples to cut out after a spike - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. return_in_uV : bool, default: True If True and the recording has scaling (gain_to_uV and offset_to_uV properties), traces are scaled to uV @@ -898,16 +858,6 @@ def estimate_templates_with_accumulator( templates_array: np.array The average templates with shape (num_units, nbefore + nafter, num_channels) """ - - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warnings.warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - stacklevel=2, - ) - return_in_uV = return_scaled - job_kwargs = fix_job_kwargs(job_kwargs) num_worker = job_kwargs["n_jobs"] diff --git a/src/spikeinterface/curation/__init__.py b/src/spikeinterface/curation/__init__.py index 9d3405ef62..9dff51dcac 100644 --- a/src/spikeinterface/curation/__init__.py +++ b/src/spikeinterface/curation/__init__.py @@ -6,7 +6,6 @@ from .auto_merge import ( compute_merge_unit_groups, auto_merge_units, - get_potential_auto_merge, ) # manual sorting, diff --git a/src/spikeinterface/curation/auto_merge.py b/src/spikeinterface/curation/auto_merge.py index 566d88023f..a31b841882 100644 --- a/src/spikeinterface/curation/auto_merge.py +++ b/src/spikeinterface/curation/auto_merge.py @@ -525,199 +525,6 @@ def _auto_merge_units_single_iteration( return merged_analyzer -def get_potential_auto_merge( - sorting_analyzer: SortingAnalyzer, - preset: str | None = "similarity_correlograms", - resolve_graph: bool = False, - min_spikes: int = 100, - min_snr: float = 2, - max_distance_um: float = 150.0, - corr_diff_thresh: float = 0.16, - template_diff_thresh: float = 0.25, - contamination_thresh: float = 0.2, - presence_distance_thresh: float = 100.0, - p_value: float = 0.2, - cc_thresh: float = 0.1, - censored_period_ms: float = 0.3, - refractory_period_ms: float = 1.0, - sigma_smooth_ms: float = 0.6, - adaptative_window_thresh: float = 0.5, - censor_correlograms_ms: float = 0.15, - firing_contamination_balance: float = 1.5, - k_nn: int = 10, - knn_kwargs: dict | None = None, - presence_distance_kwargs: dict | None = None, - extra_outputs: bool = False, - steps: list[str] | None = None, -) -> list[tuple[int | str, int | str]] | Tuple[tuple[int | str, int | str], dict]: - """ - This function is deprecated. Use compute_merge_unit_groups() instead. - This will be removed in 0.103.0 - - Algorithm to find and check potential merges between units. - - The merges are proposed based on a series of steps with different criteria: - - * "num_spikes": enough spikes are found in each unit for computing the correlogram (`min_spikes`) - * "snr": the SNR of the units is above a threshold (`min_snr`) - * "remove_contaminated": each unit is not contaminated (by checking auto-correlogram - `contamination_thresh`) - * "unit_locations": estimated unit locations are close enough (`max_distance_um`) - * "correlogram": the cross-correlograms of the two units are similar to each auto-corrleogram (`corr_diff_thresh`) - * "template_similarity": the templates of the two units are similar (`template_diff_thresh`) - * "presence_distance": the presence of the units is complementary in time (`presence_distance_thresh`) - * "cross_contamination": the cross-contamination is not significant (`cc_thresh` and `p_value`) - * "knn": the two units are close in the feature space - * "quality_score": the unit "quality score" is increased after the merge - * "slay_score": a combined score, factoring in a template similarity measure, a cross-correlation significance measure and a sliding refractory period violation measure, based on the SLAy algorithm. - - The "quality score" factors in the increase in firing rate (**f**) due to the merge and a possible increase in - contamination (**C**), wheighted by a factor **k** (`firing_contamination_balance`). - - .. math:: - - Q = f(1 - (k + 1)C) - - IMPORTANT: internally, all computations are relying on extensions of the analyzer, that are computed - with default parameters if not present (i.e. correlograms, template_similarity, ...) If you want to - have a finer control on these values, please precompute the extensions before applying the auto_merge - - Parameters - ---------- - sorting_analyzer : SortingAnalyzer - The SortingAnalyzer - preset : "similarity_correlograms" | "x_contaminations" | "temporal_splits" | "feature_neighbors" | "slay" | None, default: "similarity_correlograms" - The preset to use for the auto-merge. Presets combine different steps into a recipe and focus on: - - * | "similarity_correlograms": mainly focused on template similarity and correlograms. - | It uses the following steps: "num_spikes", "remove_contaminated", "unit_locations", - | "template_similarity", "correlogram", "quality_score" - * | "x_contaminations": similar to "similarity_correlograms", but checks for cross-contamination instead of correlograms. - | It uses the following steps: "num_spikes", "remove_contaminated", "unit_locations", - | "template_similarity", "cross_contamination", "quality_score" - * | "temporal_splits": focused on finding temporal splits using presence distance. - | It uses the following steps: "num_spikes", "remove_contaminated", "unit_locations", - | "template_similarity", "presence_distance", "quality_score" - * | "feature_neighbors": focused on finding unit pairs whose spikes are close in the feature space using kNN. - | It uses the following steps: "num_spikes", "snr", "remove_contaminated", "unit_locations", - | "knn", "quality_score" - * | "slay": an approximate implementation of SLAy, original implementation at https://github.com/saikoukunt/SLAy. - | The spikeinterface version uses `template_similarity`, rather than an auto-encoder. - | It uses the following steps: "template_similarity", "slay_score" - - If `preset` is None, you can specify the steps manually with the `steps` parameter. - resolve_graph : bool, default: False - If True, the function resolves the potential unit pairs to be merged into multiple-unit merges. - min_spikes : int, default: 100 - Minimum number of spikes for each unit to consider a potential merge. - Enough spikes are needed to estimate the correlogram - min_snr : float, default 2 - Minimum Signal to Noise ratio for templates to be considered while merging - max_distance_um : float, default: 150 - Maximum distance between units for considering a merge - corr_diff_thresh : float, default: 0.16 - The threshold on the "correlogram distance metric" for considering a merge. - It needs to be between 0 and 1 - template_diff_thresh : float, default: 0.25 - The threshold on the "template distance metric" for considering a merge. - It needs to be between 0 and 1 - contamination_thresh : float, default: 0.2 - Threshold for not taking in account a unit when it is too contaminated. - presence_distance_thresh : float, default: 100 - Parameter to control how present two units should be simultaneously. - p_value : float, default: 0.2 - The p-value threshold for the cross-contamination test. - cc_thresh : float, default: 0.1 - The threshold on the cross-contamination for considering a merge. - censored_period_ms : float, default: 0.3 - Used to compute the refractory period violations aka "contamination". - refractory_period_ms : float, default: 1 - Used to compute the refractory period violations aka "contamination". - sigma_smooth_ms : float, default: 0.6 - Parameters to smooth the correlogram estimation. - adaptative_window_thresh : float, default: 0.5 - Parameter to detect the window size in correlogram estimation. - censor_correlograms_ms : float, default: 0.15 - The period to censor on the auto and cross-correlograms. - firing_contamination_balance : float, default: 1.5 - Parameter to control the balance between firing rate and contamination in computing unit "quality score". - k_nn : int, default 5 - The number of neighbors to consider for every spike in the recording. - knn_kwargs : dict, default None - The dict of extra params to be passed to knn. - extra_outputs : bool, default: False - If True, an additional dictionary (`outs`) with processed data is returned. - steps : None or list of str, default: None - Which steps to run, if no preset is used. - Pontential steps : "num_spikes", "snr", "remove_contaminated", "unit_locations", "correlogram", - "template_similarity", "presence_distance", "cross_contamination", "knn", "quality_score" - Please check steps explanations above! - presence_distance_kwargs : None|dict, default: None - A dictionary of kwargs to be passed to compute_presence_distance(). - - Returns - ------- - potential_merges: - A list of tuples of 2 elements (if `resolve_graph`if false) or 2+ elements (if `resolve_graph` is true). - List of pairs that could be merged. - outs: - Returned only when extra_outputs=True - A dictionary that contains data for debugging and plotting. - - References - ---------- - This function is inspired and built upon similar functions from Lussac [Llobet]_, - done by Aurelien Wyngaard and Victor Llobet. - https://github.com/BarbourLab/lussac/blob/v1.0.0/postprocessing/merge_units.py - """ - # deprecation moved to 0.105.0 for @zm711 - warnings.warn( - "get_potential_auto_merge() is deprecated and will be removed in version 0.105.0. Use compute_merge_unit_groups() instead", - FutureWarning, - stacklevel=2, - ) - - presence_distance_kwargs = presence_distance_kwargs or dict() - knn_kwargs = knn_kwargs or dict() - return compute_merge_unit_groups( - sorting_analyzer, - preset, - resolve_graph, - steps_params={ - "num_spikes": {"min_spikes": min_spikes}, - "snr": {"min_snr": min_snr}, - "remove_contaminated": { - "contamination_thresh": contamination_thresh, - "refractory_period_ms": refractory_period_ms, - "censored_period_ms": censored_period_ms, - }, - "unit_locations": {"max_distance_um": max_distance_um}, - "correlogram": { - "corr_diff_thresh": corr_diff_thresh, - "censor_correlograms_ms": censor_correlograms_ms, - "sigma_smooth_ms": sigma_smooth_ms, - "adaptative_window_thresh": adaptative_window_thresh, - }, - "template_similarity": {"template_diff_thresh": template_diff_thresh}, - "presence_distance": {"presence_distance_thresh": presence_distance_thresh, **presence_distance_kwargs}, - "knn": {"k_nn": k_nn, **knn_kwargs}, - "cross_contamination": { - "cc_thresh": cc_thresh, - "p_value": p_value, - "refractory_period_ms": refractory_period_ms, - "censored_period_ms": censored_period_ms, - }, - "quality_score": { - "firing_contamination_balance": firing_contamination_balance, - "refractory_period_ms": refractory_period_ms, - "censored_period_ms": censored_period_ms, - }, - }, - compute_needed_extensions=True, - extra_outputs=extra_outputs, - steps=steps, - ) - - def auto_merge_units( sorting_analyzer: SortingAnalyzer, presets: list | None = ["similarity_correlograms"], diff --git a/src/spikeinterface/curation/curation_model.py b/src/spikeinterface/curation/curation_model.py index adff9d73d6..128bc0e6ba 100644 --- a/src/spikeinterface/curation/curation_model.py +++ b/src/spikeinterface/curation/curation_model.py @@ -479,15 +479,6 @@ def validate_curation_dict(self): return self -def CurationModel(*args, **kwargs): - warnings.warn( - "`CurationModel` is deprecated and will be removed in 0.105.0. Use `Curation` instead", - FutureWarning, - stacklevel=2, - ) - return Curation(*args, **kwargs) - - class SequentialCuration(BaseModel): """ A Pydantic model which defines a sequence of curation steps. If using sequential curations, diff --git a/src/spikeinterface/extractors/__init__.py b/src/spikeinterface/extractors/__init__.py index 75879528bb..b84e6f5252 100644 --- a/src/spikeinterface/extractors/__init__.py +++ b/src/spikeinterface/extractors/__init__.py @@ -13,8 +13,7 @@ # this __getattr__ is only triggered if the normal lookup fails so import # any of our functions is fine but if someone tries to import a class this raises # the warning and then returns the "function" version which will look the same -# to the end-user -# to be removed after version 0.105.0 +# to the end-user to be removed after version 0.105.0 def __getattr__(extractor_name): # we need this trick to allow us to use import * for spikeinterface.full if extractor_name == "__all__": diff --git a/src/spikeinterface/extractors/neoextractors/openephys.py b/src/spikeinterface/extractors/neoextractors/openephys.py index 824f8d9560..b03f731909 100644 --- a/src/spikeinterface/extractors/neoextractors/openephys.py +++ b/src/spikeinterface/extractors/neoextractors/openephys.py @@ -137,10 +137,6 @@ class OpenEphysBinaryRecordingExtractor(NeoBaseRecordingExtractor): If True, the synchronized_timestamps are loaded and set as times to the recording. If False (default), only the t_start and sampling rate are set, and timestamps are assumed to be uniform and linearly increasing - experiment_names : str, list, or None, default: None - **DEPRECATED: Use experiment_name instead. Will be removed in version 0.105.0** - This parameter was designed for Neo's multi-block loading, but SpikeInterface only loads - one block at a time. Use experiment_name to select a single experiment. all_annotations : bool, default: False Load exhaustively all annotation from neo @@ -224,20 +220,10 @@ def __init__( stream_name: str = None, block_index: int = None, load_sync_timestamps: bool = False, - experiment_names: str | list | None = None, all_annotations: bool = False, ): folder_path = Path(folder_path) - # Handle experiment_names deprecation - if experiment_names is not None: - warnings.warn( - "OpenEphysBinaryRecordingExtractor: 'experiment_names' is deprecated and will be removed in version 0.105.0. " - "Use 'experiment_name' instead to select a single experiment (e.g., experiment_name='experiment2').", - FutureWarning, - stacklevel=2, - ) - # Handle experiment_name and block_index parameters if experiment_name is not None and block_index is not None: raise ValueError( @@ -248,7 +234,7 @@ def __init__( # Convert experiment_name to experiment_names for Neo # When using experiment_name, Neo will filter to only that experiment, making it block_index=0 # experiment_name takes precedence over experiment_names - experiment_names_for_neo = experiment_names # Use deprecated parameter if provided + experiment_names_for_neo = None # No longer using the deprecated parameter if experiment_name is not None: # experiment_name overrides experiment_names experiment_names_for_neo = [experiment_name] diff --git a/src/spikeinterface/metrics/quality/quality_metrics.py b/src/spikeinterface/metrics/quality/quality_metrics.py index c23f6decb7..0e50a4eb79 100644 --- a/src/spikeinterface/metrics/quality/quality_metrics.py +++ b/src/spikeinterface/metrics/quality/quality_metrics.py @@ -248,13 +248,3 @@ def get_default_quality_metrics_params(metric_names=None): metric_names = list(set(metric_names) & set(default_params.keys())) metric_params = {m: default_params[m] for m in metric_names} return metric_params - - -def get_default_qm_params(metric_names=None): - warnings.warn( - "`get_default_qm_params` is deprecated and will be removed in a version 0.105.0. " - "Please use `get_default_quality_metrics_params` instead.", - FutureWarning, - stacklevel=2, - ) - return get_default_quality_metrics_params(metric_names=metric_names) diff --git a/src/spikeinterface/metrics/template/template_metrics.py b/src/spikeinterface/metrics/template/template_metrics.py index 1a34efe27f..a23343d0ec 100644 --- a/src/spikeinterface/metrics/template/template_metrics.py +++ b/src/spikeinterface/metrics/template/template_metrics.py @@ -27,18 +27,6 @@ def get_template_metric_list(): return get_single_channel_template_metric_names() + get_multi_channel_template_metric_names() -def get_template_metric_names(): - import warnings - - warnings.warn( - "get_template_metric_names is deprecated and will be removed in a version 0.105.0. " - "Please use get_template_metric_list instead.", - FutureWarning, - stacklevel=2, - ) - return get_template_metric_list() - - class ComputeTemplateMetrics(BaseMetricExtension): """ Compute template metrics including: @@ -365,23 +353,3 @@ def get_default_template_metrics_params(metric_names=None): metric_names = list(set(metric_names) & set(default_params.keys())) metric_params = {m: default_params[m] for m in metric_names} return metric_params - - -def get_default_tm_params(metric_names=None): - """ - Return default dictionary of template metrics parameters. - - Returns - ------- - metric_params : dict - Dictionary with default parameters for template metrics. - """ - import warnings - - warnings.warn( - "get_default_tm_params is deprecated and will be removed in a version 0.105.0. " - "Please use get_default_template_metrics_params instead.", - FutureWarning, - stacklevel=2, - ) - return get_default_template_metrics_params(metric_names) diff --git a/src/spikeinterface/postprocessing/template_metrics.py b/src/spikeinterface/postprocessing/template_metrics.py deleted file mode 100644 index e4b8689f0e..0000000000 --- a/src/spikeinterface/postprocessing/template_metrics.py +++ /dev/null @@ -1,26 +0,0 @@ -import warnings - - -from spikeinterface.metrics.template import ComputeTemplateMetrics as ComputeTemplateMetricsNew -from spikeinterface.metrics.template import compute_template_metrics as compute_template_metrics_new - - -class ComputeTemplateMetrics(ComputeTemplateMetricsNew): - def __init__(self, *args, **kwargs): - warnings.warn( - "The module 'spikeinterface.postprocessing.template_metrics' is deprecated and will be removed in 0.105.0." - "Please use 'spikeinterface.metrics.template' instead.", - FutureWarning, - stacklevel=2, - ) - super().__init__(*args, **kwargs) - - -def compute_template_metrics(*args, **kwargs): - warnings.warn( - "The module 'spikeinterface.postprocessing.template_metrics' is deprecated and will be removed in 0.105.0." - "Please use 'spikeinterface.metrics.template' instead.", - FutureWarning, - stacklevel=2, - ) - return compute_template_metrics_new(*args, **kwargs) diff --git a/src/spikeinterface/qualitymetrics/__init__.py b/src/spikeinterface/qualitymetrics/__init__.py deleted file mode 100644 index a6aad78640..0000000000 --- a/src/spikeinterface/qualitymetrics/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -import warnings - -warnings.warn( - "The module 'spikeinterface.qualitymetrics' is deprecated and will be removed in 0.105.0." - "Please use 'spikeinterface.metrics.quality' instead.", - FutureWarning, - stacklevel=2, -) - -from spikeinterface.metrics.quality import * # noqa: F403 diff --git a/src/spikeinterface/sortingcomponents/matching/main.py b/src/spikeinterface/sortingcomponents/matching/main.py index 3da7785c5e..0b054c0638 100644 --- a/src/spikeinterface/sortingcomponents/matching/main.py +++ b/src/spikeinterface/sortingcomponents/matching/main.py @@ -17,7 +17,6 @@ def find_spikes_from_templates( pipeline_kwargs=None, verbose=False, job_kwargs=None, - **old_kwargs, ) -> np.ndarray | tuple[np.ndarray, dict]: """Find spike from a recording from given templates. @@ -50,15 +49,8 @@ def find_spikes_from_templates( outputs: Optionaly returns for debug purpose. """ - - if len(old_kwargs) > 0: - # This is the old behavior and will be remove in 0.105.0 - warnings.warn( - "The signature of find_spikes_from_templates() has changed, now job_kwargs are in separated dict and not flatten" - "This warning will raise an error in version 0.105.0" - ) - assert job_kwargs is None - job_kwargs = old_kwargs + if job_kwargs is None: + job_kwargs = {} if "method" in method_kwargs: # for flexibility the caller can put method inside method_kwargs diff --git a/src/spikeinterface/sortingcomponents/peak_detection/main.py b/src/spikeinterface/sortingcomponents/peak_detection/main.py index 489be8abea..4332acac0f 100644 --- a/src/spikeinterface/sortingcomponents/peak_detection/main.py +++ b/src/spikeinterface/sortingcomponents/peak_detection/main.py @@ -18,7 +18,6 @@ def detect_peaks( pipeline_kwargs=None, verbose=False, job_kwargs=None, - **old_kwargs, ): """Peak detection based on threshold crossing in term of k x MAD. @@ -54,22 +53,13 @@ def detect_peaks( This peak detection ported from tridesclous into spikeinterface. """ - - if len(old_kwargs) > 0: - # This is the old behavior and will be remove in 0.105.0 - warnings.warn( - "The signature of detect_peaks() has changed, now method_kwargs and job_kwargs are dinstinct params." - "This warning will raise an error in version 0.105.0" - ) - assert job_kwargs is None - assert method_kwargs is None - method_kwargs, job_kwargs = split_job_kwargs(old_kwargs) + if method_kwargs is None: + method_kwargs = dict() else: - if method_kwargs is None: - method_kwargs = dict() - else: - # sevral pop later - method_kwargs = method_kwargs.copy() + # sevral pop later + method_kwargs = method_kwargs.copy() + if job_kwargs is None: + job_kwargs = dict() if "method" in method_kwargs: # for flexibility the caller can put method inside method_kwargs diff --git a/src/spikeinterface/sortingcomponents/peak_localization/main.py b/src/spikeinterface/sortingcomponents/peak_localization/main.py index f49298e407..c788f8b7fa 100644 --- a/src/spikeinterface/sortingcomponents/peak_localization/main.py +++ b/src/spikeinterface/sortingcomponents/peak_localization/main.py @@ -74,7 +74,6 @@ def localize_peaks( verbose=False, job_kwargs=None, seed=None, - **old_kwargs, ) -> np.ndarray: """Localize peak (spike) in 2D or 3D depending the method. @@ -116,18 +115,10 @@ def localize_peaks( Array with estimated location for each spike. The dtype depends on the method. ("x", "y") or ("x", "y", "z", "alpha"). """ - if len(old_kwargs) > 0: - # This is the old behavior and will be remove in 0.105.0 - warnings.warn( - "The signature of localize_peaks() has changed, now method_kwargs and job_kwargs are dinstinct params." - "This warning will raise an error in version 0.105.0" - ) - assert job_kwargs is None - assert method_kwargs is None - method_kwargs, job_kwargs = split_job_kwargs(old_kwargs) - else: - if method_kwargs is None: - method_kwargs = dict() + if method_kwargs is None: + method_kwargs = dict() + if job_kwargs is None: + job_kwargs = dict() if "method" in method_kwargs: # for flexibility the caller can put method inside method_kwargs diff --git a/src/spikeinterface/widgets/isi_distribution.py b/src/spikeinterface/widgets/isi_distribution.py index 54511b4c2a..65bda2341e 100644 --- a/src/spikeinterface/widgets/isi_distribution.py +++ b/src/spikeinterface/widgets/isi_distribution.py @@ -31,16 +31,8 @@ def __init__( window_ms: float = 100.0, bin_ms: float = 1.0, backend: str | None = None, - sorting: BaseSorting | None = None, **backend_kwargs, ): - - if sorting is not None: - # When removed, make `sorting_analyzer_or_sorting` a required argument rather than None. - deprecation_msg = "`sorting` argument is deprecated and will be removed in version 0.105.0. Please use `sorting_analyzer_or_sorting` instead" - warn(deprecation_msg, category=FutureWarning, stacklevel=2) - sorting_analyzer_or_sorting = sorting - sorting = self.ensure_sorting(sorting_analyzer_or_sorting) if unit_ids is None: diff --git a/src/spikeinterface/widgets/potential_merges.py b/src/spikeinterface/widgets/potential_merges.py index 3a96c1ea56..370efa57eb 100644 --- a/src/spikeinterface/widgets/potential_merges.py +++ b/src/spikeinterface/widgets/potential_merges.py @@ -21,7 +21,7 @@ class PotentialMergesWidget(BaseWidget): sorting_analyzer : SortingAnalyzer The input sorting analyzer potential_merges : list of lists or tuples - List of potential merges (see `spikeinterface.curation.get_potential_auto_merges`) + List of potential merges (see `spikeinterface.curation.compute_merge_unit_groups`) segment_index : int The segment index to display max_spike_samples : int or None, default: None diff --git a/src/spikeinterface/widgets/rasters.py b/src/spikeinterface/widgets/rasters.py index 2ec8f42777..91000be7c1 100644 --- a/src/spikeinterface/widgets/rasters.py +++ b/src/spikeinterface/widgets/rasters.py @@ -414,21 +414,9 @@ def __init__( time_range: list | None = None, color="k", backend: str | None = None, - sorting: BaseSorting | None = None, - sorting_analyzer: SortingAnalyzer | None = None, sort_by_depth: bool = False, **backend_kwargs, ): - if sorting is not None: - # When removed, make `sorting_analyzer_or_sorting` a required argument rather than None. - deprecation_msg = "`sorting` argument is deprecated and will be removed in version 0.105.0. Please use `sorting_analyzer_or_sorting` instead" - warn(deprecation_msg, category=FutureWarning, stacklevel=2) - sorting_analyzer_or_sorting = sorting - if sorting_analyzer is not None: - deprecation_msg = "`sorting_analyzer` argument is deprecated and will be removed in version 0.105.0. Please use `sorting_analyzer_or_sorting` instead" - warn(deprecation_msg, category=FutureWarning, stacklevel=2) - sorting_analyzer_or_sorting = sorting_analyzer - sorting = self.ensure_sorting(sorting_analyzer_or_sorting) segment_indices = validate_segment_indices(segment_indices, sorting) diff --git a/src/spikeinterface/widgets/spikes_on_traces.py b/src/spikeinterface/widgets/spikes_on_traces.py index 3079868a54..11f6d9c6a6 100644 --- a/src/spikeinterface/widgets/spikes_on_traces.py +++ b/src/spikeinterface/widgets/spikes_on_traces.py @@ -74,7 +74,6 @@ def __init__( unit_colors=None, sparsity=None, mode="auto", - return_scaled=None, return_in_uV=False, cmap="RdBu", show_channel_ids=False, @@ -90,16 +89,6 @@ def __init__( backend=None, **backend_kwargs, ): - - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warnings.warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FurtureWarning, - stacklevel=2, - ) - return_in_uV = return_scaled - sorting_analyzer = self.ensure_sorting_analyzer(sorting_analyzer) self.check_extensions(sorting_analyzer, "unit_locations") diff --git a/src/spikeinterface/widgets/traces.py b/src/spikeinterface/widgets/traces.py index c9795f3811..303225458d 100644 --- a/src/spikeinterface/widgets/traces.py +++ b/src/spikeinterface/widgets/traces.py @@ -73,7 +73,6 @@ def __init__( order_channel_by_depth=False, time_range=None, mode="auto", - return_scaled=None, return_in_uV=False, cmap="RdBu_r", show_channel_ids=False, @@ -92,16 +91,6 @@ def __init__( backend=None, **backend_kwargs, ): - - # Handle deprecated return_scaled parameter - if return_scaled is not None: - warnings.warn( - "`return_scaled` is deprecated and will be removed in version 0.105.0. Use `return_in_uV` instead.", - category=FutureWarning, - stacklevel=2, - ) - return_in_uV = return_scaled - if isinstance(recording, BaseRecording): recordings = {"rec": recording} rec0 = recording diff --git a/src/spikeinterface/widgets/unit_presence.py b/src/spikeinterface/widgets/unit_presence.py index f60e0745e7..72a9603544 100644 --- a/src/spikeinterface/widgets/unit_presence.py +++ b/src/spikeinterface/widgets/unit_presence.py @@ -33,16 +33,8 @@ def __init__( bin_duration_s: float = 0.05, smooth_sigma: float = 4.5, backend: str | None = None, - sorting: BaseSorting | None = None, **backend_kwargs, ): - - if sorting is not None: - # When removed, make `sorting_analyzer_or_sorting` a required argument rather than None. - deprecation_msg = "`sorting` argument is deprecated and will be removed in version 0.105.0. Please use `sorting_analyzer_or_sorting` instead" - warn(deprecation_msg, category=FutureWarning, stacklevel=2) - sorting_analyzer_or_sorting = sorting - sorting = self.ensure_sorting(sorting_analyzer_or_sorting) if segment_index is None: diff --git a/src/spikeinterface/widgets/utils_figpack.py b/src/spikeinterface/widgets/utils_figpack.py index 9d150980a5..46a94f8126 100644 --- a/src/spikeinterface/widgets/utils_figpack.py +++ b/src/spikeinterface/widgets/utils_figpack.py @@ -26,7 +26,7 @@ def import_figpack_or_sortingview(use_sortingview: bool): vv_base = vv_views warn( - "The 'sortingview' backend is deprecated and will be removed in version 0.105.0. " + "The 'sortingview' backend is deprecated and will be removed in version 0.106.0. " "Use the 'figpack' backend instead.", ) else: From acdb7888797d5ec2b2d825c4ae8fc75fde8478bc Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Thu, 17 Sep 2026 17:41:21 +0200 Subject: [PATCH 2/7] fix: core tests --- .../core/channelsaggregationrecording.py | 18 +++++- src/spikeinterface/core/sortinganalyzer.py | 3 - .../core/tests/test_baserecording.py | 14 +---- src/spikeinterface/core/time_series_tools.py | 2 - src/spikeinterface/extractors/__init__.py | 55 ------------------- .../tests/test_zarr_array_extractor.py | 2 +- .../metrics/quality/__init__.py | 1 - .../metrics/template/__init__.py | 2 - src/spikeinterface/postprocessing/__init__.py | 5 -- src/spikeinterface/preprocessing/__init__.py | 31 ----------- .../widgets/spikes_on_traces.py | 2 - src/spikeinterface/widgets/traces.py | 2 - 12 files changed, 18 insertions(+), 119 deletions(-) diff --git a/src/spikeinterface/core/channelsaggregationrecording.py b/src/spikeinterface/core/channelsaggregationrecording.py index 2217eec0c0..ae7309d1ab 100644 --- a/src/spikeinterface/core/channelsaggregationrecording.py +++ b/src/spikeinterface/core/channelsaggregationrecording.py @@ -147,7 +147,20 @@ def __init__(self, recording_list_or_dict=None, renamed_channel_ids=None): sub_segment = ChannelsAggregationRecordingSegment(channel_map, parent_segments) self.add_recording_segment(sub_segment) - self._kwargs = {"recording_list": recording_list, "renamed_channel_ids": renamed_channel_ids} + self._kwargs = {"recording_list_or_dict": recording_list, "renamed_channel_ids": renamed_channel_ids} + + @classmethod + def _handle_kwargs_backward_compatibility(cls, old_kwargs, full_dict): + """ + Fix backward compatibility issues with `recording_list' argument, + which is renamed to `recording_list_or_dict'. + """ + if "recording_list" in old_kwargs: + new_kwargs = old_kwargs.copy() + new_kwargs["recording_list_or_dict"] = new_kwargs.pop("recording_list") + else: + new_kwargs = old_kwargs + return new_kwargs @property def recordings(self): @@ -256,7 +269,6 @@ def get_traces( def aggregate_channels( recording_list_or_dict=None, renamed_channel_ids=None, - recording_list=None, ): """ Aggregates channels of multiple recording into a single recording object @@ -280,4 +292,4 @@ def aggregate_channels( values, are dropped. """ - return ChannelsAggregationRecording(recording_list_or_dict, renamed_channel_ids, recording_list) + return ChannelsAggregationRecording(recording_list_or_dict, renamed_channel_ids) diff --git a/src/spikeinterface/core/sortinganalyzer.py b/src/spikeinterface/core/sortinganalyzer.py index 18583b0de3..0a75bf7c1a 100644 --- a/src/spikeinterface/core/sortinganalyzer.py +++ b/src/spikeinterface/core/sortinganalyzer.py @@ -435,9 +435,6 @@ def __init__( self.peak_sign = peak_sign self.peak_mode = peak_mode self._main_channel_indices = None - - # For backward compatibility - self.return_scaled = return_in_uV self.folder: str | Path | None = None # this is used to store temporary recording diff --git a/src/spikeinterface/core/tests/test_baserecording.py b/src/spikeinterface/core/tests/test_baserecording.py index 809df7abbe..63fe18f899 100644 --- a/src/spikeinterface/core/tests/test_baserecording.py +++ b/src/spikeinterface/core/tests/test_baserecording.py @@ -288,8 +288,6 @@ def test_BaseRecording(create_cache_folder): assert traces_int16.dtype == "int16" # Both return_scaled and return_in_uV raise error when no gain_to_uV/offset_to_uV properties - with pytest.raises(ValueError): - traces_float32 = rec_int16.get_traces(return_scaled=True) with pytest.raises(ValueError): traces_float32 = rec_int16.get_traces(return_in_uV=True) @@ -297,17 +295,9 @@ def test_BaseRecording(create_cache_folder): rec_int16.set_property("gain_to_uV", [0.195] * 5) rec_int16.set_property("offset_to_uV", [0.0] * 5) - # Test deprecated return_scaled parameter - with pytest.warns(FutureWarning, match="`return_scaled` is deprecated"): - traces_float32_old = rec_int16.get_traces(return_scaled=True) # Keep this for testing the deprecation warning - assert traces_float32_old.dtype == "float32" - # Test new return_in_uV parameter - traces_float32_new = rec_int16.get_traces(return_in_uV=True) - assert traces_float32_new.dtype == "float32" - - # Verify both parameters produce the same result - assert np.array_equal(traces_float32_old, traces_float32_new) + traces_float32 = rec_int16.get_traces(return_in_uV=True) + assert traces_float32.dtype == "float32" # test cast with dtype rec_float32 = rec_int16.astype("float32") diff --git a/src/spikeinterface/core/time_series_tools.py b/src/spikeinterface/core/time_series_tools.py index 44b6925bb5..758482b965 100644 --- a/src/spikeinterface/core/time_series_tools.py +++ b/src/spikeinterface/core/time_series_tools.py @@ -562,8 +562,6 @@ def get_chunks(time_series: TimeSeries, concatenated=True, get_data_kwargs=None, ---------- time_series : TimeSeries The time_series object to get random chunks from - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. return_in_uV : bool, default: False If True and the time_series has scaling (gain_to_uV and offset_to_uV properties), traces are scaled to uV diff --git a/src/spikeinterface/extractors/__init__.py b/src/spikeinterface/extractors/__init__.py index b84e6f5252..3bce7907e4 100644 --- a/src/spikeinterface/extractors/__init__.py +++ b/src/spikeinterface/extractors/__init__.py @@ -5,58 +5,3 @@ from .neoextractors import get_neo_num_blocks, get_neo_streams from .phykilosortextractors import read_kilosort_as_analyzer - -from warnings import warn - - -# deprecation of class import idea from neuroconv -# this __getattr__ is only triggered if the normal lookup fails so import -# any of our functions is fine but if someone tries to import a class this raises -# the warning and then returns the "function" version which will look the same -# to the end-user to be removed after version 0.105.0 -def __getattr__(extractor_name): - # we need this trick to allow us to use import * for spikeinterface.full - if extractor_name == "__all__": - __all__ = [] - for imp in globals(): - # need to remove a bunch of builtins etc that shouldn't be part of all - if imp[0] != "_" and imp != "warn" and imp != "extractor_name": - __all__.append(imp) - return __all__ - all_extractors = list(recording_extractor_full_dict.values()) - all_extractors += list(sorting_extractor_full_dict.values()) - all_extractors += list(event_extractor_full_dict.values()) - all_extractors += list(snippets_extractor_full_dict.values()) - # special cases because they don't have simple wrappers - # instead a single wrapper maps to multiple classes so we return - # each class to check it - from .neoextractors import ( - MEArecRecordingExtractor, - MEArecSortingExtractor, - OpenEphysBinaryEventExtractor, - OpenEphysBinaryRecordingExtractor, - OpenEphysLegacyRecordingExtractor, - SpikeGLXEventExtractor, - ) - - all_extractors += [ - MEArecRecordingExtractor, - MEArecSortingExtractor, - OpenEphysBinaryEventExtractor, - OpenEphysBinaryRecordingExtractor, - OpenEphysLegacyRecordingExtractor, - SpikeGLXEventExtractor, - ] - for reading_function in all_extractors: - if extractor_name == reading_function.__name__: - dep_msg = ( - "Importing classes at __init__ has been deprecated in favor of only importing function-size wrappers " - "and will be removed in 0.105.0. For developers that prefer working with the class versions of extractors " - "they can be imported from spikeinterface.extractors.extractor_classes" - f"For class {reading_function.__name__}" - ) - warn(dep_msg) - return reading_function - # this is necessary for objects that we don't support - # normally this is an ImportError but since this is in the __getattr__ pytest needs an AttributeError - raise AttributeError(f"cannot import name '{extractor_name}' from '{__name__}'") diff --git a/src/spikeinterface/extractors/tests/test_zarr_array_extractor.py b/src/spikeinterface/extractors/tests/test_zarr_array_extractor.py index ddab87d4e1..2633a2e41d 100644 --- a/src/spikeinterface/extractors/tests/test_zarr_array_extractor.py +++ b/src/spikeinterface/extractors/tests/test_zarr_array_extractor.py @@ -53,7 +53,7 @@ def test_zarr_array_extractor(make_dummy_zarr_data): assert np.all(rec.get_channel_offsets() == offset) # 3. Verify exact trace reading - traces_raw = rec.get_traces(return_scaled=False) + traces_raw = rec.get_traces(return_in_uV=False) np.testing.assert_array_equal(traces_raw, original_data) # 4. Verify channel and time slicing diff --git a/src/spikeinterface/metrics/quality/__init__.py b/src/spikeinterface/metrics/quality/__init__.py index f91ed6eefc..db71887465 100644 --- a/src/spikeinterface/metrics/quality/__init__.py +++ b/src/spikeinterface/metrics/quality/__init__.py @@ -2,7 +2,6 @@ get_quality_metric_list, get_quality_pca_metric_list, get_default_quality_metrics_params, - get_default_qm_params, ComputeQualityMetrics, compute_quality_metrics, ) diff --git a/src/spikeinterface/metrics/template/__init__.py b/src/spikeinterface/metrics/template/__init__.py index f4520c416f..ea308f5aac 100644 --- a/src/spikeinterface/metrics/template/__init__.py +++ b/src/spikeinterface/metrics/template/__init__.py @@ -2,10 +2,8 @@ ComputeTemplateMetrics, compute_template_metrics, get_template_metric_list, - get_template_metric_names, get_single_channel_template_metric_names, get_multi_channel_template_metric_names, get_default_template_metrics_params, - get_default_tm_params, ) from .metrics import get_trough_and_peak_idx diff --git a/src/spikeinterface/postprocessing/__init__.py b/src/spikeinterface/postprocessing/__init__.py index ca1aa8b135..2495536d03 100644 --- a/src/spikeinterface/postprocessing/__init__.py +++ b/src/spikeinterface/postprocessing/__init__.py @@ -43,11 +43,6 @@ from .noise_level import compute_noise_levels, ComputeNoiseLevels -from .template_metrics import ( - ComputeTemplateMetrics, - compute_template_metrics, -) - from .valid_unit_periods import ( ComputeValidUnitPeriods, compute_valid_unit_periods, diff --git a/src/spikeinterface/preprocessing/__init__.py b/src/spikeinterface/preprocessing/__init__.py index 23a5bb30b1..957b5a97cc 100644 --- a/src/spikeinterface/preprocessing/__init__.py +++ b/src/spikeinterface/preprocessing/__init__.py @@ -24,34 +24,3 @@ # for snippets from .align_snippets import AlignSnippets -from warnings import warn - - -# deprecation of class import idea from neuroconv -# this __getattr__ is only triggered if the normal lookup fails so import -# any of our functions is fine but if someone tries to import a class this raises -# the warning and then returns the "function" version which will look the same -# to the end-user -# to be removed after version 0.105.0 -def __getattr__(preprocessor_name): - # we need this trick to allow us to use import * for spikeinterface.full - if preprocessor_name == "__all__": - __all__ = [] - for imp in globals(): - # need to remove a bunch of builtins etc that shouldn't be part of all - if imp[0] != "_" and imp != "warn" and imp != "preprocessor_name": - __all__.append(imp) - return __all__ - from .preprocessing_classes import _all_preprocesser_dict - - for pp_class, pp_function in _all_preprocesser_dict.items(): - if preprocessor_name == pp_class.__name__: - dep_msg = ( - "Importing classes at __init__ has been deprecated in favor of only importing functions " - "and will be removed in 0.105.0. For developers that prefer working with the class versions of preprocessors " - "they can be imported from spikeinterface.preprocessors.preprocessor_classes." - ) - warn(dep_msg) - return pp_function - # this is necessary for objects that we don't support - raise AttributeError(f"cannot import name '{preprocessor_name}' from '{__name__}'") diff --git a/src/spikeinterface/widgets/spikes_on_traces.py b/src/spikeinterface/widgets/spikes_on_traces.py index 11f6d9c6a6..b28fe25e9d 100644 --- a/src/spikeinterface/widgets/spikes_on_traces.py +++ b/src/spikeinterface/widgets/spikes_on_traces.py @@ -37,8 +37,6 @@ class SpikesOnTracesWidget(BaseWidget): * "line": classical for low channel count * "map": for high channel count use color heat map * "auto": auto switch depending on the channel count ("line" if less than 64 channels, "map" otherwise) - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. return_in_uV : bool, default: False If True and the recording has scaling (gain_to_uV and offset_to_uV properties), traces are scaled to uV diff --git a/src/spikeinterface/widgets/traces.py b/src/spikeinterface/widgets/traces.py index 303225458d..62f221b6ca 100644 --- a/src/spikeinterface/widgets/traces.py +++ b/src/spikeinterface/widgets/traces.py @@ -29,8 +29,6 @@ class TracesWidget(BaseWidget): * "line": classical for low channel count * "map": for high channel count use color heat map * "auto": auto switch depending on the channel count ("line" if less than 64 channels, "map" otherwise) - return_scaled : bool | None, default: None - DEPRECATED. Use return_in_uV instead. return_in_uV : bool, default: False If True and the recording has scaling (gain_to_uV and offset_to_uV properties), traces are scaled to uV From 2a8474c02fe9aff54c020241dd34dc8fa180a05d Mon Sep 17 00:00:00 2001 From: chrishalcrow Date: Fri, 18 Sep 2026 07:50:40 +0100 Subject: [PATCH 3/7] localize_peaks kwargs change in test_select_peaks --- .../sortingcomponents/tests/test_peak_selection.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/spikeinterface/sortingcomponents/tests/test_peak_selection.py b/src/spikeinterface/sortingcomponents/tests/test_peak_selection.py index bb0da231d9..e9d8f1987b 100644 --- a/src/spikeinterface/sortingcomponents/tests/test_peak_selection.py +++ b/src/spikeinterface/sortingcomponents/tests/test_peak_selection.py @@ -32,7 +32,14 @@ def test_select_peaks(): ) peak_locations = localize_peaks( - recording, peaks, method="center_of_mass", n_jobs=2, chunk_size=10000, progress_bar=True + recording, + peaks, + method="center_of_mass", + job_kwargs=dict( + n_jobs=2, + chunk_size=10000, + progress_bar=True, + ), ) n_peaks = 100 From 2b5806bd0854c35f8db1358694aae4a28dd22134 Mon Sep 17 00:00:00 2001 From: chrishalcrow Date: Fri, 18 Sep 2026 08:40:25 +0100 Subject: [PATCH 4/7] change sorting extractor docs --- .../core/plot_2_sorting_extractor.py | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/examples/tutorials/core/plot_2_sorting_extractor.py b/examples/tutorials/core/plot_2_sorting_extractor.py index b3ea82c77a..b6e167afe5 100644 --- a/examples/tutorials/core/plot_2_sorting_extractor.py +++ b/examples/tutorials/core/plot_2_sorting_extractor.py @@ -14,6 +14,7 @@ """ import numpy as np +import spikeinterface.core as si import spikeinterface.extractors as se ############################################################################## @@ -54,17 +55,17 @@ print("Num. events for first second of unit 1 seg1 = {}".format(len(st1))) ############################################################################## -# Some extractors also implement a :code:`write` function. We can for example -# save our newly created sorting object to NPZ format (a simple format based -# on numpy used in :code:`spikeinterface`): +# Some extractors also implement a :code:`save` method. We can for example +# save our newly created sorting object to the "numpy_foler" format +# (a simple format based on numpy used in :code:`spikeinterface`): -file_path = "my_sorting.npz" -se.NpzSortingExtractor.write_sorting(sorting, file_path) +folder_path = "my_sorting" +sorting.save(format="numpy_folder", folder=folder_path) ############################################################################## -# We can now read it back with the proper extractor: +# We can now read it back with the load function: -sorting2 = se.NpzSortingExtractor(file_path) +sorting2 = si.load(folder_path) print(sorting2) ############################################################################## @@ -127,11 +128,11 @@ # :code:`save()` function: -sorting2.save(folder="./my_sorting") +sorting2.save(folder="./my_sorting_with_spike_trains") import os -pprint(os.listdir("./my_sorting")) +pprint(os.listdir("./my_sorting_with_spike_trains")) -sorting2_cached = load("./my_sorting") +sorting2_cached = load("./my_sorting_with_spike_trains") print(sorting2_cached) From b207f8d679d76051d75de8c0c6ef3df7ac0e5428 Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Fri, 18 Sep 2026 10:36:49 +0200 Subject: [PATCH 5/7] fix: docs --- doc/api.rst | 11 ++--------- doc/development/development.rst | 1 + doc/how_to/index.rst | 1 + doc/how_to/read_various_formats.rst | 2 +- doc/modules/core.rst | 4 ++-- doc/modules/curation.rst | 1 + doc/modules/metrics.rst | 2 +- examples/how_to/read_various_formats.py | 2 +- examples/tutorials/core/plot_2_sorting_extractor.py | 5 +++-- src/spikeinterface/core/__init__.py | 2 +- src/spikeinterface/core/baserecording.py | 5 +++++ src/spikeinterface/core/basesorting.py | 1 + src/spikeinterface/core/job_tools.py | 5 +++++ src/spikeinterface/core/sortinganalyzer.py | 4 ++-- src/spikeinterface/core/tests/test_zarrextractors.py | 9 ++++++--- src/spikeinterface/extractors/extractor_classes.py | 8 +++++--- .../postprocessing/valid_unit_periods.py | 4 ++-- src/spikeinterface/preprocessing/decimate.py | 5 +++-- 18 files changed, 43 insertions(+), 29 deletions(-) diff --git a/doc/api.rst b/doc/api.rst index 103619a8eb..ac6ac683a9 100755 --- a/doc/api.rst +++ b/doc/api.rst @@ -8,7 +8,6 @@ spikeinterface.core .. autofunction:: load .. autoclass:: BaseRecording :members: - .. automethod:: BaseRecording.save .. automethod:: BaseRecording.save_to_memory .. automethod:: BaseRecording.save_to_folder .. automethod:: BaseRecording.save_to_zarr @@ -24,18 +23,14 @@ spikeinterface.core .. automethod:: BaseRecording.split_by .. autoclass:: BaseSorting :members: - .. automethod:: BaseSorting.save .. automethod:: BaseSorting.save_to_memory .. automethod:: BaseSorting.save_to_folder .. automethod:: BaseSorting.save_to_zarr .. automethod:: BaseSorting.dump .. automethod:: BaseSorting.dump_to_json .. automethod:: BaseSorting.dump_to_pickle - .. automethod:: BaseSorting.split_by - .. automethod:: BaseSorting.register_recording .. autoclass:: BaseSnippets :members: - .. automethod:: BaseSnippets.save .. automethod:: BaseSnippets.save_to_memory .. automethod:: BaseSnippets.save_to_folder .. automethod:: BaseSnippets.save_to_zarr @@ -56,7 +51,6 @@ spikeinterface.core .. autoclass:: Motion :members: .. autoclass:: BinaryRecordingExtractor - .. autoclass:: ZarrRecordingExtractor .. autoclass:: BinaryFolderRecording .. autoclass:: NumpyFolderSorting .. autoclass:: NpyFolderSnippets @@ -201,8 +195,8 @@ spikeinterface.preprocessing .. automodule:: spikeinterface.preprocessing .. autofunction:: apply_preprocessing_pipeline - .. autofunction:: get_preprocessing_dict_from_analyzer - .. autofunction:: get_preprocessing_dict_from_file + .. autofunction:: get_preprocessing_list_from_analyzer + .. autofunction:: get_preprocessing_list_from_file .. autofunction:: astype .. autofunction:: average_across_direction .. autofunction:: bandpass_filter @@ -254,7 +248,6 @@ spikeinterface.postprocessing .. automodule:: spikeinterface.postprocessing .. autofunction:: compute_noise_levels - .. autofunction:: compute_template_metrics .. autofunction:: compute_principal_components .. autofunction:: compute_spike_amplitudes .. autofunction:: compute_unit_locations diff --git a/doc/development/development.rst b/doc/development/development.rst index b8c8761aa8..82b17e7a35 100644 --- a/doc/development/development.rst +++ b/doc/development/development.rst @@ -384,6 +384,7 @@ In order to check if your spike sorter is installed, a :code:`try` - :code:`exce sorter is implemented in Python (installed with the package :code:`myspikesorter`), this block will look as follows: .. code-block:: python + import importlib.util if importlib.util.find_spec("myspikesorter"): HAVE_MYSORTER = True diff --git a/doc/how_to/index.rst b/doc/how_to/index.rst index 3c631f0376..92cd0312d2 100644 --- a/doc/how_to/index.rst +++ b/doc/how_to/index.rst @@ -7,6 +7,7 @@ Guides on how to solve specific, short problems in SpikeInterface. Learn how to. :maxdepth: 1 viewers + read_various_formats customize_a_plot combine_recordings process_by_channel_group diff --git a/doc/how_to/read_various_formats.rst b/doc/how_to/read_various_formats.rst index 1e8ee0d5bc..59dc090d07 100644 --- a/doc/how_to/read_various_formats.rst +++ b/doc/how_to/read_various_formats.rst @@ -108,7 +108,7 @@ stream information can be retrieved by using the The -:py:func::literal:`~spikeinterface.extractors.read_spike2`\` function is equivalent to instantiating a :py:class:`\ ~spikeinterface.extractors.Spike2RecordingExtractor\` +:py:func:`~spikeinterface.extractors.read_spike2` function is equivalent to instantiating a :py:class:`~spikeinterface.extractors.Spike2RecordingExtractor` object: .. code:: ipython3 diff --git a/doc/modules/core.rst b/doc/modules/core.rst index b10ae14a99..fcc92b5a6e 100644 --- a/doc/modules/core.rst +++ b/doc/modules/core.rst @@ -438,7 +438,7 @@ All computed extensions will be automatically propagated or merged when curating Handling very large datasets: ``lazy`` mode -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For very large datasets with tens-to-hundreds millions of spikes, the :code:`SortingAnalyzer` computations can be very memory intensive. By default, in fact, the :code:`SortingAnalyzer` computes and stores all the data in memory. @@ -1007,7 +1007,7 @@ LEGACY objects -------------- WaveformExtractor -^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~ This is now a legacy object that can still be accessed through the :py:class:`MockWaveformExtractor`. It is kept for backward compatibility. You can convert a ``WaveformExtractor`` to a ``SortingAnalyzer`` diff --git a/doc/modules/curation.rst b/doc/modules/curation.rst index d9b877c9da..0ce4edcc94 100644 --- a/doc/modules/curation.rst +++ b/doc/modules/curation.rst @@ -139,6 +139,7 @@ which applies a set of thresholds based on the available metrics (template/quali fail_label="bad", column_name="simple_threshold" ) + The returned ``labels`` is a ``pandas.DataFrame`` with the unit_ids as index and the assigned labels in the ``simple_threshold`` column. diff --git a/doc/modules/metrics.rst b/doc/modules/metrics.rst index 1095553852..a9b9e920a9 100644 --- a/doc/modules/metrics.rst +++ b/doc/modules/metrics.rst @@ -85,7 +85,7 @@ metric information. For example, you can get the list of available metrics and t 'velocity_above': 'Velocity of the spike propagation above the max channel in um/ms', 'velocity_below': 'Velocity of the spike propagation below the max channel in um/ms', 'waveform_baseline_flatness': 'Ratio of max baseline amplitude to max waveform amplitude. Lower = flatter baseline.' -} + } diff --git a/examples/how_to/read_various_formats.py b/examples/how_to/read_various_formats.py index b1fe277d92..eb97177408 100644 --- a/examples/how_to/read_various_formats.py +++ b/examples/how_to/read_various_formats.py @@ -57,7 +57,7 @@ print(isinstance(recording, si.BaseRecording)) ############################################################################## -# The :py:func:`~spikeinterface.extractors.read_spike2`` function is equivalent to instantiating a +# The :py:func:`~spikeinterface.extractors.read_spike2` function is equivalent to instantiating a # :py:class:`~spikeinterface.extractors.Spike2RecordingExtractor` object: # diff --git a/examples/tutorials/core/plot_2_sorting_extractor.py b/examples/tutorials/core/plot_2_sorting_extractor.py index b3ea82c77a..026547af28 100644 --- a/examples/tutorials/core/plot_2_sorting_extractor.py +++ b/examples/tutorials/core/plot_2_sorting_extractor.py @@ -57,14 +57,15 @@ # Some extractors also implement a :code:`write` function. We can for example # save our newly created sorting object to NPZ format (a simple format based # on numpy used in :code:`spikeinterface`): +from spikeinterface.core.npzsortingextractor import NpzSortingExtractor file_path = "my_sorting.npz" -se.NpzSortingExtractor.write_sorting(sorting, file_path) +NpzSortingExtractor.write_sorting(sorting, file_path) ############################################################################## # We can now read it back with the proper extractor: -sorting2 = se.NpzSortingExtractor(file_path) +sorting2 = NpzSortingExtractor(file_path) print(sorting2) ############################################################################## diff --git a/src/spikeinterface/core/__init__.py b/src/spikeinterface/core/__init__.py index 9b9c411079..72222753f7 100644 --- a/src/spikeinterface/core/__init__.py +++ b/src/spikeinterface/core/__init__.py @@ -17,7 +17,7 @@ NumpyEvent, NumpySnippets, ) -from .zarrextractors import ZarrRecordingExtractor, ZarrSortingExtractor, read_zarr, get_default_zarr_compressor +from .zarrextractors import read_zarr, read_zarr_array, get_default_zarr_compressor from .binaryfolder import BinaryFolderRecording, read_binary_folder from .sortingfolder import NumpyFolderSorting, NpzFolderSorting, read_numpy_sorting_folder, read_npz_folder from .npysnippetsextractor import NpySnippetsExtractor, read_npy_snippets diff --git a/src/spikeinterface/core/baserecording.py b/src/spikeinterface/core/baserecording.py index 2358df456b..772c026ccc 100644 --- a/src/spikeinterface/core/baserecording.py +++ b/src/spikeinterface/core/baserecording.py @@ -317,6 +317,7 @@ def save(self, format="binary", verbose: bool = False, **save_kwargs): ---------- format : str, default: "binary" The format to save the recording in. Options are: + - "binary": Saves the recording in binary format. - "zarr": Saves the recording in Zarr format. - "memory": Saves the recording in memory (shared memory or numpy array). @@ -351,13 +352,17 @@ def save(self, format="binary", verbose: bool = False, **save_kwargs): Global filters for zarr (global) - compressor_by_dataset: dict or None, default: None Optional compressor per dataset: + - traces - times + If None, the global compressor is used - filters_by_dataset: dict or None, default: None Optional filters per dataset: + - traces - times + If None, the global filters are used * "memory" format: - sharedmem : bool, default: True diff --git a/src/spikeinterface/core/basesorting.py b/src/spikeinterface/core/basesorting.py index e3bbf68424..1e136f2dff 100644 --- a/src/spikeinterface/core/basesorting.py +++ b/src/spikeinterface/core/basesorting.py @@ -522,6 +522,7 @@ def save(self, format="numpy_folder", **save_kwargs): ---------- format : str, default: "numpy_folder" The format to save the sorting in. Options are: + - "numpy_folder": Saves the sorting in a binary numpy folder format. - "zarr": Saves the sorting in Zarr format. - "memory": Saves the sorting in memory (shared memory or numpy array). diff --git a/src/spikeinterface/core/job_tools.py b/src/spikeinterface/core/job_tools.py index 737fc1c668..59af6fd254 100644 --- a/src/spikeinterface/core/job_tools.py +++ b/src/spikeinterface/core/job_tools.py @@ -21,7 +21,9 @@ ) _shared_job_kwargs_doc = """**job_kwargs : keyword arguments for parallel processing: + * chunk_duration or chunk_size or chunk_memory or total_memory + - chunk_size : int Number of samples per chunk - chunk_memory : str @@ -30,12 +32,15 @@ Total memory usage (e.g. "500M", "2G") - chunk_duration : str or float or None Chunk duration in s if float or with units if str (e.g. "1s", "500ms") + * n_jobs : int | float Number of workers that will be requested during multiprocessing. Note that the OS determines how this is distributed, but for convenience one can use + * -1 the number of workers is the same as the number of cores available to this process, respecting CPU affinity restrictions where possible * float between 0 and 1 uses a fraction of that core count + * progress_bar : bool If True, a progress bar is printed * mp_context : "fork" | "spawn" | None, default: None diff --git a/src/spikeinterface/core/sortinganalyzer.py b/src/spikeinterface/core/sortinganalyzer.py index 0a75bf7c1a..7cdf66fb98 100644 --- a/src/spikeinterface/core/sortinganalyzer.py +++ b/src/spikeinterface/core/sortinganalyzer.py @@ -2718,8 +2718,8 @@ def get_metrics_extension_data(self): metrics_df : pandas.DataFrame A concatenated dataframe with all available metrics. - Note - ---- + Notes + ----- Duplicated columns are removed (can happen if several metric extensions have a metric with the same name). """ import pandas as pd diff --git a/src/spikeinterface/core/tests/test_zarrextractors.py b/src/spikeinterface/core/tests/test_zarrextractors.py index 7e58898a6e..6278541698 100644 --- a/src/spikeinterface/core/tests/test_zarrextractors.py +++ b/src/spikeinterface/core/tests/test_zarrextractors.py @@ -4,13 +4,16 @@ import zarr from spikeinterface.core import ( - ZarrRecordingExtractor, - ZarrSortingExtractor, generate_recording, generate_sorting, load, ) -from spikeinterface.core.zarrextractors import add_sorting_to_zarr_group, get_default_zarr_compressor +from spikeinterface.core.zarrextractors import ( + ZarrRecordingExtractor, + ZarrSortingExtractor, + add_sorting_to_zarr_group, + get_default_zarr_compressor, +) def test_zarr_compression_options(tmp_path): diff --git a/src/spikeinterface/extractors/extractor_classes.py b/src/spikeinterface/extractors/extractor_classes.py index 1e9f5f6784..a2b11726a8 100644 --- a/src/spikeinterface/extractors/extractor_classes.py +++ b/src/spikeinterface/extractors/extractor_classes.py @@ -6,15 +6,17 @@ NpzSortingExtractor, NumpySorting, NpySnippetsExtractor, - ZarrRecordingExtractor, - ZarrSortingExtractor, read_binary, read_zarr, read_npz_sorting, read_npy_snippets, ) -from spikeinterface.core.zarrextractors import read_zarr_array +from spikeinterface.core.zarrextractors import ( + ZarrRecordingExtractor, + ZarrSortingExtractor, + read_zarr_array, +) # sorting/recording/event from neo from .neoextractors import * diff --git a/src/spikeinterface/postprocessing/valid_unit_periods.py b/src/spikeinterface/postprocessing/valid_unit_periods.py index cccec63842..214ebb5efc 100644 --- a/src/spikeinterface/postprocessing/valid_unit_periods.py +++ b/src/spikeinterface/postprocessing/valid_unit_periods.py @@ -39,8 +39,8 @@ class ComputeValidUnitPeriods(AnalyzerExtension): period_duration_s_absolute : float, default: 10.0 Duration of individual periods used to define good periods, in seconds. Same across all units. Note: the margin size will be the same as the period size. - A period size of 10s sets the margin to 10s, which means that periods of 10+2*10=30s are used - to estimate the false positive and negative rates of the central 10s. + A period size of 10s sets the margin to 10s, which means that periods of 10+2*10=30s are used + to estimate the false positive and negative rates of the central 10s. period_target_num_spikes : int | None, default: 300 Alternative to period_size_absolute, different for each unit: mean number of spikes that should be present in each estimation period. For neurons firing at 10 Hz, this would correspond to periods of 10s (100 spikes / 10 Hz = 10s). diff --git a/src/spikeinterface/preprocessing/decimate.py b/src/spikeinterface/preprocessing/decimate.py index 9462922806..294a3e00f3 100644 --- a/src/spikeinterface/preprocessing/decimate.py +++ b/src/spikeinterface/preprocessing/decimate.py @@ -52,8 +52,9 @@ class DecimateRecording(BasePreprocessor): ------- decimate_recording: DecimateRecording The decimated recording extractor object. With `antialias=False` the full traces of the - child recording segment correspond to the traces of the parent segment as follows: - ``` = [::]``` + child recording segment correspond to the traces of the parent segment as follows:: + + = [::] """ From 5ec9f79ced5f833a2405028709479e45cfe70f0a Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Fri, 18 Sep 2026 12:01:04 +0200 Subject: [PATCH 6/7] fix: examples plots --- .../core/plot_1_recording_extractor.py | 13 ++++---- .../core/plot_2_sorting_extractor.py | 30 +++++++++---------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/examples/tutorials/core/plot_1_recording_extractor.py b/examples/tutorials/core/plot_1_recording_extractor.py index 42143b50c8..a3143161b2 100644 --- a/examples/tutorials/core/plot_1_recording_extractor.py +++ b/examples/tutorials/core/plot_1_recording_extractor.py @@ -5,7 +5,7 @@ The :py:class:`~spikeinterface.core.BaseRecording` is the basic class for handling recorded data. Here is how it works. -A BaseRecording handles: +A RecordingExtractor handles: * traces retrieval across segments * dumping to/loading from dict-json @@ -20,7 +20,7 @@ import spikeinterface.extractors as se ############################################################################## -# We will create a :code:`BaseRecording` object from scratch using :code:`numpy` and the +# We will create a :code:`RecordingExtractor` object from scratch using :code:`numpy` and the # :py:class:`~spikeinterface.core.NumpyRecording`. # # Let's define the properties of the dataset: @@ -46,7 +46,7 @@ print(recording) ############################################################################## -# We can now print properties that the :code:`BaseRecording` retrieves from the underlying recording. +# We can now print properties that the :code:`RecordingExtractor` retrieves from the underlying recording. print(f"Number of channels = {len(recording.get_channel_ids())}") print(f"Sampling frequency = {recording.get_sampling_frequency()} Hz") @@ -75,16 +75,17 @@ ############################################################################## # Some extractors also implement a :code:`write` function. - +from spikeinterface.core.binaryrecordingextractor import BinaryRecordingExtractor file_paths = ["traces0.raw", "traces1.raw"] -se.BinaryBaseRecording.write_recording(recording, file_paths) + +BinaryRecordingExtractor.write_recording(recording, file_paths) ############################################################################## # We can read the written recording back with the proper extractor. # Note that this new recording is now "on disk" and not "in memory" as the Numpy recording was. # This means that the loading is "lazy" and the data are not loaded into memory. -recording2 = se.BinaryBaseRecording( +recording2 = BinaryRecordingExtractor( file_paths=file_paths, sampling_frequency=sampling_frequency, num_channels=num_channels, dtype=traces0.dtype ) print(recording2) diff --git a/examples/tutorials/core/plot_2_sorting_extractor.py b/examples/tutorials/core/plot_2_sorting_extractor.py index ebfbffddb7..026547af28 100644 --- a/examples/tutorials/core/plot_2_sorting_extractor.py +++ b/examples/tutorials/core/plot_2_sorting_extractor.py @@ -5,7 +5,7 @@ The :py:class:`~spikeinterface.core.BaseSorting` is the basic class for handling spike sorted data. Here is how it works. -A BaseSorting handles: +A SortingExtractor handles: * spike trains retrieval across segments * dumping to/loading from dict-json @@ -14,11 +14,10 @@ """ import numpy as np -import spikeinterface.core as si import spikeinterface.extractors as se ############################################################################## -# We will create a :code:`BaseSorting` object from scratch using :code:`numpy` and the +# We will create a :code:`SortingExtractor` object from scratch using :code:`numpy` and the # :py:class:`~spikeinterface.core.NumpySorting` # # Let's define the properties of the dataset: @@ -45,7 +44,7 @@ print(sorting) ############################################################################## -# We can now print properties that the :code:`BaseSorting` retrieves from +# We can now print properties that the :code:`SortingExtractor` retrieves from # the underlying sorted dataset. print("Unit ids = {}".format(sorting.get_unit_ids())) @@ -55,23 +54,24 @@ print("Num. events for first second of unit 1 seg1 = {}".format(len(st1))) ############################################################################## -# The :code:`BaseSorting` object implements the :code:`save` method. We can for example -# save our newly created sorting object to the "numpy_foler" format -# (a simple format based on numpy used in :code:`spikeinterface`): +# Some extractors also implement a :code:`write` function. We can for example +# save our newly created sorting object to NPZ format (a simple format based +# on numpy used in :code:`spikeinterface`): +from spikeinterface.core.npzsortingextractor import NpzSortingExtractor -folder_path = "my_sorting" -sorting.save(format="numpy_folder", folder=folder_path) +file_path = "my_sorting.npz" +NpzSortingExtractor.write_sorting(sorting, file_path) ############################################################################## -# We can now read it back with the load function: +# We can now read it back with the proper extractor: -sorting2 = si.load(folder_path) +sorting2 = NpzSortingExtractor(file_path) print(sorting2) ############################################################################## # Unit properties are key value pairs that we can store for any unit. # We will now calculate unit firing rates and add them as properties to -# the :code:`BaseSorting` object: +# the :code:`SortingExtractor` object: firing_rates = [] for unit_id in sorting2.get_unit_ids(): @@ -128,11 +128,11 @@ # :code:`save()` function: -sorting2.save(folder="./my_sorting_with_spike_trains") +sorting2.save(folder="./my_sorting") import os -pprint(os.listdir("./my_sorting_with_spike_trains")) +pprint(os.listdir("./my_sorting")) -sorting2_cached = load("./my_sorting_with_spike_trains") +sorting2_cached = load("./my_sorting") print(sorting2_cached) From 030cb2c0a582ee4ef078125c7cb5e5db0184b54c Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Fri, 18 Sep 2026 12:22:16 +0200 Subject: [PATCH 7/7] fix: remove explicit member functions from api --- doc/api.rst | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/doc/api.rst b/doc/api.rst index ac6ac683a9..335bc186aa 100755 --- a/doc/api.rst +++ b/doc/api.rst @@ -8,36 +8,10 @@ spikeinterface.core .. autofunction:: load .. autoclass:: BaseRecording :members: - .. automethod:: BaseRecording.save_to_memory - .. automethod:: BaseRecording.save_to_folder - .. automethod:: BaseRecording.save_to_zarr - .. automethod:: BaseRecording.dump - .. automethod:: BaseRecording.dump_to_json - .. automethod:: BaseRecording.dump_to_pickle - .. automethod:: BaseRecording.remove_channels - .. automethod:: BaseRecording.set_probe - .. automethod:: BaseRecording.set_probegroup - .. automethod:: BaseRecording.remove_probe - .. automethod:: BaseRecording.select_channels_with_probe - .. automethod:: BaseRecording.select_channels_with_probegroup - .. automethod:: BaseRecording.split_by .. autoclass:: BaseSorting :members: - .. automethod:: BaseSorting.save_to_memory - .. automethod:: BaseSorting.save_to_folder - .. automethod:: BaseSorting.save_to_zarr - .. automethod:: BaseSorting.dump - .. automethod:: BaseSorting.dump_to_json - .. automethod:: BaseSorting.dump_to_pickle .. autoclass:: BaseSnippets :members: - .. automethod:: BaseSnippets.save_to_memory - .. automethod:: BaseSnippets.save_to_folder - .. automethod:: BaseSnippets.save_to_zarr - .. automethod:: BaseSnippets.dump - .. automethod:: BaseSnippets.dump_to_json - .. automethod:: BaseSnippets.dump_to_pickle - .. automethod:: BaseSnippets.remove_channels .. autoclass:: BaseEvent :members: .. autoclass:: SortingAnalyzer