rework settings, add pyqtUsrObj.py

This commit is contained in:
2022-07-21 17:34:21 +02:00
parent 569ce8a78d
commit c98795a7e0
6 changed files with 287 additions and 250 deletions

View File

@@ -42,7 +42,10 @@ P=ESB_MX/python/SwissMX/
ssh saresc-cons-02 mkdir -p /tmp/zamofing_t/$P ssh saresc-cons-02 mkdir -p /tmp/zamofing_t/$P
rsync -vai ~/Documents/prj/SwissFEL/epics_ioc_modules/$P saresc-cons-02:/tmp/zamofing_t/$P rsync -vai ~/Documents/prj/SwissFEL/epics_ioc_modules/$P saresc-cons-02:/tmp/zamofing_t/$P
cd /tmp/zamofing_t/ESB_MX/python/SwissMX cd /tmp/zamofing_t/ESB_MX/python/SwissMX
/opt/gfa/python-3.7/2018.12/bin/python camera.py -u -p SARES30-CAMS156-SMX-OAV /opt/gfa/python-3.7/2018.12/bin/python camera.py -u 1 -p SARES30-CAMS156-SMX-OAV
/opt/gfa/python-3.7/2018.12/bin/python swissmx.py
caqtdm -macro 'NAME=SARES30-CAMS156-SMX-OAV,CAMNAME=SARES30-CAMS156-SMX-OAV' /sf/controls/config/qt/Camera/CameraExpert_RF.ui caqtdm -macro 'NAME=SARES30-CAMS156-SMX-OAV,CAMNAME=SARES30-CAMS156-SMX-OAV' /sf/controls/config/qt/Camera/CameraExpert_RF.ui
@@ -60,6 +63,12 @@ setup.py install --user
cd /tmp/; git clone https://github.com/spyder-ide/qtawesome.git cd /tmp/; git clone https://github.com/spyder-ide/qtawesome.git
cd /tmp/qtawesome cd /tmp/qtawesome
#To have epics channels we must be connected to the ESC network
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
``` ```
@@ -148,9 +157,6 @@ https://pyepics.github.io/pyepics/arrays.html
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
caput SAR-EXPMX:MOT_FX.RBV -2.700 caput SAR-EXPMX:MOT_FX.RBV -2.700
caput SAR-EXPMX:MOT_FY.RBV -7.450 caput SAR-EXPMX:MOT_FY.RBV -7.450

View File

@@ -8,14 +8,22 @@
import logging import logging
_log = logging.getLogger(__name__) _log = logging.getLogger(__name__)
import os
from PyQt5.QtCore import QSettings from PyQt5.QtCore import QSettings
#import yaml import os, json, yaml
#from pathlib import Path
class AppCfg(QSettings): 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" 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_MARKER_POSITIONS="beam/marker_positions"
BEAM_SIZE="beam/size" BEAM_SIZE="beam/size"
@@ -39,31 +47,37 @@ class AppCfg(QSettings):
def __init__(self): def __init__(self):
super(AppCfg, self).__init__("PSI", "SwissMX") super(AppCfg, self).__init__("PSI", "SwissMX")
keys = self.allKeys() keys = self.allKeys()
if AppCfg.ACTIVATE_PULSE_PICKER not in keys: #set default keys if not existing
self.setValue(AppCfg.ACTIVATE_PULSE_PICKER, False) if AppCfg.BEAM_SIZE not in keys:
self.setValue(AppCfg.BEAM_SIZE, [40, 20]) #([40, 20) -> tuples are not supported natively
if AppCfg.SKIP_ESCAPE_TRANSITIONS_IF_SAFE not in keys: #if AppCfg.ACTIVATE_PULSE_PICKER not in keys:
self.setValue(AppCfg.SKIP_ESCAPE_TRANSITIONS_IF_SAFE, False) # self.setValue(AppCfg.ACTIVATE_PULSE_PICKER, False)
if "hits/marker_size" not in keys: #if AppCfg.SKIP_ESCAPE_TRANSITIONS_IF_SAFE not in keys:
self.setValue("hits/marker_size", 10) # self.setValue(AppCfg.SKIP_ESCAPE_TRANSITIONS_IF_SAFE, False)
if "graphs/show_auxiliary" not in keys: def sync(self):
self.setValue("graphs/show_auxiliary", False) super(AppCfg, self).sync()
#import numpy as np
#a=np.array(((1,2,3),(4,5,6)))
#self._yamlFn=fn=os.path.expanduser('~/.config/PSI/SwissMX.yaml')
#_yaml = [{'name': 'John Doe', 'occupation': 'gardener'},
# {'name': 'Lucy Black', 'occupation': 'teacher'}]
#_yaml = {'name': 'John Doe', 'occupation': 'gardener','A':(1,2,3),'B':{1,2,3},'C': {1:(1,2,3),2:'df',3:'dddd'},4:a }
#with open(self._yamlFn, 'w') as f:
# data = yaml.dump(_yaml, f)
# print(data)
if "graphs/auxiliary_graph_index" not in keys: def setValue(self, key: str, val): #overload to debug
self.setValue("graphs/auxiliary_graph_index", 0) return super(AppCfg, self).setValue(key,val)
if "scan_request/last_location" not in keys:
d10 = os.path.join(os.path.expanduser("~"), "Data10")
self.setValue("scan_request/last_location", d10)
if AppCfg.BEAM_SIZE in keys:
_log.info("setting beamsize from stored settings: {}".format(self.value(AppCfg.BEAM_SIZE)))
else:
_log.warning("beam size may not reflect reality, please check")
self.setValue(AppCfg.BEAM_SIZE, (40, 20))
def value(self,key,*vargs): #overload to debug
val=super(AppCfg, self).value(key,*vargs)
return val
#@property
#def value(self):
# return super(AppCfg, self).value
def option(self,key: str) -> bool: def option(self,key: str) -> bool:
try: try:

135
pyqtUsrObj.py Normal file
View File

@@ -0,0 +1,135 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Demonstrates a variety of uses for ROI. This class provides a user-adjustable
region of interest marker. It is possible to customize the layout and
function of the scale/rotate handles in very flexible ways.
"""
#import initExample ## Add path to library (just for examples; you do not need this)
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
class BeamMark(pg.ROI):
"""A crosshair ROI whose position is at the center of the crosshairs. By default, it is scalable, rotatable and translatable."""
def __init__(self, pos=None, size=None, parent=None, **kargs):
#self._size=size
#self._pos=pos
#self._shape=None
pg.ROI.__init__(self, pos, size, **kargs)
def paint(self, p, *args):
#pg.ROI.paint(self, p, *args)
r=QtCore.QRectF(0, 0, self.state['size'][0], self.state['size'][1]).normalized()
p.setRenderHint(QtGui.QPainter.Antialiasing)
p.setPen(self.currentPen)
p.translate(r.left(), r.top())
p.scale(r.width(), r.height())
p.drawEllipse(0, 0, 1, 1)
p.drawRect(0, 0, 1, 1)
p.setPen(pg.mkPen(width=3, color=[200, 100, 100]))
p.drawLine(pg.Point(.5, 0), pg.Point(.5, 1))
p.drawLine(pg.Point( 0,.5), pg.Point( 1,.5))
#w, h = self.getState()["size"]
#v1, v2 = -(h * 0.8) / 2, (h * 0.8) / 2
#h1, h2 = -(w * 0.8) / 2, (w * 0.8) / 2
#p.setRenderHint(QtGui.QPainter.Antialiasing)
#p.setPen(pg.mkPen(width=3, color=[200, 100, 100]))
#p.drawLine(pg.Point(0, v1), pg.Point(0, v2))
#p.drawLine(pg.Point(h1, 0), pg.Point(h2, 0))
#p.setPen(self.currentPen)
##p.setPen(pg.mkPen(width=3, color=[200, 200, 100]))
#p.drawRect(-w / 2, -h / 2, w, h)
## p.drawText(-w, -h, '{:.0f}x{:.0f}'.format(*self._size))
## Start Qt event loop unless running in interactive mode or using pyside.
if __name__=='__main__':
import sys
import argparse
#(h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>20 else sys.argv[0])+' '
#exampleCmd=('', '-m0xf -v0')
epilog=__doc__ #+'\nExamples:'+''.join(map(lambda s:cmd+s, exampleCmd))+'\n'
parser=argparse.ArgumentParser(epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("--mode", "-m", type=lambda x: int(x,0), help="mode default=0x%(default)x", default=0)
args = parser.parse_args()
pg.setConfigOptions(imageAxisOrder='row-major')
def obj_info(obj):
pos=obj.pos()
scnPos=obj.scenePos()
t=obj.transform()
obj_info
print(f"obj_info:{obj}")
print(f"Pos:({pos.x():.6g},{pos.y():.6g})") #in coordinate value on the scene (no change by zooming)
print(f"scenePos:({scnPos.x():.6g},{scnPos.y():.6g})") #in pixel on the scene (changes by zooming)
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}")
def pt2str(p):
return (f'({p.x():.5g},{p.y():.5g})')
def childTree(obj, lvl=0):
print('+'*lvl+str(obj))
for child in obj.childItems():
childTree(child, lvl+1)
def mouse_click_event(event):
pos=event.pos()
scn=event.scenePos() # there is a small black border, that makes the difference
img=viImg.mapFromScene(scn)
roi=viUsrRoi.mapFromScene(scn)
print(f'mouse:{pt2str(pos)} {pt2str(scn)} img:{pt2str(img)} roi:{pt2str(roi)}')
#childTree(vb)
obj_info(viUsrRoi)
## Create image to display
arr=np.ones((100, 100), dtype=float)
arr[45:55, 45:55]=0
arr[25, :]=5
arr[:, 25]=5
arr[75, :]=5
arr[:, 75]=5
arr[50, :]=10
arr[:, 50]=10
arr+=np.sin(np.linspace(0, 20, 100)).reshape(1, 100)
arr+=np.random.normal(size=(100, 100))
# add an arrow for asymmetry
arr[10, :50]=10
arr[9:12, 44:48]=10
arr[8:13, 44:46]=10
## create GUI
app=QtGui.QApplication([])
w=pg.GraphicsLayoutWidget(show=True, size=(1000, 800), border=True)
w.setWindowTitle('pyqtgraph example: ROI Examples')
vb=w.addViewBox(row=1, col=0, lockAspect=True)
g=pg.GridItem()
vb.addItem(g)
viImg=pg.ImageItem(arr, border='y')
vb.addItem(viImg)
# Custom ROI for selecting an image region
viRoi=pg.ROI([20, 50], [100, 70])
vb.addItem(viRoi)
viUsrRoi=BeamMark([10, 20], [30, 20])
vb.addItem(viUsrRoi)
childTree(vb)
w.scene().sigMouseClicked.connect(mouse_click_event)
if (sys.flags.interactive!=1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()

View File

@@ -1,182 +0,0 @@
#!/usr/bin/env python
# *-----------------------------------------------------------------------*
# | |
# | Copyright (c) 2022 by Paul Scherrer Institute (http://www.psi.ch) |
# | |
# | Author Thierry Zamofing (thierry.zamofing@psi.ch) |
# *-----------------------------------------------------------------------*
import os,epics
import time
import numpy as np
class SimCam:
def __init__(self):
pass
def generate(self,sz=(1500,1000),t=100,mode=0):
w,h=sz
self._imgSeq=imgSeq=np.ndarray(shape=(t,h,w),dtype=np.uint16)
x = np.linspace(-5, 5, w)
y = np.linspace(-5, 5, h)
# full coordinate arrays
xx, yy = np.meshgrid(x, y)
for i in range(t):
#imgSeq[i,:,:] = 100*np.sqrt(np.sin(xx+.1*i)**2 + np.sin(yy+.01*i)**2)#+xx*t+yy*t)
#imgSeq[i,:,:] = 100*np.sqrt(np.sin(xx+.1*i)**2 + np.sin((1+.1*np.sin(.2*i))*yy+.001*i**2)**2)#+xx*t+yy*t)
#imgSeq[i,:,:] = 100*np.sqrt(np.sin(xx+2*np.sin(i/t*2*np.pi))**2 + np.sin(yy)**2)
px=2*np.sin(i/t*2*np.pi)
fx=1
py=2*np.sin(i/t*2*np.pi)
fy=1+.3*np.sin(i/t*2*np.pi*2)
imgSeq[i,:,:] = 100*np.sqrt(np.sin(xx*fx+px)**2 + np.sin(yy*fy+py)**2)
#np.random.bytes(100)
wr=w//4
hr=h//4
imgSeq[:,0:hr,0:wr]+=np.random.randint(0,100,(t,hr,wr),dtype=np.uint16)
def pushEPICS(self,sz=None,t=100,prefix='SwissMxSim:'):
if prefix[-1]!=':': prefix+=':'
os.environ['EPICS_CA_ADDR_LIST'] = 'localhost'
pv = dict()
pv['pic'] = epics.PV(prefix + "FPICTURE")
for k, v in (('w', 'WIDTH'), ('h', 'HEIGHT'),):
pv[k] = epics.PV(prefix + v)
if sz:
w,h=sz
pv['w'].put(w)
pv['h'].put(h)
else:
w, h = int(pv['w'].value), int(pv['h'].value)
print('generate data...')
self.generate((w,h),t)
print('done. Now cycle and publish the data to EPICS')
imgSeq=self._imgSeq
while(True):
for i in range(t):
a = imgSeq[i,:,:].ravel()
pv['pic'].put(a)
print(pv['pic'].get())
#time.sleep(.01)
if __name__ == "__main__":
def QtUI(simCam):
global img, i, fps, updateTime
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
import pyqtgraph as pg
import pyqtgraph.ptime as ptime
import sys
app = QtGui.QApplication([])
## Create window with GraphicsView widget
win = pg.GraphicsLayoutWidget()
win.show() ## show widget alone in its own window
win.setWindowTitle('pyqtgraph example: ImageItem')
view = win.addViewBox()
## lock the aspect ratio so pixels are always square
view.setAspectLocked(True)
## Create image item
img = pg.ImageItem(border='g')
view.addItem(img)
## Set initial view bounds
view.setRange(QtCore.QRectF(0, 0, 600, 600))
i=0; fps=0; updateTime = ptime.time()
def updateData():
global img, i, updateTime, fps
img.setImage(simCam._imgSeq[i])
i = (i + 1) % simCam._imgSeq.shape[0]
QtCore.QTimer.singleShot(1, updateData)
now = ptime.time()
fps2 = 1.0 / (now - updateTime)
updateTime = now
fps = fps * 0.9 + fps2 * 0.1
print("%d %0.1f fps" % (i,fps))
updateData()
## Start Qt event loop unless running in interactive mode.
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
def QtUI2(simCam):
global img, i, fps, updateTime
import sys
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import pyqtgraph.ptime as ptime
print(pg.__version__)
# Interpret image data as row-major instead of col-major
pg.setConfigOptions(imageAxisOrder='row-major')
app = QtGui.QApplication([])
## Create window with ImageView widget
win = QtGui.QMainWindow()
win.resize(800,800)
imv = pg.ImageView()
win.setCentralWidget(imv)
win.show()
win.setWindowTitle('pyqtgraph example: ImageView')
## Display the data and assign each frame a time value from 1.0 to 3.0
i=0; fps=0; updateTime = ptime.time()
imv.setImage(simCam._imgSeq[i])
def updateData():
global img, i, updateTime, fps
imv.setImage(simCam._imgSeq[i], autoRange=False, autoLevels=False)
i = (i + 1) % simCam._imgSeq.shape[0]
QtCore.QTimer.singleShot(1, updateData)
now = ptime.time()
fps2 = 1.0 / (now - updateTime)
updateTime = now
fps = fps * 0.9 + fps2 * 0.1
print("%d %0.1f fps" % (i,fps))
updateData()
## Set a custom color map
colors = [ (0, 0, 0), (45, 5, 61), (84, 42, 55), (150, 87, 60), (208, 171, 141), (255, 255, 255) ]
cmap = pg.ColorMap(pos=np.linspace(0.0, 1.0, 6), color=colors)
imv.setColorMap(cmap)
## Start Qt event loop unless running in interactive mode.
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--ui", "-u", help="qt local speed test", type=int, default=0)
parser.add_argument("--prefix","-p",help="EPICS camera-PV prefix",type=str,default="SwissMxSim",)
args = parser.parse_args()
if args.ui:
simCam=SimCam()
print('generate data...')
simCam.generate()
print('done')
if args.ui==1:
QtUI(simCam)
else:
QtUI2(simCam)
else:
obj = SimCam()
obj.pushEPICS((1500,1000),100,args.prefix)
# -*- coding: utf-8 -*-
"""
Demonstrates very basic use of ImageItem to display image data inside a ViewBox.
"""
## Add path to library (just for examples; you do not need this)

View File

@@ -316,7 +316,7 @@ class Main(QMainWindow, Ui_MainWindow):
self._centerpiece_stack.setCurrentIndex(0) self._centerpiece_stack.setCurrentIndex(0)
self._centerpiece_stack.currentChanged.connect(self.center_piece_update) self._centerpiece_stack.currentChanged.connect(self.center_piece_update)
self.init_validators() self.init_validators()
self.init_settings_tracker() #self.init_settings_tracker() ? not needed, was for TELL ?
self.wire_storage() self.wire_storage()
self.create_helical_widgets() #ZAC: orig. code self.create_helical_widgets() #ZAC: orig. code
@@ -378,7 +378,10 @@ class Main(QMainWindow, Ui_MainWindow):
app = QApplication.instance() app = QApplication.instance()
cfg = app._cfg cfg = app._cfg
w, h = cfg.value(AppCfg.BEAM_SIZE) w, h = cfg.value(AppCfg.BEAM_SIZE)
self._beammark = CstROI.BeamMark([100, 100], (int(w), int(h)), parent=self) self._beammark = bm = CstROI.BeamMark([100, 100], (int(w), int(h)), parent=self)
tr=QtGui.QTransform() # prepare ImageItem transformation:
tr.rotate(30)
bm.setTransform(tr) # assign transform
self.vb.addItem(self._beammark) self.vb.addItem(self._beammark)
def camera_pause_toggle(self): def camera_pause_toggle(self):
@@ -399,14 +402,14 @@ class Main(QMainWindow, Ui_MainWindow):
QtCore.QTimer.singleShot(delay, self.new_frame_sim_cb) QtCore.QTimer.singleShot(delay, self.new_frame_sim_cb)
def new_frame_pv_cb(self, **kwargs): def new_frame_pv_cb(self, **kwargs):
_log.debug('new_frame_pv_cb count {}'.format(kwargs['count']))
app=QApplication.instance() app=QApplication.instance()
sz=app._camera._sz sz=app._camera._sz
if kwargs['count']==sz[0]*sz[1]: if kwargs['count']==sz[0]*sz[1]:
pic=kwargs['value'].reshape(sz[::-1]) pic=kwargs['value'].reshape(sz[::-1])
else: else:
sz=self.update_size() sz=app._camera.update_size()
pic=kwargs['value'].reshape(sz[::-1]) pic=kwargs['value'].reshape(sz[::-1])
#_log.debug('new_frame_pv_cb count {}'.format(kwargs['count']))
if pic.dtype==np.int16: if pic.dtype==np.int16:
pic.dtype=np.uint16 pic.dtype=np.uint16
camera.epics_cam.set_fiducial(pic, 255) camera.epics_cam.set_fiducial(pic, 255)
@@ -1509,7 +1512,7 @@ class Main(QMainWindow, Ui_MainWindow):
zoom_base = ("rest://pc12818.psi.ch:9999") # direct connection using fetura.py package zoom_base = ("rest://pc12818.psi.ch:9999") # direct connection using fetura.py package
self.zoombox = zoom.Zoom() self.zoombox = zoom.Zoom()
self.zoombox.configure() self.zoombox.init_settings()
self.zoombox.zoomChanged.connect(self.zoom_changed_cb) self.zoombox.zoomChanged.connect(self.zoom_changed_cb)
self.zoombox.moveBacklight.connect(self.safe_backlight_move) self.zoombox.moveBacklight.connect(self.safe_backlight_move)
@@ -3123,28 +3126,28 @@ class Main(QMainWindow, Ui_MainWindow):
#if EXPERIMENT_PGROUP not in keys: #if EXPERIMENT_PGROUP not in keys:
# self.update_user_and_storage() # self.update_user_and_storage()
if "window/geometry" in keys: if cfg.WINDOW_GEOMETRY in keys:
self.restoreGeometry(cfg.value("window/geometry", "")) self.restoreGeometry(cfg.value(cfg.WINDOW_GEOMETRY, ""))
self.restoreState(cfg.value("window/windowState", "")) self.restoreState(cfg.value(cfg.WINDOW_STATE, ""))
if "window/main_splitter" in keys: if cfg.WINDOW_SPLITTER in keys:
sizes = [int(s) for s in cfg.value("window/main_splitter")] sz = [int(s) for s in cfg.value(cfg.WINDOW_SPLITTER)]
self._main_splitter.setSizes(sizes)
else: else:
self._main_splitter.setSizes([500, 1200]) sz=(500, 1200)
self._main_splitter.setSizes(sz)
if AppCfg.BEAM_MARKER_POSITIONS in keys: #if AppCfg.BEAM_MARKER_POSITIONS in keys:
self._beam_markers = s.value(AppCfg.BEAM_MARKER_POSITIONS) # self._beam_markers = s.value(AppCfg.BEAM_MARKER_POSITIONS)
self.update_beam_marker_fitters() # self.update_beam_marker_fitters()
_log.info("read beam markers {}".format(self._beam_markers)) # _log.info("read beam markers {}".format(self._beam_markers))
if AppCfg.CAMERA_TRANSFORMATIONS in keys: #if AppCfg.CAMERA_TRANSFORMATIONS in keys:
app._camera.set_transformations(s.value(AppCfg.CAMERA_TRANSFORMATIONS)) # app._camera.set_transformations(s.value(AppCfg.CAMERA_TRANSFORMATIONS))
if AppCfg.CAMERA_ZOOM_TO_PPM in keys: #if AppCfg.CAMERA_ZOOM_TO_PPM in keys:
self._zoom_to_ppm = s.value(AppCfg.CAMERA_ZOOM_TO_PPM) # self._zoom_to_ppm = s.value(AppCfg.CAMERA_ZOOM_TO_PPM)
_log.info(f"{AppCfg.CAMERA_ZOOM_TO_PPM} updated: {self._zoom_to_ppm}") # _log.info(f"{AppCfg.CAMERA_ZOOM_TO_PPM} updated: {self._zoom_to_ppm}")
self.update_ppm_fitters() # self.update_ppm_fitters()
def really_quit(self): def really_quit(self):
"""called when user Ctrl-Q the app""" """called when user Ctrl-Q the app"""
@@ -3164,10 +3167,10 @@ class Main(QMainWindow, Ui_MainWindow):
_log.warning('disconnect PV callback failed.') _log.warning('disconnect PV callback failed.')
_log.info('disconnect PV callback') _log.info('disconnect PV callback')
cfg.setValue("window/geometry", self.saveGeometry()) cfg.setValue(cfg.WINDOW_GEOMETRY, self.saveGeometry())
cfg.setValue("window/windowState", self.saveState()) cfg.setValue(cfg.WINDOW_STATE, self.saveState())
cfg.setValue("window/main_splitter", self._main_splitter.sizes()) cfg.setValue(cfg.WINDOW_SPLITTER, self._main_splitter.sizes())
cfg.setValue("last_active", time.time()) cfg.setValue('last_active', time.time())
_log.info('save settings') _log.info('save settings')
#QMainWindow.closeEvent(self, event) #QMainWindow.closeEvent(self, event)
_log.info('closeEvent done') _log.info('closeEvent done')
@@ -3269,9 +3272,76 @@ def main():
app._args=args app._args=args
startupWin.set(5, f'load settings') startupWin.set(5, f'load settings')
app._cfg=AppCfg() app._cfg=cfg=AppCfg()
#Dump config to debug
#for k in cfg.allKeys():
# print(k, cfg.value(k))
app._geometry=geometry.geometry() 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._opt_ctr=cfg.value(cfg.GEO_OPT_CTR)
startupWin.set(15, f'connect backlight') startupWin.set(15, f'connect backlight')
if args.sim&0x01: if args.sim&0x01:
app._backlight = backlight.Backlight(None) app._backlight = backlight.Backlight(None)
@@ -3309,5 +3379,6 @@ def main():
if __name__ == "__main__": if __name__ == "__main__":
os.environ['EPICS_CA_ADDR_LIST'] ='129.129.244.255 sf-saresc-cagw.psi.ch:5062 sf-saresc-cagw.psi.ch:5066' #os.environ['EPICS_CA_ADDR_LIST'] ='129.129.244.255 sf-saresc-cagw.psi.ch:5062 sf-saresc-cagw.psi.ch:5066'
os.environ['EPICS_CA_ADDR_LIST']='localhost'
main() main()

19
zoom.py
View File

@@ -49,22 +49,15 @@ class Zoom(QGroupBox, Ui_Zoom):
self.setupUi(self) self.setupUi(self)
self.setTitle("Sample Viewing") self.setTitle("Sample Viewing")
def configure(self): def init_settings(self):
app=QApplication.instance() app=QApplication.instance()
cfg=app._cfg cfg=app._cfg
keys=cfg.allKeys() keys=cfg.allKeys()
if "sample_viewing/zoom_buttons" not in keys: if cfg.ZOOM_BUTTONS in keys:
cfg.setValue("sample_viewing/zoom_buttons", buttons=json.loads(cfg.value(cfg.ZOOM_BUTTONS))
json.dumps([(1, "1"),(200, "200"),(400, "400"),(600, "600"),(800, "800"),(1000, "1000"),]),) else:
buttons = json.loads(cfg.value("sample_viewing/zoom_buttons")) buttons=((1, "1"),(200, "200"),(400, "400"),(600, "600"),(800, "800"),(1000, "1000"),)
cfg.setValue(cfg.ZOOM_BUTTONS,json.dumps(buttons))
if "backlight/backlight_pv" not in keys:
cfg.setValue("backlight/backlight_pv", "SAR-EXPMX:MOT_BLGT")
backlight_pv = cfg.value("backlight/backlight_pv")
if "sample_viewing/zoom_api" not in keys:
cfg.setValue("sample_viewing/zoom_api", "rest://pc12818.psi.ch:9999")
zoom_api = cfg.value("sample_viewing/zoom_api")
#self.get_zoom_pv = PV(zoom_api + ":ZOOM-RBV", callback=self.zoom_update_cb) #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) #self.status_pv = PV(zoom_api + ":ZOOM-STATUS", callback=self.zoom_status_cb)