Source code for gui.widget_delay_file_editor

""" 
This widget contains the functionality of a simple delay file editor.
The widget can be executed as a standalone version.

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

1.  Loading and saving of delay files from/in txt format
2.  Provides text editor panel which can be modified by the user.
3.  Clearing of editor panel.
4.  Generating of delay file by setting the start point (fs), end point
    (fs), number of time points, the spacing of time points (fs)
5.  An additional post-offset (fs) can be applied to the already
    generated delay file.
6.  It is possible to set a -4000 fs reference point
7.  The spacing can be done linearly or logarithmically
"""
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)
# todo  How should default file path be handled?
# todo  weights could be adjusted automatically, given
# todo  an estimated decay constant

import sys

# PyQt imports
from PyQt5 import QtWidgets, QtGui

# Import of file made from UI designer
from ui_delayfile import Ui_Widget_delayfile as Ui_delayfile

import numpy as np


[docs]class WidgetDFE(QtWidgets.QWidget, Ui_delayfile): # Delay File Editor def __init__(self, *args, **kwargs): super(QtWidgets.QWidget, self).__init__(*args, **kwargs) self.setupUi(self) self.pushButton_open_delay_file.clicked.connect(self.open_delay_file_dialog) self.pushButton_save_delay_file.clicked.connect(self.save_delay_file_dialog) self.pushButton_generate_delay_list.clicked.connect(self.generate_delay_list) self.pushButton_clear_delay_list.clicked.connect(self.clear_delay_list) self.pushButton_apply_poffset.clicked.connect(self.apply_poffset) self.lineEdit_spacing_delay.editingFinished.connect(self.fill_steps_delay) self.lineEdit_steps_delay.editingFinished.connect(self.fill_spacing_delay) self.lineEdit_steps_delay.textChanged.connect(self.fill_spacing_delay) self.lineEdit_start_delay.textChanged.connect(self.fill_spacing_delay) self.lineEdit_end_delay.textChanged.connect(self.fill_spacing_delay) self.filepath = "."
[docs] def set_default_paths(self, hw): """ Add defaults paths from hardware config file. Args: hw (object): Hardware properties object that holds all the relevant paths. """ self.filepath = hw.paths.ir_delay_file
[docs] def open_delay_file_dialog(self): fname = QtWidgets.QFileDialog.getOpenFileName( self, "Open delay file", self.filepath, "Text files (*.txt);;All files (*)" ) if fname[0]: f = open(fname[0], "r") with f: data = f.read() self.plainTextEdit_delay_list.setPlainText(data)
[docs] def save_delay_file_dialog(self): options = QtWidgets.QFileDialog.Options() # options |= QFileDialog.DontUseNativeDialog fileName, _ = QtWidgets.QFileDialog.getSaveFileName( self, "Save delay file", self.filepath, "Text Files (*.txt);;All Files (*)", options=options, ) if fileName != "": f = open(fileName, "w") text = self.plainTextEdit_delay_list.toPlainText() f.write(text) f.close()
[docs] def fill_spacing_delay(self): """ Spacing and Steps depend on each other. This function calculates the delay for a given spacing. """ try: delay_start = int(self.lineEdit_start_delay.text()) delay_end = int(self.lineEdit_end_delay.text()) delay_steps = abs(int(self.lineEdit_steps_delay.text())) self.lineEdit_spacing_delay.setText( "{:.2f}".format((delay_end - delay_start) / (delay_steps - 1)) ) except: return
[docs] def fill_steps_delay(self): """ Spacing and Steps depend on each other. This function calculates the spacing for a given delay. """ try: delay_start = int(self.lineEdit_start_delay.text()) delay_end = int(self.lineEdit_end_delay.text()) delay_spacing = abs(float(self.lineEdit_spacing_delay.text())) self.lineEdit_steps_delay.setText( str(int((delay_end - delay_start) / delay_spacing + 1.5)) ) except: return
[docs] def generate_delay_list(self): delay_list = [] if self.checkBox_first_delay_negative.isChecked(): delay_list.append("-40000\t1\n") self.checkBox_first_delay_negative.setChecked(False) try: delay_start = float(self.lineEdit_start_delay.text()) delay_end = float(self.lineEdit_end_delay.text()) delay_steps = abs(int(self.lineEdit_steps_delay.text())) except ValueError: delay_list.insert(0, "Check your numbers! Defaults used.\n\n") delay_start = 100 delay_end = 10000 delay_steps = 10 if self.radioButton_lin_delay_spacing.isChecked(): delays = np.linspace(delay_start, delay_end, delay_steps) else: if delay_start <= 0 or delay_end < 0: delay_list = ["Only positive numbers for log scale!\n"] delays = [] else: delays = np.geomspace(delay_start, delay_end, delay_steps) delay_list.extend([str(int(item)) + "\t1\n" for item in delays]) self.plainTextEdit_delay_list.insertPlainText("".join(delay_list))
[docs] def clear_delay_list(self): self.plainTextEdit_delay_list.clear()
# self.checkBox_first_delay_negative.setChecked(True)
[docs] def apply_poffset(self): """ Reads the text field and adds the given offset to the first item in each line if it is a number """ # get text and break it into lines text = self.plainTextEdit_delay_list.toPlainText().split("\n") # required for proper handling of the last line if text[-1] == "": text = text[:-1] # re-insert linebreaks text = [line + "\n" for line in text] # get offset from input field, default to zero try: poffset = float(self.lineEdit_poffset.text()) except: poffset = 0 # scan lines, add offset if first item is a number newtext = [] for line in text: if line == "\n": newtext.append(line) continue try: firstitem = line.split()[0] delay = float(firstitem) except: newtext.append(line) continue rest = line[len(firstitem) :] newdelay = delay + poffset newtext.append(str(newdelay) + rest) self.plainTextEdit_delay_list.clear() self.plainTextEdit_delay_list.insertPlainText("".join(newtext))
if __name__ == "__main__": # TESTING ----------------------------------------------------------- class MainWindow(QtWidgets.QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.setWindowTitle("Delay file editor") widget = WidgetDFE() self.setCentralWidget(widget) app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() app.exec()