Merge pull request #543 from zarath/bugfix/541_crash_in_draw

Use more integer devisions
pull/547/head
Holger Müller 2022-09-11 18:46:43 +02:00 zatwierdzone przez GitHub
commit 51d0e318cd
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
5 zmienionych plików z 115 dodań i 146 usunięć

Wyświetl plik

@ -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):

Wyświetl plik

@ -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):

Wyświetl plik

@ -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()

Wyświetl plik

@ -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}")

Wyświetl plik

@ -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: