kopia lustrzana https://github.com/NanoVNA-Saver/nanovna-saver
commit
7b9d803b35
|
@ -30,7 +30,7 @@ class Analysis:
|
|||
|
||||
@classmethod
|
||||
def find_crossing_zero(cls, data):
|
||||
'''
|
||||
"""
|
||||
|
||||
Find values crossing zero
|
||||
return list of tuples (before, crossing, after)
|
||||
|
@ -44,7 +44,7 @@ class Analysis:
|
|||
|
||||
:param cls:
|
||||
:param data: list of values
|
||||
'''
|
||||
"""
|
||||
my_data = np.array(data)
|
||||
zeroes = np.where(my_data == 0)[0]
|
||||
|
||||
|
@ -65,7 +65,7 @@ class Analysis:
|
|||
|
||||
@classmethod
|
||||
def find_minimums(cls, data, threshold):
|
||||
'''
|
||||
"""
|
||||
|
||||
Find values above threshold
|
||||
return list of tuples (start, lowest, end)
|
||||
|
@ -75,7 +75,7 @@ class Analysis:
|
|||
:param cls:
|
||||
:param data: list of values
|
||||
:param threshold:
|
||||
'''
|
||||
"""
|
||||
|
||||
minimums = []
|
||||
min_start = -1
|
||||
|
@ -100,7 +100,7 @@ class Analysis:
|
|||
|
||||
@classmethod
|
||||
def find_maximums(cls, data, threshold=None):
|
||||
'''
|
||||
"""
|
||||
|
||||
Find peacs
|
||||
|
||||
|
@ -108,7 +108,7 @@ class Analysis:
|
|||
:param cls:
|
||||
:param data: list of values
|
||||
:param threshold:
|
||||
'''
|
||||
"""
|
||||
peaks, _ = signal.find_peaks(
|
||||
data, width=2, distance=3, prominence=1)
|
||||
|
||||
|
|
|
@ -34,11 +34,11 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
|
||||
class MagLoopAnalysis(VSWRAnalysis):
|
||||
'''
|
||||
"""
|
||||
Find min vswr and change sweep to zoom.
|
||||
Useful for tuning magloop.
|
||||
|
||||
'''
|
||||
"""
|
||||
max_dips_shown = 1
|
||||
|
||||
vswr_bandwith_value = 2.56 # -3 dB ?!?
|
||||
|
@ -115,10 +115,10 @@ class MagLoopAnalysis(VSWRAnalysis):
|
|||
QTimer.singleShot(2000, self._safe_sweep)
|
||||
|
||||
def _safe_sweep(self):
|
||||
'''
|
||||
"""
|
||||
sweep only if button enabled
|
||||
to prevent multiple/concurrent sweep
|
||||
'''
|
||||
"""
|
||||
|
||||
if self.app.sweep_control.btn_start.isEnabled():
|
||||
self.app.sweep_start()
|
||||
|
|
|
@ -262,9 +262,9 @@ class ResonanceAnalysis(Analysis):
|
|||
|
||||
|
||||
class EFHWAnalysis(ResonanceAnalysis):
|
||||
'''
|
||||
"""
|
||||
find only resonance when HI impedance
|
||||
'''
|
||||
"""
|
||||
old_data = []
|
||||
|
||||
def reset(self):
|
||||
|
@ -320,7 +320,6 @@ 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)
|
||||
|
@ -366,7 +365,6 @@ class EFHWAnalysis(ResonanceAnalysis):
|
|||
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']})"
|
||||
|
@ -389,7 +387,7 @@ class EFHWAnalysis(ResonanceAnalysis):
|
|||
writer.writerow(row)
|
||||
|
||||
def compare(self, old, new, fields=None):
|
||||
'''
|
||||
"""
|
||||
Compare data to help changes
|
||||
|
||||
NB
|
||||
|
@ -397,7 +395,7 @@ class EFHWAnalysis(ResonanceAnalysis):
|
|||
( same index must be same frequence )
|
||||
:param old:
|
||||
:param new:
|
||||
'''
|
||||
"""
|
||||
fields = fields or [("freq", str), ]
|
||||
|
||||
def no_compare():
|
||||
|
|
|
@ -22,6 +22,7 @@ from PyQt5 import QtWidgets, QtCore
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Control(QtWidgets.QGroupBox):
|
||||
updated = QtCore.pyqtSignal(object)
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ from NanoVNASaver import Defaults
|
|||
from NanoVNASaver.Marker import Marker
|
||||
from NanoVNASaver.Controls.Control import Control
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -87,6 +86,7 @@ class MarkerControl(Control):
|
|||
Defaults.cfg.gui.markers_hidden)
|
||||
self.showMarkerButton.setText()
|
||||
self.showMarkerButton.repaint()
|
||||
|
||||
settings(self.app.marker_frame.isHidden())
|
||||
|
||||
def toggle_delta(self):
|
||||
|
|
|
@ -26,6 +26,7 @@ from NanoVNASaver.Controls.Control import Control
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SerialControl(Control):
|
||||
|
||||
def __init__(self, app: QtWidgets.QWidget):
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
import math
|
||||
from numbers import Number
|
||||
from typing import Union
|
||||
|
||||
from NanoVNASaver import SITools
|
||||
|
||||
|
@ -42,13 +43,14 @@ FMT_PARSE = SITools.Format(parse_sloppy_unit=True, parse_sloppy_kilo=True,
|
|||
parse_clamp_min=0)
|
||||
FMT_PARSE_VALUE = SITools.Format(
|
||||
parse_sloppy_unit=True, parse_sloppy_kilo=True)
|
||||
FMT_VSWR = SITools.Format(max_nr_digits=3)
|
||||
|
||||
|
||||
def format_frequency(freq: Number) -> str:
|
||||
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))
|
||||
|
||||
|
||||
|
@ -152,7 +154,7 @@ def parse_frequency(freq: str) -> int:
|
|||
|
||||
|
||||
def parse_value(val: str, unit: str = "",
|
||||
fmt: SITools.Format = FMT_PARSE_VALUE) -> int:
|
||||
fmt: SITools.Format = FMT_PARSE_VALUE) -> float:
|
||||
try:
|
||||
val.replace(',', '.')
|
||||
return float(SITools.Value(val, unit, fmt))
|
||||
|
|
|
@ -25,6 +25,7 @@ from typing import List
|
|||
import serial
|
||||
from serial.tools import list_ports
|
||||
|
||||
from NanoVNASaver.Hardware.VNA import VNA
|
||||
from NanoVNASaver.Hardware.AVNA import AVNA
|
||||
from NanoVNASaver.Hardware.NanoVNA import NanoVNA
|
||||
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.TinySA import TinySA
|
||||
from NanoVNASaver.Hardware.Serial import drain_serial, Interface
|
||||
from NanoVNASaver.Hardware.VNA import VNA
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -62,6 +61,7 @@ NAME2DEVICE = {
|
|||
"Unknown": NanoVNA,
|
||||
}
|
||||
|
||||
|
||||
# The USB Driver for NanoVNA V2 seems to deliver an
|
||||
# incompatible hardware info like:
|
||||
# 'PORTS\\VID_04B4&PID_0008\\DEMO'
|
||||
|
@ -88,11 +88,7 @@ def get_interfaces() -> List[Interface]:
|
|||
t.name, d.vid, d.pid, d.device)
|
||||
iface = Interface('serial', t.name)
|
||||
iface.port = d.device
|
||||
try:
|
||||
iface.open()
|
||||
except serial.SerialException:
|
||||
logger.warning("Could not open serial port %s", d.device)
|
||||
continue
|
||||
iface.comment = get_comment(iface)
|
||||
iface.close()
|
||||
interfaces.append(iface)
|
||||
|
@ -101,10 +97,11 @@ def get_interfaces() -> List[Interface]:
|
|||
return interfaces
|
||||
|
||||
|
||||
def get_VNA(iface: Interface) -> 'VNA':
|
||||
def get_VNA(iface: Interface) -> VNA:
|
||||
# serial_port.timeout = TIMEOUT
|
||||
return NAME2DEVICE[iface.comment](iface)
|
||||
|
||||
|
||||
def get_comment(iface: Interface) -> str:
|
||||
logger.info("Finding correct VNA type...")
|
||||
with iface.lock:
|
||||
|
@ -129,6 +126,7 @@ def get_comment(iface: Interface) -> str:
|
|||
logger.warning("Did not recognize NanoVNA type from firmware.")
|
||||
return "Unknown"
|
||||
|
||||
|
||||
def detect_version(serial_port: serial.Serial) -> str:
|
||||
data = ""
|
||||
for i in range(RETRIES):
|
||||
|
|
|
@ -61,7 +61,6 @@ class NanoVNA(VNA):
|
|||
timeout = self.serial.timeout
|
||||
with self.serial.lock:
|
||||
drain_serial(self.serial)
|
||||
timeout = self.serial.timeout
|
||||
self.serial.write("capture\r".encode('ascii'))
|
||||
self.serial.readline()
|
||||
self.serial.timeout = 4
|
||||
|
|
|
@ -66,6 +66,7 @@ _ADF4350_TXPOWER_DESC_MAP = {
|
|||
_ADF4350_TXPOWER_DESC_REV_MAP = {
|
||||
value: key for key, value in _ADF4350_TXPOWER_DESC_MAP.items()}
|
||||
|
||||
|
||||
class NanoVNA_V2(VNA):
|
||||
name = "NanoVNA-V2"
|
||||
valid_datapoints = (101, 11, 51, 201, 301, 501, 1023)
|
||||
|
@ -237,7 +238,6 @@ class NanoVNA_V2(VNA):
|
|||
logger.debug("read_board_revision: %s", result)
|
||||
return result
|
||||
|
||||
|
||||
def setSweep(self, start, stop):
|
||||
step = (stop - start) / (self.datapoints - 1)
|
||||
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)
|
||||
|
||||
def _set_register(self, addr, value, size):
|
||||
packet = b''
|
||||
if size == 1:
|
||||
packet = pack("<BBB", _CMD_WRITE, addr, value)
|
||||
elif size == 2:
|
||||
|
|
|
@ -60,7 +60,6 @@ class TinySA(VNA):
|
|||
timeout = self.serial.timeout
|
||||
with self.serial.lock:
|
||||
drain_serial(self.serial)
|
||||
timeout = self.serial.timeout
|
||||
self.serial.write("capture\r".encode('ascii'))
|
||||
self.serial.readline()
|
||||
self.serial.timeout = 4
|
||||
|
|
|
@ -155,11 +155,11 @@ class VNA:
|
|||
pass
|
||||
|
||||
def _get_running_frequencies(self):
|
||||
'''
|
||||
"""
|
||||
If possible, read frequencies already runnung
|
||||
if not return default values
|
||||
Overwrite in specific HW
|
||||
'''
|
||||
"""
|
||||
return 27000000, 30000000
|
||||
|
||||
def connected(self) -> bool:
|
||||
|
|
|
@ -28,7 +28,6 @@ class FrequencyInputWidget(QtWidgets.QLineEdit):
|
|||
self.previousFrequency = -1
|
||||
|
||||
def setText(self, text: str) -> None:
|
||||
# TODO: Fix wrong type here
|
||||
super().setText(format_frequency_inputs(text))
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ from NanoVNASaver.Formatting import (
|
|||
|
||||
from .Widget import Marker
|
||||
|
||||
|
||||
class DeltaMarker(Marker):
|
||||
def __init__(self, name: str = "", qsettings: QtCore.QSettings = None):
|
||||
super().__init__(name, qsettings)
|
||||
|
|
|
@ -45,16 +45,12 @@ class Datapoint(NamedTuple):
|
|||
@property
|
||||
def gain(self) -> float:
|
||||
mag = abs(self.z)
|
||||
if mag > 0:
|
||||
return 20 * math.log10(mag)
|
||||
return -math.inf
|
||||
return 20 * math.log10(mag) if mag > 0 else -math.inf
|
||||
|
||||
@property
|
||||
def vswr(self) -> float:
|
||||
mag = abs(self.z)
|
||||
if mag >= 1:
|
||||
return math.inf
|
||||
return (1 + mag) / (1 - mag)
|
||||
return (1 + mag) / (1 - mag) if mag < 1 else math.inf
|
||||
|
||||
@property
|
||||
def wavelength(self) -> float:
|
||||
|
@ -77,9 +73,7 @@ class Datapoint(NamedTuple):
|
|||
|
||||
def qFactor(self, ref_impedance: float = 50) -> float:
|
||||
imp = self.impedance(ref_impedance)
|
||||
if imp.real == 0.0:
|
||||
return -1
|
||||
return abs(imp.imag / imp.real)
|
||||
return -1 if imp.real == 0.0 else abs(imp.imag / imp.real)
|
||||
|
||||
def capacitiveEquivalent(self, ref_impedance: float = 50) -> float:
|
||||
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)
|
||||
delta_angle = data[idx1].phase - data[idx0].phase
|
||||
delta_freq = data[idx1].freq - data[idx0].freq
|
||||
if delta_freq == 0:
|
||||
return 0
|
||||
return -delta_angle / math.tau / delta_freq
|
||||
return 0 if delta_freq == 0 else -delta_angle / math.tau / delta_freq
|
||||
|
||||
|
||||
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:
|
||||
"""Calculate inductive equivalent for reactance"""
|
||||
if freq == 0:
|
||||
return 0
|
||||
return z.imag * 1 / (freq * 2 * math.pi)
|
||||
return 0 if freq == 0 else z.imag * 1 / (freq * 2 * math.pi)
|
||||
|
||||
|
||||
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:
|
||||
"""Convert parallel impedance to serial impedance equivalent"""
|
||||
z_sq_sum = z.real ** 2 + z.imag ** 2
|
||||
# TODO: Fix divide by zero
|
||||
z_sq_sum = z.real ** 2 + z.imag ** 2 or 10.0e-30
|
||||
return complex(z.real * z.imag ** 2 / 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
|
||||
if z.real == 0 and z.imag == 0:
|
||||
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:
|
||||
return complex(z_sq_sum / z.real, math.copysign(math.inf, z_sq_sum))
|
||||
if z.real == 0:
|
||||
|
|
|
@ -34,14 +34,17 @@ def clamp_value(value: Real, rmin: Real, rmax: Real) -> Real:
|
|||
return rmax
|
||||
return value
|
||||
|
||||
|
||||
def round_ceil(value: Real, digits: int = 0) -> Real:
|
||||
factor = 10 ** digits
|
||||
factor = 10 ** -digits
|
||||
return factor * math.ceil(value / factor)
|
||||
|
||||
|
||||
def round_floor(value: Real, digits: int = 0) -> Real:
|
||||
factor = 10 ** digits
|
||||
factor = 10 ** -digits
|
||||
return factor * math.floor(value / factor)
|
||||
|
||||
|
||||
class Format(NamedTuple):
|
||||
max_nr_digits: int = 6
|
||||
fix_decimals: bool = False
|
||||
|
|
|
@ -31,7 +31,7 @@ class SweepMode(Enum):
|
|||
AVERAGE = 2
|
||||
|
||||
|
||||
class Properties():
|
||||
class Properties:
|
||||
def __init__(self, name: str = "",
|
||||
mode: 'SweepMode' = SweepMode.SINGLE,
|
||||
averages: Tuple[int, int] = (3, 0),
|
||||
|
@ -47,7 +47,7 @@ class Properties():
|
|||
f" {self.logarithmic})")
|
||||
|
||||
|
||||
class Sweep():
|
||||
class Sweep:
|
||||
def __init__(self, start: int = 3600000, end: int = 30000000,
|
||||
points: int = 101, segments: int = 1,
|
||||
properties: 'Properties' = Properties()):
|
||||
|
@ -105,7 +105,7 @@ class Sweep():
|
|||
start = round(self.start + self.span * self._exp_factor(index))
|
||||
end = round(self.start + self.span * self._exp_factor(index + 1))
|
||||
logger.debug("get_index_range(%s) -> (%s, %s)", index, start, end)
|
||||
return (start, end)
|
||||
return start, end
|
||||
|
||||
def get_frequencies(self) -> Iterator[int]:
|
||||
for i in range(self.segments):
|
||||
|
|
|
@ -226,6 +226,7 @@ class SweepWorker(QtCore.QRunnable):
|
|||
logger.debug("Reading average no %d / %d", i + 1, averages)
|
||||
retry = 0
|
||||
tmp11 = []
|
||||
tmp21 = []
|
||||
while not tmp11 and retry < 5:
|
||||
sleep(0.5 * retry)
|
||||
retry += 1
|
||||
|
|
|
@ -244,7 +244,6 @@ class Touchstone:
|
|||
if data_len % 2 != 0:
|
||||
raise TypeError("Data values aren't pairs: " + line)
|
||||
|
||||
|
||||
# consistency checks
|
||||
if freq <= prev_freq:
|
||||
logger.warning("Frequency not ascending: %s", line)
|
||||
|
|
|
@ -24,6 +24,7 @@ from NanoVNASaver.RFTools import Datapoint
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FilesWindow(QtWidgets.QWidget):
|
||||
def __init__(self, app: QtWidgets.QWidget):
|
||||
super().__init__()
|
||||
|
|
|
@ -101,5 +101,6 @@ def main():
|
|||
logger.exception("%s", exc)
|
||||
raise exc
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
from contextlib import suppress
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
with suppress(ImportError):
|
||||
# pylint: disable=no-name-in-module,import-error,unused-import
|
||||
# pyright: reportMissingImports=false
|
||||
|
|
|
@ -24,6 +24,7 @@ import unittest
|
|||
# Import targets to be tested
|
||||
from NanoVNASaver.Formatting import format_frequency_sweep
|
||||
|
||||
|
||||
class TestCases(unittest.TestCase):
|
||||
|
||||
def test_basicIntegerValues(self):
|
||||
|
@ -69,4 +70,3 @@ class TestCases(unittest.TestCase):
|
|||
# # 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=10), '1.0000000000kHz')
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import unittest
|
|||
# Import targets to be tested
|
||||
from NanoVNASaver.Formatting import parse_frequency
|
||||
|
||||
|
||||
# TODO: should be tested against SITools.Value
|
||||
# RFTools.parseFrequency will hopefully go away in future
|
||||
# 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('1.23.Hz'), -1)
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ class TestRFTools(unittest.TestCase):
|
|||
self.assertEqual(clamp_value(1, -10, -1), -1)
|
||||
|
||||
def test_parallel_to_serial(self):
|
||||
self.assertRaises(ZeroDivisionError, parallel_to_serial, 0)
|
||||
self.assertEqual(parallel_to_serial(0), complex(0, 0))
|
||||
self.assertAlmostEqual(
|
||||
parallel_to_serial(complex(52, 260)),
|
||||
complex(50, 10))
|
||||
|
|
|
@ -57,7 +57,7 @@ class TestCases(unittest.TestCase):
|
|||
illegal_config = TConfig(
|
||||
my_int=4, my_float=3.0, my_str="Goodbye World",
|
||||
my_bool="False", my_list=(4, 5, 6))
|
||||
with self.assertRaises(AssertionError):
|
||||
with self.assertRaises(TypeError):
|
||||
self.settings_1.store_dataclass("SectionX", illegal_config)
|
||||
|
||||
def test_restore_dataclass(self):
|
||||
|
|
|
@ -21,7 +21,7 @@ from math import inf
|
|||
from decimal import Decimal # Needed for test_representation()
|
||||
|
||||
# Import targets to be tested
|
||||
from NanoVNASaver.SITools import Format, Value
|
||||
from NanoVNASaver.SITools import Format, Value, round_floor, round_ceil
|
||||
|
||||
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)
|
||||
|
||||
|
||||
def test_format_attributes(self):
|
||||
v = Value("10.0", "Hz", fmt=F_DIGITS_4)
|
||||
self.assertEqual(v.value, 10.0)
|
||||
|
@ -156,7 +155,13 @@ class TestTSIToolsValue(unittest.TestCase):
|
|||
v.parse("12 GHz")
|
||||
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
|
||||
# F_WITH_SPACE
|
||||
|
|
|
@ -21,6 +21,7 @@ import unittest
|
|||
# Import targets to be tested
|
||||
from NanoVNASaver.Settings.Sweep import Sweep, Properties
|
||||
|
||||
|
||||
class TestCases(unittest.TestCase):
|
||||
|
||||
def test_sweep(self):
|
||||
|
|
|
@ -24,6 +24,7 @@ import os
|
|||
from NanoVNASaver.Touchstone import Options, Touchstone
|
||||
from NanoVNASaver.RFTools import Datapoint
|
||||
|
||||
|
||||
class TestTouchstoneOptions(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.opts = Options()
|
||||
|
@ -165,7 +166,6 @@ class TestTouchstoneTouchstone(unittest.TestCase):
|
|||
ts.gen_interpolation()
|
||||
self.assertEqual(ts.s_freq("11", 2), Datapoint(2, 0.5, 0.5))
|
||||
|
||||
|
||||
def test_save(self):
|
||||
ts = Touchstone("./test/data/valid.s2p")
|
||||
self.assertEqual(ts.saves(), "# HZ S RI R 50\n")
|
||||
|
|
|
@ -21,6 +21,7 @@ import unittest
|
|||
# Import targets to be tested
|
||||
from NanoVNASaver.Version import Version
|
||||
|
||||
|
||||
class TestCases(unittest.TestCase):
|
||||
|
||||
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.3-u"))
|
||||
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.assertEqual(ver.major, 1)
|
||||
self.assertEqual(ver.minor, 2)
|
||||
self.assertEqual(ver.revision, 3)
|
||||
self.assertEqual(ver.note, '-test')
|
||||
Version("asdasd")
|
||||
Version("1.2.invalid")
|
||||
|
|
Ładowanie…
Reference in New Issue