plotlinlog.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. import pandas as pd
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. show = False
  5. plot50 = True
  6. plot1k = True
  7. def print_mag(fig, axs, filename, yrange):
  8. axs.set_title('Magnitude response')
  9. axs.set_xlabel('Frequency (Hz)')
  10. axs.set_ylabel('Gain (dB)', rotation=0)
  11. axs.minorticks_on()
  12. axs.grid(linewidth=1, color='black', linestyle='dotted')
  13. axs.grid(linewidth=0.2, color='black', linestyle='dotted', which='minor')
  14. axs.legend()
  15. axs.axis(xmin=9e3, xmax=1e9)
  16. axs.axis(ymin=yrange[0], ymax=yrange[1])
  17. fig.set_size_inches(9, 5)
  18. fig.canvas.set_window_title(filename)
  19. if(show):
  20. fig.show()
  21. else:
  22. fig.savefig('figures/' + filename, dpi=400)
  23. def print_phase(fig, axs, filename):
  24. axs.set_title('Phase response')
  25. axs.set_xlabel('Frequency (Hz)')
  26. axs.set_ylabel('Phase (°)', rotation=0)
  27. axs.minorticks_on()
  28. axs.grid(linewidth=1, color='black', linestyle='dotted')
  29. axs.grid(linewidth=0.2, color='black', linestyle='dotted', which='minor')
  30. axs.legend()
  31. axs.axis(xmin=9e3, xmax=1e9)
  32. axs.axis(ymin=-200, ymax=200)
  33. fig.set_size_inches(9, 5)
  34. fig.canvas.set_window_title(filename)
  35. if(show):
  36. fig.show()
  37. else:
  38. fig.savefig('figures/' + filename, dpi=400)
  39. def read_s21(filename, label):
  40. df = pd.read_csv(filename,header=0, names=['freq','re','im'],usecols=[0,1,2], skiprows=2)
  41. resp = pd.DataFrame(columns=['freq','resp'])
  42. resp.freq = df.freq
  43. resp.resp = df.re + df.im * 1j
  44. return [resp, label]
  45. def read_ltspice_txt(filename, label):
  46. df = pd.read_csv(filename,header=0, sep='\t', names=['freq','mag','phase'],usecols=[0,1,2], skiprows=1)
  47. return [df, label]
  48. def plot_mag(axs, dataset):
  49. resp = dataset[0]
  50. ulabel = dataset[1]
  51. axs.semilogx(resp.freq, 20*np.log10(np.abs(resp.resp)), label=ulabel)
  52. def plot_phase(axs, dataset):
  53. resp = dataset[0]
  54. ulabel = dataset[1]
  55. axs.semilogx(resp.freq, 180/np.pi*np.angle(resp.resp), label=ulabel)
  56. def plot_ltspice_mag(axs, dataset):
  57. resp = dataset[0]
  58. ulabel = dataset[1]
  59. axs.semilogx(resp.freq, resp.mag, label=ulabel)
  60. def plot_ltspice_phase(axs, dataset):
  61. resp = dataset[0]
  62. ulabel = dataset[1]
  63. axs.semilogx(resp.freq, resp.phase, label=ulabel)
  64. # Prepare all values
  65. s21_50_m = read_s21(r'50-minus/measure.csv', 'BK 50 minus')
  66. s21_50_p = read_s21(r'50-plus/measure.csv', 'BK 50 plus')
  67. s21_50_pe = read_s21(r'50-pe/measure.csv', 'BK 50 PE')
  68. s21_50_m_all_open = read_s21(r'50-minus-all-open/measure.csv', 'BK 50 minus, all open')
  69. s21_50_m_other_closed = read_s21(r'50-minus-open-other-closed/measure.csv', 'BK 50 minus, other closed')
  70. s21_50_p_all_open = read_s21(r'50-plus-all-open/measure.csv', 'BK 50 plus, all open')
  71. s21_50_p_other_closed = read_s21(r'50-plus-open-other-closed/measure.csv', 'BK 50 plus, other closed')
  72. s21_50_pe_all_open = read_s21(r'50-pe-all-open/measure.csv', 'BK 50 PE, all open')
  73. s21_50_pe_other_closed = read_s21(r'50-pe-open-other-closed/measure.csv', 'BK 50 PE, other closed')
  74. s21_1k_m = read_s21(r'1k-minus/measure.csv', 'BK 1000 minus')
  75. s21_1k_p = read_s21(r'1k-plus/measure.csv', 'BK 1000 plus')
  76. s21_1k_pe = read_s21(r'1k-pe/measure.csv', 'BK 1000 PE')
  77. s21_1k_m_all_open = read_s21(r'1k-minus-all-open/measure.csv', 'BK 1000 minus, all open')
  78. s21_1k_m_other_closed = read_s21(r'1k-minus-open-other-closed/measure.csv', 'BK 1000 minus, other closed')
  79. s21_1k_p_all_open = read_s21(r'1k-plus-all-open/measure.csv', 'BK 1000 plus, all open')
  80. s21_1k_p_other_closed = read_s21(r'1k-plus-open-other-closed/measure.csv', 'BK 1000 plus, other closed')
  81. s21_1k_pe_all_open = read_s21(r'1k-pe-all-open/measure.csv', 'BK 1000 PE, all open')
  82. s21_1k_pe_other_closed = read_s21(r'1k-pe-open-other-closed/measure.csv', 'BK 1000 PE, other closed')
  83. sim_50_wo_comp = read_ltspice_txt(r'50-simulation-nocomp/attenuator 54db.txt', 'Simulated BK 50 no compensation')
  84. sim_1k_wo_comp = read_ltspice_txt(r'1k-simulation-nocomp/attenuator 60db.txt', 'Simulated BK 1000 no compensation')
  85. sim_50_w_comp = read_ltspice_txt(r'50-simulation-comp/attenuator 54db.txt', 'Simulated BK 50 with compensation')
  86. sim_1k_w_comp = read_ltspice_txt(r'1k-simulation-comp/attenuator 60db.txt', 'Simulated BK 1000 with compensation')
  87. pat_50 = read_s21(r'pat50/measure.csv', 'PAT 50')
  88. pat_1k = read_s21(r'pat1000/measure.csv', 'PAT 1000')
  89. relay_off = read_s21(r'relay/relay-off.csv', 'Single open relay')
  90. if(plot50):
  91. ################# 50 Ohm #################
  92. # Simulated 50 Ohm vs Constructed 50 Ohm (left)
  93. fig11, axs11 = plt.subplots()
  94. plot_mag(axs11, s21_50_m)
  95. plot_ltspice_mag(axs11, sim_50_wo_comp)
  96. print_mag(fig11,axs11, 'simulated-vs-bk50-mag.png', [-60,-35])
  97. # Simulated 50 Ohm vs Constructed 50 Ohm (left) Phase response
  98. fig12, axs12 = plt.subplots()
  99. plot_phase(axs12, s21_50_m)
  100. plot_ltspice_phase(axs12, sim_50_wo_comp)
  101. print_phase(fig12,axs12, 'simulated-vs-bk50-phase.png')
  102. # PAT50 vs Constructed 50 Ohm (left)
  103. fig13, axs13 = plt.subplots()
  104. plot_mag(axs13, s21_50_m)
  105. plot_mag(axs13, pat_50)
  106. print_mag(fig13,axs13, 'pat50-vs-bk50-mag.png', [-60,-50])
  107. # PAT50 vs Constructed 50 Ohm (left) Phase response
  108. fig14, axs14 = plt.subplots()
  109. plot_phase(axs14, s21_50_m)
  110. plot_phase(axs14, pat_50)
  111. print_phase(fig14,axs14, 'pat50-vs-bk50-phase.png')
  112. # Constructed 50 Ohm three paths
  113. fig15, axs15 = plt.subplots()
  114. plot_mag(axs15, s21_50_m)
  115. plot_mag(axs15, s21_50_p)
  116. plot_mag(axs15, s21_50_pe)
  117. print_mag(fig15,axs15, 'bk50-paths.png', [-60,-50])
  118. # Constructed 50 Ohm adjacent suppression
  119. fig16, axs16 = plt.subplots()
  120. plot_mag(axs16, s21_50_m_all_open)
  121. plot_mag(axs16, s21_50_m_other_closed)
  122. plot_mag(axs16, s21_50_p_all_open)
  123. plot_mag(axs16, s21_50_p_other_closed)
  124. plot_mag(axs16, s21_50_pe_all_open)
  125. plot_mag(axs16, s21_50_pe_other_closed)
  126. plot_mag(axs16, relay_off)
  127. plot_mag(axs16, s21_50_m)
  128. print_mag(fig16,axs16, 'bk50-suppression.png', [-120,-10])
  129. # Simulated 50 Ohm, with vs without compensation
  130. fig17, axs17 = plt.subplots()
  131. plot_ltspice_mag(axs17, sim_50_wo_comp)
  132. plot_ltspice_mag(axs17, sim_50_w_comp)
  133. print_mag(fig17,axs17, 'simulated-50-w-vs-wo-comp-mag.png', [-60,-35])
  134. # Simulated 50 Ohm, with vs without compensation Phase response
  135. fig18, axs18 = plt.subplots()
  136. plot_ltspice_phase(axs18, sim_50_wo_comp)
  137. plot_ltspice_phase(axs18, sim_50_w_comp)
  138. print_phase(fig18,axs18, 'simulated-50-w-vs-wo-comp-phase.png')
  139. if(plot1k):
  140. ################# 1 kOhm #################
  141. # Simulated 1 kOhm vs Constructed 1k Ohm (left)
  142. fig21, axs21 = plt.subplots()
  143. plot_mag(axs21, s21_1k_m)
  144. plot_ltspice_mag(axs21, sim_1k_wo_comp)
  145. print_mag(fig21,axs21, 'simulated-vs-bk1000-mag.png', [-70,-35])
  146. # Simulated 1 kOhm vs Constructed 1k Ohm (left) Phase response
  147. fig22, axs22 = plt.subplots()
  148. plot_phase(axs22, s21_1k_m)
  149. plot_ltspice_phase(axs22, sim_1k_wo_comp)
  150. print_phase(fig22,axs22, 'simulated-vs-bk1000-phase.png')
  151. # PAT1k vs Constructed 1 kOhm (left)
  152. fig23, axs23 = plt.subplots()
  153. plot_mag(axs23, s21_1k_m)
  154. plot_mag(axs23, pat_1k)
  155. print_mag(fig23,axs23, 'pat1k-vs-bk1000-mag.png', [-70,-40])
  156. # PAT1k vs Constructed 1 kOhm (left) Phase response
  157. fig24, axs24 = plt.subplots()
  158. plot_phase(axs24, s21_1k_m)
  159. plot_phase(axs24, pat_1k)
  160. print_phase(fig24,axs24, 'pat1k-vs-bk1000-phase.png')
  161. # Constructed 1 kOhm three paths
  162. fig25, axs25 = plt.subplots()
  163. plot_mag(axs25, s21_1k_m)
  164. plot_mag(axs25, s21_1k_p)
  165. plot_mag(axs25, s21_1k_pe)
  166. print_mag(fig25,axs25, 'bk1000-paths.png', [-70,-40])
  167. # Constructed 1 kOhm adjacent suppression
  168. fig26, axs26 = plt.subplots()
  169. plot_mag(axs26, s21_1k_m_all_open)
  170. plot_mag(axs26, s21_1k_m_other_closed)
  171. plot_mag(axs26, s21_1k_p_all_open)
  172. plot_mag(axs26, s21_1k_p_other_closed)
  173. plot_mag(axs26, s21_1k_pe_all_open)
  174. plot_mag(axs26, s21_1k_pe_other_closed)
  175. plot_mag(axs26, relay_off)
  176. plot_mag(axs26, s21_1k_m)
  177. print_mag(fig26,axs26, 'bk1000-suppression.png', [-120,-10])
  178. # Simulated 1 kOhm, with vs without compensation
  179. fig27, axs27 = plt.subplots()
  180. plot_ltspice_mag(axs27, sim_1k_wo_comp)
  181. plot_ltspice_mag(axs27, sim_1k_w_comp)
  182. print_mag(fig27,axs27, 'simulated-1k-w-vs-wo-comp-mag.png', [-65,-40])
  183. # Simulated 1 kOhm, with vs without compensation Phase response
  184. fig28, axs28 = plt.subplots()
  185. plot_ltspice_phase(axs28, sim_1k_wo_comp)
  186. plot_ltspice_phase(axs28, sim_1k_w_comp)
  187. print_phase(fig28,axs28, 'simulated-1k-w-vs-wo-comp-phase.png')
  188. print("Finished!")
  189. #Pause
  190. if(show):
  191. input()