eeg_tools.
bandpass_filter
(signal, locut, hicut, srate, offset=None, passdB=1.0, stopdB=30.0, ftype='IIR', verbose=True)[source]¶Band-/Low-/High-pass filter a 1D/2D input signal
Parameters: | signal : NumPy 1d/2darray
locut : float
hicut : float
srate : float
offset : float
passdB : float
stopdB : float
ftype : str
verbose : bool
|
---|---|
Returns: | filtered : NumPy 1d/2darray
|
See also
scipy.signal.buttord
scipy.signal.butter
scipy.signal.lfilter
Notes
This routine uses a Butterworth filter (for ftype = ‘IIR’) or a Kaiser filter (for ftype = ‘FIR’) to low-/high-/bandpass the input signal. Based on the user’s input the optimal (i.e., lowest) order of the filter is calculated. Note that depending on the choice of cutoff frequencies and values of passdB and stopdB the computed filter coefficients might be very large/low causing numerical instability in the filtering routine. The code assumes you know what you’re doing and does not try to guess whether the combination of cutoff-frequencies, offset and attenuation/amplification values applied to the input signal makes sense.
By default the offset frequency is computed as fraction of the input frequencies, i.e., for low-/high-pass filters the offset is 0.5*cutoff-frequency, for band-pass filters the offset is calculated as 0.5 times the width of the pass-band. The following skteches illustrate the filter’s operating modes
Amplification
(dB)
/ \
|| Low-pass
|| ---------------------+
|| |\
|| | \
|| | +---------
|| PASS |OS| STOP
||
++===================================> Frequency (Hz)
Amplification
(dB)
/\
|| High-pass
|| +------------------------
|| /|
|| / |
|| -------+ |
|| STOP |OS| PASS
||
++===================================> Frequency (Hz)
Amplification
(dB)
/\
|| Band-pass
|| +----------+
|| /| |\
|| / | | \
|| -------+ | | +---------
|| STOP |OS| PASS |OS| STOP
||
++===================================> Frequency (Hz)
Where STOP = stop-band, OS = offset, PASS = pass-band.
Examples
We construct an artifical signal which we want to low-/high-/band-pass filter.
>>> import numpy as np
>>> srate = 5000 # Sampling rate in Hz
>>> T = 0.05
>>> nsamples = T*srate
>>> t = np.linspace(0,T,nsamples,endpoint=False)
>>> a = 0.02
>>> f0 = 600.0
>>> signal = 0.1 * np.sin(2 * np.pi * 1.2 * np.sqrt(t))
>>> signal += 0.01 * np.cos(2 * np.pi * 312 * t + 0.1)
>>> signal += a * np.cos(2 * np.pi * f0 * t + .11)
>>> signal += 0.03 * np.cos(2 * np.pi * 2000 * t)
First, we low-pass filter the signal using the default IIR Butterworth filter (all examples given below can be repeated using the FIR Kaiser filter by additionally providing the keyword argument ftype=’FIR’). As cutoff frequency we choose 50Hz, with an offset of 10Hz. That means frequencies [0-50] Hz “survive”, frequencies in the band [50-60] Hz are gradually attenuated, all frequencies >60Hz are maximally attenuated.
>>> filtered = bandpass_filter(signal,50,None,5000,offset=10)
Now, construct a high-pass filter that removes all frequencies below 500Hz, using the default offset of 0.5*`hicut` (see Notes for details).
>>> filtered = bandpass_filter(signal,None,500,5000)
Finally, we band-pass filter the signal, so that only frequency components between 500Hz and 1250Hz remain
>>> filtered = bandpass_filter(signal,500,1250,5000)
Note that ill-chosen values for the offset (e.g., very steep slopes, from the stop- to the pass-band, see Notes for a sketch) and/or attenuation/amplification dB’s may lead to very large/small filter coefficients that may cause erratic results due to numerical instability.