wip
This commit is contained in:
@@ -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):
|
||||||
|
|||||||
48
camera.py
48
camera.py
@@ -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')
|
||||||
|
|||||||
107
swissmx.py
107
swissmx.py
@@ -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']]
|
||||||
|
|||||||
Reference in New Issue
Block a user