Description
Rationale
Since SpikeInterface v0.90, the processing of a recording + a spike sorting output started from the creation of a WaveformExtractor
and the subsequent addition of data from the postprocessing and qualitymetrics (QM) modules as WaveformExtension
(from v0.93).
While some postprocessing and QM functions need waveforms, this is not the case for all (e.g., computing correlograms, spike amplitude, ISI histograms). In addition, the WaveformExtractor
also ended up including a bunch of additional metadata handling for storing and retrieving metadata of the recording and sorting objects, so it doesn’t only handle waveforms.
With this proposal, we therefore suggest to implement a new SpikeSortingResult
object which will only combine a recording and sorting object, define sparsity, handle the respective metadata, and implement loading and saving to multiple backends (memory, binary folders, zarr)
Features
- Combines Recording + Sorting
- Caches Sorting and recording info
- Works recordingless
- Supports extensions
- Waveforms is also a
ResultExtension
living in core - Other ResultExtension live elsewhere (postprocessing, qualitymetrics, …)
- Ability to compute several extensions one by one
ssr.compute(“spike_amplitude”)
orspikeinterface.postprocessing.compute_spike_amplitudes(ssr)
- Ability to compute several extensions at once:
ssr.compute([“spike_amplitude”, “unit_location”])
- Automate compute logic: registration of an extension automatically generates the function / docstring. etc.
- Native backends: memory + binary (npy) + zarr (TODO)
- Export backends: other backends that are not core-supported
- (run_sorter could output a SpikeSortingResult, to be discussed)
API changes
Old API
recording = read_openephys(...)
sorting = run_sorter(‘tridesclous’, recording, …)
# this create the object and also extractor waveforms
# we=WaveformExtactor
we = extract_waveforms(recording, sorting, ‘/waveorm_folder’)
# then some post processing
amplitudes = compute_spike_amplitude(we)
qm = compute_quality_metrics(we)
unit_locations = compute_unit_locations(we)
plot_waveforms(we)
# this used to be a strange syntax:
plot_quality_metrics(we)
This new API will be
recording = read_openephys(...)
sorting = run_sorter(‘tridesclous’, recording, …)
# this create the object and also extractor waveforms
# ssr=SpikeSortingResult
ssr = create_result(recording, sorting, ‘/result_folder’) # name to be discussed!
# then some post processing
ssr.compute(“spike_amplitude”)
ssr.compute(“quality_metrics”)
ssr.compute(“unit_locations”)
# or call by functions to get some backyard compatibility
# function call return directly the results
amplitudes = compute_spike_amplitude(ssr )
qm = compute_quality_metrics(we)
unit_locations = compute_unit_locations(we)
#or
ssr.compute([“spike_amplitude”, “quality_metrics”, “unit_locations”])
plot_waveforms(ssr)
# this is now a better syntax
plot_quality_metrics(ssr)
Refactor needed
Internal:
- Quality metrics
- Postprocessing
- Widgets
- Exporters
- Curation
External:
- SI-GUI
- Lussac
- NeuroConv
Transition plan
For a transition phase, we will need to keep a DummyWaveformExtractor that mimics the behavior of the WaveformExtractor but internally use a SpikeSortingReult
- All docs and examples will need to be updated.
- Important: keep a load_sorting_result_from_waveforms() for old results
- New tutorial on SpikeSortingResult
Agenda
December 2023 : first public discussion draft
January 2024 : start dev in a separate branch
February 2024 : last release 0.100.0 with WaveformExtractor
Day after the release : main go in 100_bug_fix branch and dev become main
June 2024 : release 0.101.0 with SpikeSortingResult
Advanced users : we need your feeback!
@magland @colehurwitz @mhhennig @khl02007 @h-mayorquin @zm711 @DradeAW @yger @ferchaure @bendichter @CodyCBakerPhD @JoeZiminski @TomBugnon @grahamfindlay @cwindolf @julienboussard
Let's discuss here and then we will open a project for sub tasks.