try to cleanup stuff(3)
This commit is contained in:
@@ -16,7 +16,7 @@ This contains a Widget to handle FixTargetFrames and fiducials, calculate final
|
||||
import logging
|
||||
_log=logging.getLogger(__name__)
|
||||
|
||||
import json, base64, yaml
|
||||
import os, json, base64, yaml
|
||||
import numpy as np
|
||||
import pyqtUsrObj as UsrGO
|
||||
import pyqtgraph as pg
|
||||
@@ -47,6 +47,22 @@ class MyJsonEncoder(json.JSONEncoder):
|
||||
return repr(obj)
|
||||
return json.JSONEncoder.default(self, obj)
|
||||
|
||||
def iterencode(self, o, _one_shot=False):
|
||||
list_lvl = 0
|
||||
l=super().iterencode(o, _one_shot=_one_shot)
|
||||
#l=tuple(l);print(''.join(l)) # helpful to debug
|
||||
for s in l:
|
||||
if s.startswith('['):
|
||||
list_lvl += 1
|
||||
if list_lvl > 0:
|
||||
s = s[0]+s[1:].replace('\n', '').strip()
|
||||
s = s.replace('\n', '').rstrip()
|
||||
#self.item_separator):
|
||||
#self.key_separator
|
||||
if s.endswith(']'):
|
||||
list_lvl -= 1
|
||||
yield s
|
||||
|
||||
def MyJsonDecoder(dct):
|
||||
if isinstance(dct, dict):
|
||||
if '__class__' in dct:
|
||||
@@ -173,28 +189,10 @@ class WndFixTarget(QWidget):
|
||||
#bm_pos_eu=self._goBeamMarker._pos_eu
|
||||
#bm_size_eu=self._goBeamMarker._size_eu
|
||||
try:
|
||||
#parse the parameters: 'key:value [,key:value]'
|
||||
# as key value separator : and = are allowed
|
||||
#examples:
|
||||
#Fiducial:
|
||||
# no param
|
||||
#FixTarget(12.5x12.5), FixTarget(23.0x23.0), FixTarget(test):
|
||||
# code_gen:2
|
||||
# code_gen=3 | tmove=10 | twait=30
|
||||
#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))
|
||||
#parse the parameters: as yaml string.
|
||||
# allows : without space, allows () as []
|
||||
# no {} to define a dictionary
|
||||
# e.g. 'a:ggf,b:5,c:[5,6.1],d(8,9,3)'
|
||||
|
||||
param=param.replace(':', ': ') # allow gen:4 without space
|
||||
param=yaml.safe_load(param) # "ofs":[10, 5],"width":200,"fidScl":0.5,"fiducial":[[18,7],[25,16],[70, 20]]
|
||||
@@ -376,7 +374,10 @@ class WndFixTarget(QWidget):
|
||||
#df = pd.DataFrame(data)
|
||||
#df.to_csv(filename, float_format="%.6f")
|
||||
#import numpy as np
|
||||
ext=filename.rsplit('.',1)[1].lower()
|
||||
base,ext=os.path.splitext(filename)
|
||||
if not ext.lower():
|
||||
ext='json'
|
||||
filename=base+'.'+ext
|
||||
try:
|
||||
wnd=app._mainWnd
|
||||
except AttributeError:
|
||||
@@ -386,7 +387,7 @@ class WndFixTarget(QWidget):
|
||||
grp=wnd._goTracked
|
||||
data=grp.childItems()
|
||||
|
||||
if ext=='json':
|
||||
if ext.lower()=='json':
|
||||
with open(filename, 'w') as f:
|
||||
json.dump(data, f,cls=MyJsonEncoder, indent=2)#separators=(',', ':')
|
||||
else:
|
||||
|
||||
111
Readme.md
111
Readme.md
@@ -102,3 +102,114 @@ python swissmx.py --sim 0xc0
|
||||
```
|
||||
Document to start SwissMX in cristallina environment (maintained by John):
|
||||
https://docs.google.com/document/d/1yEmV_DbRBKQKVCoovjXriNgSjNEBaz50WA0l3yA5jtg/edit#heading=h.z9io692b8tow
|
||||
|
||||
## code generation parameters
|
||||
```
|
||||
copied from: PBSwissMX/python/shapepath.py: ShapePath.setup_motion
|
||||
|
||||
generates program <prgId> and saves to fnPrg
|
||||
the type of generated program is defined by <mode>$
|
||||
-> the list af all points that will be moved at, is in 'mot_pts'
|
||||
|
||||
(m)= mandatory
|
||||
(o)= optional
|
||||
common kwargs:
|
||||
scale : (o) scaling velocity (default=1. value=0 would stop at each point
|
||||
cnt : (o) move path multiple times (default=1)
|
||||
dwell : (o) dwell time at end (default=100ms)
|
||||
|
||||
mode:0 unused
|
||||
mode:1 pvt motion point list
|
||||
common kwargs plus:
|
||||
points : (m) point list
|
||||
trf : (o) transformation that will be done on 'points', mot_pts=trf*points
|
||||
mode:2 unused
|
||||
mode:3 pvt motion point list using inverse fft velocity
|
||||
common kwargs plus:
|
||||
points : (m) point list
|
||||
trf : (o) transformation that will be done on 'points', mot_pts=trf*points
|
||||
numPad : (o) number of padding points to reduce aliasing (default=16)
|
||||
mode:4 pvt motion short code using grid parameters
|
||||
common kwargs plus:
|
||||
trf : (o) transformation that will be done on 'grid points'
|
||||
grid: (m) grid parameters: {orig:(0,0),pitch(10,10),cnt:(10,10),mode:0}
|
||||
mode:5 pvt motion 'stop and go' short code using grid parameters.
|
||||
Instead of continous motion it moves and waits as given in the parameters
|
||||
common kwargs plus:
|
||||
trf : (o) transformation that will be done on 'grid points'
|
||||
grid: (m) grid parameters: {orig:(0,0),pitch(10,10),cnt:(10,10),mode:0}
|
||||
tmove: (m) time to move in ms (move start on FEL-trigger
|
||||
twait: (m) time to wait in ms
|
||||
(tmove+twait will be rounded to a multiple of fel_per)
|
||||
mode:6 pvt motion 'hit and return using grid parameters. continous motion on 2n ells to pump then same 2n wells to probe, then go 2 rows down
|
||||
common kwargs plus:
|
||||
trf : (o) transformation that will be done on 'grid points'
|
||||
grid : (m) grid parameters: {orig:(0,0),pitch(10,10),cnt:(10,10),mode:0}
|
||||
ssz : (m) section size (in wells)
|
||||
smv : (o) time(in num of shots) to move to next section (horiz/vert)
|
||||
default is (ssz[0]-1,ssz[1])
|
||||
sdelay: (o) shots count of delay. Default is ssz[0]*ssz[1]
|
||||
|
||||
Examples:
|
||||
mode:1
|
||||
mode:3
|
||||
mode:4
|
||||
mode:5,tmove:20,twait:30
|
||||
mode:6,ssz:(4,3)
|
||||
```
|
||||
## graphical object parameters
|
||||
```
|
||||
FixTarget:
|
||||
90*40+480*2=4560
|
||||
60*30+360*2=2520
|
||||
2520-240=2280
|
||||
4560-240=4320
|
||||
size in mm, dscr.size in user units (um)
|
||||
"size:(6,3.5),
|
||||
dscr: {
|
||||
size:(4560,2520),
|
||||
fiducial:{type:0,pos:((240,240),(4320,240),(240,2280),(4320,2280))},
|
||||
grid:{pos:(480,360),pitch:(90,60),count:(40,30)}
|
||||
}"
|
||||
|
||||
grid:
|
||||
size, fiducialSize in mm:
|
||||
(60-1)*.120 -> 7.08mm
|
||||
(45-1)*.120 -> 5.28mm
|
||||
fiducialSize -> 0.1mm
|
||||
"size:(7.08,5.28),cnt:(60,45),fiducialSize:.01"
|
||||
|
||||
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]]"
|
||||
```
|
||||
|
||||
## fully parameter examples:
|
||||
```
|
||||
"mode:4,size:(7.08,5.28), cnt:(60,45), fiducialSize:.01" -> add a grid
|
||||
|
||||
"mode:6,ssz:(4,3), size:(7.08,5.28), cnt:(60,45), fiducialSize:.01" -> add a grid
|
||||
"mode:6,ssz:(4,3), size:(3,1.5), cnt:(30,15), fiducialSize:.01" -> add a grid
|
||||
|
||||
"mode:6,ssz:(6,8),
|
||||
dscr: {
|
||||
size:(4560,2520),
|
||||
fiducial:{type:0,pos:((240,240),(4320,240),(240,2280),(4320,2280))},
|
||||
grid:{pos:(480,360),pitch:(90,60),count:(40,30)}
|
||||
}" -> add a FixTarget
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
## testing hit and return:
|
||||
```
|
||||
-> add a FixTarget
|
||||
"mode:6,ssz:(6,8),
|
||||
dscr: {
|
||||
size:(4560,2520),
|
||||
fiducial:{type:0,pos:((240,240),(4320,240),(240,2280),(4320,2280))},
|
||||
grid:{pos:(480,360),pitch:(90,60),count:(40,30)}
|
||||
}" -> add a FixTarget
|
||||
```
|
||||
|
||||
@@ -251,25 +251,55 @@ class Grid(UsrROI):
|
||||
|
||||
def get_scan_param(self):
|
||||
'returns scan parameters for scanning with deltatau. the format is as used for shapepath'
|
||||
scan=1 # snake motion Y fast, X slow (default)
|
||||
cnt=np.array(self._cnt,np.int32)
|
||||
sz=np.array(self.size())
|
||||
pitch=sz/cnt
|
||||
xx, yy=np.meshgrid(range(cnt[0]), range(cnt[1]))
|
||||
|
||||
|
||||
if scan==0: # snake motion X fast, Y slow
|
||||
for i in range(1,cnt[1],2):
|
||||
xx[i]=xx[i][::-1]
|
||||
else: # scan==1 # snake motion Y fast, X slow (default)
|
||||
xx=xx.T
|
||||
yy=yy.T
|
||||
for i in range(1, cnt[0], 2):
|
||||
yy[i]=yy[i][::-1]
|
||||
pts=np.array([xx.reshape(-1), yy.reshape(-1)], dtype=np.float64).transpose()*pitch
|
||||
param={'points':pts}
|
||||
cnt=np.array(self._cnt, np.int32)
|
||||
grid={'pos':tuple(self.pos()), 'pitch':tuple(np.array(self.size())/cnt), 'count':self._cnt}
|
||||
use_trf=self._param.get('use_trf', True) # do not use coordinate transformation
|
||||
mode=self._param.get('mode',1)
|
||||
num_pts=np.array(self._cnt, np.int32).prod()
|
||||
param={'num_pts':num_pts}
|
||||
param.update(self._param)
|
||||
assert(param.get('code_gen',0)==0) # this provides fully x,y motor coordinates
|
||||
|
||||
# TODO: simplify !!!
|
||||
t=self.transform() #obj_info(t)
|
||||
p=np.array(self.pos())
|
||||
s=1#self.size()/self._dscr['size']
|
||||
trf=np.array(((t.m11(),t.m12()),(t.m21(),t.m22()),(0,0)))
|
||||
trf[2,:]=p # shift origin
|
||||
trf[:2,:]=(trf[:2,:].T*s).T # same as np.asmatrix(np.diag(s))*trf[:2,:], trf[:2,:]*=s not working, scale before rot / shear
|
||||
|
||||
pos=np.array((0,0)) #np.array(grid['pos']) # in um
|
||||
pitch=np.array(grid['pitch']) # in um
|
||||
trf2=np.asmatrix(np.identity(3))
|
||||
trf2[:, :2]=trf
|
||||
trf2*=np.asmatrix(((1000, 0, 0), (0, 1000, 0), (0, 0, 1)))
|
||||
trf3=np.asmatrix(((pitch[0], 0, 0), (0, pitch[1], 0), (pos[0], pos[1], 1)))
|
||||
trf=(trf3*trf2)[:, :2]
|
||||
|
||||
if mode in (1,3): # needs all points, not grid
|
||||
scan=1 # snake motion Y fast, X slow (default)
|
||||
xx, yy=np.meshgrid(range(cnt[0]), range(cnt[1]))
|
||||
if scan==0: # snake motion X fast, Y slow
|
||||
for i in range(1,cnt[1],2):
|
||||
xx[i]=xx[i][::-1]
|
||||
else: # scan==1 # snake motion Y fast, X slow (default)
|
||||
xx=xx.T
|
||||
yy=yy.T
|
||||
for i in range(1, cnt[0], 2):
|
||||
yy[i]=yy[i][::-1]
|
||||
|
||||
pts=np.array([xx.reshape(-1), yy.reshape(-1)], dtype=np.float64).transpose() #*pitch
|
||||
|
||||
if not use_trf:
|
||||
pts=(np.hstack((pts, np.ones((pts.shape[0], 1))))*trf).A
|
||||
param['trf']=trf
|
||||
param['points']=pts
|
||||
else:
|
||||
if use_trf:
|
||||
param.update({'grid':grid, 'trf':trf})
|
||||
else:
|
||||
g=grid.copy() #has not be tested !
|
||||
g['pos']=tuple((np.array((0,0,1))*trf).A.reshape(-1).tolist())
|
||||
param.update({'grid':p, 'trf':trf})
|
||||
return param
|
||||
|
||||
|
||||
@@ -371,11 +401,9 @@ class Path(UsrROI):
|
||||
s=self.size()/self.szOrig
|
||||
trf=np.array(((t.m11(),t.m12()),(t.m21(),t.m22()),(0,0)))
|
||||
trf[2,:]=p # shift origin
|
||||
#trf[:2, 0]*=s[0];trf[:2, 1]*=s[1] #scaling (before rotation shear)
|
||||
trf[:2,:]=(trf[:2,:].T*s).T # same as np.asmatrix(np.diag(s))*trf[:2,:], trf[:2,:]*=s not working, scale before rot / shear
|
||||
|
||||
trf[:2,:]=(trf[:2,:].T*s).T
|
||||
# trf*'gridpos in um' -> motor pos in mm
|
||||
param={'points':self._path,'trf':trf}
|
||||
param={'num_pts':len(self._path),'trf':trf,'points':self._path}
|
||||
param.update(self._param)
|
||||
return param
|
||||
|
||||
|
||||
19
swissmx.py
19
swissmx.py
@@ -1527,7 +1527,7 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
if type(go)==UsrGO.Fiducial:
|
||||
continue
|
||||
t=type(go)
|
||||
if t not in(UsrGO.FixTargetFrame,UsrGO.Path):
|
||||
if t not in(UsrGO.FixTargetFrame,UsrGO.Path,UsrGO.Grid):
|
||||
_log.warning(f'{t} not supported for FixTargetFrame ->skipped:{go}')
|
||||
continue
|
||||
try:
|
||||
@@ -2025,7 +2025,7 @@ object settings:
|
||||
ofs:[.2,.2]
|
||||
width:10
|
||||
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]]
|
||||
''')
|
||||
|
||||
mft._btnAdd.clicked.connect(self.module_fix_target_add_obj)
|
||||
@@ -2146,19 +2146,16 @@ object settings:
|
||||
go=UsrGO.Fiducial((fx-l/2,fy-l/2), (l, l),bz)
|
||||
go.sigRegionChangeFinished.connect(self.cb_fiducial_update_z)
|
||||
elif idx==1:
|
||||
v=geo.pos2pix((12.5, 0))
|
||||
l=np.linalg.norm(v)
|
||||
l=12.5
|
||||
#ctr=bm_pos+bm_sz/2
|
||||
#v=geo.pos2pix((12.5, 0));l=np.linalg.norm(v);l=12.5
|
||||
sz=param.pop('size',(12.5, 12.5))
|
||||
go=UsrGO.FixTargetFrame((fx-l/2,fy-l/2), (l, l), tpl='12.5x12.5',**param)
|
||||
elif idx==2:
|
||||
v=geo.pos2pix((23, 0))
|
||||
l=np.linalg.norm(v)
|
||||
l=23
|
||||
#v=geo.pos2pix((23, 0));l=np.linalg.norm(v)#l=23
|
||||
sz=param.pop('size',(23, 23))
|
||||
go=UsrGO.FixTargetFrame((fx-l/2,fy-l/2), (l, l), tpl='23.0x23.0',**param)
|
||||
elif idx==3:
|
||||
w,h=(.120*12, .120*8)
|
||||
go=UsrGO.FixTargetFrame((fx-w/2,fy-h/2), (w, h), tpl='test',**param)
|
||||
sz=param.pop('size',(.120*12, .120*8))
|
||||
go=UsrGO.FixTargetFrame((fx-sz[0]/2,fy-sz[1]/2), sz, tpl='test',**param)
|
||||
elif idx==4:
|
||||
w,h=size=param.pop('size',(30, 20))
|
||||
cnt=param.pop('cnt',(30, 22))
|
||||
|
||||
Reference in New Issue
Block a user