From 9ee2f54a977a1e7ef07ca83f32b2f5ac71d59562 Mon Sep 17 00:00:00 2001 From: jupfi Date: Wed, 16 Aug 2023 17:32:17 +0200 Subject: [PATCH] Implemented viewing of LUT. --- src/nqrduck_autotm/resources/autotm_widget.ui | 115 ++++++++++-------- src/nqrduck_autotm/view.py | 109 ++++++++++------- src/nqrduck_autotm/widget.py | 88 +++++++------- 3 files changed, 175 insertions(+), 137 deletions(-) diff --git a/src/nqrduck_autotm/resources/autotm_widget.ui b/src/nqrduck_autotm/resources/autotm_widget.ui index 834348d..d087852 100644 --- a/src/nqrduck_autotm/resources/autotm_widget.ui +++ b/src/nqrduck_autotm/resources/autotm_widget.ui @@ -7,7 +7,7 @@ 0 0 1280 - 745 + 777 @@ -111,7 +111,14 @@ Electrical - + + + + + Set Voltages + + + @@ -127,6 +134,16 @@ + + + + Frequency Step (MHz) + + + + + + @@ -139,15 +156,11 @@ - - + + - - - - Start Frequency (MHz) - - + + @@ -156,30 +169,6 @@ - - - - Voltage Matching - - - - - - - - - - Voltage Tuning - - - - - - - Stop Frequency (MHz) - - - @@ -187,29 +176,47 @@ - - - - - - - - - - Set Voltages - - - - - - - Frequency Step (MHz) - - - + + + + Voltage Matching + + + + + + + Stop Frequency (MHz) + + + + + + + Voltage Tuning + + + + + + + Start Frequency (MHz) + + + + + + + + + + View LUT + + + diff --git a/src/nqrduck_autotm/view.py b/src/nqrduck_autotm/view.py index b4c1a74..ae77053 100644 --- a/src/nqrduck_autotm/view.py +++ b/src/nqrduck_autotm/view.py @@ -1,5 +1,6 @@ import logging from datetime import datetime +import time from pathlib import Path from PyQt6.QtGui import QMovie from PyQt6.QtSerialPort import QSerialPort @@ -13,6 +14,8 @@ from PyQt6.QtWidgets import ( QPushButton, QDialog, QFileDialog, + QTableWidget, + QTableWidgetItem, ) from PyQt6.QtCore import pyqtSlot, Qt from nqrduck.module.module_view import ModuleView @@ -38,9 +41,7 @@ class AutoTMView(ModuleView): self._ui_form.refreshButton.clicked.connect(self.module.controller.find_devices) # Connect the available devices changed signal to the on_available_devices_changed slot - self.module.model.available_devices_changed.connect( - self.on_available_devices_changed - ) + self.module.model.available_devices_changed.connect(self.on_available_devices_changed) # Connect the serial changed signal to the on_serial_changed slot self.module.model.serial_changed.connect(self.on_serial_changed) @@ -65,6 +66,9 @@ class AutoTMView(ModuleView): ) ) + # On clicking of the viewLUTButton call the view_lut method + self._ui_form.viewLUTButton.clicked.connect(self.view_lut) + # On clicking of the setvoltagesButton call the set_voltages method self._ui_form.setvoltagesButton.clicked.connect( lambda: self.module.controller.set_voltages( @@ -73,18 +77,14 @@ class AutoTMView(ModuleView): ) # On clicking of the calibration button call the on_calibration_button_clicked method - self._ui_form.calibrationButton.clicked.connect( - self.on_calibration_button_clicked - ) + self._ui_form.calibrationButton.clicked.connect(self.on_calibration_button_clicked) # Connect the measurement finished signal to the plot_measurement slot self.module.model.measurement_finished.connect(self.plot_measurement) # Add a vertical layout to the info box self._ui_form.scrollAreaWidgetContents.setLayout(QVBoxLayout()) - self._ui_form.scrollAreaWidgetContents.layout().setAlignment( - Qt.AlignmentFlag.AlignTop - ) + self._ui_form.scrollAreaWidgetContents.layout().setAlignment(Qt.AlignmentFlag.AlignTop) self.init_plot() self.init_labels() @@ -194,8 +194,7 @@ class AutoTMView(ModuleView): # gamma_corr = [(data_point - e_00[i]) / (data_point * e11[i] - delta_e[i]) for i, data_point in enumerate(gamma)] gamma_corr = [ - (data_point - E_D[i]) / (E_S[i] * (data_point - E_D[i]) + E_t[i]) - for i, data_point in enumerate(gamma) + (data_point - E_D[i]) / (E_S[i] * (data_point - E_D[i]) + E_t[i]) for i, data_point in enumerate(gamma) ] """ fig, ax = plt.subplots() ax.plot([g.real for g in gamma_corr], [g.imag for g in gamma_corr]) @@ -205,9 +204,7 @@ class AutoTMView(ModuleView): ax.set_xlabel("Real") ax.set_ylabel("Imaginary") plt.show() """ - return_loss_db_corr = [ - -20 * cmath.log10(abs(g + 1e-12)) for g in gamma_corr - ] + return_loss_db_corr = [-20 * cmath.log10(abs(g + 1e-12)) for g in gamma_corr] magnitude_ax.plot(frequency, return_loss_db_corr, color="red") phase_ax.set_ylabel("|Phase (deg)|") @@ -240,9 +237,7 @@ class AutoTMView(ModuleView): text_label = QLabel(text) text_label.setStyleSheet("font-size: 25px;") self._ui_form.scrollAreaWidgetContents.layout().addWidget(text_label) - self._ui_form.scrollArea.verticalScrollBar().setValue( - self._ui_form.scrollArea.verticalScrollBar().maximum() - ) + self._ui_form.scrollArea.verticalScrollBar().setValue(self._ui_form.scrollArea.verticalScrollBar().maximum()) def add_error_text(self, text: str) -> None: """Adds text to the error text box. @@ -256,15 +251,19 @@ class AutoTMView(ModuleView): text_label = QLabel(text) text_label.setStyleSheet("font-size: 25px; color: red;") self._ui_form.scrollAreaWidgetContents.layout().addWidget(text_label) - self._ui_form.scrollArea.verticalScrollBar().setValue( - self._ui_form.scrollArea.verticalScrollBar().maximum() - ) + self._ui_form.scrollArea.verticalScrollBar().setValue(self._ui_form.scrollArea.verticalScrollBar().maximum()) def create_frequency_sweep_spinner_dialog(self) -> None: """Creates a frequency sweep spinner dialog.""" self.frequency_sweep_spinner = self.FrequencySweepSpinner() self.frequency_sweep_spinner.show() + def view_lut(self) -> None: + """Creates a new Dialog that shows the currently active LUT.""" + logger.debug("View LUT") + self.lut_window = self.LutWindow(self.module) + self.lut_window.show() + class FrequencySweepSpinner(QDialog): """This class implements a spinner dialog that is shown during a frequency sweep.""" @@ -285,6 +284,48 @@ class AutoTMView(ModuleView): self.spinner_movie.start() + class LutWindow(QDialog): + def __init__(self, module, parent=None): + super().__init__() + self.module = module + self.setParent(parent) + self.setWindowTitle("LUT") + + # Add vertical main layout + main_layout = QVBoxLayout() + + # Create table widget + self.table_widget = QTableWidget() + self.table_widget.setColumnCount(3) + self.table_widget.setHorizontalHeaderLabels(["Frequency (MHz)", "Tuning Voltage", "Matching Voltage"]) + LUT = self.module.model.LUT + for row, frequency in enumerate(LUT.data.keys()): + self.table_widget.insertRow(row) + self.table_widget.setItem(row, 0, QTableWidgetItem(str(frequency))) + self.table_widget.setItem(row, 1, QTableWidgetItem(str(LUT.data[frequency][0]))) + self.table_widget.setItem(row, 2, QTableWidgetItem(str(LUT.data[frequency][1]))) + + # Add table widget to main layout + main_layout.addWidget(self.table_widget) + + # Add Test LUT button + test_lut_button = QPushButton("Test LUT") + test_lut_button.clicked.connect(self.test_lut) + main_layout.addWidget(test_lut_button) + + self.setLayout(main_layout) + + def test_lut(self): + """This method is called when the Test LUT button is clicked. It sets all of the voltages from the lut with a small delay. + One can then view the matching on a seperate VNA. + """ + for frequency in self.module.model.LUT.data.keys(): + tuning_voltage = str(self.module.model.LUT.data[frequency][0]) + matching_voltage = str(self.module.model.LUT.data[frequency][1]) + self.module.controller.set_voltages(tuning_voltage, matching_voltage) + # Evil + time.sleep(0.5) + class CalibrationWindow(QWidget): def __init__(self, module, parent=None): super().__init__() @@ -317,9 +358,7 @@ class AutoTMView(ModuleView): short_layout = QVBoxLayout() short_button = QPushButton("Short") short_button.clicked.connect( - lambda: self.module.controller.on_short_calibration( - float(start_edit.text()), float(stop_edit.text()) - ) + lambda: self.module.controller.on_short_calibration(float(start_edit.text()), float(stop_edit.text())) ) # Short plot widget self.short_plot = MplWidget() @@ -331,9 +370,7 @@ class AutoTMView(ModuleView): open_layout = QVBoxLayout() open_button = QPushButton("Open") open_button.clicked.connect( - lambda: self.module.controller.on_open_calibration( - float(start_edit.text()), float(stop_edit.text()) - ) + lambda: self.module.controller.on_open_calibration(float(start_edit.text()), float(stop_edit.text())) ) # Open plot widget self.open_plot = MplWidget() @@ -345,9 +382,7 @@ class AutoTMView(ModuleView): load_layout = QVBoxLayout() load_button = QPushButton("Load") load_button.clicked.connect( - lambda: self.module.controller.on_load_calibration( - float(start_edit.text()), float(stop_edit.text()) - ) + lambda: self.module.controller.on_load_calibration(float(start_edit.text()), float(stop_edit.text())) ) # Load plot widget self.load_plot = MplWidget() @@ -375,15 +410,9 @@ class AutoTMView(ModuleView): self.setLayout(main_layout) # Connect the calibration finished signals to the on_calibration_finished slot - self.module.model.short_calibration_finished.connect( - self.on_short_calibration_finished - ) - self.module.model.open_calibration_finished.connect( - self.on_open_calibration_finished - ) - self.module.model.load_calibration_finished.connect( - self.on_load_calibration_finished - ) + self.module.model.short_calibration_finished.connect(self.on_short_calibration_finished) + self.module.model.open_calibration_finished.connect(self.on_open_calibration_finished) + self.module.model.load_calibration_finished.connect(self.on_load_calibration_finished) def on_short_calibration_finished(self, short_calibration: "S11Data") -> None: self.on_calibration_finished("short", self.short_plot, short_calibration) @@ -394,9 +423,7 @@ class AutoTMView(ModuleView): def on_load_calibration_finished(self, load_calibration: "S11Data") -> None: self.on_calibration_finished("load", self.load_plot, load_calibration) - def on_calibration_finished( - self, type: str, widget: MplWidget, data: "S11Data" - ) -> None: + def on_calibration_finished(self, type: str, widget: MplWidget, data: "S11Data") -> None: """This method is called when a calibration has finished. It plots the calibration data on the given widget. """ diff --git a/src/nqrduck_autotm/widget.py b/src/nqrduck_autotm/widget.py index 599136e..15d2975 100644 --- a/src/nqrduck_autotm/widget.py +++ b/src/nqrduck_autotm/widget.py @@ -12,7 +12,7 @@ from PyQt6 import QtCore, QtGui, QtWidgets class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") - Form.resize(1280, 745) + Form.resize(1280, 777) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -70,6 +70,9 @@ class Ui_Form(object): self.elecTab.setObjectName("elecTab") self.gridLayout_3 = QtWidgets.QGridLayout(self.elecTab) self.gridLayout_3.setObjectName("gridLayout_3") + self.setvoltagesButton = QtWidgets.QPushButton(parent=self.elecTab) + self.setvoltagesButton.setObjectName("setvoltagesButton") + self.gridLayout_3.addWidget(self.setvoltagesButton, 3, 0, 1, 2) self.stopfrequencyBox = QtWidgets.QDoubleSpinBox(parent=self.elecTab) self.stopfrequencyBox.setObjectName("stopfrequencyBox") self.gridLayout_3.addWidget(self.stopfrequencyBox, 7, 1, 1, 1) @@ -79,51 +82,51 @@ class Ui_Form(object): self.label_9.setFont(font) self.label_9.setObjectName("label_9") self.gridLayout_3.addWidget(self.label_9, 0, 0, 1, 1) + self.label_14 = QtWidgets.QLabel(parent=self.elecTab) + self.label_14.setObjectName("label_14") + self.gridLayout_3.addWidget(self.label_14, 8, 0, 1, 1) + self.startfrequencyBox = QtWidgets.QDoubleSpinBox(parent=self.elecTab) + self.startfrequencyBox.setObjectName("startfrequencyBox") + self.gridLayout_3.addWidget(self.startfrequencyBox, 6, 1, 1, 1) self.label_11 = QtWidgets.QLabel(parent=self.elecTab) font = QtGui.QFont() font.setBold(True) self.label_11.setFont(font) self.label_11.setObjectName("label_11") self.gridLayout_3.addWidget(self.label_11, 4, 0, 1, 1) - self.tuningBox = QtWidgets.QDoubleSpinBox(parent=self.elecTab) - self.tuningBox.setObjectName("tuningBox") - self.gridLayout_3.addWidget(self.tuningBox, 1, 1, 1, 1) - self.label_12 = QtWidgets.QLabel(parent=self.elecTab) - self.label_12.setObjectName("label_12") - self.gridLayout_3.addWidget(self.label_12, 6, 0, 1, 1) - self.label_4 = QtWidgets.QLabel(parent=self.elecTab) - self.label_4.setObjectName("label_4") - self.gridLayout_3.addWidget(self.label_4, 5, 0, 1, 1) - self.label_3 = QtWidgets.QLabel(parent=self.elecTab) - self.label_3.setObjectName("label_3") - self.gridLayout_3.addWidget(self.label_3, 2, 0, 1, 1) - self.matchingBox = QtWidgets.QDoubleSpinBox(parent=self.elecTab) - self.matchingBox.setObjectName("matchingBox") - self.gridLayout_3.addWidget(self.matchingBox, 2, 1, 1, 1) - self.label_2 = QtWidgets.QLabel(parent=self.elecTab) - self.label_2.setObjectName("label_2") - self.gridLayout_3.addWidget(self.label_2, 1, 0, 1, 1) - self.label_13 = QtWidgets.QLabel(parent=self.elecTab) - self.label_13.setObjectName("label_13") - self.gridLayout_3.addWidget(self.label_13, 7, 0, 1, 1) - self.generateLUTButton = QtWidgets.QPushButton(parent=self.elecTab) - self.generateLUTButton.setObjectName("generateLUTButton") - self.gridLayout_3.addWidget(self.generateLUTButton, 9, 0, 1, 2) self.resolutionBox = QtWidgets.QDoubleSpinBox(parent=self.elecTab) self.resolutionBox.setObjectName("resolutionBox") self.gridLayout_3.addWidget(self.resolutionBox, 5, 1, 1, 1) - self.startfrequencyBox = QtWidgets.QDoubleSpinBox(parent=self.elecTab) - self.startfrequencyBox.setObjectName("startfrequencyBox") - self.gridLayout_3.addWidget(self.startfrequencyBox, 6, 1, 1, 1) - self.setvoltagesButton = QtWidgets.QPushButton(parent=self.elecTab) - self.setvoltagesButton.setObjectName("setvoltagesButton") - self.gridLayout_3.addWidget(self.setvoltagesButton, 3, 0, 1, 2) - self.label_14 = QtWidgets.QLabel(parent=self.elecTab) - self.label_14.setObjectName("label_14") - self.gridLayout_3.addWidget(self.label_14, 8, 0, 1, 1) + self.matchingBox = QtWidgets.QDoubleSpinBox(parent=self.elecTab) + self.matchingBox.setObjectName("matchingBox") + self.gridLayout_3.addWidget(self.matchingBox, 2, 1, 1, 1) + self.label_4 = QtWidgets.QLabel(parent=self.elecTab) + self.label_4.setObjectName("label_4") + self.gridLayout_3.addWidget(self.label_4, 5, 0, 1, 1) + self.generateLUTButton = QtWidgets.QPushButton(parent=self.elecTab) + self.generateLUTButton.setObjectName("generateLUTButton") + self.gridLayout_3.addWidget(self.generateLUTButton, 9, 0, 1, 2) self.frequencystepBox = QtWidgets.QDoubleSpinBox(parent=self.elecTab) self.frequencystepBox.setObjectName("frequencystepBox") self.gridLayout_3.addWidget(self.frequencystepBox, 8, 1, 1, 1) + self.label_3 = QtWidgets.QLabel(parent=self.elecTab) + self.label_3.setObjectName("label_3") + self.gridLayout_3.addWidget(self.label_3, 2, 0, 1, 1) + self.label_13 = QtWidgets.QLabel(parent=self.elecTab) + self.label_13.setObjectName("label_13") + self.gridLayout_3.addWidget(self.label_13, 7, 0, 1, 1) + self.label_2 = QtWidgets.QLabel(parent=self.elecTab) + self.label_2.setObjectName("label_2") + self.gridLayout_3.addWidget(self.label_2, 1, 0, 1, 1) + self.label_12 = QtWidgets.QLabel(parent=self.elecTab) + self.label_12.setObjectName("label_12") + self.gridLayout_3.addWidget(self.label_12, 6, 0, 1, 1) + self.tuningBox = QtWidgets.QDoubleSpinBox(parent=self.elecTab) + self.tuningBox.setObjectName("tuningBox") + self.gridLayout_3.addWidget(self.tuningBox, 1, 1, 1, 1) + self.viewLUTButton = QtWidgets.QPushButton(parent=self.elecTab) + self.viewLUTButton.setObjectName("viewLUTButton") + self.gridLayout_3.addWidget(self.viewLUTButton, 10, 0, 1, 2) self.typeTab.addTab(self.elecTab, "") self.verticalLayout_2.addWidget(self.typeTab) self.titlefrequencyLabel = QtWidgets.QLabel(parent=Form) @@ -205,16 +208,17 @@ class Ui_Form(object): self.titletypeLabel.setText(_translate("Form", "T&M Type:")) self.pushButton.setText(_translate("Form", "Homing")) self.typeTab.setTabText(self.typeTab.indexOf(self.mechTab), _translate("Form", "Mechanical")) - self.label_9.setText(_translate("Form", "Set Voltages:")) - self.label_11.setText(_translate("Form", "Generate LUT:")) - self.label_12.setText(_translate("Form", "Start Frequency (MHz)")) - self.label_4.setText(_translate("Form", "Voltage Resolution")) - self.label_3.setText(_translate("Form", "Voltage Matching")) - self.label_2.setText(_translate("Form", "Voltage Tuning")) - self.label_13.setText(_translate("Form", "Stop Frequency (MHz)")) - self.generateLUTButton.setText(_translate("Form", "Start Voltage Sweep")) self.setvoltagesButton.setText(_translate("Form", "Set Voltages")) + self.label_9.setText(_translate("Form", "Set Voltages:")) self.label_14.setText(_translate("Form", "Frequency Step (MHz)")) + self.label_11.setText(_translate("Form", "Generate LUT:")) + self.label_4.setText(_translate("Form", "Voltage Resolution")) + self.generateLUTButton.setText(_translate("Form", "Start Voltage Sweep")) + self.label_3.setText(_translate("Form", "Voltage Matching")) + self.label_13.setText(_translate("Form", "Stop Frequency (MHz)")) + self.label_2.setText(_translate("Form", "Voltage Tuning")) + self.label_12.setText(_translate("Form", "Start Frequency (MHz)")) + self.viewLUTButton.setText(_translate("Form", "View LUT")) self.typeTab.setTabText(self.typeTab.indexOf(self.elecTab), _translate("Form", "Electrical")) self.titlefrequencyLabel.setText(_translate("Form", "Frequency Sweep:")) self.label_8.setText(_translate("Form", "MHz"))