I have to bandpass-filter a signal which has been sampled with 4000 Hz.
Only frequencies around 15 Hz shall remain after filtering (let's say in a band between 10 Hz and 20 Hz; the narrower the better).
I have several questions here:
- What is the recommended way to perform tasks like this?
What bandpass filter is suitable?
Do I need to downsample the signal before filtering. If yes, what type of additional low pass filter should I use to avoid aliasing?
In my case, it is important that the phase of the original signal will not be distorted or shifted in the whole process. Furthermore, the filter step response should have close to zero overshoot. The settling time could therefore be a little larger.
I do not want to perform a sophisticated filter design which delivers optimal results for exactly this specific signal. I am more interested in a general solution that delivers solid results using standard IIR or FIR filters (e. g. as available in Python's SciPy library) which could be reused afterwards for similar tasks.
UPDATE:
After the answer of @MarcusMüller and the provided links, I basically tried every FIR filter design method available in Python's SciPy
library and deciced to go with remez
. I developed the following code which may be used for further discussion:
import math
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import lfilter, remez
F_test = 20.0
duration = 10.0
fs = 8000
samples = int(fs*duration)
t = np.arange(samples) / fs
signal_test = (5.0 * t * np.sin(2.0*np.pi*F_test*t)) + (0.5 * np.sin(2.0*np.pi*5.0*t)) + (0.5 * np.sin(2.0*np.pi*100.0*t))
#design filter
ntaps = 5000
edges = [0, F_test - 5.0, F_test - 2.5, F_test + 2.5, F_test + 5.0, 0.5 * fs]
taps = remez(ntaps, edges, [0, 1, 0], Hz=fs, maxiter=2500)
#apply filter
signal_test_filtered = lfilter(taps, 1, signal_test)
#create plot
fig = plt.figure()
ax0 = fig.add_subplot(111)
ax0.plot(t, signal_test_filtered, label='signal_test_filtered')
ax0.set_xlabel("time [s]")
ax0.legend()
fig.show()
filtfilt
fix that?? it will just add more delay (and BPF filter the signal some more). $\endgroup$