Expand description
Neural spike detection, spatial deduplication, waveform alignment, feature extraction, localization, drift estimation, kriging, clustering, template matching, correlograms, Allen/IBL quality metrics, sorter comparison, and neural frequency bands.
Recording and sorting file formats (NWB, SpikeGLX, mtscomp, Phy, .sorting.zarr) and probe
geometry (layouts, presets, nearest-site queries) are in io.
§Where things are
| Step | Module | Start with |
|---|---|---|
| Find spikes | detection | detect_spikes_threshold, deduplicate_spikes_spatial |
| Whole recordings, bounded memory | streaming | streaming::StreamingDetector |
| Cut waveforms | extraction | extract_snippets |
| Features | features | PcaFeatureEmbedder |
| Positions and drift | spatial | PeakLocalizer implementations |
| Cluster into units | sorting | k-means, GMM, HDBSCAN, bipartite modularity |
| Quality and comparison | metrics | ISI violations, presence, amplitude cutoff; sorter agreement |
| Results on disk | storage | SortingOutput (Phy, Zarr, NWB) |
| Recordings, probes, sorting files | io | io::open, io::probe |
Complete sorters are separate crates, one per upstream project, each under its upstream’s
licence: dspk-sorter-kilosort (Kilosort4, EMUsort), dspk-sorter-ms5 (MountainSort 5),
dspk-sorter-si (SpyKING CIRCUS 2, Tridesclous 2). Pretrained models: dspk-synapse-ml.
§Example
Detect threshold crossings, then keep one spike per event: a spike seen on neighbouring channels is one spike, assigned to the channel where it is largest.
use dspk_synapse::io::probe::{Position3D, SensorLayout, SensorSite};
use dspk_synapse::{deduplicate_spikes_spatial, detect_spikes_threshold, SpikePolarity, ThresholdSpikeDetector};
// 4 channels on a line, 20 µm apart
let sites = (0..4).map(|c| SensorSite::new(c, Position3D::new(0.0, 20.0 * c as f32, 0.0), 0)).collect();
let layout = SensorLayout::new("linear", sites);
// Small noise, and one spike at sample 500: −80 µV on channel 1, −40 µV on its neighbour
let (channels, samples) = (4, 1_000);
let mut x: Vec<f32> = (0..channels * samples).map(|i| ((i * 7_919) % 200) as f32 / 100.0 - 1.0).collect();
x[samples + 500] = -80.0;
x[2 * samples + 500] = -40.0;
// Troughs below −5 σ (σ per channel, from the median absolute deviation), ≥ 1 ms apart at 30 kHz
let settings = ThresholdSpikeDetector::new(5.0, 1.0, SpikePolarity::Negative);
let crossings = detect_spikes_threshold(&x, channels, samples, 30_000.0, &settings);
assert_eq!(crossings.len(), 2); // the same spike, on two channels
// Crossings within 50 µm and 10 samples of a larger one belong to it
let spikes = deduplicate_spikes_spatial(&crossings, &layout, 50.0, 10);
assert_eq!(spikes.len(), 1);
assert_eq!(spikes[0].primary_channel, 1);
assert_eq!(spikes[0].participating_channels, vec![1, 2]);Re-exports§
pub use core::DeduplicatedSpike;pub use core::FeatureEmbedder;pub use core::MatchedSpike;pub use core::NeuralBand;pub use core::PeakLocalizer;pub use core::RecordingMeta;pub use core::SnippetBatch;pub use core::SortedUnit;pub use core::SortingOutput;pub use core::SpikeDetector;pub use core::SpikeEvent;pub use core::SpikeMatcher;pub use core::UnitQualityLabel;pub use core::WaveformDenoiser;pub use core::WaveformSnippet;pub use core::WaveformTemplate;pub use core::compute_mean_template;pub use core::dense_waveform;pub use core::pack_templates;pub use core::unpack_template;pub use detection::AdaptiveThresholdDetector;pub use detection::MatchedFilterSpikeDetector;pub use detection::NeoSpikeDetector;pub use detection::SpikePolarity;pub use detection::SpikeSpacing;pub use detection::ThresholdSpikeDetector;pub use detection::canonical_biphasic_prototype;pub use detection::DedupNeighbours;pub use detection::compute_neo_energy;pub use detection::deduplicate_spikes_spatial;pub use detection::deduplicate_spikes_spatial_device;pub use detection::detect_spikes_matched_filter;pub use detection::detect_spikes_threshold;pub use detection::detect_spikes_neo;pub use detection::detect_spikes_threshold_with_sigma;pub use detection::detection_heights;pub use detection::execute_detect_spikes_in_vram;pub use extraction::execute_extract_sinc_in_vram;pub use extraction::extract_snippet_batch;pub use extraction::extract_snippets;pub use extraction::extract_snippets_single_channel;pub use extraction::read_snippets;pub use features::ConductionVelocityEstimate;pub use features::PcaFeatureEmbedder;pub use features::PpcaFeatureEmbedder;pub use features::SpikeMorphology;pub use features::WaveletFeatureEmbedder;pub use features::compute_morphology;pub use features::estimate_hdemg_conduction_velocity;pub use features::extract_waveform_pca;pub use features::compute_haar_dwt;pub use metrics::BurstEpoch;pub use metrics::Correlogram;pub use metrics::FiringRateCurve;pub use metrics::IsiMetrics;pub use metrics::MepMetrics;pub use metrics::PairwiseTrainMatch;pub use metrics::PsthResult;pub use metrics::QualityCriteria;pub use metrics::SortingComparison;pub use metrics::StimulusTriggeredAverage;pub use metrics::UnitMatchSummary;pub use metrics::compare_sortings;pub use metrics::compare_spike_trains;pub use metrics::compute_amplitude_cutoff;pub use metrics::AmplitudeCutoffOptions;pub use metrics::compute_autocorrelogram;pub use metrics::compute_crosscorrelogram;pub use metrics::compute_d_prime;pub use metrics::compute_instantaneous_firing_rate;pub use metrics::compute_isi_violations;pub use metrics::compute_isolation_distance;pub use metrics::compute_llobet_contamination;pub use metrics::compute_presence_ratio;pub use metrics::compute_psth;pub use metrics::compute_silhouette_score;pub use metrics::compute_snr;pub use metrics::compute_stimulus_triggered_average;pub use metrics::count_refractory_violations;pub use metrics::detect_burst_epochs;pub use metrics::compute_isi_histogram;pub use metrics::quantify_mep;pub use sorting::ConvolutiveBssDecomposer;pub use sorting::DensityPeaksResult;pub use sorting::GmmClusterer;pub use sorting::GmmCovarianceKind;pub use sorting::GmmResult;pub use sorting::KdeMergeResult;pub use sorting::MotorUnitPulseTrain;pub use sorting::MatchingPursuitMatcher;pub use sorting::cluster_density_peaks;pub use sorting::DensityPeaksOptions;pub use sorting::KdeMergeOptions;pub use sorting::cluster_gmm_bic;pub use sorting::cluster_kde_merge;pub use sorting::compute_template_similarity_matrix;pub use sorting::match_spikes_matching_pursuit;pub use sorting::suggest_template_merges;pub use sorting::template_max_cosine_similarity;pub use spatial::CenterOfMassLocalizer;pub use spatial::DipoleEstimate;pub use spatial::DipoleLocalizer;pub use spatial::DriftEstimate;pub use spatial::GridConvolutionLocalizer;pub use spatial::KRIGING_REGULARIZATION;pub use spatial::MonopolarTriangulator;pub use spatial::NonRigidDriftEstimate;pub use spatial::TraceKriging;pub use spatial::compute_kriging_weight_matrix;pub use spatial::correct_snippet_batch_drift_kriging;pub use spatial::correct_traces_drift_kriging;pub use spatial::estimate_nonrigid_drift;pub use spatial::estimate_rigid_drift;pub use spatial::localize_spike_center_of_mass;pub use spatial::localize_spike_dipole;pub use spatial::localize_spike_grid_convolution;pub use spatial::localize_spike_monopolar;pub use streaming::BatchTemplateStats;pub use streaming::SINC_RESAMPLE_MARGIN;pub use streaming::StreamingDetectionConfig;pub use streaming::StreamingDetectionResult;pub use streaming::StreamingDetector;pub use streaming::TemplateAccumulator;pub use streaming::execute_reduce_templates_in_vram;pub use provenance::ArtifactSource;pub use provenance::Attributed;pub use provenance::Paper;pub use provenance::Provenance;pub use provenance::ProvenanceKind;pub use provenance::UpstreamCode;pub use storage::fill_similarity;pub use storage::load_nwb_units;pub use storage::load_phy_folder;pub use storage::load_sorting;pub use storage::load_sorting_zarr;pub use storage::load_spikes;pub use storage::save_nwb_units;pub use storage::save_phy_folder;pub use storage::save_sorting;pub use storage::save_sorting_zarr;
Modules§
- core
- detection
- Spike detection: per-channel candidates from dspk-ops peak finding (
dspk_ops::peaks), accepted by each detector’s score and spaced bySpikeSpacing; then spatial deduplication. - extraction
- features
- io
- Neural-recording formats (NWB, SpikeGLX, mtscomp), spike-sorting files (Phy / Kilosort, NWB
units,
.sorting.zarr), probe geometry, and synthetic recordings, on top ofdspk-io(host-side: no device needed). - metrics
- provenance
- Where every sorter and model comes from: the paper to cite, the upstream code and its license,
and the files downloaded to run it. Exposed by every sorter and model through
Attributed, and stored in the catalog, so a result can always be traced to its authors. - sorter
- What every dspk spike sorter shares, so each sorter crate (
dspk-sorter-kilosort,dspk-sorter-ms5,dspk-sorter-si) holds only its own algorithms, under its upstream’s licence. - sorting
- spatial
- storage
- Sortings on disk ↔
SortingOutput. The files are read and written bydspk-io(crate::io::{phy, nwb, sorting_zarr}); this module converts them: - streaming
- Out-of-core streaming spike detection with per-channel templates, dynamic halo scheduling, and online template accumulation.
Enums§
- Distance
Rule - How
distanceresolves peaks closer than it.
Functions§
- estimate_
noise_ std - Computes the robust estimate of background noise standard deviation (Quiroga et al., 2004):
$\sigma_n = \text{median}(|x|) / \Phi^{-1}(0.75)$ (
MAD_TO_SIGMA)