This commit is contained in:
2023-07-17 09:54:41 +02:00
parent 2105ba8e7d
commit 64570f55c8
4 changed files with 477 additions and 227 deletions

196
base.py
View File

@@ -25,6 +25,8 @@ from qtpy.QtWidgets import (QAction, QApplication, QDialog, QFrame, QLabel,
QProgressBar, QScrollArea, QSizePolicy,
QSplashScreen, QVBoxLayout, QWidget)
from pyqtacc.bdbase.utils import _line
from pyqtacc.bdbase.enumkind import Facility, MsgSeverity, UserMode
from pyqtacc.bdbase.helpbrowser import HelpBrowser
from pyqtacc.bdbase.readjson import ReadJSON
@@ -36,6 +38,7 @@ from pyqtacc.bdbase.sendelog import QSendToELOG
from pyqtacc.bdbase.screenshot import QScreenshot
from pyqtacc.bdbase.guiframe import GUIFrame
from caqtwidgets.pvwidgets import QNoDockWidget
import PyCafe
@@ -45,18 +48,18 @@ _appname, _appext = _pymodule.split(".")
_appversion = "1.0.0"
_author = "J. Chrin"
PROGRESS_BAR_THREAD_INIT = 0
PROGRESS_BAR_THREAD_START = 1
PROGRESS_BAR_THREAD_ABORTING = 2
PROGRESS_BAR_THREAD_ABORTED = 3
PROGRESS_BAR_THREAD_ERROR = 4
PROGRESS_BAR_THREAD_END = 100
PROGRESS_THREAD_INIT = 0
PROGRESS_THREAD_START = 1
PROGRESS_THREAD_ABORTING = 2
PROGRESS_THREAD_ABORTED = 3
PROGRESS_THREAD_ERROR = 4
PROGRESS_THREAD_END = 100
CENTRAL_WIDGET_MINIMUM_HEIGHT = 840
CENTRAL_WIDGET_MINIMUM_WIDTH = 1240
SLS_CENTRAL_WIDGET_MINIMUM_HEIGHT = 840
SLS_CENTRAL_WIDGET_MINIMUM_WIDTH = 940
'''
def _line():
"""Macro to return the current line number.
@@ -67,7 +70,7 @@ def _line():
int: Current line number.
"""
return inspect.currentframe().f_back.f_lineno
'''
class BaseWindow(QMainWindow):
""" BaseWindow
@@ -91,14 +94,15 @@ class BaseWindow(QMainWindow):
self.reanalysis_time = reanalysis_time
self.all_data = self.parent.all_data
#def __del__(self):
# self.wait()
def __del__(self):
self.wait()
def run(self):
attach_files = []
folder_name = self.folder_name
print("Running SaveFigureThread, folder_name=", folder_name, flush=True)
print("Running SaveFigureThread, folder_name=", folder_name,
flush=True)
date_str = self.parent.add_date_to_path(
time_in_seconds=self.time_in_seconds,
@@ -153,7 +157,7 @@ class BaseWindow(QMainWindow):
print("All files attached", flush=True)
else:
print("No files to attach", flush=True)
time.sleep(0.2) #avoid race condition
time.sleep(0.1) #avoid race condition
class HDFSave(QThread):
"""Thread for hdf analysis
@@ -171,23 +175,28 @@ class BaseWindow(QMainWindow):
"""Run hdf thread
"""
QApplication.processEvents(QEventLoop.ExcludeUserInputEvents, 5000)
self.all_data = self.parent.all_data
#Reanalysis data
if self.all_data is not None:
ts_in_seconds = self.all_data['Ambient data']['Time in seconds']
now_in_seconds = self.all_data['Processed data'][
'Reanalysis time in seconds'] if \
self.all_data['Processed data']['Reanalysis time'] else None
now_in_seconds = None
from_hdf = False
if 'Reanalysis time in seconds' in self.all_data['Processed data']:
from_hdf = bool(self.all_data['Processed data']['Reanalysis time'])
if from_hdf:
now_in_seconds = self.all_data['Processed data'][
'Reanalysis time in seconds']
from_hdf = bool(
self.all_data['Processed data']['Reanalysis time'])
#print("Parent Thread before ==>", self.parent.hdf_filename)
if self.parent.hdf_filename is None or not self.from_dialog:
self.parent.set_new_hdf_filename(ts_in_seconds,
now_in_seconds)
#else:
# self.parent.set_new_hdf_filename(ts_in_seconds,
# now_in_seconds)
@@ -204,9 +213,11 @@ class BaseWindow(QMainWindow):
self.parent.add_pvs_to_hdf(
dataH5, pv_list=self.parent.pv_machine_list,
from_hdf=from_hdf)
self.parent.add_general_to_hdf(dataH5)
self.parent.add_to_hdf(dataH5, proc=True, raw=True)
self.parent.hdf_save_completed = True
_mess = "Processed data saved to {}".format(
@@ -240,12 +251,31 @@ class BaseWindow(QMainWindow):
"""Run hdf thread
"""
if not hasattr(self.analysis_procedure, 'load_hdf_file'):
mess = ("Analysis not configured for HDF analysis! " +
"Missing method: load_hdf_file")
self.parent.trigger_log_message.emit(
MsgSeverity.ERROR.name,_pymodule, _line(), mess, {})
self.parent.trigger_progressbar.emit(PROGRESS_THREAD_END)
return
self.all_data = self.analysis_procedure.load_hdf_file(
self.hdf_filename_loaded)
if not self.all_data:
self.parent.trigger_progressbar.emit(PROGRESS_THREAD_END)
return
if not hasattr(self.analysis_procedure, 'reanalyze'):
mess = ("Analysis not configured for HDF analysis! " +
"Missing method: reanalyze")
self.parent.trigger_log_message.emit(
MsgSeverity.ERROR.name, _pymodule, _line(), mess, {})
self.parent.trigger_progressbar.emit(PROGRESS_THREAD_END)
return
try:
expt_dict = self.all_data['experiment']
except KeyError:
@@ -283,11 +313,16 @@ class BaseWindow(QMainWindow):
"""
trigger_thread_event = Signal(dict)
def __init__(self, parent, analysis_procedure, input_parameters):
def __init__(self, parent, analysis_procedure, input_parameters,
messages: dict={
"success": "Analysis completed", "fail":
"No data returned from analysis procedure"}):
QThread.__init__(self)
self.parent = parent
self.analysis_procedure = analysis_procedure
self.input_parameters = input_parameters
self.messages = messages
try:
if input_parameters['debug']:
print("AnalysisThread", self.input_parameters)
@@ -300,7 +335,6 @@ class BaseWindow(QMainWindow):
def run(self):
"""Run thread
"""
all_dict = self.analysis_procedure.measure_and_analyze(
self.input_parameters)
@@ -308,12 +342,11 @@ class BaseWindow(QMainWindow):
# Emit results
if all_dict:
self.trigger_thread_event.emit(all_dict)
mess = "Analysis completed"
mess = self.messages['success']
self.parent.trigger_log_message.emit(
MsgSeverity.INFO.name, _pymodule, _line(), mess, {})
else:
mess = "No data returned from analysis procedure."
mess = self.messages['fail']
self.parent.trigger_log_message.emit(
MsgSeverity.WARN.name, _pymodule, _line(), mess, {})
@@ -454,7 +487,7 @@ class BaseWindow(QMainWindow):
self.analysis_procedure = AnalysisProcedure(self)
except ImportError as e:
print(("Base class without user supplied AnalysisProcedure class."
+ " mport Error:"), e)
+ " import Error:"), e)
##self.trigger_elog_entry.connect(self.receive_elog_notification)
##self.trigger_hdf_save.connect(self.save_to_hdf)
@@ -844,14 +877,15 @@ class BaseWindow(QMainWindow):
return False
if self.daq_analysis_completed and not self.hdf_save_completed:
if not self.all_data['Processed data']['Reanalysis time']:
_mess = ("Are you sure you wish to exit " +
"without saving data to HDF?")
qm = QMessageBox()
reply = qm.warning(self, "Exit", _mess,
QMessageBox.Yes | QMessageBox.No)
if reply == QMessageBox.No:
return False
if 'Reanalysis time' in self.all_data['Processed data']:
if not self.all_data['Processed data']['Reanalysis time']:
_mess = ("Are you sure you wish to exit " +
"without saving data to HDF?")
qm = QMessageBox()
reply = qm.warning(self, "Exit", _mess,
QMessageBox.Yes | QMessageBox.No)
if reply == QMessageBox.No:
return False
return True
@Slot()
@@ -1038,9 +1072,11 @@ class BaseWindow(QMainWindow):
return True
def add_to_hdf(self): # dataH5=None, proc=True, raw=False):
""" Abstract method to be overwritten by user
def add_to_hdf(self, dataH5=None, proc=True, raw=False):
""" Abstract method to be overwritten by user. Optional.
"""
return
'''
QM = QMessageBox()
QM.setText(
str(NotImplementedError("add_to_hdf method has not been " +
@@ -1049,6 +1085,7 @@ class BaseWindow(QMainWindow):
"icon from the application/config file."))
)
QM.exec()
'''
@Slot()
def save_to_hdf(self):
@@ -1180,9 +1217,11 @@ class BaseWindow(QMainWindow):
#input_options['Comment'] = 'Please enter a comment'
if self.all_data is not None:
ts_in_seconds = self.all_data['Ambient data']['Time in seconds']
now_in_seconds = self.all_data['Processed data'][
'Reanalysis time in seconds'] if \
self.all_data['Processed data']['Reanalysis time'] else None
now_in_seconds = None
if 'Reanalysis time in seconds' in self.all_data['Processed data']:
if self.all_data['Processed data']['Reanalysis time']:
now_in_seconds = self.all_data['Processed data'][
'Reanalysis time in seconds']
self.set_new_hdf_filename(ts_in_seconds, now_in_seconds)
input_options['Destination'] = self.hdf_filename
@@ -1356,9 +1395,10 @@ class BaseWindow(QMainWindow):
"""
if self.all_data:
#Data from hdf analysis - do not save to epics
if self.all_data['Processed data']['Reanalysis time']:
print("HDF RUN - data not written to epics")
return False
if 'Reanalysis time' in self.all_data['Processed data']:
if self.all_data['Processed data']['Reanalysis time']:
print("HDF RUN - data not written to epics")
return False
if self.all_data['Input data']['simulation']:
return False
else:
@@ -1565,8 +1605,8 @@ class BaseWindow(QMainWindow):
self.progressbar_abort = "abort"
self.progressbar_color = self.progressbar_standard
self.progressbar.setObjectName(self.progressbar_color)
self.progressbar.setRange(PROGRESS_BAR_THREAD_START,
PROGRESS_BAR_THREAD_END)
self.progressbar.setRange(PROGRESS_THREAD_START,
PROGRESS_THREAD_END)
self.progressbar.setTextVisible(True)
self.progressbar.setAlignment(Qt.AlignCenter)
self.progressbar.setVisible(False)
@@ -1638,7 +1678,7 @@ class BaseWindow(QMainWindow):
_mess, QMessageBox.Ok)
return
self.hdf_thread_started()
#self.hdf_thread_started()
self.statusbar.showMessage("Loading {0}".format(
self.hdf_filename_loaded))
self.trigger_progressbar_str.emit(
@@ -1728,7 +1768,7 @@ class BaseWindow(QMainWindow):
"""
self.gui_frame.in_hdf_measurement_procedure()
QApplication.processEvents()
#print("Thread Started")
@Slot()
def hdf_thread_finished(self):
@@ -1742,8 +1782,9 @@ class BaseWindow(QMainWindow):
@Slot(dict)
def receive_analysis_results(self, all_dict):
self.all_data = all_dict
self.gui_frame.canvas_update(all_dict['Figure data'])
self.gui_frame.canvas_update(all_dict['Figure data'])
if self.gui_frame.results_output_wgt_dict:
#all_dict['Processed data']['Results']={}
#all_dict['Processed data']['Results']['mean'] = 123.23
@@ -1753,9 +1794,48 @@ class BaseWindow(QMainWindow):
self.gui_frame.send_to_results_output_wgt(results_data)
except:
pass
#print("IDX+++", self.gui_frame.central_tab_widget.indexOf('Emittance'), flush=True)
#print("IDX+++", self.gui_frame.level2_tab_wgt[0].indexOf('Plots'))
#self.gui_frame.central_tab_widget.setCurrentIndex(1)
self.gui_frame.central_tab_widget.setCurrentIndex(1)
self.gui_frame.results_tab_wgt.setCurrentIndex(0)
self.gui_frame.results_tab_wgt.setCurrentIndex(0)
if "GUITree" in self.settings.data:
#for j in range(len(self.gui_frame.level1_tab_wgt)):
j = self.gui_frame.central_tab_widget.currentIndex()
for i in range(self.gui_frame.level1_tab_wgt[j].count()):
print(j, i, self.gui_frame.level1_tab_wgt[j].tabText(i), flush=True)
if self.gui_frame.level1_tab_wgt[j].tabText(i) == "Plots":
self.gui_frame.level1_tab_wgt[j].setCurrentIndex(i)
else:
pass
else:
for i in range(self.gui_frame.central_tab_widget.count()):
print(i, self.gui_frame.central_tab_widget.tabText(i), flush=True)
if self.gui_frame.central_tab_widget.tabText(i) == "Plots":
self.gui_frame.central_tab_widget.setCurrentIndex(i)
else:
pass
for i in range(self.gui_frame.measurement_tab_wgt.count()):
print(i, self.gui_frame.measurement_tab_wgt.tabText(i), flush=True)
if self.gui_frame.measurement_tab_wgt.tabText(i) == "Plots":
self.gui_frame.measurement_tab_wgt.setCurrentIndex(i)
else:
pass
for i in range(self.gui_frame.results_tab_wgt.count()):
print(i, self.gui_frame.results_tab_wgt.tabText(i), flush=True)
if self.gui_frame.results_tab_wgt.tabText(i) == "Plots":
self.gui_frame.results_tab_wgt.setCurrentIndex(i)
else:
pass
print("receive_analysis_results=========================>", flush=True)
@Slot()
def receive_abort_analysis(self):
@@ -1766,7 +1846,7 @@ class BaseWindow(QMainWindow):
self.gui_frame.in_abort_procedure()
# Trigger abort signal to the analysis thread
self.analysis_procedure.trigger_abort.emit()
#self.trigger_progressbar.emit(PROGRESS_BAR_THREAD_ABORTING)
#self.trigger_progressbar.emit(PROGRESS_THREAD_ABORTING)
QApplication.processEvents()
@@ -1789,19 +1869,19 @@ class BaseWindow(QMainWindow):
except KeyError:
pass
if value == PROGRESS_BAR_THREAD_INIT:
if value == PROGRESS_THREAD_INIT:
self.progressbar.setVisible(False)
self.progressbar.setFormat("")
self.progressbar.reset()
self.progressbar.setObjectName(self.progressbar_color)
self.statusbar.clearMessage()
elif value == PROGRESS_BAR_THREAD_START:
elif value == PROGRESS_THREAD_START:
self.statusbar.clearMessage()
self.progressbar.setFormat("Measurement started")
self.progressbar.setValue(value)
self.progressbar.setObjectName(self.progressbar_color)
self.daq_analysis_completed = False
elif value == PROGRESS_BAR_THREAD_ABORTING:
elif value == PROGRESS_THREAD_ABORTING:
self.progressbar.setFormat(
"Aborting procedure at the next available break point")
self.progressbar.setObjectName(self.progressbar_abort)
@@ -1814,7 +1894,7 @@ class BaseWindow(QMainWindow):
self.show_log_message(
MsgSeverity.WARN.name, _pymodule, _line(), mess)
#self.statusbar.showMessage(mess)
elif value == PROGRESS_BAR_THREAD_ABORTED:
elif value == PROGRESS_THREAD_ABORTED:
self.progressbar.setFormat("Procedure aborted")
self.progressbar.setObjectName(self.progressbar_abort)
mess = "Measurement procedure aborted"
@@ -1823,15 +1903,15 @@ class BaseWindow(QMainWindow):
self.statusbar.showMessage(mess)
self.daq_analysis_completed = False
QTimer.singleShot(2000, lambda: self.trigger_progressbar.emit(
PROGRESS_BAR_THREAD_INIT))
elif value == PROGRESS_BAR_THREAD_ERROR:
PROGRESS_THREAD_INIT))
elif value == PROGRESS_THREAD_ERROR:
mess = "Error in Thread. No data returned! See Log window"
self.progressbar.setFormat(mess)
self.progressbar.setObjectName(self.progressbar_abort)
self.statusbar.showMessage(mess)
QTimer.singleShot(10000, lambda: self.trigger_progressbar.emit(
PROGRESS_BAR_THREAD_INIT))
elif value == PROGRESS_BAR_THREAD_END:
PROGRESS_THREAD_INIT))
elif value == PROGRESS_THREAD_END:
self.progressbar.setFormat("Measurement completed")
self.progressbar.setValue(value)
self.progressbar.setObjectName(self.progressbar_color)

View File

@@ -25,7 +25,6 @@ from caqtwidgets.pvwidgets import (
from apps4ops.bdbase.enumkind import Facility, MsgSeverity, UserMode
_pymodule = os.path.basename(__file__)
_appversion = "1.0.0"
@@ -75,6 +74,7 @@ class GUIFrame(QWidget):
self.all_expert_labels = parent.all_expert_labels
self.results_output_wgt_dict = {}
self.results_output_wgt_dict_2 = {}
try:
self.widget_height = self.settings.data["StyleGuide"][
@@ -128,8 +128,17 @@ class GUIFrame(QWidget):
self.results_wgt = QWidget()
self.results_layout = QHBoxLayout(self.results_wgt)
self.results_tab_wgt = QTabWidget(self.results_wgt)
self.results_wgt_2 = QWidget()
self.results_layout_2 = QHBoxLayout(self.results_wgt_2)
self.results_tab_wgt_2 = QTabWidget(self.results_wgt_2)
self.slicing_group = QGroupBox("Screen: Slicing")
self.good_region_group = QGroupBox("Good Region")
self.canvas_fig_dict = {}
self.canvas_fig_dict_2 = {}
self.left_arrow_dict = {}
self.right_arrow_dict = {}
@@ -162,6 +171,30 @@ class GUIFrame(QWidget):
self.init_results_tab_wgt()
if "GUI2" in self.settings.data:
if "subResultsTabTitle" in self.settings.data["GUI2"]:
self.results_tab_wgt_titles_2 = self.settings.data[
"GUI2"]["subResultsTabTitle"]
self.sub_results_wgt_2 = [None] * len(self.results_tab_wgt_titles_2)
self.sub_results_layout_2 = [None] * len(self.results_tab_wgt_titles_2)
for i in range(0, len(self.results_tab_wgt_titles_2)):
self.sub_results_wgt_2[i] = QWidget() #self.results_tab_wgt_2)
self.canvas_2 = [None] * len(self.results_tab_wgt_titles_2)
self.nav_2 = [None] * len(self.results_tab_wgt_titles_2)
self.arrow_button_widget_2 = [None] * len(self.results_tab_wgt_titles_2)
self.canvas_current_idx_2 = [0] * len(self.results_tab_wgt_titles_2)
self.init_results_tab_wgt_2()
self.slice_orientation = "vertical" #horizontal/vertical for SATMA02
self.init_measurement_tab_wgt()
@@ -191,22 +224,39 @@ class GUIFrame(QWidget):
_margin = 4
destination_index = []
try:
idx = self.settings.data["GUI"]["destinationTreeIndex"]
destination_index.append(idx)
except KeyError:
pass
try:
idx = self.settings.data["GUI2"]["destinationTreeIndex"]
destination_index.append(idx)
except KeyError:
pass
def is_destination(a, b, c):
for item in destination_index:
if len(item) != 3:
continue
if item[0] == a and item[1] == b and item[2] == c:
return True
return False
if "GUITree" in self.settings.data:
key_list = list(self.settings.data["GUITree"].keys())
self.level1_wgt = [None] * len(key_list)
self.level1_tab_wgt = [None] * len(key_list)
self.level2_wgt = {}
self.level2_tab_wgt = {}
self.level3_wgt = {}
self.level3_tab_wgt = {}
qw7 = {}
qw7_tab = {}
#qwgt2 = {}
#qwgt2_tab = {}
for i, title in enumerate(key_list):
print(i, title, flush=True)
self.level1_wgt[i] = QWidget()
self.level1_wgt[i].title = title
@@ -214,35 +264,29 @@ class GUIFrame(QWidget):
self.level1_tab_wgt[i].setMinimumWidth(480)
self.level1_tab_wgt[i].setFont(self.font_gui)
#layout = QGridLayout() #self.level1_wgt[i])
#layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
#layout.setSpacing(50)
#layout.setContentsMargins(9,9,9,9)
#layout.addWidget(self.level1_wgt[i])
#self.central_tab_widget.addTab(self.level1_wgt[i], title)
key_list2 = list(self.settings.data["GUITree"][title])
self.level2_wgt[i] = [None] * len(key_list2)
self.level2_tab_wgt[i] = [None] * len(key_list2)
qw7[i] = [None] * len(key_list2)
qw7_tab[i] = [None] * len(key_list2)
#qwgt2[i] = [None] * len(key_list2)
#qwgt2_tab[i] = [None] * len(key_list2)
self.level3_wgt[i] = [None] * len(key_list2)
self.level3_tab_wgt[i] = [None] * len(key_list2)
for j, title2 in enumerate(key_list2):
print(j, title2, flush=True)
key_list3 = (self.settings.data["GUITree"][title][title2])
is_plot = False
if isinstance(key_list3, list):
#if "Plots" in key_list3:
# is_plot = True
len_key_list3 = len(key_list3)
self.level3_wgt[i][j] = [None] * len_key_list3
self.level3_tab_wgt[i][j] = [None] * len_key_list3
elif isinstance(key_list3, dict):
if 'link' in key_list3:
#get link
link = key_list3['link']
@@ -256,69 +300,82 @@ class GUIFrame(QWidget):
len_key_list3 = 0
else:
len_key_list3 = 0
else:
len_key_list3 = 0
self.level2_wgt[i][j] = QWidget() #self.level1_wgt[i])
self.level2_wgt[i][j].title2 = title2
self.level2_wgt[i][j].setFont(self.font_gui)
#layout = QGridLayout()#self.level2_wgt[i][j])
#layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
#layout.setSpacing(50)
#layout.setContentsMargins(9,9,9,9)
#layout.addWidget(self.level2_wgt[i][j])
#Attaching the correct object to QTabWidget is crucuial!
if not is_plot:
self.level2_tab_wgt[i][j] = QTabWidget(self.level2_wgt[i][j])
else:
self.level2_tab_wgt[i][j] = QTabWidget(self.results_wgt)
if i == 1:
print("///", i, j, flush=True)
self.level2_tab_wgt[i][j] = QTabWidget() #self.results_wgt_2)
else:
print("//", i, j, flush=True)
self.level2_tab_wgt[i][j] = QTabWidget() #self.results_wgt)
self.level2_tab_wgt[i][j].setMinimumWidth(480)
self.level2_tab_wgt[i][j].setFont(self.font_gui)
for k in range (0, len_key_list3):
if not is_plot:
title3 = key_list3[k]
self.level3_wgt[i][j][k] = QWidget(self.level2_wgt[i][j])
self.level3_wgt[i][j][k].title3 = title3
self.level3_wgt[i][j][k].setFont(self.font_gui)
print("tilt3", key_list3[k], flush=True)
self.level3_tab_wgt[i][j][k] = QTabWidget()
#if "Plots" in key_list3[k]:
# is_plot = True
#if not is_plot:
title3 = key_list3[k]
self.level3_wgt[i][j][k] = QWidget() #self.level2_wgt[i][j])
self.level3_wgt[i][j][k].title3 = title3
self.level3_wgt[i][j][k].setFont(self.font_gui)
#self.level3_tab_wgt[i][j][k] = QTabWidget(self.level3_wgt[i][j][k])
#self.level3_tab_wgt[i][j][k].setMinimumWidth(480)
#self.level3_tab_wgt[i][j][k].setFont(self.font_gui)
##layout3 = QGridLayout() #self.level1_wgt[i])
#layout3.addWidget(self.level3_tab_wgt[i][j][k])
##layout3.addWidget(QLabel("TEST"))
##layout3.setContentsMargins(9,9,9,9)
#self.level3_wgt[i][j][k].setLayout(layout3)
if is_destination(i, j, k):
#is_plot = True
#if i==1 and j==0 and k==1:
print("LEVEL2=============>", i, j, k, title3)
self.level2_tab_wgt[i][j].addTab(self.results_wgt_2, title3)
else:
print("LEVEL2/3=============>", i, j, k, title3)
self.level2_tab_wgt[i][j].addTab(self.level3_wgt[i][j][k], title3)
if not is_plot:
self.level1_tab_wgt[i].addTab(self.level2_wgt[i][j], title2)
else:
#if i == 1 and j==0:
# print("////", i, flush=True)
# self.level1_tab_wgt[i].addTab(self.results_wgt_2, title2)
#else:
# print("//=", i, flush=True)
self.level1_tab_wgt[i].addTab(self.results_wgt, title2)
layout2 = QGridLayout() #self.level1_wgt[i])
layout2.addWidget(self.level2_tab_wgt[i][j])
layout2.addWidget(QFrame()) #Add to stop streching of Measurement Tab
#layout2.addWidget(QLabel("TEST"))
layout2.setContentsMargins(_margin, _margin, _margin, _margin)
self.level2_wgt[i][j].setLayout(layout2)
layout = QGridLayout() #self.level1_wgt[i])
layout.addWidget(self.level1_tab_wgt[i])
layout.addWidget(self.level1_tab_wgt[i], 1, 0, 1, 20)
self.level1_wgt[i].setLayout(layout)
layout.setContentsMargins(_margin, _margin, _margin, _margin)
self.central_tab_widget.addTab(self.level1_wgt[i], title)
#***How to get to the widgets within the lowest level tabs***
#lo = QHBoxLayout()
#lo.addWidget(QLabel('TEST'))
#self.gui_frame.level2_tab_wgt[1][0].widget(0).setLayout(lo)
#self.gui_frame.level3_wgt[1][0][0].setLayout(lo)
#if "GUI" in self.settings.data:
#self.central_tab_widget.addTab(
@@ -326,8 +383,6 @@ class GUIFrame(QWidget):
## self.results_wgt, self.settings.data["GUI"]["resultsTabTitle"])
self.central_tab_widget.addTab(self.log_wgt, "Log")
self.operator_wgt = self.level3_wgt[0][0][0]
self.expert_wgt = self.level3_wgt[0][0][1]
self.measurement_tab_wgt = self.level2_tab_wgt[0][0]
@@ -351,7 +406,6 @@ class GUIFrame(QWidget):
def init_measurement_tab_wgt(self):
""" Add tabs to measurement widget
"""
self.measurement_tab_wgt.setFont(self.font_gui)
self.measurement_tab_wgt.addTab(self.operator_wgt, "Operator")
self.measurement_tab_wgt.addTab(self.expert_wgt, "Expert")
@@ -361,10 +415,8 @@ class GUIFrame(QWidget):
""" Add canvas tabs for plots/results
"""
self.results_tab_wgt.setFont(self.font_gui)
for i, (wgt, subtitle) in enumerate(zip(self.sub_results_wgt,
self.results_tab_wgt_titles)):
@@ -377,13 +429,38 @@ class GUIFrame(QWidget):
wgt.setLayout(self.sub_results_layout[i])
top_layout.addWidget(wgt)
#top_layout.addWidget(QLabel("HERE"))
top_widget.setLayout(top_layout)
self.results_tab_wgt.addTab(top_widget, subtitle)
self.results_layout.addWidget(self.results_tab_wgt)
def init_results_tab_wgt_2(self):
""" Add canvas tabs for plots/results
"""
self.results_tab_wgt_2.setFont(self.font_gui)
for i, (wgt, subtitle) in enumerate(zip(self.sub_results_wgt_2,
self.results_tab_wgt_titles_2)):
top_widget = QWidget(self.results_tab_wgt_2)
top_layout = QVBoxLayout()
self.sub_results_layout_2[i] = QVBoxLayout()
if self.settings.data["GUI2"]["resultsSeq"][i] > 1:
top_layout.addWidget(self.get_arrow_button_widget(i))
wgt.setLayout(self.sub_results_layout_2[i])
top_layout.addWidget(wgt)
#top_layout.addWidget(QLabel("THERE"))
top_widget.setLayout(top_layout)
self.results_tab_wgt_2.addTab(top_widget, subtitle)
self.results_layout_2.addWidget(self.results_tab_wgt_2)
def show_log_message(self, severity=None, pymodule="", lineno=0, message="",
options=None):
@@ -565,7 +642,8 @@ class GUIFrame(QWidget):
#print("CB fired")
#print(self.input_parameters[key])
#print(self.input_parameters)
if key == "goodRegion":
self.good_region_group.setEnabled(value)
checkbox = QCheckBox(text)
checkbox.setToolTip(tip)
@@ -585,6 +663,8 @@ class GUIFrame(QWidget):
checkbox.setCheckState(checked_value)
checkbox.stateChanged.emit(checked_value)
self.line_sender_dict[key] = checkbox
return checkbox
def create_label_qdoublespinbox(self, key, label="", min_val=0, max_val=1,
@@ -617,6 +697,9 @@ class GUIFrame(QWidget):
wgt.valueChanged.connect(callback)
wgt.setValue(start_val)
wgt.valueChanged.emit(start_val)
self.line_sender_dict[key] = wgt
return lab, wgt
@@ -649,6 +732,9 @@ class GUIFrame(QWidget):
wgt.valueChanged.connect(cb)
wgt.setValue(start_val)
wgt.valueChanged.emit(start_val)
self.line_sender_dict[key] = wgt
return lab, wgt
@@ -659,8 +745,8 @@ class GUIFrame(QWidget):
def cb(new_text):
self.input_parameters[key] = new_text
print( self.input_parameters)
#print( self.input_parameters)
widget_height = 26
suggested = "WWW"
lab = QLabel(label)
@@ -688,117 +774,10 @@ class GUIFrame(QWidget):
param_width = max(fm.width(str(value_for_width)), fm.width(suggested))
wgt.setFixedWidth(param_width + 50)
self.line_sender_dict[key] = wgt
return lab, wgt
def image_parameters_group(self):
group_box = QGroupBox("Image Pipeline Expert")
box = QHBoxLayout()
box.setSpacing(10)
try:
start_val_gr = self.settings.data["Expert"]["pipeline"]["data"][
"goodRegion"]
start_val_gr = Qt.Checked if start_val_gr else Qt.Unchecked
except KeyError as ex:
start_val_gr = Qt.Unchecked
box.addWidget(self.create_checkbox(
top_key="Expert", key="goodRegion", text="Good region",
tip="Enables good region in pipeline", default_value=start_val_gr))
try:
start_val_sub = self.settings.data["Expert"]["pipeline"]["data"][
"subtractBackground"]
start_val_sub = Qt.Checked if start_val_sub else Qt.Unchecked
except KeyError as ex:
start_val_sub = Qt.Unchecked
box.addWidget(self.create_checkbox(
top_key="Expert", key="subtractBackground",
text="Subtract bkgrnd",
tip="Enables background subtraction in pipeline",
default_value=start_val_sub))
group_box.setAlignment(Qt.AlignCenter)
group_box.setObjectName("INNERCENTER")
good_region = QGroupBox("Good Region")
good_region.setObjectName("INNER")
try:
start_val_grThreshold = self.settings.data["Expert"]["pipeline"][
"data"]["grThreshold"]
except KeyError as ex:
start_val_grThreshold = 21
lab_thresh, thresh = self.create_label_qdoublespinbox(
key="grThreshold", label="Threshold:", start_val=start_val_grThreshold)
try:
start_val_grScale = self.settings.data["Expert"]["pipeline"][
"data"]["grScale"]
except KeyError as ex:
start_val_grScale = 6
lab_gfscale, gfscale = self.create_label_qspinbox(
key="grScale", label="Scale:", start_val=start_val_grScale)
layout = QGridLayout()
layout.addWidget(lab_thresh, 0, 0)
layout.addWidget(thresh, 0, 1)
layout.addWidget(lab_gfscale, 1, 0)
layout.addWidget(gfscale, 1, 1)
good_region.setLayout(layout)
slicing = QGroupBox("Slicing")
slicing.setObjectName("INNER")
try:
start_val_nslices = self.settings.data["Expert"]["pipeline"][
"data"]["slices"]
except KeyError as ex:
start_val_nslices = 21
lab_slices, slices = self.create_label_qspinbox(
key="slices", label="No. Slices:", start_val=start_val_nslices)
try:
start_val_slicing_scale = self.settings.data["Expert"]["pipeline"][
"data"]["slicingScale"]
except KeyError as ex:
start_val_slicing_scale = 5
lab_scale, scale = self.create_label_qspinbox(
key="slicingScale", label="Scale:",
start_val=start_val_slicing_scale)
try:
start_val_orientation = self.settings.data["Expert"]["pipeline"][
"data"]["orientation"]
except KeyError as ex:
start_val_orientation = "vertical"
lab_orientation, self.slice_orientation = self.create_label_qcombobox(
key="orientation", label="Orientation:",
values=["vertical", "horizontal"], start_val=start_val_orientation)
layout = QGridLayout()
layout.addWidget(lab_slices, 0, 0)
layout.addWidget(slices, 0, 1)
layout.addWidget(lab_scale, 1, 0)
layout.addWidget(scale, 1, 1)
layout.addWidget(lab_orientation, 2, 0, 1, 2, Qt.AlignBottom)
layout.addWidget(self.slice_orientation, 3, 0, 1, 2,
Qt.AlignTop | Qt.AlignRight)
slicing.setLayout(layout)
layout_top = QGridLayout()
layout_top.addLayout(box, 0, 0, 1, 2)
layout_top.addWidget(good_region, 1, 0, 1, 1,
Qt.AlignHCenter | Qt.AlignTop)
layout_top.addWidget(slicing, 1, 1, 1, 1, Qt.AlignCenter | Qt.AlignTop)
layout_top.setHorizontalSpacing(8)
group_box.setLayout(layout_top)
group_box.setFixedHeight(200)
return group_box
def create_analysis_wgt(
self, start_title="Start", start_action=None,
start_tooltip="Start measurement and analysis procedure",
@@ -1056,6 +1035,119 @@ class GUIFrame(QWidget):
return self.save_all_group_box
def image_parameters_group(self):
group_box = QGroupBox("Image Pipeline Expert")
box = QHBoxLayout()
box.setSpacing(10)
try:
start_val_gr = self.settings.data["Expert"]["pipeline"]["data"][
"goodRegion"]
start_val_gr = Qt.Checked if start_val_gr else Qt.Unchecked
except KeyError as ex:
start_val_gr = Qt.Unchecked
box.addWidget(self.create_checkbox(
top_key="Expert", key="goodRegion", text="Good region",
tip="Enables good region in pipeline", default_value=start_val_gr))
try:
start_val_sub = self.settings.data["Expert"]["pipeline"]["data"][
"subtractBackground"]
start_val_sub = Qt.Checked if start_val_sub else Qt.Unchecked
except KeyError as ex:
start_val_sub = Qt.Unchecked
box.addWidget(self.create_checkbox(
top_key="Expert", key="subtractBackground",
text="Subtract bkgrnd",
tip="Enables background subtraction in pipeline",
default_value=start_val_sub))
group_box.setAlignment(Qt.AlignCenter)
group_box.setObjectName("INNERCENTER")
self.good_region_group.setObjectName("INNER")
try:
start_val_grThreshold = self.settings.data["Expert"]["pipeline"][
"data"]["grThreshold"]
except KeyError as ex:
start_val_grThreshold = 21
lab_thresh, thresh = self.create_label_qdoublespinbox(
key="grThreshold", label="Threshold:",
start_val=start_val_grThreshold)
try:
start_val_grScale = self.settings.data["Expert"]["pipeline"][
"data"]["grScale"]
except KeyError as ex:
start_val_grScale = 6
lab_gfscale, gfscale = self.create_label_qspinbox(
key="grScale", label="Scale:", start_val=start_val_grScale)
layout = QGridLayout()
layout.addWidget(lab_thresh, 0, 0)
layout.addWidget(thresh, 0, 1)
layout.addWidget(lab_gfscale, 1, 0)
layout.addWidget(gfscale, 1, 1)
self.good_region_group.setLayout(layout)
self.slicing_group.setObjectName("INNER")
try:
start_val_nslices = self.settings.data["Expert"]["pipeline"][
"data"]["slices"]
except KeyError as ex:
start_val_nslices = 21
lab_slices, slices = self.create_label_qspinbox(
key="slices", label="No. Slices:", start_val=start_val_nslices)
try:
start_val_slicing_scale = self.settings.data["Expert"]["pipeline"][
"data"]["slicingScale"]
except KeyError as ex:
start_val_slicing_scale = 5
lab_scale, scale = self.create_label_qspinbox(
key="slicingScale", label="Scale:",
start_val=start_val_slicing_scale)
try:
start_val_orientation = self.settings.data["Expert"]["pipeline"][
"data"]["orientation"]
except KeyError as ex:
start_val_orientation = "vertical"
lab_orientation, self.slice_orientation = self.create_label_qcombobox(
key="orientation", label="Orientation:",
values=["vertical", "horizontal"], start_val=start_val_orientation)
layout = QGridLayout()
layout.addWidget(lab_slices, 0, 0)
layout.addWidget(slices, 0, 1)
layout.addWidget(lab_scale, 1, 0)
layout.addWidget(scale, 1, 1)
layout.addWidget(lab_orientation, 2, 0, 1, 2, Qt.AlignBottom)
layout.addWidget(self.slice_orientation, 3, 0, 1, 2,
Qt.AlignTop | Qt.AlignRight)
self.slicing_group.setLayout(layout)
layout_top = QGridLayout()
layout_top.addLayout(box, 0, 0, 1, 2)
layout_top.addWidget(self.good_region_group, 1, 0, 1, 1,
Qt.AlignHCenter | Qt.AlignTop)
layout_top.addWidget(self.slicing_group, 1, 1, 1, 1,
Qt.AlignCenter | Qt.AlignTop)
layout_top.setHorizontalSpacing(8)
group_box.setLayout(layout_top)
group_box.setFixedHeight(200)
return group_box
def checkbox_wgt(self, key: str = "", tooltip: str = "", object_name=None,
hline="NONE"):
def on_change(state):
@@ -1265,7 +1357,11 @@ class GUIFrame(QWidget):
for i, key in enumerate(self.multiple_figure_dict.keys()):
self.canvas_fig_dict[i] = key
print("UPDATE", flush=True)
#print(len(self.canvas), len(self.nav), len(self.sub_results_layout),
# len(self.multiple_figure_dict.keys(), flush=True))
for i, (canvas, nav, wgt, layout, key) in enumerate(
zip(self.canvas, self.nav,
self.sub_results_wgt,
@@ -1305,6 +1401,59 @@ class GUIFrame(QWidget):
self.nav[i] = None
def canvas_update_2(self, fig_data, idx=0):
#place figures in a list
self.parent.clear_screenshot()
self.multiple_figure_dict_2 = fig_data
for i, key in enumerate(self.multiple_figure_dict_2.keys()):
self.canvas_fig_dict_2[i] = key
print("UPDATE==2", flush=True)
#print(len(self.canvas), len(self.nav), len(self.sub_results_layout),
# len(self.multiple_figure_dict.keys(), flush=True))
for i, (canvas, nav, wgt, layout, key) in enumerate(
zip(self.canvas_2, self.nav_2,
self.sub_results_wgt_2,
self.sub_results_layout_2,
self.multiple_figure_dict_2.keys())):
if canvas is not None:
layout.removeWidget(canvas)
canvas.deleteLater()
if nav is not None:
nav.deleteLater()
if self.multiple_figure_dict_2[key]: #'Figure 1']:
if not isinstance(self.multiple_figure_dict_2[key], list):
temp_list = []
temp_list.append(self.multiple_figure_dict_2[key])
self.multiple_figure_dict_2[key] = temp_list
self.canvas_2[i] = FigureCanvasQTAgg(
self.multiple_figure_dict_2[key][idx])
self.sub_results_layout_2[i].addWidget(self.canvas_2[i])
self.nav_2[i] = NavigationToolbar(
self.canvas_2[i], self.sub_results_wgt_2[i],
coordinates=False)
self.nav_2[i].setMinimumWidth(400)
self.nav_2[i].setMinimumHeight(50)
#self.nav[i].setContentsMargins(0, 0, 0, 0)
self.nav_2[i].setVisible(True)
self.nav_2[i].setStyleSheet("QToolBar { border: 0px }")
self.parent.add_screenshot(
title=self.results_tab_wgt_titles_2[i], item=wgt)
else:
self.canvas_2[i] = None
self.nav_2[i] = None
def prepare_qlineread(self, line, value):
line.setObjectName("Read")
line.setFixedHeight(24)
@@ -1983,7 +2132,8 @@ class GUIFrame(QWidget):
label.setFont(self.font_pts10)
label.setContentsMargins(5, 0, 0, 0)
label.setToolTip(tooltip)
return self.input_wgt_qcombobox(label, "loggingLevel", value, irow, wgt_grid)
return self.input_wgt_qcombobox(label, "loggingLevel", value, irow,
wgt_grid)
def input_wgt_qcombobox(self, label, key, value, irow, wgt_grid):
@@ -1997,6 +2147,8 @@ class GUIFrame(QWidget):
def combo_cb(new_text):
self.input_parameters[key] = new_text
if 'loggingLevel' in key:
self.parent.logger.setLevel(new_text)
line = QComboBox()
line.clear()

View File

@@ -307,18 +307,24 @@ class QSendToELOGFrame(QDialog):
#find layout items
layout_items = []
layout_items_optional = []
print("logbook", logbook)
try:
layout_items = list(self.parent.settings.data[
"ElogBooks"][logbook]['Required'].keys())
except KeyError:
pass
print("logbook- items", layout_items)
try:
layout_items_optional = list(self.parent.settings.data[
"ElogBooks"][logbook]['Optional'].keys())
except KeyError:
pass
layout_items.extend(layout_items_optional)
print("logbook- optional", layout_items_optional)
if layout_items_optional:
layout_items.extend(layout_items_optional)
return layout_items

12
utils.py Normal file
View File

@@ -0,0 +1,12 @@
from inspect import currentframe
def _line():
"""Macro to return the current line number.
The current line number within the file is used when
reporting messages to the message logging window.
Returns:
int: Current line number.
"""
return currentframe().f_back.f_lineno