pycodestyle changes

pull/544/head
Holger Müller 2022-09-15 20:08:23 +02:00
rodzic 3f8151aad7
commit 1609295bd9
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 2FDB49E81EAE6622
10 zmienionych plików z 327 dodań i 302 usunięć

Wyświetl plik

@ -97,21 +97,16 @@ class PeakSearchAnalysis(Analysis):
count = self.input_number_of_peaks.value()
if self.rbtn_data_vswr.isChecked():
fn = format_vswr
for d in self.app.data.s11:
data.append(d.vswr)
data.extend(d.vswr for d in self.app.data.s11)
elif self.rbtn_data_s21_gain.isChecked():
fn = format_gain
for d in self.app.data.s21:
data.append(d.gain)
data.extend(d.gain for d in self.app.data.s21)
elif self.rbtn_data_resistance.isChecked():
fn = format_resistance
for d in self.app.data.s11:
data.append(d.impedance().real)
data.extend(d.impedance().real for d in self.app.data.s11)
elif self.rbtn_data_reactance.isChecked():
fn = str
for d in self.app.data.s11:
data.append(d.impedance().imag)
data.extend(d.impedance().imag for d in self.app.data.s11)
else:
logger.warning("Searching for peaks on unknown data")
return
@ -125,8 +120,10 @@ class PeakSearchAnalysis(Analysis):
peaks, _ = signal.find_peaks(
data, width=3, distance=3, prominence=1)
# elif self.rbtn_peak_both.isChecked():
# peaks_max, _ = signal.find_peaks(data, width=3, distance=3, prominence=1)
# peaks_min, _ = signal.find_peaks(np.array(data)*-1, width=3, distance=3, prominence=1)
# peaks_max, _ = signal.find_peaks(
# data, width=3, distance=3, prominence=1)
# peaks_min, _ = signal.find_peaks(
# np.array(data)*-1, width=3, distance=3, prominence=1)
# peaks = np.concatenate((peaks_max, peaks_min))
else:
# Both is not yet in

Wyświetl plik

@ -19,7 +19,6 @@
import os
import csv
import logging
from collections import OrderedDict
import numpy as np
from PyQt5 import QtWidgets
@ -74,39 +73,27 @@ class VSWRAnalysis(Analysis):
def runAnalysis(self):
max_dips_shown = self.max_dips_shown
data = [d.vswr for d in self.app.data.s11]
# min_idx = np.argmin(data)
#
# logger.debug("Minimum at %d", min_idx)
# logger.debug("Value at minimum: %f", data[min_idx])
# logger.debug("Frequency: %d", self.app.data.s11[min_idx].freq)
#
# if self.checkbox_move_marker.isChecked():
# self.app.markers[0].setFrequency(str(self.app.data.s11[min_idx].freq))
# self.app.markers[0].frequencyInput.setText(str(self.app.data.s11[min_idx].freq))
threshold = self.input_vswr_limit.value()
minimums = self.find_minimums(data, threshold)
logger.debug("Found %d sections under %f threshold",
len(minimums), threshold)
results_header = self.layout.indexOf(self.results_label)
logger.debug("Results start at %d, out of %d",
results_header, self.layout.rowCount())
for _ in range(results_header, self.layout.rowCount()):
self.layout.removeRow(self.layout.rowCount() - 1)
if len(minimums) > max_dips_shown:
self.layout.addRow(QtWidgets.QLabel("<b>More than " + str(max_dips_shown) +
" dips found. Lowest shown.</b>"))
self.layout.addRow(
QtWidgets.QLabel(
f"<b>More than {str(max_dips_shown)} dips found."
" Lowest shown.</b>"))
dips = []
for m in minimums:
start, lowest, end = m
dips.append(data[lowest])
best_dips = []
for _ in range(max_dips_shown):
min_idx = np.argmin(dips)
@ -123,27 +110,26 @@ class VSWRAnalysis(Analysis):
"Section from %d to %d, lowest at %d", start, end, lowest)
self.layout.addRow("Start", QtWidgets.QLabel(
format_frequency(self.app.data.s11[start].freq)))
self.layout.addRow(
"Minimum",
QtWidgets.QLabel(
f"{format_frequency(self.app.data.s11[lowest].freq)}"
f" ({round(data[lowest], 2)})"))
self.layout.addRow("Minimum", QtWidgets.QLabel(
f"{format_frequency(self.app.data.s11[lowest].freq)} ({round(data[lowest], 2)})"))
self.layout.addRow("End", QtWidgets.QLabel(
format_frequency(self.app.data.s11[end].freq)))
self.layout.addRow(
"Span",
QtWidgets.QLabel(
format_frequency(self.app.data.s11[end].freq -
self.app.data.s11[start].freq)))
self.layout.addRow("Span", QtWidgets.QLabel(format_frequency(
(self.app.data.s11[end].freq - self.app.data.s11[start].freq))))
else:
self.layout.addRow("Low spot", QtWidgets.QLabel(
format_frequency(self.app.data.s11[lowest].freq)))
self.layout.addWidget(PeakSearchAnalysis.QHLine())
# Remove the final separator line
self.layout.removeRow(self.layout.rowCount() - 1)
else:
self.layout.addRow(QtWidgets.QLabel(
"No areas found with VSWR below " + str(round(threshold, 2)) + "."))
self.layout.addRow(
QtWidgets.QLabel(
f"No areas found with VSWR below {round(threshold, 2)}."))
class ResonanceAnalysis(Analysis):
@ -153,9 +139,7 @@ class ResonanceAnalysis(Analysis):
def vswr_transformed(cls, z, ratio=49) -> float:
refl = reflection_coefficient(z / ratio)
mag = abs(refl)
if mag == 1:
return 1
return (1 + mag) / (1 - mag)
return 1 if mag == 1 else (1 + mag) / (1 - mag)
class QHLine(QtWidgets.QFrame):
def __init__(self):
@ -203,11 +187,10 @@ class ResonanceAnalysis(Analysis):
self.reset()
# self.results_label = QtWidgets.QLabel("<b>Results</b>")
# max_dips_shown = self.max_dips_shown
description = self.input_description.text()
if description:
filename = os.path.join("/tmp/", "{}.csv".format(description))
else:
filename = None
filename = (
os.path.join("/tmp/", f"{self.input_description.text()}.csv")
if self.input_description.text()
else None)
crossing = self._get_crossing()
@ -272,42 +255,29 @@ class EFHWAnalysis(ResonanceAnalysis):
def runAnalysis(self):
self.reset()
# self.results_label = QtWidgets.QLabel("<b>Results</b>")
# max_dips_shown = self.max_dips_shown
description = self.input_description.text()
if description:
filename = os.path.join("/tmp/", "{}.csv".format(description))
if description := self.input_description.text():
filename = os.path.join("/tmp/", f"{description}.csv")
else:
filename = None
crossing = self._get_crossing()
data = []
for d in self.app.data.s11:
data.append(d.impedance().real)
data = [d.impedance().real for d in self.app.data.s11]
maximums = sorted(self.find_maximums(data, threshold=500))
results_header = self.layout.indexOf(self.results_label)
logger.debug("Results start at %d, out of %d",
results_header, self.layout.rowCount())
for i in range(results_header, self.layout.rowCount()):
for _ in range(results_header, self.layout.rowCount()):
self.layout.removeRow(self.layout.rowCount() - 1)
extended_data = OrderedDict()
# both = np.intersect1d([i[1] for i in crossing], maximums)
extended_data = {}
both = []
tolerance = 2
for i in maximums:
for l, _, h in crossing:
if l - tolerance <= i <= h + tolerance:
for low, _, high in crossing:
if low - tolerance <= i <= high + tolerance:
both.append(i)
continue
if l > i:
if low > i:
continue
if both:
logger.info("%i crossing HW", len(both))
logger.info(crossing)
@ -320,67 +290,45 @@ class EFHWAnalysis(ResonanceAnalysis):
else:
extended_data[m] = my_data
for i in range(min(len(both), len(self.app.markers))):
# self.app.markers[i].label = {}
# for l in TYPES:
# self.app.markers[i][l.label_id] = MarkerLabel(l.name)
# self.app.markers[i].label['actualfreq'].setMinimumWidth(
# 100)
# self.app.markers[i].label['returnloss'].setMinimumWidth(80)
self.app.markers[i].setFrequency(
str(self.app.data.s11[both[i]].freq))
self.app.markers[i].frequencyInput.setText(
str(self.app.data.s11[both[i]].freq))
else:
logger.info("TO DO: find near data")
for _, lowest, _ in crossing:
my_data = self._get_data(lowest)
if lowest in extended_data:
extended_data[lowest].update(my_data)
else:
extended_data[lowest] = my_data
logger.debug("maximumx %s of type %s", maximums, type(maximums))
for m in maximums:
logger.debug("m %s of type %s", m, type(m))
my_data = self._get_data(m)
if m in extended_data:
extended_data[m].update(my_data)
else:
extended_data[m] = my_data
# saving and comparing
fields = [("freq", format_frequency_short),
("r", format_resistence_neg),
("lambda", round_2),
]
("r", format_resistence_neg), ("lambda", round_2)]
if self.old_data:
diff = self.compare(
self.old_data[-1], extended_data, fields=fields)
else:
diff = self.compare({}, extended_data, fields=fields)
self.old_data.append(extended_data)
for i, index in enumerate(sorted(extended_data.keys())):
self.layout.addRow(
f"{format_frequency_short(self.app.data.s11[index].freq)}",
QtWidgets.QLabel(f" ({diff[i]['freq']})"
f" {format_complex_imp(self.app.data.s11[index].impedance())}"
f" ({diff[i]['r']})"
f" {diff[i]['lambda']} m"))
self.layout.addRow(f"{format_frequency_short(self.app.data.s11[index].freq)}", QtWidgets.QLabel(
f" ({diff[i]['freq']}) {format_complex_imp(self.app.data.s11[index].impedance())} ({diff[i]['r']}) {diff[i]['lambda']} m"))
# Remove the final separator line
# self.layout.removeRow(self.layout.rowCount() - 1)
if filename and extended_data:
with open(filename, 'w', newline='') as csvfile:
fieldnames = extended_data[sorted(
extended_data.keys())[0]].keys()
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for index in sorted(extended_data.keys()):
row = extended_data[index]

Wyświetl plik

@ -120,7 +120,8 @@ class CalDataSet:
def complete2port(self) -> bool:
for val in self.data.values():
for name in ("short", "open", "load", "through", "thrurefl", "isolation"):
for name in ("short", "open", "load", "through", "thrurefl",
"isolation"):
if val[name] is None:
return False
return any(self.data)
@ -218,9 +219,9 @@ class Calibration:
cal["e30"] = cal["isolation"].z
cal["e10e01"] = cal["e00"] * cal["e11"] - cal["delta_e"]
cal["e22"] = gm7 / (
gm7 * cal["e11"] * gt ** 2 + cal["e10e01"] * gt ** 2)
gm7 * cal["e11"] * gt ** 2 + cal["e10e01"] * gt ** 2)
cal["e10e32"] = (gm4 - gm6) * (
1 - cal["e11"] * cal["e22"] * gt ** 2) / gt
1 - cal["e11"] * cal["e22"] * gt ** 2) / gt
def calc_corrections(self):
if not self.isValid1Port():
@ -254,8 +255,8 @@ class Calibration:
if not self.useIdealShort:
logger.debug("Using short calibration set values.")
Zsp = complex(0, 2 * math.pi * freq * (
self.shortL0 + self.shortL1 * freq +
self.shortL2 * freq ** 2 + self.shortL3 * freq ** 3))
self.shortL0 + self.shortL1 * freq +
self.shortL2 * freq ** 2 + self.shortL3 * freq ** 3))
# Referencing https://arxiv.org/pdf/1606.02446.pdf (18) - (21)
g = (Zsp / 50 - 1) / (Zsp / 50 + 1) * cmath.exp(
complex(0, 2 * math.pi * 2 * freq * self.shortLength * -1))
@ -266,8 +267,8 @@ class Calibration:
if not self.useIdealOpen:
logger.debug("Using open calibration set values.")
Zop = complex(0, 2 * math.pi * freq * (
self.openC0 + self.openC1 * freq +
self.openC2 * freq ** 2 + self.openC3 * freq ** 3))
self.openC0 + self.openC1 * freq +
self.openC2 * freq ** 2 + self.openC3 * freq ** 3))
g = ((1 - 50 * Zop) / (1 + 50 * Zop)) * cmath.exp(
complex(0, 2 * math.pi * 2 * freq * self.openLength * -1))
return g
@ -278,7 +279,8 @@ class Calibration:
logger.debug("Using load calibration set values.")
Zl = complex(self.loadR, 0)
if self.loadC > 0:
Zl = self.loadR / complex(1, 2 * self.loadR * math.pi * freq * self.loadC)
Zl = self.loadR / \
complex(1, 2 * self.loadR * math.pi * freq * self.loadC)
if self.loadL > 0:
Zl = Zl + complex(0, 2 * math.pi * freq * self.loadL)
g = (Zl / 50 - 1) / (Zl / 50 + 1) * cmath.exp(
@ -340,13 +342,14 @@ class Calibration:
def correct11(self, dp: Datapoint):
i = self.interp
s11 = (dp.z - i["e00"](dp.freq)) / (
(dp.z * i["e11"](dp.freq)) - i["delta_e"](dp.freq))
(dp.z * i["e11"](dp.freq)) - i["delta_e"](dp.freq))
return Datapoint(dp.freq, s11.real, s11.imag)
def correct21(self, dp: Datapoint, dp11: Datapoint):
i = self.interp
s21 = (dp.z - i["e30"](dp.freq)) / i["e10e32"](dp.freq)
s21 = s21 * (i["e10e01"](dp.freq) / (i["e11"](dp.freq) * dp11.z - i["delta_e"](dp.freq)))
s21 = s21 * (i["e10e01"](dp.freq) / (i["e11"](dp.freq)
* dp11.z - i["delta_e"](dp.freq)))
return Datapoint(dp.freq, s21.real, s21.imag)
# TODO: implement tests
@ -360,7 +363,8 @@ class Calibration:
calfile.write(f"! {note}\n")
calfile.write(
"# Hz ShortR ShortI OpenR OpenI LoadR LoadI"
" ThroughR ThroughI ThrureflR ThrureflI IsolationR IsolationI\n")
" ThroughR ThroughI ThrureflR ThrureflI"
" IsolationR IsolationI\n")
for freq in self.dataset.frequencies():
calfile.write(f"{self.dataset.get(freq)}\n")
@ -382,7 +386,8 @@ class Calibration:
if line.startswith("#"):
if not parsed_header and line == (
"# Hz ShortR ShortI OpenR OpenI LoadR LoadI"
" ThroughR ThroughI ThrureflR ThrureflI IsolationR IsolationI"):
" ThroughR ThroughI ThrureflR ThrureflI"
" IsolationR IsolationI"):
parsed_header = True
continue
if not parsed_header:

Wyświetl plik

@ -65,6 +65,7 @@ class Chart:
show_bands: bool = False
vswr_lines: list = DC.field(default_factory=lambda: [])
@DC.dataclass
class ChartColors: # pylint: disable=too-many-instance-attributes
background: QColor = QColor(QtCore.Qt.white)
@ -131,11 +132,11 @@ def from_type(data) -> str:
type_map = {
bytearray: lambda x: x.hex(),
QColor: lambda x: x.getRgb(),
QByteArray: lambda x: x.toHex(),
QByteArray: lambda x: x.toHex()
}
if type(data) in type_map:
return str(type_map[type(data)](data))
return str(data)
return (f"{type_map[type(data)](data)}" if
type(data) in type_map else
f"{data}")
def to_type(data: object, data_type: type) -> object:
@ -145,11 +146,11 @@ def to_type(data: object, data_type: type) -> object:
list: literal_eval,
tuple: literal_eval,
QColor: lambda x: QColor.fromRgb(*literal_eval(x)),
QByteArray: lambda x: QByteArray.fromHex(literal_eval(x)),
QByteArray: lambda x: QByteArray.fromHex(literal_eval(x))
}
if data_type in type_map:
return type_map[data_type](data)
return data_type(data)
return (type_map[data_type](data) if
data_type in type_map else
data_type(data))
# noinspection PyDataclass

Wyświetl plik

@ -17,7 +17,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging
from collections import OrderedDict
from time import sleep
from typing import List, Iterator, Set
@ -28,19 +27,19 @@ from NanoVNASaver.Hardware.Serial import Interface, drain_serial
logger = logging.getLogger(__name__)
DISLORD_BW = OrderedDict((
(10, 363),
(33, 117),
(50, 78),
(100, 39),
(200, 19),
(250, 15),
(333, 11),
(500, 7),
(1000, 3),
(2000, 1),
(4000, 0),
))
DISLORD_BW = {
10: 363,
33: 117,
50: 78,
100: 39,
200: 19,
250: 15,
333: 11,
500: 7,
1000: 3,
2000: 1,
4000: 0,
}
WAIT = 0.05

Wyświetl plik

@ -56,17 +56,20 @@ TYPES = (
Label("s21groupdelay", "S21 Group Delay", "S21 Group Delay", False),
Label("s21magshunt", "S21 |Z| shunt", "S21 Z Magnitude shunt", False),
Label("s21magseries", "S21 |Z| series", "S21 Z Magnitude series", False),
Label("s21realimagshunt", "S21 R+jX shunt", "S21 Z Real+Imag shunt", False),
Label("s21realimagseries", "S21 R+jX series", "S21 Z Real+Imag series", False),
Label("s21realimagshunt", "S21 R+jX shunt",
"S21 Z Real+Imag shunt", False),
Label("s21realimagseries", "S21 R+jX series",
"S21 Z Real+Imag series", False),
)
def default_label_ids() -> str:
return [l.label_id for l in TYPES if l.default_active]
return [label.label_id for label in TYPES if label.default_active]
class Value():
"""Contains the data area to calculate marker values from"""
def __init__(self, freq: int = 0,
s11: List[Datapoint] = None,
s21: List[Datapoint] = None):
@ -87,7 +90,8 @@ class Value():
s11 += [s11[-1], ]
if s21:
s21 += [s21[-1], ]
self.freq = s11[1].freq
self.s11 = s11[index-1:index+2]
self.s11 = s11[index - 1:index + 2]
if s21:
self.s21 = s21[index-1:index+2]
self.s21 = s21[index - 1:index + 2]

Wyświetl plik

@ -98,9 +98,9 @@ class Marker(QtCore.QObject, Value):
# Data display labels
###############################################################
self.label = {}
for l in TYPES:
self.label[l.label_id] = MarkerLabel(l.name)
self.label = {
label.label_id: MarkerLabel(label.name) for label in TYPES
}
self.label['actualfreq'].setMinimumWidth(100)
self.label['returnloss'].setMinimumWidth(80)
@ -201,7 +201,7 @@ class Marker(QtCore.QObject, Value):
for label_id in self.active_labels:
self._add_active_labels(label_id, self.left_form)
else:
left_half = math.ceil(len(self.active_labels)/2)
left_half = math.ceil(len(self.active_labels) / 2)
right_half = len(self.active_labels)
for i in range(left_half):
label_id = self.active_labels[i]
@ -258,8 +258,8 @@ class Marker(QtCore.QObject, Value):
upper_stepsize = data[-1].freq - data[-2].freq
# We are outside the bounds of the data, so we can't put in a marker
if (self.freq + lower_stepsize/2 < min_freq or
self.freq - upper_stepsize/2 > max_freq):
if (self.freq + lower_stepsize / 2 < min_freq or
self.freq - upper_stepsize / 2 > max_freq):
return
min_distance = max_freq
@ -268,11 +268,11 @@ class Marker(QtCore.QObject, Value):
min_distance = abs(item.freq - self.freq)
else:
# We have now started moving away from the nearest point
self.location = i-1
self.location = i - 1
if i < datasize:
self.frequencyInput.nextFrequency = item.freq
if i >= 2:
self.frequencyInput.previousFrequency = data[i-2].freq
self.frequencyInput.previousFrequency = data[i - 2].freq
return
# If we still didn't find a best spot, it was the last value
self.location = datasize - 1
@ -292,7 +292,8 @@ class Marker(QtCore.QObject, Value):
return
if self.location == -1: # initial position
try:
location = (self.index -1) / (self._instances - 1) * (len(s11) - 1)
location = (self.index - 1) / (
(self._instances - 1) * (len(s11) - 1))
self.location = int(location)
except ZeroDivisionError:
self.location = 0

Wyświetl plik

@ -19,7 +19,6 @@
import logging
import sys
import threading
from collections import OrderedDict
from time import strftime, localtime
from PyQt5 import QtWidgets, QtCore, QtGui
@ -40,7 +39,8 @@ from .Charts import (
CapacitanceChart,
CombinedLogMagChart, GroupDelayChart, InductanceChart,
LogMagChart, PhaseChart,
MagnitudeChart, MagnitudeZChart, MagnitudeZShuntChart, MagnitudeZSeriesChart,
MagnitudeChart, MagnitudeZChart, MagnitudeZShuntChart,
MagnitudeZSeriesChart,
QualityFactorChart, VSWRChart, PermeabilityChart, PolarChart,
RealImaginaryChart, RealImaginaryShuntChart, RealImaginarySeriesChart,
SmithChart, SParameterChart, TDRChart,
@ -70,9 +70,11 @@ class NanoVNASaver(QtWidgets.QWidget):
else:
self.icon = QtGui.QIcon("icon_48x48.png")
self.setWindowIcon(self.icon)
self.settings = Defaults.AppSettings(QtCore.QSettings.IniFormat,
QtCore.QSettings.UserScope,
"NanoVNASaver", "NanoVNASaver")
self.settings = Defaults.AppSettings(
QtCore.QSettings.IniFormat,
QtCore.QSettings.UserScope,
"NanoVNASaver",
"NanoVNASaver")
logger.info("Settings from: %s", self.settings.fileName())
Defaults.cfg = Defaults.restore(self.settings)
self.threadpool = QtCore.QThreadPool()
@ -126,7 +128,8 @@ class NanoVNASaver(QtWidgets.QWidget):
self.resize(Defaults.cfg.gui.window_width,
Defaults.cfg.gui.window_height)
scrollarea.setSizePolicy(
QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
QtWidgets.QSizePolicy.MinimumExpanding,
QtWidgets.QSizePolicy.MinimumExpanding)
self.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding,
QtWidgets.QSizePolicy.MinimumExpanding)
widget = QtWidgets.QWidget()
@ -134,39 +137,40 @@ class NanoVNASaver(QtWidgets.QWidget):
scrollarea.setWidget(widget)
self.charts = {
"s11": OrderedDict((
("capacitance", CapacitanceChart("S11 Serial C")),
("group_delay", GroupDelayChart("S11 Group Delay")),
("inductance", InductanceChart("S11 Serial L")),
("log_mag", LogMagChart("S11 Return Loss")),
("magnitude", MagnitudeChart("|S11|")),
("magnitude_z", MagnitudeZChart("S11 |Z|")),
("permeability", PermeabilityChart(
"s11": {
"capacitance": CapacitanceChart("S11 Serial C"),
"group_delay": GroupDelayChart("S11 Group Delay"),
"inductance": InductanceChart("S11 Serial L"),
"log_mag": LogMagChart("S11 Return Loss"),
"magnitude": MagnitudeChart("|S11|"),
"magnitude_z": MagnitudeZChart("S11 |Z|"),
"permeability": PermeabilityChart(
"S11 R/\N{GREEK SMALL LETTER OMEGA} &"
" X/\N{GREEK SMALL LETTER OMEGA}")),
("phase", PhaseChart("S11 Phase")),
("q_factor", QualityFactorChart("S11 Quality Factor")),
("real_imag", RealImaginaryChart("S11 R+jX")),
("smith", SmithChart("S11 Smith Chart")),
("s_parameter", SParameterChart("S11 Real/Imaginary")),
("vswr", VSWRChart("S11 VSWR")),
)),
"s21": OrderedDict((
("group_delay", GroupDelayChart("S21 Group Delay",
reflective=False)),
("log_mag", LogMagChart("S21 Gain")),
("magnitude", MagnitudeChart("|S21|")),
("magnitude_z_shunt", MagnitudeZShuntChart("S21 |Z| shunt")),
("magnitude_z_series", MagnitudeZSeriesChart("S21 |Z| series")),
("real_imag_shunt", RealImaginaryShuntChart("S21 R+jX shunt")),
("real_imag_series", RealImaginarySeriesChart("S21 R+jX series")),
("phase", PhaseChart("S21 Phase")),
("polar", PolarChart("S21 Polar Plot")),
("s_parameter", SParameterChart("S21 Real/Imaginary")),
)),
"combined": OrderedDict((
("log_mag", CombinedLogMagChart("S11 & S21 LogMag")),
)),
" X/\N{GREEK SMALL LETTER OMEGA}"),
"phase": PhaseChart("S11 Phase"),
"q_factor": QualityFactorChart("S11 Quality Factor"),
"real_imag": RealImaginaryChart("S11 R+jX"),
"smith": SmithChart("S11 Smith Chart"),
"s_parameter": SParameterChart("S11 Real/Imaginary"),
"vswr": VSWRChart("S11 VSWR"),
},
"s21": {
"group_delay": GroupDelayChart("S21 Group Delay",
reflective=False),
"log_mag": LogMagChart("S21 Gain"),
"magnitude": MagnitudeChart("|S21|"),
"magnitude_z_shunt": MagnitudeZShuntChart("S21 |Z| shunt"),
"magnitude_z_series": MagnitudeZSeriesChart("S21 |Z| series"),
"real_imag_shunt": RealImaginaryShuntChart("S21 R+jX shunt"),
"real_imag_series": RealImaginarySeriesChart(
"S21 R+jX series"),
"phase": PhaseChart("S21 Phase"),
"polar": PolarChart("S21 Polar Plot"),
"s_parameter": SParameterChart("S21 Real/Imaginary"),
},
"combined": {
"log_mag": CombinedLogMagChart("S11 & S21 LogMag"),
},
}
self.tdr_chart = TDRChart("TDR")
self.tdr_mainwindow_chart = TDRChart("TDR")
@ -515,7 +519,8 @@ class NanoVNASaver(QtWidgets.QWidget):
if s11:
min_vswr = min(s11, key=lambda data: data.vswr)
self.s11_min_swr_label.setText(
f"{format_vswr(min_vswr.vswr)} @ {format_frequency(min_vswr.freq)}")
f"{format_vswr(min_vswr.vswr)} @"
f" {format_frequency(min_vswr.freq)}")
self.s11_min_rl_label.setText(format_gain(min_vswr.gain))
else:
self.s11_min_swr_label.setText("")

Wyświetl plik

@ -58,13 +58,16 @@ class CalibrationWindow(QtWidgets.QWidget):
calibration_status_layout = QtWidgets.QFormLayout()
self.calibration_status_label = QtWidgets.QLabel("Device calibration")
self.calibration_source_label = QtWidgets.QLabel("NanoVNA")
calibration_status_layout.addRow("Calibration:", self.calibration_status_label)
calibration_status_layout.addRow("Source:", self.calibration_source_label)
calibration_status_layout.addRow("Calibration:",
self.calibration_status_label)
calibration_status_layout.addRow("Source:",
self.calibration_source_label)
calibration_status_group.setLayout(calibration_status_layout)
left_layout.addWidget(calibration_status_group)
calibration_control_group = QtWidgets.QGroupBox("Calibrate")
calibration_control_layout = QtWidgets.QFormLayout(calibration_control_group)
calibration_control_layout = QtWidgets.QFormLayout(
calibration_control_group)
cal_btn = {}
self.cal_label = {}
for label_name in Calibration.CAL_NAMES:
@ -72,7 +75,8 @@ class CalibrationWindow(QtWidgets.QWidget):
cal_btn[label_name] = QtWidgets.QPushButton(
label_name.capitalize())
cal_btn[label_name].setMinimumHeight(20)
cal_btn[label_name].clicked.connect(partial(self.manual_save, label_name))
cal_btn[label_name].clicked.connect(
partial(self.manual_save, label_name))
calibration_control_layout.addRow(
cal_btn[label_name], self.cal_label[label_name])
@ -85,7 +89,8 @@ class CalibrationWindow(QtWidgets.QWidget):
self.input_offset_delay.setRange(-10e6, 10e6)
calibration_control_layout.addRow(QtWidgets.QLabel(""))
calibration_control_layout.addRow("Offset delay", self.input_offset_delay)
calibration_control_layout.addRow(
"Offset delay", self.input_offset_delay)
self.btn_automatic = QtWidgets.QPushButton("Calibration assistant")
self.btn_automatic.setMinimumHeight(20)
@ -110,7 +115,8 @@ class CalibrationWindow(QtWidgets.QWidget):
left_layout.addWidget(calibration_control_group)
calibration_notes_group = QtWidgets.QGroupBox("Notes")
calibration_notes_layout = QtWidgets.QVBoxLayout(calibration_notes_group)
calibration_notes_layout = QtWidgets.QVBoxLayout(
calibration_notes_group)
self.notes_textedit = QtWidgets.QPlainTextEdit()
calibration_notes_layout.addWidget(self.notes_textedit)
@ -208,7 +214,8 @@ class CalibrationWindow(QtWidgets.QWidget):
cal_standard_layout.addWidget(self.cal_through_box)
self.cal_standard_save_box = QtWidgets.QGroupBox("Saved settings")
cal_standard_save_layout = QtWidgets.QVBoxLayout(self.cal_standard_save_box)
cal_standard_save_layout = QtWidgets.QVBoxLayout(
self.cal_standard_save_box)
self.cal_standard_save_box.setDisabled(True)
self.cal_standard_save_selector = QtWidgets.QComboBox()
@ -237,15 +244,18 @@ class CalibrationWindow(QtWidgets.QWidget):
if not self.app.settings.value("ExpertCalibrationUser", False, bool):
response = QtWidgets.QMessageBox.question(
self, "Are you sure?",
"Use of the manual calibration buttons " +
"is non-intuitive, and primarily suited for users with very " +
"specialized needs. The buttons do not sweep for you, nor do " +
"they interact with the NanoVNA calibration.\n\n" +
"If you are trying to do a calibration of the NanoVNA, do so " +
"on the device itself instead. If you are trying to do a " +
"calibration with NanoVNA-Saver, use the Calibration Assistant " +
"if possible.\n\n" +
"If you are certain you know what you are doing, click Yes.",
(
"Use of the manual calibration buttons is non-intuitive,"
" and primarily suited for users with very specialized"
" needs. The buttons do not sweep for you, nor do"
" they interact with the NanoVNA calibration.\n\n"
"If you are trying to do a calibration of the NanoVNA, do"
"so on the device itself instead. If you are trying to do"
"a calibration with NanoVNA-Saver, use the Calibration"
"Assistant if possible.\n\n"
"If you are certain you know what you are doing, click"
" Yes."
),
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Cancel,
QtWidgets.QMessageBox.Cancel)
@ -256,7 +266,7 @@ class CalibrationWindow(QtWidgets.QWidget):
return True
def cal_save(self, name: str):
if name in ("through", "isolation"):
if name in {"through", "isolation"}:
self.app.calibration.insert(name, self.app.data.s21)
else:
self.app.calibration.insert(name, self.app.data.s11)
@ -269,7 +279,8 @@ class CalibrationWindow(QtWidgets.QWidget):
def listCalibrationStandards(self):
self.cal_standard_save_selector.clear()
num_standards = self.app.settings.beginReadArray("CalibrationStandards")
num_standards = self.app.settings.beginReadArray(
"CalibrationStandards")
for i in range(num_standards):
self.app.settings.setArrayIndex(i)
name = self.app.settings.value("Name", defaultValue="INVALID NAME")
@ -279,7 +290,8 @@ class CalibrationWindow(QtWidgets.QWidget):
self.cal_standard_save_selector.setCurrentText("New")
def saveCalibrationStandard(self):
num_standards = self.app.settings.beginReadArray("CalibrationStandards")
num_standards = self.app.settings.beginReadArray(
"CalibrationStandards")
self.app.settings.endArray()
if self.cal_standard_save_selector.currentData() == -1:
@ -295,7 +307,8 @@ class CalibrationWindow(QtWidgets.QWidget):
write_num = self.cal_standard_save_selector.currentData()
name = self.cal_standard_save_selector.currentText()
self.app.settings.beginWriteArray("CalibrationStandards", num_standards)
self.app.settings.beginWriteArray(
"CalibrationStandards", num_standards)
self.app.settings.setArrayIndex(write_num)
self.app.settings.setValue("Name", name)
@ -338,7 +351,8 @@ class CalibrationWindow(QtWidgets.QWidget):
self.short_l1_input.setText(str(self.app.settings.value("ShortL1", 0)))
self.short_l2_input.setText(str(self.app.settings.value("ShortL2", 0)))
self.short_l3_input.setText(str(self.app.settings.value("ShortL3", 0)))
self.short_length.setText(str(self.app.settings.value("ShortDelay", 0)))
self.short_length.setText(
str(self.app.settings.value("ShortDelay", 0)))
self.open_c0_input.setText(str(self.app.settings.value("OpenC0", 50)))
self.open_c1_input.setText(str(self.app.settings.value("OpenC1", 0)))
@ -351,7 +365,8 @@ class CalibrationWindow(QtWidgets.QWidget):
self.load_capacitance.setText(str(self.app.settings.value("LoadC", 0)))
self.load_length.setText(str(self.app.settings.value("LoadDelay", 0)))
self.through_length.setText(str(self.app.settings.value("ThroughDelay", 0)))
self.through_length.setText(
str(self.app.settings.value("ThroughDelay", 0)))
self.app.settings.endArray()
@ -360,7 +375,8 @@ class CalibrationWindow(QtWidgets.QWidget):
return
delete_num = self.cal_standard_save_selector.currentData()
logger.debug("Deleting calibration no %d", delete_num)
num_standards = self.app.settings.beginReadArray("CalibrationStandards")
num_standards = self.app.settings.beginReadArray(
"CalibrationStandards")
self.app.settings.endArray()
logger.debug("Number of standards known: %d", num_standards)
@ -422,7 +438,8 @@ class CalibrationWindow(QtWidgets.QWidget):
self.app.settings.remove("")
self.app.settings.endArray()
self.app.settings.beginWriteArray("CalibrationStandards", len(names))
self.app.settings.beginWriteArray(
"CalibrationStandards", len(names))
for i, name in enumerate(names):
self.app.settings.setArrayIndex(i)
self.app.settings.setValue("Name", name)
@ -475,14 +492,21 @@ class CalibrationWindow(QtWidgets.QWidget):
self.app.worker.applyCalibration(
self.app.worker.rawData11, self.app.worker.rawData21)
logger.debug("Saving and displaying corrected data.")
self.app.saveData(self.app.worker.data11, self.app.worker.data21, self.app.sweepSource)
self.app.saveData(self.app.worker.data11,
self.app.worker.data21, self.app.sweepSource)
self.app.worker.signals.updated.emit()
def calculate(self):
def _warn_ideal(cal_type: str) -> str:
return (
'Invalid data for "{cal_type}" calibration standard.'
' Using ideal values.')
if self.app.sweep_control.btn_stop.isEnabled():
# Currently sweeping
self.app.showError("Unable to apply calibration while a sweep is running. " +
"Please stop the sweep and try again.")
self.app.showError(
"Unable to apply calibration while a sweep is running."
" Please stop the sweep and try again.")
return
if self.use_ideal_values.isChecked():
self.app.calibration.useIdealShort = True
@ -505,8 +529,7 @@ class CalibrationWindow(QtWidgets.QWidget):
self.app.calibration.useIdealShort = False
except ValueError:
self.app.calibration.useIdealShort = True
logger.warning(
'Invalid data for "short" calibration standard. Using ideal values.')
logger.warning(_warn_ideal("short"))
try:
self.app.calibration.openC0 = self.getFloatValue(
@ -522,8 +545,7 @@ class CalibrationWindow(QtWidgets.QWidget):
self.app.calibration.useIdealOpen = False
except ValueError:
self.app.calibration.useIdealOpen = True
logger.warning(
'Invalid data for "open" calibration standard. Using ideal values.')
logger.warning(_warn_ideal("open"))
try:
self.app.calibration.loadR = self.getFloatValue(
@ -537,18 +559,15 @@ class CalibrationWindow(QtWidgets.QWidget):
self.app.calibration.useIdealLoad = False
except ValueError:
self.app.calibration.useIdealLoad = True
logger.warning(
'Invalid data for "load" calibration standard.'
' Using ideal values.')
logger.warning(_warn_ideal("load"))
try:
self.app.calibration.throughLength = self.getFloatValue(
self.through_length.text()) / 10 ** 12
self.app.calibration.useIdealThrough = False
except ValueError:
self.app.calibration.useIdealThrough = True
logger.warning(
'Invalid data for "through" calibration standard.'
' Using ideal values.')
logger.warning(_warn_ideal("through"))
logger.debug("Attempting calibration calculation.")
try:
@ -557,32 +576,35 @@ class CalibrationWindow(QtWidgets.QWidget):
_format_cal_label(self.app.calibration.size(),
"Application calibration"))
if self.use_ideal_values.isChecked():
self.calibration_source_label.setText(self.app.calibration.source)
self.calibration_source_label.setText(
self.app.calibration.source)
else:
self.calibration_source_label.setText(
self.app.calibration.source + " (Standards: Custom)")
f"{self.app.calibration.source} (Standards: Custom)")
if len(self.app.worker.rawData11) > 0:
if self.app.worker.rawData11:
# There's raw data, so we can get corrected data
logger.debug("Applying calibration to existing sweep data.")
self.app.worker.data11, self.app.worker.data21 = self.app.worker.applyCalibration(
self.app.worker.rawData11, self.app.worker.rawData21)
self.app.worker.data11, self.app.worker.data21 = (
self.app.worker.applyCalibration(
self.app.worker.rawData11,
self.app.worker.rawData21))
logger.debug("Saving and displaying corrected data.")
self.app.saveData(self.app.worker.data11,
self.app.worker.data21, self.app.sweepSource)
self.app.worker.signals.updated.emit()
except ValueError as e:
# showError here hides the calibration window, so we need to pop up our own
QtWidgets.QMessageBox.warning(self, "Error applying calibration", str(e))
self.calibration_status_label.setText("Applying calibration failed.")
# showError here hides the calibration window,
# so we need to pop up our own
QtWidgets.QMessageBox.warning(
self, "Error applying calibration", str(e))
self.calibration_status_label.setText(
"Applying calibration failed.")
self.calibration_source_label.setText(self.app.calibration.source)
@staticmethod
def getFloatValue(text: str) -> float:
if text == "":
# Default value is float
return 0
return float(text)
return float(text) if text else 0.0
def loadCalibration(self):
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
@ -594,7 +616,8 @@ class CalibrationWindow(QtWidgets.QWidget):
for i, name in enumerate(
("short", "open", "load", "through", "isolation", "thrurefl")):
self.cal_label[name].setText(
_format_cal_label(self.app.calibration.data_size(name), "Loaded"))
_format_cal_label(self.app.calibration.data_size(name),
"Loaded"))
if i == 2 and not self.app.calibration.isValid2Port():
break
self.calculate()
@ -612,15 +635,15 @@ class CalibrationWindow(QtWidgets.QWidget):
filedialog.setDefaultSuffix("cal")
filedialog.setNameFilter("Calibration Files (*.cal);;All files (*.*)")
filedialog.setAcceptMode(QtWidgets.QFileDialog.AcceptSave)
selected = filedialog.exec()
if selected:
if filedialog.exec():
filename = filedialog.selectedFiles()[0]
else:
return
if filename == "":
if not filename:
logger.debug("No file name selected.")
return
self.app.calibration.notes = self.notes_textedit.toPlainText().splitlines()
self.app.calibration.notes = self.notes_textedit.toPlainText(
).splitlines()
try:
self.app.calibration.save(filename)
self.app.settings.setValue("CalibrationFile", filename)
@ -633,25 +656,28 @@ class CalibrationWindow(QtWidgets.QWidget):
self.cal_open_box.setDisabled(self.use_ideal_values.isChecked())
self.cal_load_box.setDisabled(self.use_ideal_values.isChecked())
self.cal_through_box.setDisabled(self.use_ideal_values.isChecked())
self.cal_standard_save_box.setDisabled(self.use_ideal_values.isChecked())
self.cal_standard_save_box.setDisabled(
self.use_ideal_values.isChecked())
def automaticCalibration(self):
self.btn_automatic.setDisabled(True)
introduction = QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Information,
"Calibration assistant",
"This calibration assistant will help you create a calibration in the "
"NanoVNASaver application. It will sweep the standards for you, and "
"guide you through the process.<br><br>"
"Before starting, ensure you have Open, Short and Load standards "
"available, and the cables you wish to have calibrated with the device "
"connected.<br><br>"
"If you want a 2-port calibration, also have a \"through\" connector "
"to hand.<br><br>"
"<b>The best results are achieved by having the NanoVNA calibrated "
"on-device for the full span of interest and saved to save slot 0 "
"before starting.</b><br><br>"
"Once you are ready to proceed, press Ok",
(
"This calibration assistant will help you create a calibration"
" in the NanoVNASaver application. It will sweep the"
"standards for you, and guide you through the process.<br><br>"
"Before starting, ensure you have Open, Short and Load"
" standards available, and the cables you wish to have"
" calibrated with the device connected.<br><br>"
"If you want a 2-port calibration, also have a \"through\""
" connector to hand.<br><br>"
"<b>The best results are achieved by having the NanoVNA"
" calibrated on-device for the full span of interest and saved"
" to save slot 0 before starting.</b><br><br>"
"Once you are ready to proceed, press Ok."
),
QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
response = introduction.exec()
if response != QtWidgets.QMessageBox.Ok:
@ -662,7 +688,8 @@ class CalibrationWindow(QtWidgets.QWidget):
QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Information,
"NanoVNA not connected",
"Please ensure the NanoVNA is connected before attempting calibration."
("Please ensure the NanoVNA is connected before attempting"
" calibration.")
).exec()
self.btn_automatic.setDisabled(False)
return
@ -671,7 +698,8 @@ class CalibrationWindow(QtWidgets.QWidget):
QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Information,
"Continuous sweep enabled",
"Please disable continuous sweeping before attempting calibration."
("Please disable continuous sweeping before attempting"
" calibration.")
).exec()
self.btn_automatic.setDisabled(False)
return
@ -679,8 +707,11 @@ class CalibrationWindow(QtWidgets.QWidget):
short_step = QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Information,
"Calibrate short",
"Please connect the \"short\" standard to port 0 of the NanoVNA.\n\n"
"Press Ok when you are ready to continue.",
(
"Please connect the \"short\" standard to port 0 of the"
" NanoVNA.\n\n"
"Press Ok when you are ready to continue."
),
QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
response = short_step.exec()
@ -696,7 +727,8 @@ class CalibrationWindow(QtWidgets.QWidget):
def automaticCalibrationStep(self):
if self.nextStep == -1:
self.app.worker.signals.finished.disconnect(self.automaticCalibrationStep)
self.app.worker.signals.finished.disconnect(
self.automaticCalibrationStep)
return
if self.nextStep == 0:
@ -707,10 +739,13 @@ class CalibrationWindow(QtWidgets.QWidget):
open_step = QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Information,
"Calibrate open",
"Please connect the \"open\" standard to port 0 of the NanoVNA.\n\n"
"Either use a supplied open, or leave the end of the cable unconnected "
"if desired.\n\n"
"Press Ok when you are ready to continue.",
(
"Please connect the \"open\" standard to port 0 of the"
" NanoVNA.\n\n"
"Either use a supplied open, or leave the end of the"
" cable unconnected if desired.\n\n"
"Press Ok when you are ready to continue."
),
QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
response = open_step.exec()
@ -730,8 +765,11 @@ class CalibrationWindow(QtWidgets.QWidget):
load_step = QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Information,
"Calibrate load",
"Please connect the \"load\" standard to port 0 of the NanoVNA.\n\n"
"Press Ok when you are ready to continue.",
(
"Please connect the \"load\" standard to port 0 of the"
" NanoVNA.\n\n"
"Press Ok when you are ready to continue."
),
QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
response = load_step.exec()
@ -751,9 +789,13 @@ class CalibrationWindow(QtWidgets.QWidget):
continue_step = QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Information,
"1-port calibration complete",
"The required steps for a 1-port calibration are now complete.\n\n"
"If you wish to continue and perform a 2-port calibration, press "
"\"Yes\". To apply the 1-port calibration and stop, press \"Apply\"",
(
"The required steps for a 1-port calibration are now"
" complete.\n\n"
"If you wish to continue and perform a 2-port calibration,"
" press \"Yes\". To apply the 1-port calibration and stop,"
" press \"Apply\""
),
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Apply |
QtWidgets.QMessageBox.Cancel)
@ -761,21 +803,27 @@ class CalibrationWindow(QtWidgets.QWidget):
if response == QtWidgets.QMessageBox.Apply:
self.calculate()
self.nextStep = -1
self.app.worker.signals.finished.disconnect(self.automaticCalibrationStep)
self.app.worker.signals.finished.disconnect(
self.automaticCalibrationStep)
self.btn_automatic.setDisabled(False)
return
if response != QtWidgets.QMessageBox.Yes:
self.btn_automatic.setDisabled(False)
self.nextStep = -1
self.app.worker.signals.finished.disconnect(self.automaticCalibrationStep)
self.app.worker.signals.finished.disconnect(
self.automaticCalibrationStep)
return
isolation_step = QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Information,
"Calibrate isolation",
"Please connect the \"load\" standard to port 1 of the NanoVNA.\n\n"
"If available, also connect a load standard to port 0.\n\n"
"Press Ok when you are ready to continue.",
(
"Please connect the \"load\" standard to port 1 of the"
" NanoVNA.\n\n"
"If available, also connect a load standard to"
" port 0.\n\n"
"Press Ok when you are ready to continue."
),
QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
response = isolation_step.exec()
@ -795,9 +843,11 @@ class CalibrationWindow(QtWidgets.QWidget):
through_step = QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Information,
"Calibrate through",
"Please connect the \"through\" standard between port 0 and port 1 "
"of the NanoVNA.\n\n"
"Press Ok when you are ready to continue.",
(
"Please connect the \"through\" standard between"
" port 0 and port 1 of the NanoVNA.\n\n"
"Press Ok when you are ready to continue."
),
QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
response = through_step.exec()
@ -817,8 +867,10 @@ class CalibrationWindow(QtWidgets.QWidget):
apply_step = QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Information,
"Calibrate complete",
"The calibration process is now complete. Press \"Apply\" to apply "
"the calibration parameters.",
(
"The calibration process is now complete. Press"
" \"Apply\" to apply the calibration parameters."
),
QtWidgets.QMessageBox.Apply | QtWidgets.QMessageBox.Cancel)
response = apply_step.exec()

Wyświetl plik

@ -58,7 +58,8 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
self.returnloss_group.addButton(self.returnloss_is_positive)
self.returnloss_group.addButton(self.returnloss_is_negative)
display_options_layout.addRow("Return loss is:", self.returnloss_is_negative)
display_options_layout.addRow(
"Return loss is:", self.returnloss_is_negative)
display_options_layout.addRow("", self.returnloss_is_positive)
self.returnloss_is_positive.setChecked(
@ -70,7 +71,8 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
self.changeReturnLoss()
self.show_lines_option = QtWidgets.QCheckBox("Show lines")
show_lines_label = QtWidgets.QLabel("Displays a thin line between data points")
show_lines_label = QtWidgets.QLabel(
"Displays a thin line between data points")
self.show_lines_option.stateChanged.connect(self.changeShowLines)
display_options_layout.addRow(self.show_lines_option, show_lines_label)
@ -103,7 +105,8 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
self.lineThicknessInput.setSuffix(" px")
self.lineThicknessInput.setAlignment(QtCore.Qt.AlignRight)
self.lineThicknessInput.valueChanged.connect(self.changeLineThickness)
display_options_layout.addRow("Line thickness", self.lineThicknessInput)
display_options_layout.addRow(
"Line thickness", self.lineThicknessInput)
self.markerSizeInput = QtWidgets.QSpinBox()
self.markerSizeInput.setMinimumHeight(20)
@ -117,18 +120,26 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
self.markerSizeInput.valueChanged.connect(self.changeMarkerSize)
display_options_layout.addRow("Marker size", self.markerSizeInput)
self.show_marker_number_option = QtWidgets.QCheckBox("Show marker numbers")
show_marker_number_label = QtWidgets.QLabel("Displays the marker number next to the marker")
self.show_marker_number_option.stateChanged.connect(self.changeShowMarkerNumber)
display_options_layout.addRow(self.show_marker_number_option, show_marker_number_label)
self.show_marker_number_option = QtWidgets.QCheckBox(
"Show marker numbers")
show_marker_number_label = QtWidgets.QLabel(
"Displays the marker number next to the marker")
self.show_marker_number_option.stateChanged.connect(
self.changeShowMarkerNumber)
display_options_layout.addRow(
self.show_marker_number_option, show_marker_number_label)
self.filled_marker_option = QtWidgets.QCheckBox("Filled markers")
filled_marker_label = QtWidgets.QLabel("Shows the marker as a filled triangle")
self.filled_marker_option.stateChanged.connect(self.changeFilledMarkers)
display_options_layout.addRow(self.filled_marker_option, filled_marker_label)
filled_marker_label = QtWidgets.QLabel(
"Shows the marker as a filled triangle")
self.filled_marker_option.stateChanged.connect(
self.changeFilledMarkers)
display_options_layout.addRow(
self.filled_marker_option, filled_marker_label)
self.marker_tip_group = QtWidgets.QButtonGroup()
self.marker_at_center = QtWidgets.QRadioButton("At the center of the marker")
self.marker_at_center = QtWidgets.QRadioButton(
"At the center of the marker")
self.marker_at_tip = QtWidgets.QRadioButton("At the tip of the marker")
self.marker_tip_group.addButton(self.marker_at_center)
self.marker_tip_group.addButton(self.marker_at_tip)
@ -170,7 +181,8 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
self.show_bands = QtWidgets.QCheckBox("Show bands")
self.show_bands.setChecked(self.app.bands.enabled)
self.show_bands.stateChanged.connect(lambda: self.setShowBands(self.show_bands.isChecked()))
self.show_bands.stateChanged.connect(
lambda: self.setShowBands(self.show_bands.isChecked()))
bands_layout.addRow(self.show_bands)
bands_layout.addRow(
"Chart bands",
@ -187,14 +199,15 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
vswr_marker_box = QtWidgets.QGroupBox("VSWR Markers")
vswr_marker_layout = QtWidgets.QFormLayout(vswr_marker_box)
self.vswrMarkers: List[float] = self.app.settings.value("VSWRMarkers", [], float)
self.vswrMarkers: List[float] = self.app.settings.value(
"VSWRMarkers", [], float)
if isinstance(self.vswrMarkers, float):
# Single values from the .ini become floats rather than lists. Convert them.
self.vswrMarkers = [] if self.vswrMarkers == 0.0 else [self.vswrMarkers]
vswr_marker_layout.addRow(
"VSWR Markers",self.color_picker("VSWRColor", "swr"))
"VSWR Markers", self.color_picker("VSWRColor", "swr"))
self.vswr_marker_dropdown = QtWidgets.QComboBox()
self.vswr_marker_dropdown.setMinimumHeight(20)
@ -416,9 +429,7 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
for c in self.app.selectable_charts:
if c.name == chart:
found = c
self.app.settings.setValue("Chart" + str(x) + str(y), chart)
self.app.settings.setValue(f"Chart{x}{y}", chart)
old_widget = self.app.charts_layout.itemAtPosition(x, y)
if old_widget is not None:
w = old_widget.widget()
@ -428,7 +439,6 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
if self.app.charts_layout.indexOf(found) > -1:
logger.debug("%s is already shown, duplicating.", found.name)
found = self.app.copyChart(found)
self.app.charts_layout.addWidget(found, x, y)
if found.isHidden():
found.show()
@ -471,7 +481,7 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
c.setPointSize(size)
def changeLineThickness(self, size: int):
Defaults.cfg.chart.line_thickness = int(size)
Defaults.cfg.chart.line_thickness = size
for c in self.app.subscribing_charts:
c.setLineThickness(size)
@ -551,7 +561,8 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
new_marker.updated.connect(self.app.markerUpdated)
label, layout = new_marker.getRow()
self.app.marker_control.layout.insertRow(Marker.count() - 1, label, layout)
self.app.marker_control.layout.insertRow(
Marker.count() - 1, label, layout)
self.btn_remove_marker.setDisabled(False)
if Marker.count() >= 2:
@ -569,7 +580,7 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
last_marker.updated.disconnect(self.app.markerUpdated)
self.app.marker_data_layout.removeWidget(last_marker.get_data_layout())
self.app.marker_control.layout.removeRow(Marker.count()-1)
self.app.marker_control.layout.removeRow(Marker.count() - 1)
self.app.marker_frame.adjustSize()
last_marker.get_data_layout().hide()
@ -579,7 +590,8 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
def addVSWRMarker(self):
value, selected = QtWidgets.QInputDialog.getDouble(
self, "Add VSWR Marker", "VSWR value to show:", min=1.001, decimals=3)
self, "Add VSWR Marker", "VSWR value to show:",
min=1.001, decimals=3)
if selected:
self.vswrMarkers.append(value)
if self.vswr_marker_dropdown.itemText(0) == "None":
@ -595,7 +607,8 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
if value_str != "None":
value = float(value_str)
self.vswrMarkers.remove(value)
self.vswr_marker_dropdown.removeItem(self.vswr_marker_dropdown.currentIndex())
self.vswr_marker_dropdown.removeItem(
self.vswr_marker_dropdown.currentIndex())
if self.vswr_marker_dropdown.count() == 0:
self.vswr_marker_dropdown.addItem("None")
self.app.settings.remove("VSWRMarkers")
@ -607,4 +620,4 @@ class DisplaySettingsWindow(QtWidgets.QWidget):
def updateCharts(self):
for c in self.app.subscribing_charts:
c.update()
Defaults.store(self.app.settings, Defaults.cfg)
Defaults.store(self.app.settings, Defaults.cfg)