-
Notifications
You must be signed in to change notification settings - Fork 240
Implement select_sorting_periods in core
#4316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
samuelgarcia
merged 22 commits into
SpikeInterface:main
from
alejoe91:select_sorting_periods_core
Jan 16, 2026
+215
−14
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
3dc5729
Test IBL extractors tests failing for PI update
alejoe91 d1a0532
Merge branch 'main' of github.com:SpikeInterface/spikeinterface
alejoe91 7279b67
wip
alejoe91 1962f21
Fix test for base sorting and propagate to basevector extension
alejoe91 528c82b
Fix tests in quailty metrics
alejoe91 775dda7
Fix retrieval of spikevector features
alejoe91 bb46f27
Update src/spikeinterface/core/sorting_tools.py
alejoe91 121a0b1
Apply suggestion from @chrishalcrow
alejoe91 cbf3213
refactor presence ratio and drift metrics to use periods properly
alejoe91 4409aa5
Fix rp_violations
alejoe91 71f8668
implement firing range and fix drift
alejoe91 1ea0d68
fix naming issue
alejoe91 a86c2d3
remove solved todos
alejoe91 d8e1f90
Merge branch 'main' of github.com:SpikeInterface/spikeinterface into …
alejoe91 3f93f97
Implement select_segment_periods in core
alejoe91 cd85456
remove utils
alejoe91 4f754cb
Merge with main
alejoe91 cbc0986
Fix import
alejoe91 80bc50f
Change base_period_dtype order and fix select_sorting_periods array i…
alejoe91 4c8fa23
fix conflicts
alejoe91 87fbe9a
Merge branch 'main' of github.com:SpikeInterface/spikeinterface into …
alejoe91 7446a43
Use cached get_spike_vector_to_indices
alejoe91 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,9 +3,7 @@ | |
| but check only for BaseRecording general methods. | ||
| """ | ||
|
|
||
| import shutil | ||
| from pathlib import Path | ||
|
|
||
| import time | ||
| import numpy as np | ||
| import pytest | ||
| from numpy.testing import assert_raises | ||
|
|
@@ -17,15 +15,14 @@ | |
| SharedMemorySorting, | ||
| NpzFolderSorting, | ||
| NumpyFolderSorting, | ||
| generate_ground_truth_recording, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we need this in testing sorting ? |
||
| generate_sorting, | ||
| create_sorting_npz, | ||
| generate_sorting, | ||
| load, | ||
| ) | ||
| from spikeinterface.core.base import BaseExtractor | ||
| from spikeinterface.core.base import BaseExtractor, unit_period_dtype | ||
| from spikeinterface.core.testing import check_sorted_arrays_equal, check_sortings_equal | ||
| from spikeinterface.core.generate import generate_sorting | ||
|
|
||
| from spikeinterface.core import generate_recording, generate_ground_truth_recording | ||
|
|
||
|
|
||
| def test_BaseSorting(create_cache_folder): | ||
|
|
@@ -245,6 +242,74 @@ def test_time_slice(): | |
| ) | ||
|
|
||
|
|
||
| def test_select_periods(): | ||
| sampling_frequency = 10_000.0 | ||
| duration = 100 | ||
| num_samples = int(sampling_frequency * duration) | ||
| num_units = 1000 | ||
| sorting = generate_sorting( | ||
| durations=[duration, duration], sampling_frequency=sampling_frequency, num_units=num_units | ||
| ) | ||
|
|
||
| rng = np.random.default_rng() | ||
|
|
||
| # number of random periods | ||
| n_periods = 1_000 | ||
| # generate random periods | ||
| segment_indices = rng.integers(0, sorting.get_num_segments(), n_periods) | ||
| start_samples = rng.integers(0, num_samples, n_periods) | ||
| durations = rng.integers(100, 100_000, n_periods) | ||
| end_samples = start_samples + durations | ||
| valid_periods = end_samples < num_samples | ||
| segment_indices = segment_indices[valid_periods] | ||
| start_samples = start_samples[valid_periods] | ||
| end_samples = end_samples[valid_periods] | ||
| unit_index = rng.integers(0, num_units - 1, len(segment_indices)) | ||
|
|
||
| periods = np.zeros(len(segment_indices), dtype=unit_period_dtype) | ||
| periods["segment_index"] = segment_indices | ||
| periods["start_sample_index"] = start_samples | ||
| periods["end_sample_index"] = end_samples | ||
| periods["unit_index"] = unit_index | ||
| periods = np.sort(periods, order=["segment_index", "start_sample_index"]) | ||
|
|
||
| t_start = time.perf_counter() | ||
| sliced_sorting = sorting.select_periods(periods=periods) | ||
| t_stop = time.perf_counter() | ||
| elapsed = t_stop - t_start | ||
| print(f"select_periods took {elapsed:.2f} seconds for {len(periods)} periods") | ||
|
|
||
| # Check that all spikes in the sliced sorting are within the periods | ||
| for segment_index in range(sorting.get_num_segments()): | ||
| periods_in_segment = periods[periods["segment_index"] == segment_index] | ||
| for unit_index, unit_id in enumerate(sorting.unit_ids): | ||
| spiketrain = sorting.get_unit_spike_train(segment_index=segment_index, unit_id=unit_id) | ||
|
|
||
| periods_for_unit = periods_in_segment[periods_in_segment["unit_index"] == unit_index] | ||
| spiketrain_in_periods = [] | ||
| for period in periods_for_unit: | ||
| start_sample = period["start_sample_index"] | ||
| end_sample = period["end_sample_index"] | ||
| spiketrain_in_periods.append(spiketrain[(spiketrain >= start_sample) & (spiketrain < end_sample)]) | ||
| if len(spiketrain_in_periods) == 0: | ||
| spiketrain_in_periods = np.array([], dtype=spiketrain.dtype) | ||
| else: | ||
| spiketrain_in_periods = np.unique(np.concatenate(spiketrain_in_periods)) | ||
|
|
||
| spiketrain_sliced = sliced_sorting.get_unit_spike_train(segment_index=segment_index, unit_id=unit_id) | ||
| assert len(spiketrain_in_periods) == len(spiketrain_sliced) | ||
|
|
||
| # now test with input as numpy array with shape (n_periods, 4) | ||
| periods_array = np.zeros((len(periods), 4), dtype="int64") | ||
| periods_array[:, 0] = periods["segment_index"] | ||
| periods_array[:, 1] = periods["start_sample_index"] | ||
| periods_array[:, 2] = periods["end_sample_index"] | ||
| periods_array[:, 3] = periods["unit_index"] | ||
|
|
||
| sliced_sorting_array = sorting.select_periods(periods=periods_array) | ||
| np.testing.assert_array_equal(sliced_sorting.to_spike_vector(), sliced_sorting_array.to_spike_vector()) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| import tempfile | ||
|
|
||
|
|
@@ -254,3 +319,4 @@ def test_time_slice(): | |
| test_BaseSorting(cache_folder) | ||
| test_npy_sorting() | ||
| test_empty_sorting() | ||
| test_select_periods() | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.