浏览代码

Merge branch 'Michael' of github.com:ricet8ur/calc-factor-of-vna into corrections-for-validator

ricet8ur 2 年之前
父节点
当前提交
58759f09ef
共有 3 个文件被更改,包括 79 次插入49 次删除
  1. 2 2
      TODO.md
  2. 1 2
      source/backend/calc.py
  3. 76 45
      source/frontend/front.py

+ 2 - 2
TODO.md

@@ -7,11 +7,11 @@
 2. [x] Change startup file to main.py and remove os and sys calls from frontend. Pass calc function to frontend function as an argument.
 3. [x] Add validation of separator + convertor to std backend input
 4. Should we apply corrections for coupling losses? - yes, please add this option.
-5. Draw continuous Q circle on a Smith chart using coefficients a[0..2]
+5. [x] Draw continuous Q circle on a Smith chart using coefficients a[0..2]
 6. Add axes labels to a Smith chart
 7. Pretty-print results and errors (7 digits after dot). Try latex output.
 8. Plot second chart: abs(S11) from f
-9. Add impedance data format (only frontend):
+9. Add impedance 5
     * additional field for omega
     * convertion to reflection coeffitient (how?)
 10. Codestyle fix:

+ 1 - 2
source/backend/calc.py

@@ -148,5 +148,4 @@ def fl_fitting(freq, re, im):
         Q = Ql * (1 + qk)  # Q-factor = result
         print(f"Q0 = {Q} +- {sigmaQ0}")
     
-    return Q,sigmaQ0, Ql, sigmaQl,a
-    
+    return Q,sigmaQ0, Ql, sigmaQl,a

+ 76 - 45
source/frontend/front.py

@@ -1,45 +1,75 @@
+import math
+
+XLIM = [-1.1, 1.1]
+YLIM = [-1.1, 1.1]
+
+
+def round_up(x, n=7):
+    if x == 0:
+        return 0
+    deg = math.floor(math.log(abs(x), 10))
+    return (10 ** deg) * round(x / (10 ** deg), n - 1)
+
+
+def circle(ax, x, y, radius, color='#1946BA'):
+    from matplotlib.patches import Ellipse
+    circle = Ellipse((x, y), radius * 2, radius * 2, clip_on=False,
+                     zorder=2, linewidth=2, edgecolor=color, facecolor=(0, 0, 0, .0125))
+    ax.add_artist(circle)
+
+
 import streamlit as st
 import matplotlib.pyplot as plt
 import numpy as np
 import math
 
-def plot_data(r,i, g):
-    # unit circle
-    unit_circle_x = []
-    unit_circle_y = []
-    for x in np.arange(-1, 1, 0.01):
-        unit_circle_x.append(x)
-        unit_circle_y.append((1-x**2)**0.5)
-
-    unit_circle_x.append(1)
-    unit_circle_y.append(0)
-
-    for x in np.arange(-1, 1, 0.01)[::-1]:
-        unit_circle_x.append(x)
-        unit_circle_y.append(-(1-x**2)**0.5)
 
-    fig, ax = plt.subplots()
-    ax.plot(unit_circle_x, unit_circle_y)
+def plot_data(r, i, g):
+    fig = plt.figure(figsize=(10, 10))
+    ax = fig.add_subplot()
+    ax.set_xlim(XLIM)
+    ax.set_ylim(YLIM)
+    major_ticks = np.arange(-1.0, 1.1, 0.25)
+    minor_ticks = np.arange(-1.1, 1.1, 0.05)
+    ax.set_xticks(major_ticks)
+    ax.set_xticks(minor_ticks, minor=True)
+    ax.set_yticks(major_ticks)
+    ax.set_yticks(minor_ticks, minor=True)
+    ax.grid(which='major', color='grey', linewidth=1.5)
+    ax.grid(which='minor', color='grey', linewidth=0.5, linestyle=':')
+    plt.xlabel(r'$Re(\Gamma)$', color='gray', fontsize=16, fontname="Cambria")
+    plt.ylabel('$Im(\Gamma)$', color='gray', fontsize=16, fontname="Cambria")
+    plt.title('Smith chart', fontsize=24, fontname="Cambria")
+    # cirlce approximation
+    radius = abs(g[1] - g[0] / g[2]) / 2
+    x = ((g[1] + g[0] / g[2]) / 2).real
+    y = ((g[1] + g[0] / g[2]) / 2).imag
+    circle(ax, x, y, radius, color='#FF8400')
     #
-
-    # data
-    ax.plot(r, i, 'b+')
+    # unit circle
+    circle(ax, 0, 0, 1)
     #
-    #cirlce approximation
-    # g_c = (np.conj(g[2])*g[1]-g[0])/(np.conj(g[2])-g[2])
-    # g_d = g[0]/g[2]
-    # radius = abs(g_c-g_d)
-    # p=[[],[]]
-    # for alpha in range(0,360):
-    #     p[0].append(g_c.real+radius*math.cos(math.radians(alpha)))
-    #     p[1].append(g_c.imag+radius*math.sin(math.radians(alpha)))
-    # ax.plot(p[0],p[1])
+    # data
+    ax.plot(r, i, '+', ms=10, mew=2, color='#1946BA')
     #
 
-    ax.grid(True)
-    ax.axis('square')
-    ax.set_yticks(np.arange(-1, 1.2, 0.2))
-    ax.set_yticks(np.arange(-1, 1.2, 0.2))
+    st.pyplot(fig)
+
+
+def plot_ref_from_f(r, i, f):
+    fig = plt.figure(figsize=(10, 10))
+    abs_S = list(math.sqrt(r[n] ** 2 + i[n] ** 2) for n in range(len(r)))
+    xlim = [min(f)-abs(max(f)-min(f))*0.1, max(f)+abs(max(f)-min(f))*0.1]
+    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]
+    ax = fig.add_subplot()
+    ax.set_xlim(xlim)
+    ax.set_ylim(ylim)
+    ax.grid(which='major', color='k', linewidth=1)
+    ax.grid(which='minor', color='grey', linestyle=':', linewidth=0.5)
+    plt.xlabel(r'$f,\; 1/c$', color='gray', fontsize=16, fontname="Cambria")
+    plt.ylabel('$|\Gamma|$', color='gray', fontsize=16, fontname="Cambria")
+    plt.title('Modulus of reflection coefficient from frequency', fontsize=24, fontname="Cambria")
+    ax.plot(f, abs_S, '+', ms=10, mew=2, color='#1946BA')
     st.pyplot(fig)
 
 
@@ -49,13 +79,12 @@ def run(calc_function):
     if uploaded_file is not None:
         data = uploaded_file.readlines()
 
-
     col1, col2 = st.columns(2)
 
     select_data_format = col1.selectbox('Choose data format from a list',['Frequency, Re(S11), Im(S11)','Frequency, Re(Zin), Im(Zin)'])
 
     select_separator = col2.selectbox('Choose separator',['" "' ,'","','";"'])
-    select_coupling_losses = st.checkbox('I want to apply corrections for coupling losses (lossy coupling)')
+    select_coupling_losses = st.checkbox('Apply corrections for coupling losses (lossy coupling)')
     
     def is_float(element) -> bool:
         try:
@@ -97,21 +126,23 @@ def run(calc_function):
 
     validator_status = 'nice'
     # calculate
-    circle_params=[]
+    circle_params = []
     if len(data) > 0:
-        f,r,i,validator_status = unpack_data(data)
+        f, r, i, validator_status = unpack_data(data)
 
-        Q0,sigmaQ0,QL,sigmaQl, circle_params =calc_function(f,r,i)
+        Q0, sigmaQ0, QL, sigmaQl, circle_params = calc_function(f, r, i)
+        Q0 = round_up(Q0)
+        sigmaQ0 = round_up(sigmaQ0)
+        QL = round_up(QL)
+        sigmaQl = round_up(sigmaQl)
         st.write("Cable attenuation")
-        st.write(f"Q0 = {Q0} +- {sigmaQ0}, epsilon Q0 ={sigmaQ0/Q0}")
-        st.write(f"QL = {QL} +- {sigmaQl}, epsilon QL ={sigmaQl/QL}")
-
+        st.latex(r'Q_0 =' + f'{Q0} \pm {sigmaQ0},  ' + r'\;\;\varepsilon_{Q_0} =' + f'{round_up(sigmaQ0 / Q0)}')
+        st.latex(r'Q_L =' + f'{QL} \pm {sigmaQl},  ' + r'\;\;\varepsilon_{Q_L} =' + f'{round_up(sigmaQl / QL)}')
 
-    st.write("Status: " +validator_status)
+    st.write("Status: " + validator_status)
 
     if len(data) > 0:
-        f,r,i,validator_status = unpack_data(data)
+        f, r, i, validator_status = unpack_data(data)
         if validator_status == 'very nice':
-            plot_data(r,i,circle_params)
-
-    
+            plot_data(r, i, circle_params)
+            plot_ref_from_f(r, i, f)