major rework of RIXSconfig.py
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user