FirFilter
Namespace: RTPROCESSINGLIB · Library: DSP Library
mne.filter.filter_data in MNE-Python.
#include <dsp/firfilter.h>
class UTILSLIB::FirFilter
Discoverable façade over the FilterKernel FIR-filter engine.
Mirrors the IirFilter API:
FilterKernel lowPass = FirFilter::design(256, FirFilter::LowPass, 20.0, 0.0, sFreq, 5.0); // order, type, cutoff(s), Hz, transition
const RowVectorXd smooth = FirFilter::applyZeroPhase(tones, lowPass);
designMne / filterData reproduce mne.filter.create_filter / filter_data:
const RowVectorXd mneKernel = FirFilter::designMne(sFreq, -1.0, 20.0); // mne.filter.create_filter defaults: 165 taps
const MatrixXd mneLow = FirFilter::filterData(tones, sFreq, -1.0, 20.0); // mne.filter.filter_data(x, 250, None, 20)
Static Methods
design(iOrder, type, dCutoffLow, dCutoffHigh, dSFreq, dTransition, method)
Design a linear-phase FIR filter using FilterKernel as the backend.
Frequencies are given in Hz; the method converts them to the Nyquist-normalised form expected by FilterKernel internally.
Parameters:
-
iOrder : int Filter order (number of taps − 1). Must be even for linear phase.
-
type : FilterType Filter type (LowPass, HighPass, BandPass, BandStop).
-
dCutoffLow : double Lower cutoff frequency in Hz. For LowPass/HighPass: the single cutoff. For BandPass/BandStop: lower edge of the transition band.
-
dCutoffHigh : double Upper cutoff frequency in Hz (ignored for LowPass/HighPass).
-
dSFreq : double Sampling frequency in Hz.
-
dTransition : double Width of the transition band in Hz (Parks-McClellan steepness / Cosine roll-off width). Defaults to 5 Hz.
-
method : DesignMethod Design method (Cosine or
ParksMcClellan).
Returns:
- FilterKernel — A ready-to-use
FilterKernelobject.
apply(vecData, kernel)
Apply the filter to a single row vector.
Uses overlap-add FFT convolution. The group delay of a symmetric FIR is removed by the FilterKernel engine (it takes the output segment starting at order/2), so the result is already approximately zero-phase for symmetric designs.
Parameters:
-
vecData : const Eigen::RowVectorXd & Input row vector.
-
kernel : FilterKernel &
FilterKernel(prepareFilter is called if needed).
Returns:
- Eigen::RowVectorXd — Filtered row vector (same length as input).
applyZeroPhase(vecData, kernel)
Apply the filter in a zero-phase forward-backward pass to a single row vector.
Runs the filter twice (forward then reverse) to achieve exactly zero phase shift. Effective order is doubled; transition bandwidth is halved.
Parameters:
-
vecData : const Eigen::RowVectorXd & Input row vector.
-
kernel : FilterKernel &
FilterKernel.
Returns:
- Eigen::RowVectorXd — Zero-phase filtered row vector.
applyZeroPhaseMatrix(matData, kernel, vecPicks)
Apply the filter in a zero-phase forward-backward pass to every row of a matrix.
Parameters:
-
matData : const Eigen::MatrixXd & Input matrix (n_channels × n_samples).
-
kernel : FilterKernel &
FilterKernel. -
vecPicks : const Eigen::RowVectorXi & Optional row indices to filter; if empty, all rows are filtered.
Returns:
- Eigen::MatrixXd — Zero-phase filtered matrix (same dimensions as input).
designMne(dSFreq, dLFreq, dHFreq)
Designs the zero-phase FIR filter of mne.filter.create_filter with its defaults: firwin design with a Hamming window, "auto" transition bands (min(max(0.25 f, 2 Hz), f) below, min(max(0.25 f, 2 Hz), Nyquist - f) above) and "auto" length 3.3 / narrowest band.
Parameters:
-
dSFreq : double Sampling frequency in Hz.
-
dLFreq : double High-pass edge in Hz, or a negative value for a low-pass.
-
dHFreq : double Low-pass edge in Hz, or a negative value for a high-pass.
Returns:
- Eigen::RowVectorXd — The odd-length impulse response.
filterData(matData, dSFreq, dLFreq, dHFreq)
Filters every row like mne.filter.filter_data with its FIR defaults: the designMne kernel applied by overlap-add with zero phase, each row padded by reflecting it about its end samples ("reflect_limited").
Parameters:
-
matData : const Eigen::MatrixXd & Data, one row per channel.
-
dSFreq : double Sampling frequency in Hz.
-
dLFreq : double High-pass edge in Hz, or a negative value for a low-pass.
-
dHFreq : double Low-pass edge in Hz, or a negative value for a high-pass.
Returns:
- Eigen::MatrixXd — The filtered data.
firwin2(nTaps, freq, gain, window)
Frequency-sampling FIR design, as scipy.signal.firwin2(nTaps, freq, gain, window=...).
Parameters:
-
nTaps : int Number of taps; an even count needs zero gain at Nyquist.
-
freq : const std::vector< double > & Increasing frequencies from 0 to 1 (Nyquist).
-
gain : const std::vector< double > & Gain at each frequency.
-
window : FirWindow The window.
Returns:
- Eigen::RowVectorXd — The impulse response.
filterDataZeroDouble(matData, dSFreq, dLFreq, dHFreq, window)
Band-pass every row like mne.filter.filter_data(x, sfreq, l_freq, h_freq, None, "10s", 0.5, 0.5, phase="zero-double", fir_window=..., fir_design="firwin2"): Hann for MNE-Python's ECG and EOG event detection, Hamming for the data filter of compute_proj_ecg / compute_proj_eog.
Parameters:
-
matData : const Eigen::MatrixXd & Data, one row per channel.
-
dSFreq : double Sampling frequency in Hz.
-
dLFreq : double High-pass edge in Hz.
-
dHFreq : double Low-pass edge in Hz.
-
window : FirWindow The FIR window.
Returns:
- Eigen::MatrixXd — The filtered data.
Example
- Full source:
src/examples/ex_dsp_analysis/main.cpp - Build target:
ex_dsp_analysis(runs under CTest)
Used in examples
ex_dsp_analysis
DSP library: Welch PSD, FIR filtering, peak finding, envelope correlation, SPHARA and simulation.
FilterKernel lowPass = FirFilter::design(256, FirFilter::LowPass, 20.0, 0.0, sFreq, 5.0); // order, type, cutoff(s), Hz, transition
const RowVectorXd smooth = FirFilter::applyZeroPhase(tones, lowPass);
const double kept = toneAmplitude(smooth.segment(250, 500), 10.0, sFreq);
const double removed = toneAmplitude(smooth.segment(250, 500), 40.0, sFreq);
ok &= expect(smooth.size() == tones.size() && std::fabs(kept - 1.0) < 0.02 && removed < 0.01,
QString("FirFilter 20 Hz low-pass keeps 10 Hz (%1) and removes 40 Hz (%2)").arg(kept, 0, 'f', 4).arg(removed, 0, 'f', 4));
Authors of this file
- Christoph Dinh <christoph.dinh@mne-cpp.org>