Merge pull request #506 from zarath/feature/linting_20220525

just linting
pull/507/head
Holger Müller 2022-05-27 11:01:05 +02:00 zatwierdzone przez GitHub
commit 7b9d803b35
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
33 zmienionych plików z 146 dodań i 146 usunięć

Wyświetl plik

@ -30,7 +30,7 @@ class Analysis:
@classmethod @classmethod
def find_crossing_zero(cls, data): def find_crossing_zero(cls, data):
''' """
Find values crossing zero Find values crossing zero
return list of tuples (before, crossing, after) return list of tuples (before, crossing, after)
@ -44,7 +44,7 @@ class Analysis:
:param cls: :param cls:
:param data: list of values :param data: list of values
''' """
my_data = np.array(data) my_data = np.array(data)
zeroes = np.where(my_data == 0)[0] zeroes = np.where(my_data == 0)[0]
@ -65,7 +65,7 @@ class Analysis:
@classmethod @classmethod
def find_minimums(cls, data, threshold): def find_minimums(cls, data, threshold):
''' """
Find values above threshold Find values above threshold
return list of tuples (start, lowest, end) return list of tuples (start, lowest, end)
@ -75,7 +75,7 @@ class Analysis:
:param cls: :param cls:
:param data: list of values :param data: list of values
:param threshold: :param threshold:
''' """
minimums = [] minimums = []
min_start = -1 min_start = -1
@ -100,7 +100,7 @@ class Analysis:
@classmethod @classmethod
def find_maximums(cls, data, threshold=None): def find_maximums(cls, data, threshold=None):
''' """
Find peacs Find peacs
@ -108,7 +108,7 @@ class Analysis:
:param cls: :param cls:
:param data: list of values :param data: list of values
:param threshold: :param threshold:
''' """
peaks, _ = signal.find_peaks( peaks, _ = signal.find_peaks(
data, width=2, distance=3, prominence=1) data, width=2, distance=3, prominence=1)

Wyświetl plik

@ -34,11 +34,11 @@ logger = logging.getLogger(__name__)
class MagLoopAnalysis(VSWRAnalysis): class MagLoopAnalysis(VSWRAnalysis):
''' """
Find min vswr and change sweep to zoom. Find min vswr and change sweep to zoom.
Useful for tuning magloop. Useful for tuning magloop.
''' """
max_dips_shown = 1 max_dips_shown = 1
vswr_bandwith_value = 2.56 # -3 dB ?!? vswr_bandwith_value = 2.56 # -3 dB ?!?
@ -115,10 +115,10 @@ class MagLoopAnalysis(VSWRAnalysis):
QTimer.singleShot(2000, self._safe_sweep) QTimer.singleShot(2000, self._safe_sweep)
def _safe_sweep(self): def _safe_sweep(self):
''' """
sweep only if button enabled sweep only if button enabled
to prevent multiple/concurrent sweep to prevent multiple/concurrent sweep
''' """
if self.app.sweep_control.btn_start.isEnabled(): if self.app.sweep_control.btn_start.isEnabled():
self.app.sweep_start() self.app.sweep_start()

Wyświetl plik

@ -220,10 +220,10 @@ class ResonanceAnalysis(Analysis):
for _ in range(results_header, self.layout.rowCount()): for _ in range(results_header, self.layout.rowCount()):
self.layout.removeRow(self.layout.rowCount() - 1) self.layout.removeRow(self.layout.rowCount() - 1)
# if len(crossing) > max_dips_shown: # if len(crossing) > max_dips_shown:
# self.layout.addRow(QtWidgets.QLabel("<b>More than " + str(max_dips_shown) + # self.layout.addRow(QtWidgets.QLabel("<b>More than " + str(max_dips_shown) +
# " dips found. Lowest shown.</b>")) # " dips found. Lowest shown.</b>"))
# self.crossing = crossing[:max_dips_shown] # self.crossing = crossing[:max_dips_shown]
if len(crossing) > 0: if len(crossing) > 0:
extended_data = [] extended_data = []
for m in crossing: for m in crossing:
@ -262,9 +262,9 @@ class ResonanceAnalysis(Analysis):
class EFHWAnalysis(ResonanceAnalysis): class EFHWAnalysis(ResonanceAnalysis):
''' """
find only resonance when HI impedance find only resonance when HI impedance
''' """
old_data = [] old_data = []
def reset(self): def reset(self):
@ -296,7 +296,7 @@ class EFHWAnalysis(ResonanceAnalysis):
extended_data = OrderedDict() extended_data = OrderedDict()
#both = np.intersect1d([i[1] for i in crossing], maximums) # both = np.intersect1d([i[1] for i in crossing], maximums)
both = [] both = []
tolerance = 2 tolerance = 2
@ -320,7 +320,6 @@ class EFHWAnalysis(ResonanceAnalysis):
else: else:
extended_data[m] = my_data extended_data[m] = my_data
for i in range(min(len(both), len(self.app.markers))): for i in range(min(len(both), len(self.app.markers))):
# self.app.markers[i].label = {} # self.app.markers[i].label = {}
# for l in TYPES: # for l in TYPES:
# self.app.markers[i][l.label_id] = MarkerLabel(l.name) # self.app.markers[i][l.label_id] = MarkerLabel(l.name)
@ -366,7 +365,6 @@ class EFHWAnalysis(ResonanceAnalysis):
self.old_data.append(extended_data) self.old_data.append(extended_data)
for i, index in enumerate(sorted(extended_data.keys())): for i, index in enumerate(sorted(extended_data.keys())):
self.layout.addRow( self.layout.addRow(
f"{format_frequency_short(self.app.data.s11[index].freq)}", f"{format_frequency_short(self.app.data.s11[index].freq)}",
QtWidgets.QLabel(f" ({diff[i]['freq']})" QtWidgets.QLabel(f" ({diff[i]['freq']})"
@ -389,7 +387,7 @@ class EFHWAnalysis(ResonanceAnalysis):
writer.writerow(row) writer.writerow(row)
def compare(self, old, new, fields=None): def compare(self, old, new, fields=None):
''' """
Compare data to help changes Compare data to help changes
NB NB
@ -397,7 +395,7 @@ class EFHWAnalysis(ResonanceAnalysis):
( same index must be same frequence ) ( same index must be same frequence )
:param old: :param old:
:param new: :param new:
''' """
fields = fields or [("freq", str), ] fields = fields or [("freq", str), ]
def no_compare(): def no_compare():

Wyświetl plik

@ -198,14 +198,14 @@ class Calibration:
g2 * g3 * gm2 - g2 * g3 * gm3 - g2 * g3 * gm2 - g2 * g3 * gm3 -
(g2 * gm2 - g3 * gm3) * g1) (g2 * gm2 - g3 * gm3) * g1)
cal["e00"] = - ((g2 * gm3 - g3 * gm3) * g1 * gm2 - cal["e00"] = - ((g2 * gm3 - g3 * gm3) * g1 * gm2 -
(g2 * g3 * gm2 - g2 * g3 * gm3 - (g2 * g3 * gm2 - g2 * g3 * gm3 -
(g3 * gm2 - g2 * gm3) * g1) * gm1 (g3 * gm2 - g2 * gm3) * g1) * gm1
) / denominator ) / denominator
cal["e11"] = ((g2 - g3) * gm1 - g1 * (gm2 - gm3) + cal["e11"] = ((g2 - g3) * gm1 - g1 * (gm2 - gm3) +
g3 * gm2 - g2 * gm3) / denominator g3 * gm2 - g2 * gm3) / denominator
cal["delta_e"] = - ((g1 * (gm2 - gm3) - g2 * gm2 + g3 * cal["delta_e"] = - ((g1 * (gm2 - gm3) - g2 * gm2 + g3 *
gm3) * gm1 + (g2 * gm3 - g3 * gm3) * gm3) * gm1 + (g2 * gm3 - g3 * gm3) *
gm2) / denominator gm2) / denominator
def _calc_port_2(self, freq: int, cal: CalData): def _calc_port_2(self, freq: int, cal: CalData):
gt = self.gamma_through(freq) gt = self.gamma_through(freq)
@ -218,9 +218,9 @@ class Calibration:
cal["e30"] = cal["isolation"].z cal["e30"] = cal["isolation"].z
cal["e10e01"] = cal["e00"] * cal["e11"] - cal["delta_e"] cal["e10e01"] = cal["e00"] * cal["e11"] - cal["delta_e"]
cal["e22"] = gm7 / ( 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) * ( cal["e10e32"] = (gm4 - gm6) * (
1 - cal["e11"] * cal["e22"] *gt**2) / gt 1 - cal["e11"] * cal["e22"] * gt ** 2) / gt
def calc_corrections(self): def calc_corrections(self):
if not self.isValid1Port(): if not self.isValid1Port():
@ -254,8 +254,8 @@ class Calibration:
if not self.useIdealShort: if not self.useIdealShort:
logger.debug("Using short calibration set values.") logger.debug("Using short calibration set values.")
Zsp = complex(0, 2 * math.pi * freq * ( Zsp = complex(0, 2 * math.pi * freq * (
self.shortL0 + self.shortL1 * freq + self.shortL0 + self.shortL1 * freq +
self.shortL2 * freq**2 + self.shortL3 * freq**3)) self.shortL2 * freq ** 2 + self.shortL3 * freq ** 3))
# Referencing https://arxiv.org/pdf/1606.02446.pdf (18) - (21) # Referencing https://arxiv.org/pdf/1606.02446.pdf (18) - (21)
g = (Zsp / 50 - 1) / (Zsp / 50 + 1) * cmath.exp( g = (Zsp / 50 - 1) / (Zsp / 50 + 1) * cmath.exp(
complex(0, 2 * math.pi * 2 * freq * self.shortLength * -1)) complex(0, 2 * math.pi * 2 * freq * self.shortLength * -1))
@ -266,8 +266,8 @@ class Calibration:
if not self.useIdealOpen: if not self.useIdealOpen:
logger.debug("Using open calibration set values.") logger.debug("Using open calibration set values.")
Zop = complex(0, 2 * math.pi * freq * ( Zop = complex(0, 2 * math.pi * freq * (
self.openC0 + self.openC1 * freq + self.openC0 + self.openC1 * freq +
self.openC2 * freq**2 + self.openC3 * freq**3)) self.openC2 * freq ** 2 + self.openC3 * freq ** 3))
g = ((1 - 50 * Zop) / (1 + 50 * Zop)) * cmath.exp( g = ((1 - 50 * Zop) / (1 + 50 * Zop)) * cmath.exp(
complex(0, 2 * math.pi * 2 * freq * self.openLength * -1)) complex(0, 2 * math.pi * 2 * freq * self.openLength * -1))
return g return g
@ -324,8 +324,8 @@ class Calibration:
kind="slinear", bounds_error=False, kind="slinear", bounds_error=False,
fill_value=(delta_e[0], delta_e[-1])), fill_value=(delta_e[0], delta_e[-1])),
"e10e01": interp1d(freq, e10e01, "e10e01": interp1d(freq, e10e01,
kind="slinear", bounds_error=False, kind="slinear", bounds_error=False,
fill_value=(e10e01[0], e10e01[-1])), fill_value=(e10e01[0], e10e01[-1])),
"e30": interp1d(freq, e30, "e30": interp1d(freq, e30,
kind="slinear", bounds_error=False, kind="slinear", bounds_error=False,
fill_value=(e30[0], e30[-1])), fill_value=(e30[0], e30[-1])),
@ -340,13 +340,13 @@ class Calibration:
def correct11(self, dp: Datapoint): def correct11(self, dp: Datapoint):
i = self.interp i = self.interp
s11 = (dp.z - i["e00"](dp.freq)) / ( 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) return Datapoint(dp.freq, s11.real, s11.imag)
def correct21(self, dp: Datapoint, dp11: Datapoint): def correct21(self, dp: Datapoint, dp11: Datapoint):
i = self.interp i = self.interp
s21 = (dp.z - i["e30"](dp.freq)) / i["e10e32"](dp.freq) 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) return Datapoint(dp.freq, s21.real, s21.imag)
# TODO: implement tests # TODO: implement tests
@ -381,7 +381,7 @@ class Calibration:
continue continue
if line.startswith("#"): if line.startswith("#"):
if not parsed_header and line == ( if not parsed_header and line == (
"# Hz ShortR ShortI OpenR OpenI LoadR LoadI" "# Hz ShortR ShortI OpenR OpenI LoadR LoadI"
" ThroughR ThroughI ThrureflR ThrureflI IsolationR IsolationI"): " ThroughR ThroughI ThrureflR ThrureflI IsolationR IsolationI"):
parsed_header = True parsed_header = True
continue continue

Wyświetl plik

@ -22,6 +22,7 @@ from PyQt5 import QtWidgets, QtCore
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Control(QtWidgets.QGroupBox): class Control(QtWidgets.QGroupBox):
updated = QtCore.pyqtSignal(object) updated = QtCore.pyqtSignal(object)

Wyświetl plik

@ -25,12 +25,11 @@ from NanoVNASaver import Defaults
from NanoVNASaver.Marker import Marker from NanoVNASaver.Marker import Marker
from NanoVNASaver.Controls.Control import Control from NanoVNASaver.Controls.Control import Control
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ShowButton(QtWidgets.QPushButton): class ShowButton(QtWidgets.QPushButton):
def setText(self, text: str=''): def setText(self, text: str = ''):
if not text: if not text:
text = ("Show data" text = ("Show data"
if Defaults.cfg.gui.markers_hidden else "Hide data") if Defaults.cfg.gui.markers_hidden else "Hide data")
@ -87,6 +86,7 @@ class MarkerControl(Control):
Defaults.cfg.gui.markers_hidden) Defaults.cfg.gui.markers_hidden)
self.showMarkerButton.setText() self.showMarkerButton.setText()
self.showMarkerButton.repaint() self.showMarkerButton.repaint()
settings(self.app.marker_frame.isHidden()) settings(self.app.marker_frame.isHidden())
def toggle_delta(self): def toggle_delta(self):

Wyświetl plik

@ -26,6 +26,7 @@ from NanoVNASaver.Controls.Control import Control
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class SerialControl(Control): class SerialControl(Control):
def __init__(self, app: QtWidgets.QWidget): def __init__(self, app: QtWidgets.QWidget):

Wyświetl plik

@ -18,6 +18,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
import math import math
from numbers import Number from numbers import Number
from typing import Union
from NanoVNASaver import SITools from NanoVNASaver import SITools
@ -42,13 +43,14 @@ FMT_PARSE = SITools.Format(parse_sloppy_unit=True, parse_sloppy_kilo=True,
parse_clamp_min=0) parse_clamp_min=0)
FMT_PARSE_VALUE = SITools.Format( FMT_PARSE_VALUE = SITools.Format(
parse_sloppy_unit=True, parse_sloppy_kilo=True) parse_sloppy_unit=True, parse_sloppy_kilo=True)
FMT_VSWR = SITools.Format(max_nr_digits=3)
def format_frequency(freq: Number) -> str: def format_frequency(freq: Number) -> str:
return str(SITools.Value(freq, "Hz", FMT_FREQ)) return str(SITools.Value(freq, "Hz", FMT_FREQ))
def format_frequency_inputs(freq: float) -> str: def format_frequency_inputs(freq: Union[Number, str]) -> str:
return str(SITools.Value(freq, "Hz", FMT_FREQ_INPUTS)) return str(SITools.Value(freq, "Hz", FMT_FREQ_INPUTS))
@ -140,7 +142,7 @@ def format_wavelength(length: Number) -> str:
return str(SITools.Value(length, "m", FMT_WAVELENGTH)) return str(SITools.Value(length, "m", FMT_WAVELENGTH))
def format_y_axis(val: float, unit: str="") -> str: def format_y_axis(val: float, unit: str = "") -> str:
return str(SITools.Value(val, unit, FMT_SHORT)) return str(SITools.Value(val, unit, FMT_SHORT))
@ -152,7 +154,7 @@ def parse_frequency(freq: str) -> int:
def parse_value(val: str, unit: str = "", def parse_value(val: str, unit: str = "",
fmt: SITools.Format = FMT_PARSE_VALUE) -> int: fmt: SITools.Format = FMT_PARSE_VALUE) -> float:
try: try:
val.replace(',', '.') val.replace(',', '.')
return float(SITools.Value(val, unit, fmt)) return float(SITools.Value(val, unit, fmt))

Wyświetl plik

@ -25,6 +25,7 @@ from typing import List
import serial import serial
from serial.tools import list_ports from serial.tools import list_ports
from NanoVNASaver.Hardware.VNA import VNA
from NanoVNASaver.Hardware.AVNA import AVNA from NanoVNASaver.Hardware.AVNA import AVNA
from NanoVNASaver.Hardware.NanoVNA import NanoVNA from NanoVNASaver.Hardware.NanoVNA import NanoVNA
from NanoVNASaver.Hardware.NanoVNA_F import NanoVNA_F from NanoVNASaver.Hardware.NanoVNA_F import NanoVNA_F
@ -34,8 +35,6 @@ from NanoVNASaver.Hardware.NanoVNA_H4 import NanoVNA_H4
from NanoVNASaver.Hardware.NanoVNA_V2 import NanoVNA_V2 from NanoVNASaver.Hardware.NanoVNA_V2 import NanoVNA_V2
from NanoVNASaver.Hardware.TinySA import TinySA from NanoVNASaver.Hardware.TinySA import TinySA
from NanoVNASaver.Hardware.Serial import drain_serial, Interface from NanoVNASaver.Hardware.Serial import drain_serial, Interface
from NanoVNASaver.Hardware.VNA import VNA
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -51,7 +50,7 @@ TIMEOUT = 0.2
WAIT = 0.05 WAIT = 0.05
NAME2DEVICE = { NAME2DEVICE = {
"S-A-A-2" : NanoVNA_V2, "S-A-A-2": NanoVNA_V2,
"AVNA": AVNA, "AVNA": AVNA,
"H4": NanoVNA_H4, "H4": NanoVNA_H4,
"H": NanoVNA_H, "H": NanoVNA_H,
@ -62,6 +61,7 @@ NAME2DEVICE = {
"Unknown": NanoVNA, "Unknown": NanoVNA,
} }
# The USB Driver for NanoVNA V2 seems to deliver an # The USB Driver for NanoVNA V2 seems to deliver an
# incompatible hardware info like: # incompatible hardware info like:
# 'PORTS\\VID_04B4&PID_0008\\DEMO' # 'PORTS\\VID_04B4&PID_0008\\DEMO'
@ -88,11 +88,7 @@ def get_interfaces() -> List[Interface]:
t.name, d.vid, d.pid, d.device) t.name, d.vid, d.pid, d.device)
iface = Interface('serial', t.name) iface = Interface('serial', t.name)
iface.port = d.device iface.port = d.device
try: iface.open()
iface.open()
except serial.SerialException:
logger.warning("Could not open serial port %s", d.device)
continue
iface.comment = get_comment(iface) iface.comment = get_comment(iface)
iface.close() iface.close()
interfaces.append(iface) interfaces.append(iface)
@ -101,10 +97,11 @@ def get_interfaces() -> List[Interface]:
return interfaces return interfaces
def get_VNA(iface: Interface) -> 'VNA': def get_VNA(iface: Interface) -> VNA:
# serial_port.timeout = TIMEOUT # serial_port.timeout = TIMEOUT
return NAME2DEVICE[iface.comment](iface) return NAME2DEVICE[iface.comment](iface)
def get_comment(iface: Interface) -> str: def get_comment(iface: Interface) -> str:
logger.info("Finding correct VNA type...") logger.info("Finding correct VNA type...")
with iface.lock: with iface.lock:
@ -116,19 +113,20 @@ def get_comment(iface: Interface) -> str:
logger.info("Finding firmware variant...") logger.info("Finding firmware variant...")
info = get_info(iface) info = get_info(iface)
for search, name in ( for search, name in (
("AVNA + Teensy", "AVNA"), ("AVNA + Teensy", "AVNA"),
("NanoVNA-H 4", "H4"), ("NanoVNA-H 4", "H4"),
("NanoVNA-H", "H"), ("NanoVNA-H", "H"),
("NanoVNA-F_V2", "F_V2"), ("NanoVNA-F_V2", "F_V2"),
("NanoVNA-F", "F"), ("NanoVNA-F", "F"),
("NanoVNA", "NanoVNA"), ("NanoVNA", "NanoVNA"),
("tinySA", "tinySA"), ("tinySA", "tinySA"),
): ):
if info.find(search) >= 0: if info.find(search) >= 0:
return name return name
logger.warning("Did not recognize NanoVNA type from firmware.") logger.warning("Did not recognize NanoVNA type from firmware.")
return "Unknown" return "Unknown"
def detect_version(serial_port: serial.Serial) -> str: def detect_version(serial_port: serial.Serial) -> str:
data = "" data = ""
for i in range(RETRIES): for i in range(RETRIES):

Wyświetl plik

@ -61,7 +61,6 @@ class NanoVNA(VNA):
timeout = self.serial.timeout timeout = self.serial.timeout
with self.serial.lock: with self.serial.lock:
drain_serial(self.serial) drain_serial(self.serial)
timeout = self.serial.timeout
self.serial.write("capture\r".encode('ascii')) self.serial.write("capture\r".encode('ascii'))
self.serial.readline() self.serial.readline()
self.serial.timeout = 4 self.serial.timeout = 4

Wyświetl plik

@ -66,6 +66,7 @@ _ADF4350_TXPOWER_DESC_MAP = {
_ADF4350_TXPOWER_DESC_REV_MAP = { _ADF4350_TXPOWER_DESC_REV_MAP = {
value: key for key, value in _ADF4350_TXPOWER_DESC_MAP.items()} value: key for key, value in _ADF4350_TXPOWER_DESC_MAP.items()}
class NanoVNA_V2(VNA): class NanoVNA_V2(VNA):
name = "NanoVNA-V2" name = "NanoVNA-V2"
valid_datapoints = (101, 11, 51, 201, 301, 501, 1023) valid_datapoints = (101, 11, 51, 201, 301, 501, 1023)
@ -145,7 +146,7 @@ class NanoVNA_V2(VNA):
sleep(WRITE_SLEEP) sleep(WRITE_SLEEP)
# clear sweepdata # clear sweepdata
self._sweepdata = [(complex(), complex())] * ( self._sweepdata = [(complex(), complex())] * (
self.datapoints + s21hack) self.datapoints + s21hack)
pointstodo = self.datapoints + s21hack pointstodo = self.datapoints + s21hack
# we read at most 255 values at a time and the time required empirically is # we read at most 255 values at a time and the time required empirically is
# just over 3 seconds for 101 points or 7 seconds for 255 points # just over 3 seconds for 101 points or 7 seconds for 255 points
@ -178,7 +179,7 @@ class NanoVNA_V2(VNA):
for i in range(pointstoread): for i in range(pointstoread):
(fwd_real, fwd_imag, rev0_real, rev0_imag, rev1_real, (fwd_real, fwd_imag, rev0_real, rev0_imag, rev1_real,
rev1_imag, freq_index) = unpack_from( rev1_imag, freq_index) = unpack_from(
"<iiiiiihxxxxxx", arr, i * 32) "<iiiiiihxxxxxx", arr, i * 32)
fwd = complex(fwd_real, fwd_imag) fwd = complex(fwd_real, fwd_imag)
refl = complex(rev0_real, rev0_imag) refl = complex(rev0_real, rev0_imag)
thru = complex(rev1_real, rev1_imag) thru = complex(rev1_real, rev1_imag)
@ -237,7 +238,6 @@ class NanoVNA_V2(VNA):
logger.debug("read_board_revision: %s", result) logger.debug("read_board_revision: %s", result)
return result return result
def setSweep(self, start, stop): def setSweep(self, start, stop):
step = (stop - start) / (self.datapoints - 1) step = (stop - start) / (self.datapoints - 1)
if start == self.sweepStartHz and step == self.sweepStepHz: if start == self.sweepStartHz and step == self.sweepStepHz:
@ -271,6 +271,7 @@ class NanoVNA_V2(VNA):
self._set_register(0x42, _ADF4350_TXPOWER_DESC_REV_MAP[power_desc], 1) self._set_register(0x42, _ADF4350_TXPOWER_DESC_REV_MAP[power_desc], 1)
def _set_register(self, addr, value, size): def _set_register(self, addr, value, size):
packet = b''
if size == 1: if size == 1:
packet = pack("<BBB", _CMD_WRITE, addr, value) packet = pack("<BBB", _CMD_WRITE, addr, value)
elif size == 2: elif size == 2:

Wyświetl plik

@ -60,7 +60,6 @@ class TinySA(VNA):
timeout = self.serial.timeout timeout = self.serial.timeout
with self.serial.lock: with self.serial.lock:
drain_serial(self.serial) drain_serial(self.serial)
timeout = self.serial.timeout
self.serial.write("capture\r".encode('ascii')) self.serial.write("capture\r".encode('ascii'))
self.serial.readline() self.serial.readline()
self.serial.timeout = 4 self.serial.timeout = 4

Wyświetl plik

@ -155,11 +155,11 @@ class VNA:
pass pass
def _get_running_frequencies(self): def _get_running_frequencies(self):
''' """
If possible, read frequencies already runnung If possible, read frequencies already runnung
if not return default values if not return default values
Overwrite in specific HW Overwrite in specific HW
''' """
return 27000000, 30000000 return 27000000, 30000000
def connected(self) -> bool: def connected(self) -> bool:

Wyświetl plik

@ -28,7 +28,6 @@ class FrequencyInputWidget(QtWidgets.QLineEdit):
self.previousFrequency = -1 self.previousFrequency = -1
def setText(self, text: str) -> None: def setText(self, text: str) -> None:
# TODO: Fix wrong type here
super().setText(format_frequency_inputs(text)) super().setText(format_frequency_inputs(text))

Wyświetl plik

@ -37,6 +37,7 @@ from NanoVNASaver.Formatting import (
from .Widget import Marker from .Widget import Marker
class DeltaMarker(Marker): class DeltaMarker(Marker):
def __init__(self, name: str = "", qsettings: QtCore.QSettings = None): def __init__(self, name: str = "", qsettings: QtCore.QSettings = None):
super().__init__(name, qsettings) super().__init__(name, qsettings)
@ -71,10 +72,10 @@ class DeltaMarker(Marker):
imp_p = imp_p_b - imp_p_a imp_p = imp_p_b - imp_p_a
cap_p_str = format_capacitance( cap_p_str = format_capacitance(
RFTools.impedance_to_capacitance(imp_p_b, s11_b.freq)- RFTools.impedance_to_capacitance(imp_p_b, s11_b.freq) -
RFTools.impedance_to_capacitance(imp_p_a, s11_a.freq)) RFTools.impedance_to_capacitance(imp_p_a, s11_a.freq))
ind_p_str = format_inductance( ind_p_str = format_inductance(
RFTools.impedance_to_inductance(imp_p_b, s11_b.freq)- RFTools.impedance_to_inductance(imp_p_b, s11_b.freq) -
RFTools.impedance_to_inductance(imp_p_a, s11_a.freq)) RFTools.impedance_to_inductance(imp_p_a, s11_a.freq))
x_str = cap_str if imp.imag < 0 else ind_str x_str = cap_str if imp.imag < 0 else ind_str
@ -126,5 +127,5 @@ class DeltaMarker(Marker):
self.label['s21phase'].setText(format_phase( self.label['s21phase'].setText(format_phase(
s21_b.phase - s21_a.phase)) s21_b.phase - s21_a.phase))
self.label['s21polar'].setText( self.label['s21polar'].setText(
f"{round(abs(s21_b.z) - abs(s21_a.z) , 2)}" f"{round(abs(s21_b.z) - abs(s21_a.z), 2)}"
f"{format_phase(s21_b.phase - s21_a.phase)}") f"{format_phase(s21_b.phase - s21_a.phase)}")

Wyświetl plik

@ -45,16 +45,12 @@ class Datapoint(NamedTuple):
@property @property
def gain(self) -> float: def gain(self) -> float:
mag = abs(self.z) mag = abs(self.z)
if mag > 0: return 20 * math.log10(mag) if mag > 0 else -math.inf
return 20 * math.log10(mag)
return -math.inf
@property @property
def vswr(self) -> float: def vswr(self) -> float:
mag = abs(self.z) mag = abs(self.z)
if mag >= 1: return (1 + mag) / (1 - mag) if mag < 1 else math.inf
return math.inf
return (1 + mag) / (1 - mag)
@property @property
def wavelength(self) -> float: def wavelength(self) -> float:
@ -77,9 +73,7 @@ class Datapoint(NamedTuple):
def qFactor(self, ref_impedance: float = 50) -> float: def qFactor(self, ref_impedance: float = 50) -> float:
imp = self.impedance(ref_impedance) imp = self.impedance(ref_impedance)
if imp.real == 0.0: return -1 if imp.real == 0.0 else abs(imp.imag / imp.real)
return -1
return abs(imp.imag / imp.real)
def capacitiveEquivalent(self, ref_impedance: float = 50) -> float: def capacitiveEquivalent(self, ref_impedance: float = 50) -> float:
return impedance_to_capacitance(self.impedance(ref_impedance), self.freq) return impedance_to_capacitance(self.impedance(ref_impedance), self.freq)
@ -101,9 +95,7 @@ def groupDelay(data: List[Datapoint], index: int) -> float:
idx1 = clamp_value(index + 1, 0, len(data) - 1) idx1 = clamp_value(index + 1, 0, len(data) - 1)
delta_angle = data[idx1].phase - data[idx0].phase delta_angle = data[idx1].phase - data[idx0].phase
delta_freq = data[idx1].freq - data[idx0].freq delta_freq = data[idx1].freq - data[idx0].freq
if delta_freq == 0: return 0 if delta_freq == 0 else -delta_angle / math.tau / delta_freq
return 0
return -delta_angle / math.tau / delta_freq
def impedance_to_capacitance(z: complex, freq: float) -> float: def impedance_to_capacitance(z: complex, freq: float) -> float:
@ -117,9 +109,7 @@ def impedance_to_capacitance(z: complex, freq: float) -> float:
def impedance_to_inductance(z: complex, freq: float) -> float: def impedance_to_inductance(z: complex, freq: float) -> float:
"""Calculate inductive equivalent for reactance""" """Calculate inductive equivalent for reactance"""
if freq == 0: return 0 if freq == 0 else z.imag * 1 / (freq * 2 * math.pi)
return 0
return z.imag * 1 / (freq * 2 * math.pi)
def impedance_to_norm(z: complex, ref_impedance: float = 50) -> complex: def impedance_to_norm(z: complex, ref_impedance: float = 50) -> complex:
@ -134,8 +124,7 @@ def norm_to_impedance(z: complex, ref_impedance: float = 50) -> complex:
def parallel_to_serial(z: complex) -> complex: def parallel_to_serial(z: complex) -> complex:
"""Convert parallel impedance to serial impedance equivalent""" """Convert parallel impedance to serial impedance equivalent"""
z_sq_sum = z.real ** 2 + z.imag ** 2 z_sq_sum = z.real ** 2 + z.imag ** 2 or 10.0e-30
# TODO: Fix divide by zero
return complex(z.real * z.imag ** 2 / z_sq_sum, return complex(z.real * z.imag ** 2 / z_sq_sum,
z.real ** 2 * z.imag / z_sq_sum) z.real ** 2 * z.imag / z_sq_sum)
@ -150,9 +139,6 @@ def serial_to_parallel(z: complex) -> complex:
z_sq_sum = z.real ** 2 + z.imag ** 2 z_sq_sum = z.real ** 2 + z.imag ** 2
if z.real == 0 and z.imag == 0: if z.real == 0 and z.imag == 0:
return complex(math.inf, math.inf) return complex(math.inf, math.inf)
# only possible if real and imag == 0, therefor commented out
# if z_sq_sum == 0:
# return complex(0, 0)
if z.imag == 0: if z.imag == 0:
return complex(z_sq_sum / z.real, math.copysign(math.inf, z_sq_sum)) return complex(z_sq_sum / z.real, math.copysign(math.inf, z_sq_sum))
if z.real == 0: if z.real == 0:

Wyświetl plik

@ -34,14 +34,17 @@ def clamp_value(value: Real, rmin: Real, rmax: Real) -> Real:
return rmax return rmax
return value return value
def round_ceil(value: Real, digits: int=0) -> Real:
factor = 10 ** digits def round_ceil(value: Real, digits: int = 0) -> Real:
factor = 10 ** -digits
return factor * math.ceil(value / factor) return factor * math.ceil(value / factor)
def round_floor(value: Real, digits: int=0) -> Real:
factor = 10 ** digits def round_floor(value: Real, digits: int = 0) -> Real:
factor = 10 ** -digits
return factor * math.floor(value / factor) return factor * math.floor(value / factor)
class Format(NamedTuple): class Format(NamedTuple):
max_nr_digits: int = 6 max_nr_digits: int = 6
fix_decimals: bool = False fix_decimals: bool = False
@ -105,8 +108,8 @@ class Value:
formstr = ".0f" formstr = ".0f"
else: else:
max_digits = fmt.max_nr_digits + ( max_digits = fmt.max_nr_digits + (
(1 if not fmt.fix_decimals and abs(real) < 10 else 0) + (1 if not fmt.fix_decimals and abs(real) < 10 else 0) +
(1 if not fmt.fix_decimals and abs(real) < 100 else 0)) (1 if not fmt.fix_decimals and abs(real) < 100 else 0))
formstr = f".{max_digits - 3}f" formstr = f".{max_digits - 3}f"
if self.fmt.allways_signed: if self.fmt.allways_signed:

Wyświetl plik

@ -31,7 +31,7 @@ class SweepMode(Enum):
AVERAGE = 2 AVERAGE = 2
class Properties(): class Properties:
def __init__(self, name: str = "", def __init__(self, name: str = "",
mode: 'SweepMode' = SweepMode.SINGLE, mode: 'SweepMode' = SweepMode.SINGLE,
averages: Tuple[int, int] = (3, 0), averages: Tuple[int, int] = (3, 0),
@ -47,7 +47,7 @@ class Properties():
f" {self.logarithmic})") f" {self.logarithmic})")
class Sweep(): class Sweep:
def __init__(self, start: int = 3600000, end: int = 30000000, def __init__(self, start: int = 3600000, end: int = 30000000,
points: int = 101, segments: int = 1, points: int = 101, segments: int = 1,
properties: 'Properties' = Properties()): properties: 'Properties' = Properties()):
@ -66,11 +66,11 @@ class Sweep():
f" {self.properties})") f" {self.properties})")
def __eq__(self, other) -> bool: def __eq__(self, other) -> bool:
return(self.start == other.start and return (self.start == other.start and
self.end == other.end and self.end == other.end and
self.points == other.points and self.points == other.points and
self.segments == other.segments and self.segments == other.segments and
self.properties == other.properties) self.properties == other.properties)
def copy(self) -> 'Sweep': def copy(self) -> 'Sweep':
return Sweep(self.start, self.end, self.points, self.segments, return Sweep(self.start, self.end, self.points, self.segments,
@ -82,15 +82,15 @@ class Sweep():
@property @property
def stepsize(self) -> int: def stepsize(self) -> int:
return round(self.span / (self.points * self.segments - 1)) return round(self.span / (self.points * self.segments - 1))
def check(self): def check(self):
if ( if (
self.segments <= 0 self.segments <= 0
or self.points <= 0 or self.points <= 0
or self.start <= 0 or self.start <= 0
or self.end <= 0 or self.end <= 0
or self.stepsize < 1 or self.stepsize < 1
): ):
raise ValueError(f"Illegal sweep settings: {self}") raise ValueError(f"Illegal sweep settings: {self}")
@ -105,7 +105,7 @@ class Sweep():
start = round(self.start + self.span * self._exp_factor(index)) start = round(self.start + self.span * self._exp_factor(index))
end = round(self.start + self.span * self._exp_factor(index + 1)) end = round(self.start + self.span * self._exp_factor(index + 1))
logger.debug("get_index_range(%s) -> (%s, %s)", index, start, end) logger.debug("get_index_range(%s) -> (%s, %s)", index, start, end)
return (start, end) return start, end
def get_frequencies(self) -> Iterator[int]: def get_frequencies(self) -> Iterator[int]:
for i in range(self.segments): for i in range(self.segments):

Wyświetl plik

@ -226,6 +226,7 @@ class SweepWorker(QtCore.QRunnable):
logger.debug("Reading average no %d / %d", i + 1, averages) logger.debug("Reading average no %d / %d", i + 1, averages)
retry = 0 retry = 0
tmp11 = [] tmp11 = []
tmp21 = []
while not tmp11 and retry < 5: while not tmp11 and retry < 5:
sleep(0.5 * retry) sleep(0.5 * retry)
retry += 1 retry += 1

Wyświetl plik

@ -35,10 +35,10 @@ class Options:
# Fun fact: In Touchstone 1.1 spec all params are optional unordered. # Fun fact: In Touchstone 1.1 spec all params are optional unordered.
# Just the line has to start with "#" # Just the line has to start with "#"
UNIT_TO_FACTOR = { UNIT_TO_FACTOR = {
"ghz": 10**9, "ghz": 10 ** 9,
"mhz": 10**6, "mhz": 10 ** 6,
"khz": 10**3, "khz": 10 ** 3,
"hz": 10**0, "hz": 10 ** 0,
} }
VALID_UNITS = UNIT_TO_FACTOR.keys() VALID_UNITS = UNIT_TO_FACTOR.keys()
VALID_PARAMETERS = "syzgh" VALID_PARAMETERS = "syzgh"
@ -98,7 +98,7 @@ class Options:
class Touchstone: class Touchstone:
FIELD_ORDER = ("11", "21", "12", "22") FIELD_ORDER = ("11", "21", "12", "22")
def __init__(self, filename: str=""): def __init__(self, filename: str = ""):
self.filename = filename self.filename = filename
self.sdata = [[], [], [], []] # at max 4 data pairs self.sdata = [[], [], [], []] # at max 4 data pairs
self.comments = [] self.comments = []
@ -244,7 +244,6 @@ class Touchstone:
if data_len % 2 != 0: if data_len % 2 != 0:
raise TypeError("Data values aren't pairs: " + line) raise TypeError("Data values aren't pairs: " + line)
# consistency checks # consistency checks
if freq <= prev_freq: if freq <= prev_freq:
logger.warning("Frequency not ascending: %s", line) logger.warning("Frequency not ascending: %s", line)

Wyświetl plik

@ -187,7 +187,7 @@ class CalibrationWindow(QtWidgets.QWidget):
self.load_inductance.setMinimumHeight(20) self.load_inductance.setMinimumHeight(20)
self.load_capacitance = QtWidgets.QLineEdit("0") self.load_capacitance = QtWidgets.QLineEdit("0")
self.load_capacitance.setMinimumHeight(20) self.load_capacitance.setMinimumHeight(20)
#self.load_capacitance.setDisabled(True) # Not yet implemented # self.load_capacitance.setDisabled(True) # Not yet implemented
self.load_length = QtWidgets.QLineEdit("0") self.load_length = QtWidgets.QLineEdit("0")
self.load_length.setMinimumHeight(20) self.load_length.setMinimumHeight(20)
cal_load_form.addRow("Resistance (\N{OHM SIGN})", self.load_resistance) cal_load_form.addRow("Resistance (\N{OHM SIGN})", self.load_resistance)
@ -493,15 +493,15 @@ class CalibrationWindow(QtWidgets.QWidget):
# We are using custom calibration standards # We are using custom calibration standards
try: try:
self.app.calibration.shortL0 = self.getFloatValue( self.app.calibration.shortL0 = self.getFloatValue(
self.short_l0_input.text())/10**12 self.short_l0_input.text()) / 10 ** 12
self.app.calibration.shortL1 = self.getFloatValue( self.app.calibration.shortL1 = self.getFloatValue(
self.short_l1_input.text())/10**24 self.short_l1_input.text()) / 10 ** 24
self.app.calibration.shortL2 = self.getFloatValue( self.app.calibration.shortL2 = self.getFloatValue(
self.short_l2_input.text())/10**33 self.short_l2_input.text()) / 10 ** 33
self.app.calibration.shortL3 = self.getFloatValue( self.app.calibration.shortL3 = self.getFloatValue(
self.short_l3_input.text())/10**42 self.short_l3_input.text()) / 10 ** 42
self.app.calibration.shortLength = self.getFloatValue( self.app.calibration.shortLength = self.getFloatValue(
self.short_length.text())/10**12 self.short_length.text()) / 10 ** 12
self.app.calibration.useIdealShort = False self.app.calibration.useIdealShort = False
except ValueError: except ValueError:
self.app.calibration.useIdealShort = True self.app.calibration.useIdealShort = True
@ -510,15 +510,15 @@ class CalibrationWindow(QtWidgets.QWidget):
try: try:
self.app.calibration.openC0 = self.getFloatValue( self.app.calibration.openC0 = self.getFloatValue(
self.open_c0_input.text())/10**15 self.open_c0_input.text()) / 10 ** 15
self.app.calibration.openC1 = self.getFloatValue( self.app.calibration.openC1 = self.getFloatValue(
self.open_c1_input.text())/10**27 self.open_c1_input.text()) / 10 ** 27
self.app.calibration.openC2 = self.getFloatValue( self.app.calibration.openC2 = self.getFloatValue(
self.open_c2_input.text())/10**36 self.open_c2_input.text()) / 10 ** 36
self.app.calibration.openC3 = self.getFloatValue( self.app.calibration.openC3 = self.getFloatValue(
self.open_c3_input.text())/10**45 self.open_c3_input.text()) / 10 ** 45
self.app.calibration.openLength = self.getFloatValue( self.app.calibration.openLength = self.getFloatValue(
self.open_length.text())/10**12 self.open_length.text()) / 10 ** 12
self.app.calibration.useIdealOpen = False self.app.calibration.useIdealOpen = False
except ValueError: except ValueError:
self.app.calibration.useIdealOpen = True self.app.calibration.useIdealOpen = True
@ -529,11 +529,11 @@ class CalibrationWindow(QtWidgets.QWidget):
self.app.calibration.loadR = self.getFloatValue( self.app.calibration.loadR = self.getFloatValue(
self.load_resistance.text()) self.load_resistance.text())
self.app.calibration.loadL = self.getFloatValue( self.app.calibration.loadL = self.getFloatValue(
self.load_inductance.text()) / 10**12 self.load_inductance.text()) / 10 ** 12
self.app.calibration.loadC = self.getFloatValue( self.app.calibration.loadC = self.getFloatValue(
self.load_capacitance.text()) / 10 ** 15 self.load_capacitance.text()) / 10 ** 15
self.app.calibration.loadLength = self.getFloatValue( self.app.calibration.loadLength = self.getFloatValue(
self.load_length.text())/10**12 self.load_length.text()) / 10 ** 12
self.app.calibration.useIdealLoad = False self.app.calibration.useIdealLoad = False
except ValueError: except ValueError:
self.app.calibration.useIdealLoad = True self.app.calibration.useIdealLoad = True
@ -542,7 +542,7 @@ class CalibrationWindow(QtWidgets.QWidget):
' Using ideal values.') ' Using ideal values.')
try: try:
self.app.calibration.throughLength = self.getFloatValue( self.app.calibration.throughLength = self.getFloatValue(
self.through_length.text())/10**12 self.through_length.text()) / 10 ** 12
self.app.calibration.useIdealThrough = False self.app.calibration.useIdealThrough = False
except ValueError: except ValueError:
self.app.calibration.useIdealThrough = True self.app.calibration.useIdealThrough = True

Wyświetl plik

@ -24,6 +24,7 @@ from NanoVNASaver.RFTools import Datapoint
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class FilesWindow(QtWidgets.QWidget): class FilesWindow(QtWidgets.QWidget):
def __init__(self, app: QtWidgets.QWidget): def __init__(self, app: QtWidgets.QWidget):
super().__init__() super().__init__()

Wyświetl plik

@ -102,7 +102,7 @@ class SweepSettingsWindow(QtWidgets.QWidget):
" amount of datapoints and many segments. Step display in" " amount of datapoints and many segments. Step display in"
" SweepControl cannot reflect this currently.") " SweepControl cannot reflect this currently.")
label.setWordWrap(True) label.setWordWrap(True)
label.setMinimumSize(600,70) label.setMinimumSize(600, 70)
layout.addRow(label) layout.addRow(label)
checkbox = QtWidgets.QCheckBox("Logarithmic sweep") checkbox = QtWidgets.QCheckBox("Logarithmic sweep")
checkbox.setMinimumHeight(20) checkbox.setMinimumHeight(20)

Wyświetl plik

@ -101,5 +101,6 @@ def main():
logger.exception("%s", exc) logger.exception("%s", exc)
raise exc raise exc
if __name__ == '__main__': if __name__ == '__main__':
main() main()

Wyświetl plik

@ -17,6 +17,7 @@
from contextlib import suppress from contextlib import suppress
# noinspection PyUnresolvedReferences
with suppress(ImportError): with suppress(ImportError):
# pylint: disable=no-name-in-module,import-error,unused-import # pylint: disable=no-name-in-module,import-error,unused-import
# pyright: reportMissingImports=false # pyright: reportMissingImports=false

Wyświetl plik

@ -24,6 +24,7 @@ import unittest
# Import targets to be tested # Import targets to be tested
from NanoVNASaver.Formatting import format_frequency_sweep from NanoVNASaver.Formatting import format_frequency_sweep
class TestCases(unittest.TestCase): class TestCases(unittest.TestCase):
def test_basicIntegerValues(self): def test_basicIntegerValues(self):
@ -47,7 +48,7 @@ class TestCases(unittest.TestCase):
# self.assertEqual(rft.formatSweepFrequency(10000), '10.00kHz') # self.assertEqual(rft.formatSweepFrequency(10000), '10.00kHz')
# self.assertEqual(rft.formatSweepFrequency(100000), '100.00kHz') # self.assertEqual(rft.formatSweepFrequency(100000), '100.00kHz')
# self.assertEqual(rft.formatSweepFrequency(1000000), '1.00MHz') # self.assertEqual(rft.formatSweepFrequency(1000000), '1.00MHz')
# def test_nonDefaultMinDigits(self): # def test_nonDefaultMinDigits(self):
# # simple integers with trailing zeros. setting mindigit value to something # # simple integers with trailing zeros. setting mindigit value to something
# # other than default, where trailing zeros >= mindigits, the number of # # other than default, where trailing zeros >= mindigits, the number of
@ -69,4 +70,3 @@ class TestCases(unittest.TestCase):
# # TODO: Consider post-processing result for maxdigits based on SI unit. # # TODO: Consider post-processing result for maxdigits based on SI unit.
# self.assertEqual(rft.formatSweepFrequency(1000, mindigits=5), '1.00000kHz') # self.assertEqual(rft.formatSweepFrequency(1000, mindigits=5), '1.00000kHz')
# self.assertEqual(rft.formatSweepFrequency(1000, mindigits=10), '1.0000000000kHz') # self.assertEqual(rft.formatSweepFrequency(1000, mindigits=10), '1.0000000000kHz')

Wyświetl plik

@ -22,6 +22,7 @@ import unittest
# Import targets to be tested # Import targets to be tested
from NanoVNASaver.Formatting import parse_frequency from NanoVNASaver.Formatting import parse_frequency
# TODO: should be tested against SITools.Value # TODO: should be tested against SITools.Value
# RFTools.parseFrequency will hopefully go away in future # RFTools.parseFrequency will hopefully go away in future
# and be specialised by input field and device, like # and be specialised by input field and device, like
@ -149,4 +150,3 @@ class TestCases(unittest.TestCase):
self.assertEqual(parse_frequency('123...Hz'), -1) self.assertEqual(parse_frequency('123...Hz'), -1)
self.assertEqual(parse_frequency('123....Hz'), -1) self.assertEqual(parse_frequency('123....Hz'), -1)
self.assertEqual(parse_frequency('1.23.Hz'), -1) self.assertEqual(parse_frequency('1.23.Hz'), -1)

Wyświetl plik

@ -75,7 +75,7 @@ class TestRFTools(unittest.TestCase):
self.assertEqual(clamp_value(1, -10, -1), -1) self.assertEqual(clamp_value(1, -10, -1), -1)
def test_parallel_to_serial(self): def test_parallel_to_serial(self):
self.assertRaises(ZeroDivisionError, parallel_to_serial, 0) self.assertEqual(parallel_to_serial(0), complex(0, 0))
self.assertAlmostEqual( self.assertAlmostEqual(
parallel_to_serial(complex(52, 260)), parallel_to_serial(complex(52, 260)),
complex(50, 10)) complex(50, 10))

Wyświetl plik

@ -29,7 +29,7 @@ class TConfig:
my_str: str = "Hello World" my_str: str = "Hello World"
my_bool: bool = True my_bool: bool = True
my_list: list = field(default_factory=lambda: [1, 2, 3]) my_list: list = field(default_factory=lambda: [1, 2, 3])
my_bytearray: bytearray = field(default_factory=lambda: bytearray((1,2,3))) my_bytearray: bytearray = field(default_factory=lambda: bytearray((1, 2, 3)))
class TestCases(unittest.TestCase): class TestCases(unittest.TestCase):
@ -37,7 +37,7 @@ class TestCases(unittest.TestCase):
def setUp(self) -> None: def setUp(self) -> None:
self.settings_1 = CFG.AppSettings( self.settings_1 = CFG.AppSettings(
CFG.QSettings.IniFormat, CFG.QSettings.IniFormat,
CFG.QSettings.UserScope, CFG.QSettings.UserScope,
"NanoVNASaver", "Test_1") "NanoVNASaver", "Test_1")
self.settings_2 = CFG.AppSettings( self.settings_2 = CFG.AppSettings(
CFG.QSettings.IniFormat, CFG.QSettings.IniFormat,
@ -57,7 +57,7 @@ class TestCases(unittest.TestCase):
illegal_config = TConfig( illegal_config = TConfig(
my_int=4, my_float=3.0, my_str="Goodbye World", my_int=4, my_float=3.0, my_str="Goodbye World",
my_bool="False", my_list=(4, 5, 6)) my_bool="False", my_list=(4, 5, 6))
with self.assertRaises(AssertionError): with self.assertRaises(TypeError):
self.settings_1.store_dataclass("SectionX", illegal_config) self.settings_1.store_dataclass("SectionX", illegal_config)
def test_restore_dataclass(self): def test_restore_dataclass(self):
@ -85,4 +85,4 @@ class TestCases(unittest.TestCase):
tc_2 = CFG.restore(self.settings_2) tc_2 = CFG.restore(self.settings_2)
print(f"\n{tc_1}\n{tc_2}\n") print(f"\n{tc_1}\n{tc_2}\n")
self.assertEqual(tc_1, tc_2) self.assertEqual(tc_1, tc_2)
self.assertNotEqual(tc_2.gui, CFG.GUI()) self.assertNotEqual(tc_2.gui, CFG.GUI())

Wyświetl plik

@ -21,7 +21,7 @@ from math import inf
from decimal import Decimal # Needed for test_representation() from decimal import Decimal # Needed for test_representation()
# Import targets to be tested # Import targets to be tested
from NanoVNASaver.SITools import Format, Value from NanoVNASaver.SITools import Format, Value, round_floor, round_ceil
F_DEFAULT = Format() F_DEFAULT = Format()
@ -145,7 +145,6 @@ class TestTSIToolsValue(unittest.TestCase):
self.assertEqual(v.parse("\N{INFINITY}").value, inf) self.assertEqual(v.parse("\N{INFINITY}").value, inf)
self.assertEqual(v.parse("-\N{INFINITY}").value, -inf) self.assertEqual(v.parse("-\N{INFINITY}").value, -inf)
def test_format_attributes(self): def test_format_attributes(self):
v = Value("10.0", "Hz", fmt=F_DIGITS_4) v = Value("10.0", "Hz", fmt=F_DIGITS_4)
self.assertEqual(v.value, 10.0) self.assertEqual(v.value, 10.0)
@ -156,7 +155,13 @@ class TestTSIToolsValue(unittest.TestCase):
v.parse("12 GHz") v.parse("12 GHz")
self.assertEqual(v.unit, "Hz") self.assertEqual(v.unit, "Hz")
def test_rounding(self):
self.assertEqual(round_floor(123.456), 123)
self.assertEqual(round_floor(123.456, 1), 123.4)
self.assertEqual(round_floor(123.456, -1), 120)
self.assertEqual(round_ceil(123.456), 124)
self.assertEqual(round_ceil(123.456, 1), 123.5)
self.assertEqual(round_ceil(123.456, -1), 130)
# TODO: test F_DIGITS_31 # TODO: test F_DIGITS_31
# F_WITH_SPACE # F_WITH_SPACE

Wyświetl plik

@ -21,6 +21,7 @@ import unittest
# Import targets to be tested # Import targets to be tested
from NanoVNASaver.Settings.Sweep import Sweep, Properties from NanoVNASaver.Settings.Sweep import Sweep, Properties
class TestCases(unittest.TestCase): class TestCases(unittest.TestCase):
def test_sweep(self): def test_sweep(self):

Wyświetl plik

@ -24,6 +24,7 @@ import os
from NanoVNASaver.Touchstone import Options, Touchstone from NanoVNASaver.Touchstone import Options, Touchstone
from NanoVNASaver.RFTools import Datapoint from NanoVNASaver.RFTools import Datapoint
class TestTouchstoneOptions(unittest.TestCase): class TestTouchstoneOptions(unittest.TestCase):
def setUp(self): def setUp(self):
self.opts = Options() self.opts = Options()
@ -113,7 +114,7 @@ class TestTouchstoneTouchstone(unittest.TestCase):
s11, s21, s12, s22 = ts.sdata s11, s21, s12, s22 = ts.sdata
ts.swap() ts.swap()
s11_, s21_, s12_, s22_ = ts.sdata s11_, s21_, s12_, s22_ = ts.sdata
self.assertEqual([s11_, s21_, s12_, s22_] ,[s22, s12, s21, s11]) self.assertEqual([s11_, s21_, s12_, s22_], [s22, s12, s21, s11])
def test_db_conversation(self): def test_db_conversation(self):
ts_db = Touchstone("./test/data/attenuator-0643_DB.s2p") ts_db = Touchstone("./test/data/attenuator-0643_DB.s2p")
@ -143,7 +144,7 @@ class TestTouchstoneTouchstone(unittest.TestCase):
' 15000000.0 0.849810063 -0.4147357 -0.000306106 0.0041482' ' 15000000.0 0.849810063 -0.4147357 -0.000306106 0.0041482'
' 0.0 0.0 0.0 0.0', ' 0.0 0.0 0.0 0.0',
'WARNING:NanoVNASaver.Touchstone:Reordering data', 'WARNING:NanoVNASaver.Touchstone:Reordering data',
]) ])
self.assertEqual(str(ts.opts), "# HZ S RI R 50") self.assertEqual(str(ts.opts), "# HZ S RI R 50")
self.assertEqual(len(ts.s11), 101) self.assertEqual(len(ts.s11), 101)
self.assertIn("!freq ReS11 ImS11 ReS21 ImS21 ReS12 ImS12 ReS22 ImS22", self.assertIn("!freq ReS11 ImS11 ReS21 ImS21 ReS12 ImS12 ReS22 ImS22",
@ -165,7 +166,6 @@ class TestTouchstoneTouchstone(unittest.TestCase):
ts.gen_interpolation() ts.gen_interpolation()
self.assertEqual(ts.s_freq("11", 2), Datapoint(2, 0.5, 0.5)) self.assertEqual(ts.s_freq("11", 2), Datapoint(2, 0.5, 0.5))
def test_save(self): def test_save(self):
ts = Touchstone("./test/data/valid.s2p") ts = Touchstone("./test/data/valid.s2p")
self.assertEqual(ts.saves(), "# HZ S RI R 50\n") self.assertEqual(ts.saves(), "# HZ S RI R 50\n")

Wyświetl plik

@ -21,6 +21,7 @@ import unittest
# Import targets to be tested # Import targets to be tested
from NanoVNASaver.Version import Version from NanoVNASaver.Version import Version
class TestCases(unittest.TestCase): class TestCases(unittest.TestCase):
def test_version(self): def test_version(self):
@ -30,9 +31,11 @@ class TestCases(unittest.TestCase):
self.assertFalse(ver > Version("1.2.4")) self.assertFalse(ver > Version("1.2.4"))
self.assertFalse(ver > Version("1.2.3-u")) self.assertFalse(ver > Version("1.2.3-u"))
self.assertTrue(Version("1.2.4") >= ver) self.assertTrue(Version("1.2.4") >= ver)
self.assertTrue(ver < Version("1.2.4"))
self.assertFalse(Version("0.0.0") == Version("0.0.0-rc")) self.assertFalse(Version("0.0.0") == Version("0.0.0-rc"))
self.assertEqual(ver.major, 1) self.assertEqual(ver.major, 1)
self.assertEqual(ver.minor, 2) self.assertEqual(ver.minor, 2)
self.assertEqual(ver.revision, 3) self.assertEqual(ver.revision, 3)
self.assertEqual(ver.note, '-test') self.assertEqual(ver.note, '-test')
Version("asdasd") Version("asdasd")
Version("1.2.invalid")