Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a1359cca84 | |||
| 25eed8079b | |||
| 5d6a74ab9d | |||
| e830a52119 | |||
| a0efa778cb | |||
| 44d9971bd8 | |||
| e3eca94b0f | |||
| 8c26ec4c15 | |||
| 7c291bcbf8 | |||
| 1f4fe75c73 | |||
| f70404c773 | |||
| fcf6b46ec0 | |||
| 6148e37df2 | |||
| 7580203c2b | |||
| 3033e07152 | |||
| 655b5c66a7 | |||
| 0f6889b54c | |||
| a6b60c30ce | |||
| 8dea32e263 | |||
| 4e701863c3 | |||
| 1fdf7013ed | |||
| 18ca4760bc | |||
| 16990824a8 | |||
| 72e4ed4f7a | |||
| 909ad9a3f3 | |||
| 2daa9ad6a7 | |||
| 2246e71e53 | |||
| 016ca6cebf | |||
| 9c3177f100 | |||
| 389a126f28 | |||
| d41bba4233 | |||
| 7a237d0d12 | |||
| 67b3c3be17 | |||
| 87df78d969 | |||
| e46f427ca2 | |||
| 64570f55c8 | |||
| 2105ba8e7d |
501
base.py
501
base.py
@@ -5,8 +5,9 @@ from collections import OrderedDict
|
||||
from datetime import datetime
|
||||
import getpass
|
||||
import h5py
|
||||
import logging
|
||||
import inspect
|
||||
import logging
|
||||
import numpy as np
|
||||
import platform
|
||||
import os
|
||||
import re
|
||||
@@ -25,6 +26,7 @@ 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
|
||||
@@ -32,7 +34,6 @@ from pyqtacc.bdbase.savehdf import QSaveHDF
|
||||
from pyqtacc.bdbase.hdf5filemenu import HDF5GroupBox
|
||||
from pyqtacc.bdbase.sendelog import QSendToELOG
|
||||
|
||||
|
||||
from pyqtacc.bdbase.screenshot import QScreenshot
|
||||
from pyqtacc.bdbase.guiframe import GUIFrame
|
||||
|
||||
@@ -45,30 +46,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.
|
||||
|
||||
The current line number within the file is used when
|
||||
reporting messages to the message logging window.
|
||||
|
||||
Returns:
|
||||
int: Current line number.
|
||||
"""
|
||||
return inspect.currentframe().f_back.f_lineno
|
||||
|
||||
|
||||
class BaseWindow(QMainWindow):
|
||||
""" BaseWindow
|
||||
"""
|
||||
@@ -90,70 +79,100 @@ class BaseWindow(QMainWindow):
|
||||
self.time_in_seconds = time_in_seconds
|
||||
self.reanalysis_time = reanalysis_time
|
||||
self.all_data = self.parent.all_data
|
||||
self.all_data_2 = self.parent.all_data_2
|
||||
|
||||
#Causes QThread::wait: Thread tried to wait on itself
|
||||
#def __del__(self):
|
||||
# self.wait()
|
||||
|
||||
def run(self):
|
||||
attach_files = []
|
||||
folder_name = self.folder_name
|
||||
|
||||
print("Running SaveFigureThread, folder_name=", folder_name, flush=True)
|
||||
|
||||
|
||||
date_str = self.parent.add_date_to_path(
|
||||
time_in_seconds=self.time_in_seconds,
|
||||
reanalysis_time_in_seconds=self.reanalysis_time)
|
||||
|
||||
#print("date_str", date_str, flush=True)
|
||||
|
||||
write_message_fired = False
|
||||
for i, (nfig, name) in enumerate(
|
||||
zip(self.settings.data["GUI"]["resultsSeq"],
|
||||
self.settings.data["GUI"]["subResultsTabTitle"])):
|
||||
def extract_and_attach(i, nfig, name, all_fig_data):
|
||||
canvas = 'Canvas {0}'.format(i+1)
|
||||
name_base = name.replace(' ', '_').lower()
|
||||
write_message_fired = False
|
||||
|
||||
if self.all_data['Figure data'][canvas] is not None:
|
||||
nfig_canvas = len(self.all_data['Figure data'][canvas])
|
||||
if all_fig_data[canvas] is not None:
|
||||
nfig_canvas = len(all_fig_data[canvas])
|
||||
nfig_canvas = min(nfig_canvas, nfig)
|
||||
else:
|
||||
nfig_canvas = nfig
|
||||
|
||||
|
||||
|
||||
for idx in range(0, nfig_canvas):
|
||||
if self.all_data['Figure data'][canvas] is not None:
|
||||
if all_fig_data[canvas] is not None:
|
||||
|
||||
name = name_base + "_{0}".format(
|
||||
idx) if idx > 0 else name_base
|
||||
save_dest = (folder_name + date_str + '_' + name +
|
||||
'.png')
|
||||
|
||||
|
||||
|
||||
if not os.path.exists(save_dest):
|
||||
if self.all_data['Figure data'][canvas][
|
||||
idx] is not None:
|
||||
if all_fig_data[canvas][idx] is not None:
|
||||
_dirname = os.path.dirname(save_dest)
|
||||
|
||||
if os.access(_dirname, os.W_OK):
|
||||
self.all_data['Figure data'][canvas][
|
||||
idx].savefig(save_dest)
|
||||
elif not write_message_fired:
|
||||
|
||||
all_fig_data[canvas][idx].savefig(save_dest)
|
||||
elif not write_message_fired:
|
||||
|
||||
_mess = ("Do not have write permission " +
|
||||
"for directory {0} from this " +
|
||||
"host {1}. Images not saved and " +
|
||||
"cannot be sent to elog").format(
|
||||
_dirname, os.uname()[1])
|
||||
|
||||
self.parent.trigger_log_message.emit(
|
||||
MsgSeverity.WARN.name, _pymodule,
|
||||
_line(), _mess, {})
|
||||
write_message_fired = True
|
||||
|
||||
attach_files.append(save_dest)
|
||||
|
||||
|
||||
if not write_message_fired:
|
||||
attach_files.append(save_dest)
|
||||
|
||||
|
||||
|
||||
|
||||
try:
|
||||
resultsSeq = self.settings.data["GUI"]["resultsSeq"]
|
||||
titleSeq = self.settings.data["GUI"]["subResultsTabTitle"]
|
||||
if self.all_data:
|
||||
fig_data = self.all_data['Figure data']
|
||||
for i, (nfig, name) in enumerate(zip(resultsSeq, titleSeq)):
|
||||
print(i, nfig, name, flush=True)
|
||||
print(fig_data, flush=True)
|
||||
extract_and_attach(i, nfig, name, fig_data)
|
||||
except KeyError as ex:
|
||||
pass
|
||||
|
||||
|
||||
try:
|
||||
resultsSeq = self.settings.data["GUI2"]["resultsSeq"]
|
||||
titleSeq = self.settings.data["GUI2"]["subResultsTabTitle"]
|
||||
if self.all_data_2:
|
||||
fig_data = self.all_data_2['Figure data']
|
||||
for i, (nfig, name) in enumerate(zip(resultsSeq, titleSeq)):
|
||||
extract_and_attach(i, nfig, name, fig_data)
|
||||
except KeyError as ex:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
#Not so nice.. send a signal instead?
|
||||
if attach_files:
|
||||
self.parent.attach_files = attach_files
|
||||
print(attach_files, flush=True)
|
||||
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
|
||||
@@ -164,57 +183,81 @@ class BaseWindow(QMainWindow):
|
||||
self.parent = parent
|
||||
self.from_dialog=from_dialog
|
||||
|
||||
def __del__(self):
|
||||
self.wait()
|
||||
#Only a precaution, not experienced
|
||||
#Causes QThread::wait: Thread tried to wait on itself
|
||||
#def __del__(self):
|
||||
# self.wait()
|
||||
|
||||
def run(self):
|
||||
"""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
|
||||
try:
|
||||
if 'Time in seconds' in self.all_data['Ambient data']:
|
||||
ts_in_seconds = self.all_data['Ambient data'][
|
||||
'Time in seconds']
|
||||
else:
|
||||
ts_in_seconds = None
|
||||
except KeyError:
|
||||
ts_in_seconds = None
|
||||
|
||||
from_hdf = bool(
|
||||
self.all_data['Processed data']['Reanalysis time'])
|
||||
now_in_seconds = None
|
||||
from_hdf = False
|
||||
|
||||
try:
|
||||
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']
|
||||
|
||||
#Double check
|
||||
if not from_hdf:
|
||||
if 'from_hdf' in self.all_data['Processed data']:
|
||||
from_hdf = bool(self.all_data['Processed data'][
|
||||
'from_hdf'])
|
||||
|
||||
except KeyError:
|
||||
now_in_seconds = None
|
||||
|
||||
self.parent.from_hdf = from_hdf
|
||||
|
||||
print("t=========================>", ts_in_seconds, " // ", now_in_seconds)
|
||||
print("from hdf5=========================>", from_hdf)
|
||||
|
||||
#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)
|
||||
#print("Parent Thread after ==>", self.parent.hdf_filename)
|
||||
|
||||
#Open hdf5file here and
|
||||
#mess = "HDF save to file {0} proceeding...".format(
|
||||
# self.parent.hdf_filename)
|
||||
#self.parent.trigger_log_message.emit(MsgSeverity.INFO.name,
|
||||
# _pymodule, _line(),
|
||||
# mess, {})
|
||||
try:
|
||||
print("FILENAME ==", self.parent.hdf_filename, flush=True)
|
||||
with h5py.File(self.parent.hdf_filename, 'w') as dataH5:
|
||||
self.parent.add_pvs_to_hdf(
|
||||
dataH5, pv_list=self.parent.pv_machine_list,
|
||||
from_hdf=from_hdf)
|
||||
|
||||
#experiment
|
||||
if not from_hdf:
|
||||
self.parent.add_pvs_to_hdf(
|
||||
dataH5, pv_list=self.parent.pv_machine_list,
|
||||
from_hdf=from_hdf)
|
||||
|
||||
#general
|
||||
#if not 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(
|
||||
self.parent.hdf_filename)
|
||||
self.parent.trigger_log_message.emit(
|
||||
MsgSeverity.INFO.name, _pymodule, _line(), _mess, {})
|
||||
MsgSeverity.INFO.name, _pymodule, _line(), _mess,
|
||||
{})
|
||||
except OSError as e:
|
||||
_mess = "OSError in saving to file {0}: {1}".format(
|
||||
_mess = "OSError in saving to file {0}: \n{1}".format(
|
||||
self.parent.hdf_filename, str(e))
|
||||
self.parent.trigger_log_message.emit(
|
||||
MsgSeverity.ERROR.name, _pymodule, _line(), _mess, {})
|
||||
@@ -233,19 +276,37 @@ class BaseWindow(QMainWindow):
|
||||
self.all_data = all_data
|
||||
self.hdf_filename_loaded = self.parent.hdf_filename_loaded
|
||||
|
||||
def __del__(self):
|
||||
self.wait()
|
||||
#Only a precaution, not experienced
|
||||
#Causes QThread::wait: Thread tried to wait on itself
|
||||
#def __del__(self):
|
||||
# self.wait()
|
||||
|
||||
def run(self):
|
||||
"""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:
|
||||
@@ -266,6 +327,7 @@ class BaseWindow(QMainWindow):
|
||||
|
||||
# Emit results
|
||||
if all_dict is not None:
|
||||
self.parent.from_hdf = True
|
||||
self.trigger_thread_event.emit(all_dict)
|
||||
mess = "HDF file {} analysis succeeded".format(
|
||||
self.hdf_filename_loaded)
|
||||
@@ -283,14 +345,19 @@ 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)
|
||||
print("AnalysisThread", self.input_parameters, flush=True)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
@@ -300,20 +367,19 @@ class BaseWindow(QMainWindow):
|
||||
def run(self):
|
||||
"""Run thread
|
||||
"""
|
||||
|
||||
|
||||
print("RUN IN BASE CLASS", flush=True)
|
||||
|
||||
all_dict = self.analysis_procedure.measure_and_analyze(
|
||||
self.input_parameters)
|
||||
|
||||
# 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, {})
|
||||
|
||||
@@ -343,7 +409,6 @@ class BaseWindow(QMainWindow):
|
||||
|
||||
self.settings = ReadJSON(self.appname)
|
||||
|
||||
|
||||
#Read out current_logbook
|
||||
|
||||
self.cafe = PyCafe.CyCafe()
|
||||
@@ -363,10 +428,10 @@ class BaseWindow(QMainWindow):
|
||||
self.hdf_filename_loaded = "NONE" #For loading into hdf dockwidget
|
||||
self.hdf_filename = None #For saving
|
||||
self.hdf_dialog = None
|
||||
self.from_hdf = False
|
||||
|
||||
self.daq_analysis_completed = False
|
||||
|
||||
|
||||
self.setObjectName("MainWindow")
|
||||
self.setWindowTitle(self.appname)
|
||||
|
||||
@@ -376,20 +441,7 @@ class BaseWindow(QMainWindow):
|
||||
|
||||
self.menu = self.menuBar()
|
||||
|
||||
|
||||
'''
|
||||
try:
|
||||
dirname = self.settings.data["stdout"]["destination"]
|
||||
except KeyError:
|
||||
dirname = "/tmp/"
|
||||
|
||||
if not os.path.exists(dirname):
|
||||
os.mkdir(dirname)
|
||||
|
||||
fname = dirname + self.appname + ".log"
|
||||
file_obj = os.open(fname, os.O_RDWR|os.O_CREAT)
|
||||
os.close(file_obj)
|
||||
'''
|
||||
|
||||
|
||||
self.elog_dest = self.settings.data["Elog"]["destination"]
|
||||
self.screenshot_dest = self.settings.data["screenshot"]["destination"]
|
||||
@@ -444,7 +496,7 @@ class BaseWindow(QMainWindow):
|
||||
|
||||
self.read_input_parameters()
|
||||
self.all_data = {}
|
||||
|
||||
self.all_data_2 = {}
|
||||
self.hdf_thread = None
|
||||
self.save_hdf_thread = None
|
||||
self.analysis_thread = None
|
||||
@@ -452,9 +504,11 @@ class BaseWindow(QMainWindow):
|
||||
try:
|
||||
from src.analysis import AnalysisProcedure
|
||||
self.analysis_procedure = AnalysisProcedure(self)
|
||||
print("Base class has user supplied AnalysisProcedure class.",
|
||||
flush=True)
|
||||
except ImportError as e:
|
||||
print(("Base class without user supplied AnalysisProcedure class."
|
||||
+ " mport Error:"), e)
|
||||
+ " import Error:"), e, flush=True)
|
||||
|
||||
##self.trigger_elog_entry.connect(self.receive_elog_notification)
|
||||
##self.trigger_hdf_save.connect(self.save_to_hdf)
|
||||
@@ -843,15 +897,21 @@ class BaseWindow(QMainWindow):
|
||||
_mess, QMessageBox.Ok)
|
||||
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 self.daq_analysis_completed and not self.hdf_save_completed \
|
||||
and not self.from_hdf:
|
||||
if self.all_data is not None:
|
||||
try:
|
||||
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
|
||||
except KeyError:
|
||||
pass
|
||||
return True
|
||||
|
||||
@Slot()
|
||||
@@ -861,8 +921,11 @@ class BaseWindow(QMainWindow):
|
||||
#Close all dock widgets
|
||||
#self.removeDockWidget(self.hdf_dock_widget)
|
||||
self.logger.info("Closing Application")
|
||||
print("Closing Application", flush=True)
|
||||
self.save_application_settings()
|
||||
QApplication.processEvents()
|
||||
#print( ("Stopping Monitors. This may on occasion lead to " +
|
||||
# "NO CYTHON CALLBACK MATCH FOUND notices"), flush=True)
|
||||
self.cafe.monitorStopAll()
|
||||
time.sleep(0.05)
|
||||
self.cafe.terminate()
|
||||
@@ -953,9 +1016,11 @@ class BaseWindow(QMainWindow):
|
||||
QApplication.processEvents()
|
||||
if self.autopost_epics:
|
||||
self.save_to_epics()
|
||||
|
||||
QApplication.processEvents()
|
||||
if self.autopost_hdf:
|
||||
self.save_to_hdf()
|
||||
|
||||
QApplication.processEvents()
|
||||
if self.autopost_elog:
|
||||
self.send_to_elog()
|
||||
@@ -1021,7 +1086,7 @@ class BaseWindow(QMainWindow):
|
||||
|
||||
if not self.daq_analysis_completed:
|
||||
QMessageBox.information(self, "HDF", (
|
||||
("No data to save to hdf5; no measurement undertaken!")),
|
||||
("No data to save to hdf; no measurement undertaken!")),
|
||||
QMessageBox.Ok)
|
||||
QApplication.processEvents()
|
||||
return False
|
||||
@@ -1038,9 +1103,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.
|
||||
"""
|
||||
|
||||
'''
|
||||
QM = QMessageBox()
|
||||
QM.setText(
|
||||
str(NotImplementedError("add_to_hdf method has not been " +
|
||||
@@ -1049,6 +1116,8 @@ class BaseWindow(QMainWindow):
|
||||
"icon from the application/config file."))
|
||||
)
|
||||
QM.exec()
|
||||
'''
|
||||
return
|
||||
|
||||
@Slot()
|
||||
def save_to_hdf(self):
|
||||
@@ -1088,8 +1157,9 @@ class BaseWindow(QMainWindow):
|
||||
print(_mess, flush=True)
|
||||
self.trigger_log_message.emit(
|
||||
MsgSeverity.WARN.name, _pymodule, _line(), _mess,
|
||||
{})
|
||||
{})
|
||||
return isOK
|
||||
|
||||
|
||||
if from_hdf:
|
||||
return isOK
|
||||
@@ -1137,8 +1207,11 @@ class BaseWindow(QMainWindow):
|
||||
user_dict['User'] = getpass.getuser()
|
||||
|
||||
if self.all_data is not None:
|
||||
time_in_seconds = self.all_data['Ambient data']['Time in seconds']
|
||||
now = datetime.fromtimestamp(time_in_seconds)
|
||||
if 'Time in seconds' in self.all_data['Ambient data']:
|
||||
time_in_seconds = self.all_data['Ambient data']['Time in seconds']
|
||||
now = datetime.fromtimestamp(time_in_seconds)
|
||||
else:
|
||||
now = datetime.now()
|
||||
else:
|
||||
now = datetime.now()
|
||||
|
||||
@@ -1166,23 +1239,20 @@ class BaseWindow(QMainWindow):
|
||||
""" This uses the widget interface to allow the user to enter
|
||||
additional meta-data
|
||||
"""
|
||||
|
||||
|
||||
if not self.verify_save_to_hdf():
|
||||
return False
|
||||
|
||||
input_options = OrderedDict()
|
||||
|
||||
#print(self.all_data['Ambient data'])
|
||||
#print(self.all_data['Processed data'])
|
||||
|
||||
#QCombobox if list
|
||||
#input_options['QComboBox'] = ['one', 'two', 'three']
|
||||
#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
|
||||
@@ -1191,9 +1261,7 @@ class BaseWindow(QMainWindow):
|
||||
|
||||
self.hdf_dialog = QSaveHDF(self, input_options=input_options,
|
||||
from_dialog=True)
|
||||
#user_dict = self.hdf_dialog.get_data()
|
||||
#self.hdf_filename = user_dict['Destination']
|
||||
#print("filename", self.hdf_filename)
|
||||
|
||||
|
||||
def verify_send_to_elog(self):
|
||||
|
||||
@@ -1216,12 +1284,11 @@ class BaseWindow(QMainWindow):
|
||||
if self.save_hdf_thread.isRunning():
|
||||
return True
|
||||
|
||||
if not self.hdf_save_completed:
|
||||
if not self.hdf_save_completed and not self.from_hdf:
|
||||
_mess = ("Opening ELOG, but please note that data have not " +
|
||||
"been saved to HDF. " +
|
||||
"<br>Click on the HDF icon to do this if desired")
|
||||
QMessageBox.information(self, "ELOG", _mess,
|
||||
QMessageBox.Ok)
|
||||
QMessageBox.information(self, "ELOG", _mess, QMessageBox.Ok)
|
||||
return True
|
||||
|
||||
return True
|
||||
@@ -1230,7 +1297,7 @@ class BaseWindow(QMainWindow):
|
||||
def send_to_elog(self):
|
||||
""" Response to elog_action; normally overwritten
|
||||
"""
|
||||
if not self.verify_send_to_elog():
|
||||
if not self.verify_send_to_elog():
|
||||
return
|
||||
'''
|
||||
if self.analysis_thread is not None:
|
||||
@@ -1356,9 +1423,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:
|
||||
@@ -1428,9 +1496,18 @@ class BaseWindow(QMainWindow):
|
||||
def send_to_epics(self, pv_dict: dict = None, pv_names: list = None,
|
||||
pv_values: list = None) -> (int, list):
|
||||
|
||||
|
||||
if pv_dict is not None:
|
||||
pv_values = []
|
||||
pv_names = list(pv_dict.keys())
|
||||
pv_values = list(pv_dict.values())
|
||||
for val in pv_dict.values():
|
||||
if isinstance(val, np.ndarray):
|
||||
pv_values.append(val.tolist())
|
||||
else:
|
||||
pv_values.append(val)
|
||||
print("SAVE TO EPICS", flush=True)
|
||||
print(pv_names, flush=True)
|
||||
print(pv_values, flush=True)
|
||||
else:
|
||||
if len(pv_names) != len(pv_values):
|
||||
_mess = ("len(pv_values)={0} does not match " +
|
||||
@@ -1446,7 +1523,17 @@ class BaseWindow(QMainWindow):
|
||||
self.cafe.open(pv_names)
|
||||
self.cafe.openNowAndWait(0.4)
|
||||
|
||||
status, status_list = self.cafe.setCompoundList(pv_names, pv_values)
|
||||
status = self.cyca.ICAFE_NORMAL
|
||||
status_list = []
|
||||
try:
|
||||
status, status_list = self.cafe.setCompoundList(pv_names, pv_values)
|
||||
except:
|
||||
print("Exception raised in cafe.setCompoundList", flush=True)
|
||||
status = self.cyca.ECAFE_BADTYPE
|
||||
for pv, val in zip(pv_names, pv_values):
|
||||
print("pv/val", pv, val, flush=True)
|
||||
status_list.append(self.ECAFE_BADTYPE)
|
||||
|
||||
|
||||
if status != self.cyca.ICAFE_NORMAL:
|
||||
ibad = 0
|
||||
@@ -1565,8 +1652,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 +1725,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(
|
||||
@@ -1655,7 +1742,7 @@ class BaseWindow(QMainWindow):
|
||||
self.hdf_thread.trigger_thread_event.connect(
|
||||
self.receive_analysis_results)
|
||||
#procedure moved above
|
||||
#self.hdf_thread.started.connect(self.hdf_thread_started)
|
||||
self.hdf_thread.started.connect(self.hdf_thread_started)
|
||||
self.hdf_thread.finished.connect(self.hdf_thread_finished)
|
||||
|
||||
self.hdf_thread.start()
|
||||
@@ -1668,7 +1755,8 @@ class BaseWindow(QMainWindow):
|
||||
|
||||
@Slot()
|
||||
def start_analysis_thread(self):
|
||||
|
||||
'''Slot to self.start_wgt button trigger in guiframe.py
|
||||
'''
|
||||
if not self.analysis_procedure:
|
||||
mess = "Analysis thread not configured for this application"
|
||||
self.show_log_message(MsgSeverity.ERROR, _pymodule, _line(), mess)
|
||||
@@ -1702,10 +1790,11 @@ class BaseWindow(QMainWindow):
|
||||
self.analysis_thread.started.connect(self.analysis_thread_started)
|
||||
self.analysis_thread.finished.connect(self.analysis_thread_finished)
|
||||
|
||||
|
||||
|
||||
self.analysis_thread.start()
|
||||
QApplication.processEvents()
|
||||
|
||||
|
||||
@Slot()
|
||||
def analysis_thread_started(self):
|
||||
""" Change state of widgets when measuring
|
||||
@@ -1728,7 +1817,7 @@ class BaseWindow(QMainWindow):
|
||||
"""
|
||||
self.gui_frame.in_hdf_measurement_procedure()
|
||||
QApplication.processEvents()
|
||||
#print("Thread Started")
|
||||
|
||||
|
||||
@Slot()
|
||||
def hdf_thread_finished(self):
|
||||
@@ -1742,6 +1831,8 @@ class BaseWindow(QMainWindow):
|
||||
@Slot(dict)
|
||||
def receive_analysis_results(self, all_dict):
|
||||
self.all_data = all_dict
|
||||
print("self.all_data", self.all_data.keys(), flush=True)
|
||||
|
||||
self.gui_frame.canvas_update(all_dict['Figure data'])
|
||||
|
||||
if self.gui_frame.results_output_wgt_dict:
|
||||
@@ -1753,9 +1844,47 @@ 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 +1895,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 +1918,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 +1943,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 +1952,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)
|
||||
@@ -1925,6 +2054,12 @@ class BaseWindow(QMainWindow):
|
||||
width = 860 + (len(appname)-10)*15
|
||||
height = 220
|
||||
self.splash_screen.resize(width, height)
|
||||
|
||||
#Maybe useful at some point
|
||||
#pSplashNotice = QCheckBox(self.splash_screen);
|
||||
#pSplashNotice.setChecked(Qt.Checked)
|
||||
|
||||
|
||||
self.splash_progressbar = QProgressBar(self.splash_screen)
|
||||
self.splash_timer = QTimer()
|
||||
self.splash_screen.show()
|
||||
@@ -1956,7 +2091,7 @@ class BaseWindow(QMainWindow):
|
||||
int_seconds_remaining = int(delay - (now-start1))
|
||||
seconds_remaining = '{:2d}'.format(int_seconds_remaining)
|
||||
self.splash_progressbar.setValue(val)
|
||||
#self.processEvents()
|
||||
self.processEvents()
|
||||
self.flush()
|
||||
sec_str = "s" if abs(int_seconds_remaining) != 1 else ""
|
||||
mess = """
|
||||
@@ -1997,3 +2132,59 @@ class BaseWindow(QMainWindow):
|
||||
<br></p>
|
||||
""".format(self.splash_appname), Qt.AlignCenter | Qt.AlignTop)
|
||||
self.splash_screen.finish(myapp)
|
||||
|
||||
|
||||
|
||||
def check_status_list(self, pymodule: str = _pymodule,
|
||||
operation: str = "channel access",
|
||||
pv_list: list = None, status_list: list = None,
|
||||
line: int = _line()):
|
||||
|
||||
if None in (pv_list, status_list):
|
||||
return
|
||||
|
||||
brk = ("------------------------------------------------------" +
|
||||
"------------------------------------------------------")
|
||||
self.trigger_log_message.emit(
|
||||
MsgSeverity.INFO.name, pymodule, line, brk, {})
|
||||
|
||||
options = {}
|
||||
|
||||
for i, (pv, stat) in enumerate(zip(pv_list, status_list)):
|
||||
if stat == self.cyca.ICAFE_NORMAL:
|
||||
mess = "Error in '{0}' for element [{1}], {2}.".format(
|
||||
operation, i, pv)
|
||||
options['statusCode'] = (
|
||||
str(stat) + " " +
|
||||
self.cafe.getStatusCodeAsString(stat))
|
||||
options['statusInfo'] = self.cafe.getStatusInfo(stat)
|
||||
|
||||
self.trigger_log_message.emit(
|
||||
MsgSeverity.WARN.name, pymodule, line, mess, options)
|
||||
|
||||
self.trigger_log_message.emit(
|
||||
MsgSeverity.INFO.name, pymodule, line, brk, {})
|
||||
|
||||
mess = ("The following devices reported an error " +
|
||||
"in channel access operation:")
|
||||
self.trigger_log_message.emit(
|
||||
MsgSeverity.INFO.name, pymodule, line, mess, {})
|
||||
|
||||
|
||||
def check_status(self, pymodule: str = _pymodule,
|
||||
operation: str = "channel access",
|
||||
pv: str = None, stat: int = None,
|
||||
line: int =_line()):
|
||||
|
||||
if None in (pv, status):
|
||||
return
|
||||
|
||||
if stat != self.cyca.ICAFE_NORMAL:
|
||||
mess = "Error in '{0}' for {1}.".format(operation, pv)
|
||||
options = {}
|
||||
options['statusCode'] = (
|
||||
str(stat) + " " +
|
||||
self.cafe.getStatusCodeAsString(stat))
|
||||
options['statusInfo'] = self.cafe.getStatusInfo(stat)
|
||||
self.trigger_log_message.emit(
|
||||
MsgSeverity.WARN.name, pymodule, line, mess, options)
|
||||
|
||||
595
guiframe.py
595
guiframe.py
@@ -24,8 +24,6 @@ from caqtwidgets.pvwidgets import (
|
||||
|
||||
from apps4ops.bdbase.enumkind import Facility, MsgSeverity, UserMode
|
||||
|
||||
|
||||
|
||||
_pymodule = os.path.basename(__file__)
|
||||
_appversion = "1.0.0"
|
||||
|
||||
@@ -75,6 +73,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"][
|
||||
@@ -100,6 +99,8 @@ class GUIFrame(QWidget):
|
||||
self.radiobutton = None
|
||||
self.multiple_figure_dict = None
|
||||
|
||||
self.pipeline_group_box = None
|
||||
|
||||
self.line_sender_dict = {}
|
||||
self.radio_stack_dict = {}
|
||||
self.stack_radiolist_dict = {}
|
||||
@@ -128,8 +129,16 @@ 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 = {}
|
||||
@@ -147,7 +156,8 @@ class GUIFrame(QWidget):
|
||||
"GUI"]["subResultsTabTitle"]
|
||||
|
||||
self.sub_results_wgt = [None] * len(self.results_tab_wgt_titles)
|
||||
self.sub_results_layout = [None] * len(self.results_tab_wgt_titles)
|
||||
self.sub_results_layout = [None] * len(
|
||||
self.results_tab_wgt_titles)
|
||||
|
||||
for i in range(0, len(self.results_tab_wgt_titles)):
|
||||
self.sub_results_wgt[i] = QWidget(self.results_tab_wgt)
|
||||
@@ -155,13 +165,38 @@ class GUIFrame(QWidget):
|
||||
self.canvas = [None] * len(self.results_tab_wgt_titles)
|
||||
self.nav = [None] * len(self.results_tab_wgt_titles)
|
||||
|
||||
self.arrow_button_widget = [None] * len(self.results_tab_wgt_titles)
|
||||
self.arrow_button_widget = [None] * len(
|
||||
self.results_tab_wgt_titles)
|
||||
self.canvas_current_idx = [0] * len(self.results_tab_wgt_titles)
|
||||
|
||||
|
||||
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 +226,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 +266,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 +302,82 @@ class GUIFrame(QWidget):
|
||||
len_key_list3 = 0
|
||||
else:
|
||||
len_key_list3 = 0
|
||||
|
||||
|
||||
|
||||
else:
|
||||
len_key_list3 = 0
|
||||
print("length", len_key_list3)
|
||||
|
||||
|
||||
|
||||
self.level2_wgt[i][j] = QWidget() #self.level1_wgt[i])
|
||||
self.level2_wgt[i][j].title2 = title2
|
||||
self.level2_wgt[i][j].title = 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].title = 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,13 +385,11 @@ 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]
|
||||
self.measurement_wgt = self.level2_wgt[0][0]
|
||||
|
||||
|
||||
def init_central_tab_widget(self):
|
||||
""" Add tabs to central widget
|
||||
"""
|
||||
@@ -351,7 +408,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 +417,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 +431,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 +644,12 @@ 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 +669,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 +703,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 +738,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 +751,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 +780,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",
|
||||
@@ -847,10 +832,6 @@ class GUIFrame(QWidget):
|
||||
_tip = "Restore quadruples to their pre-measurement values"
|
||||
self.restore_optics_btn.setToolTip(_tip)
|
||||
|
||||
#_text = """<p> <font style="color:{0}; background-color:'white'";>
|
||||
# {1} <br> {2} </font>
|
||||
# </p>
|
||||
# """.format('gray', 'Deflector', 'PM')
|
||||
self.target_optics = QLabel()
|
||||
#self.target_optics.setText(_text)
|
||||
self.target_optics.setFixedWidth(150)
|
||||
@@ -917,6 +898,7 @@ class GUIFrame(QWidget):
|
||||
self.start_wgt.setEnabled(False)
|
||||
self.start_wgt.setText("HDF analysis...")
|
||||
self.save_all_group_box.setEnabled(False)
|
||||
|
||||
|
||||
def hdf_reset_procedure(self):
|
||||
self.parent.h5_groupbox.analyze_h5_widget.setEnabled(True)
|
||||
@@ -1056,10 +1038,138 @@ class GUIFrame(QWidget):
|
||||
return self.save_all_group_box
|
||||
|
||||
|
||||
def image_parameters_group(self):
|
||||
self.pipeline_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))
|
||||
|
||||
self.pipeline_group_box.setAlignment(Qt.AlignCenter)
|
||||
self.pipeline_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.addWidget(self.create_checkbox(
|
||||
# top_key="Expert", key="pipelineCtrl",
|
||||
# text="Enable pipeline control from HLA",
|
||||
# tip="HLA to set pipeline parameters",
|
||||
# default_value=0), 0, 0, 1, 2)
|
||||
|
||||
|
||||
layout_top.addLayout(box, 1, 0, 1, 2)
|
||||
layout_top.addWidget(self.good_region_group, 2, 0, 1, 1,
|
||||
Qt.AlignHCenter | Qt.AlignTop)
|
||||
layout_top.addWidget(self.slicing_group, 2, 1, 1, 1,
|
||||
Qt.AlignCenter | Qt.AlignTop)
|
||||
layout_top.setHorizontalSpacing(8)
|
||||
self.pipeline_group_box.setLayout(layout_top)
|
||||
self.pipeline_group_box.setFixedHeight(200)
|
||||
|
||||
if "HLAPipelineCtrl" in self.parent.input_parameters:
|
||||
self.pipeline_group_box.setEnabled(
|
||||
self.parent.input_parameters["HLAPipelineCtrl"])
|
||||
|
||||
return self.pipeline_group_box
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def checkbox_wgt(self, key: str = "", tooltip: str = "", object_name=None,
|
||||
hline="NONE"):
|
||||
def on_change(state):
|
||||
self.input_parameters[key] = bool(state)
|
||||
|
||||
|
||||
widget = QWidget()
|
||||
layout = QGridLayout()
|
||||
@@ -1265,7 +1375,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 +1419,62 @@ class GUIFrame(QWidget):
|
||||
self.nav[i] = None
|
||||
|
||||
|
||||
def canvas_update_2(self, fig_data, idx=0):
|
||||
#place figures in a list
|
||||
|
||||
#Only clear last result fro this canvas
|
||||
#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.clear_screenshot(self.results_tab_wgt_titles_2[i],
|
||||
wgt)
|
||||
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)
|
||||
@@ -1521,6 +1691,7 @@ class GUIFrame(QWidget):
|
||||
def check_cb(new_value):
|
||||
sender= self.sender()
|
||||
self.parent.input_parameters[sender.title][sender.key] = new_value
|
||||
|
||||
|
||||
def line_cb(new_value):
|
||||
sender= self.sender()
|
||||
@@ -1578,7 +1749,7 @@ class GUIFrame(QWidget):
|
||||
value = param["data"]["value"]
|
||||
elif "link" in param["data"]:
|
||||
link_list = param["data"]["link"]
|
||||
print("ll", link_list, flush=True)
|
||||
|
||||
if len(link_list) == 1:
|
||||
value = self.settings.data[link_list[0]]
|
||||
print("values", value, flush=True)
|
||||
@@ -1593,7 +1764,7 @@ class GUIFrame(QWidget):
|
||||
label = QLabel(text)
|
||||
label.setFixedHeight(24)
|
||||
label.setFont(self.font_pts10)
|
||||
label.setContentsMargins(5, 0, 0, 0)
|
||||
label.setContentsMargins(0, 0, 0, 0)
|
||||
return label
|
||||
|
||||
if "QSpinBox" in wgt_type:
|
||||
@@ -1666,7 +1837,8 @@ class GUIFrame(QWidget):
|
||||
#print(title, tab)
|
||||
#print(key, line, icolumn, wgt_type, text, flush=True)
|
||||
_irow += 1
|
||||
|
||||
|
||||
|
||||
qw.setLayout(lo)
|
||||
qw.setFixedHeight(tab_height)
|
||||
qtab_widget_dict[itab] = qw
|
||||
@@ -1680,7 +1852,7 @@ class GUIFrame(QWidget):
|
||||
meas_label = QLabel()
|
||||
meas_label.setFixedHeight(24)
|
||||
meas_label.setFont(self.font_pts10)
|
||||
meas_label.setContentsMargins(5, 0, 0, 0)
|
||||
meas_label.setContentsMargins(0, 0, 0, 0)
|
||||
meas_label.setText(self.settings.data[top_key][key]["data"]["text"])
|
||||
meas_line = QLineEdit()
|
||||
meas_line.setObjectName("Read")
|
||||
@@ -1701,13 +1873,13 @@ class GUIFrame(QWidget):
|
||||
|
||||
final_wgt = QWidget()
|
||||
final_lo = QGridLayout()
|
||||
|
||||
final_wgt.setContentsMargins(0, 0, 0, 0)
|
||||
final_lo.addWidget(meas_label, 0, 0, 1, 2, Qt.AlignLeft | Qt.AlignVCenter)
|
||||
final_lo.addWidget(meas_line, 0, 2, 1, 2, Qt.AlignLeft | Qt.AlignVCenter)
|
||||
qHLine = QHLine()
|
||||
qHLine.setFixedHeight(10)
|
||||
final_lo.addWidget(qHLine, 1, 0, 1, 4)
|
||||
final_lo.addWidget(qtab_widget, 2, 0, 1, 4, Qt.AlignHCenter | Qt.AlignVCenter)
|
||||
final_lo.addWidget(qtab_widget, 2, 0, 1, 4, Qt.AlignLeft | Qt.AlignVCenter)
|
||||
#final_lo.setSpacing(0)
|
||||
final_wgt.setLayout(final_lo)
|
||||
|
||||
@@ -1825,6 +1997,8 @@ class GUIFrame(QWidget):
|
||||
self.input_parameters[key] = 0
|
||||
return
|
||||
|
||||
|
||||
|
||||
if hasattr(radio_buddy_text_dict[self.sender()], "pv_info"):
|
||||
|
||||
dt = radio_buddy_text_dict[self.sender()].pv_info.dataType
|
||||
@@ -1832,6 +2006,10 @@ class GUIFrame(QWidget):
|
||||
if dt not in [self.cyca.CY_DBR_STRING, self.cyca.CY_DBR_ENUM,
|
||||
self.cyca.CY_DBR_CHAR]:
|
||||
value_input = re.findall(r"-?\d+\.?\d*", value_str)
|
||||
|
||||
|
||||
|
||||
|
||||
if dt in [self.cyca.CY_DBR_FLOAT, self.cyca.CY_DBR_DOUBLE]:
|
||||
self.input_parameters[key] = float(value_input[0])
|
||||
elif dt in [self.cyca.CY_DBR_SHORT, self.cyca.CY_DBR_LONG]:
|
||||
@@ -1872,7 +2050,7 @@ class GUIFrame(QWidget):
|
||||
|
||||
if pvname in self.current_stacked_wgt_dict.values() and \
|
||||
radiobutton_list[0].isChecked(): #
|
||||
self.input_parameters[key] = pvdata.value[0]
|
||||
self.input_parameters[key] = pvdata.value[0]
|
||||
|
||||
if monitor:
|
||||
monitor_pv = CAQLabel(self, pv_name=pv, monitor_callback=mon_cb,
|
||||
@@ -1983,7 +2161,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 +2176,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()
|
||||
@@ -2091,8 +2272,6 @@ class GUIFrame(QWidget):
|
||||
for rb in rblist:
|
||||
rb.toggled.connect(on_radiobutton_change)
|
||||
|
||||
|
||||
|
||||
if self.grid_loc:
|
||||
a = self.grid_loc[0]
|
||||
b = self.grid_loc[1]
|
||||
@@ -2130,10 +2309,17 @@ class GUIFrame(QWidget):
|
||||
def input_wgt_qcheckbox(self, key, value, label_text, irow, wgt_grid):
|
||||
def check_cb(new_value):
|
||||
self.parent.input_parameters[key] = bool(new_value)
|
||||
#print("check_cbp", key, new_value, flush=True)
|
||||
if key == "HLAPipelineCtrl":
|
||||
if self.pipeline_group_box is not None:
|
||||
self.pipeline_group_box.setEnabled(bool(new_value))
|
||||
|
||||
|
||||
line = QCheckBox(label_text)
|
||||
line.setChecked(Qt.Checked if value else Qt.Unchecked)
|
||||
line.stateChanged.connect(check_cb)
|
||||
#line.toggled.connect(check_cb)
|
||||
line.setChecked(Qt.Checked if value else Qt.Unchecked)
|
||||
|
||||
line.setMaximumWidth(320)
|
||||
line.setMinimumWidth(100)
|
||||
line.setFixedHeight(28)
|
||||
@@ -2168,8 +2354,8 @@ class GUIFrame(QWidget):
|
||||
|
||||
wgt_grid.addWidget(line, a, b, c, d, Qt.AlignLeft | Qt.AlignVCenter)
|
||||
|
||||
|
||||
|
||||
#line.stateChanged.emit(Qt.Checked if value else Qt.Unchecked)
|
||||
|
||||
return line
|
||||
|
||||
def input_wgt_qlabel(self, value, irow, wgt_grid):
|
||||
@@ -2213,11 +2399,9 @@ class GUIFrame(QWidget):
|
||||
#line.textEdited.connect(line_cb)
|
||||
line.textChanged.emit(str(value))
|
||||
|
||||
|
||||
line.setAlignment(Qt.AlignRight | Qt.AlignBottom)
|
||||
line.setStyleSheet("QLabel{text-align: right}")
|
||||
|
||||
|
||||
try:
|
||||
w =self.settings.data["Parameters"][key]["data"]["width"]
|
||||
line.setFixedWidth(w)
|
||||
@@ -2310,6 +2494,13 @@ class GUIFrame(QWidget):
|
||||
min_val = self.settings.data[top_key][key]["data"]["min"]
|
||||
max_val = self.settings.data[top_key][key]["data"]["max"]
|
||||
step = self.settings.data[top_key][key]["data"]["step"]
|
||||
|
||||
try:
|
||||
if 'tooltip' in self.settings.data[top_key][key]["data"]:
|
||||
label.setToolTip(self.settings.data[top_key][key]["data"][
|
||||
"tooltip"])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
decimal = Decimal(str(step))
|
||||
line.setDecimals(abs(decimal.as_tuple().exponent)) #precision
|
||||
@@ -2468,7 +2659,7 @@ class GUIFrame(QWidget):
|
||||
qVLine = QVLine()
|
||||
|
||||
qVLine.setFixedWidth(20)
|
||||
print("ROW COUNT =======================================", wgt_grid.rowCount())
|
||||
|
||||
qVLine.setFixedHeight(17 * wgt_grid.rowCount())
|
||||
|
||||
if self.grid_loc:
|
||||
@@ -2561,7 +2752,19 @@ class GUIFrame(QWidget):
|
||||
elif buddy == "QTabWidget".upper():
|
||||
#print("buddy/label", buddy, label, key, value, flush=True)
|
||||
line = self.qtab_wgt(key, irow, wgt_grid)
|
||||
wgt_grid.addWidget(line, irow, 0, 1, 4,
|
||||
|
||||
if self.grid_loc:
|
||||
a = self.grid_loc[0]
|
||||
b = self.grid_loc[1]
|
||||
c = self.grid_loc[2]
|
||||
d = self.grid_loc[3]
|
||||
else:
|
||||
a = irow
|
||||
b = 0
|
||||
c = 1
|
||||
d = 4
|
||||
|
||||
wgt_grid.addWidget(line, a, b, c, d,
|
||||
Qt.AlignLeft | Qt.AlignVCenter)
|
||||
else:
|
||||
wgt_list = ["QCheckBox", "QComboBox", "QDoubleSpinBox", "QFrame",
|
||||
@@ -2612,9 +2815,6 @@ class GUIFrame(QWidget):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
##in_j = 0
|
||||
|
||||
for (key, val), label in zip(self.all_input_parameters.items(),
|
||||
@@ -2732,8 +2932,6 @@ class GUIFrame(QWidget):
|
||||
self.checkbox_keepImages())
|
||||
|
||||
|
||||
|
||||
|
||||
##self.expert_parameters_group.layout().addWidget(QHLine())
|
||||
#hbox2.addWidget(self.checkbox_debug(hline="None"))
|
||||
#hbox2.addWidget(self.checkbox_simulation(hline="None"))
|
||||
@@ -2785,7 +2983,6 @@ class GUIFrame(QWidget):
|
||||
#self.setLayout(layout)
|
||||
|
||||
target_list = options
|
||||
|
||||
color_list = ["#894961", "teal", "darkblue"]
|
||||
|
||||
self.radiobutton = [None] * len(options)
|
||||
|
||||
327
h5_storage.py
Normal file
327
h5_storage.py
Normal file
@@ -0,0 +1,327 @@
|
||||
import getpass
|
||||
import time
|
||||
import re
|
||||
from functools import lru_cache
|
||||
import h5py
|
||||
import numpy as np
|
||||
|
||||
dt = h5py.special_dtype(vlen=bytes)
|
||||
numerical_types = (np.dtype('float64'), np.dtype('float32'), np.dtype('uint16'), np.dtype('uint64'), np.dtype('uint32'))
|
||||
|
||||
def stringDataset(group, name, data, system=None):
|
||||
dset = group.create_dataset(name, (1,), dtype=dt, data=data)
|
||||
if system:
|
||||
addSystemAttribute(dset, system)
|
||||
|
||||
def addStringAttribute(dset_or_group, name, data):
|
||||
#return dset_or_group.attrs.create(name, np.string_(data)) # , (1,), dtype=dt)
|
||||
dset_or_group.attrs[name] = bytes(data, 'utf-8')
|
||||
|
||||
def addSystemAttribute(dset_or_group, data):
|
||||
addStringAttribute(dset_or_group, 'system', data)
|
||||
|
||||
def add_dataset(group, name, data, system=None, dtype=None):
|
||||
if type(data) is str:
|
||||
stringDataset(group, name, data, system)
|
||||
else:
|
||||
if dtype:
|
||||
dset = group.create_dataset(name, data=data, dtype=dtype)
|
||||
else:
|
||||
try:
|
||||
dset = group.create_dataset(name, data=data)
|
||||
except Exception as e:
|
||||
dset = None
|
||||
print('Error for dataset %s' % name)
|
||||
print('Continuing')
|
||||
print(e)
|
||||
|
||||
if dset is not None and system:
|
||||
addSystemAttribute(dset, system)
|
||||
|
||||
def saveH5Recursive(h5_filename, data_dict, dataH5=None):
|
||||
|
||||
def recurse_save(group, dict_or_data, dict_or_data_name, new_group=None):
|
||||
|
||||
if dict_or_data is None:
|
||||
dict_or_data = 'None'
|
||||
if group is None:
|
||||
print("'recurse_save' has been called with None")
|
||||
raise ValueError
|
||||
|
||||
|
||||
|
||||
if type(dict_or_data) is dict:
|
||||
|
||||
try:
|
||||
new_group = group.create_group(dict_or_data_name)
|
||||
except Exception as e:
|
||||
print("Error in group.create_group", str(e))
|
||||
return
|
||||
|
||||
if new_group is None:
|
||||
raise ValueError
|
||||
for key, val in dict_or_data.items():
|
||||
try:
|
||||
recurse_save(new_group, val, key)
|
||||
except ValueError:
|
||||
print('I called recurse_save with None')
|
||||
#import pdb; pdb.set_trace()
|
||||
|
||||
else:
|
||||
mydata = dict_or_data
|
||||
inner_key = dict_or_data_name
|
||||
|
||||
|
||||
|
||||
if type(mydata) is str:
|
||||
add_dataset(group, inner_key, mydata.encode('utf-8'), 'unknown')
|
||||
elif (type(mydata) is list and type(mydata[0]) is str) or (hasattr(mydata, 'dtype') and mydata.dtype.type is np.str_):
|
||||
# For list of strings, we need this procedure
|
||||
if type(mydata[0]) is str:
|
||||
mydata = np.array(mydata)
|
||||
print("string to np.str", mydata)
|
||||
elif type(mydata[0]) is str:
|
||||
print("np.str")
|
||||
try:
|
||||
if hasattr(mydata, 'dtype') and \
|
||||
(mydata.dtype.type is np.str or \
|
||||
mydata.dtype.type is str) and len(mydata.shape) == 2:
|
||||
mydata = mydata.flatten()
|
||||
if len(mydata.shape) == 2:
|
||||
new_list = [[n.encode('ascii') for n in arr] for arr in mydata]
|
||||
max_str_size = max(max(len(n) for n in arr) for arr in mydata)
|
||||
elif len(mydata.shape) == 1:
|
||||
new_list = [n.encode('ascii') for n in mydata]
|
||||
max_str_size = max(len(n) for n in mydata)
|
||||
elif len(mydata.shape) == 0:
|
||||
new_list = [mydata.encode('ascii')]
|
||||
max_str_size = len(new_list[0])
|
||||
#print('Max len %i' % max_str_size)
|
||||
dset = group.create_dataset(inner_key, mydata.shape, 'S%i' % max_str_size, new_list)
|
||||
#print(np.array(dset))
|
||||
dset.attrs.create('system', 'unknown', (1,), dtype=dt)
|
||||
|
||||
except Exception as e:
|
||||
print('Exception:', e )
|
||||
print('Error', inner_key)
|
||||
print(type(mydata))
|
||||
if type(mydata) is list:
|
||||
print('type(mydata[0])')
|
||||
print(type(mydata[0]))
|
||||
print('len mydata shape=', len(mydata.shape))
|
||||
print('mydata')
|
||||
print(mydata)
|
||||
|
||||
elif hasattr(mydata, 'dtype') and mydata.dtype == np.dtype('O'):
|
||||
|
||||
if mydata.shape == ():
|
||||
add_dataset(group, inner_key, mydata, 'unknown')
|
||||
elif len(mydata.shape) == 1:
|
||||
add_dataset(group, inner_key, mydata, 'unknown')
|
||||
else:
|
||||
for i in range(mydata.shape[0]):
|
||||
for j in range(mydata.shape[1]):
|
||||
try:
|
||||
add_dataset(group, inner_key+'_%i_%i' % (i,j), mydata[i,j], 'unknown')
|
||||
except:
|
||||
print('Error')
|
||||
print(group, inner_key, i, j)
|
||||
else:
|
||||
|
||||
|
||||
|
||||
try:
|
||||
add_dataset(group, inner_key, mydata, 'unknown')
|
||||
except Exception as e:
|
||||
print('Error', e)
|
||||
print(inner_key, type(mydata))
|
||||
|
||||
|
||||
if dataH5 is None:
|
||||
with h5py.File(h5_filename, 'w') as dataH5:
|
||||
for main_key, subdict in data_dict.items():
|
||||
recurse_save(dataH5, subdict, main_key, None)
|
||||
print("h5_storage.py SAVED TO FILE", h5_filename, flush=True)
|
||||
else:
|
||||
print("data_dict keys", data_dict.keys())
|
||||
for main_key, subdict in data_dict.items():
|
||||
recurse_save(dataH5, subdict, main_key, None)
|
||||
print("h5_storage.py SAVED TO dataH5", flush=True)
|
||||
#recurse_save(dataH5, data_dict, 'none', new_group=dataH5)
|
||||
|
||||
|
||||
def loadH5Recursive(h5_file):
|
||||
def recurse_load(group_or_val, key, saved_dict_curr):
|
||||
type_ = type(group_or_val)
|
||||
if type_ is h5py._hl.files.File:
|
||||
for new_key, new_group_or_val in group_or_val.items():
|
||||
recurse_load(new_group_or_val, new_key, saved_dict_curr)
|
||||
elif type_ is h5py._hl.group.Group:
|
||||
saved_dict_curr[key] = new_dict = {}
|
||||
for new_key, new_group_or_val in group_or_val.items():
|
||||
recurse_load(new_group_or_val, new_key, new_dict)
|
||||
elif type_ == np.dtype('O') and type(group_or_val[()]) is bytes:
|
||||
saved_dict_curr[key] = group_or_val[()].decode()
|
||||
elif type_ == h5py._hl.dataset.Dataset:
|
||||
dtype = group_or_val.dtype
|
||||
#if not hasattr(group_or_val, 'value'):
|
||||
# print('Could not store key %s with type %s in dict' % (key, dtype))
|
||||
# return
|
||||
if dtype in (np.dtype('int64'), np.dtype('int32'), np.dtype('int16'), np.dtype('int8')):
|
||||
saved_dict_curr[key] = np.array(group_or_val[()], int).squeeze()
|
||||
elif dtype == np.dtype('bool'):
|
||||
try:
|
||||
saved_dict_curr[key] = bool(group_or_val[()])
|
||||
except:
|
||||
print('Could not store key %s with type %s in dict (1)' % (key, dtype))
|
||||
elif dtype in numerical_types:
|
||||
saved_dict_curr[key] = np.array(group_or_val[()]).squeeze()
|
||||
elif dtype.str.startswith('|S'):
|
||||
if group_or_val[()].shape == (1,1):
|
||||
saved_dict_curr[key] = group_or_val[()][0,0].decode()
|
||||
elif group_or_val[()].shape == (1,):
|
||||
saved_dict_curr[key] = group_or_val[()][0].decode()
|
||||
|
||||
elif group_or_val[()].shape == ():
|
||||
saved_dict_curr[key] = group_or_val[()].decode()
|
||||
else:
|
||||
saved_dict_curr[key] = [x.decode() for x in group_or_val[()].squeeze()]
|
||||
elif dtype.str == '|O':
|
||||
saved_dict_curr[key] = group_or_val[()]
|
||||
elif type(group_or_val[()]) is str:
|
||||
saved_dict_curr[key] = group_or_val[()]
|
||||
else:
|
||||
print('Could not store key %s with type %s in dict (2)' % (key, dtype))
|
||||
else:
|
||||
print('Could not store key %s with type %s in dict (3)' % (key, type_))
|
||||
|
||||
saved_dict = {}
|
||||
with h5py.File(h5_file, 'r') as f:
|
||||
if 'none' in f:
|
||||
recurse_load(f['none'], 'key', saved_dict)
|
||||
saved_dict = saved_dict['key']
|
||||
else:
|
||||
recurse_load(f, 'key', saved_dict)
|
||||
return saved_dict
|
||||
|
||||
def save_h5_new(saved_dict, h5_file):
|
||||
|
||||
def recurse_save(dict_, group, system):
|
||||
print('recurse', dict_.keys())
|
||||
for key, subdict_or_data in dict_.items():
|
||||
type_ = type(subdict_or_data)
|
||||
print(key, type_)
|
||||
if type_ is dict:
|
||||
new_group = group.create_group(key)
|
||||
recurse_save(subdict_or_data, new_group, system)
|
||||
elif type_ is np.ndarray:
|
||||
add_dataset(group, key, subdict_or_data, system)
|
||||
elif type_ is str:
|
||||
add_dataset(group, key, subdict_or_data, system, dtype=dt)
|
||||
else:
|
||||
raise ValueError(key, type_)
|
||||
|
||||
@lru_cache()
|
||||
def re_axis(x):
|
||||
return re.compile(r'gr_%s_axis_(\d+)_(\d+)' % x)
|
||||
|
||||
@lru_cache()
|
||||
def re_gauss_function(x):
|
||||
return re.compile(r'gr_%s_fit_gauss_function_(\d+)_(\d+)' % x)
|
||||
|
||||
n_measurements, n_images = saved_dict['Raw_data']['image'].shape[:2]
|
||||
|
||||
# Create arrays for gr / slice values, that differ in size for different n_measurements, n_images
|
||||
gr_x_shape_max = -1
|
||||
gr_y_shape_max = -1
|
||||
for key, data in sorted(saved_dict['Raw_data'].items()):
|
||||
if key.startswith('gr_x_axis'):
|
||||
gr_x_shape_max = max(gr_x_shape_max, data.shape[0])
|
||||
elif key.startswith('gr_y_axis'):
|
||||
gr_y_shape_max = max(gr_y_shape_max, data.shape[0])
|
||||
|
||||
gr_x_axis = np.zeros([n_measurements, n_images, gr_x_shape_max])*np.nan
|
||||
gr_y_axis = np.zeros([n_measurements, n_images, gr_y_shape_max])*np.nan
|
||||
gr_x_fit_gauss_function = gr_x_axis.copy()
|
||||
gr_y_fit_gauss_function = gr_y_axis.copy()
|
||||
|
||||
for key, data in sorted(saved_dict['Raw_data'].items()):
|
||||
for arr, regex in [
|
||||
(gr_x_axis, re_axis('x')),
|
||||
(gr_y_axis, re_axis('y')),
|
||||
(gr_x_fit_gauss_function, re_gauss_function('x')),
|
||||
(gr_y_fit_gauss_function, re_gauss_function('y')),
|
||||
]:
|
||||
match = regex.match(key)
|
||||
if match is not None:
|
||||
#print(key, 'matches', regex)
|
||||
n_measurement, n_image = map(int, match.groups())
|
||||
arr[n_measurement, n_image,:len(data)] = data
|
||||
continue
|
||||
|
||||
with h5py.File(h5_file, 'w') as f:
|
||||
general = f.create_group('general')
|
||||
stringDataset(general, 'user', getpass.getuser())
|
||||
stringDataset(general, 'application', 'EmittanceTool')
|
||||
stringDataset(general, 'author', 'Philipp Dijkstal and Eduard Prat')
|
||||
stringDataset(general, 'created', time.ctime())
|
||||
|
||||
experiment = f.create_group('experiment')
|
||||
try:
|
||||
from epics import caget
|
||||
lrr = float(caget('SIN-TIMAST-TMA:Beam-Exp-Freq-RB'))
|
||||
except Exception as e:
|
||||
print('Could not obtain Laser rep rate!')
|
||||
print(e)
|
||||
lrr = np.nan
|
||||
add_dataset(experiment, 'Laser rep rate', lrr, 'unknown')
|
||||
# TBD: save snapshot here
|
||||
|
||||
scan1 = f.create_group('scan 1')
|
||||
|
||||
method = scan1.create_group('method')
|
||||
method.create_dataset('records', data=[float(n_measurements)])
|
||||
method.create_dataset('samples', data=[float(n_images)])
|
||||
method.create_dataset('dimension', data=[1])
|
||||
stringDataset(method, 'type', 'Line scan')
|
||||
recurse_save(saved_dict['Input'], method, 'Application Input')
|
||||
|
||||
|
||||
data = scan1.create_group('data')
|
||||
|
||||
screen = data.create_group(saved_dict['Input']['Profile monitor'])
|
||||
recurse_save(saved_dict['Meta_data'], screen, 'Emittance data')
|
||||
|
||||
|
||||
for key, data_ in sorted(saved_dict['Raw_data'].items()):
|
||||
if not any([x.match(key) for x in [re_axis('x'), re_axis('y'), re_gauss_function('x'), re_gauss_function('y')]]):
|
||||
add_dataset(screen, key, data_, 'Camera')
|
||||
#print('Created %s' % key)
|
||||
|
||||
if not np.all(np.isnan(gr_x_axis)):
|
||||
add_dataset(screen, 'gr_x_axis', gr_x_axis, 'Camera')
|
||||
else:
|
||||
print('gr_x_axis is nan')
|
||||
if not np.all(np.isnan(gr_y_axis)):
|
||||
add_dataset(screen, 'gr_y_axis', gr_y_axis, 'Camera')
|
||||
else:
|
||||
print('gr_y_axis is nan')
|
||||
if not np.all(np.isnan(gr_x_fit_gauss_function)):
|
||||
add_dataset(screen, 'gr_x_fit_gauss_function', gr_x_fit_gauss_function, 'Camera')
|
||||
else:
|
||||
print('gr_x_fit_gauss_function is nan')
|
||||
if not np.all(np.isnan(gr_y_fit_gauss_function)):
|
||||
add_dataset(screen, 'gr_y_fit_gauss_function', gr_y_fit_gauss_function, 'Camera')
|
||||
else:
|
||||
print('gr_y_fit_gauss_function is nan')
|
||||
|
||||
if 'Magnet_data' in saved_dict:
|
||||
for n_magnet, magnet in enumerate(saved_dict['Magnet_data']['Magnets']):
|
||||
mag_group = method.create_group('actuators/%s' % magnet)
|
||||
add_dataset(mag_group, 'K', saved_dict['Magnet_data']['K'][n_magnet], 'Magnet')
|
||||
add_dataset(mag_group, 'I-SET', saved_dict['Magnet_data']['I-SET'][n_magnet], 'Magnet')
|
||||
elif not saved_dict['Input']['Dry run'] in (np.array(False), False):
|
||||
raise ValueError('No magnet data')
|
||||
else:
|
||||
print('Magnet data not saved.')
|
||||
|
||||
@@ -220,7 +220,6 @@ class QSaveHDF(QDialog):
|
||||
|
||||
|
||||
def get_data(self):
|
||||
|
||||
self.user_dict['Application'] = self.applicationLabel.text()
|
||||
self.user_dict['User'] = self.author.text()
|
||||
self.user_dict['Comment'] = self.comment.document().toPlainText()
|
||||
|
||||
@@ -4,9 +4,9 @@ import os
|
||||
import time
|
||||
|
||||
from qtpy.QtCore import Qt
|
||||
from qtpy.QtWidgets import (QComboBox, QDialog, QFileDialog, QHBoxLayout,
|
||||
QLabel, QLineEdit, QPushButton, QTextEdit,
|
||||
QVBoxLayout)
|
||||
from qtpy.QtWidgets import (
|
||||
QApplication, QComboBox, QDialog, QFileDialog, QHBoxLayout, QLabel,
|
||||
QLineEdit, QPushButton, QTextEdit, QVBoxLayout)
|
||||
|
||||
import elog # https://github.com/paulscherrerinstitute/py_elog
|
||||
from pyqtacc.bdbase.enumkind import MsgSeverity
|
||||
@@ -212,7 +212,7 @@ class QSendToELOGFrame(QDialog):
|
||||
self.attributes['When'] = str(time.time())
|
||||
self.attributes['Wann'] = str(time.time())
|
||||
|
||||
|
||||
QApplication.processEvents()
|
||||
|
||||
if self.attachFile is not None:
|
||||
_attachFile = []
|
||||
@@ -227,15 +227,18 @@ class QSendToELOGFrame(QDialog):
|
||||
self.files.append(str(_attachFile[i]))
|
||||
elif "/sls/bd/data/" in _attachFile[i]:
|
||||
self.files.append(str(_attachFile[i]))
|
||||
elif "/sf/data/" in _attachFile[i]:
|
||||
self.files.append(str(_attachFile[i]))
|
||||
else:
|
||||
self.files.append(self.destination + str(_attachFile[i]))
|
||||
QApplication.processEvents()
|
||||
|
||||
el = self.elog_items.currentText()
|
||||
|
||||
url = self.parent.settings.data["ElogBooks"][el]["url"]
|
||||
|
||||
self.logbook = elog.open(url, user='robot', password='robot')
|
||||
|
||||
QApplication.processEvents()
|
||||
|
||||
try:
|
||||
if self.files:
|
||||
@@ -307,18 +310,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
12
utils.py
Normal 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
|
||||
Reference in New Issue
Block a user