pull/544/head
Holger Müller 2022-09-15 07:53:08 +02:00
rodzic d86cbec7c4
commit 8bc452d48f
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 2FDB49E81EAE6622
12 zmienionych plików z 188 dodań i 204 usunięć

Wyświetl plik

@ -19,7 +19,7 @@
import logging import logging
from dataclasses import dataclass, replace from dataclasses import dataclass, replace
from typing import List, Set, Tuple, ClassVar, Any from typing import List, Set, Tuple, ClassVar, Any, Optional
from PyQt5 import QtWidgets, QtGui, QtCore from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtCore import pyqtSignal from PyQt5.QtCore import pyqtSignal
@ -37,12 +37,13 @@ class ChartColors: # pylint: disable=too-many-instance-attributes
foreground: QtGui.QColor = QtGui.QColor(QtCore.Qt.lightGray) foreground: QtGui.QColor = QtGui.QColor(QtCore.Qt.lightGray)
reference: QtGui.QColor = QtGui.QColor(0, 0, 255, 64) reference: QtGui.QColor = QtGui.QColor(0, 0, 255, 64)
reference_secondary: QtGui.QColor = QtGui.QColor(0, 0, 192, 48) reference_secondary: QtGui.QColor = QtGui.QColor(0, 0, 192, 48)
sweep: QtGui.QColor = QtGui.QColor(QtCore.Qt.darkYellow) sweep: QtGui.QColor = QtGui.QColor(QtCore.Qt.darkYellow)
sweep_secondary: QtGui.QColor = QtGui.QColor(QtCore.Qt.darkMagenta) sweep_secondary: QtGui.QColor = QtGui.QColor(QtCore.Qt.darkMagenta)
swr: QtGui.QColor = QtGui.QColor(255, 0, 0, 128) swr: QtGui.QColor = QtGui.QColor(255, 0, 0, 128)
text: QtGui.QColor = QtGui.QColor(QtCore.Qt.black) text: QtGui.QColor = QtGui.QColor(QtCore.Qt.black)
bands: QtGui.QColor = QtGui.QColor(128, 128, 128, 48) bands: QtGui.QColor = QtGui.QColor(128, 128, 128, 48)
@dataclass @dataclass
class ChartDimensions: class ChartDimensions:
height: int = 200 height: int = 200
@ -52,14 +53,16 @@ class ChartDimensions:
line: int = 1 line: int = 1
point: int = 2 point: int = 2
@dataclass @dataclass
class ChartDragBox: class ChartDragBox:
pos: Tuple[int] = (-1, -1) pos: Tuple[int] = (-1, -1)
pos_start: Tuple[int] = (0, 0) pos_start: Tuple[int] = (0, 0)
state: bool = False state: bool = False
move_x: int = -1 move_x: int = -1
move_y: int = -1 move_y: int = -1
@dataclass @dataclass
class ChartFlags: class ChartFlags:
draw_lines: bool = False draw_lines: bool = False
@ -121,7 +124,8 @@ class Chart(QtWidgets.QWidget):
self.swrMarkers: Set[float] = set() self.swrMarkers: Set[float] = set()
self.action_popout = QtWidgets.QAction("Popout chart") self.action_popout = QtWidgets.QAction("Popout chart")
self.action_popout.triggered.connect(lambda: self.popoutRequested.emit(self)) self.action_popout.triggered.connect(
lambda: self.popoutRequested.emit(self))
self.addAction(self.action_popout) self.addAction(self.action_popout)
self.action_save_screenshot = QtWidgets.QAction("Save image") self.action_save_screenshot = QtWidgets.QAction("Save image")
@ -176,8 +180,8 @@ class Chart(QtWidgets.QWidget):
None, None,
) )
def getNearestMarker(self, x, y) -> Marker: def getNearestMarker(self, x, y) -> Optional[Marker]:
if len(self.data) == 0: if not self.data:
return None return None
shortest = 10**6 shortest = 10**6
nearest = None nearest = None
@ -218,13 +222,13 @@ class Chart(QtWidgets.QWidget):
def mouseReleaseEvent(self, a0: QtGui.QMouseEvent): def mouseReleaseEvent(self, a0: QtGui.QMouseEvent):
self.draggedMarker = None self.draggedMarker = None
if self.dragbox.state: if self.dragbox.state:
self.zoomTo(self.dragbox.pos_start[0], self.dragbox.pos_start[1], a0.x(), a0.y()) self.zoomTo(
self.dragbox.pos_start[0], self.dragbox.pos_start[1], a0.x(), a0.y())
self.dragbox.state = False self.dragbox.state = False
self.dragbox.pos = (-1, -1) self.dragbox.pos = (-1, -1)
self.dragbox.pos_start = (0, 0) self.dragbox.pos_start = (0, 0)
self.update() self.update()
def wheelEvent(self, a0: QtGui.QWheelEvent) -> None: def wheelEvent(self, a0: QtGui.QWheelEvent) -> None:
delta = a0.angleDelta().y() delta = a0.angleDelta().y()
if not delta or (not self.data and not self.reference): if not delta or (not self.data and not self.reference):
@ -305,7 +309,7 @@ class Chart(QtWidgets.QWidget):
@staticmethod @staticmethod
def drawMarker(x: int, y: int, def drawMarker(x: int, y: int,
qp: QtGui.QPainter, color: QtGui.QColor, qp: QtGui.QPainter, color: QtGui.QColor,
number: int=0): number: int = 0):
cmarker = ChartMarker(qp) cmarker = ChartMarker(qp)
cmarker.draw(x, y, color, f"{number}") cmarker.draw(x, y, color, f"{number}")
@ -314,7 +318,7 @@ class Chart(QtWidgets.QWidget):
if position is None: if position is None:
qf = QtGui.QFontMetricsF(self.font()) qf = QtGui.QFontMetricsF(self.font())
width = qf.boundingRect(self.sweepTitle).width() width = qf.boundingRect(self.sweepTitle).width()
position = QtCore.QPointF(self.width()/2 - width/2, 15) position = QtCore.QPointF(self.width() / 2 - width / 2, 15)
qp.drawText(position, self.sweepTitle) qp.drawText(position, self.sweepTitle)
def update(self): def update(self):

Wyświetl plik

@ -236,8 +236,7 @@ class FrequencyChart(Chart):
self.logarithmicY = logarithmic and self.logarithmicYAllowed() self.logarithmicY = logarithmic and self.logarithmicYAllowed()
self.update() self.update()
@staticmethod def logarithmicYAllowed(self) -> bool:
def logarithmicYAllowed() -> bool:
return False return False
def setMinimumFrequency(self): def setMinimumFrequency(self):

Wyświetl plik

@ -88,8 +88,8 @@ class GroupDelayChart(FrequencyChart):
phase_change = unwrapped[-1] - unwrapped[-2] phase_change = unwrapped[-1] - unwrapped[-2]
freq_change = d.freq - data[-2].freq freq_change = d.freq - data[-2].freq
else: else:
phase_change = unwrapped[i+1] - unwrapped[i-1] phase_change = unwrapped[i + 1] - unwrapped[i - 1]
freq_change = data[i+1].freq - data[i-1].freq freq_change = data[i + 1].freq - data[i - 1].freq
delay = (-phase_change / (freq_change * 360)) * 10e8 delay = (-phase_change / (freq_change * 360)) * 10e8
if not self.reflective: if not self.reflective:
delay /= 2 delay /= 2
@ -124,7 +124,8 @@ class GroupDelayChart(FrequencyChart):
tickcount = math.floor(self.dim.height / 60) tickcount = math.floor(self.dim.height / 60)
for i in range(tickcount): for i in range(tickcount):
delay = min_delay + span * i / tickcount delay = min_delay + span * i / tickcount
y = self.topMargin + round((self.maxDelay - delay) / self.span * self.dim.height) y = self.topMargin + \
round((self.maxDelay - delay) / self.span * self.dim.height)
if delay not in {min_delay, max_delay}: if delay not in {min_delay, max_delay}:
qp.setPen(QtGui.QPen(Chart.color.text)) qp.setPen(QtGui.QPen(Chart.color.text))
# TODO use format class # TODO use format class
@ -133,7 +134,8 @@ class GroupDelayChart(FrequencyChart):
delaystr = str(round(delay, digits if digits != 0 else None)) delaystr = str(round(delay, digits if digits != 0 else None))
qp.drawText(3, y + 3, delaystr) qp.drawText(3, y + 3, delaystr)
qp.setPen(QtGui.QPen(Chart.color.foreground)) qp.setPen(QtGui.QPen(Chart.color.foreground))
qp.drawLine(self.leftMargin - 5, y, self.leftMargin + self.dim.width, y) qp.drawLine(self.leftMargin - 5, y,
self.leftMargin + self.dim.width, y)
qp.drawLine(self.leftMargin - 5, qp.drawLine(self.leftMargin - 5,
self.topMargin, self.topMargin,

Wyświetl plik

@ -160,8 +160,8 @@ class LogMagChart(FrequencyChart):
def getYPosition(self, d: Datapoint) -> int: def getYPosition(self, d: Datapoint) -> int:
logMag = self.logMag(d) logMag = self.logMag(d)
if math.isinf(logMag): if math.isinf(logMag):
return None return self.topMargin
return self.topMargin + round( return self.topMargin + int(
(self.maxValue - logMag) / self.span * self.dim.height) (self.maxValue - logMag) / self.span * self.dim.height)
def valueAtPosition(self, y) -> List[float]: def valueAtPosition(self, y) -> List[float]:

Wyświetl plik

@ -33,18 +33,15 @@ class MagnitudeChart(FrequencyChart):
super().__init__(name) super().__init__(name)
self.minDisplayValue = 0 self.minDisplayValue = 0
self.maxDisplayValue = 1
self.fixedValues = True self.fixedValues = True
self.y_action_fixed_span.setChecked(True) self.y_action_fixed_span.setChecked(True)
self.y_action_automatic.setChecked(False) self.y_action_automatic.setChecked(False)
self.minValue = 0 self.minValue = 0
self.maxValue = 1
self.span = 1
def drawValues(self, qp: QtGui.QPainter): def drawValues(self, qp: QtGui.QPainter):
if len(self.data) == 0 and len(self.reference) == 0: if not self.data and not self.reference:
return return
self._set_start_stop() self._set_start_stop()
@ -54,71 +51,62 @@ class MagnitudeChart(FrequencyChart):
self.drawBands(qp, self.fstart, self.fstop) self.drawBands(qp, self.fstart, self.fstop)
if self.fixedValues: if self.fixedValues:
maxValue = self.maxDisplayValue max_value = self.maxDisplayValue
minValue = self.minDisplayValue min_value = self.minDisplayValue
self.maxValue = maxValue
self.minValue = minValue
else: else:
# Find scaling # Find scaling
minValue = 100 min_value = 100
maxValue = 0 max_value = 0
for d in self.data: for d in self.data:
mag = self.magnitude(d) mag = self.magnitude(d)
if mag > maxValue: max_value = max(max_value, mag)
maxValue = mag min_value = min(min_value, mag)
if mag < minValue:
minValue = mag
for d in self.reference: # Also check min/max for the reference sweep for d in self.reference: # Also check min/max for the reference sweep
if d.freq < self.fstart or d.freq > self.fstop: if d.freq < self.fstart or d.freq > self.fstop:
continue continue
mag = self.magnitude(d) max_value = max(max_value, mag)
if mag > maxValue: min_value = min(min_value, mag)
maxValue = mag min_value = 10 * math.floor(min_value / 10)
if mag < minValue: max_value = 10 * math.ceil(max_value / 10)
minValue = mag
minValue = 10*math.floor(minValue/10) self.maxValue = max_value
self.minValue = minValue self.minValue = min_value
maxValue = 10*math.ceil(maxValue/10)
self.maxValue = maxValue
span = maxValue-minValue self.span = (max_value - min_value) or 0.01
if span == 0:
span = 0.01
self.span = span
target_ticks = math.floor(self.dim.height / 60)
target_ticks = int(self.dim.height // 60)
for i in range(target_ticks): for i in range(target_ticks):
val = minValue + i / target_ticks * span val = min_value + i / target_ticks * self.span
y = self.topMargin + round((self.maxValue - val) / self.span * self.dim.height) y = self.topMargin + int((self.maxValue - val) / self.span
* self.dim.height)
qp.setPen(Chart.color.text) qp.setPen(Chart.color.text)
if val != minValue: if val != min_value:
digits = max(0, min(2, math.floor(3 - math.log10(abs(val))))) digits = max(0, min(2, math.floor(3 - math.log10(abs(val)))))
if digits == 0: vswrstr = (str(round(val)) if digits == 0 else
vswrstr = str(round(val)) str(round(val, digits)))
else:
vswrstr = str(round(val, digits))
qp.drawText(3, y + 3, vswrstr) qp.drawText(3, y + 3, vswrstr)
qp.setPen(QtGui.QPen(Chart.color.foreground)) qp.setPen(QtGui.QPen(Chart.color.foreground))
qp.drawLine(self.leftMargin - 5, y, self.leftMargin + self.dim.width, y) qp.drawLine(self.leftMargin - 5, y,
self.leftMargin + self.dim.width, y)
qp.setPen(QtGui.QPen(Chart.color.foreground)) qp.setPen(QtGui.QPen(Chart.color.foreground))
qp.drawLine(self.leftMargin - 5, self.topMargin, qp.drawLine(self.leftMargin - 5, self.topMargin,
self.leftMargin + self.dim.width, self.topMargin) self.leftMargin + self.dim.width, self.topMargin)
qp.setPen(Chart.color.text) qp.setPen(Chart.color.text)
qp.drawText(3, self.topMargin + 4, str(maxValue)) qp.drawText(3, self.topMargin + 4, str(max_value))
qp.drawText(3, self.dim.height+self.topMargin, str(minValue)) qp.drawText(3, self.dim.height + self.topMargin, str(min_value))
self.drawFrequencyTicks(qp) self.drawFrequencyTicks(qp)
qp.setPen(Chart.color.swr) qp.setPen(Chart.color.swr)
for vswr in self.swrMarkers: for vswr in self.swrMarkers:
if vswr <= 1: if vswr <= 1:
continue continue
mag = (vswr-1)/(vswr+1) mag = (vswr - 1) / (vswr + 1)
y = self.topMargin + round((self.maxValue - mag) / self.span * self.dim.height) y = self.topMargin + int((self.maxValue - mag) / self.span
qp.drawLine(self.leftMargin, y, self.leftMargin + self.dim.width, y) * self.dim.height)
qp.drawText(self.leftMargin + 3, y - 1, "VSWR: " + str(vswr)) qp.drawLine(self.leftMargin, y,
self.leftMargin + self.dim.width, y)
qp.drawText(self.leftMargin + 3, y - 1, f"VSWR: {vswr}")
self.drawData(qp, self.data, Chart.color.sweep) self.drawData(qp, self.data, Chart.color.sweep)
self.drawData(qp, self.reference, Chart.color.reference) self.drawData(qp, self.reference, Chart.color.reference)

Wyświetl plik

@ -45,7 +45,7 @@ class MagnitudeZChart(FrequencyChart):
self.span = 1 self.span = 1
def drawValues(self, qp: QtGui.QPainter): def drawValues(self, qp: QtGui.QPainter):
if len(self.data) == 0 and len(self.reference) == 0: if not self.data and not self.reference:
return return
self._set_start_stop() self._set_start_stop()
@ -56,8 +56,9 @@ class MagnitudeZChart(FrequencyChart):
if self.fixedValues: if self.fixedValues:
self.maxValue = self.maxDisplayValue self.maxValue = self.maxDisplayValue
self.minValue = max( self.minValue = (
self.minDisplayValue, 0.01) if self.logarithmicY else self.minDisplayValue max(self.minDisplayValue, 0.01) if self.logarithmicY else
self.minDisplayValue)
else: else:
# Find scaling # Find scaling
self.minValue = 100 self.minValue = 100
@ -85,7 +86,7 @@ class MagnitudeZChart(FrequencyChart):
self.span = (self.maxValue - self.minValue) or 0.01 self.span = (self.maxValue - self.minValue) or 0.01
# We want one horizontal tick per 50 pixels, at most # We want one horizontal tick per 50 pixels, at most
horizontal_ticks = math.floor(self.dim.height/50) horizontal_ticks = int(self.dim.height / 50)
fmt = Format(max_nr_digits=4) fmt = Format(max_nr_digits=4)
for i in range(horizontal_ticks): for i in range(horizontal_ticks):
y = self.topMargin + round(i * self.dim.height / horizontal_ticks) y = self.topMargin + round(i * self.dim.height / horizontal_ticks)
@ -122,7 +123,8 @@ class MagnitudeZChart(FrequencyChart):
absy = y - self.topMargin absy = y - self.topMargin
if self.logarithmicY: if self.logarithmicY:
span = math.log(self.maxValue) - math.log(self.minValue) span = math.log(self.maxValue) - math.log(self.minValue)
val = math.exp(math.log(self.maxValue) - absy * span / self.dim.height) val = math.exp(math.log(self.maxValue) -
absy * span / self.dim.height)
else: else:
val = self.maxValue - (absy / self.dim.height * self.span) val = self.maxValue - (absy / self.dim.height * self.span)
return [val] return [val]

Wyświetl plik

@ -48,9 +48,6 @@ class PermeabilityChart(FrequencyChart):
def logarithmicYAllowed(self) -> bool: def logarithmicYAllowed(self) -> bool:
return True return True
def copy(self):
return super().copy()
def drawChart(self, qp: QtGui.QPainter): def drawChart(self, qp: QtGui.QPainter):
qp.setPen(QtGui.QPen(Chart.color.text)) qp.setPen(QtGui.QPen(Chart.color.text))
qp.drawText(self.leftMargin + 5, 15, self.name + qp.drawText(self.leftMargin + 5, 15, self.name +
@ -58,15 +55,20 @@ class PermeabilityChart(FrequencyChart):
qp.drawText(10, 15, "R") qp.drawText(10, 15, "R")
qp.drawText(self.leftMargin + self.dim.width + 10, 15, "X") qp.drawText(self.leftMargin + self.dim.width + 10, 15, "X")
qp.setPen(QtGui.QPen(Chart.color.foreground)) qp.setPen(QtGui.QPen(Chart.color.foreground))
qp.drawLine(self.leftMargin, self.topMargin - 5, qp.drawLine(self.leftMargin,
self.leftMargin, self.topMargin + self.dim.height + 5) self.topMargin - 5,
qp.drawLine(self.leftMargin-5, self.topMargin + self.dim.height, self.leftMargin,
self.leftMargin + self.dim.width + 5, self.topMargin + self.dim.height) self.topMargin + self.dim.height + 5)
qp.drawLine(self.leftMargin - 5,
self.topMargin + self.dim.height,
self.leftMargin + self.dim.width + 5,
self.topMargin + self.dim.height)
self.drawTitle(qp) self.drawTitle(qp)
def drawValues(self, qp: QtGui.QPainter): def drawValues(self, qp: QtGui.QPainter):
if len(self.data) == 0 and len(self.reference) == 0: if not self.data and not self.reference:
return return
pen = QtGui.QPen(Chart.color.sweep) pen = QtGui.QPen(Chart.color.sweep)
pen.setWidth(self.dim.point) pen.setWidth(self.dim.point)
line_pen = QtGui.QPen(Chart.color.sweep) line_pen = QtGui.QPen(Chart.color.sweep)
@ -90,14 +92,10 @@ class PermeabilityChart(FrequencyChart):
re, im = imp.real, imp.imag re, im = imp.real, imp.imag
re = re * 10e6 / d.freq re = re * 10e6 / d.freq
im = im * 10e6 / d.freq im = im * 10e6 / d.freq
if re > max_val: max_val = max(max_val, re)
max_val = re max_val = max(max_val, im)
if re < min_val: min_val = min(min_val, re)
min_val = re min_val = min(min_val, im)
if im > max_val:
max_val = im
if im < min_val:
min_val = im
for d in self.reference: # Also check min/max for the reference sweep for d in self.reference: # Also check min/max for the reference sweep
if d.freq < self.fstart or d.freq > self.fstop: if d.freq < self.fstart or d.freq > self.fstop:
continue continue
@ -105,27 +103,19 @@ class PermeabilityChart(FrequencyChart):
re, im = imp.real, imp.imag re, im = imp.real, imp.imag
re = re * 10e6 / d.freq re = re * 10e6 / d.freq
im = im * 10e6 / d.freq im = im * 10e6 / d.freq
if re > max_val: max_val = max(max_val, re)
max_val = re max_val = max(max_val, im)
if re < min_val: min_val = min(min_val, re)
min_val = re min_val = min(min_val, im)
if im > max_val:
max_val = im
if im < min_val:
min_val = im
if self.logarithmicY: if self.logarithmicY:
min_val = max(0.01, min_val) min_val = max(0.01, min_val)
self.max = max_val self.max = max_val
self.span = (max_val - min_val) or 0.01
span = max_val - min_val
if span == 0:
span = 0.01
self.span = span
# We want one horizontal tick per 50 pixels, at most # We want one horizontal tick per 50 pixels, at most
horizontal_ticks = math.floor(self.dim.height/50) horizontal_ticks = math.floor(self.dim.height / 50)
fmt = Format(max_nr_digits=4) fmt = Format(max_nr_digits=4)
for i in range(horizontal_ticks): for i in range(horizontal_ticks):
y = self.topMargin + round(i * self.dim.height / horizontal_ticks) y = self.topMargin + round(i * self.dim.height / horizontal_ticks)
@ -163,10 +153,10 @@ class PermeabilityChart(FrequencyChart):
secondary_pen.setWidth(self.dim.point) secondary_pen.setWidth(self.dim.point)
line_pen.setWidth(self.dim.line) line_pen.setWidth(self.dim.line)
for i in range(len(self.data)): for i, data in enumerate(self.data):
x = self.getXPosition(self.data[i]) x = self.getXPosition(data)
y_re = self.getReYPosition(self.data[i]) y_re = self.getReYPosition(data)
y_im = self.getImYPosition(self.data[i]) y_im = self.getImYPosition(data)
qp.setPen(primary_pen) qp.setPen(primary_pen)
if self.isPlotable(x, y_re): if self.isPlotable(x, y_re):
qp.drawPoint(x, y_re) qp.drawPoint(x, y_re)
@ -175,8 +165,8 @@ class PermeabilityChart(FrequencyChart):
qp.drawPoint(x, y_im) qp.drawPoint(x, y_im)
if self.flag.draw_lines and i > 0: if self.flag.draw_lines and i > 0:
prev_x = self.getXPosition(self.data[i - 1]) prev_x = self.getXPosition(self.data[i - 1])
prev_y_re = self.getReYPosition(self.data[i-1]) prev_y_re = self.getReYPosition(self.data[i - 1])
prev_y_im = self.getImYPosition(self.data[i-1]) prev_y_im = self.getImYPosition(self.data[i - 1])
# Real part first # Real part first
line_pen.setColor(Chart.color.sweep) line_pen.setColor(Chart.color.sweep)
@ -221,12 +211,12 @@ class PermeabilityChart(FrequencyChart):
qp.drawLine(self.leftMargin + self.dim.width, 14, qp.drawLine(self.leftMargin + self.dim.width, 14,
self.leftMargin + self.dim.width + 5, 14) self.leftMargin + self.dim.width + 5, 14)
for i in range(len(self.reference)): for i, reference in enumerate(self.reference):
if self.reference[i].freq < self.fstart or self.reference[i].freq > self.fstop: if reference.freq < self.fstart or reference.freq > self.fstop:
continue continue
x = self.getXPosition(self.reference[i]) x = self.getXPosition(reference)
y_re = self.getReYPosition(self.reference[i]) y_re = self.getReYPosition(reference)
y_im = self.getImYPosition(self.reference[i]) y_im = self.getImYPosition(reference)
qp.setPen(primary_pen) qp.setPen(primary_pen)
if self.isPlotable(x, y_re): if self.isPlotable(x, y_re):
qp.drawPoint(x, y_re) qp.drawPoint(x, y_re)
@ -235,8 +225,8 @@ class PermeabilityChart(FrequencyChart):
qp.drawPoint(x, y_im) qp.drawPoint(x, y_im)
if self.flag.draw_lines and i > 0: if self.flag.draw_lines and i > 0:
prev_x = self.getXPosition(self.reference[i - 1]) prev_x = self.getXPosition(self.reference[i - 1])
prev_y_re = self.getReYPosition(self.reference[i-1]) prev_y_re = self.getReYPosition(self.reference[i - 1])
prev_y_im = self.getImYPosition(self.reference[i-1]) prev_y_im = self.getImYPosition(self.reference[i - 1])
line_pen.setColor(Chart.color.reference) line_pen.setColor(Chart.color.reference)
qp.setPen(line_pen) qp.setPen(line_pen)
@ -269,8 +259,10 @@ class PermeabilityChart(FrequencyChart):
y_re = self.getReYPosition(self.data[m.location]) y_re = self.getReYPosition(self.data[m.location])
y_im = self.getImYPosition(self.data[m.location]) y_im = self.getImYPosition(self.data[m.location])
self.drawMarker(x, y_re, qp, m.color, self.markers.index(m)+1) self.drawMarker(x, y_re, qp, m.color,
self.drawMarker(x, y_im, qp, m.color, self.markers.index(m)+1) self.markers.index(m) + 1)
self.drawMarker(x, y_im, qp, m.color,
self.markers.index(m) + 1)
def getImYPosition(self, d: Datapoint) -> int: def getImYPosition(self, d: Datapoint) -> int:
im = d.impedance().imag im = d.impedance().imag
@ -326,7 +318,7 @@ class PermeabilityChart(FrequencyChart):
myr = self.getReYPosition(self.data[m.location]) myr = self.getReYPosition(self.data[m.location])
myi = self.getImYPosition(self.data[m.location]) myi = self.getImYPosition(self.data[m.location])
dx = abs(x - mx) dx = abs(x - mx)
dy = min(abs(y - myr), abs(y-myi)) dy = min(abs(y - myr), abs(y - myi))
distance = math.sqrt(dx**2 + dy**2) distance = math.sqrt(dx**2 + dy**2)
if distance < shortest: if distance < shortest:
shortest = distance shortest = distance

Wyświetl plik

@ -49,19 +49,17 @@ class QualityFactorChart(FrequencyChart):
# Make up some sensible scaling here # Make up some sensible scaling here
if self.fixedValues: if self.fixedValues:
maxQ = self.maxDisplayValue maxQ = self.maxDisplayValue
minQ = self.minDisplayValue
else: else:
minQ = 0
maxQ = 0 maxQ = 0
for d in self.data: for d in self.data:
Q = d.qFactor() Q = d.qFactor()
if Q > maxQ: maxQ = max(maxQ, Q)
maxQ = Q
scale = 0 scale = 0
if maxQ > 0: if maxQ > 0:
scale = max(scale, math.floor(math.log10(maxQ))) scale = max(scale, math.floor(math.log10(maxQ)))
maxQ = math.ceil(maxQ / 10 ** scale) * 10 ** scale maxQ = math.ceil(maxQ / 10 ** scale) * 10 ** scale
self.minQ = minQ
self.minQ = self.minDisplayValue
self.maxQ = maxQ self.maxQ = maxQ
self.span = self.maxQ - self.minQ self.span = self.maxQ - self.minQ
if self.span == 0: if self.span == 0:
@ -71,28 +69,30 @@ class QualityFactorChart(FrequencyChart):
for i in range(tickcount): for i in range(tickcount):
q = self.minQ + i * self.span / tickcount q = self.minQ + i * self.span / tickcount
y = self.topMargin + round((self.maxQ - q) / self.span * self.dim.height) y = self.topMargin + int((self.maxQ - q) / self.span *
self.dim.height)
q = round(q)
if q < 10: if q < 10:
q = round(q, 2) q = round(q, 2)
elif q < 20: if q < 20:
q = round(q, 1) q = round(q, 1)
else:
q = round(q)
qp.setPen(QtGui.QPen(Chart.color.text)) qp.setPen(QtGui.QPen(Chart.color.text))
qp.drawText(3, y+3, str(q)) qp.drawText(3, y + 3, str(q))
qp.setPen(QtGui.QPen(Chart.color.foreground)) qp.setPen(QtGui.QPen(Chart.color.foreground))
qp.drawLine(self.leftMargin-5, y, self.leftMargin + self.dim.width, y) qp.drawLine(self.leftMargin - 5, y,
self.leftMargin + self.dim.width, y)
qp.drawLine(self.leftMargin - 5, qp.drawLine(self.leftMargin - 5,
self.topMargin, self.topMargin,
self.leftMargin + self.dim.width, self.topMargin) self.leftMargin + self.dim.width,
self.topMargin)
qp.setPen(Chart.color.text) qp.setPen(Chart.color.text)
max_q = round(maxQ)
if maxQ < 10: if maxQ < 10:
qstr = str(round(maxQ, 2)) max_q = round(maxQ, 2)
elif maxQ < 20: elif maxQ < 20:
qstr = str(round(maxQ, 1)) max_q = round(maxQ, 1)
else: qp.drawText(3, 35, f"{max_q}")
qstr = str(round(maxQ))
qp.drawText(3, 35, qstr)
def drawValues(self, qp: QtGui.QPainter): def drawValues(self, qp: QtGui.QPainter):
if len(self.data) == 0 and len(self.reference) == 0: if len(self.data) == 0 and len(self.reference) == 0:
@ -119,7 +119,8 @@ class QualityFactorChart(FrequencyChart):
def getYPosition(self, d: Datapoint) -> int: def getYPosition(self, d: Datapoint) -> int:
Q = d.qFactor() Q = d.qFactor()
return self.topMargin + round((self.maxQ - Q) / self.span * self.dim.height) return self.topMargin + int((self.maxQ - Q) / self.span *
self.dim.height)
def valueAtPosition(self, y) -> List[float]: def valueAtPosition(self, y) -> List[float]:
absy = y - self.topMargin absy = y - self.topMargin

Wyświetl plik

@ -18,7 +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
import logging import logging
from typing import List from typing import List, Optional
from PyQt5 import QtWidgets, QtGui from PyQt5 import QtWidgets, QtGui
@ -120,7 +120,7 @@ class RealImaginaryChart(FrequencyChart):
self.topMargin - 5, self.topMargin - 5,
self.leftMargin, self.leftMargin,
self.topMargin + self.dim.height + 5) self.topMargin + self.dim.height + 5)
qp.drawLine(self.leftMargin-5, qp.drawLine(self.leftMargin - 5,
self.topMargin + self.dim.height, self.topMargin + self.dim.height,
self.leftMargin + self.dim.width + 5, self.leftMargin + self.dim.width + 5,
self.topMargin + self.dim.height) self.topMargin + self.dim.height)
@ -195,13 +195,13 @@ class RealImaginaryChart(FrequencyChart):
step_size = span / 8 step_size = span / 8
if max_imag < step_size: if max_imag < step_size:
# The 0 line is the first step after the top. Scale accordingly. # The 0 line is the first step after the top. Scale accordingly.
max_imag = -min_imag/7 max_imag = -min_imag / 7
elif -min_imag < step_size: elif -min_imag < step_size:
# The 0 line is the last step before the bottom. Scale accordingly. # The 0 line is the last step before the bottom. Scale accordingly.
min_imag = -max_imag/7 min_imag = -max_imag / 7
else: else:
# Scale max_imag to be a whole factor of min_imag # Scale max_imag to be a whole factor of min_imag
num_min = math.floor(min_imag/step_size * -1) num_min = math.floor(min_imag / step_size * -1)
num_max = 8 - num_min num_max = 8 - num_min
max_imag = num_max * (min_imag / num_min) * -1 max_imag = num_max * (min_imag / num_min) * -1
@ -257,10 +257,10 @@ class RealImaginaryChart(FrequencyChart):
secondary_pen.setWidth(self.dim.point) secondary_pen.setWidth(self.dim.point)
line_pen.setWidth(self.dim.line) line_pen.setWidth(self.dim.line)
for i in range(len(self.data)): for i, data in enumerate(self.data):
x = self.getXPosition(self.data[i]) x = self.getXPosition(data)
y_re = self.getReYPosition(self.data[i]) y_re = self.getReYPosition(data)
y_im = self.getImYPosition(self.data[i]) y_im = self.getImYPosition(data)
qp.setPen(primary_pen) qp.setPen(primary_pen)
if self.isPlotable(x, y_re): if self.isPlotable(x, y_re):
qp.drawPoint(x, y_re) qp.drawPoint(x, y_re)
@ -269,8 +269,8 @@ class RealImaginaryChart(FrequencyChart):
qp.drawPoint(x, y_im) qp.drawPoint(x, y_im)
if self.flag.draw_lines and i > 0: if self.flag.draw_lines and i > 0:
prev_x = self.getXPosition(self.data[i - 1]) prev_x = self.getXPosition(self.data[i - 1])
prev_y_re = self.getReYPosition(self.data[i-1]) prev_y_re = self.getReYPosition(self.data[i - 1])
prev_y_im = self.getImYPosition(self.data[i-1]) prev_y_im = self.getImYPosition(self.data[i - 1])
# Real part first # Real part first
line_pen.setColor(Chart.color.sweep) line_pen.setColor(Chart.color.sweep)
@ -315,12 +315,12 @@ class RealImaginaryChart(FrequencyChart):
qp.drawLine(self.leftMargin + self.dim.width, 14, qp.drawLine(self.leftMargin + self.dim.width, 14,
self.leftMargin + self.dim.width + 5, 14) self.leftMargin + self.dim.width + 5, 14)
for i in range(len(self.reference)): for i, reference in enumerate(self.reference):
if self.reference[i].freq < self.fstart or self.reference[i].freq > self.fstop: if reference.freq < self.fstart or reference.freq > self.fstop:
continue continue
x = self.getXPosition(self.reference[i]) x = self.getXPosition(reference)
y_re = self.getReYPosition(self.reference[i]) y_re = self.getReYPosition(reference)
y_im = self.getImYPosition(self.reference[i]) y_im = self.getImYPosition(reference)
qp.setPen(primary_pen) qp.setPen(primary_pen)
if self.isPlotable(x, y_re): if self.isPlotable(x, y_re):
qp.drawPoint(x, y_re) qp.drawPoint(x, y_re)
@ -329,8 +329,8 @@ class RealImaginaryChart(FrequencyChart):
qp.drawPoint(x, y_im) qp.drawPoint(x, y_im)
if self.flag.draw_lines and i > 0: if self.flag.draw_lines and i > 0:
prev_x = self.getXPosition(self.reference[i - 1]) prev_x = self.getXPosition(self.reference[i - 1])
prev_y_re = self.getReYPosition(self.reference[i-1]) prev_y_re = self.getReYPosition(self.reference[i - 1])
prev_y_im = self.getImYPosition(self.reference[i-1]) prev_y_im = self.getImYPosition(self.reference[i - 1])
line_pen.setColor(Chart.color.reference) line_pen.setColor(Chart.color.reference)
qp.setPen(line_pen) qp.setPen(line_pen)
@ -363,8 +363,10 @@ class RealImaginaryChart(FrequencyChart):
y_re = self.getReYPosition(self.data[m.location]) y_re = self.getReYPosition(self.data[m.location])
y_im = self.getImYPosition(self.data[m.location]) y_im = self.getImYPosition(self.data[m.location])
self.drawMarker(x, y_re, qp, m.color, self.markers.index(m)+1) self.drawMarker(x, y_re, qp, m.color,
self.drawMarker(x, y_im, qp, m.color, self.markers.index(m)+1) self.markers.index(m) + 1)
self.drawMarker(x, y_im, qp, m.color,
self.markers.index(m) + 1)
def getImYPosition(self, d: Datapoint) -> int: def getImYPosition(self, d: Datapoint) -> int:
im = self.impedance(d).imag im = self.impedance(d).imag
@ -405,17 +407,17 @@ class RealImaginaryChart(FrequencyChart):
self.update() self.update()
def getNearestMarker(self, x, y) -> Marker: def getNearestMarker(self, x, y) -> Optional[Marker]:
if len(self.data) == 0: if not self.data:
return None return None
shortest = 10**6 shortest = 10e6
nearest = None nearest = None
for m in self.markers: for m in self.markers:
mx, _ = self.getPosition(self.data[m.location]) mx, _ = self.getPosition(self.data[m.location])
myr = self.getReYPosition(self.data[m.location]) myr = self.getReYPosition(self.data[m.location])
myi = self.getImYPosition(self.data[m.location]) myi = self.getImYPosition(self.data[m.location])
dx = abs(x - mx) dx = abs(x - mx)
dy = min(abs(y - myr), abs(y-myi)) dy = min(abs(y - myr), abs(y - myi))
distance = math.sqrt(dx**2 + dy**2) distance = math.sqrt(dx**2 + dy**2)
if distance < shortest: if distance < shortest:
shortest = distance shortest = distance

Wyświetl plik

@ -16,7 +16,6 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# 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 logging import logging
from typing import List from typing import List
@ -54,7 +53,7 @@ class SParameterChart(FrequencyChart):
qp.drawText(self.leftMargin + self.dim.width - 15, 15, "Imag") qp.drawText(self.leftMargin + self.dim.width - 15, 15, "Imag")
qp.setPen(QtGui.QPen(Chart.color.foreground)) qp.setPen(QtGui.QPen(Chart.color.foreground))
qp.drawLine(self.leftMargin, self.topMargin - 5, qp.drawLine(self.leftMargin, self.topMargin - 5,
self.leftMargin, self.topMargin + self.dim.height+5) self.leftMargin, self.topMargin + self.dim.height + 5)
qp.drawLine(self.leftMargin - 5, self.topMargin + self.dim.height, qp.drawLine(self.leftMargin - 5, self.topMargin + self.dim.height,
self.leftMargin + self.dim.width, self.topMargin + self.dim.height) self.leftMargin + self.dim.width, self.topMargin + self.dim.height)

Wyświetl plik

@ -20,8 +20,7 @@ import logging
import math import math
from typing import List from typing import List
from PyQt5 import QtGui, QtCore from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5 import QtWidgets, QtGui
from NanoVNASaver.Charts.Chart import Chart from NanoVNASaver.Charts.Chart import Chart
from NanoVNASaver.RFTools import Datapoint from NanoVNASaver.RFTools import Datapoint
@ -55,7 +54,7 @@ class SquareChart(Chart):
raise NotImplementedError() raise NotImplementedError()
def draw_data(self, qp: QtGui.QPainter, color: QtGui.QColor, def draw_data(self, qp: QtGui.QPainter, color: QtGui.QColor,
data: List[Datapoint], fstart: int=0, fstop: int=0): data: List[Datapoint], fstart: int = 0, fstop: int = 0):
if not data: if not data:
return return
fstop = fstop or data[-1].freq fstop = fstop or data[-1].freq
@ -66,10 +65,11 @@ class SquareChart(Chart):
qp.setPen(pen) qp.setPen(pen)
prev_x = self.getXPosition(data[0]) prev_x = self.getXPosition(data[0])
prev_y = int(self.height() / 2 + data[0].im * -1 * self.dim.height / 2) prev_y = int(self.height() / 2 + data[0].im * -1 *
self.dim.height / 2)
for i, d in enumerate(data): for i, d in enumerate(data):
x = self.getXPosition(d) x = self.getXPosition(d)
y = int(self.height()/2 + d.im * -1 * self.dim.height/2) y = int(self.height() / 2 + d.im * -1 * self.dim.height / 2)
if d.freq > fstart and d.freq < fstop: if d.freq > fstart and d.freq < fstop:
qp.drawPoint(x, y) qp.drawPoint(x, y)
if self.flag.draw_lines and i > 0: if self.flag.draw_lines and i > 0:
@ -85,19 +85,21 @@ class SquareChart(Chart):
fstart = self.data[0].freq if self.data else 0 fstart = self.data[0].freq if self.data else 0
fstop = self.data[-1].freq if self.data else 0 fstop = self.data[-1].freq if self.data else 0
self.draw_data(qp, Chart.color.reference, self.reference, fstart, fstop) self.draw_data(qp, Chart.color.reference,
self.reference, fstart, fstop)
for m in self.markers: for m in self.markers:
if m.location != -1 and m.location < len(self.data): if m.location != -1 and m.location < len(self.data):
x = self.getXPosition(self.data[m.location]) x = self.getXPosition(self.data[m.location])
y = self.height() / 2 + self.data[m.location].im * -1 * self.dim.height / 2 y = self.height() / 2 + \
self.drawMarker(x, y, qp, m.color, self.markers.index(m)+1) self.data[m.location].im * -1 * self.dim.height / 2
self.drawMarker(x, y, qp, m.color, self.markers.index(m) + 1)
def resizeEvent(self, a0: QtGui.QResizeEvent) -> None: def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
if not self.flag.is_popout: if not self.flag.is_popout:
self.setFixedWidth(a0.size().height()) self.setFixedWidth(a0.size().height())
self.dim.width = a0.size().height()-40 self.dim.width = a0.size().height() - 40
self.dim.height = a0.size().height()-40 self.dim.height = a0.size().height() - 40
else: else:
min_dimension = min(a0.size().height(), a0.size().width()) min_dimension = min(a0.size().height(), a0.size().width())
self.dim.width = self.dim.height = min_dimension - 40 self.dim.width = self.dim.height = min_dimension - 40
@ -138,12 +140,11 @@ class SquareChart(Chart):
m.setFrequency(str(round(target[minimum_position].freq))) m.setFrequency(str(round(target[minimum_position].freq)))
m.frequencyInput.setText(str(round(target[minimum_position].freq))) m.frequencyInput.setText(str(round(target[minimum_position].freq)))
def getXPosition(self, d: Datapoint) -> int: def getXPosition(self, d: Datapoint) -> int:
return int(self.width()/2 + d.re * self.dim.width/2) return int(self.width() / 2 + d.re * self.dim.width / 2)
def getYPosition(self, d: Datapoint) -> int: def getYPosition(self, d: Datapoint) -> int:
return int(self.height()/2 + d.im * -1 * self.dim.height/2) return int(self.height() / 2 + d.im * -1 * self.dim.height / 2)
def zoomTo(self, x1, y1, x2, y2): def zoomTo(self, x1, y1, x2, y2):
pass pass

Wyświetl plik

@ -44,14 +44,15 @@ class VSWRChart(FrequencyChart):
return True return True
def drawValues(self, qp: QtGui.QPainter): def drawValues(self, qp: QtGui.QPainter):
if len(self.data) == 0 and len(self.reference) == 0: if not self.data and not self.reference:
return return
if self.fixedSpan: if self.fixedSpan:
fstart = self.minFrequency fstart = self.minFrequency
fstop = self.maxFrequency fstop = self.maxFrequency
elif len(self.data) > 0: elif len(self.data) > 0:
fstart = self.data[0].freq fstart = self.data[0].freq
fstop = self.data[len(self.data)-1].freq fstop = self.data[len(self.data) - 1].freq
else: else:
fstart = self.reference[0].freq fstart = self.reference[0].freq
fstop = self.reference[len(self.reference) - 1].freq fstop = self.reference[len(self.reference) - 1].freq
@ -78,10 +79,7 @@ class VSWRChart(FrequencyChart):
except OverflowError: except OverflowError:
maxVSWR = self.maxDisplayValue maxVSWR = self.maxDisplayValue
self.maxVSWR = maxVSWR self.maxVSWR = maxVSWR
span = maxVSWR-minVSWR self.span = (maxVSWR - minVSWR) or 0.01
if span == 0:
span = 0.01
self.span = span
target_ticks = math.floor(self.dim.height / 60) target_ticks = math.floor(self.dim.height / 60)
@ -91,53 +89,49 @@ class VSWRChart(FrequencyChart):
vswr = self.valueAtPosition(y)[0] vswr = self.valueAtPosition(y)[0]
qp.setPen(Chart.color.text) qp.setPen(Chart.color.text)
if vswr != 0: if vswr != 0:
digits = max(0, min(2, math.floor(3 - math.log10(abs(vswr))))) digits = max(
if digits == 0: 0, min(2, math.floor(3 - math.log10(abs(vswr)))))
vswrstr = str(round(vswr)) v_text = f"{round(vswr, digits)}" if digits else "0"
else: qp.drawText(3, y + 3, v_text)
vswrstr = str(round(vswr, digits))
qp.drawText(3, y+3, vswrstr)
qp.setPen(QtGui.QPen(Chart.color.foreground)) qp.setPen(QtGui.QPen(Chart.color.foreground))
qp.drawLine(self.leftMargin-5, y, self.leftMargin+self.dim.width, y) qp.drawLine(self.leftMargin - 5, y,
qp.drawLine(self.leftMargin - 5, self.topMargin + self.dim.height, self.leftMargin + self.dim.width, y)
self.leftMargin + self.dim.width, self.topMargin + self.dim.height) qp.drawLine(self.leftMargin - 5,
self.topMargin + self.dim.height,
self.leftMargin + self.dim.width,
self.topMargin + self.dim.height)
qp.setPen(Chart.color.text) qp.setPen(Chart.color.text)
digits = max(0, min(2, math.floor(3 - math.log10(abs(minVSWR))))) digits = max(
if digits == 0: 0, min(2, math.floor(3 - math.log10(abs(minVSWR)))))
vswrstr = str(round(minVSWR)) v_text = f"{round(minVSWR, digits)}" if digits else "0"
else: qp.drawText(3, self.topMargin + self.dim.height, v_text)
vswrstr = str(round(minVSWR, digits))
qp.drawText(3, self.topMargin + self.dim.height, vswrstr)
else: else:
for i in range(target_ticks): for i in range(target_ticks):
vswr = minVSWR + i * self.span/target_ticks vswr = minVSWR + i * self.span / target_ticks
y = self.getYPositionFromValue(vswr) y = self.getYPositionFromValue(vswr)
qp.setPen(Chart.color.text) qp.setPen(Chart.color.text)
if vswr != 0: if vswr != 0:
digits = max(0, min(2, math.floor(3 - math.log10(abs(vswr))))) digits = max(
if digits == 0: 0, min(2, math.floor(3 - math.log10(abs(vswr)))))
vswrstr = str(round(vswr)) vswrstr = f"{round(vswr, digits)}" if digits else "0"
else: qp.drawText(3, y + 3, vswrstr)
vswrstr = str(round(vswr, digits))
qp.drawText(3, y+3, vswrstr)
qp.setPen(QtGui.QPen(Chart.color.foreground)) qp.setPen(QtGui.QPen(Chart.color.foreground))
qp.drawLine(self.leftMargin-5, y, self.leftMargin+self.dim.width, y) qp.drawLine(self.leftMargin - 5, y,
self.leftMargin + self.dim.width, y)
qp.drawLine(self.leftMargin - 5, qp.drawLine(self.leftMargin - 5,
self.topMargin, self.topMargin,
self.leftMargin + self.dim.width, self.leftMargin + self.dim.width,
self.topMargin) self.topMargin)
qp.setPen(Chart.color.text) qp.setPen(Chart.color.text)
digits = max(0, min(2, math.floor(3 - math.log10(abs(maxVSWR))))) digits = max(0, min(2, math.floor(3 - math.log10(abs(maxVSWR)))))
if digits == 0: v_text = f"{round(maxVSWR, digits)}" if digits else "0"
vswrstr = str(round(maxVSWR)) qp.drawText(3, 35, v_text)
else:
vswrstr = str(round(maxVSWR, digits))
qp.drawText(3, 35, vswrstr)
qp.setPen(Chart.color.swr) qp.setPen(Chart.color.swr)
for vswr in self.swrMarkers: for vswr in self.swrMarkers:
y = self.getYPositionFromValue(vswr) y = self.getYPositionFromValue(vswr)
qp.drawLine(self.leftMargin, y, self.leftMargin + self.dim.width, y) qp.drawLine(self.leftMargin, y,
self.leftMargin + self.dim.width, y)
qp.drawText(self.leftMargin + 3, y - 1, str(vswr)) qp.drawText(self.leftMargin + 3, y - 1, str(vswr))
self.drawFrequencyTicks(qp) self.drawFrequencyTicks(qp)