Tutorial, part 2: interval statistics

Three parts: 1 · File to raster · 2 · Interval statistics · 3 · Many sessions

Part one stopped at a container of six sorted units. This part asks what those six spike trains actually do over time - how regular each one is, whether it bursts, and how to say so with a number a reviewer will accept.

Everything here reads the session12.afz saved at the end of part one, so nothing is re-sorted. The six units kept 27 250 of the session's 41 882 events; the rest are the rejected u07 and events that no cluster claimed, which is normal and not an error.

import axonforge as af
units = af.io.read("session12.afz")           # the container from part one
for u in units.labels:
    st = units.train(u)
    print(u, st.n, af.stats.cv(st), af.stats.cv2(st))

Regularity: CV against CV2#

The coefficient of variation of the intervals is the obvious regularity measure, but it is contaminated by slow rate changes: a unit that fires steadily but speeds up over the session looks irregular to cv even though every neighbouring pair of intervals is similar. cv2 fixes this by averaging over adjacent pairs only, so a slow drift cancels. When the two disagree, the gap is rate drift, not spiking irregularity.

UnitSpikesRate, HzCVCV2Fano (1 s)BurstsReading
u019 12015.20.580.550.90regular, no drift
u024 3007.21.020.981.112close to Poisson
u032 7604.61.631.213.4141bursts, and some drift
u046 05010.10.740.711.03fairly regular
u053 4805.81.180.891.944drift inflates CV
u061 5402.60.920.901.05sparse, steady
Interval statistics of the six kept units. u05 is the instructive one: CV 1.18 looks irregular, but CV2 0.89 says the irregularity is mostly a slow rate change across the session.

Autocorrelograms#

The autocorrelogram counts, for each spike, how many other spikes of the same unit fall at each short lag. Its shape at small lags separates a regular cell from a bursting one at a glance: a regular unit has a clear trough near zero (its own refractory gap), while a bursting unit has a peak there because spikes arrive in clumps.

u01 - regular u03 - bursting 0 −50 ms +50 ms 0 −50 ms +50 ms
Autocorrelograms over ±50 ms, 1 ms bins, the zero-lag bin excluded. u01 dips toward zero lag - it will not fire twice within its refractory period. u03 peaks within 10 ms of zero, the signature of bursting, and it is the same unit the burst detector flags 141 times.
counts, edges = af.stats.autocorrelogram(units.train("u03"), bin_ms=1.0, span_ms=50.0)
b = af.stats.bursts(units.train("u03"), max_isi_ms=6.0, min_spikes=3)
print(len(b))                                 # 141 bursts

Fano factor and its window#

The Fano factor is the variance of the spike count divided by its mean, over fixed windows. For a Poisson train it is one; u03's value of 3.4 reflects the clumping. The catch is that the number depends entirely on the window, which is why stats.fano prints the window alongside the value and refuses to be compared across windows. At 100 ms windows the same unit reads closer to 1.6; the clumping is slower than that, so a short window misses it.

Reporting habit

CV, CV2 and the Fano window belong together in a methods paragraph. A CV on its own invites the reader to assume stationarity you did not check; printing CV2 next to it shows whether that assumption held, and quoting the Fano window stops the factor being read as a universal constant of the cell.