major rework of RIXSconfig.py

This commit is contained in:
2024-09-04 11:23:01 +02:00
parent 976036c3e4
commit 3d9a581a1d

View File

@@ -29,9 +29,10 @@ bitmask for simulation:
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QSlider, QLineEdit,\
QCheckBox, QHBoxLayout, QVBoxLayout, QGroupBox, QGridLayout, QComboBox
QCheckBox, QHBoxLayout, QVBoxLayout, QGroupBox, QGridLayout, QComboBox, QMessageBox
from PyQt5.QtGui import QPainter, QColor, QPen, QBrush, QPolygon, QTransform
from PyQt5.QtCore import QPoint, QPointF, Qt
from numpy.matlib import empty
from pyqtgraph.Qt import QtCore, QtGui
import PyQt5.QtGui as QtGui
@@ -118,7 +119,7 @@ class WndMainRIXS(QWidget):
w.clicked.connect(lambda dummy,pb=pb: self.OnOpenChildWnd(pb))
lv.addWidget(w)
w=QGroupBox(dev._name, self)
w=QGroupBox(dev._name, self,objectName=dev._name)
lv.addWidget(w)
lg=QGridLayout(w)
row=0
@@ -169,18 +170,27 @@ class WndMainRIXS(QWidget):
def btnSyncMotors(self):
#reads the epics motor and updates the vizualization
_log.info('')
app=QApplication.instance()
dev=app._dev
pv_rbv=dev._pvDict['rbv']
geo=dev._geo
pv_rbv=dev._pvDict['rbv']
wGrp=self.findChild(QGroupBox,dev._name)
wLe=wGrp.findChild(QLineEdit, 'energy')
#wLe=self.findChild(QLineEdit, 'energy')
wLe.blockSignals(True)
wLe.setText('<unknown>')
wLe.blockSignals(False)
m=dict()
for k,v in pv_rbv.items():
if v.connected:
geo[k]=v.get()
m[k]=v.get()
else:
_log.warning(f'pv {k} not connected')
return
dev.motor2geometry()
dev.setGeometry(dev._geo)
break
dev.motor2geometry(m)
geo.update(m)
dev.setGeo2Paint(dev._geo)
try:
wndCld=app._wndVisualize
except AttributeError as e:
@@ -293,7 +303,7 @@ class WndMainRIXS(QWidget):
_log.error(f'can not find probe: {repr(e)}')
return
geo=vlsg.energy2geometry(energy,probe)
dev.setGeometry(geo)
dev.setGeo2Paint(geo)
try:
dev.geometry2motor()
except ValueError as e:
@@ -313,8 +323,6 @@ class WndMainRIXS(QWidget):
wndCld.updateDevice(dev)
class RIXSdevice():
_lutDifrBeamPaint=( # (number of difr beam,draw mode,alpha,width)
(4, 2, 190, 0),
@@ -356,7 +364,7 @@ class RIXSdevice():
'bb':87, # reflection angle
'cc':22, # detector angle
}
self.setGeometry(g)
self.setGeo2Paint(g)
self.connectEPICS()
def connectEPICS(self):
@@ -367,8 +375,14 @@ class RIXSdevice():
for m,v in self._motors:
pvn=self._prefix+'MOT_'+m.upper()+'.RBV'
pv=epics.get_pv(pvn,connection_callback=self.OnConnectionChange,callback=self.OnValueChange)
#pv=epics.get_pv(pvn)
pv_rbv[m]=pv
_log.info(f'{pv}')
print(len(pv_rbv))
#for pv in pv_rbv.values(): #need to do it is 2 steps.
# pv.connection_callbacks.append(self.OnConnectionChange)
# idx=pv.add_callback(self.OnValueChange)
# pv.run_callback(idx)
def OnConnectionChange(self, pvname=None, conn=None, **kws):
pvc=self._pvConnected
@@ -376,7 +390,8 @@ class RIXSdevice():
pvc+=1
else:
if pvc>0: pvc-=1
_log.info(f'PV connection {pvc}/{len(self._pvDict)}: {pvname} {conn}')
pv_rbv=self._pvDict['rbv']
_log.info(f'PV connection {pvc}/{len(pv_rbv)}: {pvname} {conn}')
self._pvConnected=pvc
app=QApplication.instance()
@@ -402,18 +417,29 @@ class RIXSdevice():
#}
_log.info(f"PV val:{pvname}:{value}")
app=QApplication.instance()
self.motor2geometry()
self.setGeo2Paint(self._geo)
try:
wnd=app._wndVars
wndCld=app._wndVisualize
except AttributeError as e:
pass
else:
wnd.update_label(pvname,value,**kw)
wndCld.updateDevice(self)
try:
wndCld=app._wndVars
except AttributeError as e:
pass
else:
#wnd.update_label(pvname, value, **kw) # would not update the geometry
wndCld.updateDevice(self)
#pv.add_callback('RBV', self.update_label)
#_log.warning(f"can't handle PV: {pvname}:{value}")
# return
#self.vis_update(key,value,'008000')
def setGeometry(self,geo):
def setGeo2Paint(self,geo):
self._geo=geo
p=self._paint
sclA,sclD=p['sclTrf']
@@ -428,7 +454,6 @@ class RIXSdevice():
def geometry2motor(self):
# returns raw motor positions
# offset detector plane to deflected beam: 34deg
geo=self._geo
r1,r2,aa,bb,cc=geo['r1'],geo['r2'],geo['aa'],geo['bb'],geo['cc']
mt=gtz=gty1=gty2=grx=gtx=dtz=dty1=dty2=drx=None
@@ -436,7 +461,7 @@ class RIXSdevice():
radArm=np.deg2rad(degArm)
gtz=r1
grx=90-aa
dtz=np.cos(radArm)*r2
dtz=r1+np.cos(radArm)*r2
dty1=dty2=np.sin(radArm)*r2
drx=90-aa+90-bb+cc-34
dd=cc-34 # angle of bellow to detector
@@ -460,24 +485,54 @@ class RIXSdevice():
elif abs(dd)>15:
raise(ValueError('angle bellow to detector > 15°'))
def motor2geometry(self):
_log.info('TODO...')
geo=self._geo
mt,gtz,gty1,gty2,grx,gtx,dtz,dty1,dty2,drx= geo['mt'],geo['gtz'],geo['gty1'],geo['gty2'],geo['grx'],geo['gtx'],geo['dtz'],geo['dty1'],geo['dty2'],geo['drx']
def motor2geometry(self,m=None):
# reads the motor position from the pv and updates the geometry
# IT DOES NOT touch the motor fields in _geometry !
if m is None: #dictionary is empty
pv_rbv=self._pvDict['rbv']
if len(pv_rbv)<10:
_log.info('not yet populated')
return
m=dict()
for k, v in pv_rbv.items():
if v.connected and v._args['value'] is not None:
# v._args['value'] is not None is needed as connected sometimes is not save enough
m[k]=v.get()
else:
_log.warning(f'pv {k} not connected or no value')
return
def mot2geo(mt,gtz,gty1,gty2,grx,gtx,dtz,dty1,dty2,drx):
geo=self._geo
#degArm=90-aa+90-bb
#radArm=np.deg2rad(degArm)
#gtz=r1
#grx=90-aa
#dtz=np.cos(radArm)*r2
#dty1=dty2=np.sin(radArm)*r2
#drx=90-aa+90-bb+cc-34
#dd=cc-34 # angle of bellow to detector
r1=gtz
#r2=
aa=90-grx
#bb=
#cc=
r1=gtz
x=(dtz-gtz)
y=(dty1+dty2)/2
r2=(x**2+y**2)**.5
radArm=np.arctan2(y,x)
degArm=np.rad2deg(radArm)
aa=90-grx
#degArm=90-aa+90-bb
bb=90-aa+90-degArm
#drx=90-aa+90-bb+cc-34
#cc=drx-90+aa-90+bb+34
cc=drx-degArm+34
geo.update({
'r1':r1,
#'r2':r2,
'aa':aa,
#'bb':bb,
#'cc':cc,
})
geo.update({
'r1':r1,
'r2':r2,
'aa':aa,
'bb':bb,
'cc':cc,
})
mot2geo(**m)
@@ -758,7 +813,7 @@ class WndVisualize(QWidget):
p['sclTrf']=(2**(val/2),p['sclTrf'][1])
else:
p['sclTrf']=(p['sclTrf'][0],2**(val/2))
dev.setGeometry(dev._geo)
dev.setGeo2Paint(dev._geo)
else:
p[key]=val
g=dev._geo
@@ -844,6 +899,7 @@ class WndVisualize(QWidget):
qp.end()
def updateDevice(self, dev):
#_log.info(f'WndVis')
self._devSel=dev
devP=dev._paint
wGrp=self._wdGrpDraw
@@ -998,14 +1054,14 @@ class WndVars(QWidget):
self.update()
def update_label(self, k,v,**kwargs):
_log.info(f'{k}:{v}:{kwargs}')
#_log.info(f'{k}:{v}:{kwargs}')
app=QApplication.instance()
dev=app._dev
if kwargs:
rbv=v
key=re.search('_(.*)\.',k).group(1).lower()
val=dev._geo.get(key,None)
_log.debug(f'monitoring: {key}:{val}:{rbv}')
#_log.debug(f'monitoring: {key}:{val}:{rbv}')
else:
key=k
val=v
@@ -1015,7 +1071,7 @@ class WndVars(QWidget):
rbv=pv.get()
else:
rbv=None
_log.debug(f'change: {key}:{val}:{rbv}')
#_log.debug(f'change: {key}:{val}:{rbv}')
grpMot=self._wdGrpMotor
wLe=grpMot.findChild(QLineEdit, key)
if wLe is not None:
@@ -1042,17 +1098,30 @@ class WndVars(QWidget):
def btnMoveMotors(self):
app=QApplication.instance()
dev=app._dev
pv_rbv=dev._pvDict['rbv']
grpMot=self._wdGrpMotor
lg=grpMot.layout()
row=lg.rowCount()
cnt=0
for r in range(row-1): # -1 because last one is a button
wCb=lg.itemAtPosition(r, 0)
if wCb is None: continue
if wCb.widget().isChecked(): cnt+=1
if cnt==0: return
btn=QMessageBox.question(
self,
"Motion",
f"Really want to move {cnt} motors ?",
buttons=QMessageBox.Yes|QMessageBox.No,
defaultButton=QMessageBox.No,
)
if btn!=QMessageBox.Yes: return
geo=dev._geo
try:
pv_val=dev._pvDict['val']
except KeyError as e:
pv_val=dev._pvDict['val']=dict()
geo=dev._geo
grpMot=self._wdGrpMotor
lg=grpMot.layout()
col=lg.columnCount()
row=lg.rowCount()
for r in range(row-1): # -1 because last one is a button
wCb=lg.itemAtPosition(r, 0)
if wCb is None: