A real probe: every spike, where it came from, and how the probe moved
Kilosort4’s test recording: 45 s of a Neuropixels 1.0 probe (384 sites over 3.8 mm, plus a
sync channel), 30 kHz, int16. First run 00_fetch_kilosort_data.py.
- Detect over the whole file, streaming on the device (
detect_recording: band-pass, common median reference, threshold, merging across sites) — whatdspk detectdoes. - Locate each spike as it is detected: the centre of mass of its snippet’s peak-to-peak heights over its nearest sites (µm on the probe), computed on the device with the snippets.
- Drift: spikes’ depths over time show the probe moving in the brain (bands of activity
bend);
spatial.driftestimates that motion — what sorters correct before clustering.
from pathlib import Path
import numpy as np
import dspkfrom dspk.synapse import detection, io, spatial
DATA = Path(__file__).resolve().parents[1] / "datasets" / "kilosort4" / "ZFM-02370_mini.imec0.ap.short.bin"if not DATA.exists(): raise SystemExit(f"{DATA} is missing: run playground/09_sorting/00_fetch_kilosort_data.py first")
rec = dspk.io.open(DATA)probe = io.Probe.preset("neuropixels1") # 384 sites; the file's channel 385 is the sync linefs, total = rec.sample_rate, rec.samplesprint(rec)
# 1–2. Detection over the whole recording (streamed in batches on the device), each spike located# from its 8 nearest sitessorting, summary = detection.detect_recording(rec, probe, car=True, k_neighbors=8)spikes = sorting.spikes()positions = spikes["locations"]print(f"{summary['spikes']} spikes after merging ({summary['raw_crossings']} threshold crossings)")ok = ~np.isnan(positions[:, 1])print(f"located {ok.mean():.0%} of the spikes")
# 3. Drift from the located spikes (rigid: one displacement for the whole probe per time bin)t, depth, amp = spikes["samples"][ok], positions[ok, 1], np.abs(spikes["amplitudes"][ok])drift = spatial.drift(t, depth, amp, total, fs, depth_min_um=float(depth.min()), depth_max_um=float(depth.max()))print(f"drift over the recording: {np.ptp(drift['drift_um']):.1f} µm peak to peak")
The whole script is playground/09_sorting/01_detect_and_locate.py. Run it with uv run python playground/09_sorting/01_detect_and_locate.py.