diff --git a/pyctbgui/pyctbgui/services/Acquisition.py b/pyctbgui/pyctbgui/services/Acquisition.py index a7db13b63..e7293a10d 100644 --- a/pyctbgui/pyctbgui/services/Acquisition.py +++ b/pyctbgui/pyctbgui/services/Acquisition.py @@ -134,7 +134,6 @@ class AcquisitionTab(QtWidgets.QWidget): self.view.labelTransceiver.setDisabled(True) self.view.spinBoxTransceiver.setDisabled(True) self.plotTab.showallCounterCheckBox(False) - self.plotTab.activate_counter(0, True) # analog plot has 1 active counter by default case readoutMode.DIGITAL_ONLY: self.view.spinBoxAnalog.setDisabled(True) self.view.labelAnalog.setDisabled(True) @@ -143,7 +142,6 @@ class AcquisitionTab(QtWidgets.QWidget): self.view.labelTransceiver.setDisabled(True) self.view.spinBoxTransceiver.setDisabled(True) self.plotTab.showallCounterCheckBox(False) - self.plotTab.activate_counter(0, True) # digital plot has 1 active counter by default case readoutMode.ANALOG_AND_DIGITAL: self.view.spinBoxAnalog.setEnabled(True) self.view.labelAnalog.setEnabled(True) @@ -152,7 +150,6 @@ class AcquisitionTab(QtWidgets.QWidget): self.view.labelTransceiver.setDisabled(True) self.view.spinBoxTransceiver.setDisabled(True) self.plotTab.showallCounterCheckBox(False) - self.plotTab.activate_counter(0, True) # analog and digital plots have 1 active counter by default case readoutMode.TRANSCEIVER_ONLY: self.view.spinBoxAnalog.setDisabled(True) self.view.labelAnalog.setDisabled(True) diff --git a/pyctbgui/pyctbgui/services/Plot.py b/pyctbgui/pyctbgui/services/Plot.py index 1e1411b83..ff87a8a1c 100644 --- a/pyctbgui/pyctbgui/services/Plot.py +++ b/pyctbgui/pyctbgui/services/Plot.py @@ -29,12 +29,29 @@ class PlotTab(QtWidgets.QWidget): self.transceiverTab = None self.acquisitionTab = None self.adcTab = None - self.cmin: list[float] = Defines.max_counters * [0.0] - self.cmax: list[float] = Defines.max_counters * [0.0] - self.colorRangeMode: Defines.colorRange = Defines.colorRange.auto + + self.shownCounterImages: list[bool] = [True] * Defines.max_counters # per default show all 4 counter images + + self.showtransceiverImage : bool = False + self.showdigitalImage : bool = False + self.showanalogImage : bool = False + self.activated_counters: list[bool] = Defines.max_counters * [False] - self.cminSpinBoxes : list[QtWidgets.QSpinBox] = None - self.cmaxSpinBoxes : list[QtWidgets.QSpinBox] = None + + # color range variables + self.colorRangeMode: Defines.colorRange = Defines.colorRange.auto + + self.digitalcolorrange : list[float] = [0.0, 0.0] + self.analogcolorrange : list[float] = [0.0, 0.0] + self.transceivercolorrange : list[list[float]] = [[0.0, 0.0] for _ in range(Defines.max_counters)] + + self.digitalcminSpinBoxes : QtWidgets.QSpinBox = None + self.digitalcmaxSpinBoxes : QtWidgets.QSpinBox = None + self.analogcminSpinBoxes : QtWidgets.QSpinBox = None + self.analogcmaxSpinBoxes : QtWidgets.QSpinBox = None + self.transceivercminSpinBoxes : list[QtWidgets.QSpinBox] = None + self.transceivercmaxSpinBoxes : list[QtWidgets.QSpinBox] = None + # list of callback functions to notify tabs when we should hide their legend # follows the observer design pattern self.hideLegendObservers = [] @@ -55,12 +72,18 @@ class PlotTab(QtWidgets.QWidget): self.checkBoxCounters = [self.view.checkBoxCounter0, self.view.checkBoxCounter1, self.view.checkBoxCounter2, self.view.checkBoxCounter3] for checkBox in self.checkBoxCounters: - checkBox.setChecked(False) + checkBox.setChecked(True) # per default enable all checkBox.setEnabled(False) - self.cminSpinBoxes = [self.view.cminSpinBox0, self.view.cminSpinBox1, self.view.cminSpinBox2, self.view.cminSpinBox3] - self.cmaxSpinBoxes = [self.view.cmaxSpinBox0, self.view.cmaxSpinBox1, self.view.cmaxSpinBox2, self.view.cmaxSpinBox3] - self.labelColorRangeCounters = [self.view.labelColorRangeCounter0, self.view.labelColorRangeCounter1, self.view.labelColorRangeCounter2, self.view.labelColorRangeCounter3] + self.transceivercminSpinBoxes = [self.view.transceivercminSpinBox0, self.view.transceivercminSpinBox1, self.view.transceivercminSpinBox2, self.view.transceivercminSpinBox3] + self.transceivercmaxSpinBoxes = [self.view.transceivercmaxSpinBox0, self.view.transceivercmaxSpinBox1, self.view.transceivercmaxSpinBox2, self.view.transceivercmaxSpinBox3] + self.analogcminSpinBoxes = self.view.analogcminSpinBox + self.analogcmaxSpinBoxes = self.view.analogcmaxSpinBox + self.digitalcminSpinBoxes = self.view.digitalcminSpinBox + self.digitalcmaxSpinBoxes = self.view.digitalcmaxSpinBox + + + #self.labelColorRangeCounters = [self.view.labelColorRangeCounter0, self.view.labelColorRangeCounter1, self.view.labelColorRangeCounter2, self.view.labelColorRangeCounter3] def connect_ui(self): @@ -97,14 +120,20 @@ class PlotTab(QtWidgets.QWidget): self.view.radioButtonFixed.clicked.connect(partial(self.setColorRangeMode, Defines.colorRange.fixed)) self.view.radioButtonCenter.clicked.connect(partial(self.setColorRangeMode, Defines.colorRange.center)) - for index, cminSpinBox in enumerate(self.cminSpinBoxes): - cminSpinBox.editingFinished.connect(partial(self.setCmin, index=index)) + for index, cminSpinBox in enumerate(self.transceivercminSpinBoxes): + cminSpinBox.editingFinished.connect(partial(self.setCmin, imagetype = Defines.ImageType.TRANSCEIVER, index=index)) - for index, cmaxSpinBox in enumerate(self.cmaxSpinBoxes): - cmaxSpinBox.editingFinished.connect(partial(self.setCmax, index=index)) + for index, cmaxSpinBox in enumerate(self.transceivercmaxSpinBoxes): + cmaxSpinBox.editingFinished.connect(partial(self.setCmax, imagetype = Defines.ImageType.TRANSCEIVER, index=index)) + + self.analogcminSpinBoxes.editingFinished.connect(partial(self.setCmin, imagetype = Defines.ImageType.ANALOG, index=0)) + self.analogcmaxSpinBoxes.editingFinished.connect(partial(self.setCmax, imagetype = Defines.ImageType.ANALOG, index=0)) + self.digitalcminSpinBoxes.editingFinished.connect(partial(self.setCmin, imagetype = Defines.ImageType.DIGITAL, index=0)) + self.digitalcmaxSpinBoxes.editingFinished.connect(partial(self.setCmax, imagetype = Defines.ImageType.DIGITAL, index=0)) for index, checkBox in enumerate(self.checkBoxCounters): - checkBox.stateChanged.connect(partial(self.displayCounter, index)) + checkBox.stateChanged.connect(lambda state, index=index: self.setCounterCheckBox(index, is_checked=(state == QtCore.Qt.Checked))) + # show image Values for analog image nMaxY = lambda : self.mainWindow.nAnalogRows @@ -112,8 +141,8 @@ class PlotTab(QtWidgets.QWidget): frame = lambda : self.mainWindow.analog_frame plot = self.mainWindow.plotAnalogImage plot.scene.sigMouseMoved.connect(partial(self.showPlotValues, plot, nMaxX, nMaxY, frame)) - plot.getImageItem().sigImageChanged.connect(partial(self.updateColorRange, plot=plot)) # order is important otherwise overwritten - plot.getHistogramWidget().item.sigLevelChangeFinished.connect(lambda _histItem, plot=plot: self.handleHistogramChange(plot)) + plot.getImageItem().sigImageChanged.connect(partial(self.updateColorRange, imagetype = Defines.ImageType.ANALOG, plot=plot)) + plot.getHistogramWidget().item.sigLevelChangeFinished.connect(lambda _histItem, plot=plot: self.handleHistogramChange(plot, imagetype=Defines.ImageType.ANALOG)) # show image Values for digital image @@ -122,8 +151,8 @@ class PlotTab(QtWidgets.QWidget): frame = lambda : self.mainWindow.digital_frame plot = self.mainWindow.plotDigitalImage plot.scene.sigMouseMoved.connect(partial(self.showPlotValues, plot, nMaxX, nMaxY, frame)) - plot.getImageItem().sigImageChanged.connect(partial(self.updateColorRange, plot=plot)) - plot.getHistogramWidget().item.sigLevelChangeFinished.connect(lambda _histItem, plot=plot: self.handleHistogramChange(plot)) + plot.getImageItem().sigImageChanged.connect(partial(self.updateColorRange, imagetype = Defines.ImageType.DIGITAL, plot=plot)) + plot.getHistogramWidget().item.sigLevelChangeFinished.connect(lambda _histItem, plot=plot: self.handleHistogramChange(plot, imagetype=Defines.ImageType.DIGITAL)) # show image Values for transceiver image @@ -133,48 +162,44 @@ class PlotTab(QtWidgets.QWidget): for index, image_view in enumerate(self.transceiverTab.transceiverImageViews): frame = lambda image_view=image_view: image_view.getImageItem().image image_view.scene.sigMouseMoved.connect(partial(self.showPlotValues, image_view, nMaxX, nMaxY, frame)) - image_view.getImageItem().sigImageChanged.connect(partial(self.updateColorRange, plot=image_view, index=index)) + image_view.getImageItem().sigImageChanged.connect(partial(self.updateColorRange, imagetype = Defines.ImageType.TRANSCEIVER, plot=image_view, index=index)) image_view.getHistogramWidget().item.sigLevelChangeFinished.connect( - lambda _histItem, image_view=image_view, index=index: self.handleHistogramChange(image_view, index)) # sigLevelChangeFinished passes the histogram item as the first argument, we need to ignore it and pass the image_view instead + lambda _histItem, image_view=image_view, index=index: self.handleHistogramChange(plot = image_view, imagetype=Defines.ImageType.TRANSCEIVER, index=index)) # sigLevelChangeFinished passes the histogram item as the first argument, we need to ignore it and pass the image_view instead self.view.checkBoxShowLegend.stateChanged.connect(self.toggleLegend) - def displayCounter(self, index : int, state : int): - # toggle the display of the counter i and update the splitter - self.setCounterCheckBox(index, state == QtCore.Qt.Checked) - self.transceiverTab.shownCounters[index] = (state == QtCore.Qt.Checked) + def setCounterCheckBox(self, index : int, is_checked : bool): + """ + slot function for the counter checkboxes, enables/disables the cmin/cmax spinboxes for the counter at index, updates image splitter to show counter image + """ + print(f"setCounterCheckBox: index={index}, state={is_checked}") + self.transceivercmaxSpinBoxes[index].setEnabled(is_checked and self.colorRangeMode == Defines.colorRange.fixed) + self.transceivercminSpinBoxes[index].setEnabled(is_checked and self.colorRangeMode == Defines.colorRange.fixed) + + print(f"Set Check Box: {is_checked}") + self.shownCounterImages[index] = is_checked # TODO: maybe I dont need that self.transceiverTab.update_ImageSplitter() - - def setCounterCheckBox(self, index : int, check : bool): - self.checkBoxCounters[index].setChecked(check) - self.activated_counters[index] = check - self.cmaxSpinBoxes[index].setEnabled(check and self.colorRangeMode == Defines.colorRange.fixed) - self.cminSpinBoxes[index].setEnabled(check and self.colorRangeMode == Defines.colorRange.fixed) - + def enableCounterCheckBox(self, index : int, enabled : bool): + print(f"enableCounterCheckBox: index={index}, enabled={enabled}") self.checkBoxCounters[index].setEnabled(enabled) - self.cmaxSpinBoxes[index].setEnabled(enabled and self.colorRangeMode == Defines.colorRange.fixed) - self.cminSpinBoxes[index].setEnabled(enabled and self.colorRangeMode == Defines.colorRange.fixed) + is_checked = self.checkBoxCounters[index].isChecked() + self.transceivercmaxSpinBoxes[index].setEnabled(enabled and is_checked and self.colorRangeMode == Defines.colorRange.fixed) + self.transceivercminSpinBoxes[index].setEnabled(enabled and is_checked and self.colorRangeMode == Defines.colorRange.fixed) def showallCounterCheckBox(self, enabled : bool): + print(f"showallCounterCheckBox: {enabled}") for checkBox in self.checkBoxCounters: checkBox.setVisible(enabled) self.view.labelCounters.setVisible(enabled) - # per counter color range only shown for multiple counters, otherwise only first cmin/cmax spinbox without label - for label in self.labelColorRangeCounters: - label.setVisible(enabled) - for cminSpinBox, cmaxSpinBox in zip(self.cminSpinBoxes[1:], self.cmaxSpinBoxes[1:]): - cminSpinBox.setVisible(enabled) - cmaxSpinBox.setVisible(enabled) - - def activate_counter(self, index : int, active : bool): - self.activated_counters[index] = active + for cminSpinBox, cmaxSpinBox in zip(self.transceivercminSpinBoxes, self.transceivercmaxSpinBoxes): + cminSpinBox.setEnabled(enabled and self.colorRangeMode == Defines.colorRange.fixed and self.checkBoxCounters[self.transceivercminSpinBoxes.index(cminSpinBox)].isChecked()) + cmaxSpinBox.setEnabled(enabled and self.colorRangeMode == Defines.colorRange.fixed and self.checkBoxCounters[self.transceivercmaxSpinBoxes.index(cmaxSpinBox)].isChecked()) - def refresh(self): self.getZMQHWM() @@ -257,36 +282,81 @@ class PlotTab(QtWidgets.QWidget): for notify_function in self.hideLegendObservers: notify_function() - def setCmin(self, value=None, index = 0, updateColorBar=True): + def setCmin(self, imagetype : Defines.ImageType, value = None, index = 0, updateColorBar=True): """ - slot for setting cmin from cminSpinBox - also used as a normal function + Set the minimum color range value + + Parameters + ---------- + imagetype : Defines.ImageType + The type of image (DIGITAL, ANALOG, or TRANSCEIVER). + value : float, optional + The value to set for the minimum color range (default is None). + index : int, optional + The index of the counter (default is 0). + updateColorBar : bool, optional + Whether to update the color bar (default is True). """ if value is None: - self.cmin[index] = self.cminSpinBoxes[index].value() + if imagetype == Defines.ImageType.DIGITAL: + self.digitalcolorrange[0] = self.digitalcminSpinBoxes.value() + elif imagetype == Defines.ImageType.ANALOG: + self.analogcolorrange[0] = self.analogcminSpinBoxes.value() + else: + self.transceivercolorrange[index][0] = self.transceivercminSpinBoxes[index].value() else: - self.cmin[index] = value - self.cminSpinBoxes[index].setValue(self.cmin[index]) + if imagetype == Defines.ImageType.DIGITAL: + self.digitalcolorrange[0] = value + self.digitalcminSpinBoxes.setValue(self.digitalcolorrange[0]) + elif imagetype == Defines.ImageType.ANALOG: + self.analogcolorrange[0] = value + self.analogcminSpinBoxes.setValue(self.analogcolorrange[0]) + else: + self.transceivercolorrange[index][0] = value + self.transceivercminSpinBoxes[index].setValue(self.transceivercolorrange[index][0]) if updateColorBar: - self.updateColorBar(index=index) + self.updateColorBar(imagetype = imagetype, index=index) - def setCmax(self, value=None, index = 0, updateColorBar=True): + def setCmax(self, imagetype : Defines.ImageType, value=None, index = 0, updateColorBar=True): """ - slot for setting cmax from cmaxSpinBox - also used as a normal function + Set the maximum color range value + + Parameters + ---------- + imagetype : Defines.ImageType + The type of image (DIGITAL, ANALOG, or TRANSCEIVER). + value : float, optional + The value to set for the minimum color range (default is None). + index : int, optional + The index of the counter (default is 0). + updateColorBar : bool, optional + Whether to update the color bar (default is True). """ + if value is None: - self.cmax[index] = self.cmaxSpinBoxes[index].value() + if imagetype == Defines.ImageType.DIGITAL: + self.digitalcolorrange[1] = self.digitalcmaxSpinBoxes.value() + elif imagetype == Defines.ImageType.ANALOG: + self.analogcolorrange[1] = self.analogcmaxSpinBoxes.value() + else: + self.transceivercolorrange[index][1] = self.transceivercmaxSpinBoxes[index].value() else: - self.cmax[index] = value - self.cmaxSpinBoxes[index].setValue(self.cmax[index]) - + if imagetype == Defines.ImageType.DIGITAL: + self.digitalcolorrange[1] = value + self.digitalcmaxSpinBoxes.setValue(self.digitalcolorrange[1]) + elif imagetype == Defines.ImageType.ANALOG: + self.analogcolorrange[1] = value + self.analogcmaxSpinBoxes.setValue(self.analogcolorrange[1]) + else: + self.transceivercolorrange[index][1] = value + self.transceivercmaxSpinBoxes[index].setValue(self.transceivercolorrange[index][1]) + if updateColorBar: - self.updateColorBar(index=index) + self.updateColorBar(imagetype=imagetype, index=index) - def setColorRangeMode(self, mode): + def setColorRangeMode(self, mode : Defines.colorRange): """ slot for setting the color range mode (all,fixed,3-97%) """ @@ -294,77 +364,116 @@ class PlotTab(QtWidgets.QWidget): # disable or enable cmin/cmax spinboxes enableSpinBoxes = mode == Defines.colorRange.fixed - for cminSpinBox, cmaxSpinBox, checkBox in zip(self.cminSpinBoxes, self.cmaxSpinBoxes, self.checkBoxCounters): - cminSpinBox.setEnabled(enableSpinBoxes and (checkBox.isChecked() and checkBox.isEnabled())) # if the checkbox is disabled, we still want to enable the spinbox - cmaxSpinBox.setEnabled(enableSpinBoxes and (checkBox.isChecked() and checkBox.isEnabled())) # if the checkbox is disabled, we still want to enable the spinbox + + + for cminSpinBox, cmaxSpinBox, checkBox in zip(self.transceivercminSpinBoxes, self.transceivercmaxSpinBoxes, self.checkBoxCounters): + cminSpinBox.setEnabled(enableSpinBoxes and (checkBox.isChecked() and checkBox.isEnabled() and self.showtransceiverImage)) # if the checkbox is disabled, we still want to enable the spinbox + cmaxSpinBox.setEnabled(enableSpinBoxes and (checkBox.isChecked() and checkBox.isEnabled() and self.showtransceiverImage)) # if the checkbox is disabled, we still want to enable the spinbox + + self.analogcminSpinBoxes.setEnabled(enableSpinBoxes and self.showanalogImage) + self.analogcmaxSpinBoxes.setEnabled(enableSpinBoxes and self.showanalogImage) + + self.digitalcminSpinBoxes.setEnabled(enableSpinBoxes and self.showdigitalImage) + self.digitalcmaxSpinBoxes.setEnabled(enableSpinBoxes and self.showdigitalImage) for index in range(Defines.max_counters): - if self.activated_counters[index]: - self.updateColorRange(index=index) + self.updateColorRange(imagetype=Defines.ImageType.TRANSCEIVER, index=index) - def handleHistogramChange(self, plot, index=0): + self.updateColorRange(imagetype=Defines.ImageType.ANALOG) + + self.updateColorRange(imagetype=Defines.ImageType.DIGITAL) + + def handleHistogramChange(self, plot, imagetype : Defines.ImageType, index=0): """ Parameters ---------- plot : Plot The plot object whose histogram has changed. + imagetype : Defines.ImageType + The type of image (DIGITAL, ANALOG, or TRANSCEIVER). index : int, optional The index of the counter (default is 0). """ cmin, cmax = plot.getHistogramWidget().item.getLevels() - self.setCmin(cmin, index=index, updateColorBar=False) - self.setCmax(cmax, index=index, updateColorBar=False) + self.setCmin(imagetype=imagetype, value=cmin, index=index, updateColorBar=False) + self.setCmax(imagetype=imagetype, value=cmax, index=index, updateColorBar=False) - # self.setColorRangeMode(Defines.colorRange.fixed) - def updateColorRange(self, plot = None, index=0): + def updateColorRange(self, imagetype : Defines.ImageType, plot = None, index=0): """ + Updates the color range of the plot at index based on the current color range mode. for mode: - auto: sets cmin and cmax to the maximums/minimum values of the frame - 3-97%: limits cmax and cmin so that we ignore 3% from each end of the whole range - fixed: this function does not change cmin and cmax + + Parameters + ---------- + imagetype : Defines.ImageType + The type of image (DIGITAL, ANALOG, or TRANSCEIVER). + plot : Plot, optional + The plot object to update (default is None). + index : int, optional + The index of the counter (default is 0). """ - if plot is None: - if self.mainWindow.romode.value in [3, 4]: # update transceiver - plot = self.transceiverTab.transceiverImageViews[index] - elif self.mainWindow.romode.value in [1, 2]: # update digital - plot = self.mainWindow.plotDigitalImage - elif self.mainWindow.romode.value in [0, 2]: # update analog - plot = self.mainWindow.plotAnalogImage + print(f"updateColorRange: imagetype={imagetype}, index={index}, colorRangeMode={self.colorRangeMode}") + if imagetype == Defines.ImageType.TRANSCEIVER: # update transceiver + defaultPlot = self.transceiverTab.transceiverImageViews[index] + cmin, cmax = self.transceivercolorrange[index] + elif imagetype == Defines.ImageType.DIGITAL: # update digital + defaultPlot = self.mainWindow.plotDigitalImage + cmin, cmax = self.digitalcolorrange + elif imagetype == Defines.ImageType.ANALOG: # update analog + defaultPlot = self.mainWindow.plotAnalogImage + cmin, cmax = self.analogcolorrange + if plot is None: + plot = defaultPlot if self.colorRangeMode == Defines.colorRange.auto: - frame_min = np.min(plot.getImageItem().image) - frame_max = np.max(plot.getImageItem().image) - self.setCmin(frame_min, index=index) - self.setCmax(frame_max, index=index) + if plot.getImageItem().image is None or plot.getImageItem().image.size == 0: + return + else: + frame_min = np.min(plot.getImageItem().image) + frame_max = np.max(plot.getImageItem().image) + self.setCmin(imagetype=imagetype, value=frame_min, index=index) + self.setCmax(imagetype=imagetype, value=frame_max, index=index) elif self.colorRangeMode == Defines.colorRange.center: - frame_min = np.min(plot.getImageItem().image) - frame_max = np.max(plot.getImageItem().image) - self.setCmin(frame_min + 0.03 * (frame_max - frame_min), index=index) - self.setCmax(frame_max - 0.03 * (frame_max - frame_min), index=index) + if plot.getImageItem().image is None or plot.getImageItem().image.size == 0: + return + + else: + frame_min = np.min(plot.getImageItem().image) + frame_max = np.max(plot.getImageItem().image) + self.setCmin(imagetype=imagetype, value=frame_min + 0.03 * (frame_max - frame_min), index=index) + self.setCmax(imagetype=imagetype, value=frame_max - 0.03 * (frame_max - frame_min), index=index) elif self.colorRangeMode == Defines.colorRange.fixed: - self.setCmin(self.cmin[index], index=index) - self.setCmax(self.cmax[index], index=index) + self.setCmin(imagetype=imagetype, value=cmin, index=index) + self.setCmax(imagetype=imagetype, value=cmax, index=index) - def updateColorBar(self, index = 0): + def updateColorBar(self, imagetype : Defines.ImageType, index = 0): """ updates the color bar of the plot at index """ + plot = None - if self.mainWindow.romode.value in [3, 4]: # update transceiver + cmin, cmax = 0.0, 0.0 + if imagetype == Defines.ImageType.TRANSCEIVER: plot = self.transceiverTab.transceiverImageViews[index] - elif self.mainWindow.romode.value in [1, 2]: # update digital + cmin, cmax = self.transceivercolorrange[index] + elif imagetype == Defines.ImageType.DIGITAL: # update digital plot = self.mainWindow.plotDigitalImage - elif self.mainWindow.romode.value in [0, 2]: # update analog + cmin, cmax = self.digitalcolorrange + elif imagetype == Defines.ImageType.ANALOG: # update analog plot = self.mainWindow.plotAnalogImage + cmin, cmax = self.analogcolorrange if plot is not None: - plot.getHistogramWidget().item.sigLevelChangeFinished.disconnect() # disconnect before setting the levels - plot.getHistogramWidget().item.setLevels(min=self.cmin[index], max=self.cmax[index]) - plot.getHistogramWidget().item.sigLevelChangeFinished.connect( - lambda _histItem, image_view=plot, index=index: self.handleHistogramChange(image_view, index)) # reconnect + histItem = plot.getHistogramWidget().item + histItem.blockSignals(True) # avoid triggering handleHistogramChange while setting the levels + histItem.setLevels(min=cmin, max=cmax) + histItem.blockSignals(False) def setColorMap(self): @@ -372,7 +481,7 @@ class PlotTab(QtWidgets.QWidget): # print(f'color map:{self.comboBoxColorMap.currentText()}') self.mainWindow.plotAnalogImage.setColorMap(cm) self.mainWindow.plotDigitalImage.setColorMap(cm) - for i, showncounter in enumerate(self.transceiverTab.shownCounters): + for i, showncounter in enumerate(self.shownCounterImages): if showncounter: self.transceiverTab.transceiverImageViews[i].setColorMap(cm) @@ -468,11 +577,13 @@ class PlotTab(QtWidgets.QWidget): if self.view.radioButtonWaveform.isChecked(): self.mainWindow.plotAnalogWaveform.show() elif self.view.radioButtonImage.isChecked(): + self.showanalogImage = True self.mainWindow.plotAnalogImage.show() if self.mainWindow.romode.value in [1, 2, 4]: if self.view.radioButtonWaveform.isChecked(): self.mainWindow.plotDigitalWaveform.show() elif self.view.radioButtonImage.isChecked(): + self.showdigitalImage = True self.mainWindow.plotDigitalImage.show() self.view.labelDigitalWaveformOption.setEnabled(True) self.view.radioButtonOverlay.setEnabled(True) @@ -482,7 +593,8 @@ class PlotTab(QtWidgets.QWidget): if self.view.radioButtonWaveform.isChecked(): self.mainWindow.plotTransceiverWaveform.show() elif self.view.radioButtonImage.isChecked(): - for i, showncounter in enumerate(self.transceiverTab.shownCounters): + self.showtransceiverImage = True + for i, showncounter in enumerate(self.shownCounterImages): self.transceiverTab.transceiverImageViews[i].setVisible(showncounter) self.transceiverTab.transceiverImageSplitter.show() diff --git a/pyctbgui/pyctbgui/services/Signals.py b/pyctbgui/pyctbgui/services/Signals.py index 9572dc3f6..0a8ec8dab 100644 --- a/pyctbgui/pyctbgui/services/Signals.py +++ b/pyctbgui/pyctbgui/services/Signals.py @@ -193,7 +193,7 @@ class SignalsTab(QtWidgets.QWidget): self.mainWindow.nDigitalRows = 0 self.mainWindow.nDigitalCols = 0 self.mainWindow.digital_frame = np.zeros((self.mainWindow.nDigitalRows, self.mainWindow.nDigitalCols)) - self.mainWindow.plotDigitalImage.setImage(self.mainWindow.digital_frame) + self.mainWindow.plotDigitalImage.setImage(self.mainWindow.digital_frame, autoLevels=False) self.mainWindow.verticalLayoutPlot.addWidget(self.mainWindow.plotDigitalImage, 4) def updateSignalNames(self): diff --git a/pyctbgui/pyctbgui/services/Transceiver.py b/pyctbgui/pyctbgui/services/Transceiver.py index 36ae7db9a..647fa13cb 100644 --- a/pyctbgui/pyctbgui/services/Transceiver.py +++ b/pyctbgui/pyctbgui/services/Transceiver.py @@ -27,7 +27,6 @@ class TransceiverTab(QtWidgets.QWidget): self.nCounters: int = Defines.max_counters self.nTransceiverRows : int = 0 self.nTransceiverCols : int = 0 - self.shownCounters: list[bool] = [True] * Defines.max_counters # per default show all 4 counters self.transceiverImageSplitter = QtWidgets.QSplitter(QtCore.Qt.Vertical) self.transceiverImageViews : list = [] # pg image view for each counter self.firstTransceiverImage : list[bool] = [True] * Defines.max_counters # to keep track of first image for each counter to maintain zoom state @@ -167,7 +166,7 @@ class TransceiverTab(QtWidgets.QWidget): # keep the zoomed in state (not 1st image) for idx, image_view in enumerate(self.transceiverImageViews): - if(self.firstTransceiverImage[idx] and self.shownCounters[idx]): + if(self.firstTransceiverImage[idx] and self.plotTab.shownCounterImages[idx]): self.firstTransceiverImage[idx] = False else: image_view.getView().setState(image_states[idx]) @@ -176,17 +175,18 @@ class TransceiverTab(QtWidgets.QWidget): def update_numCounters(self, num_counters): # update the number of counters and adjust the image splitter accordingly + print(f"Updating number of counters to {num_counters}") self.nCounters = num_counters for i in range(Defines.max_counters): - self.shownCounters[i] = i < self.nCounters - self.plotTab.setCounterCheckBox(i, self.shownCounters[i]) # check the counter checkbox - self.plotTab.enableCounterCheckBox(i, self.shownCounters[i]) # disable counter checkbox + self.plotTab.shownCounterImages[i] = i < self.nCounters + self.plotTab.setCounterCheckBox(i, self.plotTab.shownCounterImages[i]) # check the counter checkbox + self.plotTab.enableCounterCheckBox(i, self.plotTab.shownCounterImages[i]) # disable counter checkbox self.update_ImageSplitter() # update the splitter to show/hide image views based on the number of counters def update_ImageSplitter(self): - for i, showncounter in enumerate(self.shownCounters): + for i, showncounter in enumerate(self.plotTab.shownCounterImages): self.transceiverImageViews[i].setVisible(showncounter) def initializeAllTransceiverPlots(self): diff --git a/pyctbgui/pyctbgui/ui/plot.ui b/pyctbgui/pyctbgui/ui/plot.ui index 6ea67e130..2e0e53d8c 100644 --- a/pyctbgui/pyctbgui/ui/plot.ui +++ b/pyctbgui/pyctbgui/ui/plot.ui @@ -1391,7 +1391,7 @@ - + false @@ -1735,8 +1735,8 @@ - + diff --git a/pyctbgui/pyctbgui/utils/defines.py b/pyctbgui/pyctbgui/utils/defines.py index 12f752274..d51f13287 100644 --- a/pyctbgui/pyctbgui/utils/defines.py +++ b/pyctbgui/pyctbgui/utils/defines.py @@ -16,6 +16,11 @@ class Defines: max_counters = 4 # max number of counters max_counters_tabIndex = 4 + class ImageType(Enum): + DIGITAL = 0 + ANALOG = 1 + TRANSCEIVER = 2 + class adc: tabIndex = 5 count = 32