Source code for gui.widget_readme_file_editor
"""
This widget contains the functionality of a simple readme and notes
editor. The widget can be executed as a standalone version.
########################################
Functionalities provided in this widget:
########################################
1. Provides text *viewer* panel previewing the setup info. The setup
information contains every important piece of information which can
be obtained from the hardware.
2. Provides a text *editor* panel for arbitrary notes
3. The content of both panels will be saved automatically with each
experiment - widget_main_window does that. In addition, the notes
panel can be saved to and loaded from a file of the user's choice
from within this editor widget.
"""
# 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)
expdir = os.path.join(parentdir, "experiments")
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"))
import json
import os
# PyQt imports
from PyQt5 import QtWidgets, QtGui
# Import of file made from UI designer
from ui_readmefile import Ui_Widget_readmefile as Ui_readmefile
[docs]class WidgetRFE(QtWidgets.QWidget, Ui_readmefile): # Readme File Editor
"""Readme editor widget
Inherits:
QtWidgets.QWidget
Ui_readmefile: Widget layout
"""
[docs] def __init__(self, *args, mw_obj=None, **kwargs):
"""
Init editor widget
Args:
mw_obj (MainWindow,optional): Reference to the Main Window.
This is the object where all the setup information comes
from. Defaults to None, but this defeats the purpose.
"""
super(QtWidgets.QWidget, self).__init__(*args, **kwargs)
self.setupUi(self)
self.mw_obj = mw_obj # Main window object, needed for all the juicy attributes
# Connect signals
self.pushButton_open_notes_file.clicked.connect(self.open_notes_file_dialog)
self.pushButton_save_notes_file.clicked.connect(self.save_notes_file_dialog)
self.pushButton_insert_notes_template.clicked.connect(
self.insert_notes_template
)
self.pushButton_fill_standard_fields.clicked.connect(self.fill_standard_fields)
self.pushButton_clear_all.clicked.connect(self.clear_all)
self.filepath = "."
[docs] def open_notes_file_dialog(self):
fname = QtWidgets.QFileDialog.getOpenFileName(
self,
"Open notes file",
self.filepath,
"Text files (*.txt);;Markdown files (*.md);;All files (*)",
)
if fname[0]:
f = open(fname[0], "r")
with f:
data = f.read()
self.plainTextEdit_notes.setPlainText(data)
[docs] def save_notes_file_dialog(self):
options = QtWidgets.QFileDialog.Options()
# options |= QFileDialog.DontUseNativeDialog
fileName, _ = QtWidgets.QFileDialog.getSaveFileName(
self,
"Save notes file",
self.filepath,
"Text files (*.txt);;Markdown files (*.md);;All files (*)",
options=options,
)
if fileName != "":
f = open(fileName, "w")
text = self.plainTextEdit_notes.toPlainText()
f.write(text)
f.close()
[docs] def insert_notes_template(self):
"""
Insert some standard fields at cursor position
"""
with open(os.path.join(parentdir, "notes_template.txt"), "r") as template_file:
notes_template = template_file.read()
self.plainTextEdit_notes.insertPlainText(notes_template)
[docs] def get_all_the_symbols(self):
"""
Helper function for testing
Fills the setup info panel with the symbols of the local and the
global scope.
"""
text = "GLOBALS\n\n"
for key, value in globals().items():
text += str(key) + " : " + str(value) + "\n"
text += "\nLOCALS\n\n"
for key, value in locals().items():
if key in ["text", "key", "value"]:
text += str(key) + " : ... avoiding recursion here\n"
else:
text += str(key) + " : " + str(value) + "\n"
self.plainTextEdit_setupinfo.insertPlainText(text)
[docs] def fill_standard_fields(self):
"""
Refreshes setup info panel with current information
This function can be called manually upon button press, but more
importantly this is called during the start of each experiment,
before the content of both panels (setup info and notes) is
saved to disk.
"""
self.plainTextEdit_setupinfo.clear()
text = ""
import datetime
todaydate = str(datetime.date.today())
text += "# Date\n" + todaydate + "\n\n"
if self.mw_obj is None:
text += "Failed accessing all the juicy attributes. So sad!\n\n"
self.plainTextEdit_setupinfo.insertPlainText(text)
return
try:
setup_name = self.mw_obj.hw.name
except:
setup_name = "Setup name not found"
text += "# Setup name\n" + setup_name + "\n\n"
try:
user_name = self.mw_obj.username
except:
user_name = "User name not found"
text += "# User name\n" + user_name + "\n\n"
try:
file_name = self.mw_obj.groupBox_file.lineEdit_file_save_name.text()
except:
file_name = "File name not found"
text += "# File name\n" + file_name + "\n\n"
try:
experiment = self.mw_obj.comboBox_experiments.currentText()
except:
experiment = "not found"
text += "# Experiment type: " + experiment + "\n\n"
text += "# T_zero\n"
text += "Stage position where both pulses temporally overlap in the sample. Unit in mm.\n\n"
try:
tzeros = ""
for name, stage in self.mw_obj.groupBox_pi_control.pi_stage.items():
tzeros += "Name: " + name + ": "
tzeros += str(stage.t_zero) + " mm\n"
except:
tzeros = "Zero times not found"
text += tzeros + "\n"
# ---------------------- Spectrometer ---------------------------
try:
central_wn = self.mw_obj.groupBox_triax.lineEdit_triax_wavenumber.text()
except:
central_wn = "Central wavenumber not found"
text += "# Central wavenumber\n" + central_wn + "\n\n"
try:
central_wl = self.mw_obj.groupBox_triax.lineEdit_triax_wavelength.text()
except:
central_wl = "Central wavenumber not found"
text += "# Central wavelength\n" + central_wl + "\n\n"
try:
triax_grating = self.mw_obj.groupBox_triax.lineEdit_triax_grating.text()
except:
triax_grating = "Triax grating not found"
text += "# Triax grating\n" + triax_grating + "\n\n"
try:
triax_grating_ld = (
self.mw_obj.groupBox_triax.lineEdit_triax_line_density.text()
)
except:
triax_grating_ld = "Triax grating line density not found"
text += "# Triax grating line density\n" + triax_grating_ld + "\n\n"
try:
triax_cur_turret = (
self.mw_obj.groupBox_triax.lineEdit_triax_cur_turret.text()
)
except:
triax_cur_turret = "Current Triax turret not found"
text += "# Current Triax turret\n" + triax_cur_turret + "\n\n"
try:
samples_to_acquire = (
self.mw_obj.groupBox_adc.lineEdit_adc_samples_to_acquire.text()
)
except:
samples_to_acquire = "Samples to acquire not found"
text += "# Samples to acquire\n" + samples_to_acquire + "\n\n"
# ------------------- Wavegen parameters -----------------------
text += "# Wave generation parameters\n"
try:
wg = ""
wg += (
"Coherence time (ps): "
+ str(
self.mw_obj.groupBox_pi_control.pi_stage[
"interferometer stage"
].coherence_time
)
+ "\n"
)
wg += (
"Frequency (Hz): "
+ str(
self.mw_obj.groupBox_pi_control.pi_stage[
"interferometer stage"
].approx_frequency
)
+ "\n"
)
wg += (
"Speed up/down: "
+ str(
self.mw_obj.groupBox_pi_control.pi_stage[
"interferometer stage"
].speedupdown
)
+ "\n\n"
)
except:
wg = "Parameters not found or no wave generation defined.\n\n"
text += wg
# ------------------- Data format -----------------------
text += "# Data format\n\n"
with open(os.path.join(expdir, "experiments_data_format.json")) as json_file:
data_formats = json.load(json_file)
data_format = data_formats[experiment]["programming data dimension"][0]
save_format = data_formats[experiment]["saving dimension"][0]
text += "# Programming data dimension\n"
text += "Internally used data format. Especially for the sort_data method of the data_processing class.\n"
text += (
"Details can be found in the docs of the respective experiment type.\n\n"
)
text += data_format + "\n\n"
text += "# Saving dimension\n"
text += "In general we save 4 different files for each scan, pump pixel, delay, etc.\n"
text += "In one file the data (generally transmissions) is saved according to the number of pixels in one detector array\n"
text += (
"and the number of shot to shot changing states that this experiment has.\n"
)
text += "Details can be found in the docs of the current experiment.\n\n"
text += "One file (counts) contains the number of times each state was observed for each pixel\n"
text += "One file (weights) contains the inverse variance of the transmission for each state for each pixel\n"
text += "One file (s2s_std) contains the standard deviation of the shot to shot calculated difference signal\n"
text += "The s2s_std file does not have the same dimensions as the other three files\n"
text += "The data file has the following dimensions.\n\n"
text += save_format + "\n\n"
# delays/pump pixel: self.groupBox_file.lineEdit_fp/ir/uv
self.plainTextEdit_setupinfo.insertPlainText(text)
if __name__ == "__main__":
# TESTING -----------------------------------------------------------
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setWindowTitle("Setup info and notes file editor")
widget = WidgetRFE()
self.setCentralWidget(widget)
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()