wip
This commit is contained in:
10
Readme.md
10
Readme.md
@@ -7,7 +7,6 @@ pyqtgraph.examples.run()
|
||||
|
||||
```
|
||||
|
||||
|
||||
EPICS simulator
|
||||
---------------
|
||||
```
|
||||
@@ -67,8 +66,13 @@ cd /tmp/qtawesome
|
||||
EPICS_CA_ADDR_LIST='129.129.244.255 sf-saresc-cagw.psi.ch:5062 sf-saresc-cagw.psi.ch:5066'
|
||||
cd /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/oldRepos/app/src
|
||||
python swissmx.py
|
||||
```
|
||||
|
||||
|
||||
pyqtgraph examples
|
||||
------------------
|
||||
```
|
||||
import pyqtgraph.examples
|
||||
pyqtgraph.examples.run()
|
||||
```
|
||||
|
||||
|
||||
@@ -90,8 +94,6 @@ wlp2s0: MAC: 80:38:fb:d6:01:78 wlan-corp 129.129.64.249
|
||||
enx00e04c680519: MAC: 00:e0:4c:68:05:19
|
||||
|
||||
|
||||
import pyqtgraph.examples
|
||||
pyqtgraph.examples.run()
|
||||
Benchmark -> VideoSpeedTest
|
||||
|
||||
rsync -vai /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX/ saresc-cons-02:/tmp/zamofing_t/
|
||||
|
||||
@@ -12,20 +12,22 @@ from PyQt5.QtCore import QSettings
|
||||
import os, json, yaml
|
||||
|
||||
class AppCfg(QSettings):
|
||||
WINDOW_GEOMETRY="window/geometry"
|
||||
WINDOW_STATE= "window/state"
|
||||
WINDOW_SPLITTER="window/splitter"
|
||||
|
||||
# ---------- OBSOLETE ??? ----------
|
||||
ZOOM_BUTTONS="sample_viewing/zoom_buttons"
|
||||
|
||||
SKIP_ESCAPE_TRANSITIONS_IF_SAFE="escape/skip_transitions_if_safe"
|
||||
|
||||
GEO_OPT_CTR='geometry/opt_ctr'
|
||||
GEO_PIX2POS='geometry/pix2pos'
|
||||
|
||||
BEAM_MARKER_POSITIONS="beam/marker_positions"
|
||||
BEAM_SIZE="beam/size"
|
||||
GEO_BEAM_SZ="geometry/beam_size"
|
||||
GEO_BEAM_POS="geometry/beam_pos"
|
||||
|
||||
|
||||
WINDOW_GEOMETRY="window/geometry"
|
||||
WINDOW_SPLITTER="window/splitter"
|
||||
WINDOW_STATE= "window/state"
|
||||
|
||||
# ---------- OBSOLETE ??? ----------
|
||||
#ZOOM_BUTTONS="sample_viewing/zoom_buttons"
|
||||
|
||||
SKIP_ESCAPE_TRANSITIONS_IF_SAFE="escape/skip_transitions_if_safe"
|
||||
|
||||
CRYOJET_MOTION_ENABLED="cryojet/motion_enabled"
|
||||
CRYOJET_NOZZLE_OUT="cryojet/nozzle_out"
|
||||
@@ -47,9 +49,78 @@ class AppCfg(QSettings):
|
||||
def __init__(self):
|
||||
super(AppCfg, self).__init__("PSI", "SwissMX")
|
||||
keys = self.allKeys()
|
||||
# Dump config to debug
|
||||
#for k in keys:
|
||||
# print(k, self.value(k))
|
||||
|
||||
#set default keys if not existing
|
||||
if AppCfg.BEAM_SIZE not in keys:
|
||||
self.setValue(AppCfg.BEAM_SIZE, [40, 20]) #([40, 20) -> tuples are not supported natively
|
||||
if AppCfg.GEO_BEAM_SZ not in keys:
|
||||
_log.warning(f'{AppCfg.GEO_BEAM_SZ} not defined. set default')
|
||||
self.setValue(AppCfg.GEO_BEAM_SZ, [40, 20]) #([40, 20) -> tuples are not supported natively
|
||||
|
||||
if AppCfg.GEO_PIX2POS not in keys:
|
||||
_log.warning(f'{AppCfg.GEO_OPT_CTR} not defined. calc default')
|
||||
import geometry
|
||||
geo=geometry.geometry()
|
||||
pix2pos_measure={
|
||||
1:[(-3.0, -7.6, 116.99110193046, 632.5463827525),
|
||||
(-2.0, -7.6, 934.07501517856, 600.7926167715),
|
||||
(-2.0, -7.1, 916.54131238102, 191.0366615002),
|
||||
(-3.0, -7.1, 103.74668003329, 226.2150231456)],
|
||||
200:[(-3.1, -7.3, 113.66321353086, 824.9041423107),
|
||||
(-2.3, -7.3, 1065.97386092697, 792.2851118419),
|
||||
(-2.3, -6.7, 1033.68452410347, 74.0336610693),
|
||||
(-3.1, -6.7, 84.62681572700, 116.6832971512)],
|
||||
400:[(-3.4, -6.7, 155.00053674203, 601.3838942136),
|
||||
(-3.0, -6.7, 957.95919656052, 573.0827012272),
|
||||
(-3.2, -6.5, 541.08684037200, 187.9171307943),
|
||||
(-3.2, -6.8, 564.32152887203, 789.1146957326)],
|
||||
600:[(-3.3, -6.8, 328.27244399903, 509.5061192017),
|
||||
(-3.1, -6.8, 992.78996735279, 488.0323963092),
|
||||
(-3.2, -6.9, 672.03111567934, 832.4122409755),
|
||||
(-3.2, -6.7, 645.70960116180, 164.2534779331)],
|
||||
800:[(-3.2, -6.7, 639.52253576449, 53.4455632943),
|
||||
(-3.2, -6.85, 671.47023245203, 882.6335091391),
|
||||
(-3.3, -6.75, 105.12470026379, 361.3051859197),
|
||||
(-3.1, -6.75, 1195.96864609255, 313.1068618673)],
|
||||
1000:[(-3.25, -6.75, 195.05641095116, 353.3492286375),
|
||||
(-3.15, -6.75, 1117.27204644084, 314.9636405871),
|
||||
(-3.2, -6.8, 675.10991143017, 790.3040145281),
|
||||
(-3.2, -6.72, 638.98580653116, 59.3803912957)]}
|
||||
geo.update_pix2pos(pix2pos_measure)
|
||||
self.setValue(AppCfg.GEO_PIX2POS, geo._lut_pix2pos)
|
||||
|
||||
if AppCfg.GEO_OPT_CTR not in keys:
|
||||
_log.warning(f'{AppCfg.GEO_OPT_CTR} not defined. calc default')
|
||||
import geometry
|
||||
geo=geometry.geometry()
|
||||
opt_ctr_meas={ # x,y = 0.02, -4.89
|
||||
1000:[(1057.4251530483375, 116.10122290395591),
|
||||
(117.84916300310408, 190.27827474963223),
|
||||
(184.2181041281829, 963.2812360887852),
|
||||
(1092.5616512910262, 899.514998537239)],
|
||||
800:[(888.2494207687248, 203.2917926172947),
|
||||
(329.96950424600305, 248.83910515411347),
|
||||
(372.9141132092893, 708.2162858826),
|
||||
(906.4683457834523, 675.6824912134438)],
|
||||
600:[(781.5385742538922, 251.44180872764602),
|
||||
(447.09116505496564, 264.4553265953085),
|
||||
(471.81684900352445, 554.6567750441825),
|
||||
(798.4561474818535, 535.1364982426887)],
|
||||
400:[(722.9777438494109, 286.5783069703348),
|
||||
(525.1722722609408, 295.68776947769857),
|
||||
(535.5830865550707, 462.26079818377866),
|
||||
(729.4845027832422, 450.5486321028824)],
|
||||
200:[(689.1425973934884, 308.70128734536104),
|
||||
(565.5141776506945, 307.39993555859473),
|
||||
(574.6236401580583, 406.30267135282986),
|
||||
(693.0466527537872, 399.79591241899857)],
|
||||
1:[(673.5263759522934, 307.39993555859473),
|
||||
(591.5412133860195, 308.70128734536104),
|
||||
(595.4452687463182, 376.3715802572061),
|
||||
(672.2250241655271, 373.7688766836736)]}
|
||||
geo.update_optical_center(opt_ctr_meas)
|
||||
self.setValue(AppCfg.GEO_OPT_CTR, geo._opt_ctr)
|
||||
|
||||
#if AppCfg.ACTIVATE_PULSE_PICKER not in keys:
|
||||
# self.setValue(AppCfg.ACTIVATE_PULSE_PICKER, False)
|
||||
|
||||
@@ -18,8 +18,8 @@ from PyQt5.uic import loadUiType
|
||||
from epics.ca import pend_event
|
||||
|
||||
Ui_MotorTweak, QWidget = loadUiType('epics_widgets/MotorTweak.ui')
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.INFO)
|
||||
_log = logging.getLogger(__name__)
|
||||
#logger.setLevel(logging.INFO)
|
||||
|
||||
class SimMotor:
|
||||
def __init__(self,motor_base, short_name):
|
||||
@@ -140,9 +140,9 @@ class SimMotorTweak(QWidget, Ui_MotorTweak):
|
||||
if assert_position:
|
||||
wait=True
|
||||
if drive is None:
|
||||
logger.debug('{} abs target from widget'.format(self.short_name))
|
||||
_log.debug('{} abs target from widget'.format(self.motor._short_name))
|
||||
drive = float(self._drive_val.text())
|
||||
logger.debug('{} abs move => {}'.format(self.short_name, drive))
|
||||
_log.debug('{} abs move => {}'.format(self.motor._short_name, drive))
|
||||
self._pos=drive
|
||||
|
||||
def emit_signals(self, **kw):
|
||||
@@ -180,12 +180,12 @@ class SimMotorTweak(QWidget, Ui_MotorTweak):
|
||||
status = kw['char_value']
|
||||
if status in ('Holding', 'Stopped'):
|
||||
v = self._pv_readback.get(as_string=True)
|
||||
logger.debug('updating VAL on status change to holding/stopped = {}'.format(v))
|
||||
_log.debug('updating VAL on status change to holding/stopped = {}'.format(v))
|
||||
self._drive_val.setText(v)
|
||||
|
||||
def set_val(self, **kw):
|
||||
v = kw['char_value']
|
||||
logger.debug('updating VAL = {}'.format(v))
|
||||
_log.debug('updating VAL = {}'.format(v))
|
||||
self._drive_val.setText(v)
|
||||
|
||||
def update_label(self, **kwargs):
|
||||
@@ -242,9 +242,9 @@ class SimMotorTweak(QWidget, Ui_MotorTweak):
|
||||
self._controlbox.setDisabled(False)
|
||||
elif action == changeprecAction:
|
||||
msg = 'Precision for motor {}'.format(name)
|
||||
logger.debug('prec before %d', prec)
|
||||
_log.debug('prec before %d', prec)
|
||||
prec, ok = QInputDialog.getInt(self, msg, msg, prec, 0, 10)
|
||||
logger.debug('prec after (%d) %d', ok, prec)
|
||||
_log.debug('prec after (%d) %d', ok, prec)
|
||||
if ok:
|
||||
self._prec = prec
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ class IlluminationControl(object):
|
||||
try:
|
||||
s=self._socket
|
||||
except AttributeError: #simulated mode
|
||||
_log.info('simulated mode')
|
||||
_log.debug('simulated mode')
|
||||
return self._sim['stat']
|
||||
self.send_command(bytes((stat,all)))
|
||||
resp = self._socket.recv(1024)
|
||||
|
||||
@@ -19,29 +19,37 @@ import numpy as np
|
||||
from PyQt5.QtGui import QPolygon,QPolygonF
|
||||
from PyQt5.QtCore import QPointF,QLineF
|
||||
|
||||
def obj_info(obj):
|
||||
print(f"obj_info:{obj}")
|
||||
def obj_tree(obj,p=''):
|
||||
obj_info(obj,p)
|
||||
for o in obj.childItems():
|
||||
obj_tree(o,p+'.')
|
||||
|
||||
def obj_info(obj,p=''):
|
||||
print(f"{p}obj_info:{obj}")
|
||||
try:
|
||||
pos=obj.pos()
|
||||
print(f"Pos:({pos.x():.6g},{pos.y():.6g})") # in coordinate value on the scene (no change by zooming)
|
||||
print(f"{p}Pos:({pos.x():.6g},{pos.y():.6g})") # in coordinate value on the scene (no change by zooming)
|
||||
except AttributeError:
|
||||
pass
|
||||
try:
|
||||
for k, v in (('Viewport', obj.viewport()), ('Window', obj.window())):
|
||||
print(
|
||||
f"{k} (x,y)(w,h):({v.x():.6g},{v.y():.6g})({v.width():.6g},{v.height():.6g})") # in coordinate value on the scene (no change by zooming)
|
||||
f"{p}{k} (x,y)(w,h):({v.x():.6g},{v.y():.6g})({v.width():.6g},{v.height():.6g})") # in coordinate value on the scene (no change by zooming)
|
||||
except AttributeError:
|
||||
pass
|
||||
try:
|
||||
scnPos=obj.scenePos()
|
||||
print(f"scenePos:({scnPos.x():.6g},{scnPos.y():.6g})") # in pixel on the scene (changes by zooming)
|
||||
print(f"{p}scenePos:({scnPos.x():.6g},{scnPos.y():.6g})") # in pixel on the scene (changes by zooming)
|
||||
except AttributeError:
|
||||
pass
|
||||
try:
|
||||
t=obj.transform()
|
||||
print(f"QTransform:{t.m11():8.5g} {t.m12():8.5g} {t.m13():8.5g}")
|
||||
print(f" {t.m21():8.5g} {t.m22():8.5g} {t.m23():8.5g}")
|
||||
print(f" {t.m31():8.5g} {t.m32():8.5g} {t.m33():8.5g}")
|
||||
if type(obj)==QtGui.QTransform:
|
||||
t=obj
|
||||
else:
|
||||
t=obj.transform()
|
||||
print(f"{p}QTransform:{t.m11():8.5g} {t.m12():8.5g} {t.m13():8.5g}")
|
||||
print(f"{p} {t.m21():8.5g} {t.m22():8.5g} {t.m23():8.5g}")
|
||||
print(f"{p} {t.m31():8.5g} {t.m32():8.5g} {t.m33():8.5g}")
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
279
swissmx.py
279
swissmx.py
@@ -20,13 +20,18 @@ bitmask for simulation:
|
||||
|
||||
'''
|
||||
import logging
|
||||
logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ')
|
||||
|
||||
logging.getLogger('PyQt5.uic').setLevel(logging.INFO)
|
||||
logging.getLogger('requests').setLevel(logging.INFO)
|
||||
logging.getLogger('urllib3').setLevel(logging.INFO)
|
||||
logging.getLogger('paramiko').setLevel(logging.INFO)
|
||||
logging.getLogger('matplotlib').setLevel(logging.INFO)
|
||||
logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ')
|
||||
logging.getLogger('PIL').setLevel(logging.INFO)
|
||||
logging.getLogger('illumination').setLevel(logging.INFO)
|
||||
logging.getLogger('zoom').setLevel(logging.INFO)
|
||||
_log = logging.getLogger("swissmx")
|
||||
#_log.setLevel(logging.INFO)
|
||||
|
||||
import time
|
||||
class timestamp():
|
||||
@@ -52,7 +57,7 @@ import random, signal
|
||||
|
||||
|
||||
TASK_JUNGFRAU_SETTINGS = "jungfrau_settings"
|
||||
TASK_SETUP_PPM_CALIBRATION = "ppm_calibration"
|
||||
TASK_SETUP_GEOMETRY_CALIB = "geometry_calib"
|
||||
TASK_SETUP_PPM_CALIBRATION_TBOX = "ppm_calibration_tbox"
|
||||
TASK_SETUP_BEAM_CENTER = "beamcenter_calibration"
|
||||
TASK_SETUP_CAMERA = "setup_camera"
|
||||
@@ -146,25 +151,9 @@ ts.log('Import part 7/7:')
|
||||
#_log.info(f"connecting to microscope to camera server: {appsconf['microscope']['sample_camera']['pv_prefix']} ")
|
||||
#sample_camera = camera.camera_server(basename=appsconf["microscope"]["sample_camera"]["pv_prefix"]) #ZAC: orig. code
|
||||
|
||||
def print_transform(t):
|
||||
m11 = t.m11()
|
||||
m12 = t.m12()
|
||||
m13 = t.m13()
|
||||
m21 = t.m21()
|
||||
m22 = t.m22()
|
||||
m23 = t.m23()
|
||||
m31 = t.m31()
|
||||
m32 = t.m32()
|
||||
m33 = t.m33()
|
||||
print("{:20s}{:12.3f} {:12.3f} {:12.3f}".format("Transform", m11, m12, m13))
|
||||
print("{:20s}{:12.3f} {:12.3f} {:12.3f}".format(" ", m21, m22, m23))
|
||||
print("{:20s}{:12.3f} {:12.3f} {:12.3f}".format(" ", m31, m32, m33))
|
||||
|
||||
|
||||
def tdstamp():
|
||||
return time.strftime("%Y%m%dH%H%M%S")
|
||||
|
||||
|
||||
def datestamp():
|
||||
return time.strftime("%Y%m%d")
|
||||
|
||||
@@ -286,12 +275,12 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
self._status_task.setAccessibleName("status_task_label")
|
||||
self.statusbar.addPermanentWidget(self._status_task)
|
||||
|
||||
self.add_beam_marker()
|
||||
self._beam_markers = {}
|
||||
#self.add_beam_marker()
|
||||
#self._beam_markers = {}
|
||||
|
||||
# ppm calibration
|
||||
self._zoom_to_ppm = {}
|
||||
self._ppm_click = None
|
||||
#self._zoom_to_ppm = {}
|
||||
#self._ppm_click = None
|
||||
|
||||
self.load_stylesheet()
|
||||
|
||||
@@ -318,31 +307,53 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
self.switch_task()
|
||||
|
||||
def init_graphics(self):
|
||||
app = QApplication.instance()
|
||||
cfg = app._cfg
|
||||
self.glw = pg.GraphicsLayoutWidget()
|
||||
self.microscope_page.setLayout(QVBoxLayout())
|
||||
self.microscope_page.layout().addWidget(self.glw)
|
||||
self.glw.show()
|
||||
self.glw.scene().sigMouseMoved.connect(self.mouse_move_event)
|
||||
self.glw.scene().sigMouseClicked.connect(self.mouse_click_event)
|
||||
|
||||
self.vb=vb=self.glw.addViewBox(invertY=False)#,enableMenu=False)
|
||||
#--- viewbox ---
|
||||
self.vb=vb=self.glw.addViewBox(invertY=False)#),border='r')#,enableMenu=False)
|
||||
vb.setAspectLocked(True)
|
||||
vb.setBackgroundColor((120, 90, 90))
|
||||
|
||||
#--- image ---
|
||||
self.img=img=pg.ImageItem()
|
||||
tr=QtGui.QTransform() # prepare ImageItem transformation:
|
||||
tr.rotate(30)
|
||||
#opt_ctr=app._geometry._opt_ctr
|
||||
tr.setMatrix(-1, 0, 0,
|
||||
0,-1, 0,
|
||||
0, 0, 1)
|
||||
# opt_ctr[0], opt_ctr[1], 1)
|
||||
img.setTransform(tr) # assign transform
|
||||
# self.graphicsView.setCentralItem(self.vb)
|
||||
self.glw.scene().sigMouseMoved.connect(self.mouse_move_event)
|
||||
self.glw.scene().sigMouseClicked.connect(self.mouse_click_event)
|
||||
vb.setAspectLocked(True)
|
||||
vb.setBackgroundColor((120, 90, 90))
|
||||
vb.addItem(img)
|
||||
|
||||
#--- grid ---
|
||||
try:
|
||||
grid=pg.GridItem(pen=(0,255,0),textPen=(0,255,0)) #green grid and labels
|
||||
except:
|
||||
grid=pg.GridItem()
|
||||
tr.reset()
|
||||
grid.setTransform(tr) # assign transform
|
||||
vb.addItem(grid)
|
||||
|
||||
#--- beam marker ---
|
||||
w, h = cfg.value(AppCfg.GEO_BEAM_SZ)
|
||||
bm=UsrGO.BeamMark([50, 120], [30, 20])
|
||||
bm.setTransform(tr) # assign transform
|
||||
self.vb.addItem(bm)
|
||||
|
||||
#--- testing scan grid ---
|
||||
vi=UsrGO.Grid((120, -100), (200, 150), (30, 22), 2)
|
||||
vi.setTransform(tr) # assign transform
|
||||
self.vb.addItem(vi)
|
||||
#UsrGO.obj_tree(vb)
|
||||
|
||||
|
||||
def create_helical_widgets(self):
|
||||
tbox = self._helical_tablebox
|
||||
htab = self._helical_scan_table = HelicalTableWidget()
|
||||
@@ -392,7 +403,7 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
def add_beam_marker(self):
|
||||
app = QApplication.instance()
|
||||
cfg = app._cfg
|
||||
w, h = cfg.value(AppCfg.BEAM_SIZE)
|
||||
w, h = cfg.value(AppCfg.GEO_BEAM_SZ)
|
||||
self._beammark = bm = CstROI.BeamMark([100, 100], (int(w), int(h)), parent=self)
|
||||
tr=QtGui.QTransform() # prepare ImageItem transformation:
|
||||
tr.rotate(30)
|
||||
@@ -797,37 +808,50 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
|
||||
# group regions
|
||||
block = QWidget()
|
||||
block.setAccessibleName(TASK_SETUP_PPM_CALIBRATION)
|
||||
block.setAccessibleName(TASK_SETUP_GEOMETRY_CALIB)
|
||||
block.setContentsMargins(0, 0, 0, 0)
|
||||
block.setLayout(QVBoxLayout())
|
||||
grp = QWidget()
|
||||
block.layout().addWidget(grp)
|
||||
block.layout().addStretch()
|
||||
grp.setLayout(QGridLayout())
|
||||
tbox.addItem(block, "Pixel/MM Settings")
|
||||
grp.layout().addWidget(QLabel("feature size (µM)"), 0, 0)
|
||||
self._ppm_feature_size_spinbox = QDoubleSpinBox()
|
||||
self._ppm_feature_size_spinbox.setRange(5, 10000)
|
||||
self._ppm_feature_size_spinbox.setValue(50)
|
||||
self._ppm_feature_size_spinbox.setDecimals(0)
|
||||
self._ppm_feature_size_spinbox.setSuffix(" µM")
|
||||
grp.layout().addWidget(self._ppm_feature_size_spinbox, 0, 1)
|
||||
self._ppm_calibration = but = QPushButton("Start calibration")
|
||||
tbox.addItem(block, "geometry calibration")
|
||||
#grp.layout().addWidget(QLabel("feature size (µM)"), 0, 0)
|
||||
#self._ppm_feature_size_spinbox = QDoubleSpinBox()
|
||||
#self._ppm_feature_size_spinbox.setRange(5, 10000)
|
||||
#self._ppm_feature_size_spinbox.setValue(50)
|
||||
#self._ppm_feature_size_spinbox.setDecimals(0)
|
||||
#self._ppm_feature_size_spinbox.setSuffix(" µM")
|
||||
#grp.layout().addWidget(self._ppm_feature_size_spinbox, 0, 1)
|
||||
self._btn_pix2pos = but = QPushButton("pix2pos")
|
||||
but.setCheckable(True)
|
||||
but.clicked.connect(self.update_ppm_fitters)
|
||||
grp.layout().addWidget(but, 1, 0, 1, 2)
|
||||
but.clicked.connect(self.update_pix2pos)
|
||||
grp.layout().addWidget(but, 0, 0)
|
||||
self._btn_opt_ctr = but = QPushButton("opt_ctr")
|
||||
but.setCheckable(True)
|
||||
but.clicked.connect(self.update_opt_ctr)
|
||||
grp.layout().addWidget(but, 1, 0)
|
||||
|
||||
help = QTextBrowser()
|
||||
grp.layout().addWidget(help, 2, 0, 5, 2)
|
||||
grp.layout().addWidget(help, 2, 0)
|
||||
help.setHtml(
|
||||
"""<body>
|
||||
<h1>Pixel/MM Setup</h1>
|
||||
<h2>Pixel to position calibration</h2>
|
||||
<ol>
|
||||
<li>press: <b>Start calibration</b></li>
|
||||
<li>press: <b>pix2pos</b></li>
|
||||
<li>for each zoom level:
|
||||
<li>choose a good fiducial mark
|
||||
<li>move the stage x/y at min. 3 different locations
|
||||
<li>CTRL-Click (left mouse button) on the fiducial mark
|
||||
<li>un-click: <b>Start calibration</b></li>
|
||||
<li>un-click: <b>pix2pos</b></li>
|
||||
</ol>
|
||||
<h2>optical center calibration</h2>
|
||||
<ol>
|
||||
<li>press: <b>opt_ctr</b></li>
|
||||
<li>choose at least 3 fiducial mark visible at various zoom levels
|
||||
<li>for at least two zoom level:
|
||||
<li>CTRL-Click (left mouse button) on the fiducial marks
|
||||
<li>un-click: <b>opt_ctr</b></li>
|
||||
</ol>
|
||||
</body>
|
||||
"""
|
||||
@@ -978,14 +1002,31 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
self.beamx_fitter = np.poly1d(bx_coefs)
|
||||
self.beamy_fitter = np.poly1d(by_coefs)
|
||||
|
||||
def update_ppm_fitters(self, calib):
|
||||
def update_pix2pos(self, calib):
|
||||
app=QApplication.instance()
|
||||
if calib:
|
||||
_log.info("received new pix2pos calibration")
|
||||
app._ppmRaw=dict()
|
||||
app._raw_pix2pos=dict()
|
||||
else:
|
||||
app._geometry.update_pix2pos(app._ppmRaw)
|
||||
del app._ppmRaw
|
||||
s=str(app._raw_pix2pos).replace('),','),\n ').replace('],','],\n')
|
||||
print(s)
|
||||
res=QMessageBox.question(self, "calibration", f"use calibration\n{s} ? ")
|
||||
if res==QMessageBox.Yes:
|
||||
app._geometry.update_pix2pos(app._raw_pix2pos)
|
||||
del app._raw_pix2pos
|
||||
|
||||
def update_opt_ctr(self, calib):
|
||||
app=QApplication.instance()
|
||||
if calib:
|
||||
_log.info("received new pix2pos calibration")
|
||||
app._raw_opt_ctr=dict()
|
||||
else:
|
||||
s=str(app._raw_opt_ctr).replace('),','),\n ').replace('],','],\n')
|
||||
print(s)
|
||||
res=QMessageBox.question(self, "calibration", f"use calibration\n{s} ? ")
|
||||
if res==QMessageBox.Yes:
|
||||
app._geometry.update_optical_center(app._raw_opt_ctr)
|
||||
del app._raw_opt_ctr
|
||||
return
|
||||
|
||||
def zoom_changed_cb(self, value):
|
||||
@@ -1054,7 +1095,7 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
task = self.active_task()
|
||||
xy = self.img.mapFromScene(pos)
|
||||
z = app._zoom.get()
|
||||
_log.debug('mouse_pos:{} scene_pos:{} zoom:{}'.format(pos,xy,z))
|
||||
#_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
|
||||
@@ -1092,49 +1133,61 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
)
|
||||
)
|
||||
|
||||
def mouse_click_event_ppm(self, event):
|
||||
def mouse_click_event_geometry_calib(self, event):
|
||||
app=QApplication.instance()
|
||||
zoom = app._zoom.get()
|
||||
fast_x=self.tweakers["fast_x"];fast_y=self.tweakers["fast_y"]
|
||||
try:
|
||||
raw=app._ppmRaw[zoom]
|
||||
except (AttributeError,KeyError) as e:
|
||||
if type(e) is AttributeError:
|
||||
QMessageBox.warning(self, "pix2pos calibration", "Press 'Start calibration' button first")
|
||||
return
|
||||
app._ppmRaw=dict()
|
||||
raw=app._ppmRaw[zoom]=list()
|
||||
#event.screenPos() #position in pixel on the screen
|
||||
#event.pos() #position in pixel on the widget
|
||||
#event.scenePos() # position in user coordinates of the widget
|
||||
#img.mapFromScene(scenePos) #pixel position of the image at scenePos user coordinates
|
||||
#mousePos=event.pos() #position in pixel on the widget
|
||||
#scenePos=event.scenePos()
|
||||
#imgPos = self.img.mapFromScene(scenePos)
|
||||
#_log.debug('mouse_pos:{} scene_pos:{} imgPos:{}'.format(tuple(mousePos),tuple(scenePos),(imgPos.x(),imgPos.y())))
|
||||
#_log.debug('fast stage:{} {}'.format(fast_x.get_position(),fast_y.get_position()))
|
||||
imgPos = self.img.mapFromScene(event.scenePos())
|
||||
fx=fast_x.get_position();fy=fast_y.get_position()
|
||||
x=imgPos.x();y=imgPos.y()
|
||||
_log.debug('append calib: zoom:{} stage_x_y:{}/{} cam_pix_x_y:{}/{}'.format(zoom,fx,fy,x,y))
|
||||
raw.append((fx,fy,x,y))
|
||||
if self._btn_pix2pos.isChecked():
|
||||
try:
|
||||
raw=app._raw_pix2pos[zoom]
|
||||
except KeyError as e:
|
||||
raw=app._raw_pix2pos[zoom]=list()
|
||||
imgPos=self.img.mapFromScene(event.scenePos())
|
||||
fx=fast_x.get_position();
|
||||
fy=fast_y.get_position()
|
||||
x=imgPos.x();y=imgPos.y()
|
||||
_log.debug('append calib: zoom:{} stage_x_y:{}/{} cam_pix_x_y:{}/{}'.format(zoom, fx, fy, x, y))
|
||||
raw.append((fx, fy, x, y))
|
||||
elif self._btn_opt_ctr.isChecked():
|
||||
try:
|
||||
raw=app._raw_opt_ctr[zoom]
|
||||
except KeyError as e:
|
||||
raw=app._raw_opt_ctr[zoom]=list()
|
||||
imgPos=self.img.mapFromScene(event.scenePos())
|
||||
x=imgPos.x();y=imgPos.y()
|
||||
_log.debug('append calib: zoom:{} cam_pix_x_y:{}/{}'.format(zoom, x, y))
|
||||
raw.append(( x, y))
|
||||
else:
|
||||
QMessageBox.warning(self, "calibration", "no calibration started yet.\nPress 'pix2pos' or 'opt_ctr' button first")
|
||||
|
||||
def mouse_click_event(self, event):
|
||||
_log.debug("{}".format(event))
|
||||
_log.debug(" pos {}".format(event.pos()))
|
||||
_log.debug("screen pos {}".format(event.screenPos()))
|
||||
_log.debug("scene pos {}".format(event.scenePos()))
|
||||
_log.debug("screen pos {}".format(event.screenPos())) #pixel position on the whole screen
|
||||
_log.debug("scene pos {}".format(event.scenePos())) #pixel position on the scene (including black frame)
|
||||
#_log.debug(" pos {}".format(event.pos())) #pixel position of the ckicked object mapped to its coordinates
|
||||
p=event.scenePos()
|
||||
_log.debug(f"vb pos {self.vb.mapFromScene(p)}") #pixel position on the scene (including black frame)
|
||||
for o in self.vb.childGroup.childItems():
|
||||
_log.debug(f"{type(o)} pos {o.mapFromScene(p)}") #pixel position on the scene (including black frame)
|
||||
|
||||
task = self.active_task()
|
||||
if task==TASK_SETUP_PPM_CALIBRATION:
|
||||
self.mouse_click_event_ppm(event)
|
||||
if task==TASK_SETUP_GEOMETRY_CALIB:
|
||||
self.mouse_click_event_geometry_calib(event)
|
||||
return
|
||||
|
||||
|
||||
return
|
||||
assert(event.currentItem==self.vb)
|
||||
UsrGO.obj_tree(self.vb)
|
||||
#UsrGO.obj_info(self.img)
|
||||
|
||||
event.pos()# return Point(self.currentItem.mapFromScene(self._scenePos))
|
||||
|
||||
app=QApplication.instance()
|
||||
fx_motor, fy_motor, bx_motor, bz_motor, omega_motor = self.get_gonio_tweakers()
|
||||
|
||||
if event.button() == Qt.RightButton:
|
||||
print_transform(self.vb.childTransform())
|
||||
UsrGO.obj_info(self.vb.childTransform())
|
||||
event.ignore()
|
||||
return
|
||||
pos = event.scenePos()
|
||||
@@ -3302,75 +3355,11 @@ def main():
|
||||
|
||||
startupWin.set(5, f'load settings')
|
||||
app._cfg=cfg=AppCfg()
|
||||
#Dump config to debug
|
||||
#for k in cfg.allKeys():
|
||||
# print(k, cfg.value(k))
|
||||
|
||||
app._geometry=geometry.geometry()
|
||||
|
||||
# pix2pos_measure={
|
||||
# 1:[(-3.0, -7.6, 116.99110193046, 632.5463827525),
|
||||
# (-2.0, -7.6, 934.07501517856, 600.7926167715),
|
||||
# (-2.0, -7.1, 916.54131238102, 191.0366615002),
|
||||
# (-3.0, -7.1, 103.74668003329, 226.2150231456)],
|
||||
# 200:[(-3.1, -7.3, 113.66321353086, 824.9041423107),
|
||||
# (-2.3, -7.3, 1065.97386092697, 792.2851118419),
|
||||
# (-2.3, -6.7, 1033.68452410347, 74.0336610693),
|
||||
# (-3.1, -6.7, 84.62681572700, 116.6832971512)],
|
||||
# 400:[(-3.4, -6.7, 155.00053674203, 601.3838942136),
|
||||
# (-3.0, -6.7, 957.95919656052, 573.0827012272),
|
||||
# (-3.2, -6.5, 541.08684037200, 187.9171307943),
|
||||
# (-3.2, -6.8, 564.32152887203, 789.1146957326)],
|
||||
# 600:[(-3.3, -6.8, 328.27244399903, 509.5061192017),
|
||||
# (-3.1, -6.8, 992.78996735279, 488.0323963092),
|
||||
# (-3.2, -6.9, 672.03111567934, 832.4122409755),
|
||||
# (-3.2, -6.7, 645.70960116180, 164.2534779331)],
|
||||
# 800:[(-3.2, -6.7, 639.52253576449, 53.4455632943),
|
||||
# (-3.2, -6.85, 671.47023245203, 882.6335091391),
|
||||
# (-3.3, -6.75, 105.12470026379, 361.3051859197),
|
||||
# (-3.1, -6.75, 1195.96864609255, 313.1068618673)],
|
||||
# 1000:[(-3.25, -6.75, 195.05641095116, 353.3492286375),
|
||||
# (-3.15, -6.75, 1117.27204644084, 314.9636405871),
|
||||
# (-3.2, -6.8, 675.10991143017, 790.3040145281),
|
||||
# (-3.2, -6.72, 638.98580653116, 59.3803912957)]}
|
||||
#
|
||||
# opt_ctr_meas={ # x,y = 0.02, -4.89
|
||||
# 1000:[(1057.4251530483375, 116.10122290395591),
|
||||
# (117.84916300310408, 190.27827474963223),
|
||||
# (184.2181041281829, 963.2812360887852),
|
||||
# (1092.5616512910262, 899.514998537239)],
|
||||
# 800:[(888.2494207687248, 203.2917926172947),
|
||||
# (329.96950424600305, 248.83910515411347),
|
||||
# (372.9141132092893, 708.2162858826),
|
||||
# (906.4683457834523, 675.6824912134438)],
|
||||
# 600:[(781.5385742538922, 251.44180872764602),
|
||||
# (447.09116505496564, 264.4553265953085),
|
||||
# (471.81684900352445, 554.6567750441825),
|
||||
# (798.4561474818535, 535.1364982426887)],
|
||||
# 400:[(722.9777438494109, 286.5783069703348),
|
||||
# (525.1722722609408, 295.68776947769857),
|
||||
# (535.5830865550707, 462.26079818377866),
|
||||
# (729.4845027832422, 450.5486321028824)],
|
||||
# 200:[(689.1425973934884, 308.70128734536104),
|
||||
# (565.5141776506945, 307.39993555859473),
|
||||
# (574.6236401580583, 406.30267135282986),
|
||||
# (693.0466527537872, 399.79591241899857)],
|
||||
# 1:[(673.5263759522934, 307.39993555859473),
|
||||
# (591.5412133860195, 308.70128734536104),
|
||||
# (595.4452687463182, 376.3715802572061),
|
||||
# (672.2250241655271, 373.7688766836736)]}
|
||||
#
|
||||
# app._geometry.update_pix2pos(pix2pos_measure)
|
||||
# app._geometry.update_optical_center(opt_ctr_meas)
|
||||
#
|
||||
# app._cfg.setValue('geometry/pix2pos',app._geometry._lut_pix2pos)
|
||||
# app._cfg.setValue('geometry/opt_ctr',app._geometry._opt_ctr)
|
||||
# app._cfg.sync()
|
||||
|
||||
app._geometry._lut_pix2pos=cfg.value(cfg.GEO_OPT_CTR)
|
||||
app._geometry._lut_pix2pos=cfg.value(cfg.GEO_PIX2POS)
|
||||
app._geometry._opt_ctr=cfg.value(cfg.GEO_OPT_CTR)
|
||||
|
||||
|
||||
startupWin.set(15, f'connect backlight')
|
||||
if args.sim&0x01:
|
||||
app._backlight = backlight.Backlight(None)
|
||||
|
||||
41
zoom.py
41
zoom.py
@@ -51,16 +51,23 @@ class Zoom(QGroupBox, Ui_Zoom):
|
||||
|
||||
def init_settings(self):
|
||||
app=QApplication.instance()
|
||||
cfg=app._cfg
|
||||
keys=cfg.allKeys()
|
||||
if cfg.ZOOM_BUTTONS in keys:
|
||||
buttons=json.loads(cfg.value(cfg.ZOOM_BUTTONS))
|
||||
else:
|
||||
buttons=((1, "1"),(200, "200"),(400, "400"),(600, "600"),(800, "800"),(1000, "1000"),)
|
||||
cfg.setValue(cfg.ZOOM_BUTTONS,json.dumps(buttons))
|
||||
|
||||
#cfg=app._cfg
|
||||
#keys=cfg.allKeys()
|
||||
#if cfg.ZOOM_BUTTONS in keys:
|
||||
# buttons=json.loads(cfg.value(cfg.ZOOM_BUTTONS))
|
||||
#else:
|
||||
# buttons=((1, "1"),(200, "200"),(400, "400"),(600, "600"),(800, "800"),(1000, "1000"),)
|
||||
# cfg.setValue(cfg.ZOOM_BUTTONS,json.dumps(buttons))
|
||||
#self.get_zoom_pv = PV(zoom_api + ":ZOOM-RBV", callback=self.zoom_update_cb)
|
||||
#self.status_pv = PV(zoom_api + ":ZOOM-STATUS", callback=self.zoom_status_cb)
|
||||
#try:
|
||||
# pv=app._zoom.getPv('POS_RB')
|
||||
#except AttributeError as e:
|
||||
# _log.debug('Simulated zoom')
|
||||
#else:
|
||||
# pv.callbacks ... = self.zoom_update_cb
|
||||
# check also: pv.clear_auto_monitor() # disconnect PV monitor callback -> program exit faster.
|
||||
buttons=((1, "1"), (200, "200"), (400, "400"), (600, "600"), (800, "800"), (1000, "1000"),)
|
||||
current_zoom_value = self.get_zoom()
|
||||
|
||||
# zoom widgets
|
||||
@@ -268,14 +275,14 @@ class Zoom(QGroupBox, Ui_Zoom):
|
||||
_log.debug("get_zoom(epics) => {}".format(pos))
|
||||
return pos
|
||||
|
||||
def zoom_update_cb(self, pvname, value, char_value, **kwargs):
|
||||
self._zoom_spinner.blockSignals(True)
|
||||
self._zoom_spinner.setValue(value)
|
||||
self._zoom_spinner.blockSignals(False)
|
||||
# def zoom_update_cb(self, pvname, value, char_value, **kwargs):
|
||||
# self._zoom_spinner.blockSignals(True)
|
||||
# self._zoom_spinner.setValue(value)
|
||||
# self._zoom_spinner.blockSignals(False)
|
||||
|
||||
def zoom_status_cb(self, pvname, value, char_value, **kwargs):
|
||||
busy = bool(value)
|
||||
self.setDisabled(busy)
|
||||
# def zoom_status_cb(self, pvname, value, char_value, **kwargs):
|
||||
# busy = bool(value)
|
||||
# self.setDisabled(busy)
|
||||
|
||||
|
||||
class QopticZoom(object):
|
||||
@@ -301,7 +308,7 @@ class QopticZoom(object):
|
||||
try:
|
||||
pv = self.getPv('POS_RB')
|
||||
except AttributeError:
|
||||
val=self._val; _log.info('simulated mode:{}'.format(val))
|
||||
val=self._val; _log.debug('simulated mode:{}'.format(val))
|
||||
return val
|
||||
else:
|
||||
pv=self.getPv('POS_RB')
|
||||
@@ -311,7 +318,7 @@ class QopticZoom(object):
|
||||
try:
|
||||
pv=self.getPv('POS_SP')
|
||||
except AttributeError:
|
||||
_log.info('simulated mode:{}'.format(val))
|
||||
_log.debug('simulated mode:{}'.format(val))
|
||||
self._val=val #simulated mode
|
||||
else:
|
||||
pv.put(val)
|
||||
|
||||
Reference in New Issue
Block a user