Fix bugs in CalibrationGuide.

pull/697/head
tbergkvist 2024-04-10 13:00:56 +02:00
rodzic 1264a35d11
commit 8ed9696256
4 zmienionych plików z 56 dodań i 81 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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)

Wyświetl plik

@ -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

Wyświetl plik

@ -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))