rework config/parameter setting

This commit is contained in:
2022-09-05 10:30:48 +02:00
parent c11e0acfcd
commit 8fc532d3ae
2 changed files with 197 additions and 31 deletions

View File

@@ -9,11 +9,13 @@ import logging
_log = logging.getLogger(__name__) _log = logging.getLogger(__name__)
from PyQt5.QtCore import QSettings from PyQt5.QtCore import QSettings
from PyQt5.QtWidgets import QApplication, QLineEdit from PyQt5.QtWidgets import QApplication, QLineEdit, QWidget, QGridLayout, QLabel
import json import json
import pyqtgraph as pg
import numpy as np import numpy as np
import GenericDialog import GenericDialog
#from pyqtgraph.Qt import QtCore, QtGui
class MyJsonEncoder(json.JSONEncoder): class MyJsonEncoder(json.JSONEncoder):
""" Special json encoder for numpy types """ """ Special json encoder for numpy types """
@@ -31,6 +33,7 @@ class MyJsonEncoder(json.JSONEncoder):
class AppCfg(QSettings): class AppCfg(QSettings):
GBL_FLD_SCR_SHOT="global/folder_screenshot" GBL_FLD_SCR_SHOT="global/folder_screenshot"
GBL_DEV_PREFIX="global/device_prefix" #SAR-EXPMX
GEO_OPT_CTR='geometry/opt_ctr' GEO_OPT_CTR='geometry/opt_ctr'
GEO_PIX2POS='geometry/pix2pos' GEO_PIX2POS='geometry/pix2pos'
@@ -44,6 +47,11 @@ class AppCfg(QSettings):
WINDOW_SPLITTER="window/splitter" WINDOW_SPLITTER="window/splitter"
WINDOW_STATE= "window/state" WINDOW_STATE= "window/state"
DFT_POS_DET ="default_position/detector" #json
DFT_POS_PST ="default_position/post_sample_tube" #json
DFT_POS_COL ="default_position/collimator" #json
DFT_POS_BKLGT ="default_position/backlight" #json
PST_X_UP ="post_sample_tube/x_up" PST_X_UP ="post_sample_tube/x_up"
PST_Y_UP ="post_sample_tube/y_up" PST_Y_UP ="post_sample_tube/y_up"
PST_X_DOWN="post_sample_tube/x_down" PST_X_DOWN="post_sample_tube/x_down"
@@ -96,6 +104,11 @@ class AppCfg(QSettings):
# print(k, self.value(k)) # print(k, self.value(k))
#set default keys if not existing #set default keys if not existing
if AppCfg.GBL_DEV_PREFIX not in keys:
_log.warning(f'{AppCfg.GBL_DEV_PREFIX} not defined. set default')
self.setValue(AppCfg.GBL_DEV_PREFIX, ['SAR-EXPMX','SARES30-ESBMX']) #prefix deltatau,smaract
if AppCfg.GEO_BEAM_SZ not in keys: if AppCfg.GEO_BEAM_SZ not in keys:
_log.warning(f'{AppCfg.GEO_BEAM_SZ} not defined. set default') _log.warning(f'{AppCfg.GEO_BEAM_SZ} not defined. set default')
self.setValue(AppCfg.GEO_BEAM_SZ, [30.2, 25.6]) #([40, 20) -> tuples are not supported natively self.setValue(AppCfg.GEO_BEAM_SZ, [30.2, 25.6]) #([40, 20) -> tuples are not supported natively
@@ -200,7 +213,6 @@ class AppCfg(QSettings):
self.setValue(key, not v) self.setValue(key, not v)
self.sync() self.sync()
#inst_folder = Path(__file__).absolute().parent #inst_folder = Path(__file__).absolute().parent
#config_file = inst_folder / "swissmx.yaml" #config_file = inst_folder / "swissmx.yaml"
#configs = yaml.load(config_file.read_text(),Loader=yaml.FullLoader) #configs = yaml.load(config_file.read_text(),Loader=yaml.FullLoader)
@@ -410,3 +422,114 @@ class AppCfg(QSettings):
settings.setValue(k, v) settings.setValue(k, v)
settings.sync() settings.sync()
# ----------------------------------------------
class WndParameter():
def __init__(self,mainWnd):
from pyqtgraph.parametertree import Parameter, ParameterTree, ParameterItem, registerParameterType
params=[
{'name':'Basic parameter data types', 'type':'group', 'children':[
{'name':'Integer', 'type':'int', 'value':10},
{'name':'Float', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'Subgroup', 'type':'group', 'children':[
{'name':'Sub-param 1', 'type':'int', 'value':10},
{'name':'Sub-param 2', 'type':'float', 'value':1.2e6},
]},
]},
{'name':'geometry', 'type':'group', 'children':[
{'name':'size of the beam', 'type':'group', 'children':[
{'name':'width', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'height', 'type':'float', 'value':10.5, 'step':0.1},
]},
]},
{'name':'post sample tube reference positions', 'type':'group', 'children':[
{'name':'Up X', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'Up Y', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'Down X', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'Down Y', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'out delta X', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'out delta Y', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'tube Z in position', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'tube Z OUT position', 'type':'float', 'value':10.5, 'step':0.1},
]},
{'name':'collimator reference positions', 'type':'group', 'children':[
{'name':'in X', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'in Y', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'out deltaX', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'out deltaY', 'type':'float', 'value':10.5, 'step':0.1},
]},
{'name':'Back Light reference positions', 'type':'group', 'children':[
{'name':'In position', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'Out position', 'type':'float', 'value':0.0, 'step':0.1},
]},
{'name':'Delta Tau Parameters', 'type':'group', 'children':[
{'name':'host name (host[:port:port_gather])', 'type':'float', 'value':10.5, 'step':0.1},
{'name':'show plots after collection', 'type':'bool', 'value':True, 'tip':"This is a checkbox"},
]},
{'name':'Save/Restore functionality', 'type':'group', 'children':[
{'name':'Save State', 'type':'action'},
{'name':'Restore State', 'type':'action', 'children':[
{'name':'Add missing items', 'type':'bool', 'value':True},
{'name':'Remove extra items', 'type':'bool', 'value':True},
]},
]},
]
self._p=p=Parameter.create(name='params', type='group', children=params)
p.sigTreeStateChanged.connect(lambda a,b: self.cb_change(a,b))
# Too lazy for recursion:
for child in p.children():
child.sigValueChanging.connect(lambda a,b: self.cb_valueChanging(a,b))
for ch2 in child.children():
ch2.sigValueChanging.connect(lambda a,b: self.cb_valueChanging(a,b))
p.param('Save/Restore functionality', 'Save State').sigActivated.connect(self.cb_save)
p.param('Save/Restore functionality', 'Restore State').sigActivated.connect(self.cb_restore)
t=ParameterTree()
t.setParameters(p, showTop=False)
t.setWindowTitle('pyqtgraph example: Parameter Tree')
t.resize(400, 800)
self._wnd=t
def cb_change(self,param, changes):
p=self._p
print("tree changes:")
for param, change, data in changes:
path=p.childPath(param)
if path is not None:
childName='.'.join(path)
else:
childName=param.name()
print(' parameter: %s'%childName)
print(' change: %s'%change)
print(' data: %s'%str(data))
print(' ----------')
def cb_valueChanging(self,param, value):
print("Value changing (not finalized): %s %s"%(param, value))
def cb_save(self):
self._state=p.saveState()
def cb_restore(self):
add=p['Save/Restore functionality', 'Restore State', 'Add missing items']
rem=p['Save/Restore functionality', 'Restore State', 'Remove extra items']
p.restoreState(self._state, addChildren=add, removeChildren=rem)
## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
import sys
app=QApplication([])
## Create tree of Parameter objects
cfg=AppCfg()
w=WndParameter(None)
w._wnd.show()
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QApplication.instance().exec_()

View File

@@ -598,6 +598,13 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
action.triggered.connect(cfg.dlg_deltatau_parameters) action.triggered.connect(cfg.dlg_deltatau_parameters)
self.menuAdvanced.addAction(action) self.menuAdvanced.addAction(action)
action = QAction("parameters", self)
action.setToolTip("modify application parameters")
action.setStatusTip("modify application parameters")
action.triggered.connect(lambda x: cfg.dlg_parameters(self))
self.menuAdvanced.addAction(action)
#action = QAction("Cryojet Reference Positions", self) #action = QAction("Cryojet Reference Positions", self)
#action.setToolTip("Update the reference positions for the cryojet nozzle position") #action.setToolTip("Update the reference positions for the cryojet nozzle position")
#action.setStatusTip("Update the reference positions for the cryojet nozzle position") #action.setStatusTip("Update the reference positions for the cryojet nozzle position")
@@ -887,32 +894,36 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
self._message_critical_fault.setText(msg) self._message_critical_fault.setText(msg)
def build_group_faststage(self, toolbox): def build_group_faststage(self, toolbox):
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
qutilities.add_item_to_toolbox(toolbox,"Fast Stage", qutilities.add_item_to_toolbox(toolbox,"Fast Stage",
widget_list=[ widget_list=[
# self.get_tweaker('SAR-EXPMX:MOT_BLGT', alias='backlight', label='backlight'), #self.get_tweaker('f"{pfx}:MOT_BLGT', alias='backlight', label='backlight'),
self.get_tweaker("SAR-EXPMX:MOT_FY", alias="fast_y", label="fast Y"), self.get_tweaker(f"{pfx}:MOT_FY", alias="fast_y", label="fast Y"),
self.get_tweaker("SAR-EXPMX:MOT_FX", alias="fast_x", label="fast X"), self.get_tweaker(f"{pfx}:MOT_FX", alias="fast_x", label="fast X"),
self.get_tweaker("SAR-EXPMX:MOT_ROT_Y",alias="omega",label="omega",tweak_min=0.001,tweak_max=180.0,), self.get_tweaker(f"{pfx}:MOT_ROT_Y",alias="omega",label="omega",tweak_min=0.001,tweak_max=180.0,),
self.get_tweaker("SAR-EXPMX:MOT_CX", alias="base_x", label="base X"), self.get_tweaker(f"{pfx}:MOT_CX", alias="base_x", label="base X"),
self.get_tweaker("SAR-EXPMX:MOT_CZ", alias="base_z", label="base Z"), self.get_tweaker(f"{pfx}:MOT_CZ", alias="base_z", label="base Z"),
self.get_tweaker(f"{pfx}:MOT_DET_Z", alias="det_z", label="detector Z"),
], ],
) )
def build_group_collimator(self, toolbox): def build_group_collimator(self, toolbox):
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[1]
qutilities.add_item_to_toolbox(toolbox,"Collimator", qutilities.add_item_to_toolbox(toolbox,"Collimator",
widget_list=[ widget_list=[
self.get_tweaker("SARES30-ESBMX1", alias="colli_x", label="colli X", mtype="smaract_motor",), self.get_tweaker(f"{pfx}1", alias="colli_x", label="colli X", mtype="smaract_motor",),
self.get_tweaker("SARES30-ESBMX2", alias="colli_y", label="colli Y", mtype="smaract_motor",), self.get_tweaker(f"{pfx}2", alias="colli_y", label="colli Y", mtype="smaract_motor",),
], ],
) )
def build_group_posttube(self, toolbox): def build_group_posttube(self, toolbox):
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[1]
widgets = [ widgets = [
self.get_tweaker("SARES30-ESBMX4", alias="tube_usx", label="upstream X", mtype="smaract_motor",), self.get_tweaker(f"{pfx}4", alias="tube_usx", label="upstream X", mtype="smaract_motor",),
self.get_tweaker("SARES30-ESBMX6", alias="tube_usy", label="upstream Y", mtype="smaract_motor",), self.get_tweaker(f"{pfx}6", alias="tube_usy", label="upstream Y", mtype="smaract_motor",),
self.get_tweaker("SARES30-ESBMX5", alias="tube_dsx", label="downstream X", mtype="smaract_motor",), self.get_tweaker(f"{pfx}5", alias="tube_dsx", label="downstream X", mtype="smaract_motor",),
self.get_tweaker("SARES30-ESBMX7", alias="tube_dsy", label="downstream Y", mtype="smaract_motor",), self.get_tweaker(f"{pfx}7", alias="tube_dsy", label="downstream Y", mtype="smaract_motor",),
self.get_tweaker("SARES30-ESBMX8", alias="tube_z", label="tube Z", mtype="smaract_motor"), self.get_tweaker(f"{pfx}8", alias="tube_z", label="tube Z", mtype="smaract_motor"),
] ]
c = QWidget() c = QWidget()
c.setLayout(QGridLayout()) c.setLayout(QGridLayout())
@@ -937,12 +948,13 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
toolbox.addItem(block, label) toolbox.addItem(block, label)
def build_group_xeye(self, toolbox): def build_group_xeye(self, toolbox):
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[1]
qutilities.add_item_to_toolbox( qutilities.add_item_to_toolbox(
toolbox, toolbox,
"X-Ray Eye", "X-Ray Eye",
widget_list=[ widget_list=[
self.get_tweaker("SARES30-ESBMX14", alias="xeye_x", label="X", mtype="smaract_motor"), self.get_tweaker(f"{pfx}14", alias="xeye_x", label="X", mtype="smaract_motor"),
self.get_tweaker("SARES30-ESBMX15", alias="xeye_y", label="Y", mtype="smaract_motor"), self.get_tweaker(f"{pfx}15", alias="xeye_y", label="Y", mtype="smaract_motor"),
], ],
) )
@@ -1516,8 +1528,9 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
self.close() self.close()
def cb_deltatau_home_faststages(self): def cb_deltatau_home_faststages(self):
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
_log.warning("homing fast stages") _log.warning("homing fast stages")
epics.PV("SAR-EXPMX1:ASYN.AOUT").put(b"enable plc 1") epics.PV(f"{pfx}1:ASYN.AOUT").put(b"enable plc 1")
def cb_testcode(self): def cb_testcode(self):
try: try:
@@ -2087,6 +2100,32 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
usy.move_rel(-tandem_twv) usy.move_rel(-tandem_twv)
dsy.move_rel(-tandem_twv) dsy.move_rel(-tandem_twv)
def move_detector(self, pos):
#SAR-EXPMX: MOT_DET_Z.VAL
app=QApplication.instance()
cfg=app._cfg
det_z = self.tweakers["det_z"]
if AppCfg.DFT_POS_DET not in cfg.allKeys():
msg="detector default positions are not configured."
_log.warning(msg)
QMessageBox.warning(self, "configuration incomplete", msg)
return
pos = cfg.value(AppCfg.DFT_POS_DET)
_log.info("moving collimator {} to X,Y = {:.3f}, {:.3f}".format(pos, x_pos, y_pos))
if pos == "out":
cy.move_abs(y_pos+dy, assert_position=True)
cx.move_abs(x_pos+dx, assert_position=True)
elif pos == "in":
cx.move_abs(x_pos, assert_position=True)
cy.move_abs(y_pos, assert_position=True)
elif pos == "ready":
cx.move_abs(x_pos, assert_position=True)
cy.move_abs(y_pos+dy, assert_position=True)
else:
raise ValueError("Collimator position *{}* is not known!!")
def move_collimator(self, pos): def move_collimator(self, pos):
app=QApplication.instance() app=QApplication.instance()
cfg=app._cfg cfg=app._cfg
@@ -2118,6 +2157,7 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
else: else:
raise ValueError("Collimator position *{}* is not known!!") raise ValueError("Collimator position *{}* is not known!!")
# **************** OBSOLETE AND/OR OLD STUFF **************** # **************** OBSOLETE AND/OR OLD STUFF ****************
@@ -2737,37 +2777,40 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
cx.move_abs(to_pos, assert_position=True) cx.move_abs(to_pos, assert_position=True)
def _OLD_build_cryo_group(self, toolbox): def _OLD_build_cryo_group(self, toolbox):
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
qutilities.add_item_to_toolbox( qutilities.add_item_to_toolbox(
toolbox, toolbox,
"Cryojet", "Cryojet",
widget_list=[ widget_list=[
self.get_tweaker("SAR-EXPMX:MOT_CRYO", alias="cryo", label="cryo X") self.get_tweaker(f"{pfx}:MOT_CRYO", alias="cryo", label="cryo X")
], ],
) )
def _OLD_build_wegde_group(self, toolbox): def _OLD_build_wegde_group(self, toolbox):
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
qutilities.add_item_to_toolbox(toolbox,"Wedge Mover", qutilities.add_item_to_toolbox(toolbox,"Wedge Mover",
widget_list=[ widget_list=[
self.get_tweaker("SAR-EXPMX:MOT_WEDGE1", alias="wedge_1", label="wedge_1"), self.get_tweaker(f"{pfx}:MOT_WEDGE1", alias="wedge_1", label="wedge_1"),
self.get_tweaker("SAR-EXPMX:MOT_WEDGE2", alias="wedge_2", label="wedge_2"), self.get_tweaker(f"{pfx}:MOT_WEDGE2", alias="wedge_2", label="wedge_2"),
self.get_tweaker("SAR-EXPMX:MOT_WEDGE3", alias="wedge_3", label="wedge_3"), self.get_tweaker(f"{pfx}:MOT_WEDGE3", alias="wedge_3", label="wedge_3"),
self.get_tweaker("SAR-EXPMX:MOT_WEDGE4", alias="wedge_4", label="wedge_4"), self.get_tweaker(f"{pfx}:MOT_WEDGE4", alias="wedge_4", label="wedge_4"),
self.get_tweaker("SAR-EXPMX:MOT_WEDGEX", alias="wedge_x", label="wedge_x"), self.get_tweaker(f"{pfx}:MOT_WEDGEX", alias="wedge_x", label="wedge_x"),
self.get_tweaker("SAR-EXPMX:MOT_WEDGEY", alias="wedge_y", label="wedge_y"), self.get_tweaker(f"{pfx}:MOT_WEDGEY", alias="wedge_y", label="wedge_y"),
self.get_tweaker("SAR-EXPMX:MOT_WEDGEA", alias="wedge_a", label="wedge_a"), self.get_tweaker(f"{pfx}:MOT_WEDGEA", alias="wedge_a", label="wedge_a"),
self.get_tweaker("SAR-EXPMX:MOT_WEDGEB", alias="wedge_b", label="wedge_b"), self.get_tweaker(f"{pfx}:MOT_WEDGEB", alias="wedge_b", label="wedge_b"),
], ],
) )
def _OLD_build_slits_group(self, toolbox): def _OLD_build_slits_group(self, toolbox):
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
qutilities.add_item_to_toolbox( qutilities.add_item_to_toolbox(
toolbox, toolbox,
"Slits", "Slits",
widget_list=[ widget_list=[
self.get_tweaker("SARES30-ESBMX10", alias="slit_right", label="left", mtype="smaract_motor", ), self.get_tweaker(f"{pfx}10", alias="slit_right", label="left", mtype="smaract_motor", ),
self.get_tweaker("SARES30-ESBMX11", alias="slit_left", label="right", mtype="smaract_motor",), self.get_tweaker(f"{pfx}11", alias="slit_left", label="right", mtype="smaract_motor",),
self.get_tweaker("SARES30-ESBMX12", alias="slit_bottom", label="bottom", mtype="smaract_motor",), self.get_tweaker(f"{pfx}12", alias="slit_bottom", label="bottom", mtype="smaract_motor",),
self.get_tweaker("SARES30-ESBMX13",alias="slit_top",label="top",mtype="smaract_motor",), self.get_tweaker(f"{pfx}13",alias="slit_top",label="top",mtype="smaract_motor",),
], ],
) )