Saturday, October 7, 2023

TKINTER: CHEBYSHEV FILTERING---BALIGE ACADEMY

  This is the product of BALIGE ACADEMY TEAM: Vivian Siahaan and Rismon Hasiholan Sianipar.

SEMANGAT BELAJAR dan HORAS!!!

BALIGE CITY, NORTH SUMATERA


SUPPORT OUR CHANNEL BY SUBSCRIBING TO IT:



CHEBYSHEV LOWPASS FILTERING:



#filter_utils.py
import matplotlib.pyplot as plt import numpy as np import scipy.signal as sig from am_utils import AM_Utils from fm_utils import FM_Utils from pm_utils import PM_Utils from ask_utils import ASK_Utils from fsk_utils import FSK_Utils from psk_utils import PSK_Utils class Filter_Utils: def __init__(self): self.am_utils = AM_Utils() self.fm_utils = FM_Utils() self.pm_utils = PM_Utils() self.ask_utils = ASK_Utils() self.fsk_utils = FSK_Utils() self.psk_utils = PSK_Utils() def generate_noisy_sinusoidal(self, T, F, Fs, noise_amplitude): # Defines time line t = np.arange(0, T, 1/Fs) signal = np.sin(2*np.pi*F*t) # Generate random noise noise = noise_amplitude * np.random.randn(len(t)) y = signal + noise return t, y def generate_random_binary_array(self, length): # Generate a random binary array of specified length return np.random.randint(2, size=length) def generate_noisy_square(self, T, Fs, samples_per_bit, noise_amplitude): # Defines time line t = np.arange(0, T, 1/Fs) bit_arr_size = int(2*Fs/samples_per_bit) bit_arr = self.generate_random_binary_array(bit_arr_size) square_signal = np.repeat(bit_arr, samples_per_bit)[:len(t)] # Ensures the lengths of square_signal and t match if len(square_signal) < len(t): square_signal = np.pad(square_signal, (0, len(t) - len(square_signal))) # Generate random noise noise = noise_amplitude * np.random.randn(len(t)) y = square_signal + noise return t, y def generate_noisy_amp_modulation(self, T, Fs, noise_amplitude): t, carrier_wave, modulating_wave, am_signal = self.am_utils.calculate_amplitude_modulation(Fs, T, 1, 25, 1, 5) # Generate random noise noise = noise_amplitude * np.random.randn(len(t)) y = am_signal + noise return t, y def generate_noisy_freq_modulation(self, T, Fs, noise_amplitude): t, carrier_wave, modulating_wave, fm_signal = self.fm_utils.calculate_frequency_modulation(2, Fs, T, 1, 25, 1, 5) # Generate random noise noise = noise_amplitude * np.random.randn(len(t)) y = fm_signal + noise return t, y def generate_noisy_phase_modulation(self, T, Fs, noise_amplitude): t, carrier_wave, modulating_wave, am_signal = self.pm_utils.calculate_phase_modulation(Fs, T, 1, 15, 0, 1, 5, 0) # Generate random noise noise = noise_amplitude * np.random.randn(len(t)) y = am_signal + noise return t, y def generate_noisy_ask_modulation(self, T, Fs, noise_amplitude): t, carrier_wave, modulating_wave, ask_signal = self.ask_utils.calculate_ask_modulation(Fs, T, 1, 15, 0, 50) # Generate random noise noise = noise_amplitude * np.random.randn(len(t)) y = ask_signal + noise return t, y def generate_noisy_fsk_modulation(self, T, Fs, noise_amplitude): t, carrier_wave, modulating_wave, fsk_signal = self.fsk_utils.calculate_fsk_modulation(Fs, T, 1, 15, 0, 50) # Generate random noise noise = noise_amplitude * np.random.randn(len(t)) y = fsk_signal + noise return t, y def generate_noisy_psk_modulation(self, T, Fs, noise_amplitude): t, carrier_wave, modulating_wave, psk_signal = self.psk_utils.calculate_psk_modulation(Fs, T, 1, 15, 0, 50) # Generate random noise noise = noise_amplitude * np.random.randn(len(t)) y = psk_signal + noise return t, y def perform_convolution(self, t, signal_in, time_filter): # Performs convolution filtered_output = np.convolve(signal_in, time_filter, mode='same') # Create a time array with the same length as filtered_output t_filtered = t[:len(filtered_output)] return t_filtered, filtered_output def plot_signal_filtering(self, t, signal_in, title1, time_filter, title2, figure, canvas): figure.clear() ax1 = figure.add_subplot(2,2,1) ax1.plot(t, signal_in, linewidth=2.0, color='red') ax1.set_ylabel('Amplitude', color='blue') ax1.set_xlabel('Time (second)', color='blue') ax1.set_title(title1) ax1.set_facecolor('#F0F0F0') ax1.grid(True) ax2 = figure.add_subplot(2,2,2) stem= ax2.stem(range(len(time_filter)), time_filter) stem[1].set_linewidth(3) ax2.set_xlabel('n', color='blue') ax2.set_title(title2) ax2.set_facecolor('#F0F0F0') ax2.grid(True) ax3 = figure.add_subplot(2,2,3) w, v = sig.freqz(time_filter) ax3.plot(w, 20*np.log10(abs(v)), linewidth=3) ax3.set_ylabel('Decible') ax3.set_xlabel('Radians per second (0-π)') ax3.set_title("Frequency Response of Filter") ax3.set_facecolor('#F0F0F0') ax3.grid(True) ax4 = figure.add_subplot(2,2,4) t_filtered, filtered_output = self.perform_convolution(t, signal_in, time_filter) ax4.plot(t_filtered, filtered_output, linewidth=2.0, color='red') ax4.set_ylabel('Amplitude', color='blue') ax4.set_xlabel('Time (second)', color='blue') ax4.set_title("Filtered Output") ax4.set_facecolor('#F0F0F0') ax4.grid(True) figure.tight_layout() canvas.draw() def butterworth_lowpass(self, signal_in, N, lowcut, Fs): nyqs=0.5*Fs low= lowcut/nyqs # b is the numerator of the filter & a is the denominator b, a = sig.butter(N, low, 'lowpass', analog=False) # w is the freq in z-domain & h is the magnitude in z-domain w, h = sig.freqz(b, a, fs=Fs, worN=2000) signal_out = sig.filtfilt(b, a, signal_in, axis=0) return signal_out, b, a, w, h def butterworth_bandpass(self, signal_in, order, lowcut, highcut, Fs): nyqs = 0.5* Fs low = lowcut / nyqs high = highcut/ nyqs # b is the numerator of the filter & a is the denominator b, a = sig.butter(order, [low, high], 'bandpass', analog=False) # w is the freq in z-domain & h is the magnitude in z-domain w, h = sig.freqz(b, a, fs=Fs, worN=2000) signal_out = sig.filtfilt(b, a, signal_in, axis=0) return signal_out, b, a, w, h def butterworth_highpass(self, signal_in, N, highcut, Fs): nyqs=0.5*Fs high= highcut/nyqs # b is the numerator of the filter & a is the denominator b, a = sig.butter(N, high, 'highpass', analog=False) # w is the freq in z-domain & h is the magnitude in z-domain w, h = sig.freqz(b, a, fs=Fs, worN=2000) signal_out = sig.filtfilt(b, a, signal_in, axis=0) return signal_out, b, a, w, h def butterworth_bandstop(self, signal_in, order, lowcut, highcut, Fs): nyqs = 0.5* Fs low = lowcut / nyqs high = highcut/ nyqs # b is the numerator of the filter & a is the denominator b, a = sig.butter(order, [low, high], 'bandstop', analog=False) # w is the freq in z-domain & h is the magnitude in z-domain w, h = sig.freqz(b, a, fs=Fs, worN=2000) signal_out = sig.filtfilt(b, a, signal_in, axis=0) return signal_out, b, a, w, h def cheby_type1_lowpass(self, signal_in, N, lowcut, Apass, Fs): nyqs=0.5*Fs low= lowcut/nyqs # b is the numerator of the filter & a is the denominator b, a = sig.cheby1(N, low, Apass, btype='lowpass', analog=False, output='ba') # w is the freq in z-domain & h is the magnitude in z-domain w, h = sig.freqz(b, a, fs=Fs, worN=2000) signal_out = sig.filtfilt(b, a, signal_in, axis=0) return signal_out, b, a, w, h def plot_iir_filtering(self, t, signal_in, title1, signal_out, b, a, w, h, figure, canvas): figure.clear() ax1 = figure.add_subplot(2,2,1) ax1.plot(t, signal_in, linewidth=2.0, color='red') ax1.set_ylabel('Amplitude', color='blue') ax1.set_xlabel('Time (second)', color='blue') ax1.set_title(title1) ax1.set_facecolor('#F0F0F0') ax1.grid(True) ax2 = figure.add_subplot(2,2,2) imp = sig.unit_impulse(50) response = sig.lfilter(b, a, imp) ax2.stem(np.arange(0, 50), imp, use_line_collection=True) ax2.stem(np.arange(0, 50), response, use_line_collection=True) ax2.set_xlabel('n', color='blue') ax2.set_title("Impulse Response of Filter") ax2.set_facecolor('#F0F0F0') ax2.grid(True) ax3 = figure.add_subplot(2,2,3) ax3.plot(w, 20*np.log10(abs(h)), linewidth=3) ax3.set_ylabel('Decible') ax3.set_xlabel('Hz') ax3.set_title("Frequency Response of Filter") #ax3.set_ylim(-0.5, 1) ax3.set_facecolor('#F0F0F0') ax3.grid(True) ax4 = figure.add_subplot(2,2,4) ax4.plot(t, signal_out, linewidth=2.0, color='red') ax4.set_ylabel('Amplitude', color='blue') ax4.set_xlabel('Time (second)', color='blue') ax4.set_title("Filtered Output") ax4.set_facecolor('#F0F0F0') ax4.grid(True) figure.tight_layout() canvas.draw() #form_cheby_type1_lowpass.py import tkinter as tk from tkinter import ttk from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import scipy.signal as sig from filter_utils import Filter_Utils from form1 import Form1 class Form_Cheby_Type1_LowPass: def __init__(self, window): self.window = window width = 1520 height = 760 self.window.geometry(f"{width}x{height}") #Adds label widgets self.add_labels(self.window) #Adds canvasses self.add_canvas(self.window) #Adds entry widgets self.add_entries(self.window) #Adds listbox widget self.add_listbox(self.window) #Binds events self.binds_event() #Creates neccesary objects self.filter_utils = Filter_Utils() def add_labels(self, master): # Create labels self.label1 = tk.Label(master, text="SAMPLING FREQUENCY") self.label1.grid(row=0, column=0, padx=5, pady=0.1, sticky="w") self.label2 = tk.Label(master, text="TIME PERIODE") self.label2.grid(row=2, column=0, padx=5, pady=0.1, sticky="nw") self.label3 = tk.Label(master, text="FILTER ORDER") self.label3.grid(row=4, column=0, padx=5, pady=0.1, sticky="nw") self.label4 = tk.Label(master, text="CUT-OFF FREQUENCY") self.label4.grid(row=6, column=0, padx=5, pady=0.1, sticky="nw") self.label5 = tk.Label(master, text="PASSBAND RIPPLE") self.label5.grid(row=8, column=0, padx=5, pady=0.1, sticky="nw") self.label6 = tk.Label(master, text="NOISE AMPLITUDE") self.label6.grid(row=10, column=0, padx=5, pady=0.1, sticky="nw") self.label7 = tk.Label(master, text="CHOOSE SIGNALS") self.label7.grid(row=12, column=0, padx=5, pady=0.1, sticky="nw") def add_entries(self, master): # Create entry widgets self.entry_fs = tk.Entry(master, width=20, bg="lightblue") self.entry_fs.grid(row=1, column=0, padx=5, pady=0.1, sticky="nw") self.entry_fs.insert(0, "1000") self.entry_fs.bind('<Return>', self.choose_list_widget) self.entry_periode = tk.Entry(master, width=20, bg="lightblue") self.entry_periode.grid(row=3, column=0, padx=5, pady=0.1, sticky="nw") self.entry_periode.insert(0, "1") self.entry_periode.bind('<Return>', self.choose_list_widget) self.entry_filt_ord = tk.Entry(master, width=20, bg="lightblue") self.entry_filt_ord.grid(row=5, column=0, padx=5, pady=0.1, sticky="nw") self.entry_filt_ord.insert(0, "3") self.entry_filt_ord.bind('<Return>', self.choose_list_widget) self.entry_cutoff = tk.Entry(master, width=20, bg="lightblue") self.entry_cutoff.grid(row=7, column=0, padx=5, pady=0.1, sticky="nw") self.entry_cutoff.insert(0, "100") self.entry_cutoff.bind('<Return>', self.choose_list_widget) self.entry_ripple = tk.Entry(master, width=20, bg="lightblue") self.entry_ripple.grid(row=9, column=0, padx=5, pady=0.1, sticky="nw") self.entry_ripple.insert(0, "0.1") self.entry_ripple.bind('<Return>', self.choose_list_widget) self.entry_noise = tk.Entry(master, width=20, bg="lightblue") self.entry_noise.grid(row=11, column=0, padx=5, pady=0.1, sticky="nw") self.entry_noise.insert(0, "0.1") self.entry_noise.bind('<Return>', self.choose_list_widget) def add_canvas(self, master): # Create a frame for canvas1 with a border frame1 = ttk.Frame(master, borderwidth=3, relief="groove") frame1.grid(row=0, column=1, columnspan=1, rowspan=25, padx=5, pady=5, sticky="n") # Adds canvas1 widget to frame1 self.figure1 = Figure(figsize=(13.2, 7.4), dpi=100) self.figure1.patch.set_facecolor('#F0F0F0') self.canvas1 = FigureCanvasTkAgg(self.figure1, master=frame1) self.canvas1.get_tk_widget().pack(fill=tk.BOTH, expand=True) def add_listbox(self, root): #Menambahkan listbox widget self.listbox = tk.Listbox(root, selectmode=tk.SINGLE, width=25) self.listbox.grid(row=12, column=0, sticky='nw', padx=1, pady=1) # Menyisipkan item ke dalam list widget items = ["Noisy Sinusoidal", "Noisy Square Wave", "Noisy Amplitude Modulation Signal", "Noisy Frequency Modulation Signal", "Noisy Phase Modulation Signal", "Noisy ASK Modulation Signal", "Noisy FSK Modulation Signal", "Noisy PSK Modulation Signal"] for item in items: self.listbox.insert(tk.END, item) self.listbox.config(height=len(items)) def binds_event(self): #Binds listbox to choose_list_widget() function self.listbox.bind("<<ListboxSelect>>", self.choose_list_widget) def read_and_check_input(self, fs, T, filt_ord, cutoff, Apass, amp): try: fsampling = float(fs) except ValueError: fsampling = 1000 self.entry_fs.delete(0, tk.END) self.entry_fs.insert(0, "1000") try: periode = float(T) except ValueError: periode = 1 self.entry_periode.delete(0, tk.END) self.entry_periode.insert(0, "1") try: filter_order = float(filt_ord) except ValueError: filter_order = 3 self.entry_filt_ord.delete(0, tk.END) self.entry_filt_ord.insert(0, "3") try: cutoff_freq = float(cutoff) except ValueError: cutoff_freq = 100 self.entry_cutoff.delete(0, tk.END) self.entry_cutoff.insert(0, "100") try: ripple = float(Apass) except ValueError: ripple = 0.1 self.entry_ripple.delete(0, tk.END) self.entry_ripple.insert(0, "0.1") try: noise_amp = float(amp) except ValueError: noise_amp = 0.1 self.entry_noise.delete(0, tk.END) self.entry_noise.insert(0, "0.1") return fsampling, periode, filter_order, cutoff_freq, ripple, noise_amp def choose_list_widget(self, event): chosen = self.listbox.get(self.listbox.curselection()) #Reads and checks params fsampling = self.entry_fs.get() periode = self.entry_periode.get() filter_ord = self.entry_filt_ord.get() cutoff_freq = self.entry_cutoff.get() ripple = self.entry_ripple.get() amp = self.entry_noise.get() Fs, T, filt_order, cutoff, ripple_pass, noise_amp = self.read_and_check_input(fsampling, periode, filter_ord, cutoff_freq, ripple, amp) if chosen == "Noisy Sinusoidal": freq_sinus = 10 t, y = self.filter_utils.generate_noisy_sinusoidal(T, freq_sinus, Fs, noise_amp) signal_out, b, a, w, h = self.filter_utils.cheby_type1_lowpass(y, filt_order, cutoff, ripple_pass, Fs) self.filter_utils.plot_iir_filtering(t, y, f"Noisy Sinusoidal Signal, Freq={freq_sinus}, Noise Amp={noise_amp}", signal_out, b, a, w, h, self.figure1, self.canvas1) if chosen == "Noisy Square Wave": samples_per_bit = 50 t, y = self.filter_utils.generate_noisy_square(T, Fs, samples_per_bit, noise_amp) signal_out, b, a, w, h = self.filter_utils.cheby_type1_lowpass(y, filt_order, cutoff, ripple_pass, Fs) self.filter_utils.plot_iir_filtering(t, y, f"Noisy Square Signal, Samples Per Bit={samples_per_bit}, Noise Amp={noise_amp}", signal_out, b, a, w, h, self.figure1, self.canvas1) if chosen == "Noisy Amplitude Modulation Signal": t, y = self.filter_utils.generate_noisy_amp_modulation(T, Fs, noise_amp) signal_out, b, a, w, h = self.filter_utils.cheby_type1_lowpass(y, filt_order, cutoff, ripple_pass, Fs) self.filter_utils.plot_iir_filtering(t, y, f"Noisy Amplitude Modulation Signal, Noise Amp={noise_amp}", signal_out, b, a, w, h, self.figure1, self.canvas1) if chosen == "Noisy Frequency Modulation Signal": t, y = self.filter_utils.generate_noisy_freq_modulation(T, Fs, noise_amp) signal_out, b, a, w, h = self.filter_utils.cheby_type1_lowpass(y, filt_order, cutoff, ripple_pass, Fs) self.filter_utils.plot_iir_filtering(t, y, f"Noisy Frequency Modulation Signal, Noise Amp={noise_amp}", signal_out, b, a, w, h, self.figure1, self.canvas1) if chosen == "Noisy Phase Modulation Signal": t, y = self.filter_utils.generate_noisy_phase_modulation(T, Fs, noise_amp) signal_out, b, a, w, h = self.filter_utils.cheby_type1_lowpass(y, filt_order, cutoff, ripple_pass, Fs) self.filter_utils.plot_iir_filtering(t, y, f"Noisy Phase Modulation Signal, Noise Amp={noise_amp}", signal_out, b, a, w, h, self.figure1, self.canvas1) if chosen == "Noisy ASK Modulation Signal": t, y = self.filter_utils.generate_noisy_ask_modulation(T, Fs, noise_amp) signal_out, b, a, w, h = self.filter_utils.cheby_type1_lowpass(y, filt_order, cutoff, ripple_pass, Fs) self.filter_utils.plot_iir_filtering(t, y, f"Noisy ASK Modulation Signal, Noise Amp={noise_amp}", signal_out, b, a, w, h, self.figure1, self.canvas1) if chosen == "Noisy FSK Modulation Signal": t, y = self.filter_utils.generate_noisy_fsk_modulation(T, Fs, noise_amp) signal_out, b, a, w, h = self.filter_utils.cheby_type1_lowpass(y, filt_order, cutoff, ripple_pass, Fs) self.filter_utils.plot_iir_filtering(t, y, f"Noisy FSK Modulation Signal, Noise Amp={noise_amp}", signal_out, b, a, w, h, self.figure1, self.canvas1) if chosen == "Noisy PSK Modulation Signal": t, y = self.filter_utils.generate_noisy_psk_modulation(T, Fs, noise_amp) signal_out, b, a, w, h = self.filter_utils.cheby_type1_lowpass(y, filt_order, cutoff, ripple_pass, Fs) self.filter_utils.plot_iir_filtering(t, y, f"Noisy PSK Modulation Signal, Noise Amp={noise_amp}", signal_out, b, a, w, h, self.figure1, self.canvas1) if __name__ == "__main__": window = tk.Tk() Form_Cheby_Type1_LowPass(window) window.mainloop()


DOWNLOAD FULL SOURCE CODE VERSION 14.0





No comments: