rework config/parameter setting
This commit is contained in:
127
app_config.py
127
app_config.py
@@ -9,11 +9,13 @@ import logging
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
from PyQt5.QtCore import QSettings
|
||||
from PyQt5.QtWidgets import QApplication, QLineEdit
|
||||
from PyQt5.QtWidgets import QApplication, QLineEdit, QWidget, QGridLayout, QLabel
|
||||
import json
|
||||
import pyqtgraph as pg
|
||||
import numpy as np
|
||||
import GenericDialog
|
||||
|
||||
#from pyqtgraph.Qt import QtCore, QtGui
|
||||
|
||||
class MyJsonEncoder(json.JSONEncoder):
|
||||
""" Special json encoder for numpy types """
|
||||
@@ -31,6 +33,7 @@ class MyJsonEncoder(json.JSONEncoder):
|
||||
|
||||
class AppCfg(QSettings):
|
||||
GBL_FLD_SCR_SHOT="global/folder_screenshot"
|
||||
GBL_DEV_PREFIX="global/device_prefix" #SAR-EXPMX
|
||||
|
||||
GEO_OPT_CTR='geometry/opt_ctr'
|
||||
GEO_PIX2POS='geometry/pix2pos'
|
||||
@@ -44,6 +47,11 @@ class AppCfg(QSettings):
|
||||
WINDOW_SPLITTER="window/splitter"
|
||||
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_Y_UP ="post_sample_tube/y_up"
|
||||
PST_X_DOWN="post_sample_tube/x_down"
|
||||
@@ -96,6 +104,11 @@ class AppCfg(QSettings):
|
||||
# print(k, self.value(k))
|
||||
|
||||
#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:
|
||||
_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
|
||||
@@ -200,7 +213,6 @@ class AppCfg(QSettings):
|
||||
self.setValue(key, not v)
|
||||
self.sync()
|
||||
|
||||
|
||||
#inst_folder = Path(__file__).absolute().parent
|
||||
#config_file = inst_folder / "swissmx.yaml"
|
||||
#configs = yaml.load(config_file.read_text(),Loader=yaml.FullLoader)
|
||||
@@ -410,3 +422,114 @@ class AppCfg(QSettings):
|
||||
settings.setValue(k, v)
|
||||
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_()
|
||||
|
||||
101
swissmx.py
101
swissmx.py
@@ -598,6 +598,13 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
action.triggered.connect(cfg.dlg_deltatau_parameters)
|
||||
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.setToolTip("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)
|
||||
|
||||
def build_group_faststage(self, toolbox):
|
||||
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
|
||||
qutilities.add_item_to_toolbox(toolbox,"Fast Stage",
|
||||
widget_list=[
|
||||
# self.get_tweaker('SAR-EXPMX:MOT_BLGT', alias='backlight', label='backlight'),
|
||||
self.get_tweaker("SAR-EXPMX:MOT_FY", alias="fast_y", label="fast Y"),
|
||||
self.get_tweaker("SAR-EXPMX: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("SAR-EXPMX: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_BLGT', alias='backlight', label='backlight'),
|
||||
self.get_tweaker(f"{pfx}:MOT_FY", alias="fast_y", label="fast Y"),
|
||||
self.get_tweaker(f"{pfx}:MOT_FX", alias="fast_x", label="fast X"),
|
||||
self.get_tweaker(f"{pfx}:MOT_ROT_Y",alias="omega",label="omega",tweak_min=0.001,tweak_max=180.0,),
|
||||
self.get_tweaker(f"{pfx}:MOT_CX", alias="base_x", label="base X"),
|
||||
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):
|
||||
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[1]
|
||||
qutilities.add_item_to_toolbox(toolbox,"Collimator",
|
||||
widget_list=[
|
||||
self.get_tweaker("SARES30-ESBMX1", 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}1", alias="colli_x", label="colli X", mtype="smaract_motor",),
|
||||
self.get_tweaker(f"{pfx}2", alias="colli_y", label="colli Y", mtype="smaract_motor",),
|
||||
],
|
||||
)
|
||||
|
||||
def build_group_posttube(self, toolbox):
|
||||
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[1]
|
||||
widgets = [
|
||||
self.get_tweaker("SARES30-ESBMX4", 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("SARES30-ESBMX5", 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("SARES30-ESBMX8", alias="tube_z", label="tube Z", mtype="smaract_motor"),
|
||||
self.get_tweaker(f"{pfx}4", alias="tube_usx", label="upstream X", mtype="smaract_motor",),
|
||||
self.get_tweaker(f"{pfx}6", alias="tube_usy", label="upstream Y", mtype="smaract_motor",),
|
||||
self.get_tweaker(f"{pfx}5", alias="tube_dsx", label="downstream X", mtype="smaract_motor",),
|
||||
self.get_tweaker(f"{pfx}7", alias="tube_dsy", label="downstream Y", mtype="smaract_motor",),
|
||||
self.get_tweaker(f"{pfx}8", alias="tube_z", label="tube Z", mtype="smaract_motor"),
|
||||
]
|
||||
c = QWidget()
|
||||
c.setLayout(QGridLayout())
|
||||
@@ -937,12 +948,13 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
toolbox.addItem(block, label)
|
||||
|
||||
def build_group_xeye(self, toolbox):
|
||||
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[1]
|
||||
qutilities.add_item_to_toolbox(
|
||||
toolbox,
|
||||
"X-Ray Eye",
|
||||
widget_list=[
|
||||
self.get_tweaker("SARES30-ESBMX14", 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}14", alias="xeye_x", label="X", 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()
|
||||
|
||||
def cb_deltatau_home_faststages(self):
|
||||
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
|
||||
_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):
|
||||
try:
|
||||
@@ -2087,6 +2100,32 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
usy.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):
|
||||
app=QApplication.instance()
|
||||
cfg=app._cfg
|
||||
@@ -2118,6 +2157,7 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
else:
|
||||
raise ValueError("Collimator position *{}* is not known!!")
|
||||
|
||||
|
||||
# **************** OBSOLETE AND/OR OLD STUFF ****************
|
||||
|
||||
|
||||
@@ -2737,37 +2777,40 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
cx.move_abs(to_pos, assert_position=True)
|
||||
|
||||
def _OLD_build_cryo_group(self, toolbox):
|
||||
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
|
||||
qutilities.add_item_to_toolbox(
|
||||
toolbox,
|
||||
"Cryojet",
|
||||
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):
|
||||
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
|
||||
qutilities.add_item_to_toolbox(toolbox,"Wedge Mover",
|
||||
widget_list=[
|
||||
self.get_tweaker("SAR-EXPMX:MOT_WEDGE1", alias="wedge_1", label="wedge_1"),
|
||||
self.get_tweaker("SAR-EXPMX:MOT_WEDGE2", alias="wedge_2", label="wedge_2"),
|
||||
self.get_tweaker("SAR-EXPMX:MOT_WEDGE3", alias="wedge_3", label="wedge_3"),
|
||||
self.get_tweaker("SAR-EXPMX:MOT_WEDGE4", alias="wedge_4", label="wedge_4"),
|
||||
self.get_tweaker("SAR-EXPMX:MOT_WEDGEX", alias="wedge_x", label="wedge_x"),
|
||||
self.get_tweaker("SAR-EXPMX:MOT_WEDGEY", alias="wedge_y", label="wedge_y"),
|
||||
self.get_tweaker("SAR-EXPMX: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_WEDGE1", alias="wedge_1", label="wedge_1"),
|
||||
self.get_tweaker(f"{pfx}:MOT_WEDGE2", alias="wedge_2", label="wedge_2"),
|
||||
self.get_tweaker(f"{pfx}:MOT_WEDGE3", alias="wedge_3", label="wedge_3"),
|
||||
self.get_tweaker(f"{pfx}:MOT_WEDGE4", alias="wedge_4", label="wedge_4"),
|
||||
self.get_tweaker(f"{pfx}:MOT_WEDGEX", alias="wedge_x", label="wedge_x"),
|
||||
self.get_tweaker(f"{pfx}:MOT_WEDGEY", alias="wedge_y", label="wedge_y"),
|
||||
self.get_tweaker(f"{pfx}:MOT_WEDGEA", alias="wedge_a", label="wedge_a"),
|
||||
self.get_tweaker(f"{pfx}:MOT_WEDGEB", alias="wedge_b", label="wedge_b"),
|
||||
],
|
||||
)
|
||||
|
||||
def _OLD_build_slits_group(self, toolbox):
|
||||
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
|
||||
qutilities.add_item_to_toolbox(
|
||||
toolbox,
|
||||
"Slits",
|
||||
widget_list=[
|
||||
self.get_tweaker("SARES30-ESBMX10", alias="slit_right", label="left", mtype="smaract_motor", ),
|
||||
self.get_tweaker("SARES30-ESBMX11", alias="slit_left", label="right", mtype="smaract_motor",),
|
||||
self.get_tweaker("SARES30-ESBMX12", 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}10", alias="slit_right", label="left", mtype="smaract_motor", ),
|
||||
self.get_tweaker(f"{pfx}11", alias="slit_left", label="right", mtype="smaract_motor",),
|
||||
self.get_tweaker(f"{pfx}12", alias="slit_bottom", label="bottom", mtype="smaract_motor",),
|
||||
self.get_tweaker(f"{pfx}13",alias="slit_top",label="top",mtype="smaract_motor",),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user