import pandas as pd import numpy as np import matplotlib.pyplot as plt show = False plot50 = True plot1k = True def print_mag(fig, axs, filename, yrange): axs.set_title('Magnitude response') axs.set_xlabel('Frequency (Hz)') axs.set_ylabel('Gain (dB)', rotation=0) axs.minorticks_on() axs.grid(linewidth=1, color='black', linestyle='dotted') axs.grid(linewidth=0.2, color='black', linestyle='dotted', which='minor') axs.legend() axs.axis(xmin=9e3, xmax=1e9) axs.axis(ymin=yrange[0], ymax=yrange[1]) fig.set_size_inches(9, 5) fig.canvas.set_window_title(filename) if(show): fig.show() else: fig.savefig('figures/' + filename, dpi=400) def print_phase(fig, axs, filename): axs.set_title('Phase response') axs.set_xlabel('Frequency (Hz)') axs.set_ylabel('Phase (°)', rotation=0) axs.minorticks_on() axs.grid(linewidth=1, color='black', linestyle='dotted') axs.grid(linewidth=0.2, color='black', linestyle='dotted', which='minor') axs.legend() axs.axis(xmin=9e3, xmax=1e9) axs.axis(ymin=-200, ymax=200) fig.set_size_inches(9, 5) fig.canvas.set_window_title(filename) if(show): fig.show() else: fig.savefig('figures/' + filename, dpi=400) def read_s21(filename, label): df = pd.read_csv(filename,header=0, names=['freq','re','im'],usecols=[0,1,2], skiprows=2) resp = pd.DataFrame(columns=['freq','resp']) resp.freq = df.freq resp.resp = df.re + df.im * 1j return [resp, label] def read_ltspice_txt(filename, label): df = pd.read_csv(filename,header=0, sep='\t', names=['freq','mag','phase'],usecols=[0,1,2], skiprows=1) return [df, label] def plot_mag(axs, dataset): resp = dataset[0] ulabel = dataset[1] axs.semilogx(resp.freq, 20*np.log10(np.abs(resp.resp)), label=ulabel) def plot_phase(axs, dataset): resp = dataset[0] ulabel = dataset[1] axs.semilogx(resp.freq, 180/np.pi*np.angle(resp.resp), label=ulabel) def plot_ltspice_mag(axs, dataset): resp = dataset[0] ulabel = dataset[1] axs.semilogx(resp.freq, resp.mag, label=ulabel) def plot_ltspice_phase(axs, dataset): resp = dataset[0] ulabel = dataset[1] axs.semilogx(resp.freq, resp.phase, label=ulabel) # Prepare all values s21_50_m = read_s21(r'50-minus/measure.csv', 'BK 50 minus') s21_50_p = read_s21(r'50-plus/measure.csv', 'BK 50 plus') s21_50_pe = read_s21(r'50-pe/measure.csv', 'BK 50 PE') s21_50_m_all_open = read_s21(r'50-minus-all-open/measure.csv', 'BK 50 minus, all open') s21_50_m_other_closed = read_s21(r'50-minus-open-other-closed/measure.csv', 'BK 50 minus, other closed') s21_50_p_all_open = read_s21(r'50-plus-all-open/measure.csv', 'BK 50 plus, all open') s21_50_p_other_closed = read_s21(r'50-plus-open-other-closed/measure.csv', 'BK 50 plus, other closed') s21_50_pe_all_open = read_s21(r'50-pe-all-open/measure.csv', 'BK 50 PE, all open') s21_50_pe_other_closed = read_s21(r'50-pe-open-other-closed/measure.csv', 'BK 50 PE, other closed') s21_1k_m = read_s21(r'1k-minus/measure.csv', 'BK 1000 minus') s21_1k_p = read_s21(r'1k-plus/measure.csv', 'BK 1000 plus') s21_1k_pe = read_s21(r'1k-pe/measure.csv', 'BK 1000 PE') s21_1k_m_all_open = read_s21(r'1k-minus-all-open/measure.csv', 'BK 1000 minus, all open') s21_1k_m_other_closed = read_s21(r'1k-minus-open-other-closed/measure.csv', 'BK 1000 minus, other closed') s21_1k_p_all_open = read_s21(r'1k-plus-all-open/measure.csv', 'BK 1000 plus, all open') s21_1k_p_other_closed = read_s21(r'1k-plus-open-other-closed/measure.csv', 'BK 1000 plus, other closed') s21_1k_pe_all_open = read_s21(r'1k-pe-all-open/measure.csv', 'BK 1000 PE, all open') s21_1k_pe_other_closed = read_s21(r'1k-pe-open-other-closed/measure.csv', 'BK 1000 PE, other closed') sim_50_wo_comp = read_ltspice_txt(r'50-simulation-nocomp/attenuator 54db.txt', 'Simulated BK 50 no compensation') sim_1k_wo_comp = read_ltspice_txt(r'1k-simulation-nocomp/attenuator 60db.txt', 'Simulated BK 1000 no compensation') sim_50_w_comp = read_ltspice_txt(r'50-simulation-comp/attenuator 54db.txt', 'Simulated BK 50 with compensation') sim_1k_w_comp = read_ltspice_txt(r'1k-simulation-comp/attenuator 60db.txt', 'Simulated BK 1000 with compensation') pat_50 = read_s21(r'pat50/measure.csv', 'PAT 50') pat_1k = read_s21(r'pat1000/measure.csv', 'PAT 1000') relay_off = read_s21(r'relay/relay-off.csv', 'Single open relay') if(plot50): ################# 50 Ohm ################# # Simulated 50 Ohm vs Constructed 50 Ohm (left) fig11, axs11 = plt.subplots() plot_mag(axs11, s21_50_m) plot_ltspice_mag(axs11, sim_50_wo_comp) print_mag(fig11,axs11, 'simulated-vs-bk50-mag.png', [-60,-35]) # Simulated 50 Ohm vs Constructed 50 Ohm (left) Phase response fig12, axs12 = plt.subplots() plot_phase(axs12, s21_50_m) plot_ltspice_phase(axs12, sim_50_wo_comp) print_phase(fig12,axs12, 'simulated-vs-bk50-phase.png') # PAT50 vs Constructed 50 Ohm (left) fig13, axs13 = plt.subplots() plot_mag(axs13, s21_50_m) plot_mag(axs13, pat_50) print_mag(fig13,axs13, 'pat50-vs-bk50-mag.png', [-60,-50]) # PAT50 vs Constructed 50 Ohm (left) Phase response fig14, axs14 = plt.subplots() plot_phase(axs14, s21_50_m) plot_phase(axs14, pat_50) print_phase(fig14,axs14, 'pat50-vs-bk50-phase.png') # Constructed 50 Ohm three paths fig15, axs15 = plt.subplots() plot_mag(axs15, s21_50_m) plot_mag(axs15, s21_50_p) plot_mag(axs15, s21_50_pe) print_mag(fig15,axs15, 'bk50-paths.png', [-60,-50]) # Constructed 50 Ohm adjacent suppression fig16, axs16 = plt.subplots() plot_mag(axs16, s21_50_m_all_open) plot_mag(axs16, s21_50_m_other_closed) plot_mag(axs16, s21_50_p_all_open) plot_mag(axs16, s21_50_p_other_closed) plot_mag(axs16, s21_50_pe_all_open) plot_mag(axs16, s21_50_pe_other_closed) plot_mag(axs16, relay_off) plot_mag(axs16, s21_50_m) print_mag(fig16,axs16, 'bk50-suppression.png', [-120,-10]) # Simulated 50 Ohm, with vs without compensation fig17, axs17 = plt.subplots() plot_ltspice_mag(axs17, sim_50_wo_comp) plot_ltspice_mag(axs17, sim_50_w_comp) print_mag(fig17,axs17, 'simulated-50-w-vs-wo-comp-mag.png', [-60,-35]) # Simulated 50 Ohm, with vs without compensation Phase response fig18, axs18 = plt.subplots() plot_ltspice_phase(axs18, sim_50_wo_comp) plot_ltspice_phase(axs18, sim_50_w_comp) print_phase(fig18,axs18, 'simulated-50-w-vs-wo-comp-phase.png') if(plot1k): ################# 1 kOhm ################# # Simulated 1 kOhm vs Constructed 1k Ohm (left) fig21, axs21 = plt.subplots() plot_mag(axs21, s21_1k_m) plot_ltspice_mag(axs21, sim_1k_wo_comp) print_mag(fig21,axs21, 'simulated-vs-bk1000-mag.png', [-70,-35]) # Simulated 1 kOhm vs Constructed 1k Ohm (left) Phase response fig22, axs22 = plt.subplots() plot_phase(axs22, s21_1k_m) plot_ltspice_phase(axs22, sim_1k_wo_comp) print_phase(fig22,axs22, 'simulated-vs-bk1000-phase.png') # PAT1k vs Constructed 1 kOhm (left) fig23, axs23 = plt.subplots() plot_mag(axs23, s21_1k_m) plot_mag(axs23, pat_1k) print_mag(fig23,axs23, 'pat1k-vs-bk1000-mag.png', [-70,-40]) # PAT1k vs Constructed 1 kOhm (left) Phase response fig24, axs24 = plt.subplots() plot_phase(axs24, s21_1k_m) plot_phase(axs24, pat_1k) print_phase(fig24,axs24, 'pat1k-vs-bk1000-phase.png') # Constructed 1 kOhm three paths fig25, axs25 = plt.subplots() plot_mag(axs25, s21_1k_m) plot_mag(axs25, s21_1k_p) plot_mag(axs25, s21_1k_pe) print_mag(fig25,axs25, 'bk1000-paths.png', [-70,-40]) # Constructed 1 kOhm adjacent suppression fig26, axs26 = plt.subplots() plot_mag(axs26, s21_1k_m_all_open) plot_mag(axs26, s21_1k_m_other_closed) plot_mag(axs26, s21_1k_p_all_open) plot_mag(axs26, s21_1k_p_other_closed) plot_mag(axs26, s21_1k_pe_all_open) plot_mag(axs26, s21_1k_pe_other_closed) plot_mag(axs26, relay_off) plot_mag(axs26, s21_1k_m) print_mag(fig26,axs26, 'bk1000-suppression.png', [-120,-10]) # Simulated 1 kOhm, with vs without compensation fig27, axs27 = plt.subplots() plot_ltspice_mag(axs27, sim_1k_wo_comp) plot_ltspice_mag(axs27, sim_1k_w_comp) print_mag(fig27,axs27, 'simulated-1k-w-vs-wo-comp-mag.png', [-65,-40]) # Simulated 1 kOhm, with vs without compensation Phase response fig28, axs28 = plt.subplots() plot_ltspice_phase(axs28, sim_1k_wo_comp) plot_ltspice_phase(axs28, sim_1k_w_comp) print_phase(fig28,axs28, 'simulated-1k-w-vs-wo-comp-phase.png') print("Finished!") #Pause if(show): input()