ezmsg.simbiophys.baseline_drift#
Always-on slow 1/f (pink) baseline drift.
Adds a low-frequency, velocity-independent baseline wander to a signal so that
even at rest there is non-zero power at very low frequencies. This complements
ezmsg.simbiophys.dynamic_colored_noise, whose Kasdin filter runs at the
full output rate and therefore only holds a true 1/f slope down to a corner of
a few hundred Hz (at 30 kHz, ~700 Hz with 5 poles). Reaching sub-Hz drift that
way would need thousands of poles.
Instead we generate pink noise with a fixed spectral exponent (β = 1) on a
low internal grid (drift_fs, e.g. 50 Hz), where a handful of poles put
the 1/f corner well below 1 Hz, then linearly interpolate that slow signal up
to the output rate and add it. Because the drift is dominated by frequencies far
below the drift-grid Nyquist, linear interpolation is effectively exact.
The drift filter state, interpolation anchors, and phase are all carried across chunks so the output is continuous and independent of how the stream is chunked.
Performance: the grid is generated on only drift_fs samples per second (a
handful per chunk), so the sequential IIR recursion is tiny. Upsampling to the
output rate, scaling, and adding to the input are fused into a single compiled
pass that touches the (n_samples, n_channels) result exactly once (see
_pink_drift_add()), which keeps the stage memory-bandwidth bound and
scales well to large channel counts on low-power CPUs.
Classes
- class BaselineDriftSettings(scale=1.0, drift_fs=50.0, n_poles=24, beta=1.0, seed=None)[source]#
Bases:
Settings- drift_fs: float = 50.0#
Internal sample rate (Hz) at which the slow pink noise is generated. Lower rates push the 1/f corner lower for a given pole count; it only needs to sit comfortably above the drift frequencies of interest.
- class BaselineDriftState[source]#
Bases:
object- delay_lines: ndarray[tuple[Any, ...], dtype[float64]] | None = None#
Kasdin filter delay lines, shape (n_channels, n_poles).
- coeffs: ndarray[tuple[Any, ...], dtype[float64]] | None = None#
Fixed filter coefficients for
beta, shape (n_poles,).
- prev: ndarray[tuple[Any, ...], dtype[float64]] | None = None#
Left interpolation anchor (current low-rate sample), shape (n_channels,).
- class BaselineDriftTransformer(*args, **kwargs)[source]#
Bases:
BaseStatefulTransformer[BaselineDriftSettings,AxisArray,AxisArray,BaselineDriftState]Add always-on slow 1/f baseline drift to a signal.
The drift is generated independently of the input values (it depends only on the input’s shape and sample rate for timing), so it is present even when the upstream signal is at rest. One independent drift process is generated per channel of the input.
- class BaselineDriftUnit(*args, settings=None, **kwargs)[source]#
Bases:
BaseTransformerUnit[BaselineDriftSettings,AxisArray,AxisArray,BaselineDriftTransformer]Unit wrapper for BaselineDriftTransformer.
- Parameters:
settings (Settings | None)
- SETTINGS#
alias of
BaselineDriftSettings