zeechimp commited on
Commit
f2aa0f4
·
verified ·
1 Parent(s): 0f830b5

Create benchmark.py

Browse files
Files changed (1) hide show
  1. benchmark.py +66 -0
benchmark.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Benchmark SpikeCascade against an offline baseline and emit the
3
+ calibration contract required by the paper.
4
+
5
+ Usage:
6
+ python benchmark.py --data path/to/recording.npy \
7
+ --baseline path/to/kilosort_output.npz
8
+
9
+ The output is a single JSON object with the four calibration fields:
10
+ activity_fraction, stage3_fraction, latency_ms, correlation
11
+ plus a 'speedup_vs_full' field computed by the theorem
12
+ S = (1 + alpha) / (1/k + alpha), alpha = (1 - T_s/T) / (T_s/T).
13
+ """
14
+
15
+ import argparse
16
+ import json
17
+ import time
18
+
19
+ import numpy as np
20
+
21
+ from modeling_spikecascade import SpikeCascadeForSorting
22
+
23
+
24
+ def main():
25
+ parser = argparse.ArgumentParser()
26
+ parser.add_argument("--data", required=True, help="(n_channels, n_samples) .npy")
27
+ parser.add_argument("--baseline", required=True, help=".npz with 'unit_ids' and 'spike_times_ms'")
28
+ parser.add_argument("--model", default="your-org/SpikeCascade")
29
+ args = parser.parse_args()
30
+
31
+ voltage = np.load(args.data).astype(np.float32)
32
+ baseline = np.load(args.baseline)
33
+ baseline_counts = {}
34
+ for uid in baseline["unit_ids"]:
35
+ baseline_counts[int(uid)] = baseline_counts.get(int(uid), 0) + 1
36
+
37
+ model = SpikeCascadeForSorting.from_pretrained(args.model)
38
+
39
+ # Warm up.
40
+ _ = model.infer(voltage[:, :3000])
41
+
42
+ t0 = time.perf_counter()
43
+ report = model.infer(voltage, baseline_spike_counts=baseline_counts)
44
+ wall_ms = (time.perf_counter() - t0) * 1000
45
+
46
+ # The theorem: S = (1 + alpha) / (1/k + alpha), with
47
+ # alpha = (1 - f) / f and f = stage3_fraction.
48
+ f = report.stage3_fraction
49
+ alpha = (1.0 - f) / f if f > 0 else float("inf")
50
+ k = 20.0 # conservative cost ratio (full clustering / template match)
51
+ speedup = (1.0 + alpha) / (1.0 / k + alpha) if f > 0 else 1.0
52
+
53
+ out = {
54
+ "activity_fraction": report.activity_fraction,
55
+ "stage3_fraction": report.stage3_fraction,
56
+ "latency_ms": report.latency_ms,
57
+ "wall_ms": wall_ms,
58
+ "correlation": report.correlation,
59
+ "speedup_vs_full": speedup,
60
+ "warning": report.warning,
61
+ }
62
+ print(json.dumps(out, indent=2))
63
+
64
+
65
+ if __name__ == "__main__":
66
+ main()