Source code for gui.widget_fpas

"""
This widget contains the functionality of the fpas hardware class
provided in fpas.py. This widget is only necessary in the h-lab. The
widget can be executed as a standalone version if the fpas is connected
and the correct port is chosen. 

########################################
Functionalities provided in this widget:
########################################

1.  Save gain and trim values from FPAS to file
2.  Display the file in an editor window
3.  Upload gain and trim values to FPAS
4.  Select a Channel and readout the gain and trim values
5.  Set gain and trim values for given channel
6.  Display currently set integration delay and integration time
"""
if __name__ == "__main__":
    # Add directories to path for imports
    import os, sys, inspect

    currentdir = os.path.dirname(
        os.path.abspath(inspect.getfile(inspect.currentframe()))
    )
    parentdir = os.path.dirname(currentdir)

    sys.path.insert(0, os.path.join(currentdir, "ui_files"))
    sys.path.insert(0, parentdir)
    sys.path.insert(0, os.path.join(parentdir, "hardware_interfaces"))

# PyQt imports
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtCore import QRunnable, QThreadPool

# Import RegEx input validators
from regex_validators import *

# Import Qt Threading wrapper
from qt_multithreading_wrapper import Worker

# Import of file made from UI designer
from ui_fpas import Ui_GroupBox_fpas as Ui_fpas

from fpas import Fpas

# Logger Settings
import logging

# logging.basicConfig(level=logging.INFO)

import pprint


[docs]class WidgetFpas(QtWidgets.QGroupBox, Ui_fpas): def __init__(self, *args, obj=None, fpas=None, **kwargs): super(QtWidgets.QGroupBox, self).__init__(*args, **kwargs) self.setupUi(self) self.fpas = fpas self.default_path = r"C:\Users\I-LAB-PC\Documents\trash" self.threadpool = QThreadPool() # todo THESE ARE TEMPORARY DEFAULT VALUES self.lineEdit_fpas_integration_delay.setText("100") # in ns self.lineEdit_fpas_integration_time.setText("3014") # in ns # Setting input validators ----------------------------- # Line Edits of "FPAS" GroupBox self.lineEdit_fpas_single_channel.setValidator( positive_int_input_validator ) # Assign input validator to this lineEdit self.lineEdit_fpas_gain.setValidator(positive_int_with_0_input_validator) self.lineEdit_fpas_trim.setValidator(positive_int_with_0_input_validator) self.lineEdit_fpas_integration_time.setValidator(positive_int_input_validator) self.lineEdit_fpas_integration_delay.setValidator( positive_int_with_0_input_validator ) # ----------------------------- # Signals --------------------- self.lineEdit_fpas_single_channel.returnPressed.connect( self.update_single_channel ) self.lineEdit_fpas_gain.returnPressed.connect(self.update_single_gain) self.lineEdit_fpas_trim.returnPressed.connect(self.update_single_trim) self.lineEdit_fpas_integration_delay.returnPressed.connect( self.update_integration_time_and_delay ) self.lineEdit_fpas_integration_time.returnPressed.connect( self.update_integration_time_and_delay ) self.pushButton_fpas_upload_all.clicked.connect(self.upload_all_to_fpas) self.pushButton_fpas_save_all.clicked.connect(self.download_all_to_fpas)
[docs] def upload_all_to_fpas(self): def run(fileName): gains, trims = self.fpas.upload(fileName) self.gain_str = pprint.pformat(gains) self.trim_str = pprint.pformat(trims) self.fpas.set_trim_all(trims) self.fpas.set_gain_all(gains) fileName, _ = QFileDialog.getOpenFileName( self, "Open FPAS Gains and Trims File", self.default_path, "JSON files (*.json)", ) worker = Worker(run, fileName) # Deactivate GUI worker.signals.started.connect(lambda: self.setDisabled(True)) # Update textEdit worker.signals.finished.connect( lambda: self.plainTextEdit_fpas.insertPlainText( self.gain_str + "\n" + self.trim_str ) ) # Reactivate GUI worker.signals.finished.connect(lambda: self.setEnabled(True)) self.threadpool.start(worker)
[docs] def download_all_to_fpas(self): def run(fileName): gains = fpas.readout_channels() trims = fpas.readout_channels(gain=False) self.gain_str = pprint.pformat(gains) self.trim_str = pprint.pformat(trims) self.fpas.download(fileName, gains, trims) fileName, _ = QFileDialog.getSaveFileName( self, "Save FPAS Gains and Trims File", self.default_path, "JSON files (*.json)", ) worker = Worker(run, fileName) # Deactivate GUI worker.signals.started.connect(lambda: self.setDisabled(True)) # Update textEdit worker.signals.finished.connect( lambda: self.plainTextEdit_fpas.insertPlainText( self.gain_str + "\n" + self.trim_str ) ) # Reactivate GUI worker.signals.finished.connect(lambda: self.setEnabled(True)) self.threadpool.start(worker)
[docs] def update_single_channel(self): def run(channel): gain = self.fpas.read_gain_trim(channel, gain=True) trim = self.fpas.read_gain_trim(channel, gain=False) self.lineEdit_fpas_gain.setText(str(gain)) self.lineEdit_fpas_trim.setText(str(trim)) # If channel number is too high, set to 143 channel = int(self.lineEdit_fpas_single_channel.text()) if channel > 143: channel = 143 self.label_fpas_single_channel.setText("143") worker = Worker(run, channel) # Deactivate GUI worker.signals.started.connect(lambda: self.setDisabled(True)) # Reactivate GUI worker.signals.finished.connect(lambda: self.setEnabled(True)) self.threadpool.start(worker)
[docs] def update_single_gain(self): # function to run in multithread. Here the run function handles # every method which is called within FPAS module. Here, # specifically the setting of the gain def run(channel): # Define gain input gain = int(self.lineEdit_fpas_gain.text()) self.fpas.set_gain(channel, gain) # Read out new gain. Might be different from set gain, # because internally the fpas module checks if value is out # of bounds gain = self.fpas.read_gain_trim(channel) self.lineEdit_fpas_gain.setText(str(gain)) # If no channel was specified do nothing if not self.lineEdit_fpas_single_channel.text(): return # Define channel and if channel number is too high, set to 143 channel = int(self.lineEdit_fpas_single_channel.text()) if channel > 143: channel = 143 self.label_fpas_single_channel.setText("143") worker = Worker(run, channel) # Deactivate GUI worker.signals.started.connect(lambda: self.setDisabled(True)) # Reactivate GUI worker.signals.finished.connect(lambda: self.setEnabled(True)) self.threadpool.start(worker)
[docs] def update_single_trim(self): # function to run in multithread. Here the run function handles # every method which is called within FPAS module. Here, # specifically the setting of the trim def run(channel): # Define trim input trim = int(self.lineEdit_fpas_trim.text()) self.fpas.set_trim(channel, trim) # Read out new trim. Might be different from set trim, # because internally the fpas module checks if value is out # of bounds trim = self.fpas.read_gain_trim(channel, gain=False) self.lineEdit_fpas_trim.setText(str(trim)) # If no channel was specified do nothing if not self.lineEdit_fpas_single_channel.text(): return # Define channel and if channel number is too high, set to 143 channel = int(self.lineEdit_fpas_single_channel.text()) if channel > 143: channel = 143 self.label_fpas_single_channel.setText("143") worker = Worker(run, channel) # Deactivate GUI worker.signals.started.connect(lambda: self.setDisabled(True)) # Reactivate GUI worker.signals.finished.connect(lambda: self.setEnabled(True)) self.threadpool.start(worker)
[docs] def update_integration_time_and_delay(self): def run(): integration_time = int(self.lineEdit_fpas_integration_time.text()) integration_delay = int(self.lineEdit_fpas_integration_delay.text()) self.fpas.set_delay_and_integration_time( integration_time, integration_delay ) # If either lineEdits are empty the values can not be set if not self.lineEdit_fpas_integration_time.text(): return elif not self.lineEdit_fpas_integration_delay.text(): return else: worker = Worker(run) # Deactivate GUI worker.signals.started.connect(lambda: self.setDisabled(True)) # Reactivate GUI worker.signals.finished.connect(lambda: self.setEnabled(True)) self.threadpool.start(worker)
if __name__ == "__main__": # TESTING ----------------------------------------------------------- class MainWindow(QtWidgets.QMainWindow): def __init__(self, fpas, *args, obj=None, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.setWindowTitle("Please god let this work") fpas_widget = WidgetFpas(fpas=fpas) self.setCentralWidget(fpas_widget) app = QtWidgets.QApplication(sys.argv) with Fpas("COM2") as fpas: window = MainWindow(fpas) window.show() app.exec_()