From 7690f39c19b9fa68947cea8bae8441b57ea2580d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20M=C3=BCller?= Date: Sun, 11 Sep 2022 18:29:03 +0200 Subject: [PATCH] Use more integer devisions Using more integer divisions to get right type for QPainter points --- NanoVNASaver/Charts/Frequency.py | 9 ++-- NanoVNASaver/Charts/RI.py | 79 ++++++++++++--------------- NanoVNASaver/Charts/SParam.py | 79 +++++++++------------------ NanoVNASaver/Charts/Smith.py | 92 +++++++++++++++++--------------- NanoVNASaver/Charts/TDR.py | 2 +- 5 files changed, 115 insertions(+), 146 deletions(-) diff --git a/NanoVNASaver/Charts/Frequency.py b/NanoVNASaver/Charts/Frequency.py index 9779b2b..cda2c85 100644 --- a/NanoVNASaver/Charts/Frequency.py +++ b/NanoVNASaver/Charts/Frequency.py @@ -36,7 +36,6 @@ logger = logging.getLogger(__name__) class FrequencyChart(Chart): - def __init__(self, name): super().__init__(name) self.maxFrequency = 100000000 @@ -335,7 +334,7 @@ class FrequencyChart(Chart): return ( self.topMargin + round((self.maxValue - self.value_function(d) / - self.span * self.dim.height))) + self.span * self.dim.height))) except ValueError: return self.topMargin @@ -455,13 +454,13 @@ class FrequencyChart(Chart): def _check_frequency_boundaries(self, qp: QtGui.QPainter): if (self.data and self._data_oob(self.data) and - (not self.reference or self._data_oob(self.reference))): + (not self.reference or self._data_oob(self.reference))): # Data outside frequency range qp.setBackgroundMode(QtCore.Qt.OpaqueMode) qp.setBackground(Chart.color.background) qp.setPen(Chart.color.text) - qp.drawText(self.leftMargin + self.dim.width / 2 - 70, - self.topMargin + self.dim.height / 2 - 20, + qp.drawText(self.leftMargin + self.dim.width // 2 - 70, + self.topMargin + self.dim.height // 2 - 20, "Data outside frequency span") def drawDragbog(self, qp: QtGui.QPainter): diff --git a/NanoVNASaver/Charts/RI.py b/NanoVNASaver/Charts/RI.py index ee5b466..078ea0c 100644 --- a/NanoVNASaver/Charts/RI.py +++ b/NanoVNASaver/Charts/RI.py @@ -156,32 +156,23 @@ class RealImaginaryChart(FrequencyChart): for d in self.data: imp = self.impedance(d) re, im = imp.real, imp.imag - if math.isinf(re): # Avoid infinite scales + if math.isinf(re): # Avoid infinite scales continue - if re > max_real: - max_real = re - if re < min_real: - min_real = re - if im > max_imag: - max_imag = im - if im < min_imag: - min_imag = im + max_real = max(max_real, re) + min_real = min(min_real, re) + max_imag = max(max_imag, im) + min_imag = min(min_imag, im) for d in self.reference: # Also check min/max for the reference sweep if d.freq < self.fstart or d.freq > self.fstop: continue imp = self.impedance(d) re, im = imp.real, imp.imag - if math.isinf(re): # Avoid infinite scales + if math.isinf(re): # Avoid infinite scales continue - if re > max_real: - max_real = re - if re < min_real: - min_real = re - if im > max_imag: - max_imag = im - if im < min_imag: - min_imag = im - + max_real = max(max_real, re) + min_real = min(min_real, re) + max_imag = max(max_imag, im) + min_imag = min(min_imag, im) # Always have at least 8 numbered horizontal lines max_real = math.ceil(max_real) min_real = math.floor(min_real) @@ -190,8 +181,8 @@ class RealImaginaryChart(FrequencyChart): if max_imag - min_imag < 8: missing = 8 - (max_imag - min_imag) - max_imag += math.ceil(missing/2) - min_imag -= math.floor(missing/2) + max_imag += math.ceil(missing / 2) + min_imag -= math.floor(missing / 2) if 0 > max_imag > -2: max_imag = 0 @@ -217,31 +208,29 @@ class RealImaginaryChart(FrequencyChart): self.max_real = max_real self.max_imag = max_imag - span_real = max_real - min_real - if span_real == 0: - span_real = 0.01 - self.span_real = span_real - - span_imag = max_imag - min_imag - if span_imag == 0: - span_imag = 0.01 - self.span_imag = span_imag + self.span_real = (max_real - min_real) or 0.01 + self.span_imag = (max_imag - min_imag) or 0.01 # We want one horizontal tick per 50 pixels, at most - horizontal_ticks = math.floor(self.dim.height/50) + horizontal_ticks = self.dim.height // 50 fmt = Format(max_nr_digits=3) for i in range(horizontal_ticks): - y = self.topMargin + round(i * self.dim.height / horizontal_ticks) + y = self.topMargin + i * self.dim.height // horizontal_ticks qp.setPen(QtGui.QPen(Chart.color.foreground)) - qp.drawLine(self.leftMargin - 5, y, self.leftMargin + self.dim.width + 5, y) + qp.drawLine(self.leftMargin - 5, y, + self.leftMargin + self.dim.width + 5, y) qp.setPen(QtGui.QPen(Chart.color.text)) - re = max_real - i * span_real / horizontal_ticks - im = max_imag - i * span_imag / horizontal_ticks - qp.drawText(3, y + 4, str(Value(re, fmt=fmt))) - qp.drawText(self.leftMargin + self.dim.width + 8, y + 4, str(Value(im, fmt=fmt))) + re = max_real - i * self.span_real / horizontal_ticks + im = max_imag - i * self.span_imag / horizontal_ticks + qp.drawText(3, y + 4, f"{Value(re, fmt=fmt)}") + qp.drawText( + self.leftMargin + self.dim.width + 8, + y + 4, + f"{Value(im, fmt=fmt)}") - qp.drawText(3, self.dim.height + self.topMargin, str(Value(min_real, fmt=fmt))) + qp.drawText(3, self.dim.height + self.topMargin, + str(Value(min_real, fmt=fmt))) qp.drawText(self.leftMargin + self.dim.width + 8, self.dim.height + self.topMargin, str(Value(min_imag, fmt=fmt))) @@ -379,18 +368,20 @@ class RealImaginaryChart(FrequencyChart): def getImYPosition(self, d: Datapoint) -> int: im = self.impedance(d).imag - return self.topMargin + round((self.max_imag - im) / self.span_imag * self.dim.height) + return (self.topMargin + int(self.max_imag - im) // self.span_imag + * self.dim.height) def getReYPosition(self, d: Datapoint) -> int: re = self.impedance(d).real - if math.isfinite(re): - return self.topMargin + round((self.max_real - re) / self.span_real * self.dim.height) - return self.topMargin + return (self.topMargin + int(self.max_real - re) // self.span_real + * self.dim.height if math.isfinite(re) else self.topMargin) def valueAtPosition(self, y) -> List[float]: absy = y - self.topMargin - valRe = -1 * ((absy / self.dim.height * self.span_real) - self.max_real) - valIm = -1 * ((absy / self.dim.height * self.span_imag) - self.max_imag) + valRe = -1 * ((absy / self.dim.height * + self.span_real) - self.max_real) + valIm = -1 * ((absy / self.dim.height * + self.span_imag) - self.max_imag) return [valRe, valIm] def zoomTo(self, x1, y1, x2, y2): diff --git a/NanoVNASaver/Charts/SParam.py b/NanoVNASaver/Charts/SParam.py index 6699bc3..7bd4e97 100644 --- a/NanoVNASaver/Charts/SParam.py +++ b/NanoVNASaver/Charts/SParam.py @@ -49,96 +49,71 @@ class SParameterChart(FrequencyChart): def drawChart(self, qp: QtGui.QPainter): qp.setPen(QtGui.QPen(Chart.color.text)) - qp.drawText(int(round(self.dim.width / 2)) - 20, 15, self.name + "") + qp.drawText(self.dim.width // 2 - 20, 15, f"{self.name}") qp.drawText(10, 15, "Real") qp.drawText(self.leftMargin + self.dim.width - 15, 15, "Imag") qp.setPen(QtGui.QPen(Chart.color.foreground)) qp.drawLine(self.leftMargin, self.topMargin - 5, - self.leftMargin, self.topMargin+self.dim.height+5) - qp.drawLine(self.leftMargin-5, self.topMargin+self.dim.height, - self.leftMargin+self.dim.width, self.topMargin + self.dim.height) + self.leftMargin, self.topMargin + self.dim.height+5) + qp.drawLine(self.leftMargin - 5, self.topMargin + self.dim.height, + self.leftMargin + self.dim.width, self.topMargin + self.dim.height) def drawValues(self, qp: QtGui.QPainter): if len(self.data) == 0 and len(self.reference) == 0: return - self._set_start_stop() - - # Draw bands if required if self.bands.enabled: self.drawBands(qp, self.fstart, self.fstop) - if self.fixedValues: maxValue = self.maxDisplayValue minValue = self.minDisplayValue - self.maxValue = maxValue - self.minValue = minValue else: - # Find scaling minValue = -1 maxValue = 1 - self.maxValue = maxValue - self.minValue = minValue - # for d in self.data: - # val = d.re - # if val > maxValue: - # maxValue = val - # if val < minValue: - # minValue = val - # for d in self.reference: # Also check min/max for the reference sweep - # if d.freq < self.fstart or d.freq > self.fstop: - # continue - # logmag = self.logMag(d) - # if logmag > maxValue: - # maxValue = logmag - # if logmag < minValue: - # minValue = logmag - - # minValue = 10*math.floor(minValue/10) - # self.minValue = minValue - # maxValue = 10*math.ceil(maxValue/10) - # self.maxValue = maxValue - - span = maxValue-minValue + self.minValue = minValue + self.maxValue = maxValue + span = maxValue - minValue if span == 0: span = 0.01 self.span = span - - tick_count = math.floor(self.dim.height / 60) + tick_count = self.dim.height // 60 tick_step = self.span / tick_count - for i in range(tick_count): val = minValue + i * tick_step - y = self.topMargin + round((maxValue - val)/span*self.dim.height) + y = self.topMargin + (maxValue - val) // span * self.dim.height 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) if val > minValue and val != maxValue: qp.setPen(QtGui.QPen(Chart.color.text)) qp.drawText(3, y + 4, str(round(val, 2))) - qp.setPen(QtGui.QPen(Chart.color.foreground)) qp.drawLine(self.leftMargin - 5, self.topMargin, self.leftMargin + self.dim.width, self.topMargin) - qp.setPen(Chart.color.text) - qp.drawText(3, self.topMargin + 4, str(maxValue)) - qp.drawText(3, self.dim.height+self.topMargin, str(minValue)) - self.drawFrequencyTicks(qp) + qp.setPen(Chart.color.text) + qp.drawText(3, self.topMargin + 4, f"{maxValue}") + qp.drawText(3, self.dim.height + self.topMargin, f"{minValue}") + self.drawFrequencyTicks(qp) self.drawData(qp, self.data, Chart.color.sweep, self.getReYPosition) - self.drawData(qp, self.reference, Chart.color.reference, self.getReYPosition) - self.drawData(qp, self.data, Chart.color.sweep_secondary, self.getImYPosition) - self.drawData(qp, self.reference, Chart.color.reference_secondary, self.getImYPosition) + self.drawData(qp, self.reference, Chart.color.reference, + self.getReYPosition) + self.drawData(qp, self.data, Chart.color.sweep_secondary, + self.getImYPosition) + self.drawData(qp, self.reference, + Chart.color.reference_secondary, self.getImYPosition) + self.drawMarkers(qp, y_function=self.getReYPosition) self.drawMarkers(qp, y_function=self.getImYPosition) def getYPosition(self, d: Datapoint) -> int: - return self.topMargin + round((self.maxValue - d.re) / self.span * self.dim.height) + return self.topMargin + (self.maxValue - d.re) // self.span * self.dim.height def getReYPosition(self, d: Datapoint) -> int: - return self.topMargin + round((self.maxValue - d.re) / self.span * self.dim.height) + return self.topMargin + (self.maxValue - d.re) // self.span * self.dim.height def getImYPosition(self, d: Datapoint) -> int: - return self.topMargin + round((self.maxValue - d.im) / self.span * self.dim.height) + return self.topMargin + (self.maxValue - d.im) // self.span * self.dim.height def valueAtPosition(self, y) -> List[float]: absy = y - self.topMargin @@ -146,9 +121,7 @@ class SParameterChart(FrequencyChart): return [val] def logMag(self, p: Datapoint) -> float: - if self.isInverted: - return -p.gain - return p.gain + return -p.gain if self.isInverted else p.gain def copy(self): new_chart: LogMagChart = super().copy() diff --git a/NanoVNASaver/Charts/Smith.py b/NanoVNASaver/Charts/Smith.py index 035f8f2..1f82dcd 100644 --- a/NanoVNASaver/Charts/Smith.py +++ b/NanoVNASaver/Charts/Smith.py @@ -27,59 +27,65 @@ logger = logging.getLogger(__name__) class SmithChart(SquareChart): def drawChart(self, qp: QtGui.QPainter) -> None: - centerX = int(self.width()/2) - centerY = int(self.height()/2) + center_x = self.width() // 2 + center_y = self.height() // 2 + width_2 = self.dim.width // 2 + height_2 = self.dim.height // 2 qp.setPen(QtGui.QPen(Chart.color.text)) qp.drawText(3, 15, self.name) qp.setPen(QtGui.QPen(Chart.color.foreground)) - qp.drawEllipse(QtCore.QPoint(centerX, centerY), - int(self.dim.width / 2), - int(self.dim.height / 2)) - qp.drawLine( - centerX - int(self.dim.width / 2), - centerY, - centerX + int(self.dim.width / 2), - centerY) + qp.drawEllipse(QtCore.QPoint(center_x, center_y), width_2, height_2) + qp.drawLine(center_x - width_2, center_y, + center_x + width_2, center_y) - qp.drawEllipse(QtCore.QPoint(centerX + int(self.dim.width/4), centerY), - int(self.dim.width/4), int(self.dim.height/4)) # Re(Z) = 1 - qp.drawEllipse(QtCore.QPoint(centerX + int(2/3*self.dim.width/2), centerY), - int(self.dim.width/6), int(self.dim.height/6)) # Re(Z) = 2 - qp.drawEllipse(QtCore.QPoint(centerX + int(3 / 4 * self.dim.width / 2), centerY), - int(self.dim.width / 8), int(self.dim.height / 8)) # Re(Z) = 3 - qp.drawEllipse(QtCore.QPoint(centerX + int(5 / 6 * self.dim.width / 2), centerY), - int(self.dim.width / 12), int(self.dim.height / 12)) # Re(Z) = 5 + qp.drawEllipse( + QtCore.QPoint(center_x + int(self.dim.width/4), center_y), + self.dim.width // 4, self.dim.height // 4) # Re(Z) = 1 + qp.drawEllipse( + QtCore.QPoint(center_x + self.dim.width // 3, center_y), + self.dim.width // 6, self.dim.height // 6) # Re(Z) = 2 + qp.drawEllipse( + QtCore.QPoint(center_x + 3 * self.dim.width // 8, center_y), + self.dim.width // 8, self.dim.height // 8) # Re(Z) = 3 + qp.drawEllipse( + QtCore.QPoint(center_x + 5 * self.dim.width // 12, center_y), + self.dim.width // 12, self.dim.height // 12) # Re(Z) = 5 + qp.drawEllipse( + QtCore.QPoint(center_x + self.dim.width // 6, center_y), + self.dim.width // 3, self.dim.height // 3) # Re(Z) = 0.5 + qp.drawEllipse( + QtCore.QPoint(center_x + self.dim.width // 12, center_y), + 5 * self.dim.width // 12, 5 * self.dim.height // 12) # Re(Z) = 0.2 - qp.drawEllipse(QtCore.QPoint(centerX + int(1 / 3 * self.dim.width / 2), centerY), - int(self.dim.width / 3), int(self.dim.height / 3)) # Re(Z) = 0.5 - qp.drawEllipse(QtCore.QPoint(centerX + int(1 / 6 * self.dim.width / 2), centerY), - int(self.dim.width / 2.4), int(self.dim.height / 2.4)) # Re(Z) = 0.2 - - qp.drawArc(centerX + int(3/8*self.dim.width), centerY, int(self.dim.width/4), - int(self.dim.width/4), 90*16, 152*16) # Im(Z) = -5 - qp.drawArc(centerX + int(3/8*self.dim.width), centerY, int(self.dim.width/4), - -int(self.dim.width/4), -90 * 16, -152 * 16) # Im(Z) = 5 - qp.drawArc(centerX + int(self.dim.width/4), centerY, int(self.dim.width/2), - int(self.dim.height/2), 90*16, 127*16) # Im(Z) = -2 - qp.drawArc(centerX + int(self.dim.width/4), centerY, int(self.dim.width/2), - -int(self.dim.height/2), -90*16, -127*16) # Im(Z) = 2 - qp.drawArc(centerX, centerY, + qp.drawArc(center_x + 3 * self.dim.width // 8, center_y, + self.dim.width // 4, self.dim.width // 4, + 90 * 16, 152 * 16) # Im(Z) = -5 + qp.drawArc(center_x + 3 * self.dim.width // 8, center_y, + self.dim.width // 4, -self.dim.width // 4, + -90 * 16, -152 * 16) # Im(Z) = 5 + qp.drawArc(center_x + self.dim.width // 4, center_y, + width_2, height_2, + 90 * 16, 127 * 16) # Im(Z) = -2 + qp.drawArc(center_x + self.dim.width // 4, center_y, + width_2, -height_2, + -90 * 16, -127 * 16) # Im(Z) = 2 + qp.drawArc(center_x, center_y, self.dim.width, self.dim.height, 90*16, 90*16) # Im(Z) = -1 - qp.drawArc(centerX, centerY, - self.dim.width, -self.dim.height, + qp.drawArc(center_x, center_y, + self.dim.width, - self.dim.height, -90 * 16, -90 * 16) # Im(Z) = 1 - qp.drawArc(centerX - int(self.dim.width / 2), centerY, + qp.drawArc(center_x - width_2, center_y, self.dim.width * 2, self.dim.height * 2, int(99.5*16), int(43.5*16)) # Im(Z) = -0.5 - qp.drawArc(centerX - int(self.dim.width / 2), centerY, + qp.drawArc(center_x - width_2, center_y, self.dim.width * 2, -self.dim.height * 2, int(-99.5 * 16), int(-43.5 * 16)) # Im(Z) = 0.5 - qp.drawArc(centerX - self.dim.width * 2, centerY, + qp.drawArc(center_x - self.dim.width * 2, center_y, self.dim.width * 5, self.dim.height * 5, int(93.85 * 16), int(18.85 * 16)) # Im(Z) = -0.2 - qp.drawArc(centerX - self.dim.width*2, centerY, - self.dim.width*5, -self.dim.height*5, + qp.drawArc(center_x - self.dim.width * 2, center_y, + self.dim.width * 5, -self.dim.height * 5, int(-93.85 * 16), int(-18.85 * 16)) # Im(Z) = 0.2 self.drawTitle(qp) @@ -89,8 +95,8 @@ class SmithChart(SquareChart): if swr <= 1: continue gamma = (swr - 1)/(swr + 1) - r = round(gamma * self.dim.width/2) - qp.drawEllipse(QtCore.QPoint(centerX, centerY), r, r) + r = gamma * self.dim.width // 2 + qp.drawEllipse(QtCore.QPoint(center_x, center_y), r, r) qp.drawText( - QtCore.QRect(centerX - 50, centerY - 4 + r, 100, 20), - QtCore.Qt.AlignCenter, str(swr)) + QtCore.QRect(center_x - 50, center_y - 4 + r, 100, 20), + QtCore.Qt.AlignCenter, f"{swr}") diff --git a/NanoVNASaver/Charts/TDR.py b/NanoVNASaver/Charts/TDR.py index 3e2fd22..1ed26fd 100644 --- a/NanoVNASaver/Charts/TDR.py +++ b/NanoVNASaver/Charts/TDR.py @@ -291,7 +291,7 @@ class TDRChart(Chart): self.leftMargin, self.height() - self.bottomMargin + 5) # Number of ticks does not include the origin - ticks = math.floor((self.width() - self.leftMargin) / 100) + ticks = (self.width() - self.leftMargin) // 100 self.drawTitle(qp) if self.tdrWindow.td.size: