rework config/parameter setting part 2

This commit is contained in:
2022-09-05 15:34:40 +02:00
parent 8fc532d3ae
commit d263c09028
3 changed files with 365 additions and 329 deletions

View File

@@ -812,7 +812,7 @@ if __name__ == "__main__":
} }
elif t==3: elif t==3:
data=[ data=[
UsrGO.Grid(pos=(120.0, -100.0), size=(1000.0, 500.0), cnt=(10, 5), ficucialScale=2), UsrGO.Grid(pos=(120.0, -100.0), size=(1000.0, 500.0), cnt=(10, 5), fiducialSize=2),
Monster(name='Cave lizard', hp=[3,6], ac=16, attacks=['BITE','HURT']) Monster(name='Cave lizard', hp=[3,6], ac=16, attacks=['BITE','HURT'])
] ]
mainWin.wndFixTrg._data=data mainWin.wndFixTrg._data=data

View File

@@ -9,7 +9,7 @@ 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, QWidget, QGridLayout, QLabel from PyQt5.QtWidgets import QApplication, QMainWindow #QLineEdit, QWidget, QGridLayout, QLabel
import json import json
import pyqtgraph as pg import pyqtgraph as pg
import numpy as np import numpy as np
@@ -52,23 +52,6 @@ class AppCfg(QSettings):
DFT_POS_COL ="default_position/collimator" #json DFT_POS_COL ="default_position/collimator" #json
DFT_POS_BKLGT ="default_position/backlight" #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"
PST_Y_DOWN="post_sample_tube/y_down"
PST_DX ="post_sample_tube/dx"
PST_DY ="post_sample_tube/dy"
PST_TZ_IN ="post_sample_tube/z_in"
PST_TZ_OUT="post_sample_tube/z_out"
COL_DX ="collimator/dx"
COL_DY ="collimator/dy"
COL_X_IN ="collimator/x_in"
COL_Y_IN ="collimator/y_in"
BKLGT_IN ="backlight/in"
BKLGT_OUT ="backlight/out"
DT_HOST="deltatau/host" DT_HOST="deltatau/host"
DT_SHOW_PLOTS="deltatau/show_plots" DT_SHOW_PLOTS="deltatau/show_plots"
DT_VEL_SCL="deltatau/velocity_scale" DT_VEL_SCL="deltatau/velocity_scale"
@@ -174,7 +157,7 @@ class AppCfg(QSettings):
t=type(val) t=type(val)
if key in (AppCfg.GEO_PIX2POS,): if key in (AppCfg.GEO_PIX2POS,):
val=json.dumps(val, cls=MyJsonEncoder) val=json.dumps(val, cls=MyJsonEncoder)
elif key in (AppCfg.GEO_CAM_PARAM,): elif key in (AppCfg.GEO_CAM_PARAM,AppCfg.DFT_POS_DET,AppCfg.DFT_POS_PST,AppCfg.DFT_POS_COL,AppCfg.DFT_POS_BKLGT,):
val=json.dumps(val, cls=MyJsonEncoder) val=json.dumps(val, cls=MyJsonEncoder)
val=val.replace('"',"'") val=val.replace('"',"'")
elif key in (AppCfg.GEO_OPT_CTR,AppCfg.GEO_BEAM_SZ,AppCfg.GEO_BEAM_POS,): elif key in (AppCfg.GEO_OPT_CTR,AppCfg.GEO_BEAM_SZ,AppCfg.GEO_BEAM_POS,):
@@ -189,9 +172,10 @@ class AppCfg(QSettings):
if key in (AppCfg.GEO_PIX2POS,): if key in (AppCfg.GEO_PIX2POS,):
val=json.loads(val)#, object_hook=MyJsonDecoder) val=json.loads(val)#, object_hook=MyJsonDecoder)
val=(np.array(val[0]),np.array(val[1])) val=(np.array(val[0]),np.array(val[1]))
if key in (AppCfg.GEO_CAM_PARAM,): elif key in (AppCfg.GEO_CAM_PARAM,AppCfg.DFT_POS_DET,AppCfg.DFT_POS_PST,AppCfg.DFT_POS_COL,AppCfg.DFT_POS_BKLGT,):
val=val.replace("'",'"') if val is not None:
val=json.loads(val) # , object_hook=MyJsonDecoder) val=val.replace("'",'"')
val=json.loads(val) # , object_hook=MyJsonDecoder)
elif key in (AppCfg.GEO_BEAM_SZ,AppCfg.GEO_BEAM_POS,): elif key in (AppCfg.GEO_BEAM_SZ,AppCfg.GEO_BEAM_POS,):
val=np.array(tuple(map(float, val)))/1000 val=np.array(tuple(map(float, val)))/1000
elif key in (AppCfg.GEO_OPT_CTR): elif key in (AppCfg.GEO_OPT_CTR):
@@ -213,6 +197,181 @@ class AppCfg(QSettings):
self.setValue(key, not v) self.setValue(key, not v)
self.sync() self.sync()
from pyqtgraph.parametertree import Parameter, ParameterTree
class WndParameter(QMainWindow):
def __init__(self, parent=None):
super(WndParameter, self).__init__(parent)
app=QApplication.instance()
cfg=app._cfg
#GBL_FLD_SCR_SHOT="global/folder_screenshot"
#GBL_DEV_PREFIX="global/device_prefix" # SAR-EXPMX
#GEO_OPT_CTR
#GEO_PIX2POS
#GEO_BEAM_POS
#GEO_CAM_PARAM
geo_beam_sz = cfg.value(AppCfg.GEO_BEAM_SZ)*1000
dft_pos_pst = cfg.value(AppCfg.DFT_POS_PST)
dft_pos_col = cfg.value(AppCfg.DFT_POS_COL)
dft_pos_bklgt = cfg.value(AppCfg.DFT_POS_BKLGT)
dft_pos_det = cfg.value(AppCfg.DFT_POS_DET)
geo_cam_param = cfg.value(AppCfg.GEO_CAM_PARAM)
gbl_dev_prefix = cfg.value(AppCfg.GBL_DEV_PREFIX)
dt_host = cfg.value(AppCfg.DT_HOST)
dt_show_plots = cfg.value(AppCfg.DT_SHOW_PLOTS)
dt_vel_scl = cfg.value(AppCfg.DT_VEL_SCL)
if dft_pos_pst is None:dft_pos_pst={}
if dft_pos_col is None:dft_pos_col={}
if dft_pos_bklgt is None:dft_pos_bklgt={}
if dft_pos_det is None:dft_pos_det={}
params=[
{'name':'geometry','type':'group', 'children':[
{'name': AppCfg.GEO_BEAM_SZ, 'title':'size of the beam', 'type':'group', 'children':[
{'name':'width', 'type':'float', 'value':geo_beam_sz[0], 'step':0.1,'suffix':' um'},
{'name':'height', 'type':'float', 'value':geo_beam_sz[1], 'step':0.1,'suffix':' um'},
#{'name':'TEST', 'type':'float', 'value':10.5, 'step':0.001, 'decimals':5},
]},
]},
{'name': AppCfg.DFT_POS_PST, 'title':'post sample tube reference positions', 'type':'group', 'children':[
{'name':'Up X' ,'value':dft_pos_pst.get('x_up' ,0),'type':'float','limits':(-45,15),'step':0.1,'decimals':5,'suffix':' mm'},
{'name':'Up Y' ,'value':dft_pos_pst.get('y_up' ,0),'type':'float','limits':(-45,15),'step':0.1,'decimals':5,'suffix':' mm'},
{'name':'Down X' ,'value':dft_pos_pst.get('x_down' ,0),'type':'float','limits':(-45,15),'step':0.1,'decimals':5,'suffix':' mm'},
{'name':'Down Y' ,'value':dft_pos_pst.get('y_down' ,0),'type':'float','limits':(-45,15),'step':0.1,'decimals':5,'suffix':' mm'},
{'name':'out delta X' ,'value':dft_pos_pst.get('x_out_delta',0),'type':'float','limits':(-32,32),'step':0.1,'decimals':5,'suffix':' mm'},
{'name':'out delta Y' ,'value':dft_pos_pst.get('y_out_delta',0),'type':'float','limits':(-32,32),'step':0.1,'decimals':5,'suffix':' mm'},
{'name':'tube Z in position' ,'value':dft_pos_pst.get('z_in' ,0),'type':'float','limits':(-8 ,1 ),'step':0.1,'decimals':5,'suffix':' mm'},
{'name':'tube Z OUT position','value':dft_pos_pst.get('z_out' ,0),'type':'float','limits':(-8 ,1 ),'step':0.1,'decimals':5,'suffix':' mm'},
]},
{'name': AppCfg.DFT_POS_COL, 'title':'collimator reference positions', 'type':'group', 'children':[
{'name':'in X', 'value':dft_pos_col.get('x_in',0), 'type':'float', 'limits':(-15.9, 15.9 ),'step':0.1, 'decimals':5, 'suffix':' mm'},
{'name':'in Y', 'value':dft_pos_col.get('y_in',0), 'type':'float', 'limits':(-15.9, 15.9 ),'step':0.1, 'decimals':5, 'suffix':' mm'},
{'name':'out deltaX', 'value':dft_pos_col.get('x_out_delta',0),'type':'float', 'limits':(-15.9, 15.9 ),'step':0.1, 'decimals':5, 'suffix':' mm'},
{'name':'out deltaY', 'value':dft_pos_col.get('y_out_delta',0),'type':'float', 'limits':(-15.9, 15.9 ),'step':0.1, 'decimals':5, 'suffix':' mm'},
]},
{'name': AppCfg.DFT_POS_BKLGT, 'title':'Back Light reference positions', 'type':'group', 'children':[
{'name':'In position', 'value':dft_pos_bklgt.get('pos_in',0), 'type':'float', 'limits':(-30000, 10 ),'step':10, 'decimals':5, 'suffix':'ustep'},
{'name':'Out position', 'value':dft_pos_bklgt.get('pos_out',0), 'type':'float', 'limits':(-1000, 10 ),'step':10, 'decimals':5, 'suffix':'ustep'},
]},
{'name': AppCfg.DFT_POS_DET, 'title':'detector reference positions', 'type':'group', 'children':[
{'name':'In position', 'value':dft_pos_det.get('pos_in',0), 'type':'float', 'limits':(-20, 20 ),'step':0.1, 'decimals':5, 'suffix':' mm'},
{'name':'Out position', 'value':dft_pos_det.get('pos_out',0), 'type':'float', 'limits':(-20, 20 ),'step':0.1, 'decimals':5, 'suffix':' mm'},
]},
{'name': AppCfg.GBL_DEV_PREFIX, 'title':'device prefix', 'type':'group', 'children':[
{'name':'deltatau motors', 'value':gbl_dev_prefix[0],'type':'str' },
{'name':'smaract motors', 'value':gbl_dev_prefix[1],'type':'str' },
]},
{'name':AppCfg.GEO_CAM_PARAM, 'title':'camera parameters', 'type':'group', 'children':[
{'name':'gain', 'value':geo_cam_param.get('gain',0), 'type':'float', 'step':1, },
{'name':'exposure', 'value':geo_cam_param.get('exposure',0), 'type':'float', 'step':1, },
{'name':'binning', 'value':geo_cam_param.get('binning','[1,1]'),'type':'str'},
{'name':'roi', 'value':geo_cam_param.get('roi','[1,2,3,4]'),'type':'str'},
{'name':'mono8', 'value':geo_cam_param.get('mono8','0'), 'type':'str'},
]},
{'name':'Delta Tau Parameters', 'type':'group', 'children':[
{'name':AppCfg.DT_HOST ,'title':'host name (host[:port:port_gather])','value':dt_host ,'type':'str'} ,
{'name':AppCfg.DT_SHOW_PLOTS,'title':'show plots after collection' ,'value':dt_show_plots,'type':'bool' ,'tip':"This is a checkbox"},
{'name':AppCfg.DT_VEL_SCL ,'title':'velocity_scale' ,'value':dt_vel_scl ,'type':'float','limits':(0,1),'step':0.1,'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)
self._paramTree=pt=ParameterTree(parent=self)
pt.setParameters(p, showTop=False)
pt.setWindowTitle('SwissMX parameters')
#t.resize(600, 800)
self.setCentralWidget(pt)
self.move(100, 100)
self.resize(600, 800)
def cb_change(self,paramAll, changes):
app=QApplication.instance()
cfg=app._cfg
assert(self._p==paramAll)
#param.parent()
for param, change, data in changes:
path=paramAll.childPath(param)
if path is not None:
childName='.'.join(path)
else:
childName=param.name()
_log.debug(f'parameter:{childName} change:{change} data:{str(data)}')
parent=param.parent()
par_nm=parent.name()
nm=param.name()
if par_nm in(AppCfg.DT_HOST,AppCfg.DT_SHOW_PLOTS,AppCfg.DT_VEL_SCL):
cfg.setValue(nm,param.value())
elif par_nm==AppCfg.GEO_BEAM_SZ:
v = np.array(tuple(map(lambda x: x.value(),parent.children())))
cfg.setValue(par_nm,v)
try:
bm=self.parent()._goBeamMarker
except AttributeError as e:
_log.warning('can not set beam size to application window')
else:
bm.setSize(v)
elif par_nm == AppCfg.DFT_POS_PST:
k=tuple(map(lambda x: x.name(),parent.children()))
k=('x_up','y_up','x_down','y_down','x_out_delta','y_out_delta','z_in','z_out',)
v = tuple(map(lambda x: x.value(),parent.children()))
d=dict(zip(k,v))
cfg.setValue(par_nm,d)
elif par_nm == AppCfg.DFT_POS_COL:
k=tuple(map(lambda x: x.name(),parent.children()))
k=('x_in','y_in','x_out_delta','y_out_delta')
v = tuple(map(lambda x: x.value(),parent.children()))
d=dict(zip(k,v))
cfg.setValue(par_nm,d)
elif par_nm == AppCfg.DFT_POS_BKLGT:
k=tuple(map(lambda x: x.name(),parent.children()))
k=('pos_in','pos_out')
v = tuple(map(lambda x: x.value(),parent.children()))
d=dict(zip(k,v))
cfg.setValue(par_nm,d)
elif par_nm == AppCfg.DFT_POS_DET:
k=tuple(map(lambda x: x.name(),parent.children()))
k=('pos_in','pos_out')
v = tuple(map(lambda x: x.value(),parent.children()))
d=dict(zip(k,v))
cfg.setValue(par_nm,d)
elif par_nm == AppCfg.GBL_DEV_PREFIX:
v = tuple(map(lambda x: x.value(),parent.children()))
cfg.setValue(par_nm,v)
cfg.sync()
def cb_valueChanging(self,param, value):
_log.debug(f'Value changing (not finalized): {param}, {value}')
def cb_save(self):
self._state=p.saveState()
def cb_restore(self):
p=self._p
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)
# ----------------------------- OBSOLETE -----------------------------
#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)
@@ -239,296 +398,168 @@ class AppCfg(QSettings):
# return str(p) # return str(p)
def dlg_geometry(self,obj): # def dlg_geometry(self,obj):
SPN=GenericDialog.Spinner # SPN=GenericDialog.Spinner
app=QApplication.instance() # app=QApplication.instance()
cfg=app._cfg # cfg=app._cfg
w, h = map(float,cfg.value(AppCfg.GEO_BEAM_SZ)) # w, h = map(float,cfg.value(AppCfg.GEO_BEAM_SZ))
d = GenericDialog.GenericDialog( # d = GenericDialog.GenericDialog(
title="geometry", # title="geometry",
message="Enter the size of the beam in microns", # message="Enter the size of the beam in microns",
inputs={ # inputs={
"bw": ("beam width um" ,w,SPN(w, min=1, max=200, suffix=" \u00B5m"),), # "bw": ("beam width um" ,w,SPN(w, min=1, max=200, suffix=" \u00B5m"),),
"bh": ("beam height um",h,SPN(h, min=1, max=200, suffix=" \u00B5m"),), # "bh": ("beam height um",h,SPN(h, min=1, max=200, suffix=" \u00B5m"),),
}, # },
) # )
if d.exec(): # if d.exec():
results = d.results # results = d.results
_log.info("Updating beamsize to {}".format(results)) # _log.info("Updating beamsize to {}".format(results))
bm_sz= (results["bw"], results["bh"]) # bm_sz= (results["bw"], results["bh"])
_log.debug("types {}".format(type(w))) # _log.debug("types {}".format(type(w)))
cfg.setValue(AppCfg.GEO_BEAM_SZ, bm_sz) # cfg.setValue(AppCfg.GEO_BEAM_SZ, bm_sz)
cfg.sync() # cfg.sync()
bm=obj._goBeamMarker # bm=obj._goBeamMarker
bm.setSize(bm_sz) # bm.setSize(bm_sz)
#self._beammark.set_beam_size((w, h)) # #self._beammark.set_beam_size((w, h))
#
def dlg_posttube_references(self): # def dlg_collimator_reference_positions(self):
SPN=GenericDialog.Spinner # SPN=GenericDialog.Spinner
app=QApplication.instance() # app=QApplication.instance()
cfg=app._cfg # cfg=app._cfg
x_up = cfg.value(AppCfg.PST_X_UP , 0.0,type=float) # x_out = cfg.value(AppCfg.COL_DX , 0.0,type=float)
y_up = cfg.value(AppCfg.PST_Y_UP , 0.0,type=float) # y_out = cfg.value(AppCfg.COL_DY , 0.0,type=float)
x_down = cfg.value(AppCfg.PST_X_DOWN, 0.0,type=float) # x_in = cfg.value(AppCfg.COL_X_IN, 0.0,type=float)
y_down = cfg.value(AppCfg.PST_Y_DOWN, 0.0,type=float) # y_in = cfg.value(AppCfg.COL_Y_IN, 0.0,type=float)
dx = cfg.value(AppCfg.PST_DX , 0.0,type=float) # d = GenericDialog.GenericDialog(
dy = cfg.value(AppCfg.PST_DY , 0.0,type=float) # title="Collimator configuration",
tz_in = cfg.value(AppCfg.PST_TZ_IN , 0.0,type=float) # message="Enter reference positions for the collimator",
tz_out = cfg.value(AppCfg.PST_TZ_OUT, 0.0,type=float) # inputs={
# AppCfg.COL_DX: ("Collimator out deltaX", x_out, SPN(x_out, decimals=3, min=-15.9, max=15.9, suffix=" mm"),),
d = GenericDialog.GenericDialog( # AppCfg.COL_DY: ("Collimator out deltaY", y_out, SPN(y_out, decimals=3, min=-15.9, max=15.9, suffix=" mm"),),
title="Post Sample Tube Configuration", # AppCfg.COL_X_IN: ("Collimator in X", x_in, SPN(x_in, decimals=3, min=-15.9, max=15.9, suffix=" mm"),),
message="Enter the relative displacements for X and Y to move the post sample tube either in or out.", # AppCfg.COL_Y_IN: ("Collimator in Y", y_in, SPN(y_in, decimals=3, min=-15.9, max=15.9, suffix=" mm"),),
inputs={ # },
AppCfg.PST_X_UP : ("Up X" , x_up , SPN(x_up , decimals=3, min=-45.0, max=15.0, suffix=" mm"), ), # )
AppCfg.PST_Y_UP : ("Up Y" , y_up , SPN(y_up , decimals=3, min=-45.0, max=15.0, suffix=" mm"), ), # if d.exec():
AppCfg.PST_X_DOWN: ("Down X" , x_down, SPN(x_down, decimals=3, min=-45.0, max=15.0, suffix=" mm"), ), # results = d.results
AppCfg.PST_Y_DOWN: ("Down Y" , y_down, SPN(y_down, decimals=3, min=-45.0, max=15.0, suffix=" mm"), ), # _log.info("setting collimator reference positions {}".format(results))
AppCfg.PST_DX : ("out delta X" , dx , SPN(dx , decimals=3, min=-32.0, max=32.0, suffix=" mm"), ), # for k, v in results.items():
AppCfg.PST_DY : ("out delta Y" , dy , SPN(dy , decimals=3, min=-32.0, max=32.0, suffix=" mm"), ), # cfg.setValue(k, v)
AppCfg.PST_TZ_IN : ("tube Z in position" , tz_in , SPN(tz_in , decimals=3, min=-8.0 , max=1.0 , suffix=" mm"), ), # cfg.sync()
AppCfg.PST_TZ_OUT: ("tube Z OUT position", tz_out, SPN(tz_out, decimals=3, min=-8.0 , max=1.0 , suffix=" mm"), ), #
}, # def dlg_backlight_positions(self):
) # SPN=GenericDialog.Spinner
if d.exec(): # app=QApplication.instance()
results = d.results # cfg=app._cfg
_log.info("setting post-sample-tube displacements {}".format(results)) # p_in = cfg.value(AppCfg.BKLGT_IN,0,type=int)
for k, v in results.items(): # p_out = cfg.value(AppCfg.BKLGT_OUT,0,type=int)
cfg.setValue(k, v) # d = GenericDialog.GenericDialog(
cfg.sync() # title="Back Light configuration",
# message="Enter reference positions for the backlight",
def dlg_collimator_reference_positions(self): # inputs={
SPN=GenericDialog.Spinner # AppCfg.BKLGT_IN: ("In position" , p_in , SPN(p_in, min=-30000, max=10), ),
app=QApplication.instance() # AppCfg.BKLGT_OUT: ("Out position", p_out, SPN(p_out, min=-1000, max=10), ),
cfg=app._cfg # },
x_out = cfg.value(AppCfg.COL_DX , 0.0,type=float) # )
y_out = cfg.value(AppCfg.COL_DY , 0.0,type=float) # if d.exec():
x_in = cfg.value(AppCfg.COL_X_IN, 0.0,type=float) # results = d.results
y_in = cfg.value(AppCfg.COL_Y_IN, 0.0,type=float) # _log.info("setting back light reference positions {}".format(results))
d = GenericDialog.GenericDialog( # for k, v in results.items():
title="Collimator configuration", # cfg.setValue(k, v)
message="Enter reference positions for the collimator", # cfg.sync()
inputs={ #
AppCfg.COL_DX: ("Collimator out deltaX", x_out, SPN(x_out, decimals=3, min=-15.9, max=15.9, suffix=" mm"),), # def dlg_cryojet_positions(self):
AppCfg.COL_DY: ("Collimator out deltaY", y_out, SPN(y_out, decimals=3, min=-15.9, max=15.9, suffix=" mm"),), # p_in = settings.value(CRYOJET_NOZZLE_IN, type=float)
AppCfg.COL_X_IN: ("Collimator in X", x_in, SPN(x_in, decimals=3, min=-15.9, max=15.9, suffix=" mm"),), # p_out = settings.value(CRYOJET_NOZZLE_OUT, type=float)
AppCfg.COL_Y_IN: ("Collimator in Y", y_in, SPN(y_in, decimals=3, min=-15.9, max=15.9, suffix=" mm"),), # motion_enabled = option(CRYOJET_MOTION_ENABLED)
}, # d = GenericDialog(
) # title="Cryojet Nozzle Configuration",
if d.exec(): # message="Enter reference positions for the cryojet nozzle position",
results = d.results # inputs={
_log.info("setting collimator reference positions {}".format(results)) # CRYOJET_NOZZLE_IN: ("In position", p_in, Spinner(p_in, min=3, max=15)),
for k, v in results.items(): # CRYOJET_NOZZLE_OUT: ("Out position",p_out,Spinner(p_out, min=-1000, max=10),),
cfg.setValue(k, v) # CRYOJET_MOTION_ENABLED: ("Move Cryojet in Transitions",motion_enabled,Checkbox(motion_enabled, "move cryojet"),),
cfg.sync() # },
# )
def dlg_backlight_positions(self): # if d.exec():
SPN=GenericDialog.Spinner # results = d.results
app=QApplication.instance() # _log.info("setting cryojet reference positions {}".format(results))
cfg=app._cfg # for k, v in results.items():
p_in = cfg.value(AppCfg.BKLGT_IN,0,type=int) # settings.setValue(k, v)
p_out = cfg.value(AppCfg.BKLGT_OUT,0,type=int) # settings.sync()
d = GenericDialog.GenericDialog( #
title="Back Light configuration", # def dlg_deltatau_parameters(self):
message="Enter reference positions for the backlight", # SPN=GenericDialog.Spinner
inputs={ # CB=GenericDialog.Checkbox
AppCfg.BKLGT_IN: ("In position" , p_in , SPN(p_in, min=-30000, max=10), ), # app=QApplication.instance()
AppCfg.BKLGT_OUT: ("Out position", p_out, SPN(p_out, min=-1000, max=10), ), # cfg=app._cfg
}, # #dt1 = cfg.value(AppCfg.DT_HOST,'SAR-CPPM-EXPMX1')
) # dt1 = cfg.value(AppCfg.DT_HOST)
if d.exec(): # dt2 = cfg.value(AppCfg.DT_VEL_SCL, 1, type=float)
results = d.results # dt3 = cfg.option(AppCfg.DT_SHOW_PLOTS)
_log.info("setting back light reference positions {}".format(results)) #
for k, v in results.items(): # d = GenericDialog.GenericDialog(
cfg.setValue(k, v) # title="Delta Tau Parameters",
cfg.sync() # message="These parameters affect the data collection.",
# inputs={
def dlg_cryojet_positions(self): # AppCfg.DT_HOST:("host name (host[:port:port_gather])", dt1, QLineEdit(),),
p_in = settings.value(CRYOJET_NOZZLE_IN, type=float) # AppCfg.DT_VEL_SCL: ("Velocity Scale (1=optimal, 0=zero vel at target)", dt2,SPN(dt2, min=0, max=1, suffix=""),),
p_out = settings.value(CRYOJET_NOZZLE_OUT, type=float) # AppCfg.DT_SHOW_PLOTS: ("show plots after collection", dt3,CB(dt3, "active"),),
motion_enabled = option(CRYOJET_MOTION_ENABLED) # #DELTATAU_SORT_POINTS: ("Sort pointshoot/prelocated coords", b,CB(b, "sort points"),),
d = GenericDialog( # },
title="Cryojet Nozzle Configuration", # )
message="Enter reference positions for the cryojet nozzle position", # if d.exec():
inputs={ # results = d.results
CRYOJET_NOZZLE_IN: ("In position", p_in, Spinner(p_in, min=3, max=15)), # _log.info("setting delta tau parameters {}".format(results))
CRYOJET_NOZZLE_OUT: ("Out position",p_out,Spinner(p_out, min=-1000, max=10),), # for k, v in results.items():
CRYOJET_MOTION_ENABLED: ("Move Cryojet in Transitions",motion_enabled,Checkbox(motion_enabled, "move cryojet"),), # cfg.setValue(k, v)
}, # cfg.sync()
) #
if d.exec(): # def dlg_tell_mount_positions(self):
results = d.results # AUTODRY_ENABLED = "tell/autodry_enabled"
_log.info("setting cryojet reference positions {}".format(results)) # AUTODRY_MAXMOUNTS = "tell/autodry_max_number_of_mounts"
for k, v in results.items(): # AUTODRY_MAXTIME = "tell/autodry_max_time"
settings.setValue(k, v) #
settings.sync() # SECS_HOURS = 60 * 60
#
def dlg_deltatau_parameters(self): # enabled = option(AUTODRY_ENABLED)
SPN=GenericDialog.Spinner # maxtime = settings.value(AUTODRY_MAXTIME, type=float) / SECS_HOURS
CB=GenericDialog.Checkbox # maxmounts = settings.value(AUTODRY_MAXMOUNTS, type=int)
app=QApplication.instance() #
cfg=app._cfg # d = GenericDialog.GenericDialog(
#dt1 = cfg.value(AppCfg.DT_HOST,'SAR-CPPM-EXPMX1') # title="TELL Settings",
dt1 = cfg.value(AppCfg.DT_HOST) # message="These control some features of the TELL sample changer",
dt2 = cfg.value(AppCfg.DT_VEL_SCL, 1, type=float) # inputs={
dt3 = cfg.option(AppCfg.DT_SHOW_PLOTS) # AUTODRY_ENABLED: ("Auto dry", enabled,
# Checkbox(enabled, "enabled")),
d = GenericDialog.GenericDialog( # AUTODRY_MAXMOUNTS: ("Max. num. mounts between dry",maxmounts,
title="Delta Tau Parameters", # Spinner(maxmounts, decimals=0, min=1, max=100, suffix=" mounts"),),
message="These parameters affect the data collection.", # AUTODRY_MAXTIME: ("Max. time between dry",maxtime,
inputs={ # Spinner(maxtime, decimals=1, min=0.5, max=5, suffix=" hours"),),
AppCfg.DT_HOST:("host name (host[:port:port_gather])", dt1, QLineEdit(),), # },
AppCfg.DT_VEL_SCL: ("Velocity Scale (1=optimal, 0=zero vel at target)", dt2,SPN(dt2, min=0, max=1, suffix=""),), # )
AppCfg.DT_SHOW_PLOTS: ("show plots after collection", dt3,CB(dt3, "active"),), # if d.exec():
#DELTATAU_SORT_POINTS: ("Sort pointshoot/prelocated coords", b,CB(b, "sort points"),), # results = d.results
}, # _log.info("setting tell parameters {}".format(results))
) # for k, v in results.items():
if d.exec(): # if k == AUTODRY_MAXTIME:
results = d.results # v = v * SECS_HOURS
_log.info("setting delta tau parameters {}".format(results)) # settings.setValue(k, v)
for k, v in results.items(): # settings.sync()
cfg.setValue(k, v)
cfg.sync()
def dlg_tell_mount_positions(self):
AUTODRY_ENABLED = "tell/autodry_enabled"
AUTODRY_MAXMOUNTS = "tell/autodry_max_number_of_mounts"
AUTODRY_MAXTIME = "tell/autodry_max_time"
SECS_HOURS = 60 * 60
enabled = option(AUTODRY_ENABLED)
maxtime = settings.value(AUTODRY_MAXTIME, type=float) / SECS_HOURS
maxmounts = settings.value(AUTODRY_MAXMOUNTS, type=int)
d = GenericDialog.GenericDialog(
title="TELL Settings",
message="These control some features of the TELL sample changer",
inputs={
AUTODRY_ENABLED: ("Auto dry", enabled,
Checkbox(enabled, "enabled")),
AUTODRY_MAXMOUNTS: ("Max. num. mounts between dry",maxmounts,
Spinner(maxmounts, decimals=0, min=1, max=100, suffix=" mounts"),),
AUTODRY_MAXTIME: ("Max. time between dry",maxtime,
Spinner(maxtime, decimals=1, min=0.5, max=5, suffix=" hours"),),
},
)
if d.exec():
results = d.results
_log.info("setting tell parameters {}".format(results))
for k, v in results.items():
if k == AUTODRY_MAXTIME:
v = v * SECS_HOURS
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. ## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__': if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG,format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ')
import sys import sys
app=QApplication([]) app=QApplication([])
## Create tree of Parameter objects app._cfg=AppCfg()
cfg=AppCfg()
w=WndParameter(None) w=WndParameter(None)
w._wnd.show() w.show()
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):

View File

@@ -114,7 +114,7 @@ import pyqtgraph.exporters
pg.setConfigOptions(antialias=True,imageAxisOrder='row-major') pg.setConfigOptions(antialias=True,imageAxisOrder='row-major')
ts.log('Import part 6/8:') ts.log('Import part 6/8:')
import app_utils import app_utils
from app_config import AppCfg #settings, option, toggle_option from app_config import AppCfg,WndParameter #settings, option, toggle_option
import epics import epics
from epics.ca import pend_event from epics.ca import pend_event
@@ -568,40 +568,41 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
self.shortcut.activated.connect(self._OLD_camera_pause_toggle) self.shortcut.activated.connect(self._OLD_camera_pause_toggle)
# adding a menu entry to one of the menus # adding a menu entry to one of the menus
action = QAction("geometry", self) #action = QAction("geometry", self)
action.setToolTip("Update optical center, beam marker size etc.") #action.setToolTip("Update optical center, beam marker size etc.")
action.setStatusTip("Update optical center, beam marker size etc.") #action.setStatusTip("Update optical center, beam marker size etc.")
action.triggered.connect(lambda x: cfg.dlg_geometry(self)) #action.triggered.connect(lambda x: cfg.dlg_geometry(self))
self.menuAdvanced.addAction(action) #self.menuAdvanced.addAction(action)
action = QAction("Backlight Reference Positions", self) #action = QAction("Backlight Reference Positions", self)
action.setToolTip("Update the reference positions for the backlight") #action.setToolTip("Update the reference positions for the backlight")
action.setStatusTip("Update the reference positions for the backlight") #action.setStatusTip("Update the reference positions for the backlight")
action.triggered.connect(cfg.dlg_backlight_positions) #action.triggered.connect(cfg.dlg_backlight_positions)
self.menuAdvanced.addAction(action) #self.menuAdvanced.addAction(action)
action = QAction("Collimator Reference Positions", self) #action = QAction("Collimator Reference Positions", self)
action.setToolTip("Update the reference positions for the collimator") #action.setToolTip("Update the reference positions for the collimator")
action.setStatusTip("Update the reference positions for the collimator") #action.setStatusTip("Update the reference positions for the collimator")
action.triggered.connect(cfg.dlg_collimator_reference_positions) #action.triggered.connect(cfg.dlg_collimator_reference_positions)
self.menuAdvanced.addAction(action) #self.menuAdvanced.addAction(action)
action = QAction("Post sample tube Reference Positions", self) #action = QAction("Post sample tube Reference Positions", self)
action.setToolTip("Update the reference positions for the post tube") #action.setToolTip("Update the reference positions for the post tube")
action.setStatusTip("Update the reference positions for the post tube") #action.setStatusTip("Update the reference positions for the post tube")
action.triggered.connect(cfg.dlg_posttube_references) #action.triggered.connect(cfg.dlg_posttube_references)
self.menuAdvanced.addAction(action) #self.menuAdvanced.addAction(action)
action = QAction("Delta Tau Parameters", self) #action = QAction("Delta Tau Parameters", self)
action.setToolTip("Parameters affecting the Delta Tau") #action.setToolTip("Parameters affecting the Delta Tau")
action.setStatusTip("Parameters affecting the Delta Tau") #action.setStatusTip("Parameters affecting the Delta Tau")
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 = QAction("parameters", self)
action.setToolTip("modify application parameters") action.setToolTip("modify application parameters")
action.setStatusTip("modify application parameters") action.setStatusTip("modify application parameters")
action.triggered.connect(lambda x: cfg.dlg_parameters(self))
action.triggered.connect(self.cb_modify_app_param)
self.menuAdvanced.addAction(action) self.menuAdvanced.addAction(action)
@@ -1321,6 +1322,10 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
#imgPos=self._goImg.mapFromScene(event.scenePos()) #imgPos=self._goImg.mapFromScene(event.scenePos())
#x=imgPos.x();y=imgPos.y() #x=imgPos.x();y=imgPos.y()
def cb_modify_app_param(self):
wnd=WndParameter(self)
wnd.show()
@pyqtSlot() @pyqtSlot()
def cb_save_cam_image(self,overlays=False): def cb_save_cam_image(self,overlays=False):
app=QApplication.instance() app=QApplication.instance()