Browse Source

Dockerfile correction; Add .s3p support;
Better interval clip option

ricet8ur 1 year ago
parent
commit
e4bac4c124
4 changed files with 70 additions and 27 deletions
  1. 1 1
      Dockerfile
  2. 1 1
      requirements.txt
  3. 13 0
      resource/data/10_check_4port.s4p
  4. 55 25
      source/frontend/front.py

+ 1 - 1
Dockerfile

@@ -5,6 +5,6 @@ RUN pip install -r requirements.txt
 EXPOSE 8501
 COPY . /app
 ENTRYPOINT ["streamlit", "run"]
-CMD ["./source/main.py", "--browser.serverAddress=0.0.0.0", "--browser.gatherUsageStats=false", "--server.maxUploadSize = 20"]
+CMD ["./source/main.py", "--browser.serverAddress=0.0.0.0", "--browser.gatherUsageStats=false", "--server.maxUploadSize=20"]
 # docker build -t calc-q-factor:latest .
 # docker run -p 8501:8501 calc-q-factor:latest

+ 1 - 1
requirements.txt

@@ -6,4 +6,4 @@ numpy
 streamlit_echarts
 streamlit-ace
 sigfig
-paperclip
+pyperclip

+ 13 - 0
resource/data/10_check_4port.s4p

@@ -0,0 +1,13 @@
+# GHZ S MA R 50
+5.00000 0.60 161.24 0.40 -42.20 0.42 -66.58 0.53 -79.34 !row 1
+0.40 -42.20 0.60 161.20 0.53 -79.34 0.42 -66.58 !row 2
+0.42 -66.58 0.53 -79.34 0.60 161.24 0.40 -42.20 !row 3
+0.53 -79.34 0.42 -66.58 0.40 -42.20 0.60 161.24 !row 4
+6.00000 0.57 150.37 0.40 -44.34 0.41 -81.24 0.57 -95.77 !row 1
+0.40 -44.34 0.57 150.37 0.57 -95.77 0.41 -81.24 !row 2
+0.41 -81.24 0.57 -95.77 0.57 150.37 0.40 -44.34 !row 3
+0.57 -95.77 0.41 -81.24 0.40 -44.34 0.57 150.37 !row 4
+7.00000 0.50 136.69 0.45 -46.41 0.37 -99.09 0.62 -114.19 !row 1
+0.45 -46.41 0.50 136.69 0.62 -114.19 0.37 -99.09 !row 2
+0.37 -99.09 0.62 -114.19 0.50 136.69 0.45 -46.41 !row 3
+0.62 -114.19 0.37 -99.09 0.45 -46.41 0.50 136.69 !row 4

+ 55 - 25
source/frontend/front.py

@@ -3,7 +3,6 @@ import streamlit as st
 import matplotlib.pyplot as plt
 import numpy as np
 import sigfig
-import pyperclip
 from streamlit_ace import st_ace
 from streamlit_echarts import st_echarts, JsCode
 
@@ -176,7 +175,7 @@ def run(calc_function):
                     data[x] = data[x].decode('utf-8-sig', 'ignore')
                 except:
                     return 'Not an utf-8-sig line №: ' + str(x)
-        return 'data read: success'
+        return 'data read, but not parsed'
 
     # for Touchstone .snp format
     def parse_heading(data):
@@ -228,6 +227,24 @@ def run(calc_function):
             break
         return column_count, return_status
 
+    def prepare_snp(data, number):
+        prepared_data = []
+        return_status = 'data read, but not parsed'
+        for x in range(len(data)):
+            line = check_line_comments(data[x])
+            if line is None:
+                continue
+
+            splitted_line = line.split()
+            if number * 2 + 1 == len(splitted_line):
+                prepared_data.append(line)
+            elif number * 2 == len(splitted_line):
+                prepared_data[-1] += line
+            else:
+                return_status = "Parsing error for .snp format on line №" + str(x)
+
+        return prepared_data, return_status
+
     def unpack_data(data, first_column, column_count, ref_resistance, ace_preview_markers):
         nonlocal select_measurement_parameter
         nonlocal select_data_representation
@@ -327,7 +344,7 @@ def run(calc_function):
             return_status = 'Choosen data range is too small, add more points'
         elif max(abs(np.array(r)+ 1j* np.array(i))) > 2:
             return_status = 'Your data points have an abnormality:\
-                        they are too far outlise the unit cirlce.\
+                        they are too far outside the unit cirlce.\
                         Make sure the format is correct'
 
         return f, r, i, return_status
@@ -347,10 +364,11 @@ def run(calc_function):
 
     # file upload button
     uploaded_file = st.file_uploader('Upload a file from your vector analizer. \
-        Make sure the file format is .snp or it has a similar inner structure.'                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         )
+        Make sure the file format is .snp or it has a similar inner structure.'                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       )
 
     # check .snp
     data_format_snp = False
+    data_format_snp_number = 0
     if uploaded_file is None:
         st.write("DEMO: ")
         # display DEMO
@@ -360,15 +378,15 @@ def run(calc_function):
                 data = f.readlines()
         except:
             # 'streamlit run' call in the wrong directory. Display smaller demo:
-            data =[line.strip()+'\n' for line in '''# Hz S MA R 50
-                11415403125 0.37010744 92.47802
-                11416090625 0.33831283 92.906929
-                11416778125 0.3069371 94.03318
-                '''.split('\n')]
+            data =['# Hz S MA R 50\n\
+                11415403125 0.37010744 92.47802\n\
+                11416090625 0.33831283 92.906929\n\
+                11416778125 0.3069371 94.03318']
     else:
         data = uploaded_file.readlines()
         if uploaded_file.name[-4:-2]=='.s' and uploaded_file.name[-1]== 'p':
             data_format_snp = True
+            data_format_snp_number = int(uploaded_file.name[-2])
 
     validator_status = '...'
     ace_preview_markers = []
@@ -379,8 +397,9 @@ def run(calc_function):
     if len(data) > 0:
 
         validator_status = read_data(data)
-        if validator_status == 'data read: success':
+        if validator_status == 'data read, but not parsed':
             hz, select_measurement_parameter, select_data_representation, input_ref_resistance = parse_heading(data)
+
             col1, col2 = st.columns([1,2])
 
             with col1.expander("Processing options"):
@@ -445,21 +464,32 @@ def run(calc_function):
                        markers=ace_preview_markers,
                        height="300px")
 
-            column_count, validator_status = count_columns(data)
+            if data_format_snp and data_format_snp_number >= 3:
+                data, validator_status = prepare_snp(data, data_format_snp_number)
+
+    if validator_status == "data read, but not parsed":
+        column_count, validator_status = count_columns(data)
 
+    f, r, i = [], [], []
     if validator_status == "data parsed":
         input_ports_pair = 1
         if column_count > 3:
-            input_ports_pair = st.number_input(
-                "Pair of data columns (pair of ports)\n with network parameters:",
-                min_value=1,
-                max_value=(column_count - 1) // 2,
-                value=1)
+            pair_count = (column_count - 1) // 2
+            input_ports_pair_id = st.number_input(
+                "Choosen pair of ports with network parameters:",
+                min_value = 1,
+                max_value = pair_count,
+                value = 1) - 1
+            ports_count = round(pair_count **0.5)
+            st.write(select_measurement_parameter +
+                     str(input_ports_pair_id // ports_count + 1) +
+                     str(input_ports_pair_id % ports_count + 1))
+
         f, r, i, validator_status = unpack_data(
             data,(input_ports_pair - 1) * 2 + 1, column_count, input_ref_resistance,
             ace_preview_markers)
         f = [x * hz for x in f]  # to hz
-        
+
     st.write("Use range slider to choose best suitable data interval")
     interval_range, interval_start, interval_end = plot_interact_abs_from_f(f, r, i, interval_range)
 
@@ -468,11 +498,13 @@ def run(calc_function):
         f_cut, r_cut, i_cut = (x[interval_start:interval_end]
                            for x in (f, r, i))
 
-        def copy_to_clip_s_single():
-            pyperclip.copy("# Hz S RI R 50\n" +
-            ''.join(f'{f_cut[x]} {r_cut[x]} {i_cut[x]}\n' for x in range(len(f_cut))))
-
-        st.button("Copy selected data interval to clipboard as .s1p", on_click=copy_to_clip_s_single)
+        with st.expander("Selected data interval as .s1p"):
+            st_ace(value="# Hz S RI R 50\n" +
+            ''.join(f'{f_cut[x]} {r_cut[x]} {i_cut[x]}\n' for x in range(len(f_cut))),
+                       readonly=True,
+                       auto_update=True,
+                       placeholder="Selection is empty",
+                       height="150px")
 
         if len(f_cut) < 3:
             validator_status = "Choosen interval is too small, add more points"
@@ -528,6 +560,4 @@ def run(calc_function):
         with st.expander("Show static abs(S) plot"):
             plot_abs_vs_f(f_cut, r_cut, i_cut)
 
-        select_show_excluded_points = st.checkbox("Show excluded points", value=True)
-
-        plot_smith(r, i, circle_params, r_cut, i_cut, select_show_excluded_points)
+        plot_smith(r, i, circle_params, r_cut, i_cut, st.checkbox("Show excluded points", value=True))