From c98795a7e05d717c360c4fad69de5689dffad899 Mon Sep 17 00:00:00 2001 From: Thierry Zamofing Date: Thu, 21 Jul 2022 17:34:21 +0200 Subject: [PATCH] rework settings, add pyqtUsrObj.py --- Readme.md | 14 +++- app_config.py | 60 +++++++++------ pyqtUsrObj.py | 135 ++++++++++++++++++++++++++++++++++ scratch/simCam.py | 182 ---------------------------------------------- swissmx.py | 127 +++++++++++++++++++++++++------- zoom.py | 19 ++--- 6 files changed, 287 insertions(+), 250 deletions(-) create mode 100644 pyqtUsrObj.py delete mode 100755 scratch/simCam.py diff --git a/Readme.md b/Readme.md index 9de0e2a..72a84bf 100644 --- a/Readme.md +++ b/Readme.md @@ -42,7 +42,10 @@ P=ESB_MX/python/SwissMX/ 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 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 @@ -60,6 +63,12 @@ setup.py install --user cd /tmp/; git clone https://github.com/spyder-ide/qtawesome.git 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_FY.RBV -7.450 diff --git a/app_config.py b/app_config.py index 2d6175e..e56d275 100644 --- a/app_config.py +++ b/app_config.py @@ -8,14 +8,22 @@ import logging _log = logging.getLogger(__name__) -import os from PyQt5.QtCore import QSettings -#import yaml -#from pathlib import Path +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" @@ -39,31 +47,37 @@ class AppCfg(QSettings): def __init__(self): super(AppCfg, self).__init__("PSI", "SwissMX") keys = self.allKeys() - if AppCfg.ACTIVATE_PULSE_PICKER not in keys: - self.setValue(AppCfg.ACTIVATE_PULSE_PICKER, False) + #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.SKIP_ESCAPE_TRANSITIONS_IF_SAFE not in keys: - self.setValue(AppCfg.SKIP_ESCAPE_TRANSITIONS_IF_SAFE, False) + #if AppCfg.ACTIVATE_PULSE_PICKER not in keys: + # self.setValue(AppCfg.ACTIVATE_PULSE_PICKER, False) - if "hits/marker_size" not in keys: - self.setValue("hits/marker_size", 10) + #if AppCfg.SKIP_ESCAPE_TRANSITIONS_IF_SAFE not in keys: + # self.setValue(AppCfg.SKIP_ESCAPE_TRANSITIONS_IF_SAFE, False) - if "graphs/show_auxiliary" not in keys: - self.setValue("graphs/show_auxiliary", False) + def sync(self): + 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: - self.setValue("graphs/auxiliary_graph_index", 0) - - 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 setValue(self, key: str, val): #overload to debug + return super(AppCfg, self).setValue(key,val) + 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: try: diff --git a/pyqtUsrObj.py b/pyqtUsrObj.py new file mode 100644 index 0000000..2d47d79 --- /dev/null +++ b/pyqtUsrObj.py @@ -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_() + diff --git a/scratch/simCam.py b/scratch/simCam.py deleted file mode 100755 index e6c5edc..0000000 --- a/scratch/simCam.py +++ /dev/null @@ -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) - - diff --git a/swissmx.py b/swissmx.py index d5eb075..a104ac8 100755 --- a/swissmx.py +++ b/swissmx.py @@ -316,7 +316,7 @@ class Main(QMainWindow, Ui_MainWindow): self._centerpiece_stack.setCurrentIndex(0) self._centerpiece_stack.currentChanged.connect(self.center_piece_update) self.init_validators() - self.init_settings_tracker() + #self.init_settings_tracker() ? not needed, was for TELL ? self.wire_storage() self.create_helical_widgets() #ZAC: orig. code @@ -378,7 +378,10 @@ class Main(QMainWindow, Ui_MainWindow): app = QApplication.instance() cfg = app._cfg 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) def camera_pause_toggle(self): @@ -399,14 +402,14 @@ class Main(QMainWindow, Ui_MainWindow): QtCore.QTimer.singleShot(delay, self.new_frame_sim_cb) def new_frame_pv_cb(self, **kwargs): + _log.debug('new_frame_pv_cb count {}'.format(kwargs['count'])) app=QApplication.instance() sz=app._camera._sz if kwargs['count']==sz[0]*sz[1]: pic=kwargs['value'].reshape(sz[::-1]) else: - sz=self.update_size() + sz=app._camera.update_size() pic=kwargs['value'].reshape(sz[::-1]) - #_log.debug('new_frame_pv_cb count {}'.format(kwargs['count'])) if pic.dtype==np.int16: pic.dtype=np.uint16 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 self.zoombox = zoom.Zoom() - self.zoombox.configure() + self.zoombox.init_settings() self.zoombox.zoomChanged.connect(self.zoom_changed_cb) self.zoombox.moveBacklight.connect(self.safe_backlight_move) @@ -3123,28 +3126,28 @@ class Main(QMainWindow, Ui_MainWindow): #if EXPERIMENT_PGROUP not in keys: # self.update_user_and_storage() - if "window/geometry" in keys: - self.restoreGeometry(cfg.value("window/geometry", "")) - self.restoreState(cfg.value("window/windowState", "")) + if cfg.WINDOW_GEOMETRY in keys: + self.restoreGeometry(cfg.value(cfg.WINDOW_GEOMETRY, "")) + self.restoreState(cfg.value(cfg.WINDOW_STATE, "")) - if "window/main_splitter" in keys: - sizes = [int(s) for s in cfg.value("window/main_splitter")] - self._main_splitter.setSizes(sizes) + if cfg.WINDOW_SPLITTER in keys: + sz = [int(s) for s in cfg.value(cfg.WINDOW_SPLITTER)] else: - self._main_splitter.setSizes([500, 1200]) + sz=(500, 1200) + self._main_splitter.setSizes(sz) - if AppCfg.BEAM_MARKER_POSITIONS in keys: - self._beam_markers = s.value(AppCfg.BEAM_MARKER_POSITIONS) - self.update_beam_marker_fitters() - _log.info("read beam markers {}".format(self._beam_markers)) + #if AppCfg.BEAM_MARKER_POSITIONS in keys: + # self._beam_markers = s.value(AppCfg.BEAM_MARKER_POSITIONS) + # self.update_beam_marker_fitters() + # _log.info("read beam markers {}".format(self._beam_markers)) - if AppCfg.CAMERA_TRANSFORMATIONS in keys: - app._camera.set_transformations(s.value(AppCfg.CAMERA_TRANSFORMATIONS)) + #if AppCfg.CAMERA_TRANSFORMATIONS in keys: + # app._camera.set_transformations(s.value(AppCfg.CAMERA_TRANSFORMATIONS)) - if AppCfg.CAMERA_ZOOM_TO_PPM in keys: - self._zoom_to_ppm = s.value(AppCfg.CAMERA_ZOOM_TO_PPM) - _log.info(f"{AppCfg.CAMERA_ZOOM_TO_PPM} updated: {self._zoom_to_ppm}") - self.update_ppm_fitters() + #if AppCfg.CAMERA_ZOOM_TO_PPM in keys: + # self._zoom_to_ppm = s.value(AppCfg.CAMERA_ZOOM_TO_PPM) + # _log.info(f"{AppCfg.CAMERA_ZOOM_TO_PPM} updated: {self._zoom_to_ppm}") + # self.update_ppm_fitters() def really_quit(self): """called when user Ctrl-Q the app""" @@ -3164,10 +3167,10 @@ class Main(QMainWindow, Ui_MainWindow): _log.warning('disconnect PV callback failed.') _log.info('disconnect PV callback') - cfg.setValue("window/geometry", self.saveGeometry()) - cfg.setValue("window/windowState", self.saveState()) - cfg.setValue("window/main_splitter", self._main_splitter.sizes()) - cfg.setValue("last_active", time.time()) + cfg.setValue(cfg.WINDOW_GEOMETRY, self.saveGeometry()) + cfg.setValue(cfg.WINDOW_STATE, self.saveState()) + cfg.setValue(cfg.WINDOW_SPLITTER, self._main_splitter.sizes()) + cfg.setValue('last_active', time.time()) _log.info('save settings') #QMainWindow.closeEvent(self, event) _log.info('closeEvent done') @@ -3269,9 +3272,76 @@ def main(): app._args=args 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() +# 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') if args.sim&0x01: app._backlight = backlight.Backlight(None) @@ -3309,5 +3379,6 @@ def 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() diff --git a/zoom.py b/zoom.py index 1c7d6d6..1d669f4 100755 --- a/zoom.py +++ b/zoom.py @@ -49,22 +49,15 @@ class Zoom(QGroupBox, Ui_Zoom): self.setupUi(self) self.setTitle("Sample Viewing") - def configure(self): + def init_settings(self): app=QApplication.instance() cfg=app._cfg keys=cfg.allKeys() - if "sample_viewing/zoom_buttons" not in keys: - cfg.setValue("sample_viewing/zoom_buttons", - json.dumps([(1, "1"),(200, "200"),(400, "400"),(600, "600"),(800, "800"),(1000, "1000"),]),) - buttons = json.loads(cfg.value("sample_viewing/zoom_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") + 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)