The Kilosort test recording
From here on the playground uses real data: Kilosort4’s test recording, a Neuropixels 1.0 probe
(385 channels, 30 kHz, 45 s, int16, SpikeGLX). This downloads it once into
playground/datasets/kilosort4/ (git-ignored), checks it against the SHA-256 the playground was
written with, and writes the JSON .meta dspk reads raw binaries with.
uv run python playground/09_sorting/00_fetch_kilosort_data.py [--url URL] [--dest DIR]The address is the one Kilosort4’s documentation downloads it from; if it moves, pass the new
one with --url (the checksum still guards the file). Already have it? --from FILE copies a
local .bin instead (it is checked the same way).
import argparseimport hashlibimport jsonimport shutilimport urllib.requestimport zipfilefrom pathlib import Path
#: Where Kilosort4's documentation downloads the recording from (a zip of the .bin).DEFAULT_URL = "https://www.kilosort.org/downloads/ZFM-02370_mini.imec0.ap.short.zip"NAME = "ZFM-02370_mini.imec0.ap.short.bin"#: SHA-256 of the .bin this playground was written with.SHA256 = "918be4edccddbb1a0d420afae649cf0f33f2f6720365d743fa9cb0923da7b2b9"SIZE = 1_039_500_000#: dspk's raw-binary sidecar for it (SpikeGLX imec AP band: 2.34375 µV per step).META = {"channels": 385, "sample_rate_hz": 30000.0, "format": "int16", "order": "time_major", "gain_uv": 2.34375, "offset_uv": 0.0, "header_bytes": 0, "samples": 1350000}
parser = argparse.ArgumentParser(description=__doc__)parser.add_argument("--url", default=DEFAULT_URL)parser.add_argument("--dest", type=Path, default=Path(__file__).resolve().parents[1] / "datasets" / "kilosort4")parser.add_argument("--from", dest="source", type=Path, help="copy this local .bin instead of downloading")args, _ = parser.parse_known_args()
def sha256(path: Path) -> str: h = hashlib.sha256() with path.open("rb") as f: while chunk := f.read(1 << 24): h.update(chunk) return h.hexdigest()Get the file (once)
args.dest.mkdir(parents=True, exist_ok=True)target = args.dest / NAMEif target.exists() and target.stat().st_size == SIZE and sha256(target) == SHA256: print(f"already here: {target}")else: if args.source: shutil.copyfile(args.source, target) else: archive = args.dest / "download.zip" print(f"downloading {args.url} …") urllib.request.urlretrieve(args.url, archive) with zipfile.ZipFile(archive) as z: member = next(m for m in z.namelist() if m.endswith(NAME)) with z.open(member) as src, target.open("wb") as dst: shutil.copyfileobj(src, dst) archive.unlink() got = sha256(target) if got != SHA256: target.unlink() raise SystemExit(f"checksum mismatch: expected {SHA256}, got {got}; the file was removed") print(f"verified: {target}")(args.dest / NAME.replace(".bin", ".meta")).write_text(json.dumps(META, indent=2) + "\n")print("ready: dspk.io.open(", target, ")")The whole script is playground/09_sorting/00_fetch_kilosort_data.py. Run it with uv run python playground/09_sorting/00_fetch_kilosort_data.py.