From 78309783cbaa60eb5f979d0c771552f129cde92b Mon Sep 17 00:00:00 2001 From: Charlie Windolf Date: Mon, 18 May 2026 17:23:16 -0400 Subject: [PATCH 01/11] Remove strategy from NoiseGeneratorRecording --- src/spikeinterface/generation/noise_tools.py | 51 ++++---------------- 1 file changed, 9 insertions(+), 42 deletions(-) diff --git a/src/spikeinterface/generation/noise_tools.py b/src/spikeinterface/generation/noise_tools.py index f64a8abe72..55bd03b694 100644 --- a/src/spikeinterface/generation/noise_tools.py +++ b/src/spikeinterface/generation/noise_tools.py @@ -1,5 +1,4 @@ import numpy as np -from typing import Literal from spikeinterface.core import BaseRecording, BaseRecordingSegment from spikeinterface.core.generate import _ensure_seed @@ -33,12 +32,6 @@ class NoiseGeneratorRecording(BaseRecording): The dtype of the recording. Note that only np.float32 and np.float64 are supported. seed : int | None, default: None The seed for np.random.default_rng. - strategy : "tile_pregenerated" | "on_the_fly", default: "tile_pregenerated" - The strategy of generating noise chunk: - * "tile_pregenerated": pregenerate a noise chunk of noise_block_size sample and repeat it - very fast and cusume only one noise block. - * "on_the_fly": generate on the fly a new noise block by combining seed + noise block index - no memory preallocation but a bit more computaion (random) noise_block_size : int, default: 30000 Size in sample of noise block. @@ -57,7 +50,6 @@ def __init__( cov_matrix: np.ndarray | None = None, dtype: np.dtype | str | None = "float32", seed: int | None = None, - strategy: Literal["tile_pregenerated", "on_the_fly"] = "tile_pregenerated", noise_block_size: int = 30000, ): @@ -65,7 +57,6 @@ def __init__( dtype = np.dtype(dtype).name # Cast to string for serialization if dtype not in ("float32", "float64"): raise ValueError(f"'dtype' must be 'float32' or 'float64' but is {dtype}") - assert strategy in ("tile_pregenerated", "on_the_fly"), "'strategy' must be 'tile_pregenerated' or 'on_the_fly'" if np.isscalar(noise_levels): noise_levels = np.ones((1, num_channels)) * noise_levels @@ -103,7 +94,6 @@ def __init__( cov_matrix, dtype, segments_seeds[i], - strategy, ) self.add_recording_segment(rec_segment) @@ -115,7 +105,6 @@ def __init__( "cov_matrix": cov_matrix, "dtype": dtype, "seed": seed, - "strategy": strategy, "noise_block_size": noise_block_size, } @@ -131,7 +120,6 @@ def __init__( cov_matrix, dtype, seed, - strategy, ): assert seed is not None @@ -144,23 +132,6 @@ def __init__( self.cov_matrix = cov_matrix self.dtype = dtype self.seed = seed - self.strategy = strategy - - if self.strategy == "tile_pregenerated": - rng = np.random.default_rng(seed=self.seed) - - if self.cov_matrix is None: - self.noise_block = ( - rng.standard_normal(size=(self.noise_block_size, self.num_channels), dtype=self.dtype) - * noise_levels - ) - else: - self.noise_block = rng.multivariate_normal( - np.zeros(self.num_channels), self.cov_matrix, size=self.noise_block_size - ) - - elif self.strategy == "on_the_fly": - pass def get_num_samples(self) -> int: return self.num_samples @@ -169,7 +140,7 @@ def get_traces( self, start_frame: int | None = None, end_frame: int | None = None, - channel_indices: list | None = None, + channel_indices: list | np.ndarray | tuple | None = None, ) -> np.ndarray: if start_frame is None: @@ -188,18 +159,15 @@ def get_traces( pos = 0 for block_index in range(first_block_index, last_block_index + 1): - if self.strategy == "tile_pregenerated": - noise_block = self.noise_block - elif self.strategy == "on_the_fly": - rng = np.random.default_rng(seed=(self.seed, block_index)) - if self.cov_matrix is None: - noise_block = rng.standard_normal(size=(self.noise_block_size, self.num_channels), dtype=self.dtype) - else: - noise_block = rng.multivariate_normal( - np.zeros(self.num_channels), self.cov_matrix, size=self.noise_block_size - ) + rng = np.random.default_rng(seed=(self.seed, block_index)) + if self.cov_matrix is None: + noise_block = rng.standard_normal(size=(self.noise_block_size, self.num_channels), dtype=self.dtype) + else: + noise_block = rng.multivariate_normal( + np.zeros(self.num_channels), self.cov_matrix, size=self.noise_block_size + ) - noise_block *= self.noise_levels + noise_block *= self.noise_levels if block_index == first_block_index: if first_block_index != last_block_index: @@ -284,7 +252,6 @@ def generate_noise( sampling_frequency=sampling_frequency, durations=durations, dtype=dtype, - strategy="on_the_fly", noise_levels=noise_levels, cov_matrix=cov_matrix, seed=seed, From 3282876865e825608493065f529338897843c823 Mon Sep 17 00:00:00 2001 From: Charlie Windolf Date: Mon, 18 May 2026 17:42:26 -0400 Subject: [PATCH 02/11] Add spectral_density (impl. with a wrapper segment) --- src/spikeinterface/generation/noise_tools.py | 65 ++++++++++++++++++- .../generation/tests/test_noise_tools.py | 58 +++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/src/spikeinterface/generation/noise_tools.py b/src/spikeinterface/generation/noise_tools.py index 55bd03b694..579fca994b 100644 --- a/src/spikeinterface/generation/noise_tools.py +++ b/src/spikeinterface/generation/noise_tools.py @@ -3,6 +3,8 @@ from spikeinterface.core import BaseRecording, BaseRecordingSegment from spikeinterface.core.generate import _ensure_seed from spikeinterface.core.core_tools import define_function_from_class +from spikeinterface.preprocessing.basepreprocessor import BasePreprocessorSegment +from spikeinterface.core.recording_tools import get_chunk_with_margin class NoiseGeneratorRecording(BaseRecording): @@ -28,6 +30,14 @@ class NoiseGeneratorRecording(BaseRecording): Std of the white noise (if an array, defined by per channels) cov_matrix : np.ndarray | None, default: None The covariance matrix of the noise + spectral_density : np.ndarray | None, default: None + The spectral density of the noise, as you could estimate from an array of snippets with shape + `(n_snippets, spectral_snippet_length)` by the following method (Welch's method): + + ```python + periodogram = rfft(snippets, n=next_fast_len(snippets.shape[1]), norm="ortho") + spectral_density = np.sqrt((periodogram * periodogram.conj()).mean(axis=0)) + ``` dtype : np.dtype | str | None, default: "float32" The dtype of the recording. Note that only np.float32 and np.float64 are supported. seed : int | None, default: None @@ -48,6 +58,7 @@ def __init__( durations: list[float], noise_levels: float | np.ndarray = 1.0, cov_matrix: np.ndarray | None = None, + spectral_density: np.ndarray | None = None, dtype: np.dtype | str | None = "float32", seed: int | None = None, noise_block_size: int = 30000, @@ -95,6 +106,10 @@ def __init__( dtype, segments_seeds[i], ) + if spectral_density is not None: + rec_segment = AddTemporalCorrelationsSegment( + rec_segment, spectral_density + ) self.add_recording_segment(rec_segment) self._kwargs = { @@ -190,13 +205,52 @@ def get_traces( return traces +class AddTemporalCorrelationsSegment(BasePreprocessorSegment): + def __init__(self, parent_recording_segment, spectral_density: np.ndarray): + super().__init__(parent_recording_segment) + assert spectral_density.ndim == 1 + self.spectral_density = spectral_density + self.margin = spectral_density.shape[0] - 1 + self.block_len = 2 * spectral_density.shape[0] - 1 + self.kernel = np.fft.fftshift(np.fft.irfft(spectral_density, n=self.block_len)) + + def get_traces( + self, + start_frame: int | None = None, + end_frame: int | None = None, + channel_indices: list | np.ndarray | tuple | None = None, + ): + from scipy.signal import convolve + + traces = get_chunk_with_margin( + self.parent_recording_segment, + start_frame=start_frame, + end_frame=end_frame, + channel_indices=channel_indices, + margin=self.margin, + add_reflect_padding=True, + ) + # need to use "direct", or else output differs numerically when start_frame, end_frame change + # that's because the FFT method would FFT the traces, and there would be slight numerical differences + traces = convolve(traces.T, self.kernel[None], mode="valid", method="direct").T + return traces + + + noise_generator_recording = define_function_from_class( source_class=NoiseGeneratorRecording, name="noise_generator_recording" ) def generate_noise( - probe, sampling_frequency, durations, dtype="float32", noise_levels=15.0, spatial_decay=None, seed=None + probe, + sampling_frequency, + durations, + dtype="float32", + noise_levels=15.0, + spatial_decay=None, + spectral_density=None, + seed=None, ): """ Generate a noise recording. @@ -217,6 +271,14 @@ def generate_noise( If tuple, then this represent the range. spatial_decay : float | None, default: None If not None, the spatial decay of the noise used to generate the noise covariance matrix. + spectral_density : np.ndarray | None, default: None + The spectral density of the noise, as you could estimate from an array of snippets with shape + `(n_snippets, spectral_snippet_length)` by the following method (Welch's method): + + ```python + periodogram = rfft(snippets, n=next_fast_len(snippets.shape[1]), norm="ortho") + spectral_density = np.sqrt((periodogram * periodogram.conj()).mean(axis=0)) + ``` seed : int | None, default: None The seed for random generator. @@ -254,6 +316,7 @@ def generate_noise( dtype=dtype, noise_levels=noise_levels, cov_matrix=cov_matrix, + spectral_density=spectral_density, seed=seed, ) diff --git a/src/spikeinterface/generation/tests/test_noise_tools.py b/src/spikeinterface/generation/tests/test_noise_tools.py index f633ed1de4..3463f91aae 100644 --- a/src/spikeinterface/generation/tests/test_noise_tools.py +++ b/src/spikeinterface/generation/tests/test_noise_tools.py @@ -1,7 +1,10 @@ +import numpy as np import probeinterface +import pytest from spikeinterface.generation import ( generate_noise, + NoiseGeneratorRecording, ) @@ -40,5 +43,60 @@ def test_generate_noise(): # plt.show() +@pytest.mark.parametrize("duration", [1.0, 2.0, 2.2]) +def test_noise_generator_temporal(duration): + psdlen = 25 + kdomain = np.linspace(0.0, 10.0, psdlen) + fake_psd = (kdomain + 0.1) * np.exp(-kdomain) + # this ensures std dev of output ~= 1 + fake_psd /= np.sqrt((fake_psd**2).mean()) + + # Test that the recording has the correct size in shape + sampling_frequency = 30000 # Hz + durations = [duration] + dtype = np.dtype("float32") + num_channels = 2 + seed = 0 + + rec = NoiseGeneratorRecording( + num_channels=num_channels, + sampling_frequency=sampling_frequency, + durations=durations, + dtype=dtype, + seed=seed, + spectral_density=fake_psd, + ) + + # check output matches at different chunks + full_traces = rec.get_traces() + end_frame = rec.get_num_frames() + for t0 in [0, 100]: + for t1 in [end_frame, end_frame - 100]: + chk = rec.get_traces(0, t0, t1) + chk0 = full_traces[t0:t1] + np.testing.assert_array_equal(chk, chk0) + + np.testing.assert_allclose(full_traces.std(), 1.0, rtol=0.02) + + # re-estimate the psd from the result + # it will not be perfect, okay! + n = 2 * psdlen - 1 + snips = full_traces[: n * (full_traces.shape[0] // n)] + snips = snips.reshape(-1, n, snips.shape[-1]) + psd = np.fft.rfft(snips, n=n, axis=1, norm="ortho") + psd = np.sqrt(np.square(np.abs(psd)).mean(axis=(0, 2))) + + sample_size = snips.shape[0] * snips.shape[2] + standard_error = 1.0 / np.sqrt(sample_size) + + # accuracy is good at low freqs + np.testing.assert_allclose( + psd[1 : psdlen // 3], + fake_psd[1 : psdlen // 3], + atol=3 * standard_error, + rtol=0.1, + ) + np.testing.assert_allclose(psd, fake_psd, atol=0.5) + if __name__ == "__main__": test_generate_noise() From 6ee700d12a6ec05ed8a518089e1658807ec7125e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 May 2026 21:51:54 +0000 Subject: [PATCH 03/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/spikeinterface/generation/noise_tools.py | 5 +---- src/spikeinterface/generation/tests/test_noise_tools.py | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/spikeinterface/generation/noise_tools.py b/src/spikeinterface/generation/noise_tools.py index 579fca994b..89de50eab2 100644 --- a/src/spikeinterface/generation/noise_tools.py +++ b/src/spikeinterface/generation/noise_tools.py @@ -107,9 +107,7 @@ def __init__( segments_seeds[i], ) if spectral_density is not None: - rec_segment = AddTemporalCorrelationsSegment( - rec_segment, spectral_density - ) + rec_segment = AddTemporalCorrelationsSegment(rec_segment, spectral_density) self.add_recording_segment(rec_segment) self._kwargs = { @@ -236,7 +234,6 @@ def get_traces( return traces - noise_generator_recording = define_function_from_class( source_class=NoiseGeneratorRecording, name="noise_generator_recording" ) diff --git a/src/spikeinterface/generation/tests/test_noise_tools.py b/src/spikeinterface/generation/tests/test_noise_tools.py index 3463f91aae..476b95631d 100644 --- a/src/spikeinterface/generation/tests/test_noise_tools.py +++ b/src/spikeinterface/generation/tests/test_noise_tools.py @@ -98,5 +98,6 @@ def test_noise_generator_temporal(duration): ) np.testing.assert_allclose(psd, fake_psd, atol=0.5) + if __name__ == "__main__": test_generate_noise() From 6809fb0a9cad2d24a1eb6f73885df0b7500afedc Mon Sep 17 00:00:00 2001 From: Charlie Windolf Date: Tue, 19 May 2026 10:01:16 -0400 Subject: [PATCH 04/11] tests: Removing some stray strategy args to the NoiseGeneratorRecording --- src/spikeinterface/core/generate.py | 2 +- src/spikeinterface/core/tests/test_generate.py | 2 -- src/spikeinterface/curation/tests/common.py | 2 +- src/spikeinterface/exporters/tests/common.py | 2 +- src/spikeinterface/extractors/toy_example.py | 2 +- .../sortingcomponents/motion/tests/test_motion_interpolation.py | 2 +- src/spikeinterface/sortingcomponents/tests/common.py | 2 +- src/spikeinterface/widgets/tests/test_widgets.py | 2 +- 8 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/spikeinterface/core/generate.py b/src/spikeinterface/core/generate.py index 1470473fe2..d5afca9bc1 100644 --- a/src/spikeinterface/core/generate.py +++ b/src/spikeinterface/core/generate.py @@ -2286,7 +2286,7 @@ def generate_ground_truth_recording( upsample_factor=None, upsample_vector=None, generate_sorting_kwargs=dict(firing_rates=15, refractory_period_ms=4.0), - noise_kwargs=dict(noise_levels=5.0, strategy="on_the_fly"), + noise_kwargs=dict(noise_levels=5.0), generate_unit_locations_kwargs=dict(margin_um=10.0, minimum_z=5.0, maximum_z=50.0, minimum_distance=20), generate_templates_kwargs=None, dtype="float32", diff --git a/src/spikeinterface/core/tests/test_generate.py b/src/spikeinterface/core/tests/test_generate.py index c5a0b83f87..09849583dd 100644 --- a/src/spikeinterface/core/tests/test_generate.py +++ b/src/spikeinterface/core/tests/test_generate.py @@ -220,7 +220,6 @@ def test_noise_generator_several_noise_levels(): dtype="float32", seed=32, noise_levels=1, - strategy="on_the_fly", noise_block_size=20000, ) assert np.all(np.abs(get_noise_levels(rec1) - 1) < 0.1) @@ -232,7 +231,6 @@ def test_noise_generator_several_noise_levels(): dtype="float32", seed=32, noise_levels=[0, 1, 2, 3], - strategy="on_the_fly", noise_block_size=20000, ) assert np.all(np.abs(get_noise_levels(rec2) - np.arange(4)) < 0.1) diff --git a/src/spikeinterface/curation/tests/common.py b/src/spikeinterface/curation/tests/common.py index a665b074a6..662dfdaa78 100644 --- a/src/spikeinterface/curation/tests/common.py +++ b/src/spikeinterface/curation/tests/common.py @@ -25,7 +25,7 @@ def make_sorting_analyzer(sparse=True, num_units=5, durations=[300.0]): num_channels=4, num_units=num_units, generate_sorting_kwargs=dict(firing_rates=20.0, refractory_period_ms=4.0), - noise_kwargs=dict(noise_levels=5.0, strategy="on_the_fly"), + noise_kwargs=dict(noise_levels=5.0), seed=2205, ) diff --git a/src/spikeinterface/exporters/tests/common.py b/src/spikeinterface/exporters/tests/common.py index d86df0c6c8..186f850b88 100644 --- a/src/spikeinterface/exporters/tests/common.py +++ b/src/spikeinterface/exporters/tests/common.py @@ -18,7 +18,7 @@ def make_sorting_analyzer(sparse=True, with_group=False): contact_shape_params={"radius": 6}, ), generate_sorting_kwargs=dict(firing_rates=10.0, refractory_period_ms=4.0), - noise_kwargs=dict(noise_levels=5.0, strategy="on_the_fly"), + noise_kwargs=dict(noise_levels=5.0), seed=2205, ) diff --git a/src/spikeinterface/extractors/toy_example.py b/src/spikeinterface/extractors/toy_example.py index 626ea0050a..fb028a5707 100644 --- a/src/spikeinterface/extractors/toy_example.py +++ b/src/spikeinterface/extractors/toy_example.py @@ -155,7 +155,7 @@ def toy_example( ms_after=ms_after, dtype="float32", seed=seed, - noise_kwargs=dict(noise_levels=10.0, strategy="on_the_fly"), + noise_kwargs=dict(noise_levels=10.0), ) return recording, sorting diff --git a/src/spikeinterface/sortingcomponents/motion/tests/test_motion_interpolation.py b/src/spikeinterface/sortingcomponents/motion/tests/test_motion_interpolation.py index 9635bad48b..7c232a4328 100644 --- a/src/spikeinterface/sortingcomponents/motion/tests/test_motion_interpolation.py +++ b/src/spikeinterface/sortingcomponents/motion/tests/test_motion_interpolation.py @@ -241,7 +241,7 @@ def test_InterpolateMotionRecording(): contact_shape_params={"radius": 6}, ), generate_sorting_kwargs=dict(firing_rates=6.0, refractory_period_ms=4.0), - noise_kwargs=dict(noise_levels=5.0, strategy="on_the_fly"), + noise_kwargs=dict(noise_levels=5.0), seed=2205, ) diff --git a/src/spikeinterface/sortingcomponents/tests/common.py b/src/spikeinterface/sortingcomponents/tests/common.py index e8bee33794..c691c70f15 100644 --- a/src/spikeinterface/sortingcomponents/tests/common.py +++ b/src/spikeinterface/sortingcomponents/tests/common.py @@ -16,7 +16,7 @@ def make_dataset(): contact_shape_params={"radius": 6}, ), generate_sorting_kwargs=dict(firing_rates=6.0, refractory_period_ms=4.0), - noise_kwargs=dict(noise_levels=5.0, strategy="on_the_fly"), + noise_kwargs=dict(noise_levels=5.0), seed=2205, ) diff --git a/src/spikeinterface/widgets/tests/test_widgets.py b/src/spikeinterface/widgets/tests/test_widgets.py index c811c386e2..5468b373e9 100644 --- a/src/spikeinterface/widgets/tests/test_widgets.py +++ b/src/spikeinterface/widgets/tests/test_widgets.py @@ -54,7 +54,7 @@ def setUpClass(cls): contact_shape_params={"radius": 6}, ), generate_sorting_kwargs=dict(firing_rates=10.0, refractory_period_ms=4.0), - noise_kwargs=dict(noise_levels=5.0, strategy="on_the_fly"), + noise_kwargs=dict(noise_levels=5.0), seed=2205, ) # cls.recording = recording.save(folder=cache_folder / "recording") From 16257621430c8188cabcb132fae01b8d80c39bc7 Mon Sep 17 00:00:00 2001 From: Charlie Windolf Date: Tue, 19 May 2026 10:08:06 -0400 Subject: [PATCH 05/11] tests: del 'tile_pregenerated' kw to `generate_ground_truth_recording()` --- src/spikeinterface/core/tests/test_analyzer_extension_core.py | 2 +- src/spikeinterface/core/tests/test_sorting_tools.py | 2 +- src/spikeinterface/core/tests/test_sortinganalyzer.py | 2 +- src/spikeinterface/core/tests/test_sparsity.py | 2 +- src/spikeinterface/core/tests/test_template_tools.py | 2 +- src/spikeinterface/core/tests/test_waveform_tools.py | 2 +- .../tests/test_waveforms_extractor_backwards_compatibility.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/spikeinterface/core/tests/test_analyzer_extension_core.py b/src/spikeinterface/core/tests/test_analyzer_extension_core.py index fd550c729e..f0b918af6c 100644 --- a/src/spikeinterface/core/tests/test_analyzer_extension_core.py +++ b/src/spikeinterface/core/tests/test_analyzer_extension_core.py @@ -30,7 +30,7 @@ def get_sorting_analyzer(cache_folder, format="memory", sparse=True): alpha=(200.0, 500.0), ) ), - noise_kwargs=dict(noise_levels=5.0, strategy="tile_pregenerated"), + noise_kwargs=dict(noise_levels=5.0), seed=2406, ) if format == "memory": diff --git a/src/spikeinterface/core/tests/test_sorting_tools.py b/src/spikeinterface/core/tests/test_sorting_tools.py index 4194f459b3..92b68373bf 100644 --- a/src/spikeinterface/core/tests/test_sorting_tools.py +++ b/src/spikeinterface/core/tests/test_sorting_tools.py @@ -52,7 +52,7 @@ def test_random_spikes_selection(): num_channels=10, num_units=5, generate_sorting_kwargs=dict(firing_rates=10.0, refractory_period_ms=4.0), - noise_kwargs=dict(noise_levels=5.0, strategy="tile_pregenerated"), + noise_kwargs=dict(noise_levels=5.0), seed=2205, ) max_spikes_per_unit = 12 diff --git a/src/spikeinterface/core/tests/test_sortinganalyzer.py b/src/spikeinterface/core/tests/test_sortinganalyzer.py index a9bd71b5c0..648c926860 100644 --- a/src/spikeinterface/core/tests/test_sortinganalyzer.py +++ b/src/spikeinterface/core/tests/test_sortinganalyzer.py @@ -31,7 +31,7 @@ def get_dataset(): num_channels=10, num_units=5, generate_sorting_kwargs=dict(firing_rates=10.0, refractory_period_ms=4.0), - noise_kwargs=dict(noise_levels=5.0, strategy="tile_pregenerated"), + noise_kwargs=dict(noise_levels=5.0), seed=2205, ) diff --git a/src/spikeinterface/core/tests/test_sparsity.py b/src/spikeinterface/core/tests/test_sparsity.py index 6e85221621..59f46c5699 100644 --- a/src/spikeinterface/core/tests/test_sparsity.py +++ b/src/spikeinterface/core/tests/test_sparsity.py @@ -152,7 +152,7 @@ def get_dataset(): num_channels=10, num_units=5, generate_sorting_kwargs=dict(firing_rates=10.0, refractory_period_ms=4.0), - noise_kwargs=dict(noise_levels=1.0, strategy="tile_pregenerated"), + noise_kwargs=dict(noise_levels=1.0), seed=2205, ) recording.set_property("group", ["a"] * 5 + ["b"] * 5) diff --git a/src/spikeinterface/core/tests/test_template_tools.py b/src/spikeinterface/core/tests/test_template_tools.py index a28680612a..c6e78c2a37 100644 --- a/src/spikeinterface/core/tests/test_template_tools.py +++ b/src/spikeinterface/core/tests/test_template_tools.py @@ -19,7 +19,7 @@ def get_sorting_analyzer(): sampling_frequency=10_000.0, num_channels=4, num_units=10, - noise_kwargs=dict(noise_levels=5.0, strategy="tile_pregenerated"), + noise_kwargs=dict(noise_levels=5.0), seed=2205, ) recording.annotate(is_filtered=True) diff --git a/src/spikeinterface/core/tests/test_waveform_tools.py b/src/spikeinterface/core/tests/test_waveform_tools.py index 5e0350f833..0d677129ac 100644 --- a/src/spikeinterface/core/tests/test_waveform_tools.py +++ b/src/spikeinterface/core/tests/test_waveform_tools.py @@ -29,7 +29,7 @@ def get_dataset(): num_channels=4, num_units=7, generate_sorting_kwargs=dict(firing_rates=5.0, refractory_period_ms=4.0), - noise_kwargs=dict(noise_levels=1.0, strategy="tile_pregenerated"), + noise_kwargs=dict(noise_levels=1.0), seed=2205, ) return recording, sorting diff --git a/src/spikeinterface/core/tests/test_waveforms_extractor_backwards_compatibility.py b/src/spikeinterface/core/tests/test_waveforms_extractor_backwards_compatibility.py index e75f3be156..702cfc7ad1 100644 --- a/src/spikeinterface/core/tests/test_waveforms_extractor_backwards_compatibility.py +++ b/src/spikeinterface/core/tests/test_waveforms_extractor_backwards_compatibility.py @@ -34,7 +34,7 @@ def get_dataset(): alpha=(100.0, 500.0), ) ), - noise_kwargs=dict(noise_levels=5.0, strategy="tile_pregenerated"), + noise_kwargs=dict(noise_levels=5.0), seed=2406, ) return recording, sorting From 330f50cb5e7b27279373045e74321d3b1ebda894 Mon Sep 17 00:00:00 2001 From: Charlie Windolf Date: Tue, 19 May 2026 10:24:04 -0400 Subject: [PATCH 06/11] tests: remove tile_pregenerated in analyzer extension tests --- .../postprocessing/tests/common_extension_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/postprocessing/tests/common_extension_tests.py b/src/spikeinterface/postprocessing/tests/common_extension_tests.py index e03d54fe74..f565fe6a21 100644 --- a/src/spikeinterface/postprocessing/tests/common_extension_tests.py +++ b/src/spikeinterface/postprocessing/tests/common_extension_tests.py @@ -30,7 +30,7 @@ def get_dataset(): alpha=(100.0, 500.0), ) ), - noise_kwargs=dict(noise_levels=5.0, strategy="tile_pregenerated"), + noise_kwargs=dict(noise_levels=5.0), seed=2205, ) return recording, sorting From c8afd1e05a6ea7b2464507cf36df36d8da3a7469 Mon Sep 17 00:00:00 2001 From: Charlie Windolf Date: Tue, 19 May 2026 10:33:58 -0400 Subject: [PATCH 07/11] tests: del tile_pregenerated in test_multi_extensions --- .../postprocessing/tests/test_multi_extensions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/spikeinterface/postprocessing/tests/test_multi_extensions.py b/src/spikeinterface/postprocessing/tests/test_multi_extensions.py index e3c45fe8ef..820aaad4f6 100644 --- a/src/spikeinterface/postprocessing/tests/test_multi_extensions.py +++ b/src/spikeinterface/postprocessing/tests/test_multi_extensions.py @@ -70,7 +70,7 @@ def get_dataset_to_merge(): num_channels=10, num_units=10, generate_sorting_kwargs=dict(firing_rates=10.0, refractory_period_ms=4.0), - noise_kwargs=dict(noise_levels=5.0, strategy="tile_pregenerated"), + noise_kwargs=dict(noise_levels=5.0), generate_unit_locations_kwargs=dict(margin_um=10.0, minimum_z=2.0, maximum_z=15.0, minimum_distance=20), seed=2205, ) @@ -102,7 +102,7 @@ def get_dataset_to_split(): num_channels=10, num_units=10, generate_sorting_kwargs=dict(firing_rates=10.0, refractory_period_ms=4.0), - noise_kwargs=dict(noise_levels=5.0, strategy="tile_pregenerated"), + noise_kwargs=dict(noise_levels=5.0), seed=2205, ) From 53a5a641e2d7e49bade94be402527dfd5bb84a12 Mon Sep 17 00:00:00 2001 From: Charlie Windolf Date: Tue, 19 May 2026 10:46:07 -0400 Subject: [PATCH 08/11] tests: del tile_pregenerated in test_metrics_functions --- .../metrics/quality/tests/test_metrics_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/metrics/quality/tests/test_metrics_functions.py b/src/spikeinterface/metrics/quality/tests/test_metrics_functions.py index e267b176ce..04b3c068fb 100644 --- a/src/spikeinterface/metrics/quality/tests/test_metrics_functions.py +++ b/src/spikeinterface/metrics/quality/tests/test_metrics_functions.py @@ -84,7 +84,7 @@ def _sorting_analyzer_violations(): sampling_frequency=sorting.sampling_frequency, num_channels=6, sorting=sorting, - noise_kwargs=dict(noise_levels=5.0, strategy="tile_pregenerated"), + noise_kwargs=dict(noise_levels=5.0), seed=2205, ) sorting_analyzer = create_sorting_analyzer(sorting, recording, format="memory", sparse=True) From 608577feec2bbd7c552f9878ec880cab39bdfdb9 Mon Sep 17 00:00:00 2001 From: Charlie Windolf Date: Tue, 19 May 2026 10:59:40 -0400 Subject: [PATCH 09/11] tests: del tile_pregenerated in metrics/conftest --- src/spikeinterface/metrics/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/metrics/conftest.py b/src/spikeinterface/metrics/conftest.py index 5313e763c1..e43a044d2d 100644 --- a/src/spikeinterface/metrics/conftest.py +++ b/src/spikeinterface/metrics/conftest.py @@ -65,7 +65,7 @@ def sorting_analyzer_simple(): alpha=(200.0, 500.0), ) ), - noise_kwargs=dict(noise_levels=5.0, strategy="tile_pregenerated"), + noise_kwargs=dict(noise_levels=5.0), seed=1205, ) From 8c1bb86fceed2ed3aaf35ef3d4428e10971eb157 Mon Sep 17 00:00:00 2001 From: Charlie Windolf Date: Tue, 19 May 2026 11:00:46 -0400 Subject: [PATCH 10/11] tests: del on_the_fly in common_benchmark_testing --- src/spikeinterface/benchmark/tests/common_benchmark_testing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/benchmark/tests/common_benchmark_testing.py b/src/spikeinterface/benchmark/tests/common_benchmark_testing.py index 49f9e9350a..6833babc5f 100644 --- a/src/spikeinterface/benchmark/tests/common_benchmark_testing.py +++ b/src/spikeinterface/benchmark/tests/common_benchmark_testing.py @@ -39,7 +39,7 @@ def make_dataset(job_kwargs={}): contact_shape_params={"radius": 6}, ), generate_sorting_kwargs=dict(firing_rates=6.0, refractory_period_ms=4.0), - noise_kwargs=dict(noise_levels=5.0, strategy="on_the_fly"), + noise_kwargs=dict(noise_levels=5.0), seed=2205, ) From c4a035d411403ba931c55796c1a348e2de0ee758 Mon Sep 17 00:00:00 2001 From: Charlie Windolf Date: Tue, 19 May 2026 11:27:03 -0400 Subject: [PATCH 11/11] noise: forgot that get_chunk_with_margin() -> tuple. also assert length is correct. --- src/spikeinterface/generation/noise_tools.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/spikeinterface/generation/noise_tools.py b/src/spikeinterface/generation/noise_tools.py index 89de50eab2..e3b6a28c47 100644 --- a/src/spikeinterface/generation/noise_tools.py +++ b/src/spikeinterface/generation/noise_tools.py @@ -220,7 +220,12 @@ def get_traces( ): from scipy.signal import convolve - traces = get_chunk_with_margin( + if start_frame is None: + start_frame = 0 + if end_frame is None: + end_frame = self.get_num_samples() + + traces, *_ = get_chunk_with_margin( self.parent_recording_segment, start_frame=start_frame, end_frame=end_frame, @@ -231,6 +236,7 @@ def get_traces( # need to use "direct", or else output differs numerically when start_frame, end_frame change # that's because the FFT method would FFT the traces, and there would be slight numerical differences traces = convolve(traces.T, self.kernel[None], mode="valid", method="direct").T + assert traces.shape[0] == end_frame - start_frame return traces