front.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import math
  2. XLIM = [-1.1, 1.1]
  3. YLIM = [-1.1, 1.1]
  4. def round_up(x, n=7):
  5. if x == 0:
  6. return 0
  7. deg = math.floor(math.log(abs(x), 10))
  8. return (10 ** deg) * round(x / (10 ** deg), n - 1)
  9. def circle(ax, x, y, radius, color='#1946BA'):
  10. from matplotlib.patches import Ellipse
  11. circle = Ellipse((x, y), radius * 2, radius * 2, clip_on=False,
  12. zorder=2, linewidth=2, edgecolor=color, facecolor=(0, 0, 0, .0125))
  13. ax.add_artist(circle)
  14. import streamlit as st
  15. import matplotlib.pyplot as plt
  16. import numpy as np
  17. import math
  18. def plot_data(r, i, g):
  19. fig = plt.figure(figsize=(10, 10))
  20. ax = fig.add_subplot()
  21. ax.set_xlim(XLIM)
  22. ax.set_ylim(YLIM)
  23. major_ticks = np.arange(-1.0, 1.1, 0.25)
  24. minor_ticks = np.arange(-1.1, 1.1, 0.05)
  25. ax.set_xticks(major_ticks)
  26. ax.set_xticks(minor_ticks, minor=True)
  27. ax.set_yticks(major_ticks)
  28. ax.set_yticks(minor_ticks, minor=True)
  29. ax.grid(which='major', color='grey', linewidth=1.5)
  30. ax.grid(which='minor', color='grey', linewidth=0.5, linestyle=':')
  31. plt.xlabel(r'$Re(\Gamma)$', color='gray', fontsize=16, fontname="Cambria")
  32. plt.ylabel('$Im(\Gamma)$', color='gray', fontsize=16, fontname="Cambria")
  33. plt.title('Smith chart', fontsize=24, fontname="Cambria")
  34. # cirlce approximation
  35. radius = abs(g[1] - g[0] / g[2]) / 2
  36. x = ((g[1] + g[0] / g[2]) / 2).real
  37. y = ((g[1] + g[0] / g[2]) / 2).imag
  38. circle(ax, x, y, radius, color='#FF8400')
  39. #
  40. # unit circle
  41. circle(ax, 0, 0, 1)
  42. #
  43. # data
  44. ax.plot(r, i, '+', ms=10, mew=2, color='#1946BA')
  45. #
  46. st.pyplot(fig)
  47. def plot_ref_from_f(r, i, f):
  48. fig = plt.figure(figsize=(10, 10))
  49. abs_S = list(math.sqrt(r[n] ** 2 + i[n] ** 2) for n in range(len(r)))
  50. xlim = [min(f)-abs(max(f)-min(f))*0.1, max(f)+abs(max(f)-min(f))*0.1]
  51. ylim = [min(abs_S)-abs(max(abs_S)-min(abs_S))*0.5, max(abs_S)+abs(max(abs_S)-min(abs_S))*0.5]
  52. ax = fig.add_subplot()
  53. ax.set_xlim(xlim)
  54. ax.set_ylim(ylim)
  55. ax.grid(which='major', color='k', linewidth=1)
  56. ax.grid(which='minor', color='grey', linestyle=':', linewidth=0.5)
  57. plt.xlabel(r'$f,\; 1/c$', color='gray', fontsize=16, fontname="Cambria")
  58. plt.ylabel('$|\Gamma|$', color='gray', fontsize=16, fontname="Cambria")
  59. plt.title('Modulus of reflection coefficient from frequency', fontsize=24, fontname="Cambria")
  60. ax.plot(f, abs_S, '+', ms=10, mew=2, color='#1946BA')
  61. st.pyplot(fig)
  62. def run(calc_function):
  63. data = []
  64. uploaded_file = st.file_uploader('Upload a csv')
  65. if uploaded_file is not None:
  66. data = uploaded_file.readlines()
  67. col1, col2 = st.columns(2)
  68. select_data_format = col1.selectbox('Choose data format from a list',['Frequency, Re(S11), Im(S11)','Frequency, Re(Zin), Im(Zin)'])
  69. select_separator = col2.selectbox('Choose separator',['" "' ,'","','";"'])
  70. select_coupling_losses = st.checkbox('Apply corrections for coupling losses (lossy coupling)')
  71. def is_float(element) -> bool:
  72. try:
  73. float(element)
  74. val = float(element)
  75. if math.isnan(val) or math.isinf(val):
  76. raise ValueError
  77. return True
  78. except ValueError:
  79. return False
  80. def unpack_data(data):
  81. nonlocal select_separator
  82. nonlocal select_data_format
  83. f, r, i = [], [], []
  84. if select_data_format == 'Frequency, Re(S11), Im(S11)':
  85. for x in range(len(data)):
  86. # print(select_separator)
  87. select_separator=select_separator.replace('\"','')
  88. if select_separator==" ":
  89. tru = data[x].split()
  90. else:
  91. data[x]=data[x].replace(select_separator,' ')
  92. tru = data[x].split()
  93. if len(tru)!=3:
  94. return f, r, i, 'Bad line in your file. №:' + str(x)
  95. a, b, c = (y for y in tru)
  96. if not ((is_float(a)) or (is_float(b)) or (is_float(c))):
  97. return f, r, i, 'Bad data. Your data isnt numerical type. Number of bad line:' + str(x)
  98. f.append(float(a)) # frequency
  99. r.append(float(b)) # Re of S11
  100. i.append(float(c)) # Im of S11
  101. else:
  102. return f, r, i, 'Bad data format'
  103. return f, r, i, 'very nice'
  104. validator_status = 'nice'
  105. # calculate
  106. circle_params = []
  107. if len(data) > 0:
  108. f, r, i, validator_status = unpack_data(data)
  109. Q0, sigmaQ0, QL, sigmaQl, circle_params = calc_function(f, r, i)
  110. Q0 = round_up(Q0)
  111. sigmaQ0 = round_up(sigmaQ0)
  112. QL = round_up(QL)
  113. sigmaQl = round_up(sigmaQl)
  114. st.write("Cable attenuation")
  115. st.latex(r'Q_0 =' + f'{Q0} \pm {sigmaQ0}, ' + r'\;\;\varepsilon_{Q_0} =' + f'{round_up(sigmaQ0 / Q0)}')
  116. st.latex(r'Q_L =' + f'{QL} \pm {sigmaQl}, ' + r'\;\;\varepsilon_{Q_L} =' + f'{round_up(sigmaQl / QL)}')
  117. st.write("Status: " + validator_status)
  118. if len(data) > 0:
  119. f, r, i, validator_status = unpack_data(data)
  120. if validator_status == 'very nice':
  121. plot_data(r, i, circle_params)
  122. plot_ref_from_f(r, i, f)