Skip to content

Recorders

Spike train recording and analysis utilities.

  • BitstreamSpikeRecorder — Records spikes as 1D bitstream (0/1 per timestep). Provides: total spike count, firing rate (Hz given dt in ms), ISI histogram, raster data for plotting.
from sc_neurocore import BitstreamSpikeRecorder

recorder = BitstreamSpikeRecorder()
for t in range(1000):
    spike = neuron.step(current)
    recorder.record(spike)

print(f"Total spikes: {recorder.total_spikes}")
print(f"Firing rate: {recorder.firing_rate(dt=1.0):.1f} Hz")

sc_neurocore.recorders.spike_recorder.BitstreamSpikeRecorder dataclass

Record spikes over time and compute basic statistics.

Stores a 1D bitstream of spikes (0/1) and provides: - total spikes - firing rate (Hz) given dt (ms) - inter-spike interval (ISI) histogram

Source code in src/sc_neurocore/recorders/spike_recorder.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
@dataclass
class BitstreamSpikeRecorder:
    """
    Record spikes over time and compute basic statistics.

    Stores a 1D bitstream of spikes (0/1) and provides:
    - total spikes
    - firing rate (Hz) given dt (ms)
    - inter-spike interval (ISI) histogram
    """

    dt_ms: float = 1.0
    spikes: List[int] = field(default_factory=list)

    def record(self, spike: int) -> None:
        if spike not in (0, 1):
            raise ValueError("Spike must be 0 or 1.")
        self.spikes.append(spike)

    def reset(self) -> None:
        self.spikes.clear()

    def as_array(self) -> np.ndarray[Any, Any]:
        return np.array(self.spikes, dtype=np.uint8)

    def total_spikes(self) -> int:
        return int(np.sum(self.as_array()))

    def firing_rate_hz(self) -> float:
        spikes = self.as_array()
        T = spikes.size
        if T == 0:
            return 0.0
        duration_ms = T * self.dt_ms
        if duration_ms == 0:
            return 0.0
        return float(self.total_spikes() / (duration_ms / 1000.0))

    def isi_histogram(
        self,
        bins: int = 10,
    ) -> Tuple[np.ndarray[Any, Any], np.ndarray[Any, Any]]:
        """
        Compute histogram of inter-spike intervals in ms.

        Returns
        -------
        hist : np.ndarray
            Histogram counts.
        bin_edges : np.ndarray
            Bin edges (ms).
        """
        spikes = self.as_array()
        spike_indices = np.where(spikes == 1)[0]

        if spike_indices.size < 2:
            return np.zeros(bins, dtype=int), np.linspace(0, 1, bins + 1)

        isi_steps = np.diff(spike_indices)
        isi_ms = isi_steps * self.dt_ms

        hist, bin_edges = np.histogram(isi_ms, bins=bins)
        return hist, bin_edges

isi_histogram(bins=10)

Compute histogram of inter-spike intervals in ms.

Returns

hist : np.ndarray Histogram counts. bin_edges : np.ndarray Bin edges (ms).

Source code in src/sc_neurocore/recorders/spike_recorder.py
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
def isi_histogram(
    self,
    bins: int = 10,
) -> Tuple[np.ndarray[Any, Any], np.ndarray[Any, Any]]:
    """
    Compute histogram of inter-spike intervals in ms.

    Returns
    -------
    hist : np.ndarray
        Histogram counts.
    bin_edges : np.ndarray
        Bin edges (ms).
    """
    spikes = self.as_array()
    spike_indices = np.where(spikes == 1)[0]

    if spike_indices.size < 2:
        return np.zeros(bins, dtype=int), np.linspace(0, 1, bins + 1)

    isi_steps = np.diff(spike_indices)
    isi_ms = isi_steps * self.dt_ms

    hist, bin_edges = np.histogram(isi_ms, bins=bins)
    return hist, bin_edges