various fixes
This commit is contained in:
@@ -263,10 +263,10 @@ 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
|
||||
0x08 upload progress
|
||||
0x10 plot gather path
|
||||
0x20 plot pvt trajectory (before motion)
|
||||
0x40 print sync details
|
||||
'''
|
||||
|
||||
params=[
|
||||
@@ -330,9 +330,9 @@ verbose bits:
|
||||
{'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':'show_plots', 'value':dt_misc['show_plots'], 'type':'bool', 'title':'show plots after collection'},
|
||||
{'name':'vel_scl', 'value':dt_misc['vel_scl'], 'type':'float', 'limits':(0, 1), 'step':0.1, 'title':'velocity_scale', 'tip':"scale between smooth(1.0) and stop and go(0.0)"},
|
||||
{'name':'pt2pt_time', 'value':dt_misc['pt2pt_time'], 'type':'float', 'step':0.1,'tip':"time in ms from point to point"},
|
||||
{'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},
|
||||
|
||||
27
camera.py
27
camera.py
@@ -109,34 +109,27 @@ class epics_cam(object):
|
||||
def get_image(self):
|
||||
_log.warning('this can be very slow. Use callbacks if possible.')
|
||||
try:
|
||||
pv_pic=self.getPv('FPICTURE')
|
||||
except AttributeError:
|
||||
imgSeq=self._sim['imgSeq']
|
||||
except AttributeError: pass
|
||||
else:
|
||||
imgSeq=self._sim['imgSeq']
|
||||
idx=self._sim['imgIdx']
|
||||
self._sim['imgIdx']=(idx + 1) % imgSeq.shape[0]
|
||||
#_log.debug('simulated idx:{}'.format(idx))
|
||||
self.pic=pic=imgSeq[idx]
|
||||
self._pic=pic=imgSeq[idx]
|
||||
return pic
|
||||
try:
|
||||
pic=self._pic
|
||||
return pic
|
||||
except AttributeError as e:
|
||||
pass
|
||||
pv_pic=self.getPv('FPICTURE')
|
||||
sz=self._sz
|
||||
pic = pv_pic.get(count=sz[0]*sz[1], as_numpy=True).reshape(sz[::-1])
|
||||
epics_cam.set_fiducial(pic,255)
|
||||
except AttributeError as e:
|
||||
_log.warning("failed to fetch image")
|
||||
else:
|
||||
if pic.dtype==np.int16:
|
||||
pic.dtype=np.uint16
|
||||
try:
|
||||
trf=self._transformation
|
||||
except AttributeError as e:
|
||||
pass
|
||||
else:
|
||||
if trf[1,0]==0:
|
||||
pic=pic[::trf[0,0],::trf[1,1]]
|
||||
else:
|
||||
pic=pic[::trf[0,1],::trf[1,0]].T
|
||||
|
||||
self.pic=pic
|
||||
self._pic=pic
|
||||
return pic
|
||||
|
||||
def stop(self,v=CameraStatus.IDLE):
|
||||
|
||||
19
geometry.py
19
geometry.py
@@ -256,13 +256,13 @@ class geometry:
|
||||
_log.debug('least square data:\nK:{}\nAA:{}'.format(K, AA))
|
||||
|
||||
@staticmethod
|
||||
def autofocus(cam,mot,rng=(-1,1),n=30,saveImg=False):
|
||||
def autofocus(cam,mot,rng=(-1,1),n=30,progressDlg=None,saveImg=False):
|
||||
# cam camera object
|
||||
# mot motor object
|
||||
# mot motor object (e.g. SimMotorTweak)
|
||||
# rng region (min max relative to current position) to seek
|
||||
# n number of images to take in region
|
||||
# roi region of interrest to calculate sharpness
|
||||
# mode mode to calculate sharpness (sum/max-min/hist? of edge detection in roi)
|
||||
# progressDlg a pg.ProgressDialog to allow to abort the function call
|
||||
|
||||
if mot is not None:
|
||||
p0=mot.get_rbv()
|
||||
else:
|
||||
@@ -295,13 +295,19 @@ class geometry:
|
||||
img=np.asarray(img)
|
||||
else:
|
||||
mot.move_abs(p, wait=True)
|
||||
img=cam._pic # get_image()
|
||||
img=cam.get_image() # get latest image
|
||||
img16=np.array(img, np.int16)
|
||||
msk=np.array(((1, 0, -1), (2, 0, -2), (1, 0, -1)), np.int16)
|
||||
sb1=signal.convolve2d(img16, msk, mode='same', boundary='fill', fillvalue=0)
|
||||
sb2=signal.convolve2d(img16, msk.T, mode='same', boundary='fill', fillvalue=0)
|
||||
sb=np.abs(sb1)+np.abs(sb2)
|
||||
mtr[i]=sb.sum()
|
||||
try:
|
||||
progressDlg+=1
|
||||
if progressDlg.wasCanceled():
|
||||
return
|
||||
except TypeError as e:
|
||||
pass
|
||||
_log.debug(f'{i}/{p:.4g} -> {mtr[i]:.4g}')
|
||||
|
||||
mx=mtr.argmax()
|
||||
@@ -333,8 +339,7 @@ class geometry:
|
||||
img=PIL.Image.open(cam)
|
||||
img=np.asarray(img)
|
||||
else:
|
||||
img=cam._pic # get_image()
|
||||
img16=np.array(img, np.int16)
|
||||
img=cam.get_image() # get latest image
|
||||
|
||||
fid=np.ones((sz[1]+2*brd[1],sz[0]+2*brd[0]),dtype=np.uint8)*255
|
||||
fid[brd[1]:sz[1]+brd[1],brd[0]:sz[0]+brd[0]]=0
|
||||
|
||||
@@ -15,7 +15,7 @@ _log=logging.getLogger(__name__)
|
||||
from PyQt5.QtWidgets import (QApplication,)
|
||||
from app_config import AppCfg #settings, option, toggle_option
|
||||
|
||||
|
||||
import epics
|
||||
from pbtools.misc.pp_comm import PPComm
|
||||
from pbtools.misc.gather import Gather
|
||||
import shapepath
|
||||
@@ -25,6 +25,7 @@ try:
|
||||
except ImportError as e:
|
||||
_log.warning(e)
|
||||
|
||||
|
||||
class Deltatau:
|
||||
def __init__(self):
|
||||
app=QApplication.instance()
|
||||
@@ -83,7 +84,14 @@ class Jungfrau:
|
||||
except NameError as e:
|
||||
_log.warning(f'Jungfrau not connected: {e}')
|
||||
self._daq=None
|
||||
self._pv_pulse_id=epics.PV('SAR-EXPMX-EVR0:RX-PULSEID')
|
||||
|
||||
|
||||
def acquire(self,run_name, n_pulses, wait=False):
|
||||
if self._daq is not None:
|
||||
self._pulse_id_start=self._pv_pulse_id.value
|
||||
self._daq.acquire( run_name, n_pulses=n_pulses, wait=False)
|
||||
|
||||
def gather_upload(self):
|
||||
self._pulse_id_end=self._pv_pulse_id.value
|
||||
|
||||
|
||||
36
swissmx.py
36
swissmx.py
@@ -30,6 +30,7 @@ logging.getLogger('matplotlib').setLevel(logging.INFO)
|
||||
logging.getLogger('PIL').setLevel(logging.INFO)
|
||||
logging.getLogger('illumination').setLevel(logging.INFO)
|
||||
logging.getLogger('zoom').setLevel(logging.INFO)
|
||||
logging.getLogger('pbtools.misc.pp_comm').setLevel(logging.INFO)
|
||||
_log = logging.getLogger("swissmx")
|
||||
#_log.setLevel(logging.INFO)
|
||||
|
||||
@@ -47,6 +48,8 @@ import sys, os, time
|
||||
import json, re
|
||||
import random, signal, subprocess
|
||||
import matplotlib as mpl
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
mpl.use('Qt5Agg') # needed to avoid blocking of ui !
|
||||
|
||||
TASK_JUNGFRAU_SETTINGS = "jungfrau_settings"
|
||||
@@ -1595,7 +1598,10 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch)
|
||||
app=QApplication.instance()
|
||||
geo=app._geometry
|
||||
#geo.autofocus(app._camera, self.tweakers['base_z'],rng=(-1, 1), n=30,saveImg=True)
|
||||
geo.autofocus(app._camera, self.tweakers['base_z'],rng=(-1, 1), n=10)
|
||||
n=10
|
||||
rng=(-1, 1)
|
||||
with pg.ProgressDialog('Progress', 0, n) as dlg:
|
||||
geo.autofocus(app._camera, self.tweakers['base_z'],rng, n,dlg)
|
||||
|
||||
def cb_find_fiducial(self):
|
||||
app=QApplication.instance()
|
||||
@@ -2059,8 +2065,17 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch)
|
||||
sp.verbose=dt_misc['verbose']
|
||||
sp.points=kwargs['points']
|
||||
sp.meta['pt2pt_time']=dt_misc['pt2pt_time']
|
||||
with pg.ProgressDialog('Progress', 0, 100) as dlg:
|
||||
dlg.setWindowModality(Qt.WindowModal)
|
||||
#dlg.setRange(0, 0)
|
||||
#dlg.setCancelButtonText("Abort Acquisition")
|
||||
#dlg.canceled.connect(self.complete_daq)
|
||||
#dlg.setAutoClose(True)
|
||||
#dlg.show()
|
||||
|
||||
dlg.setLabelText("Setup Gather/Sync");dlg+=5
|
||||
sp.setup_gather()
|
||||
sp.setup_sync(verbose=sp.verbose&0x20, timeOfs=0.05)
|
||||
sp.setup_sync(verbose=sp.verbose&0x40, timeOfs=0.05)
|
||||
try:
|
||||
p=geo._fitPlane
|
||||
sp.setup_coord_trf(cz=f'{p[0]:+.18g}X{p[1]:+.18g}Y{p[2]:+.18g}') # reset to shape path system
|
||||
@@ -2068,21 +2083,32 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch)
|
||||
_log.warning('no plane fitting done. z does not move')
|
||||
sp.setup_coord_trf() # reset to shape path system
|
||||
# sp.meta['pt2pt_time']=10 #put between setup_sync and setup_motion to have more motion points than FEL syncs
|
||||
dlg.setLabelText("Download motion program");dlg+=5
|
||||
sp.setup_motion(fnPrg=fn+'.prg', mode=3, scale=1., dwell=10)
|
||||
dlg.setLabelText("Homing and get ready");dlg+=35
|
||||
sp.homing() # homing if needed
|
||||
sp.run() # start motion program
|
||||
sp.wait_armed() # wait until motors are at first position
|
||||
sp.trigger(0.5) # send a start trigger (if needed) after given time
|
||||
#PV with the current pulse
|
||||
# [sf-lc7a ~]$ caget
|
||||
jf.acquire('filename.tmp',sp.points.shape[0])
|
||||
if not dt._comm is None:
|
||||
dlg.setLabelText("run motion/acquisition")
|
||||
dlg.setMaximum(sp.points.shape[0])
|
||||
while True:
|
||||
p=sp.progress()
|
||||
if p<0: break
|
||||
_log.info(f'progress {p}/{sp.points.shape[0]}')
|
||||
if p<0 or dlg.wasCanceled():
|
||||
break
|
||||
#_log.info(f'progress {p}/{sp.points.shape[0]}')
|
||||
dlg.setValue(p)
|
||||
time.sleep(.1)
|
||||
if not dlg.wasCanceled():
|
||||
jf.gather_upload()
|
||||
dlg.setLabelText("upload gather data")
|
||||
sp.gather_upload(fnRec=fn+'.npz')
|
||||
if dt_misc['show_plots']:
|
||||
dp=deltatau.shapepath.DebugPlot(sp)
|
||||
dp=psi_device.shapepath.DebugPlot(sp)
|
||||
dp.plot_gather(mode=11)
|
||||
plt.show(block=False)
|
||||
#plt.show(block=True)
|
||||
|
||||
@@ -107,9 +107,9 @@ class autofocus(QtGui.QMainWindow):
|
||||
# fft[300:700,400:800]=0
|
||||
# v[i,1]=fft.sum()
|
||||
|
||||
self._imv1.setImage(sb,autoRange=auto,autoLevels=auto,autoHistogramRange=auto)
|
||||
#self._imv2.setImage(sb,autoRange=auto,autoLevels=auto,autoHistogramRange=auto)
|
||||
self._imv2.setImage(sbLut,autoRange=auto,autoLevels=auto,autoHistogramRange=auto)
|
||||
self._imv1.setImage(img,autoRange=auto,autoLevels=auto,autoHistogramRange=auto)
|
||||
self._imv2.setImage(sb,autoRange=auto,autoLevels=auto,autoHistogramRange=auto)
|
||||
#self._imv2.setImage(sbLut,autoRange=auto,autoLevels=auto,autoHistogramRange=auto)
|
||||
mtr=self._metrics
|
||||
|
||||
mtr[i, 0]=img.std()
|
||||
|
||||
@@ -69,13 +69,26 @@ class fiducial(QtGui.QMainWindow):
|
||||
self._imgLst=imgLst=sorted(glob.glob("../scratch/fiducial/*.png"))
|
||||
self._metrics=mtr=np.ndarray(shape=(len(imgLst), 5))
|
||||
mtr[:]=0
|
||||
self._sld=sld=QtGui.QSlider(QtCore.Qt.Horizontal)
|
||||
sld.setMinimum(0)
|
||||
sld.setMaximum(len(imgLst)-1)
|
||||
sld.setValue(0)
|
||||
sld.setTickPosition(QtGui.QSlider.TicksBelow)
|
||||
sld.setTickInterval(1)
|
||||
sld.valueChanged.connect(self.cb_sld_change)
|
||||
self._sldImgIdx=sld1=QtGui.QSlider(QtCore.Qt.Horizontal)
|
||||
sld1.setMinimum(0)
|
||||
sld1.setMaximum(len(imgLst)-1)
|
||||
sld1.setValue(0)
|
||||
sld1.setTickPosition(QtGui.QSlider.TicksBelow)
|
||||
sld1.setTickInterval(1)
|
||||
sld1.valueChanged.connect(self.cb_sld_change)
|
||||
|
||||
self._sldTplSz=sld2=QtGui.QSlider(QtCore.Qt.Horizontal)
|
||||
sld2.setMinimum(0)
|
||||
sld2.setMaximum(300)
|
||||
sld2.setValue(90)
|
||||
sld2.valueChanged.connect(self.cb_sld_change)
|
||||
|
||||
self._sldTplBrd=sld3=QtGui.QSlider(QtCore.Qt.Horizontal)
|
||||
sld3.setMinimum(3)
|
||||
sld3.setMaximum(50)
|
||||
sld3.setValue(20)
|
||||
sld3.valueChanged.connect(self.cb_sld_change)
|
||||
|
||||
|
||||
self._imv1=imv1=pg.ImageView()
|
||||
self._imv2=imv2=pg.ImageView()
|
||||
@@ -91,10 +104,12 @@ class fiducial(QtGui.QMainWindow):
|
||||
|
||||
pw.resize(100,100)
|
||||
pw.setMaximumSize(2000,200)
|
||||
l.addWidget(sld, 0, 0)
|
||||
l.addWidget(imv1, 1, 0)
|
||||
l.addWidget(imv2, 2, 0)
|
||||
l.addWidget(pw, 3, 0)
|
||||
l.addWidget(sld1, 0, 0)
|
||||
l.addWidget(sld2, 1, 0)
|
||||
l.addWidget(sld3, 2, 0)
|
||||
l.addWidget(imv1, 3, 0)
|
||||
l.addWidget(imv2, 4, 0)
|
||||
l.addWidget(pw, 5, 0)
|
||||
|
||||
## Display the data
|
||||
self.cb_sld_change(0,True)
|
||||
@@ -108,7 +123,7 @@ class fiducial(QtGui.QMainWindow):
|
||||
self._imv2.setLevels(0, 1)
|
||||
|
||||
def cb_sld_change(self,val,auto=False):
|
||||
i=self._sld.value()
|
||||
i=self._sldImgIdx.value()
|
||||
_log.debug(f'{i}')
|
||||
fn= self._imgLst[i]
|
||||
img=PIL.Image.open(fn)
|
||||
@@ -134,15 +149,17 @@ class fiducial(QtGui.QMainWindow):
|
||||
#fid=np.ones((250,250),dtype=np.uint8)*255
|
||||
#fid[20:230,20:230]=0
|
||||
|
||||
sz=(90, 90); brd=(20, 20) # zoom 001
|
||||
#sz=(130, 130); brd=(20, 20) # zoom 200
|
||||
#sz=(210, 210); brd=(20, 20) # zoom 400
|
||||
#sz=( 84, 84); brd=( 7, 7) # zoom 001
|
||||
#sz=(128, 128); brd=( 9, 9) # zoom 200
|
||||
#sz=(200, 200); brd=(13, 13) # zoom 400
|
||||
v=self._sldTplSz.value(); sz=(v,v)
|
||||
v=self._sldTplBrd.value(); brd=(v,v)
|
||||
|
||||
fid=np.ones((sz[1]+2*brd[1],sz[0]+2*brd[0]),dtype=np.uint8)*255
|
||||
fid[brd[1]:sz[1]+brd[1],brd[0]:sz[0]+brd[0]]=0
|
||||
mask=np.ones((sz[1]+2*brd[1],sz[0]+2*brd[0]),dtype=np.uint8)*255
|
||||
mask[2*brd[1]:sz[1],2*brd[0]:sz[0]]=0
|
||||
|
||||
|
||||
#https://docs.opencv.org/4.5.2/d4/dc6/tutorial_py_template_matching.html
|
||||
#res = cv.matchTemplate(img,fid,cv.TM_CCORR_NORMED )
|
||||
res = cv.matchTemplate(img,fid,cv.TM_CCORR_NORMED,mask=mask)
|
||||
@@ -177,6 +194,11 @@ class fiducial(QtGui.QMainWindow):
|
||||
self._imv1.setImage(img,autoRange=auto,autoLevels=auto,autoHistogramRange=auto)
|
||||
self._imv2.setImage(res,autoRange=auto,autoLevels=auto,autoHistogramRange=auto)
|
||||
pos=mtr.mean(0)[::-1]+(fw2,fh2)
|
||||
print(fid)
|
||||
print(mask)
|
||||
print(corr)
|
||||
print(mtr)
|
||||
print(f'TplSz:{sz} TplBrd:{brd}')
|
||||
_log.debug(f'position: {pos} correlation:{corr.mean()}')
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user