Non-linear: median and Teager–Kaiser energy
Not every useful filter is linear. A running median ignores short events: wide enough, it
removes the spikes and keeps the background. The Teager–Kaiser energy
(x[t]² − x[t−1]·x[t+1]) does the opposite: it grows where the signal is both large and fast,
so spikes stand out of the noise; spike detectors use it.
import numpy as np
import dspkfrom plating import signals
s = signals.synthetic()WIDTH = dspk.ops.filter.MAX_MEDIAN_WIDTH # 31 samples, ~1 ms at 30 kHzspikes_band = dspk.ops.filter.iir(s.data, s.sample_rate, "highpass", 300.0)median = dspk.ops.filter.median(spikes_band, WIDTH)energy = dspk.ops.filter.teager_kaiser(spikes_band)
ch = s.loudest_channelon_ch = s.spike_samples[np.isin(s.spike_units, np.flatnonzero(s.unit_channels == ch))]print(f"channel {ch}: {on_ch.size} spikes of units peaking there")
The whole script is playground/02_filtering/05_median_and_energy.py. Run it with uv run python playground/02_filtering/05_median_and_energy.py.