Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: needed fixes due to newly integrated PRs #809

Merged
merged 1 commit into from
Feb 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
try:
import sphinx

cmd_line = f"sphinx-apidoc --implicit-namespaces -f -o {output_dir} {module_dir}"
cmd_line = (
f"sphinx-apidoc --implicit-namespaces -f -o {output_dir} {module_dir}"
)

args = cmd_line.split(" ")
if tuple(sphinx.__version__.split(".")) >= ("1", "7"):
Expand Down Expand Up @@ -105,7 +107,9 @@
version = ""

if not version or version.lower() == "unknown":
version = os.getenv("READTHEDOCS_VERSION", "unknown") # automatically set by RTD
version = os.getenv(
"READTHEDOCS_VERSION", "unknown"
) # automatically set by RTD

release = version

Expand Down Expand Up @@ -159,10 +163,7 @@
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
html_theme_options = {
"sidebar_width": "300px",
"page_width": "1200px"
}
html_theme_options = {"sidebar_width": "300px", "page_width": "1200px"}

# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = []
Expand Down Expand Up @@ -247,7 +248,13 @@
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
("index", "user_guide.tex", "nanovna-saver Documentation", "Holger Mueller", "manual")
(
"index",
"user_guide.tex",
"nanovna-saver Documentation",
"Holger Mueller",
"manual",
)
]

# The name of an image file (relative to this directory) to place at the top of
Expand Down
101 changes: 72 additions & 29 deletions src/NanoVNASaver/Charts/TDR.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
import math

import numpy as np
from PySide6.QtCore import QPoint, Qt, QRect
from PySide6.QtCore import QPoint, QRect, Qt
from PySide6.QtGui import (
QAction,
QActionGroup,
QColor,
QFontMetrics,
QMouseEvent,
QPainter,
QPaintEvent,
Expand All @@ -32,8 +34,6 @@
QResizeEvent,
QShortcut,
QWheelEvent,
QColor,
QFontMetrics,
)
from PySide6.QtWidgets import QDialog, QInputDialog, QMenu, QSizePolicy

Expand Down Expand Up @@ -394,19 +394,29 @@ def mouseMoveEvent(self, a0: QMouseEvent) -> None:
self.update()

def _draw_ticks(
self, height, width, x_step, min_index, qp: QPainter
self, height, _width, x_step, min_index, qp: QPainter
) -> None:
desired_steps = math.ceil((self.width() - self.leftMargin - self.rightMargin) / 100)
desired_steps = math.ceil(
(self.width() - self.leftMargin - self.rightMargin) / 100
)
min_length, max_length, m_per_pixel = self._get_chart_parameters()
delta_length = max_length - min_length

step_length = delta_length / desired_steps
decimals = math.ceil(abs(math.log10(step_length)))
step_length_rounded = math.ceil(step_length * (10 ** decimals)) / (10 ** decimals)
step_length_rounded = math.ceil(step_length * (10**decimals)) / (
10**decimals
)

start_length = min_length - (min_length % step_length_rounded) + step_length_rounded
start_length = (
min_length
- (min_length % step_length_rounded)
+ step_length_rounded
)

for distance in np.arange(start_length, max_length, step_length_rounded):
for distance in np.arange(
start_length, max_length, step_length_rounded
):
x = self.leftMargin + round((distance - min_length) / m_per_pixel)

# lines
Expand All @@ -415,14 +425,22 @@ def _draw_ticks(

# text
qp.setPen(QPen(Chart.color.text))
self._draw_centered_hanging_text(qp, f"{{:.{decimals}f}} m".format(distance),
QPoint(x, self.topMargin + height), False)
self._draw_centered_hanging_text(
qp,
f"{{:.{decimals}f}} m".format(distance),
QPoint(x, self.topMargin + height),
False,
)

# text at origin
qp.setPen(QPen(Chart.color.text))
distance = self.tdrWindow.distance_axis[min_index] / 2
self._draw_centered_hanging_text(qp, f"{{:.{decimals}f}} m".format(distance),
QPoint(self.leftMargin, self.topMargin + height), False)
self._draw_centered_hanging_text(
qp,
f"{{:.{decimals}f}} m".format(distance),
QPoint(self.leftMargin, self.topMargin + height),
False,
)

def _draw_y_ticks(
self, height, width, min_impedance, max_impedance, qp: QPainter
Expand Down Expand Up @@ -461,17 +479,20 @@ def _draw_max_point(
self._draw_centered_hanging_text(
qp,
f"{round(self.tdrWindow.distance_axis[id_max] / 2, 2)}m",
max_point,
True)
max_point,
True,
)

def _draw_marker(self, height, x_step, y_step, min_index, qp: QPainter):
marker_point = QPoint(
self.positionAtLength(self.marker_location, limit=False),
(self.topMargin + height)
(self.topMargin + height),
)
qp.setPen(Chart.color.text)
qp.drawEllipse(marker_point, 2, 2)
self._draw_centered_hanging_text(qp, f"{self.marker_location:.3f} m", marker_point, True)
self._draw_centered_hanging_text(
qp, f"{self.marker_location:.3f} m", marker_point, True
)

def _draw_graph(self, height, width, qp: QPainter) -> None:
min_index = 0
Expand Down Expand Up @@ -513,13 +534,21 @@ def _draw_graph(self, height, width, qp: QPainter) -> None:
tdr_points = [
QPoint(
self.leftMargin + int((i - min_index) / x_step),
(self.topMargin + height) - int(np.real(self.tdrWindow.td[i]) / y_step)
) for i in range(min_index, max_index)]
(self.topMargin + height)
- int(np.real(self.tdrWindow.td[i]) / y_step),
)
for i in range(min_index, max_index)
]
step_response_points = [
QPoint(
self.leftMargin + int((i - min_index) / x_step),
(self.topMargin + height) - int((self.tdrWindow.step_response_Z[i] - min_impedance) / y_step)
) for i in range(min_index, max_index)]
(self.topMargin + height)
- int(
(self.tdrWindow.step_response_Z[i] - min_impedance) / y_step
),
)
for i in range(min_index, max_index)
]

pen.setColor(Chart.color.sweep)
qp.setPen(pen)
Expand All @@ -542,7 +571,11 @@ def _draw_graph(self, height, width, qp: QPainter) -> None:
[qp.drawPoint(p) for p in tdr_points if self.isPlotable(p)]
pen.setColor(Chart.color.sweep_secondary)
qp.setPen(pen)
[qp.drawPoint(p) for p in step_response_points if self.isPlotable(p)]
[
qp.drawPoint(p)
for p in step_response_points
if self.isPlotable(p)
]

self._draw_max_point(height, x_step, y_step, min_index, qp)

Expand Down Expand Up @@ -622,18 +655,20 @@ def _get_chart_parameters(self):
)
)
x_step = float(max_length - min_length) / width_px
# logger.debug(f"min_length: {min_length}, max_length: {max_length}, x_step: {x_step}")
return min_length, max_length, x_step

def lengthAtPosition(self, x: int, limit=True):
if not hasattr(self.tdrWindow, "td"):
return 0
width_px = self.width() - self.leftMargin - self.rightMargin
min_length, max_length, x_step = self._get_chart_parameters()
absx = x - self.leftMargin
if limit and absx < 0:
return float(min_length)
return float(
max_length if limit and absx > width else absx * x_step + min_length
max_length
if limit and absx > width_px
else absx * x_step + min_length
)

def positionAtLength(self, length, limit=True):
Expand Down Expand Up @@ -667,8 +702,12 @@ def zoomTo(self, x1, y1, x2, y2) -> None:
x_max = x_max + (at_zero - x_min)
x_min = at_zero

if self.lengthAtPosition(x_max, limit=False) > (self.tdrWindow.distance_axis[-1] / 2):
at_end = self.positionAtLength(self.tdrWindow.distance_axis[-1] / 2, limit=False)
if self.lengthAtPosition(x_max, limit=False) > (
self.tdrWindow.distance_axis[-1] / 2
):
at_end = self.positionAtLength(
self.tdrWindow.distance_axis[-1] / 2, limit=False
)
x_min = x_min + (at_end - x_max)
x_max = at_end

Expand All @@ -687,19 +726,23 @@ def resizeEvent(self, a0: QResizeEvent) -> None:
self.dim.width = self.width() - self.leftMargin - self.rightMargin
self.dim.height = self.height() - self.bottomMargin - self.topMargin

def _draw_centered_hanging_text(self, qp, text, center: QPoint, above: bool):
def _draw_centered_hanging_text(
self, qp, text, center: QPoint, above: bool
):
# Measure text size
fm = QFontMetrics(qp.font())
text_width = fm.horizontalAdvance(text)
text_height = fm.height()

# Compute top-left position for centered text
x = center.x() - text_width // 2
y = center.y() + (- text_height / 4 if above else text_height)
y = round(center.y() + (-text_height / 4 if above else text_height))

# enhance readability when drawn over ticks
margin = 5
rect = QRect(x - margin, y - text_height, text_width + 2 * margin, text_height)
rect = QRect(
x - margin, y - text_height, text_width + 2 * margin, text_height
)
semi_transparent_bg = QColor(Chart.color.background)
semi_transparent_bg.setAlpha(150)
qp.fillRect(rect, semi_transparent_bg)
Expand All @@ -713,4 +756,4 @@ def get_fft_points(self):
separate points a lower (but still very high resolution) makes
the GUI more responsive.
"""
return 2 ** 12 if self.flag.draw_lines else 2 ** 14
return 2**12 if self.flag.draw_lines else 2**14
1 change: 1 addition & 0 deletions src/NanoVNASaver/Hardware/Hardware.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ 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:
Expand Down
19 changes: 10 additions & 9 deletions src/NanoVNASaver/Hardware/NanoVNA_F_V2.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import serial
from PySide6.QtGui import QPixmap

from ..utils import Version
from .Convert import get_rgb16_pixmap
from .NanoVNA import NanoVNA
from .Serial import Interface
Expand All @@ -32,19 +33,19 @@ class NanoVNA_F_V2(NanoVNA):
name = "NanoVNA-F_V2"
screenwidth = 800
screenheight = 480
valid_datapoints = (101, 11, 51, 201, 301)
valid_datapoints: tuple[int, ...] = (101, 11, 51, 201, 301)
sweep_points_min = 11
sweep_points_max = 301

def __init__(self, iface: Interface):
super().__init__(iface)
self.sweep_max_freq_hz = 3e9
self.version = self.read_firmware_version()
# max datapoints reach up to 301 since version 0.5.0
if self.version >= Version("0.5.0"):
if self.version >= Version.parse("0.5.0"):
pass
# max datapoints reach up to 201 since version 0.2.0
elif self.version >= Version("0.2.0"):
elif self.version >= Version.parse("0.2.0"):
self.valid_datapoints = (101, 11, 51, 201)
self.sweep_points_max = 201
# max datapoints reach up to 101 before version 0.2.0
Expand All @@ -66,15 +67,15 @@ def getScreenshot(self) -> QPixmap:
return QPixmap()

def read_firmware_version(self) -> "Version":
"""For example, command version in NanoVNA_F_V2 and NanoVNA_F_V3 returns as this
0.5.8
"""For example, command version in NanoVNA_F_V2 and NanoVNA_F_V3
returns as this 0.5.8
"""
result = list(self.exec_command("version"))
logger.debug("firmware version result:\n%s", result[0])
return Version(result[0])
return Version.parse(result[0])

def read_features(self):
super().read_features()
def get_features(self):
super().get_features()
result = " ".join(self.exec_command("help")).split()
if "sn:" or "SN:" in result:
self.features.add("SN")
Expand Down
8 changes: 0 additions & 8 deletions src/NanoVNASaver/Hardware/NanoVNA_H4.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,3 @@ def __init__(self, iface: Interface):
self.sweep_method = "scan"
if "Scan mask command" in self.features:
self.sweep_method = "scan_mask"

# def init_features(self) -> None:
# logger.debug("read_features")
# super().read_features()
# if self.readFirmware().find("DiSlord") > 0:
# self.features.add("Customizable data points")
# logger.info("VNA has 201 datapoints capability")
# self.valid_datapoints: tuple[int, ...] = [201, 11, 51, 101]
1 change: 0 additions & 1 deletion src/NanoVNASaver/Hardware/TinySA.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ class TinySA_Ultra(TinySA):
screenwidth = 480
screenheight = 320
valid_datapoints: tuple[int, ...] = (450, 51, 101, 145, 290)
hardware_revision: Version | None = None

def __init__(self, iface: Interface):
super().__init__(iface)
Expand Down
2 changes: 1 addition & 1 deletion src/NanoVNASaver/Hardware/VNA.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class VNA:
valid_datapoints: tuple[int, ...] = (101, 51, 11)
wait = 0.05
SN = "NOT SUPPORTED"
hardware_revision = "NOT SUPPORTED"
hardware_revision: str | Version = "NOT SUPPORTED"
sweep_points_max = 101
sweep_points_min = 11

Expand Down
Loading
Loading