From dfd21755e0d57b4e37db6f369e365d35c06b5488 Mon Sep 17 00:00:00 2001 From: Thierry Zamofing Date: Thu, 29 Aug 2024 16:35:14 +0200 Subject: [PATCH] wip --- ARESvis/ARESvis.py | 454 ++++++++++++++++++++++------------- spectrumProc/spectrumProc.py | 10 +- 2 files changed, 293 insertions(+), 171 deletions(-) diff --git a/ARESvis/ARESvis.py b/ARESvis/ARESvis.py index f8d52ce..8c5cddb 100755 --- a/ARESvis/ARESvis.py +++ b/ARESvis/ARESvis.py @@ -9,11 +9,18 @@ """ Furka ARES chamber visualization +For simulated motor IOC: +/home/zamofing_t/Documents/prj/SwissFEL/test_ioc/MotorSim/iocBoot/ARESvis/ARESvis.cmd +For motor ui: +caQtDM ~/Documents/prj/SwissFEL/test_ioc/MotorSim/iocBoot/ARESvis/ARESvis.ui& + + self.pv_angles = [epics.PV("SATES30-ARES:MOT_SRY.RBV"), epics.PV("SATES30-ARES:MOT_DRY.RBV"), epics.PV("SATES30-ARES:MOT_2TRY.RBV")] -SATES30-ARES:MOT_2TRY.RBV # 2thetha angle -SATES30-ARES:MOT_DRY.RBV # detector angle SATES30-RIXS:MOT_RY.RBV # sliding seal +SATES30-ARES:MOT_JFRY.RBV # jungfrau detector angle: +SATES30-ARES:MOT_2TRY.RBV # 2thetha angle: foc.mirror Diode2 Diode3 +SATES30-ARES:MOT_DRY.RBV # detector angle: Diode1 Mirror SATES30-ARES:MOT_SRY.RBV # sample rotation @@ -61,15 +68,17 @@ class ARESdevice(): self._name=name self._paint=p={ 'ofs':(500, 500), # location of device - 'rArm':150, # radius of chamber (RIXS arm) - 'r2Th':120, # radius 2Theta platfform - 'rDet':80, # radius of detector - 'rTrg':10, # radius of target + 'rArm':3*62, # radius of chamber (RIXS arm) + 'rJFr':3*52, # radius of Jungfrau + 'r2Th':3*48, # radius 2Theta platfform + 'rDet':3*23, # radius of detector table + 'rTrg':3*20, # radius of target 'szArm':(20, 50), - 'aaArm':100, # angle RIXS arm - 'aa2Th':110, # angle 2thetha - 'aaDet':120, # angle detector - 'aaTrg':130, # angle target + 'aArm':100, # angle RIXS arm + 'aJFr':140, # angle detector + 'a2Th':30, # angle 2thetha + 'aDet':-20, # angle detector + 'aTrg':10, # angle target 'mode':4, #difraction beam paint mode 'szG':(200, 5), # size VLS grating @@ -167,13 +176,16 @@ class ARESdevice(): ofs=p['ofs'] rArm=p['rArm'] + rJFr=p['rJFr'] r2Th=p['r2Th'] rDet=p['rDet'] rTrg=p['rTrg'] - aaArm=p['aaArm'] - aa2Th=p['aa2Th'] - aaDet=p['aaDet'] - aaTrg=p['aaTrg'] + + aArm=p['aArm'] + aJFr=p['aJFr'] + a2Th=p['a2Th'] + aDet=p['aDet'] + aTrg=p['aTrg'] sclTrf=p['sclTrf'] # --- prepare transformations --- # tf0: target not rotated @@ -186,13 +198,15 @@ class ARESdevice(): tf0.translate(ofs[0], ofs[1]) tf0.scale(sclTrf[1],sclTrf[1]) tfArm=copy.copy(tf0) # center - tfArm.rotate(aaArm) - tf2Th=copy.copy(tf0) # center - tf2Th.rotate(aa2Th) + tfArm.rotate(-aArm) + tfJFr=copy.copy(tf0) + tfJFr.rotate(-aJFr) + tf2Th=copy.copy(tf0) + tf2Th.rotate(-a2Th) tfDet=copy.copy(tf0) - tfDet.rotate(aaDet) + tfDet.rotate(-aDet) tfTrg=copy.copy(tf0) - tfTrg.rotate(aaTrg) + tfTrg.rotate(-aTrg) #tfd.translate(r2,0).rotate(-cc) penBk=QPen(QtCore.Qt.black, 0, QtCore.Qt.SolidLine) @@ -221,6 +235,7 @@ class ARESdevice(): #circles of rtation qp.drawEllipse(-rArm, -rArm, 2*rArm, 2*rArm) # ARES chamber + qp.drawEllipse(-rJFr, -rJFr, 2*rJFr, 2*rJFr) # Jungfrau qp.drawEllipse(-r2Th, -r2Th, 2*r2Th, 2*r2Th) # 2theta qp.drawEllipse(-rDet, -rDet, 2*rDet, 2*rDet) # detector qp.drawEllipse(-rTrg, -rTrg, 2*rTrg, 2*rTrg) # target @@ -237,36 +252,58 @@ class ARESdevice(): #RIXS-arm devices qp.setTransform(tfArm) qp.setPen(QPen(QtCore.Qt.red, 3, QtCore.Qt.SolidLine)) - qp.drawLine(0,rArm,0,rArm+10) + qp.drawLine(0,-rArm,0,-rArm+10) qp.setPen(penBk) qp.setBrush(QColor(255,0,0,128)) - qp.drawRect(-15, -20+rArm, 5, 50) # foc. mirror 1 - qp.drawRect(+10, -20+rArm, 5, 50) # foc. mirror 2 + qp.drawRect(-20, -50-rArm, 40, 50) # 2th mount sample + qp.drawRect(-100, -200-rArm, 200, 150) # 2th mount sample + + #Jungfrau devices + qp.setTransform(tfJFr) + qp.setPen(QPen(QtCore.Qt.magenta, 3, QtCore.Qt.SolidLine)) + qp.drawLine(0,-rJFr,0,-rJFr+10) + qp.setPen(penBk) + qp.setBrush(QColor(255,0,255,128)) + qp.drawRect(-50, -20-rJFr, 100, 15) # detector mount sample #2-theta devices qp.setTransform(tf2Th) qp.setPen(QPen(QtCore.Qt.green, 3, QtCore.Qt.SolidLine)) - qp.drawLine(0,r2Th,0,r2Th+10) + qp.drawLine(0,-r2Th,0,-r2Th+10) qp.setPen(penBk) qp.setBrush(QColor(0,255,0,128)) - qp.drawRect(-20, -20+r2Th, 15, 15) # 2th mount sample - + qp.drawRect(-15, -30-r2Th, 5, 3*29) # foc. mirror 1 + qp.drawRect(+10, -30-r2Th, 5, 3*29) # foc. mirror 2 + qp.rotate(20) + qp.drawRect(-10, -r2Th, 20, 20) # diode2 + qp.setTransform(tf2Th);qp.rotate(120) + qp.drawRect(-10, -r2Th, 20, 20) # diode3 #detector devices qp.setTransform(tfDet) qp.setPen(QPen(QtCore.Qt.blue, 3, QtCore.Qt.SolidLine)) - qp.drawLine(0,rDet,0,rDet+10) + qp.drawLine(0,-rDet,0,-rDet+10) qp.setPen(penBk) qp.setBrush(QColor(0,0,255,128)) - qp.drawRect(+20, -20+rDet, 10, 15) # detector mount sample + qp.drawRect(-10, -rDet, 20, 10) # diode1 + qp.rotate(30);qp.translate(0,-rDet);qp.rotate(45) + qp.drawRect(-10, 0, 30, 5) # mirror1 + #target devices qp.setTransform(tfTrg) qp.setPen(QPen(QtCore.Qt.cyan, 3, QtCore.Qt.SolidLine)) - qp.drawLine(0,rTrg,0,rTrg+10) + qp.drawLine(0,-rTrg,0,-rTrg+10) qp.setPen(penBk) qp.setBrush(QColor(0,255,255,128)) - qp.drawRect(+20, +20+rTrg, 10, 10) # target mount sample + qp.drawRect(-30, -20, 60, 20) # target mount sample + + #parabola mirror + qp.setTransform(tf0) + qp.setPen(penBk) + qp.setBrush(QColor(80,80,80,128)) + qp.drawPolygon(QPolygon([QPoint(-15,30),QPoint(-15,60),QPoint(15,60),])) + #qp.setPen(penBk) #qp.drawRect(-10, -10+rArm, 20, 20) @@ -293,156 +330,180 @@ class ARESdevice(): # qp.setTransform(tf);self.plotOrig(qp) class WndVisualize(QWidget): - def __init__(self): - super().__init__() - self.initUI() + def __init__(self): + super().__init__() + self.initUI() + self.connectEPICS() - def initUI(self): - self.setGeometry(560, 100, 1300, 800) - self.setWindowTitle('Visualize') - app=QApplication.instance() - dev=app._dev - self._wdGrpDraw=w=QGroupBox(dev._name,self) - w.move(10,10) - row=0 - lg=QGridLayout(w) - pDev=dev._paint - for key, rng, tk in ( - ('aaArm',(0,360,), 30), # angle ARES sliding seal - ('aa2Th',(0,360,), 30), # angle 2thetha - ('aaDet',(0,360,), 30), # angle detector - ('aaTrg',(0,360,), 30), # angle target - ('sclA', ( -8, 8), 1), - ('sclD', (-8, 8), 1),): + def initUI(self): + self.setGeometry(560, 100, 1300, 800) + self.setWindowTitle('Visualize') + app=QApplication.instance() + dev=app._dev + self._wdGrpDraw=w=QGroupBox(dev._name,self) + w.move(10,10) + row=0 + lg=QGridLayout(w) + pDev=dev._paint + for key, rng, tk in ( + ('aArm',(0,360,), 30), # angle ARES sliding seal + ('aJFr' ,(0,360,), 30), # angle Jungfrau + ('a2Th',(0,360,), 30), # angle 2thetha + ('aDet',(0,360,), 30), # angle detector + ('aTrg',(0,360,), 30), # angle target + ('sclA', ( -8, 8), 1), + ('sclD', (-8, 8), 1),): - wLb=QLabel(key) - wSl=QSlider(QtCore.Qt.Horizontal,objectName=key) - wSl.setFixedWidth(200);wSl.setMinimum(rng[0]);wSl.setMaximum(rng[1]) - if key.startswith('scl'): - if key[-1]=='A': - v=pDev['sclTrf'][0] - else: - v=pDev['sclTrf'][1] - v=int(round(np.log2(v)*2)) - else: - v=pDev[key] - wSl.setValue(v) - wSl.setTickPosition(QSlider.TicksBelow);wSl.setTickInterval(tk) - wSl.valueChanged.connect(lambda val,key=key: self.sldChanged(key,val)) - - lg.addWidget(wLb, row, 0) - lg.addWidget(wSl, row, 1);row+=1 - self.show() - - def destroy(self, destroyWindow, destroySubWindows): #overloaded function - _log.info('destroy') - - def closeEvent(self, event): #overloaded function - _log.info('closeEvent') - - def sldChanged(self,key,val,*args,**kwargs): - app=QApplication.instance() - dev=app._dev - p=dev._paint + wLb=QLabel(key) + wSl=QSlider(QtCore.Qt.Horizontal,objectName=key) + wSl.setFixedWidth(200);wSl.setMinimum(rng[0]);wSl.setMaximum(rng[1]) if key.startswith('scl'): - wGrp=self._wdGrpDraw if key[-1]=='A': - p['sclTrf']=(2**(val/2),p['sclTrf'][1]) + v=pDev['sclTrf'][0] else: - p['sclTrf']=(p['sclTrf'][0],2**(val/2)) - print(p['sclTrf']) - dev.setGeometry(dev._geo) + v=pDev['sclTrf'][1] + v=int(round(np.log2(v)*2)) else: - p[key]=val - g=dev._geo - if key in ('r1','r2'): - sclD=p['sclTrf'][1] - g[key]=val/sclD - elif key in ('aa', 'bb'): - sclA=p['sclTrf'][0] - g[key]=90-val/sclA - else: - g[key]=val - self.update() + v=pDev[key] + wSl.setValue(v) + wSl.setTickPosition(QSlider.TicksBelow);wSl.setTickInterval(tk) + wSl.valueChanged.connect(lambda val,key=key: self.sldChanged(key,val)) - def mouseReleaseEvent(self, a0): - try: - del self._mouseDrag - except AttributeError: - pass + lg.addWidget(wLb, row, 0) + lg.addWidget(wSl, row, 1);row+=1 + self.show() - def mousePressEvent(self, a0): - app=QApplication.instance() - mousePos=a0.pos() - print(a0.type) - if a0.type()!=QtGui.QMouseEvent.MouseButtonPress: - return + def connectEPICS(self): + self._pv=pv=set() + for rec_name in ( + 'SATES30-RIXS:MOT_RY', + 'SATES30-ARES:MOT_JFRY', + 'SATES30-ARES:MOT_2TRY', + 'SATES30-ARES:MOT_DRY', + 'SATES30-ARES:MOT_SRY',): + + m=epics.Motor(rec_name) + pv.add(m) + #_log.debug(m.get_position()) # this is the VAL field + #_log.debug(m.PV('RBV').get()) # this is the RBV field + #_log.debug(m.get('RBV')) # this is the RBV field + #m.add_callback('RBV', self.update_label) + #m.set_callback('RBV', self.emit_signals, {'source_field': 'RBV'}) + #/home/zamofing_t/.local/lib/python3.8/site-packages/epics/motor.py + m.add_callback('RBV', self.OnChangedRBV) + #print(pv) +# def update_label(self, **kwargs): +# _log.info(kwargs) + +# def emit_signals(self, **kw): +# _log.info(kw) + + #def OnChangedRBV(self, **kw): + def OnChangedRBV(self, pvname, value, **kw): + #_log.info(kw) + #{ + # 'pvname': 'SATES30-ARES:MOT_2TRY.RBV', + # 'value': 102.507, + # 'char_value': '102.5070', + # 'status': 0, + # 'ftype': 20, + # 'chid': 26100744, + # 'host': 'localhost:5064', + # 'count': 1, + # 'access': 'read-only', + # 'write_access': False, + # 'read_access': True, + # 'severity': 0, + # 'timestamp': 1724915455.46745, + # 'posixseconds': 1724915455.0, + # 'nanoseconds': 467450100, + # 'precision': 4, + # 'units': 'deg', + # 'enum_strs': None, + # 'upper_disp_limit': 0.0, + # 'lower_disp_limit': 0.0, + # 'upper_alarm_limit': nan, + # 'lower_alarm_limit': nan, + # 'lower_warning_limit': nan, + # 'upper_warning_limit': nan, + # 'upper_ctrl_limit': 0.0, + # 'lower_ctrl_limit': 0.0, + # 'nelm': 1, + # 'type': 'time_double', + # 'typefull': 'time_double', + # 'cb_info': (1, ) + #} + #_log.info(f"{kw['pvname']}:{kw['value']}") + _log.info(f"{pvname}:{value}") + if pvname=='SATES30-RIXS:MOT_RY.RBV': + self.sldChanged('aArm',value) + elif pvname=='SATES30-ARES:MOT_JFRY.RBV': + self.sldChanged('aJFr',value) + elif pvname=='SATES30-ARES:MOT_2TRY.RBV': + self.sldChanged('a2Th',value) + elif pvname=='SATES30-ARES:MOT_DRY.RBV': + self.sldChanged('aDet',value) + elif pvname=='SATES30-ARES:MOT_SRY.RBV': + self.sldChanged('aTrg',value) + else: + _log.warning(f"can't handle PV: {pvname}:{value}") + + def destroy(self, destroyWindow, destroySubWindows): #overloaded function + _log.info('destroy') + + def closeEvent(self, event): #overloaded function + _log.info('closeEvent') + + def sldChanged(self,key,val,*args,**kwargs): + app=QApplication.instance() + dev=app._dev + p=dev._paint + if key.startswith('scl'): wGrp=self._wdGrpDraw - #if wGrp.underMouse(): #draging sliders? - if wGrp.geometry().contains(mousePos): - self._mouseDrag={'obj':wGrp, 'start':mousePos} - return - dev=app._dev - if dev.containsPoint(mousePos): - self._devSel=dev - wGrp=self._wdGrpDraw - wGrp.setTitle(dev._name) - devP=dev._paint - for wSl in wGrp.findChildren(QSlider): - #_log.info(wSl) - key=wSl.objectName() - if key.startswith('scl'): - if key[-1]=='A': - v=devP['sclTrf'][0] - else: - v=devP['sclTrf'][1] - v=int(round(np.log2(v)*2)) - else: - v=devP[key] - wSl.setValue(v) + if key[-1]=='A': + p['sclTrf']=(2**(val/2),p['sclTrf'][1]) + else: + p['sclTrf']=(p['sclTrf'][0],2**(val/2)) + print(p['sclTrf']) + dev.setGeometry(dev._geo) + else: + p[key]=val + g=dev._geo + if key in ('r1','r2'): + sclD=p['sclTrf'][1] + g[key]=val/sclD + elif key in ('aa', 'bb'): + sclA=p['sclTrf'][0] + g[key]=90-val/sclA + else: + g[key]=val + self.update() - self._mouseDrag={'obj':dev,'start':(mousePos,dev._paint['ofs'])} - try: - _log.info(f'{self._mouseDrag}') - except AttributeError: - _log.info(f'no object to drag') + def mouseReleaseEvent(self, a0): + try: + del self._mouseDrag + except AttributeError: + pass - - def mouseMoveEvent(self, a0): - try: - md=self._mouseDrag - except AttributeError: - return - obj=md['obj'] - s=md['start'] - if obj==self._wdGrpDraw: - p=a0.pos() - md['start']=p - p=obj.geometry().topLeft()+p-s - obj.move(p) - return - p=a0.pos() - ofs=QPoint(*s[1])+p-s[0] - _log.info(f'{p} {ofs}') - obj._paint['ofs']=(ofs.x(),ofs.y()) - self.update() - - def paintEvent(self, e): - qp = QPainter() - qp.begin(self) - qp.setRenderHints(QPainter.HighQualityAntialiasing) - app=QApplication.instance() - dev=app._dev - app._dev.paint(qp) - qp.end() - - def updateDevice(self, dev): + def mousePressEvent(self, a0): + app=QApplication.instance() + mousePos=a0.pos() + print(a0.type) + if a0.type()!=QtGui.QMouseEvent.MouseButtonPress: + return + wGrp=self._wdGrpDraw + #if wGrp.underMouse(): #draging sliders? + if wGrp.geometry().contains(mousePos): + self._mouseDrag={'obj':wGrp, 'start':mousePos} + return + dev=app._dev + if dev.containsPoint(mousePos): self._devSel=dev - devP=dev._paint wGrp=self._wdGrpDraw wGrp.setTitle(dev._name) + devP=dev._paint for wSl in wGrp.findChildren(QSlider): - # _log.info(wSl) + #_log.info(wSl) key=wSl.objectName() if key.startswith('scl'): if key[-1]=='A': @@ -452,14 +513,67 @@ class WndVisualize(QWidget): v=int(round(np.log2(v)*2)) else: v=devP[key] - wSl.blockSignals(True) wSl.setValue(v) - wSl.blockSignals(False) - self.update() - def OnEvent(self,*args,**kwargs): - #test event - print(f'OnEvent: {args} ,{kwargs}') + self._mouseDrag={'obj':dev,'start':(mousePos,dev._paint['ofs'])} + try: + _log.info(f'{self._mouseDrag}') + except AttributeError: + _log.info(f'no object to drag') + + + def mouseMoveEvent(self, a0): + try: + md=self._mouseDrag + except AttributeError: + return + obj=md['obj'] + s=md['start'] + if obj==self._wdGrpDraw: + p=a0.pos() + md['start']=p + p=obj.geometry().topLeft()+p-s + obj.move(p) + return + p=a0.pos() + ofs=QPoint(*s[1])+p-s[0] + _log.info(f'{p} {ofs}') + obj._paint['ofs']=(ofs.x(),ofs.y()) + self.update() + + def paintEvent(self, e): + qp = QPainter() + qp.begin(self) + qp.setRenderHints(QPainter.HighQualityAntialiasing) + app=QApplication.instance() + dev=app._dev + app._dev.paint(qp) + qp.end() + + def updateDevice(self, dev): + self._devSel=dev + devP=dev._paint + wGrp=self._wdGrpDraw + wGrp.setTitle(dev._name) + for wSl in wGrp.findChildren(QSlider): + # _log.info(wSl) + key=wSl.objectName() + if key.startswith('scl'): + if key[-1]=='A': + v=devP['sclTrf'][0] + else: + v=devP['sclTrf'][1] + v=int(round(np.log2(v)*2)) + else: + v=devP[key] + wSl.blockSignals(True) + wSl.setValue(v) + wSl.blockSignals(False) + self.update() + + def OnEvent(self,*args,**kwargs): + #test event + print(f'OnEvent: {args} ,{kwargs}') if __name__ == '__main__': diff --git a/spectrumProc/spectrumProc.py b/spectrumProc/spectrumProc.py index bc80ff1..92fba1f 100755 --- a/spectrumProc/spectrumProc.py +++ b/spectrumProc/spectrumProc.py @@ -179,7 +179,15 @@ class WndMainRIXS(QWidget): with open(fn, 'rb') as fh: app=QApplication.instance() app._rawData=pickle.load(fh) - _log.info(app._rawData.keys()) + #_log.info(app._rawData.keys()) + #run=app._rawData[226] + #_log.info(run.keys()) + #raw2D=run['2D'] + #_log.info(f'{type(raw2D)}:{len(raw2D)} {raw2D}') + #line=raw2D[0] + #_log.info(f'{type(line)}: {line}') + #_log.info(raw2D) + #np.shape(raw2D) w=self._cbRaw for i, tx in enumerate(tuple(app._rawData.keys())): w.insertItem(i, str(tx))