diff --git a/pyqtUsrObj.py b/pyqtUsrObj.py index b5f19bd..476e288 100644 --- a/pyqtUsrObj.py +++ b/pyqtUsrObj.py @@ -17,7 +17,33 @@ import pyqtgraph as pg from pyqtgraph.Qt import QtCore, QtGui import numpy as np from PyQt5.QtGui import QPolygon,QPolygonF -from PyQt5.QtCore import QPointF +from PyQt5.QtCore import QPointF,QLineF + +def obj_info(obj): + print(f"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) + 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) + except AttributeError: + pass + try: + scnPos=obj.scenePos() + print(f"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}") + except AttributeError: + pass class BeamMark(pg.ROI): """A crosshair ROI whose position is at the center of the crosshairs. By default, it is scalable, rotatable and translatable.""" @@ -53,9 +79,10 @@ class BeamMark(pg.ROI): class Grid(pg.ROI): '''a grid''' - def __init__( self, pos=(0,0), size=(30,20), cnt=(6,4), **kargs): + def __init__( self, pos=(0,0), size=(30,20), cnt=(6,4), ficucialScale=5, **kargs): pg.ROI.__init__(self, pos, size, **kargs) self._cnt=cnt + self._fidScl=ficucialScale self.addScaleHandle([1, 1], [0, 0]) self.addScaleHandle([0, 0], [1, 1]) self.addScaleRotateHandle([1, 0], [0, 0]) @@ -76,6 +103,16 @@ class Grid(pg.ROI): y=i*py p.drawLine(pg.Point(0, y), pg.Point(sz[0] ,y )) + fidScl=self._fidScl + rx=fidScl*r.width()/sz[0] + ry=fidScl*r.height()/sz[1] + p.setPen(pg.mkPen(width=1, color=(255, 0, 0))) + for j in range(ny): + y=j*py + for i in range(nx): + x=i*px + p.drawEllipse(QPointF(x,y), rx, ry) + #p.translate(r.left(), r.top()) #p.scale(r.width(), r.height()) #p.drawEllipse(0, 0, 1, 1) @@ -83,17 +120,31 @@ class Grid(pg.ROI): class Path(pg.ROI): - '''a grid''' - - def __init__( self, pos=(0,0), mark=np.array(((3,4),)), path=np.array(((6,4),(16,24),(-5,7),(3,12))), **kargs): - all=np.vstack((mark,path)) + ''' + a path object with fiducials + path=np.array(n,2) of path points + ficucialScale=size for fiducials in dimensions of path + fiducial = np.array(n,2) of fiducial points + a circle is plot at the path positions + a cross is plot at the fiducial positions + ''' + def __init__( self, pos=(0,0), path=np.array(((6,4),(16,24),(-5,7),(3,12))), fiducial=None, ficucialScale=5, **kargs): + if fiducial is None: + all=path + else: + all=np.vstack((fiducial,path)) mn=all.min(0) mx=all.max(0) - size=mx-mn - - pg.ROI.__init__(self, pos, size, **kargs) - self._mark=mark + sz=mx-mn + pg.ROI.__init__(self, pos, sz, **kargs) + self._fiducial=fiducial self._path=path + self._fidScl=ficucialScale + self._rect=r=QtCore.QRectF(mn[0], mn[1], sz[0], sz[1]) + self._qpath=qPth=QPolygonF() + for pt in path: + qPth.append(QPointF(*pt)) + self.addScaleHandle([1, 1], [0, 0]) self.addScaleHandle([0, 0], [1, 1]) self.addScaleRotateHandle([1, 0], [0, 0]) @@ -102,20 +153,32 @@ class Path(pg.ROI): #pg.ROI.paint(self, p, *args) pos=self.state['pos'] sz=self.state['size'] - mark=self._mark - path=self._path - + r=self._rect p.setRenderHint(QtGui.QPainter.Antialiasing) p.setPen(self.currentPen) - #p.translate(pos[0], pos[1]) - p.drawEllipse(0, 0, int(sz[0]), int(sz[1])) + #p.drawEllipse(0, 0, int(sz[0]), int(sz[1])) p.drawRect(0, 0, int(sz[0]), int(sz[1])) - qPlg=QPolygonF() - for pt in path: - qPlg.append(QPointF(*pt)) - #pp =QPolygonF(path) - p.drawPolyline(qPlg) + #obj_info(p) + p.scale(sz[0]/r.width(), sz[1]/r.height()) + p.translate(-r.left(), -r.top()) + + qpath=self._qpath + p.drawPolyline(qpath) + fidScl=self._fidScl + rx=fidScl*r.width()/sz[0] + ry=fidScl*r.height()/sz[1] + p.setPen(pg.mkPen(width=1, color=(255, 0, 0))) + for ctr in qpath: + p.drawEllipse(ctr, rx, ry) + + fid=self._fiducial + for i in range(fid.shape[0]): + x,y=fid[i,:];print(x,y) + lh=QLineF(x-5*rx,y,x+5*rx,y) + lv=QLineF(x, y-5*ry, x, y+5*ry) + p.drawLines(lh,lv) + @@ -134,20 +197,6 @@ if __name__=='__main__': 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})') @@ -156,6 +205,26 @@ if __name__=='__main__': for child in obj.childItems(): childTree(child, lvl+1) + def gen_swissmx_points(flipx=False,flipy=False,ofs=(-200,0),width=1000): + 'generathe a path that writes swissfel' + #string from inkscape path of the drawing + d="m 524.7061,637.31536 3.54883,0 3.54882,0 3.54883,0 0,-4.20801 0,-4.20801 0,-4.208 0,-4.20801 4.22949,0 4.22949,0 4.2295,0 4.22949,0 0,-3.55957 0,-3.55957 0,-3.55957 0,-3.55957 -4.22949,0 -4.2295,0 -4.22949,0 -4.22949,0 0,-4.22949 0,-4.2295 0,-4.22949 0,-4.22949 -3.54883,0 -3.54882,0 -3.54883,0 -3.54883,0 0,4.22949 0,4.22949 0,4.2295 0,4.22949 -4.20752,0 -4.20752,0 -4.20752,0 -4.20752,0 0,3.55957 0,3.55957 0,3.55957 0,3.55957 4.20752,0 4.20752,0 4.20752,0 4.20752,0 0,4.20801 0,4.208 0,4.20801 0,4.20801 -11.87126,0.36152 -12.12171,-0.13934 -2.52941,3.93977 -2.57238,3.94369 -2.50854,3.88614 -2.50731,3.91767 -2.49035,3.88268 -2.50987,3.91244 -2.50453,3.88732 -2.51897,3.9189 -6.39782,5.72802 -6.63782,6.70894 -3.21517,5.11464 -3.3404,5.32333 -3.08995,5.11464 -3.17343,5.15637 -16.69223,0.0698 5.55908,0 5.55909,0 5.55908,0 3.18604,-5.17432 3.18603,-5.17431 3.18604,-5.17432 3.18603,-5.17431 3.17481,5.17431 3.1748,5.17432 3.17481,5.17431 3.1748,5.17432 5.59229,0 5.59228,0 5.59229,0 5.59228,0 -2.74121,-4.15283 -2.74121,-4.15283 -2.74121,-4.15283 -2.74121,-4.15284 -2.74122,-4.15283 -2.74121,-4.15283 -2.74121,-4.15283 -2.74121,-4.15283 2.50488,-3.90015 2.50489,-3.90015 2.50488,-3.90014 2.50488,-3.90015 2.50488,-3.90015 2.50489,-3.90015 2.50488,-3.90014 2.50488,-3.90015 -5.42724,0 -5.42725,0 -5.42724,0 -5.42725,0 -2.76855,4.95508 -2.76856,4.95508 -2.76855,4.95508 -2.76856,4.95508 -2.85644,-4.95508 -2.85645,-4.95508 -2.85644,-4.95508 -2.85645,-4.95508 -5.48193,0 -5.48194,0 -5.48194,0 -5.48193,0 2.52686,3.8562 2.52685,3.8562 2.52686,3.8562 2.52686,3.85621 2.52685,3.8562 2.52686,3.8562 2.52685,3.8562 2.52686,3.8562 -2.77954,4.19678 -2.77954,4.19678 -2.77954,4.19677 -2.77955,4.19678 -2.77954,4.19678 -2.77954,4.19678 -2.77954,4.19677 -2.77954,4.19678 -4.91638,0 -4.91638,0 -4.91639,0 -4.91638,0 -4.91638,0 -4.91638,0 -4.91638,0 -4.91638,0 -4.91639,0 -4.91638,0 -4.91638,0 -4.91638,0 -4.91638,0 -4.91639,0 -4.91638,0 -4.91638,0 4.07568,0 4.07568,0 4.07569,0 4.07568,0 0,-6.14136 0,-6.14135 0,-6.14136 0,-6.14136 0,-6.14136 0,-6.14135 0,-6.14136 0,-6.14136 1.57105,6.14136 1.57104,6.14136 1.57104,6.14135 1.57105,6.14136 1.57105,6.14136 1.57104,6.14136 1.57104,6.14135 1.57105,6.14136 3.68066,0 3.68067,0 3.68067,0 3.68066,0 1.57642,-6.14136 1.57641,-6.14135 1.57642,-6.14136 1.57641,-6.14136 1.57642,-6.14136 1.57642,-6.14135 1.57641,-6.14136 1.57642,-6.14136 0,6.14136 0,6.14136 0,6.14135 0,6.14136 0,6.14136 0,6.14136 0,6.14135 0,6.14136 4.06494,0 4.06494,0 4.06494,0 4.06494,0 0,-8.05298 0,-8.05298 0,-8.05298 0,-8.05297 0,-8.05298 0,-8.05298 0,-8.05298 0,-8.05298 -6.52588,0 -6.52588,0 -6.52587,0 -6.52588,0 -1.25781,4.8999 -1.25782,4.89991 -1.25781,4.8999 -1.25781,4.8999 -1.25781,4.8999 -1.25782,4.89991 -1.25781,4.8999 -1.25781,4.8999 -1.26343,-4.8999 -1.26343,-4.8999 -1.26343,-4.89991 -1.26343,-4.8999 -1.26342,-4.8999 -1.26343,-4.8999 -1.26343,-4.89991 -1.26343,-4.8999 -6.54785,0 -6.54785,0 -6.54785,0 -6.54785,0 0,8.05298 0,8.05298 0,8.05298 0,8.05298 0,8.05297 0,8.05298 0,8.05298 -4.25755,8.13646 -8.40743,0.19687 -8.40743,0.19687 -8.40743,0.19687 -8.40743,0.19687 5.93521,0.22812 8.09742,-0.56079 6.18579,-1.6814 4.55883,-2.66919 3.13062,-3.43823 1.84571,-3.87866 0.61523,-3.98853 -0.58179,-3.83373 -1.74634,-3.50416 -2.802,-2.95581 -3.83472,-2.18676 -5.49316,-1.60401 -7.77832,-1.20849 -7.64649,-1.58204 -1.75781,-2.59179 1.36328,-2.59375 4.4375,-1.09766 5.09766,1.40625 2.19727,3.29492 4.24072,-0.41748 4.24073,-0.41748 4.24072,-0.41748 4.24072,-0.41748 -1.98804,-4.09741 -2.44946,-3.15259 -2.97778,-2.3291 -3.65894,-1.62598 -5.05371,-0.95629 -7.25098,-0.3191 -7.10766,0.41748 -5.50367,1.25244 -4.19677,2.05494 -3.18604,2.91186 -2.01099,3.65796 -0.67065,4.29517 0.61523,3.98852 1.84571,3.5271 2.78002,2.823 3.32935,1.87817 5.06421,1.42822 7.89868,1.56006 7.69141,1.84571 2.02148,2.98828 -1.53906,2.85742 -5.58008,1.53711 -5.27344,-1.36133 -3.07617,-4.52734 -4.43847,0.41748 -4.43848,0.41748 -4.43848,0.41748 -4.43847,0.41748 2.50488,5.95459 4.43848,4.4165 3.18313,1.59592 4.10031,1.14017 -3.65979,0.0939 -5.9713,6e-5 -5.97131,5e-5 -5.9713,6e-5 -5.9713,6e-5 -5.9713,5e-5 -5.97131,6e-5 -5.9713,5e-5 -5.9713,6e-5 5.34491,0.81842 8.09742,-0.56079 6.18579,-1.6814 4.55883,-2.66919 3.13062,-3.43823 1.84571,-3.87866 0.61523,-3.98853 -0.58179,-3.83373 -1.74634,-3.50416 -2.802,-2.95581 -3.83472,-2.18676 -5.49316,-1.60401 -7.77832,-1.20849 -7.64649,-1.58204 -1.75781,-2.59179 1.36328,-2.59375 4.4375,-1.09766 5.09766,1.40625 2.19727,3.29492 4.24072,-0.41748 4.24073,-0.41748 4.24072,-0.41748 4.24072,-0.41748 -1.98804,-4.09741 -2.44946,-3.15259 -2.97778,-2.3291 -3.65894,-1.62598 -5.05371,-0.95629 -7.25098,-0.3191 -7.10766,0.41748 -5.50367,1.25244 -4.19677,2.05494 -3.18604,2.91186 -2.01099,3.65796 -0.67065,4.29517 0.61523,3.98852 1.84571,3.5271 2.78002,2.823 3.32935,1.87817 5.06421,1.42822 7.89868,1.56006 7.69141,1.84571 2.02148,2.98828 -1.53906,2.85742 -5.58008,1.53711 -5.27344,-1.36133 -3.07617,-4.52734 -4.43847,0.41748 -4.43848,0.41748 -4.43848,0.41748 -4.43847,0.41748 2.50488,5.95459 4.43848,4.4165 3.18313,1.59592 4.10031,1.14017 -3.06953,-0.0416 -3.06952,-0.0416 -8.58102,-0.0261 -10.12782,-0.0261 -7.03422,-0.0261 -8.58102,-0.0261 4.47168,0 6.6151,0 2.32826,0 4.47168,0 0,-5.83374 0,-5.83374 0,-5.83374 0,-5.83374 0,-5.83374 0,-5.83374 0,-5.83374 0,-5.83374 -4.47168,0 -4.47168,0 -4.47168,0 0,-5.5796 4.47168,0 4.47168,0 4.47168,0 0,-6.08691 0,-6.08692 -4.47168,0 -4.47168,0 -4.47168,0 -4.47168,0 0,6.08692 0,6.08691 0,5.5796 0,5.83374 0,5.83374 0,5.83374 0,5.83374 0,5.83374 0,5.83374 0,5.83374 -3.67318,5.83374 -8.7308,0 -10.73079,0 -6.7308,0 -9.10563,0 -2.25201,0.007 -8.72971,0.0266 -7.53755,-0.0442 -9.68477,0.0107 -6.3443,0 3.99902,0 3.99902,0 3.99903,0 3.99902,0 2.28516,-7.02002 2.28516,-7.02002 2.28516,-7.02002 2.28516,-7.02002 2.36181,7.02002 2.36182,7.02002 2.36181,7.02002 2.36182,7.02002 3.97705,0 3.97705,0 3.97705,0 3.97705,0 2.14795,-5.83374 2.14795,-5.83374 2.14795,-5.83374 2.14795,-5.83374 2.14795,-5.83374 2.14795,-5.83374 2.14795,-5.83374 2.14795,-5.83374 -4.2959,0 -4.2959,0 -4.2959,0 -4.2959,0 -0.93921,3.67505 -0.93921,3.67505 -0.93921,3.67505 -0.93921,3.67505 -0.9392,3.67504 -0.93921,3.67505 -0.93921,3.67505 -0.93921,3.67505 -1.23047,-3.67505 -1.23047,-3.67505 -1.23047,-3.67505 -1.23047,-3.67504 -1.23046,-3.67505 -1.23047,-3.67505 -1.23047,-3.67505 -1.23047,-3.67505 -4.03223,0 -4.03222,0 -4.03223,0 -4.03223,0 -1.18652,3.67505 -1.18653,3.67505 -1.18652,3.67505 -1.18653,3.67505 -1.18652,3.67504 -1.18652,3.67505 -1.18653,3.67505 -1.18652,3.67505 -0.93921,-3.67505 -0.93921,-3.67505 -0.93921,-3.67505 -0.93921,-3.67504 -0.9392,-3.67505 -0.93921,-3.67505 -0.93921,-3.67505 -0.93921,-3.67505 -4.32862,0 -4.32861,0 -4.32862,0 -4.32861,0 2.16431,5.83374 2.1643,5.83374 2.16431,5.83374 2.16431,5.83374 2.16431,5.83374 2.1643,5.83374 2.16431,5.83374 -3.84635,5.83374 -5.60781,0.003 -5.6078,0.003 -5.60781,0.003 -5.6078,0.003 -5.4839,-1.59358 0,0 5.47119,-3.35034 4.10888,-4.60278 2.5708,-5.4712 0.85694,-5.95459 -0.64868,-5.02123 -1.94507,-4.51587 -3.32837,-3.91114 -4.88843,-3.20801 -7.482173,-2.87842 -5.1337,-1.42273 -6.06186,-1.41174 -6.67969,-2.37304 -1.44922,-2.76758 1.75782,-3.56055 5.22851,-1.49414 6.5918,1.97852 1.99951,2.5708 1.16455,3.75732 4.69141,-0.2749 4.691403,-0.2749 4.6914,-0.27491 4.69141,-0.2749 -0.94483,-4.66918 -1.604,-3.98804 -2.26318,-3.30688 -2.92236,-2.62574 -3.59802,-2.01858 -4.334103,-1.44162 -5.0702,-0.86484 -5.80627,-0.28824 -4.76547,0.1593 -4.23282,0.47791 -6.86695,1.91162 -5.04223,2.98828 -3.61401,3.95507 -2.14283,4.53687 -0.7146,4.82251 1.40625,6.88892 4.21875,5.54858 3.26035,2.31812 4.19986,2.07641 5.13919,1.83472 6.07834,1.59302 6.54785,1.81226 3.64746,1.92211 2.19727,4.48242 -2.33008,4.65821 -6.54688,1.97851 -5.05371,-0.97827 -3.73535,-2.93384 -1.57153,-2.9663 -0.93433,-4.06495 -4.73486,0.29688 -4.73487,0.29687 -4.73486,0.29688 -4.73486,0.29687 0.76065,4.6637 1.44711,4.23523 2.13376,3.80676 2.82059,3.3783 3.79577,2.76855 5.0592,1.97754 6.32264,1.18652 7.58606,0.39551 9.481626,-0.95145 -7.224723,-0.043 -7.224724,-0.043 -7.224723,-0.043 -7.224723,-0.043 -7.224723,-0.043 -7.224723,-0.043 -7.224724,-0.043 -7.224723,-0.043" + d=d.split() + pts=np.ndarray((len(d)-1,2),dtype=np.float) + for i in range(pts.shape[0]): + pts[i,:]=tuple(map(float,d[i+1].split(','))) + + pts[0,:]=(0,0) + pts=pts.cumsum(0) + pts=pts[::-1,:] + pts=pts-pts[0] + pts*=width/pts[:,0].max() + if flipx: pts[:,0]=-pts[:,0] + if not flipy: pts[:,1]=-pts[:,1] + pts+=ofs + return pts + + def mouse_click_event(event): pos=event.pos() scn=event.scenePos() # there is a small black border, that makes the difference @@ -194,15 +263,18 @@ if __name__=='__main__': viImg=pg.ImageItem(arr, border='y') vb.addItem(viImg) # Custom ROI for selecting an image region - viRoi=pg.ROI([20, 50], [100, 70]) + viRoi=pg.ROI([20, -50], [60, 40]) vb.addItem(viRoi) - viUsrRoi=BeamMark([10, 20], [30, 20]) + viUsrRoi=BeamMark([50, 120], [30, 20]) vb.addItem(viUsrRoi) - vi=Grid( (50,10), (200,150), (30,20)) + vi=Grid( (120,-100), (200,150), (30,20),2) #vi=Grid( (50,10), (200,150), (6,4)) vb.addItem(vi) #vi= visual item - vi=Path() + fidScl=.5 + fiducial=np.array(((18, 7), (25, 16), (70, 20))) + path=gen_swissmx_points(ofs=(10, 5), width=200) + vi=Path((120,100),path,fiducial,fidScl) vb.addItem(vi) childTree(vb) diff --git a/swissmx.py b/swissmx.py index 5bf2b2f..5c61ac4 100755 --- a/swissmx.py +++ b/swissmx.py @@ -94,7 +94,7 @@ from epics_widgets.MotorTweak import MotorTweak from epics_widgets.SmaractMotorTweak import SmaractMotorTweak from epics_widgets.SimMotorTweak import SimMotorTweak ts.log('Import part 5/7:') -from matplotlib import pyplot +import matplotlib as mpl import numpy as np import pyqtgraph as pg import pyqtgraph.exporters @@ -251,7 +251,12 @@ class Main(QMainWindow, Ui_MainWindow): vb.setAspectLocked(True) vb.setBackgroundColor((120, 90, 90)) vb.addItem(self.img) - grid=pg.GridItem() + try: + grid=pg.GridItem(pen=(0,255,0),textPen=(0,255,0)) #green grid and labels + except: + grid=pg.GridItem() + + vb.addItem(grid) self._escape_current_state = "Maintenance" @@ -3236,7 +3241,17 @@ class StartupSplash: time.sleep(.1) def main(): - import argparse + from PyQt5.QtCore import QT_VERSION_STR + _log.info(f'Version: pyqtgraph:{pg.__version__} matplotlib:{mpl.__version__} numpy:{np.__version__} epics:{epics.__version__} qt:{QT_VERSION_STR}' ) + import argparse, socket + hostname=socket.gethostname() + if hostname=='ganymede': + #use EPICS locally + os.environ['EPICS_CA_ADDR_LIST']='localhost' + #use EPICS if connected to ESC network + # os.environ['EPICS_CA_ADDR_LIST'] ='129.129.244.255 sf-saresc-cagw.psi.ch:5062 sf-saresc-cagw.psi.ch:5066' + + #(h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>20 else sys.argv[0])+' ' #exampleCmd=('', '-m0xf -v0') @@ -3380,6 +3395,4 @@ 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']='localhost' main()