This commit is contained in:
2022-09-01 13:29:57 +02:00
parent 1d818568f5
commit a54e580664
3 changed files with 121 additions and 49 deletions

View File

@@ -32,13 +32,13 @@ class MyJsonEncoder(json.JSONEncoder):
class AppCfg(QSettings): class AppCfg(QSettings):
GBL_FLD_SCR_SHOT="global/folder_screenshot" GBL_FLD_SCR_SHOT="global/folder_screenshot"
GEO_OPT_CTR='geometry/opt_ctr' GEO_OPT_CTR='geometry/opt_ctr'
GEO_PIX2POS='geometry/pix2pos' GEO_PIX2POS='geometry/pix2pos'
GEO_BEAM_SZ="geometry/beam_size" GEO_BEAM_SZ="geometry/beam_size"
GEO_BEAM_POS="geometry/beam_pos" GEO_BEAM_POS="geometry/beam_pos"
GEO_CAM_PARAM="geometry/cam_param"
WINDOW_GEOMETRY="window/geometry" WINDOW_GEOMETRY="window/geometry"
WINDOW_SPLITTER="window/splitter" WINDOW_SPLITTER="window/splitter"
@@ -147,9 +147,13 @@ class AppCfg(QSettings):
def setValue(self, key: str, val): #overload to debug def setValue(self, key: str, val): #overload to debug
# only simple lists, str, int, float can not be serialized nicely # only simple lists, str, int, float can not be serialized nicely
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,):
val=json.dumps(val, cls=MyJsonEncoder)
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,):
if type(val)==np.ndarray:
val=val.tolist() val=val.tolist()
elif type(val)==tuple: elif type(val)==tuple:
val=list(val) val=list(val)
@@ -157,9 +161,12 @@ class AppCfg(QSettings):
def value(self,key,*vargs,**kwargs): #overload to debug def value(self,key,*vargs,**kwargs): #overload to debug
val=super(AppCfg, self).value(key,*vargs,**kwargs) val=super(AppCfg, self).value(key,*vargs,**kwargs)
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,):
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):

View File

@@ -169,6 +169,54 @@ class epics_cam(object):
pv_w=self.getPv('WIDTH');pv_h=self.getPv('HEIGHT') pv_w=self.getPv('WIDTH');pv_h=self.getPv('HEIGHT')
self._sz=(int(pv_w.value), int(pv_h.value)) self._sz=(int(pv_w.value), int(pv_h.value))
def get_param(self):
param=dict()
pv_gain=self.getPv('AMPGAIN')
pv_exp=self.getPv('EXPOSURE')
pv_bx=self.getPv('BINX');pv_by=self.getPv('BINY')
pv_rxs=self.getPv('REGIONX_START');pv_rxe=self.getPv('REGIONX_END')
pv_rys=self.getPv('REGIONY_START');pv_rye=self.getPv('REGIONY_END')
pv_mono8=self.getPv('FORCEMONO8')
param['gain']=pv_gain.get()
param['exposure']=pv_exp.get()
param['binning']=(pv_bx.get(),pv_by.get())
xs=pv_rxs.get();xe=pv_rxe.get()
ys=pv_rys.get();ye=pv_rye.get()
param['roi']=(xs,ys,xe-xs,ye-ys)
param['mono8']=pv_mono8.get()
return param
def set_param(self,**kwargs):
param=[]
for k,v in kwargs:
if k=='gain':
pv_gain=self.getPv('AMPGAIN')
param.append((pv_gain,v))
elif k=='exposure':
pv_exp=self.getPv('EXPOSURE')
param.append((pv_exp,v))
elif k=='binning':
pv_bx=self.getPv('BINX');pv_by=self.getPv('BINY')
param.append((pv_bx,v[0]))
param.append((pv_by,v[1]))
elif k=='roi':
pv_rxs=self.getPv('REGIONX_START');pv_rxe=self.getPv('REGIONX_END')
pv_rys=self.getPv('REGIONY_START');pv_rye=self.getPv('REGIONY_END')
pv_rxs.put(v[0], wait=False)
pv_rxe.put(v[0]+v[2], wait=False)
pv_rys.put(v[1], wait=False)
pv_rye.put(v[1]+v[3], wait=False)
param.append((pv_rxs,v[0]))
param.append((pv_rxe,v[0]+v[2]))
param.append((pv_rys,v[1]))
param.append((pv_rye,v[1]+v[3]))
elif k=='mono8':
pv_mono8=self.getPv('FORCEMONO8')
param.append((pv_mono8,vv))
self.update_params(param)
def set_exposure(self,exp): def set_exposure(self,exp):
try: try:
pv_exp=self.getPv('EXPOSURE') pv_exp=self.getPv('EXPOSURE')

View File

@@ -86,7 +86,7 @@ import qtawesome
import qutilities import qutilities
from PyQt5 import QtCore, QtGui from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import Qt, pyqtSlot, QSize, QRegExp, pyqtSignal, QObject, QThread from PyQt5.QtCore import Qt, pyqtSlot, QSize, QRegExp, pyqtSignal, QObject, QThread
from PyQt5.QtGui import QKeySequence, QPixmap, QRegExpValidator from PyQt5.QtGui import QKeySequence, QPixmap, QRegExpValidator, QFont
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QAction, QApplication, QDoubleSpinBox, QFileDialog, QFormLayout, QGridLayout, QGroupBox, QHBoxLayout, QLabel, QLineEdit, QAction, QApplication, QDoubleSpinBox, QFileDialog, QFormLayout, QGridLayout, QGroupBox, QHBoxLayout, QLabel, QLineEdit,
QMessageBox, QPlainTextEdit, QProgressBar, QProgressDialog, QPushButton, QShortcut, QSizePolicy, QSpinBox, QMessageBox, QPlainTextEdit, QProgressBar, QProgressDialog, QPushButton, QShortcut, QSizePolicy, QSpinBox,
@@ -302,9 +302,10 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
self._message_critical_fault = QLabel(None) self._message_critical_fault = QLabel(None)
self._message_critical_fault.setAccessibleName("device_fault") self._message_critical_fault.setAccessibleName("device_fault")
self.statusbar.insertWidget(0, self._message_critical_fault) self.statusbar.insertWidget(0, self._message_critical_fault)
self._lb_coords = QLabel(None) self._lb_coords=lbl=QLabel(None)
self._lb_coords.setText("coords") #f=QFont('monospace', 10)
self.statusbar.addPermanentWidget(self._lb_coords) #lbl.setFont(f)
self.statusbar.addPermanentWidget(lbl)
self._fel_status = QLabel(None) self._fel_status = QLabel(None)
self._fel_status.setAccessibleName("fel_status_statusbar") self._fel_status.setAccessibleName("fel_status_statusbar")
@@ -645,7 +646,25 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
self.cb_new_frame_sim() self.cb_new_frame_sim()
except AttributeError: except AttributeError:
self.sigNewCamImg.connect(self.cb_update_img) self.sigNewCamImg.connect(self.cb_update_img)
app._camera.run(self.cb_new_frame_pv) cam=app._camera
cfg=app._cfg
param=cam.get_param()
try:
paramSv=cfg.value(AppCfg.GEO_CAM_PARAM)
except AttributeError as e:
cfg.setValue(AppCfg.GEO_CAM_PARAM, param)
else:
for k,v in param.items():
if v!=paramSv[k]:
if type(v)==tuple:
if v==tuple(paramSv[k]):
continue
#cam.set_param(paramSv)
#cfg.setValue(AppCfg.GEO_CAM_PARAM, param)
#break
_log.debug(f'diff:{k},{v} != {paramSv[k]}')
cam.run(self.cb_new_frame_pv)
def cb_new_frame_pv(self, **kwargs): def cb_new_frame_pv(self, **kwargs):
#thrd=threading.current_thread() #thrd=threading.current_thread()
@@ -932,47 +951,40 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
def cb_mouse_move(self, pos): def cb_mouse_move(self, pos):
app = QApplication.instance() app = QApplication.instance()
self._mouse_pos = pos geo = app._geometry
#pos = pixel position on the widget
task = self.active_task() task = self.active_task()
xy = self._goImg.mapFromScene(pos)
z = app._zoom.get_val() z = app._zoom.get_val()
#_log.debug('mouse_pos:{} scene_pos:{} zoom:{}'.format(pos,xy,z))
#TODO: implement mouse handling
# if self._ppm_toolbox._force_ppm > 0:
# ppm = self._ppm_toolbox._force_ppm
# else:
try:
ppm = self.ppm_fitter(z)
except:
ppm = 1E3
x, y = xy.x(), xy.y()
try:
bx, by = self.get_beam_mark_on_camera_xy()
except:
bx, by = 500, 500
dx = (x - bx) / ppm
dy = -(y - by) / ppm
try:
fx = self.tweakers["fast_x"].motor.get_position()
fy = self.tweakers["fast_y"].motor.get_position()
fx += dx
fy += dy
except:
fx=fy=0
self._lb_coords.setText( #bm=self._goBeamMarker
"\u23FA{:>}:{:>6.0f} {:<.0f}" #pos=event.scenePos()
"\u23FA{:>}:{:>6.0f} {:<.0f}" pImg=pg.Point(self._goImg.mapFromScene(pos))
"\u23FA{:>}:{:<.0f}" pTrk=pg.Point(self._goTracked.mapFromScene(pos))
"\u23FA{:>}:{:>6.1f} {:<.1f} \u00B5" fx=self.tweakers["fast_x"].get_val()
"\u23FA{:>}:{:>7.3f} {:<.3f} mm".format( fy=self.tweakers["fast_y"].get_val()
"Beam at", bx, by, pTrk=pTrk-(fx,fy)
"Pixel coord ", x, y, #s=f'pImg{pImg} pTrk{pTrk} bm._pos_eu{bm._pos_eu}'
"PPM", ppm,
"Distance to beam", 1000 * dx, 1000 * dy,
"Stage", fx, fy, s=\
) f'img pix ({pImg[0]:>0.1f} {pImg[1]:>0.1f})px \u23A2 ' \
) f'dist to beam ({pTrk[0]:>0.6g} {pTrk[1]:>0.6g}mm) '
_log.debug(s)
self._lb_coords.setText(s)
#self._lb_coords.setText(
# "\u23FA{:>}:{:>6.0f} {:<.0f}"
# "\u23FA{:>}:{:>6.0f} {:<.0f}"
# "\u23FA{:>}:{:<.0f}"
# "\u23FA{:>}:{:>6.1f} {:<.1f} \u00B5"
# "\u23FA{:>}:{:>7.3f} {:<.3f} mm".format(
# "Beam at", bx, by,
# "Pixel coord ", x, y,
# "PPM", ppm,
# "Distance to beam", 1000 * dx, 1000 * dy,
# "Stage", fx, fy,
# )
#)
def cb_mouse_click(self, event): def cb_mouse_click(self, event):
#_log.debug("{}".format(event)) #_log.debug("{}".format(event))
@@ -983,7 +995,8 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
#_log.debug(f"vb pos {self.vb.mapFromScene(p)}") #pixel position on the scene (including black frame) #_log.debug(f"vb pos {self.vb.mapFromScene(p)}") #pixel position on the scene (including black frame)
#for o in self.vb.childGroup.childItems(): #for o in self.vb.childGroup.childItems():
# _log.debug(f"{type(o)} pos {o.mapFromScene(p)}") #pixel position on the scene (including black frame) # _log.debug(f"{type(o)} pos {o.mapFromScene(p)}") #pixel position on the scene (including black frame)
_log.debug(f"currentItem:{event.currentItem}")
#_log.debug(f"currentItem:{event.currentItem}")
task = self.active_task() task = self.active_task()
if task==TASK_SETUP_GEOMETRY_CALIB: if task==TASK_SETUP_GEOMETRY_CALIB:
self.mouse_click_event_geometry_calib(event) self.mouse_click_event_geometry_calib(event)
@@ -1270,7 +1283,11 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
import PIL.Image import PIL.Image
#img=PIL.Image.fromarray(cam.pic.astype(np.uint8)) #img=PIL.Image.fromarray(cam.pic.astype(np.uint8))
try: try:
pic=cam.pic pic=cam._pic
mx=pic.max()
if pic.max()>255:
scl=2**int(round(np.log2(mx)-8))
pic=np.array(pic/scl,dtype=np.uint8)
except AttributeError: except AttributeError:
sim=app._camera._sim sim=app._camera._sim
pic=cam._sim['imgSeq'][sim['imgIdx']] pic=cam._sim['imgSeq'][sim['imgIdx']]