Ivo
Ivo

Reputation: 11

Adaptive 50Hz filter

I apply following filter to get rid of 50Hz net noise on my signal:

#python code
def filter_50(signal):
    for i in np.arange(50,500,50):
        fs = 1000.0  # Sample frequency (Hz)
        f0 = i  # Frequency to be removed from signal (Hz)
        w0 = f0 / (fs / 2)  # Normalized Frequency
        Q= 30
        b, a = iirnotch(w0, Q)
        signal = scipy.signal.filtfilt(b, a, signal)
    return(signal)

But I still see in my signal noise of 50Hz. The Noise amplitude is clearly lower but still not low enough. Does anybody have an example how to apply a adaptive filter to get rid of 50Hz net noise? Or does anybody have an other filter, or approach to get rid of the 50Hz noise?

I played around with Q but it does not work good enough.

Upvotes: 0

Views: 3668

Answers (2)

Gerges
Gerges

Reputation: 6519

Well, using a filter, you always have the compromise between signal distortion and removing the unwanted frequencies. You will always have some kind of signal remaining after filtering, depending on the filter attenuation coefficient. The Butterworth filter can have almost 100% attenuation if specified as a notch filter. Here is the effect of using a butterworth filter:

This shows the original signal which is 50 Hz, and the goal is if the filter is good enough, we should not see any signal after filtering. However after applying a 2nd order butterworth filter with 15 Hz bandwidth, we do see there is still some signal especially at beginning and end of signal, and this is due to filter distortion.

enter image description here

and the frequency response of the filter looks like this in frequency domain (amplitude and phase).

enter image description here

So although the phase changes smoothly, the "notch" effect of the butterworth filter amplitude is also smooth.

On the other hand, the iirnotch filter can have a single tap at the frequency of interest, however to limit distortion, it cannot reach 100% attenuation.

Here is a signal before and after filtering with a iirnotch filter with Q = 30

enter image description here

and filter frequency response:

enter image description here

Changing Q will change the level of attenuation at 50 Hz and the distortion. I think overall, it is a good idea to use iirnotch if your noise is near or overlapping with signal of interest, otherwise Butterwoth might be a better choice.

Here is the code for the figures:

from scipy.signal import filtfilt, iirnotch, freqz, butter
from scipy.fftpack import fft, fftshift, fftfreq
import numpy as np
from matplotlib import pyplot


def do_fft(y, fs):
    Y = fftshift(fft(y, 2 ** 12))
    f = fftshift(fftfreq(2 ** 12, 1 / fs))
    return f, Y


def make_signal(fs, f0, T=250e-3):
    # T is total signal time
    t = np.arange(0, T, 1 / fs)
    y = np.sin(2 * np.pi * f0 * t)
    return t, y


def make_plot():
    fig, ax = pyplot.subplots(1, 2)
    ax[0].plot(t, y)
    ax[0].plot(t, y_filt)
    ax[0].set_title('Time domain')
    ax[0].set_xlabel('time [seconds]')
    ax[1].plot(f, abs(Y))
    ax[1].plot(f, abs(Y_filt))
    ax[1].set_title('Frequency domain')
    ax[1].set_xlabel('Freq [Hz]')

    # filter response
    fig, ax = pyplot.subplots(1, 2)
    ax[0].plot(filt_freq, abs(h))
    ax[0].set_title('Amplitude')
    ax[0].set_xlim([0, 200])
    ax[0].set_xlabel('Freq [Hz]')
    ax[1].plot(filt_freq, np.unwrap(np.angle(h)) * 180 / np.pi)
    ax[1].set_title('Phase')
    ax[1].set_xlim([0, 200])
    ax[1].set_xlabel('Freq [Hz]')

    pyplot.show()


fs = 1000
f0 = 50
t, y = make_signal(fs=fs, f0=f0)
f, Y = do_fft(y, fs=1000)

# Filtering using iirnotch
w0 = f0/(fs/2)
Q = 30
b, a = iirnotch(w0, Q)

# filter response
w, h = freqz(b, a)
filt_freq = w*fs/(2*np.pi)
y_filt = filtfilt(b, a, y)
f, Y_filt = do_fft(y_filt, fs)

make_plot()


w0 = [(f0-15)/(fs/2), (f0+15)/(fs/2)]
b, a = butter(2, w0, btype='bandstop')
w, h = freqz(b, a)
filt_freq = w*fs/(2*np.pi)
y_filt = filtfilt(b, a, y)
f, Y_filt = do_fft(y_filt, fs)
make_plot()

Upvotes: 1

Blupon
Blupon

Reputation: 1039

Is your signal contained at higher frequencies than 50 Hz ? Otherwise what about this Butterworth low pass filter on another SO post

You could perhaps use a band pass filter, like on this second other SO post

Upvotes: 0

Related Questions