Skip to main content

Crate dspk_synapse

Crate dspk_synapse 

Source
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

StepModuleStart with
Find spikesdetectiondetect_spikes_threshold, deduplicate_spikes_spatial
Whole recordings, bounded memorystreamingstreaming::StreamingDetector
Cut waveformsextractionextract_snippets
FeaturesfeaturesPcaFeatureEmbedder
Positions and driftspatialPeakLocalizer implementations
Cluster into unitssortingk-means, GMM, HDBSCAN, bipartite modularity
Quality and comparisonmetricsISI violations, presence, amplitude cutoff; sorter agreement
Results on diskstorageSortingOutput (Phy, Zarr, NWB)
Recordings, probes, sorting filesioio::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 by SpikeSpacing; 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 of dspk-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 by dspk-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§

DistanceRule
How distance resolves 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)