Skip to content

Add method="fir" to highpass_filter and bandpass_filter - #4856

Open
galenlynch wants to merge 6 commits into
SpikeInterface:mainfrom
galenlynch:feat/bandpass-fir-method
Open

galenlynch wants to merge 6 commits into
SpikeInterface:mainfrom
galenlynch:feat/bandpass-fir-method

Conversation

@galenlynch

Copy link
Copy Markdown
Contributor

Builds on #4855, which must merge first.

highpass_filter(rec, method="fir") and bandpass_filter(rec, method="fir") apply the kernels from design_fir_highpass and design_fir_bandpass with fir_filter, so users get the FIR without designing a kernel. The default stays "iir". Speed and frequency response are as in #4855.

  • The cutoffs keep their meaning. freq_min and freq_max are still the −6 dB points, as for the default Butterworth.
  • Three new arguments set the FIR: transition_low_hz=175, transition_high_hz=2000 (bandpass only) and stopband_db=45. These are serialized, not the taps.
  • IIR-only arguments raise. With method="fir", setting filter_order, ftype, filter_mode, coeff or direction raises ValueError. margin_ms is ignored, because the FIR reads exactly the margin it needs.
  • Tests. method="fir" output equals fir_filter with the same design exactly. The tests also cover chunk invariance, save and load, and the errors.
Effect on spike templates templates_iir_fir

Four units across the amplitude range, on each unit's peak channel. The difference, magnified 10 times, is a slow oscillation near 300 Hz, where the two filters' transitions differ; each panel's scale bar reads a tenth of its label for it.

Templates of 216 units from 10 min of one Neuropixels 2.0 probe, at the sorter's spike times (up to 2,000 spikes each), after phase_shift, highpass_filter(method=...) and common_reference in float32. On each unit's peak channel, the IIR and FIR templates differ by 0.27 µV rms (median), or 0.34% of the peak and at most 1.0%. The FIR's peak is 0.39% larger (median, −0.2% to 0.9%), because the Butterworth's passband sags.

fir_filter(recording, taps) applies any FIR kernel, shared or per
channel, by overlap-save. Its margin is the kernel's support, so its
output does not depend on chunking. Channels are filtered in blocks
sized to keep each block's buffers in the L2 cache. design_fir_bandpass
and design_fir_highpass design Kaiser-window kernels from a stated spec:
-6 dB at the cutoffs, a given transition width at each edge, and a given
stopband attenuation. Keeping design separate from application lets
kernels be inspected or combined before use.

The defaults (175 Hz lower transition, 45 dB stopband) pass at most
0.03% of the probe's specified noise power below 150 Hz, and no more
than the default Butterworth between 150 and 300 Hz, on every channel of
a Neuropixels 2.0 recording. A 400 Hz lower transition passed 2.4 times
the Butterworth's power between 150 and 300 Hz.

check_chunk_invariance in core.testing compares chunked reads with one
whole read, so any preprocessor's seam error can be tested directly.
The core test jobs run without scipy and collect every test module, so a
module-level scipy import failed collection there.
method="fir" applies a Kaiser kernel from design_fir_bandpass or
design_fir_highpass by overlap-save. freq_min and freq_max stay the -6 dB
points, as for the default Butterworth, and transition_low_hz,
transition_high_hz and stopband_db set the rest of the response. The
output does not depend on chunking, so margin_ms is ignored. The
recording serializes the design parameters, not the taps.

IIR-only arguments raise when set with method="fir" rather than being
silently dropped. The default stays "iir", since the FIR is a different
filter and switching would change every user's output.
@alejoe91 alejoe91 added preprocessing Related to preprocessing module performance Performance issues/improvements labels Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance Performance issues/improvements preprocessing Related to preprocessing module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants