kopia lustrzana https://github.com/NanoVNA-Saver/nanovna-saver
Fix bugs in CalibrationGuide.
rodzic
1264a35d11
commit
8ed9696256
|
@ -19,6 +19,7 @@
|
|||
|
||||
from .Calibration import Calibration
|
||||
from .Sweep import SweepMode
|
||||
from .RFTools import corr_att_data
|
||||
|
||||
class CalibrationGuide():# renamed from CalibrationWindow since it is no longer a window.
|
||||
nextStep = -1
|
||||
|
@ -28,9 +29,16 @@ class CalibrationGuide():# renamed from CalibrationWindow since it is no longer
|
|||
self.data = touchstone
|
||||
self.worker = worker
|
||||
|
||||
def saveData(self, data, data21): # This function is werid and should probably be rewritten.
|
||||
with self.dataLock:
|
||||
self.data.s11 = data
|
||||
self.data.s21 = data21
|
||||
if self.s21att > 0:
|
||||
self.data.s21 = corr_att_data(self.data.s21, self.s21att)
|
||||
|
||||
def cal_save(self, name: str):
|
||||
if name in {"through", "isolation"}:
|
||||
self.calibration.insert(name, self.data.s21) ######## FIX THIS
|
||||
self.calibration.insert(name, self.data.s21)
|
||||
else:
|
||||
self.calibration.insert(name, self.data.s11)
|
||||
|
||||
|
@ -47,7 +55,6 @@ class CalibrationGuide():# renamed from CalibrationWindow since it is no longer
|
|||
self.saveData(
|
||||
self.worker.rawData11,
|
||||
self.worker.rawData21,
|
||||
self.sweepSource,
|
||||
)
|
||||
|
||||
def setOffsetDelay(self, value: float):
|
||||
|
@ -69,7 +76,6 @@ class CalibrationGuide():# renamed from CalibrationWindow since it is no longer
|
|||
self.saveData(
|
||||
self.worker.data11,
|
||||
self.worker.data21,
|
||||
self.sweepSource,
|
||||
)
|
||||
|
||||
def calculate(self):
|
||||
|
@ -85,28 +91,19 @@ class CalibrationGuide():# renamed from CalibrationWindow since it is no longer
|
|||
|
||||
try:
|
||||
self.calibration.calc_corrections()
|
||||
|
||||
if self.use_ideal_values:
|
||||
self.calibration_source_label.setText(
|
||||
self.calibration.source
|
||||
)
|
||||
|
||||
if self.worker.rawData11:
|
||||
# There's raw data, so we can get corrected data
|
||||
if self.verbose:
|
||||
print("Applying calibration to existing sweep data.")
|
||||
(
|
||||
self.worker.data11,
|
||||
self.worker.data21,
|
||||
) = self.worker.applyCalibration(
|
||||
self.worker.rawData11, self.worker.rawData21
|
||||
)
|
||||
(self.worker.data11, self.worker.data21) = self.worker.applyCalibration(self.worker.rawData11, self.worker.rawData21)
|
||||
|
||||
if self.verbose:
|
||||
print("Saving and displaying corrected data.")
|
||||
|
||||
self.saveData(
|
||||
self.worker.data11,
|
||||
self.worker.data21,
|
||||
self.sweepSource,
|
||||
)
|
||||
except ValueError as e:
|
||||
raise Exception(f"Error applying calibration: {str(e)}\nApplying calibration failed.")
|
||||
|
@ -155,30 +152,31 @@ class CalibrationGuide():# renamed from CalibrationWindow since it is no longer
|
|||
Once you are ready to proceed, press enter. (q to quit).""")
|
||||
|
||||
if response.lower() == 'q':
|
||||
return
|
||||
return False
|
||||
print("Starting automatic calibration assistant.")
|
||||
if not self.vna.connected():
|
||||
print("NanoVNA not connected.\n\nPlease ensure the NanoVNA is connected before attempting calibration.")
|
||||
return
|
||||
return False
|
||||
|
||||
if self.worker.sweep.properties.mode == SweepMode.CONTINOUS:
|
||||
print("Please disable continuous sweeping before attempting calibration.")
|
||||
return
|
||||
return False
|
||||
|
||||
response = input("Calibrate short.\n\nPlease connect the short standard to port 0 of the NanoVNA.\n\n Press enter when you are ready to continue. (q to quit).")
|
||||
|
||||
if response.lower() == 'q':
|
||||
return
|
||||
return False
|
||||
|
||||
self.reset()
|
||||
self.calibration.source = "Calibration assistant"
|
||||
self.nextStep = 0
|
||||
self.sweep_start()
|
||||
return
|
||||
self.automaticCalibrationStep()
|
||||
self.worker.run()
|
||||
return True
|
||||
|
||||
def automaticCalibrationStep(self):
|
||||
if self.nextStep == -1:
|
||||
return
|
||||
return False
|
||||
|
||||
if self.nextStep == 0:
|
||||
# Short
|
||||
|
@ -193,9 +191,9 @@ class CalibrationGuide():# renamed from CalibrationWindow since it is no longer
|
|||
|
||||
if response.lower() == 'q':
|
||||
self.nextStep = -1
|
||||
return
|
||||
self.sweep_start()
|
||||
return
|
||||
return False
|
||||
self.worker.run()
|
||||
return True
|
||||
|
||||
if self.nextStep == 1:
|
||||
# Open
|
||||
|
@ -207,9 +205,9 @@ class CalibrationGuide():# renamed from CalibrationWindow since it is no longer
|
|||
|
||||
if response.lower() == 'q':
|
||||
self.nextStep = -1
|
||||
return
|
||||
self.sweep_start()
|
||||
return
|
||||
return False
|
||||
self.worker.run()
|
||||
return True
|
||||
|
||||
if self.nextStep == 2:
|
||||
# Load
|
||||
|
@ -223,10 +221,10 @@ class CalibrationGuide():# renamed from CalibrationWindow since it is no longer
|
|||
if response.lower() == 'q':
|
||||
self.calculate()
|
||||
self.nextStep = -1
|
||||
return
|
||||
return False
|
||||
if response.lower() == 'y' or response.lower() == "yes":
|
||||
self.nextStep = -1
|
||||
return
|
||||
return True
|
||||
|
||||
response = input("""Calibrate isolation\n
|
||||
Please connect the load standard to port 1 of the
|
||||
|
@ -235,9 +233,9 @@ class CalibrationGuide():# renamed from CalibrationWindow since it is no longer
|
|||
|
||||
if response.lower() == 'q':
|
||||
self.nextStep = -1
|
||||
return
|
||||
self.sweep_start()
|
||||
return
|
||||
return False
|
||||
self.worker.run()
|
||||
return True
|
||||
|
||||
if self.nextStep == 3:
|
||||
# Isolation
|
||||
|
@ -249,11 +247,10 @@ class CalibrationGuide():# renamed from CalibrationWindow since it is no longer
|
|||
Press Ok when you are ready to continue. (q to quit).""")
|
||||
|
||||
if response.lower() == 'q':
|
||||
self.btn_automatic.setDisabled(False)
|
||||
self.nextStep = -1
|
||||
return
|
||||
self.sweep_start()
|
||||
return
|
||||
return False
|
||||
self.worker.run()
|
||||
return True
|
||||
|
||||
if self.nextStep == 4:
|
||||
# Done
|
||||
|
@ -264,11 +261,9 @@ class CalibrationGuide():# renamed from CalibrationWindow since it is no longer
|
|||
enter to apply the calibration parameters. (q to quit).""")
|
||||
|
||||
if response.lower() == 'q':
|
||||
self.btn_automatic.setDisabled(False)
|
||||
self.nextStep = -1
|
||||
return
|
||||
return False
|
||||
|
||||
self.calculate()
|
||||
self.btn_automatic.setDisabled(False)
|
||||
self.nextStep = -1
|
||||
return
|
||||
return True
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
from .Hardware import Hardware as hw
|
||||
from .Hardware.VNA import VNA
|
||||
from .Calibration import Calibration
|
||||
from .CalibrationGuide import CalibrationGuide
|
||||
from .Touchstone import Touchstone
|
||||
from .RFTools import Datapoint
|
||||
from .SweepWorker import SweepWorker
|
||||
import matplotlib.pyplot as plt
|
||||
import math
|
||||
|
||||
|
@ -12,31 +14,19 @@ class NanoVNASaverHeadless:
|
|||
self.iface = hw.get_interfaces()[vna_index]
|
||||
self.vna = hw.get_VNA(self.iface)
|
||||
self.calibration = Calibration()
|
||||
self.touchstone = Touchstone("Save.s2p") # s2p for two port nanovnas.
|
||||
self.worker = SweepWorker(self.vna, verbose)
|
||||
self.CalibrationGuide = CalibrationGuide(self.calibration, self.touchstone, self.worker)
|
||||
if self.verbose:
|
||||
print("VNA is connected: ", self.vna.connected())
|
||||
print("Firmware: ", self.vna.readFirmware())
|
||||
print("Features: ", self.vna.read_features())
|
||||
|
||||
def calibrate(self):
|
||||
self.wait_for_ans("OPEN")
|
||||
data = self.get_data()
|
||||
open_dp_list = self.make_datapoint_list(data[4], data[0], data[1])
|
||||
self.calibration.insert("open", open_dp_list)
|
||||
|
||||
self.wait_for_ans("SHORT")
|
||||
data = self.get_data()
|
||||
short_dp_list = self.make_datapoint_list(data[4], data[0], data[1])
|
||||
self.calibration.insert("short", short_dp_list)
|
||||
|
||||
self.wait_for_ans("LOAD")
|
||||
data = self.get_data()
|
||||
load_dp_list = self.make_datapoint_list(data[4], data[0], data[1])
|
||||
self.calibration.insert("load", load_dp_list)
|
||||
|
||||
self.wait_for_ans("THROUGH")
|
||||
data = self.get_data()
|
||||
thru_dp_list = self.make_datapoint_list(data[4], data[2], data[3])
|
||||
self.calibration.insert("through", thru_dp_list)
|
||||
proceed = self.CalibrationGuide.automaticCalibration()
|
||||
while proceed:
|
||||
self.CalibrationGuide.automaticCalibrationStep()
|
||||
|
||||
|
||||
def set_sweep(self, start, stop):
|
||||
self.vna.setSweep(start, stop)
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
######################### TODO Rewrite this to be used headless.
|
||||
|
||||
|
||||
from time import sleep
|
||||
|
||||
|
|
|
@ -18,12 +18,6 @@
|
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
######################### TODO Rewrite this to be used headless.
|
||||
|
||||
|
||||
|
||||
import logging
|
||||
import math
|
||||
import cmath
|
||||
import io
|
||||
|
@ -31,9 +25,7 @@ from operator import attrgetter
|
|||
|
||||
from scipy.interpolate import interp1d
|
||||
|
||||
from NanoVNASaver.RFTools import Datapoint
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
from .RFTools import Datapoint
|
||||
|
||||
|
||||
class Options:
|
||||
|
@ -96,7 +88,7 @@ class Options:
|
|||
try:
|
||||
self.resistance = int(rstr)
|
||||
except ValueError:
|
||||
logger.warning("Non integer resistance value: %s", rstr)
|
||||
print("Non integer resistance value: %s", rstr)
|
||||
self.resistance = int(float(rstr))
|
||||
else:
|
||||
raise TypeError(f"Illegal option line: {line}")
|
||||
|
@ -199,7 +191,7 @@ class Touchstone:
|
|||
for line in fp:
|
||||
line = line.strip()
|
||||
if line.startswith("!"):
|
||||
logger.info(line)
|
||||
print(line)
|
||||
self.comments.append(line)
|
||||
continue
|
||||
return line
|
||||
|
@ -222,12 +214,12 @@ class Touchstone:
|
|||
next(data_list).append(Datapoint(freq, z.real, z.imag))
|
||||
|
||||
def load(self):
|
||||
logger.info("Attempting to open file %s", self.filename)
|
||||
print("Attempting to open file %s", self.filename)
|
||||
try:
|
||||
with open(self.filename, encoding="utf-8") as infile:
|
||||
self.loads(infile.read())
|
||||
except IOError as e:
|
||||
logger.exception("Failed to open %s: %s", self.filename, e)
|
||||
print("Failed to open %s: %s", self.filename, e)
|
||||
|
||||
def loads(self, s: str):
|
||||
"""Parse touchstone 1.1 string input
|
||||
|
@ -236,7 +228,7 @@ class Touchstone:
|
|||
try:
|
||||
self._loads(s)
|
||||
except TypeError as e:
|
||||
logger.exception("Failed to parse %s: %s", self.filename, e)
|
||||
print("Failed to parse %s: %s", self.filename, e)
|
||||
|
||||
def _loads(self, s: str):
|
||||
need_reorder = False
|
||||
|
@ -253,7 +245,7 @@ class Touchstone:
|
|||
continue
|
||||
# accept comment lines after header
|
||||
if line.startswith("!"):
|
||||
logger.warning("Comment after header: %s", line)
|
||||
print("Comment after header: %s", line)
|
||||
self.comments.append(line)
|
||||
continue
|
||||
|
||||
|
@ -267,7 +259,7 @@ class Touchstone:
|
|||
|
||||
# consistency checks
|
||||
if freq <= prev_freq:
|
||||
logger.warning("Frequency not ascending: %s", line)
|
||||
print("Frequency not ascending: %s", line)
|
||||
need_reorder = True
|
||||
prev_freq = freq
|
||||
|
||||
|
@ -278,7 +270,7 @@ class Touchstone:
|
|||
|
||||
self._append_line_data(freq, data)
|
||||
if need_reorder:
|
||||
logger.warning("Reordering data")
|
||||
print("Reordering data")
|
||||
for datalist in self.sdata:
|
||||
datalist.sort(key=attrgetter("freq"))
|
||||
|
||||
|
@ -289,7 +281,7 @@ class Touchstone:
|
|||
nr_params: Number of s-parameters. 2 for s1p, 4 for s2p
|
||||
"""
|
||||
|
||||
logger.info("Attempting to open file %s for writing", self.filename)
|
||||
print("Attempting to open file %s for writing", self.filename)
|
||||
with open(self.filename, "w", encoding="utf-8") as outfile:
|
||||
outfile.write(self.saves(nr_params))
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue