Spaces:
Paused
Paused
File size: 1,845 Bytes
5e0b58b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 | """Deterministic adapter from measured SNN data to an immutable SignalFrame."""
from __future__ import annotations
from collections.abc import Mapping, Sequence
from .features import burst_index, population_rate_hz, synchrony
from .models import RegionActivity, SignalFrame, SpikeSample
from .temporal import window_duration_ms
class SignalInterpreter:
"""Build SignalFrame values without owning or mutating the runtime loop."""
def build_frame(
self,
*,
tick_from: int,
tick_to: int,
dt_ms: float,
neuron_ids: Sequence[int],
spikes: Sequence[SpikeSample],
energies: Mapping[int, float],
threshold_adaptations: Mapping[int, float],
active_regions: Sequence[RegionActivity] = (),
) -> SignalFrame:
ids = tuple(int(value) for value in neuron_ids)
samples = tuple(spikes)
duration_ms = window_duration_ms(tick_from, tick_to, dt_ms=dt_ms)
mean_energy = (
sum(energies.get(neuron_id, 0.0) for neuron_id in ids) / len(ids)
if ids
else 0.0
)
mean_threshold = (
sum(threshold_adaptations.get(neuron_id, 0.0) for neuron_id in ids)
/ len(ids)
if ids
else 0.0
)
return SignalFrame(
tick_from=tick_from,
tick_to=tick_to,
neuron_ids=ids,
population_rate_hz=population_rate_hz(
samples, neuron_count=len(ids), duration_ms=duration_ms
),
spike_count=len(samples),
burst_index=burst_index(samples),
synchrony=synchrony(samples, neuron_count=len(ids)),
mean_energy=mean_energy,
mean_threshold_adaptation=mean_threshold,
active_regions=tuple(active_regions),
)
|