I am trying to create an FIR bandpass filter in python using scipy with the following characteristics:
$$f_{c_{low}} = 310\,Hz$$
$$f_{c_{high}} =600\, Hz$$ giving me a bandwidth of: $$Bandwidth = f_{c_{high}} - f_{c_{low}} = 390 $$
I generate an real valued input signal using a sampling frequency of 1 kHz [using the following code]: $$y(t) = sin(2\pi\cdot 10 \cdot t) +sin(2\pi\cdot 480 \cdot t) + sin(2\pi\cdot 500 \cdot t) +sin(2\pi\cdot 800 \cdot t)$$
fs = 1000 # the sampling frequency
w0 = 10
w1 = 480
w2 = 500
w3 = 800
t = np.linspace(0, 1, fs, False) # 1 second
signal = np.sin(2*np.pi*w0*t) +np.sin(2*np.pi*w1*t) + np.sin(2*np.pi*w2*t)+np.sin(2*np.pi*w3*t)
and I use the following code snippet to produce the bandpass filter:
def bandpass_filter_fir(cut_l,cut_h,order=5):
def t(fs_,gn=1):
nyq = 0.5 * fs_
return sig.firwin2(order+1, [0,cut_l/nyq,cut_l/nyq,cut_h/nyq,cut_h/nyq,1],[0,0,gn,gn,0,0])
return t
I divide the cutoff frequencies by the Nyquist frequency to normalize them. However, doing so for this particular example would produce a normalized frequency larger than 1 for the cutoff high frequency:
$$\frac{2 \cdot f_c}{fs} = \frac{2 \cdot 600}{1000}=1.2$$
which is not valid since according to the Nyquist sampling theory: $$ f_c \leq \frac{f_s}{2} $$
Executing the following code snippet:
order = 1001
f1,f2 = 310,600
bp_filter = bandpass_filter_fir(f1,f2,order=order)
w, h = sig.freqz(bp2_filter(1000), worN=500) # since I plan to plot the frequency response
would lead to the following generated error in python:
~/.local/lib/python3.8/site-packages/scipy/signal/fir_filter_design.py in firwin(numtaps, cutoff, width, window, pass_zero, scale, nyq, fs)
396 raise ValueError("At least one cutoff frequency must be given.")
397 if cutoff.min() <= 0 or cutoff.max() >= 1:
--> 398 raise ValueError("Invalid cutoff frequency: frequencies must be "
399 "greater than 0 and less than fs/2.")
400 if np.any(np.diff(cutoff) <= 0):
ValueError: Invalid cutoff frequency: frequencies must be greater than 0 and less than fs/2.
So my question is how to deal with it ? Do I up-sample the signal such that the $f_s = 2f_{c_{high}}$ and pass it through the filter then down-sample the output of the filter back to its original sampling frequency?
and you can only filter in that range
? How do i restrict it to that range? the bandwidth is 290 Hz. I have slightly modified the question, to perhaps add more clarity. i am not understand what you mean byfrequency range of the analog filter just before the signal was sampled
. Does the frequency range of the filter change depending on how the signal was sampled? $\endgroup$