#TODO: # currently 2 settings/configs are used # QSettings -> cat ~/.config/Paul\ Scherrer\ Institut/SwissMX.conf # yaml -> swissmx.yaml # QSettings are changed by program # #yaml is fixed and not altened by program import logging import re _log = logging.getLogger(__name__) from PyQt5 import QtCore, QtGui from PyQt5.QtCore import QSettings from PyQt5.QtWidgets import QApplication, QMainWindow import json import numpy as np class MyJsonEncoder(json.JSONEncoder): """ Special json encoder for numpy types """ def default(self, obj): if isinstance(obj, np.integer): return int(obj) elif isinstance(obj, np.floating): return float(obj) elif isinstance(obj, np.ndarray): return obj.tolist() elif type(obj) not in (dict,list,str,int): _log.error('dont know how to json') return repr(obj) return json.JSONEncoder.default(self, obj) 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' GEO_BEAM_SZ="geometry/beam_size" GEO_BEAM_POS="geometry/beam_pos" GEO_CAM_PARAM="geometry/cam_param" GEO_CAM_TRF="geometry/cam_trf" WINDOW_GEOMETRY="window/geometry" 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 DT_HOST="deltatau/host" DT_MISC="deltatau/miscellaneous" # ---------- OBSOLETE ??? ---------- #ZOOM_BUTTONS="sample_viewing/zoom_buttons" #SKIP_ESCAPE_TRANSITIONS_IF_SAFE="escape/skip_transitions_if_safe" #CRYOJET_MOTION_ENABLED="cryojet/motion_enabled" #CRYOJET_NOZZLE_OUT="cryojet/nozzle_out" #CRYOJET_NOZZLE_IN="cryojet/nozzle_in" #DELTATAU_HOST="deltatau/host" #DELTATAU_SHOW_PLOTS="deltatau/show_plots" #DELTATAU_OMEGACOS="deltatau/omegacos" #DELTATAU_SORT_POINTS="deltatau/sort_points" #DELTATAU_VELOCITY_SCALE="deltatau/velocity_scale" #CAMERA_TRANSFORMATIONS="camera/transformations" #CAMERA_ZOOM_TO_PPM="camera/zoom_to_ppm" #EXPERIMENT_PGROUP="experiment/pgroup" #EXPERIMENT_UID="experiment/uid" #ACTIVATE_PULSE_PICKER="scanning/activate_pulse_picker" def __init__(self): super(AppCfg, self).__init__("PSI", "SwissMX") keys = self.allKeys() # Dump config to debug #for k in keys: # 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 if AppCfg.GEO_BEAM_POS not in keys: _log.warning(f'{AppCfg.GEO_BEAM_POS} not defined. set default') self.setValue(AppCfg.GEO_BEAM_POS, [23.4, -54.2]) # beam position relativ to optical center in mm if AppCfg.GEO_PIX2POS not in keys: _log.warning(f'{AppCfg.GEO_PIX2POS} not defined. use default') #lut_pix2pos=(np.array([1., 200., 400., 600., 800., 1000.]), # np.array([[[ 2.42827273e-03, -9.22117396e-05], # [-1.10489804e-04, -2.42592492e-03]], # [[ 1.64346103e-03, -7.52341417e-05], # [-6.60711165e-05, -1.64190224e-03]], # [[ 9.91307639e-04, -4.02008751e-05], # [-4.23878232e-05, -9.91563507e-04]], # [[ 5.98443038e-04, -2.54046255e-05], # [-2.76831563e-05, -6.02738142e-04]], # [[ 3.64418977e-04, -1.41389267e-05], # [-1.55708176e-05, -3.66233567e-04]], # [[ 2.16526433e-04, -8.23070130e-06], # [-9.29894004e-06, -2.16842976e-04]]])) # rough data for binning=1,1 z=np.array((1.0, 200.0, 400.0, 600.0, 800.0, 1000.0)) t1=np.array(([1, 0.0000], [0.0000, -1])).reshape(1, -1) t2=np.array((0.001214,0.000821,0.000495,0.000299,0.000182,0.000108)).reshape(-1, 1) trf=(t1*t2).reshape((-1, 2, 2)) lut_pix2pos=(z, trf) self.setValue(AppCfg.GEO_PIX2POS, lut_pix2pos) if AppCfg.GEO_OPT_CTR not in keys: _log.warning(f'{AppCfg.GEO_OPT_CTR} not defined. use default') opt_ctr=np.array([603.28688025, 520.01112846]) self.setValue(AppCfg.GEO_OPT_CTR, opt_ctr) if AppCfg.GEO_CAM_TRF not in keys: _log.warning(f'{AppCfg.GEO_CAM_TRF} not defined. use default') trf=np.array(((-1,0,0),(0,-1,0),(0,0,1))) self.setValue(AppCfg.GEO_CAM_TRF, trf) if AppCfg.DT_HOST not in keys: _log.warning(f'{AppCfg.DT_HOST} not defined. use default') self.setValue(AppCfg.DT_HOST,'SAR-CPPM-EXPMX1') #self.setValue(AppCfg.DT_HOST,'localhost:10001:10002') #if AppCfg.ACTIVATE_PULSE_PICKER not in keys: # self.setValue(AppCfg.ACTIVATE_PULSE_PICKER, False) #if AppCfg.SKIP_ESCAPE_TRANSITIONS_IF_SAFE not in keys: # self.setValue(AppCfg.SKIP_ESCAPE_TRANSITIONS_IF_SAFE, False) def sync(self): super(AppCfg, self).sync() #import numpy as np #a=np.array(((1,2,3),(4,5,6))) #self._yamlFn=fn=os.path.expanduser('~/.config/PSI/SwissMX.yaml') #_yaml = [{'name': 'John Doe', 'occupation': 'gardener'}, # {'name': 'Lucy Black', 'occupation': 'teacher'}] #_yaml = {'name': 'John Doe', 'occupation': 'gardener','A':(1,2,3),'B':{1,2,3},'C': {1:(1,2,3),2:'df',3:'dddd'},4:a } #with open(self._yamlFn, 'w') as f: # data = yaml.dump(_yaml, f) # print(data) def setValue(self, key: str, val): #overload to debug # only simple lists, str, int, float can not be serialized nicely t=type(val) if key in (AppCfg.GEO_PIX2POS,AppCfg.GEO_CAM_TRF): val=json.dumps(val, cls=MyJsonEncoder) elif key in (AppCfg.GEO_CAM_PARAM, AppCfg.DFT_POS_DET,AppCfg.DFT_POS_PST,AppCfg.DFT_POS_COL,AppCfg.DFT_POS_BKLGT, AppCfg.DT_MISC): val=json.dumps(val, cls=MyJsonEncoder) val=val.replace('"',"'") elif key in (AppCfg.GEO_OPT_CTR,AppCfg.GEO_BEAM_SZ,AppCfg.GEO_BEAM_POS): if type(val)==np.ndarray: val=val.tolist() elif type(val)==tuple: val=list(val) return super(AppCfg, self).setValue(key,val) def value(self,key,*vargs,**kwargs): #overload to debug val=super(AppCfg, self).value(key,*vargs,**kwargs) if key in (AppCfg.GEO_PIX2POS,): val=json.loads(val)#, object_hook=MyJsonDecoder) val=(np.array(val[0]),np.array(val[1])) elif key in (AppCfg.GEO_CAM_TRF,): val=json.loads(val)#, object_hook=MyJsonDecoder) val=np.array(val) elif key in (AppCfg.GEO_CAM_PARAM, AppCfg.DFT_POS_DET,AppCfg.DFT_POS_PST,AppCfg.DFT_POS_COL,AppCfg.DFT_POS_BKLGT, AppCfg.DT_MISC): if val is not None: val=val.replace("'",'"') val=json.loads(val) # , object_hook=MyJsonDecoder) else: if key==AppCfg.DT_MISC: val={'show_plots': True, 'vel_scl': 1.0, 'pt2pt_time': 10.0,'sync_mode':1,'sync_flag':3,'verbose':0xff} else: val={} elif key in (AppCfg.GEO_BEAM_SZ,AppCfg.GEO_BEAM_POS,): val=np.array(tuple(map(float, val)))/1000 elif key in (AppCfg.GEO_OPT_CTR): val=np.array(tuple(map(float, val))) return val #@property #def value(self): # return super(AppCfg, self).value def option(self,key: str) -> bool: try: return self.value(key, type=bool) except: _log.error(f"option {key} not known") return False def toggle_option(self,key: str): v = self.value(key, type=bool) self.setValue(key, not v) self.sync() from pyqtgraph.parametertree import Parameter, ParameterTree class WndParameter(QMainWindow): def __init__(self, parent=None): super(WndParameter, self).__init__(parent) self.setWindowTitle('SwissMX Preferences') 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_misc = cfg.value(AppCfg.DT_MISC) tip_sync_mode='''\ default=2 0 : no sync at all 1 : synchronize start 2 : synchronize start and adapt motion speed this function generates the code blocks: self.sync_wait and self.sync_run sync_wait can be put in the program to force a timing sync sync_run are the commands to run the whole program ''' tip_sync_flag='''\ default=0 bit 0=1 : simulated start trigger bit 1=2 : simulated frame trigger 0 : real start and frame trigger 1 : simulated start and real frame trigger 2 : real start and simulated frame trigger 3 : simulated start and frame trigger pt2pt_time : time point to point (needed sor sync code) ''' tip_verbose='''\ verbose bits: 0x01 basic info 0x02 plot sorting steps 0x04 list program 0x04 upload progress 0x08 plot gather path 0x10 plot pvt trajectory (before motion) 0x20 print sync details ''' params=[ {'name':'geometry','type':'group','expanded':False,'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.GEO_CAM_TRF, 'value':cfg.value(AppCfg.GEO_CAM_TRF), 'type':'str'}, {'name':AppCfg.GEO_CAM_PARAM, 'title':'camera parameters', 'type':'group', 'expanded':True, 'children':[ {'name':'gain', 'value':geo_cam_param.get('gain'), 'type':'float', 'step':1, }, {'name':'exposure','value':geo_cam_param.get('exposure'),'type':'float', 'step':1, }, {'name':'binning', 'value':geo_cam_param.get('binning'), 'type':'str'}, {'name':'roi', 'value':geo_cam_param.get('roi'), 'type':'str'}, {'name':'mono8', 'value':geo_cam_param.get('mono8'), 'type':'bool'}, ]}, ]}, {'name': AppCfg.DFT_POS_PST, 'title':'post sample tube reference positions','type':'group','expanded':False,'children':[ {'name':'x_in_us', 'title':'in X upstream' ,'value':dft_pos_pst.get('x_in_us' ,0),'type':'float','limits':(-45,15),'step':0.1,'decimals':5,'suffix':' mm'}, {'name':'y_in_us', 'title':'in Y upstream' ,'value':dft_pos_pst.get('y_in_us' ,0),'type':'float','limits':(-45,15),'step':0.1,'decimals':5,'suffix':' mm'}, {'name':'x_in_ds', 'title':'in X downstream' ,'value':dft_pos_pst.get('x_in_ds' ,0),'type':'float','limits':(-45,15),'step':0.1,'decimals':5,'suffix':' mm'}, {'name':'y_in_ds', 'title':'in Y downstream' ,'value':dft_pos_pst.get('y_in_ds' ,0),'type':'float','limits':(-45,15),'step':0.1,'decimals':5,'suffix':' mm'}, {'name':'x_out_delta','title':'out X delta' ,'value':dft_pos_pst.get('x_out_delta',0),'type':'float','limits':(-32,32),'step':0.1,'decimals':5,'suffix':' mm'}, {'name':'y_out_delta','title':'out Y delta' ,'value':dft_pos_pst.get('y_out_delta',0),'type':'float','limits':(-32,32),'step':0.1,'decimals':5,'suffix':' mm'}, {'name':'z_in', 'title':'in Z' ,'value':dft_pos_pst.get('z_in' ,0),'type':'float','limits':(-8 ,5 ),'step':0.1,'decimals':5,'suffix':' mm'}, {'name':'z_out', 'title':'out Z' ,'value':dft_pos_pst.get('z_out' ,0),'type':'float','limits':(-8 ,5 ),'step':0.1,'decimals':5,'suffix':' mm'}, {'name':'set_in', 'title':'use current position as "in"', 'type':'action'}, {'name':'set_out', 'title':'use current position as "out"', 'type':'action'}, ]}, {'name': AppCfg.DFT_POS_COL, 'title':'collimator reference positions', 'type':'group','expanded':False, 'children':[ {'name':'x_in', 'title':'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':'y_in', 'title':'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':'x_out','title':'out X', 'value':dft_pos_col.get('x_out',0),'type':'float', 'limits':(-15.9, 15.9 ),'step':0.1, 'decimals':5, 'suffix':' mm'}, {'name':'y_out','title':'out Y', 'value':dft_pos_col.get('y_out',0),'type':'float', 'limits':(-15.9, 15.9 ),'step':0.1, 'decimals':5, 'suffix':' mm'}, {'name':'set_in', 'title':'use current position as "in"', 'type':'action'}, {'name':'set_out', 'title':'use current position as "out"', 'type':'action'}, ]}, {'name': AppCfg.DFT_POS_BKLGT, 'title':'Back Light reference positions', 'type':'group','expanded':False, 'children':[ {'name':'pos_in', 'title':'In position', 'value':dft_pos_bklgt.get('pos_in',0), 'type':'float', 'limits':(-30000, 10 ),'step':10, 'decimals':5, 'suffix':'ustep'}, {'name':'pos_out','title':'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','expanded':False, 'children':[ {'name':'pos_in', 'title':'In position', 'value':dft_pos_det.get('pos_in',0), 'type':'float', 'limits':(-20, 20 ),'step':0.1, 'decimals':5, 'suffix':' mm'}, {'name':'pos_out','title':'Out position', 'value':dft_pos_det.get('pos_out',0), 'type':'float', 'limits':(-20, 20 ),'step':0.1, 'decimals':5, 'suffix':' mm'}, {'name':'set_in', 'title':'use current position as "in"', 'type':'action'}, {'name':'set_out', 'title':'use current position as "out"', 'type':'action'}, ]}, {'name': AppCfg.GBL_DEV_PREFIX, 'title':'device prefix', 'type':'group','expanded':False, 'children':[ {'name':'deltatau motors', 'value':gbl_dev_prefix[0],'type':'str' }, {'name':'smaract motors', 'value':gbl_dev_prefix[1],'type':'str' }, ]}, {'name':'Delta Tau Parameters', 'type':'group','expanded':False, 'children':[ {'name':AppCfg.DT_HOST ,'title':'host name (host[:port:port_gather])','value':dt_host ,'type':'str'} , {'name':AppCfg.DT_MISC, 'title':'miscellaneous', 'type':'group', 'children':[ {'name':'show plots after collection', 'value':dt_misc['show_plots'], 'type':'bool','tip':"This is a checkbox"}, {'name':'velocity_scale', 'value':dt_misc['vel_scl'], 'type':'float', 'limits':(0, 1), 'step':0.1, 'tip':"This is a checkbox"}, {'name':'pt2pt_time', 'value':dt_misc['pt2pt_time'],'type':'float', 'step':0.1,'tip':"This is a checkbox"}, {'name':'sync_mode', 'value':dt_misc['sync_mode'], 'type':'int', 'tip':tip_sync_mode}, {'name':'sync_flag', 'value':dt_misc['sync_flag'], 'type':'int', 'tip':tip_sync_flag}, {'name':'verbose', 'value':dt_misc['verbose'], 'type':'int', 'tip':tip_verbose}, ]}, ]}, #{'name':'miscellaneous', 'type':'group','expanded':False, 'children':[ # {'name':AppCfg.GEO_CAM_TRF, 'value':cfg.value(AppCfg.GEO_CAM_TRF), 'type':'str'}, #]}, #{'name':'Save/Restore functionality', 'type':'group','expanded':False, '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(AppCfg.DFT_POS_PST, 'set_in' ).sigActivated.connect(lambda x: self.cb_use_cur_pos_as(AppCfg.DFT_POS_PST, 'in')) p.param(AppCfg.DFT_POS_PST, 'set_out').sigActivated.connect(lambda x: self.cb_use_cur_pos_as(AppCfg.DFT_POS_PST, 'out')) p.param(AppCfg.DFT_POS_COL, 'set_in' ).sigActivated.connect(lambda x: self.cb_use_cur_pos_as(AppCfg.DFT_POS_COL, 'in')) p.param(AppCfg.DFT_POS_COL, 'set_out').sigActivated.connect(lambda x: self.cb_use_cur_pos_as(AppCfg.DFT_POS_COL, 'out')) p.param(AppCfg.DFT_POS_DET, 'set_in' ).sigActivated.connect(lambda x: self.cb_use_cur_pos_as(AppCfg.DFT_POS_DET, 'in')) p.param(AppCfg.DFT_POS_DET, 'set_out').sigActivated.connect(lambda x: self.cb_use_cur_pos_as(AppCfg.DFT_POS_DET, 'out')) #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=True) pt.setWindowTitle('SwissMX parameters') #t.resize(600, 800) self.setCentralWidget(pt) self.move(100, 100) self.resize(600, 1000) 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==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.GEO_CAM_PARAM: d=dict(map(lambda x:(x.name(),x.value()), parent.children())) try: d['roi']=tuple(map(int,re.findall('(?:\d+)',d['roi']))) d['binning']=tuple(map(int,re.findall('(?:\d+)',d['binning']))) except TypeError: _log.warning(f'failed to parse {AppCfg.GEO_CAM_PARAM}:{d}') cfg.setValue(par_nm, d) elif nm in(AppCfg.GEO_CAM_TRF): s=param.value() #https://docs.python.org/3/library/re.html#simulating-scanf + no grouping trf=np.array(tuple(map(float,re.findall('[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?',s)))).reshape(3,3) cfg.setValue(nm,trf) try: grp=self.parent()._goImgGrp except AttributeError as e: _log.warning('can not set transformation to application window') else: tr=QtGui.QTransform() # prepare ImageItem transformation: tr.setMatrix(trf[0, 0], trf[1, 0], trf[2, 0], # (-1, 0, 0, trf[0, 1], trf[1, 1], trf[2, 1], # 0,-1, 0, trf[0, 2], trf[1, 2], trf[2, 2]) # 0, 0, 1) grp.setTransform(tr) # assign transform elif par_nm == AppCfg.DFT_POS_PST: d=dict(map(lambda x:(x.name(),x.value()), parent.children())) for k in ('set_in','set_out'): del d[k] cfg.setValue(par_nm,d) elif par_nm == AppCfg.DFT_POS_COL: d=dict(map(lambda x:(x.name(),x.value()), parent.children())) for k in ('set_in','set_out'): del d[k] cfg.setValue(par_nm,d) elif par_nm == AppCfg.DFT_POS_BKLGT: d=dict(map(lambda x:(x.name(),x.value()), parent.children())) cfg.setValue(par_nm,d) elif par_nm == AppCfg.DFT_POS_DET: d=dict(map(lambda x:(x.name(),x.value()), parent.children())) for k in ('set_in','set_out'): del d[k] 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) elif nm in (AppCfg.DT_HOST): cfg.setValue(nm, param.value()) elif par_nm==AppCfg.DT_MISC: d=dict(map(lambda x:(x.name(),x.value()), parent.children())) cfg.setValue(par_nm, d) else: _log.warning(f'can\'t save parameter:{childName} change:{change} data:{str(data)}') raise cfg.sync() def cb_valueChanging(self,param, value): _log.debug(f'Value changing (not finalized): {param}, {value}') def cb_use_cur_pos_as(self,dev,pos): _log.debug(f'HERE {dev}:{pos}') p=self._p.param(dev) try: twk=self.parent().tweakers except AttributeError as e: _log.warning('can not access tweakers to read values') if pos=='in': #sample: just to test p.children()[0].setValue(12.4) elif pos=='out': p.children()[0].setValue(14.1) return #['fast_y', 'fast_x', 'omega', 'base_x', 'base_z', # 'det_z', # 'colli_x', 'colli_y', # 'tube_usx', 'tube_usy', 'tube_dsx', 'tube_dsy', 'tube_z', # 'xeye_x', 'xeye_y']) #p.children() cld=p.children() if dev==AppCfg.DFT_POS_PST: # k=('x_in_us','y_in_us','x_in_ds','y_in_ds','x_out_delta','y_out_delta','z_in','z_out',) if pos=='in': lut=((0,'tube_usx'),(1,'tube_usy'),(2,'tube_dsx'),(3,'tube_dsy'),(6,'tube_z')) elif pos=='out': cld[4].setValue(cld[0].value()-twk['tube_usx'].get_val()) #x_in_us-x_us cld[5].setValue(cld[1].value()-twk['tube_usy'].get_val()) #y_in_us-y_us lut=((7,'tube_z'),) elif dev==AppCfg.DFT_POS_COL: # k=('x_in', 'y_in', 'x_out', 'y_out') if pos=='in': lut=((0,'colli_x'),(1,'colli_y'),) elif pos=='out': lut=((2,'colli_x'),(3,'colli_y'),) elif dev==AppCfg.DFT_POS_DET: if pos=='in': lut=((0,'det_z'),) elif pos=='out': lut=((1,'det_z'),) for i,k in lut: cld[i].setValue(twk[k].get_val()) #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 #config_file = inst_folder / "swissmx.yaml" #configs = yaml.load(config_file.read_text(),Loader=yaml.FullLoader) #endstation = configs["configure_for"] #appsconf = configs[endstation] #simulated = appsconf.get("simulate", False) #logger.info(f"configuring for endstation: {endstation.upper()}") #if simulated: # logger.warning("SIMULATION is ACTIVE") #css_file = inst_folder / "swissmx.css" #def font(name: str) -> str: # p = Path(__file__).absolute().parent / "fonts" / name # return str(p) #def logo(size: int = 0) -> str: # p = Path(__file__).absolute().parent / "logos" / "logo.png" # if size: # p = Path(__file__).absolute().parent / "logos" / f"tell_logo_{size}x{size}.png" # return str(p) # def dlg_geometry(self,obj): # SPN=GenericDialog.Spinner # app=QApplication.instance() # cfg=app._cfg # w, h = map(float,cfg.value(AppCfg.GEO_BEAM_SZ)) # d = GenericDialog.GenericDialog( # title="geometry", # message="Enter the size of the beam in microns", # inputs={ # "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"),), # }, # ) # if d.exec(): # results = d.results # _log.info("Updating beamsize to {}".format(results)) # bm_sz= (results["bw"], results["bh"]) # _log.debug("types {}".format(type(w))) # cfg.setValue(AppCfg.GEO_BEAM_SZ, bm_sz) # cfg.sync() # bm=obj._goBeamMarker # bm.setSize(bm_sz) # #self._beammark.set_beam_size((w, h)) # # def dlg_collimator_reference_positions(self): # SPN=GenericDialog.Spinner # app=QApplication.instance() # 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) # x_in = cfg.value(AppCfg.COL_X_IN, 0.0,type=float) # y_in = cfg.value(AppCfg.COL_Y_IN, 0.0,type=float) # d = GenericDialog.GenericDialog( # title="Collimator configuration", # message="Enter reference positions for the collimator", # inputs={ # AppCfg.COL_DX: ("Collimator out deltaX", x_out, SPN(x_out, decimals=3, min=-15.9, max=15.9, suffix=" mm"),), # AppCfg.COL_DY: ("Collimator out deltaY", y_out, SPN(y_out, decimals=3, min=-15.9, max=15.9, suffix=" mm"),), # AppCfg.COL_X_IN: ("Collimator in X", x_in, SPN(x_in, decimals=3, min=-15.9, max=15.9, suffix=" mm"),), # AppCfg.COL_Y_IN: ("Collimator in Y", y_in, SPN(y_in, decimals=3, min=-15.9, max=15.9, suffix=" mm"),), # }, # ) # if d.exec(): # results = d.results # _log.info("setting collimator reference positions {}".format(results)) # for k, v in results.items(): # cfg.setValue(k, v) # cfg.sync() # # def dlg_backlight_positions(self): # SPN=GenericDialog.Spinner # app=QApplication.instance() # cfg=app._cfg # p_in = cfg.value(AppCfg.BKLGT_IN,0,type=int) # p_out = cfg.value(AppCfg.BKLGT_OUT,0,type=int) # d = GenericDialog.GenericDialog( # title="Back Light configuration", # message="Enter reference positions for the backlight", # inputs={ # AppCfg.BKLGT_IN: ("In position" , p_in , SPN(p_in, min=-30000, max=10), ), # AppCfg.BKLGT_OUT: ("Out position", p_out, SPN(p_out, min=-1000, max=10), ), # }, # ) # if d.exec(): # results = d.results # _log.info("setting back light reference positions {}".format(results)) # for k, v in results.items(): # cfg.setValue(k, v) # cfg.sync() # # def dlg_cryojet_positions(self): # p_in = settings.value(CRYOJET_NOZZLE_IN, type=float) # p_out = settings.value(CRYOJET_NOZZLE_OUT, type=float) # motion_enabled = option(CRYOJET_MOTION_ENABLED) # d = GenericDialog( # title="Cryojet Nozzle Configuration", # message="Enter reference positions for the cryojet nozzle position", # inputs={ # CRYOJET_NOZZLE_IN: ("In position", p_in, Spinner(p_in, min=3, max=15)), # CRYOJET_NOZZLE_OUT: ("Out position",p_out,Spinner(p_out, min=-1000, max=10),), # CRYOJET_MOTION_ENABLED: ("Move Cryojet in Transitions",motion_enabled,Checkbox(motion_enabled, "move cryojet"),), # }, # ) # if d.exec(): # results = d.results # _log.info("setting cryojet reference positions {}".format(results)) # for k, v in results.items(): # settings.setValue(k, v) # settings.sync() # # def dlg_deltatau_parameters(self): # SPN=GenericDialog.Spinner # CB=GenericDialog.Checkbox # app=QApplication.instance() # cfg=app._cfg # #dt1 = cfg.value(AppCfg.DT_HOST,'SAR-CPPM-EXPMX1') # dt1 = cfg.value(AppCfg.DT_HOST) # dt2 = cfg.value(AppCfg.DT_VEL_SCL, 1, type=float) # dt3 = cfg.option(AppCfg.DT_SHOW_PLOTS) # # d = GenericDialog.GenericDialog( # title="Delta Tau Parameters", # message="These parameters affect the data collection.", # inputs={ # 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"),), # #DELTATAU_SORT_POINTS: ("Sort pointshoot/prelocated coords", b,CB(b, "sort points"),), # }, # ) # if d.exec(): # results = d.results # _log.info("setting delta tau parameters {}".format(results)) # for k, v in results.items(): # 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() # ---------------------------------------------- ## Start Qt event loop unless running in interactive mode or using pyside. if __name__ == '__main__': logging.basicConfig(level=logging.DEBUG,format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ') import sys app=QApplication([]) app._cfg=AppCfg() w=WndParameter(None) w.show() if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): QApplication.instance().exec_()