spikestats
Spike-train statistics in pure Python, with zero dependencies.
spikestats computes the standard measures of spike-train rate and variability from a plain
list of spike times: firing rate, inter-spike intervals, coefficient of variation, CV2,
local variation (Lv and the refractory-corrected LvR), spike counts, the Fano factor, the
spike-time tiling coefficient (STTC), and the cross- and autocorrelogram (CCG and ACG) for
pairwise coincidence structure. There is nothing to configure
and nothing to install beyond the package itself: the input is a list[float] of spike times
and the output is a float.
It pairs with spikegen for generating trains and spikedist for comparing them. The three share the same plain-list data model, so they compose without adapters.
Why
The established tools for these measures, Elephant and spiketools, are excellent but pull in
NumPy, SciPy, and custom data objects (neo.SpikeTrain and friends). When you only need a
firing rate or a CV from a list of spike times, that is a heavy dependency tree to carry, and
it is awkward in teaching material, small scripts, and lightweight pipelines. spikestats
keeps the math, drops the dependencies, and works on the lists you already have.
Install
pip install spikestats
Usage
import spikestats as ss
spikes = [0.012, 0.031, 0.058, 0.090, 0.110, 0.155] # seconds
ss.firing_rate(spikes, duration=0.2) # spikes per second
ss.inter_spike_intervals(spikes) # consecutive differences
ss.cv_isi(spikes) # coefficient of variation of the ISIs
ss.cv2(spikes) # Holt et al. 1996, robust to rate drift
ss.lv(spikes) # Shinomoto et al. 2003 local variation
ss.lvr(spikes, refractory=0.002) # Shinomoto et al. 2009, refractory-corrected
ss.spike_counts(spikes, duration=0.2, bin_width=0.05)
ss.fano_factor(spikes, duration=0.2, bin_width=0.05)
Pairwise correlation
import spikestats as ss
a = [0.012, 0.058, 0.110, 0.155] # seconds
b = [0.015, 0.061, 0.300] # seconds
# Spike-time tiling coefficient (Cutts and Eglen 2014): firing-rate-robust correlation
# of two trains over a recording interval, with a synchronicity window dt.
ss.spike_time_tiling_coefficient(a, b, dt=0.005, interval=(0.0, 0.2))
# Cross-correlogram: histogram of lags (target - reference) in symmetric bins centered on
# zero. Returns 2 * ceil(max_lag / bin_width) + 1 integer counts, most-negative lag first.
ss.cross_correlogram(a, b, bin_width=0.005, max_lag=0.05)
# Autocorrelogram: the train's CCG with itself, excluding the trivial i == i self-pairs.
# Symmetric by construction; peaks appear at multiples of the train's ISI.
ss.autocorrelogram(a, bin_width=0.005, max_lag=0.05)
Time-resolved metrics
import spikestats as ss
spikes = [0.012, 0.031, 0.058, 0.090, 0.110, 0.155, 0.210, 0.245] # seconds
# Non-overlapping bin counts tiling [0, duration)
counts = ss.binned_spike_counts(spikes, duration=0.3, bin_width=0.1)
# => [3, 3, 2] (one list[int] per bin)
# Sliding-window firing rate: returns (center_times, rates_hz)
centers, rates = ss.time_resolved_rate(spikes, duration=0.3, bin_width=0.1, step=0.05)
# PSTH averaged over multiple trials: returns (bin_center_times, mean_rate_hz)
trials = [spikes, [0.020, 0.060, 0.100, 0.140, 0.200]]
bin_centers, mean_rates = ss.psth(trials, duration=0.3, bin_width=0.1)
# Per-bin Fano factor across trials: returns (bin_center_times, fano_per_bin)
bin_centers, fano = ss.time_resolved_fano(trials, duration=0.3, bin_width=0.1)
API
All functions take spike times as a sequence of numbers and sort them internally.
Scalar metrics
firing_rate(spikes, *, duration): spike count divided byduration.inter_spike_intervals(spikes): list of consecutive differences (empty for fewer than two spikes).cv_isi(spikes): population standard deviation of the ISIs over their mean. Regular train 0, Poisson 1.cv2(spikes): mean of2 * |I(n+1) - I(n)| / (I(n+1) + I(n))over adjacent intervals.lv(spikes): mean of3 * ((I(n) - I(n+1)) / (I(n) + I(n+1)))^2. Regular train 0, Poisson 1.lvr(spikes, *, refractory): LvR with a refractoriness constant in the spike-time unit.spike_counts(spikes, *, duration, bin_width): counts per equal-width bin tiling[0, n * bin_width).fano_factor(spikes, *, duration, bin_width): population variance of the bin counts over their mean.
Pairwise metrics
spike_time_tiling_coefficient(spikes_a, spikes_b, *, dt, interval): spike-time tiling coefficient (Cutts and Eglen 2014).intervalis a(start, end)recording window anddtis the synchronicity window. Returns a value in[-1, 1]; identical trains give 1.0, and the measure is symmetric and robust to differing firing rates. Empty trains return 0.0.cross_correlogram(reference, target, *, bin_width, max_lag) -> list[int]: binned cross-correlogram (CCG). Histograms the lagtarget_time - reference_timeof every spike pair into2 * n + 1symmetric bins withn = ceil(max_lag / bin_width). Binkcovers the half-open lag interval[(k - n - 0.5) * bin_width, (k - n + 0.5) * bin_width), so the central bin (indexn) is centered on lag zero. Counts are ordered most-negative lag first. The sign convention istarget - reference, socross_correlogram(a, b)reversed equalscross_correlogram(b, a).autocorrelogram(spikes, *, bin_width, max_lag) -> list[int]: binned autocorrelogram (ACG), the CCG of a train with itself on the same bin grid. The trivial zero-lag self-pairsi == iare excluded, so the central bin counts only genuine pairs of distinct spikes. The ACG is symmetric by construction.
Time-resolved metrics
All functions use the half-open boundary [0, duration): a spike at exactly duration is excluded.
binned_spike_counts(spikes, *, duration, bin_width) -> list[int]: spike counts inint(duration / bin_width)consecutive non-overlapping bins tiling[0, duration).time_resolved_rate(spikes, *, duration, bin_width, step) -> tuple[list[float], list[float]]: sliding-window firing rate. Window of widthbin_widthsteps bystepacross[0, duration). Returns(window_center_times, rates_in_hz). Window positions are computed by integer indexing of the step size to avoid floating-point drift.psth(trials, *, duration, bin_width) -> tuple[list[float], list[float]]: peristimulus time histogram.trialsis a sequence of spike-time sequences. Returns(bin_center_times, mean_rate_per_bin_hz)averaged over trials. RaisesValueErroron emptytrials.time_resolved_fano(trials, *, duration, bin_width) -> tuple[list[float], list[float]]: per-bin Fano factor (population variance / mean of per-trial counts). Returns(bin_center_times, fano_per_bin). Bins with zero mean across all trials are returned asfloat('nan'). Uses population variance (denominator N), so a single trial always gives 0.
Parameters after * are keyword-only and have no default values; pass them explicitly.
Notes
cv_isiuses the population standard deviation, matching the commonnumpy.stddefault.cv2,lv, andlvrneed at least three spikes; they raise a clearValueErrorotherwise.spike_countsusesfloor(duration / bin_width)equal-width bins, so every bin has the same width; any remainder of the duration and any spikes outside the binned window are ignored.binned_spike_countsusesint(duration / bin_width)bins (same count). All time-resolved functions use the half-open interval[0, duration): a spike att == durationis excluded.time_resolved_fanouses population variance (denominator N). With a single trial, variance is 0 for every bin; use multiple trials to get meaningful Fano estimates. Bins where the mean count is 0 across all trials are returned asfloat('nan').spike_time_tiling_coefficientrequires every spike to lie within the closedinterval[start, end]; a spike outside raises aValueError. Following the Cutts and Eglen convention, when a denominator1 - P * Tis zero (for example whendtis large enough that the tiling saturates to 1), that half of the STTC contributes 0. An empty train gives 0.0.cross_correlogramandautocorrelogramuse symmetric bins centered on lag zero:n = ceil(max_lag / bin_width)bins on each side give an odd2 * n + 1bins, with the central bin covering[-bin_width / 2, +bin_width / 2). A lag is counted when it falls in the grid,[-(n + 0.5) * bin_width, +(n + 0.5) * bin_width), which always covers at least[-max_lag, max_lag].bin_widthandmax_lagmust be positive andmax_lagmust be at least onebin_width, otherwise aValueErroris raised. The ACG excludes thei == iself-pairs and is symmetric.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spikestats-0.4.0.tar.gz.
File metadata
- Download URL: spikestats-0.4.0.tar.gz
- Upload date:
- Size: 769.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
151e898d204c8edc474b8aa1352969f952be521cf1c2f7c032cb9b69dbab403d
|
|
| MD5 |
2aac830cdeff245ece4628914acfcb4e
|
|
| BLAKE2b-256 |
70e5bafa57ffb100d401302ec0d5f75a6758522170d83138b5e857f8804893f4
|
File details
Details for the file spikestats-0.4.0-py3-none-any.whl.
File metadata
- Download URL: spikestats-0.4.0-py3-none-any.whl
- Upload date:
- Size: 14.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
902b3cb375f4aaef09515242f37bfb6389c09b7c071a739c540d84a18763ed53
|
|
| MD5 |
02627087fecd3f4ce81aad98ca5d5f4b
|
|
| BLAKE2b-256 |
e1d60de74fc4686abfceeb67c6737436d06f3c8ad3783ca6ee8271c10fea61fe
|