SFELPHOTON-1409: hit-and-return, yaml as param

This commit is contained in:
2024-11-27 07:55:57 +01:00
parent a548b005f7
commit b029cd62be

View File

@@ -100,7 +100,7 @@ class timestamp():
ts=timestamp() ts=timestamp()
ts.log('Import part 1/8:') ts.log('Import part 1/8:')
import sys, os import sys, os
import json, re import yaml
import signal, subprocess import signal, subprocess
import matplotlib as mpl import matplotlib as mpl
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
@@ -1516,7 +1516,7 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
#self._inspect = self._grid_inspect_area #self._inspect = self._grid_inspect_area
#self._inspect.setPlainText("") #self._inspect.setPlainText("")
fast_x=self.tweakers["fast_x"]; fast_x=self.tweakers["fast_x"]
fast_y=self.tweakers["fast_y"] fast_y=self.tweakers["fast_y"]
fx=fast_x.get_val() fx=fast_x.get_val()
fy=fast_y.get_val() fy=fast_y.get_val()
@@ -1986,6 +1986,53 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch)
self._tabs_daq_methods.setCurrentWidget(mft) #set this as the active tabs self._tabs_daq_methods.setCurrentWidget(mft) #set this as the active tabs
mft._cbType.addItems(["Fiducial", "FixTarget(12.5x12.5)", "FixTarget(23.0x23.0)", "FixTarget(test)", "Grid()", "SwissMX()", "SwissFEL()"]) mft._cbType.addItems(["Fiducial", "FixTarget(12.5x12.5)", "FixTarget(23.0x23.0)", "FixTarget(test)", "Grid()", "SwissMX()", "SwissFEL()"])
#print(psi_device.shapepath.ShapePath.setup_motion.__doc__)
mft._txtParam.setToolTip('''\
additional parameter as yaml for object settings and motion generation:
full example for grid() object and motion settings:
size:[3.6,2.664],cnt:[30,22],fiducialSize:0.05,mode:6,scale:.5,ssz:[7,4],smv:[6,4],sdelay:9
further examples:
object settings:
for Grid(): size:[4,3],cnt:[30,22],fiducialSize:0.1
motion param:
for continous: cnt:2,scale:.3,dwell:100
for stop-and-go: tmove:10,twait:20
for hit-and-return: ssz:(4,6)
motion generation:
For details read: psi_device.shapepath.ShapePath.setup_motion.__doc__
mode: select one of following modes: 1,3,4,5,6
mode settings:
all: cnt:1
scale:1.
dwell:10
5: tmove:10
twait:20
6: ssz:(7,4)
smv:(6,4) (delault defined)
sdelay:9 (delault defined)
object settings:
Fiducial:
no param
FixTarget(12.5x12.5), FixTarget(23.0x23.0), FixTarget(test):
no param
Grid():
size:[30,20]
cnt:[30,22]
fiducialSize:0.1
SwissMX():
ofs:[.2,.2]
width:10
fidScl:.02
fiducial:[[.1,.1],[.1,2.7],[10.3,.1],[10.3, 2.7]]
SwissFEL():
ofs:[.2,.2]
width:10
fidScl:.02
fiducial:[[.1,.1],[[.1,2.2],[10.3,.1],[10.3,2.2]]
''')
mft._btnAdd.clicked.connect(self.module_fix_target_add_obj) mft._btnAdd.clicked.connect(self.module_fix_target_add_obj)
mft._btnDelAll.clicked.connect(self.module_fix_target_del_all_obj) mft._btnDelAll.clicked.connect(self.module_fix_target_del_all_obj)
mft._btnFit.clicked.connect(self.module_fix_target_fit_fiducial) mft._btnFit.clicked.connect(self.module_fix_target_fit_fiducial)
@@ -2097,8 +2144,9 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch)
bm_pos=self._goBeamMarker.pos() bm_pos=self._goBeamMarker.pos()
bm_sz=self._goBeamMarker.size() bm_sz=self._goBeamMarker.size()
idx=mft._cbType.currentIndex() idx=mft._cbType.currentIndex()
param=mft._txtParam.text() param=mft._txtParam.text().replace('(','[').replace(')',']').strip()
if param=='' or param[0]!='{':
param='{'+param+'}'
#mft._cbType.addItems(["Fiducial", "FixTarget(12.5x12.5)", "FixTarget(23.0x23.0)", "FixTarget(<param>)", "Grid(<param>)", "SwissMX-path"]) #mft._cbType.addItems(["Fiducial", "FixTarget(12.5x12.5)", "FixTarget(23.0x23.0)", "FixTarget(<param>)", "Grid(<param>)", "SwissMX-path"])
#bm_pos_eu=self._goBeamMarker._pos_eu #bm_pos_eu=self._goBeamMarker._pos_eu
#bm_size_eu=self._goBeamMarker._size_eu #bm_size_eu=self._goBeamMarker._size_eu
@@ -2126,17 +2174,9 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch)
# fidScl:.02 # fidScl:.02
# fiducial:((.1, .1), (.1, 2.2), (10.3, .1), (10.3, 2.2)) # fiducial:((.1, .1), (.1, 2.2), (10.3, .1), (10.3, 2.2))
pLst=param.split('|') param=param.replace(':', ': ') # allow gen:4 without space
pStr=list() param=yaml.safe_load(param) # "ofs":[10, 5],"width":200,"fidScl":0.5,"fiducial":[[18,7],[25,16],[70, 20]]
for p in pLst: except BaseException as e:
if not p: continue
m=re.match('\s*(.*?)\s*[=:]\s*(.*)\s*', p)
k, v=m.groups()
v=v.replace('(', '[').replace(')', ']')
pStr.append(f'"{k}":{v}')
pStr='{'+','.join(pStr)+'}'
param=json.loads(pStr) # "ofs":[10, 5],"width":200,"fidScl":0.5,"fiducial":[[18,7],[25,16],[70, 20]]
except json.decoder.JSONDecodeError as e:
_log.error(f'{e}:{param}') _log.error(f'{e}:{param}')
param=dict() param=dict()
if idx==0: if idx==0:
@@ -2271,18 +2311,10 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch)
def daq_collect(self, **kwargs):# points, visualizer_method, visualizer_params): def daq_collect(self, **kwargs):# points, visualizer_method, visualizer_params):
''' '''
kwargs: kwargs:
code_gen: 0 pvt motion using ptsTrf
1 pvt motion using trf and points
2 pvt motion, compact grid code
3 pvt motion, compact grid code move and wait
tmove: time to move
twait: time to wait
grid: grid dictionary with orig, pitch, count grid: grid dictionary with orig, pitch, count
trf: transformation matrix trf: transformation matrix
points: list of points without transformation points: list of points without transformation
pts_trf: list of points with transformation pts_trf: list of points with transformation
''' '''
app = QApplication.instance() app = QApplication.instance()
cfg = app._cfg cfg = app._cfg
@@ -2322,28 +2354,22 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch)
#dlg.setAutoClose(True) #dlg.setAutoClose(True)
#dlg.show() #dlg.show()
dlg.setLabelText("Setup Gather/Sync");dlg+=5 dlg.setLabelText("Setup Gather/Sync");dlg+=5
code_gen=kwargs.get('code_gen',0) use_trf=kwargs.get('use_trf', True) # do not use coordinate transformation
if not 'mode' in kwargs:
kwargs['mode']=1
if not use_trf:
trf=kwargs.pop('trf')
points=kwargs['points']
kwargs['points']=kwargs.pop('pts_trf')
sp.setup_sync(verbose=sp.verbose&0x40, timeOfs=dt_misc['time_ofs'], timeCor=dt_misc['time_cor']) sp.setup_sync(verbose=sp.verbose&0x40, timeOfs=dt_misc['time_ofs'], timeCor=dt_misc['time_cor'])
dlg.setLabelText("Download motion program");dlg+=5 dlg.setLabelText("Download motion program");dlg+=5
if code_gen==0: sp.setup_motion(fnPrg=fn+'.prg', **kwargs)
sp.setup_motion(fnPrg=fn+'.prg', mode=3, scale=1., dwell=10, points=kwargs['pts_trf'])
elif code_gen==1:
sp.setup_motion(fnPrg=fn+'.prg', mode=3, scale=1., dwell=10, points=kwargs['points'],trf=kwargs['trf'])
elif code_gen==2:
sp.setup_motion(fnPrg=fn+'.prg', mode=4, scale=1., dwell=10, grid=kwargs['grid'], trf=kwargs['trf'])
elif code_gen==3:
sp.setup_motion(fnPrg=fn+'.prg', mode=5, dwell=10, tmove=kwargs['tmove'] ,twait=kwargs['twait'], grid=kwargs['grid'],trf=kwargs['trf'])
sp.setup_gather() sp.setup_gather()
try: try:
p=geo._fitPlane p=geo._fitPlane
# TODO: Cleanup #TODO: cleanup
if code_gen==0: if use_trf:
# X has inverted sign !
# Z is in um -> therefore the offset must be multiplied with 1000 ! Z motor has opposite sign !
#cz=f'{+p[0]:+.18g}X{-p[1]:+.18g}Y{-p[2]*1000:+.18g}'
t=p*np.array((1,1,1000))
cz=f'{t[0]:+.18g}X{t[1]:+.18g}Y{t[2]:+.18g}'
else:
trf=kwargs['trf'] # grid-coord -> motor-um trf=kwargs['trf'] # grid-coord -> motor-um
#(0,0,1)*trf #(0,0,1)*trf
# trf*'gridpos in um' -> motor pos in mm # trf*'gridpos in um' -> motor pos in mm
@@ -2354,25 +2380,31 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch)
#(0, 0, 1)*trf2*trf3 -> z in um of gridpos(0,0) #(0, 0, 1)*trf2*trf3 -> z in um of gridpos(0,0)
t=(trf2*trf3)[:,0].A.ravel() t=(trf2*trf3)[:,0].A.ravel()
cz=f'{t[0]:+.18g}X{t[1]:+.18g}Y{t[2]:+.18g}' cz=f'{t[0]:+.18g}X{t[1]:+.18g}Y{t[2]:+.18g}'
else:
# X has inverted sign !
# Z is in um -> therefore the offset must be multiplied with 1000 ! Z motor has opposite sign !
#cz=f'{+p[0]:+.18g}X{-p[1]:+.18g}Y{-p[2]*1000:+.18g}'
t=p*np.array((1,1,1000))
cz=f'{t[0]:+.18g}X{t[1]:+.18g}Y{t[2]:+.18g}'
except AttributeError: except AttributeError:
cz='0' cz='0'
_log.warning('no plane fitting done. z does not move') _log.warning('no plane fitting done. z does not move')
trf=kwargs['trf'] trf=kwargs['trf']
if code_gen==0: if use_trf:
fx='X';fy='Y' fx=f'{trf[0, 0]:+.18g}X{trf[1, 0]:+.18g}Y{trf[2, 0]:+.18g}'
fy=f'{trf[0, 1]:+.18g}X{trf[1, 1]:+.18g}Y{trf[2, 1]:+.18g}'
else: else:
fx=f'{trf[0,0]:+.18g}X{trf[1,0]:+.18g}Y{trf[2,0]:+.18g}' fx='X';fy='Y'
fy=f'{trf[0,1]:+.18g}X{trf[1,1]:+.18g}Y{trf[2,1]:+.18g}'
if _log.level==logging.DEBUG: if _log.level==logging.DEBUG:
try: t try: t
except NameError: t=(np.nan,np.nan,np.nan) except NameError: t=(np.nan,np.nan,np.nan)
fn='/tmp/coord.log' fn='/tmp/coord.log'
_log.debug(f'write all coordinates to {fn}') _log.debug(f'write all coordinates to {fn}')
if code_gen==0: if use_trf:
xy1=np.hstack((kwargs["pts_trf"],np.ones((kwargs["pts_trf"].shape[0],1))))
else:
xy1=np.hstack((kwargs["points"],np.ones((kwargs["points"].shape[0],1)))) xy1=np.hstack((kwargs["points"],np.ones((kwargs["points"].shape[0],1))))
else:
xy1=np.hstack((kwargs["pts_trf"],np.ones((kwargs["pts_trf"].shape[0],1))))
pcz=np.matrix(((t[0],t[1],t[2])))*xy1.T pcz=np.matrix(((t[0],t[1],t[2])))*xy1.T
x_y_fx_fy_cz=np.vstack((kwargs["points"].T, kwargs["pts_trf"].T, pcz)).A x_y_fx_fy_cz=np.vstack((kwargs["points"].T, kwargs["pts_trf"].T, pcz)).A
with open('/tmp/coord.log','w') as fh: with open('/tmp/coord.log','w') as fh: