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