IIR stands for Infinite Impulse Response, It is one of the striking features of many linear-time invariant systems that are distinguished by having an impulse response h(t)/h(n) which does not become zero after some point but instead continues infinitely.
What is IIR Notch Filter?
A Notch Filter is a bandstop filter with a very narrow stopband and two passbands, it actually highly attenuates/eliminates a particular frequency component from the input signal while leaving the amplitude of the other frequencies more or less unchanged.
The specifications are as follows:
- Generate a signal of 15 Hz corrupted with 50 Hz power line frequency.
- Sampling frequency: 1 kHz
Approach:
Step 1: Importing all the necessary libraries.
from scipy import signal
import matplotlib.pyplot as plt
import numpy as np
|
Step 2: Defining the specifications of the IIR Bandpass Notch-Filter
# Create/view notch filter samp_freq = 1000 # Sample frequency (Hz)
notch_freq = 50.0 # Frequency to be removed from signal (Hz)
quality_factor = 20.0 # Quality factor
|
Step 3:
# Design a notch filter using signal.iirnotch b_notch, a_notch = signal.iirnotch(notch_freq, quality_factor, samp_freq)
# Compute magnitude response of the designed filter freq, h = signal.freqz(b_notch, a_notch, fs = 2 * np.pi)
|
Step 4:
fig = plt.figure(figsize = ( 8 , 6 ))
# Plot magnitude response of the filter plt.plot(freq * samp_freq / ( 2 * np.pi), 20 * np.log10( abs (h)),
'r' , label = 'Bandpass filter' , linewidth = '2' )
plt.xlabel( 'Frequency [Hz]' , fontsize = 20 )
plt.ylabel( 'Magnitude [dB]' , fontsize = 20 )
plt.title( 'Notch Filter' , fontsize = 20 )
plt.grid() |
Output:
Step 5:
# Create and view signal that is a mixture # of two different frequencies f1 = 15 # Frequency of 1st signal in Hz
f2 = 50 # Frequency of 2nd signal in Hz
# Set time vector # Generate 1000 sample sequence in 1 sec n = np.linspace( 0 , 1 , 1000 )
|
Step 6:
# Generate the signal containing f1 and f2 noisySignal = np.sin( 2 * np.pi * 15 * n) + np.sin( 2 * np.pi * 50 * n) + \
np.random.normal( 0 , . 1 , 1000 ) * 0.03
|
Step 7:
# Plotting fig = plt.figure(figsize = ( 8 , 6 ))
plt.subplot( 211 )
plt.plot(n, noisySignal, color = 'r' , linewidth = 2 )
plt.xlabel( 'Time' , fontsize = 20 )
plt.ylabel( 'Magnitude' , fontsize = 18 )
plt.title( 'Noisy Signal' , fontsize = 20 )
|
Output:
Step 8:
# Apply notch filter to the noisy signal using signal.filtfilt outputSignal = signal.filtfilt(b_notch, a_notch, noisySignal)
|
Step 9:
# Plot notch-filtered version of signal plt.subplot( 212 )
# Plot output signal of notch filter plt.plot(n, outputSignal) plt.xlabel( 'Time' , fontsize = 20 )
plt.ylabel( 'Magnitude' , fontsize = 18 )
plt.title( 'Filtered Signal' , fontsize = 20 )
plt.subplots_adjust(hspace = 0.5 )
fig.tight_layout() plt.show() |
Output:
Below is the implementation:
from scipy import signal
import matplotlib.pyplot as plt
import numpy as np
# Create/view notch filter samp_freq = 1000 # Sample frequency (Hz)
notch_freq = 50.0 # Frequency to be removed from signal (Hz)
quality_factor = 20.0 # Quality factor
# Design a notch filter using signal.iirnotch b_notch, a_notch = signal.iirnotch(notch_freq, quality_factor, samp_freq)
# Compute magnitude response of the designed filter freq, h = signal.freqz(b_notch, a_notch, fs = samp_freq)
fig = plt.figure(figsize = ( 8 , 6 ))
# Plot magnitude response of the filter plt.plot(freq * samp_freq / ( 2 * np.pi), 20 * np.log10( abs (h)),
'r' , label = 'Bandpass filter' , linewidth = '2' )
plt.xlabel( 'Frequency [Hz]' , fontsize = 20 )
plt.ylabel( 'Magnitude [dB]' , fontsize = 20 )
plt.title( 'Notch Filter' , fontsize = 20 )
plt.grid() # Create and view signal that is a mixture of two different frequencies f1 = 15 # Frequency of 1st signal in Hz
f2 = 50 # Frequency of 2nd signal in Hz
# Set time vector n = np.linspace( 0 , 1 , 1000 ) # Generate 1000 sample sequence in 1 sec
# Generate the signal containing f1 and f2 noisySignal = np.sin( 2 * np.pi * 15 * n) + np.sin( 2 * np.pi * 50 * n) + \
np.random.normal( 0 , . 1 , 1000 ) * 0.03
# Plotting fig = plt.figure(figsize = ( 8 , 6 ))
plt.subplot( 211 )
plt.plot(n, noisySignal, color = 'r' , linewidth = 2 )
plt.xlabel( 'Time' , fontsize = 20 )
plt.ylabel( 'Magnitude' , fontsize = 18 )
plt.title( 'Noisy Signal' , fontsize = 20 )
# Apply notch filter to the noisy signal using signal.filtfilt outputSignal = signal.filtfilt(b_notch, a_notch, noisySignal)
# Plot notch-filtered version of signal plt.subplot( 212 )
# Plot output signal of notch filter plt.plot(n, outputSignal) plt.xlabel( 'Time' , fontsize = 20 )
plt.ylabel( 'Magnitude' , fontsize = 18 )
plt.title( 'Filtered Signal' , fontsize = 20 )
plt.subplots_adjust(hspace = 0.5 )
fig.tight_layout() plt.show() |
Output: