'band pass filter ValueError: Digital filter critical frequencies must be 0 < Wn < 1
I am trying to use bandpass filter on an ecg signals, this is the code:
from scipy.signal import butter
def bandpass_filter(self, data, lowcut, highcut, signal_freq, filter_order):
nyquist_freq = 0.5 * signal_freq
low = lowcut / nyquist_freq
high = highcut / nyquist_freq
b, a = butter(filter_order, [low, high], btype='band', analog=False)
y = lfilter(b,a, data)
return y
def detect_peaks(self):
self.filtered_ecg_measurements = self.bandpass_filter(ecg_measurements,
lowcut=self.filter_lowcut,
highcut=self.filter_highcut,
signal_freq=self.signal_frequency,
filter_order=self.filter_order)
self.signal_frequency = 250
self.filter_lowcut = 0.0
self.filter_highcut = 15.0
self.filter_order = 1
This error appears every time I try to run this function:
Traceback (most recent call last):
File "D:/Project/code/untitled/test.py", line 297, in <module>
log_data=True, plot_data=True, show_plot=False)
File "D:/Project/code/untitled/test.py", line 98, in __init__
self.detect_peaks()
File "D:/Project/code/untitled/test.py", line 135, in detect_peaks
filter_order=self.filter_order)
File "D:/Project/code/untitled/test.py", line 256, in bandpass_filter
b, a = butter(filter_order, [low, high], btype='band', analog=False)
File "C:\Users\AppData\Roaming\Python\Python36\site-packages\scipy\signal\filter_design.py", line 2394, in butter
output=output, ftype='butter')
File "C:\Users\AppData\Roaming\Python\Python36\site-packages\scipy\signal\filter_design.py", line 1959, in iirfilter
raise ValueError("Digital filter critical frequencies "
ValueError: Digital filter critical frequencies must be 0 < Wn < 1
the error text is :
Digital filter critical frequencies must be 0 < Wn < 1
Solution 1:[1]
It may be because of the input of parameter fs. It has to be larger than any of 2 * Wn.
As in scipy/signal/filter_design.py source code:
if fs is not None:
if analog:
raise ValueError("fs cannot be specified for an analog filter")
Wn = 2*Wn/fs
And later:
if not analog:
if numpy.any(Wn <= 0) or numpy.any(Wn >= 1):
raise ValueError("Digital filter critical frequencies must be 0 < Wn < 1")
Solution 2:[2]
scipy.signal.butter(N, Wn, btype='low', analog=False, output='ba')
Wn : array_like
A scalar or length-2 sequence giving the critical frequencies. For a Butterworth filter, this is the point at which the gain drops to 1/sqrt(2) that of the passband (the “-3 dB point”). For digital filters, Wn is normalized from 0 to 1, where 1 is the Nyquist frequency, pi radians/sample. (Wn is thus in half-cycles / sample.) For analog filters, Wn is an angular frequency (e.g. rad/s).
Your exception is here where low/high is not [0,1]
b, a = butter(filter_order, [low, high], btype='band', analog=False)
for filter_type == 1, Wn is float other than nparray.
https://github.com/scipy/scipy/blob/v0.19.1/scipy/signal/filter_design.py#L2226-L2297
>>> N, Wn = signal.buttord([20, 50], [14, 60], 3, 40, True)
>>> b, a = signal.butter(N, Wn, 'band', True)
Solution 3:[3]
As Darkoob12 pointed out in the comments to the question, lowcut cannot equal zero. If lowcut is set to zero, it will produce the error message seen by OP.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | tutentaten |
