Mono motors in read only mode

This commit is contained in:
Mohacsi Istvan 2022-11-22 17:52:45 +01:00
parent fd7208ed3e
commit bbf53a3e64
4 changed files with 186 additions and 19 deletions

View File

@ -57,8 +57,8 @@ if __name__ == "__main__":
for key in lut_db: for key in lut_db:
try: try:
dut = createProxy(str(key)) dut = createProxy(str(key))
# print(f"{key}\t: {type(dut)}\t{dut.read()}") print(f"{key}\t: {type(dut)}\t{dut.read()}")
print(f"{key}\t: {type(dut)}") # print(f"{key}\t: {type(dut)}")
except Exception as ex: except Exception as ex:
num_errors += 1 num_errors += 1
print(key) print(key)

View File

@ -166,13 +166,13 @@ motrz1e:
deviceGroup: monitor deviceGroup: monitor
status: {enabled: true} status: {enabled: true}
type: EpicsSignalRO type: EpicsSignalRO
#mopush1: mopush1:
# desc: 'Monochromator crystal 1 angle' desc: 'Monochromator crystal 1 angle'
# acquisition: {schedule: sync} acquisition: {schedule: sync}
# config: {name: mopush1, prefix: 'X12SA-OP-MO:ROX1'} config: {name: mopush1, read_pv: 'X12SA-OP-MO:ROX1'}
# deviceGroup: beamlineMotor deviceGroup: monitor
# status: {enabled: true} status: {enabled: true}
# type: EpicsMotor type: EpicsSignalRO
moth1e: moth1e:
desc: 'Monochromator crystal 1 theta encoder' desc: 'Monochromator crystal 1 theta encoder'
acquisition: {schedule: sync} acquisition: {schedule: sync}
@ -201,13 +201,13 @@ motry2:
deviceGroup: beamlineMotor deviceGroup: beamlineMotor
status: {enabled: true} status: {enabled: true}
type: EpicsMotor type: EpicsMotor
#mopush2: mopush2:
# desc: 'Monochromator crystal 2 angle' desc: 'Monochromator crystal 2 angle'
# acquisition: {schedule: sync} acquisition: {schedule: sync}
# config: {name: mopush2, prefix: 'X12SA-OP-MO:ROX2'} config: {name: mopush2, read_pv: 'X12SA-OP-MO:ROX2.VAL'}
# deviceGroup: beamlineMotor deviceGroup: monitor
# status: {enabled: true} status: {enabled: true}
# type: EpicsMotor type: EpicsSignalRO
moth2e: moth2e:
desc: 'Monochromator crystal 2 theta encoder' desc: 'Monochromator crystal 2 theta encoder'
acquisition: {schedule: sync} acquisition: {schedule: sync}
@ -878,3 +878,63 @@ FBPMUY:
status: {enabled: true} status: {enabled: true}
type: EpicsSignalRO type: EpicsSignalRO
sttrx:
desc: 'Girder X translation'
acquisition: {schedule: sync}
config: {name: sttrx, prefix: 'X12SA-HG'}
deviceGroup: beamlineMotor
status: {enabled: true}
type: GirderMotorX1
sttry:
desc: 'Girder Y translation'
acquisition: {schedule: sync}
config: {name: sttry, prefix: 'X12SA-HG'}
deviceGroup: beamlineMotor
status: {enabled: true}
type: GirderMotorY1
strox:
desc: 'Girder virtual pitch'
acquisition: {schedule: sync}
config: {name: strox, prefix: 'X12SA-HG'}
deviceGroup: beamlineMotor
status: {enabled: true}
type: GirderMotorPITCH
stroy:
desc: 'Girder virtual yaw'
acquisition: {schedule: sync}
config: {name: stroy, prefix: 'X12SA-HG'}
deviceGroup: beamlineMotor
status: {enabled: true}
type: GirderMotorYAW
stroz:
desc: 'Girder virtual roll'
acquisition: {schedule: sync}
config: {name: stroz, prefix: 'X12SA-HG'}
deviceGroup: beamlineMotor
status: {enabled: true}
type: GirderMotorROLL
mokev:
desc: 'Monochromator energy in keV'
acquisition: {schedule: sync}
config: {name: mokev, read_pv: 'X12SA-OP-MO:ROX2.VAL'}
deviceGroup: monitor
status: {enabled: true}
type: EnergyKev
moth1:
desc: 'Monochromator Theta 1'
acquisition: {schedule: sync}
config: {name: moth1, read_pv: 'X12SA-OP-MO:ECX1'}
deviceGroup: monitor
status: {enabled: true}
type: MonoTheta1
moth2:
desc: 'Monochromator Theta 2'
acquisition: {schedule: sync}
config: {name: moth1, read_pv: 'X12SA-OP-MO:ECX2'}
deviceGroup: monitor
status: {enabled: true}
type: MonoTheta2

View File

@ -3,7 +3,7 @@ from .slits import SlitH, SlitV
from .XbpmBase import XbpmBase, XbpmCsaxsOp from .XbpmBase import XbpmBase, XbpmCsaxsOp
from .SpmBase import SpmBase from .SpmBase import SpmBase
from .InsertionDevice import InsertionDevice from .InsertionDevice import InsertionDevice
from .specMotors import PmMonoBender, PmDetectorRotation from .specMotors import PmMonoBender, PmDetectorRotation, GirderMotorX1, GirderMotorY1, GirderMotorROLL, GirderMotorYAW, GirderMotorPITCH, MonoTheta1, MonoTheta2, EnergyKev
# Standard ophyd classes # Standard ophyd classes

View File

@ -8,19 +8,20 @@ IMPORTANT: Virtual monochromator axes should be implemented already in EPICS!!!
""" """
import numpy as np import numpy as np
from math import isclose, tan, atan from math import isclose, tan, atan, sqrt, sin, asin
from ophyd import ( from ophyd import (
EpicsSignal, EpicsSignal,
EpicsSignalRO, EpicsSignalRO,
EpicsMotor, EpicsMotor,
PseudoPositioner, PseudoPositioner,
PseudoSingle, PseudoSingle,
PVPositioner,
Device, Device,
Component, Component,
Kind, Kind,
) )
from ophyd.pseudopos import pseudo_position_argument, real_position_argument from ophyd.pseudopos import pseudo_position_argument, real_position_argument
from ophyd.utils.epics_pvs import data_type
class PmMonoBender(PseudoPositioner): class PmMonoBender(PseudoPositioner):
@ -91,3 +92,109 @@ class PmDetectorRotation(PseudoPositioner):
@real_position_argument @real_position_argument
def inverse(self, real_pos): def inverse(self, real_pos):
return self.PseudoPosition(dtth=r2d(-atan(real_pos.dtpush / self._tables_dt_push_dist_mm))) return self.PseudoPosition(dtth=r2d(-atan(real_pos.dtpush / self._tables_dt_push_dist_mm)))
class GirderMotorX1(PVPositioner):
"""Girder X translation pseudo motor
"""
setpoint = Component(EpicsSignal, ":X_SET", name="sp")
readback = Component(EpicsSignalRO, ":X1", name="rbv")
done = Component(EpicsSignal, ":M-DMOV", name="dmov")
class GirderMotorY1(PVPositioner):
"""Girder Y translation pseudo motor
"""
setpoint = Component(EpicsSignal, ":Y_SET", name="sp")
readback = Component(EpicsSignalRO, ":Y1", name="rbv")
done = Component(EpicsSignal, ":M-DMOV", name="dmov")
class GirderMotorYAW(PVPositioner):
"""Girder YAW pseudo motor
"""
setpoint = Component(EpicsSignal, ":YAW_SET", name="sp")
readback = Component(EpicsSignalRO, ":YAW1", name="rbv")
done = Component(EpicsSignal, ":M-DMOV", name="dmov")
class GirderMotorROLL(PVPositioner):
"""Girder ROLL pseudo motor
"""
setpoint = Component(EpicsSignal, ":ROLL_SET", name="sp")
readback = Component(EpicsSignalRO, ":ROLL1", name="rbv")
done = Component(EpicsSignal, ":M-DMOV", name="dmov")
class GirderMotorPITCH(PVPositioner):
"""Girder YAW pseudo motor
"""
setpoint = Component(EpicsSignal, ":PITCH_SET", name="sp")
readback = Component(EpicsSignalRO, ":PITCH1", name="rbv")
done = Component(EpicsSignal, ":M-DMOV", name="dmov")
class VirtualSignalBase(EpicsSignalRO):
"""This is a test class to create derives signals from one or
multiple original signals...
"""
def calc(self, val):
return val
def get(self, *args, **kwargs):
raw = super().get(*args, **kwargs)
return self.calc(raw)
def describe(self):
val = self.get()
d = super().describe()
d[self.name]["dtype"] = data_type(val)
return d
class MonoTheta1(VirtualSignalBase):
"""Converts the pusher motor position to theta angle
"""
_mono_a0_enc_scale1 = -1.0
_mono_a1_lever_length1 = 206.706
_mono_a2_pusher_offs1 = 6.85858
_mono_a3_enc_offs1 = -16.9731
def calc(self, val):
asin_arg = (val - self._mono_a2_pusher_offs1) / self._mono_a1_lever_length1
theta1 = self._mono_a0_enc_scale1 * asin( asin_arg ) / 3.141592 * 180.0 + self._mono_a3_enc_offs1
return theta1
class MonoTheta2(VirtualSignalBase):
"""Converts the pusher motor position to theta angle
"""
_mono_a3_enc_offs2 = -19.7072
_mono_a2_pusher_offs2 = 5.93905
_mono_a1_lever_length2 = 206.572
_mono_a0_enc_scale2 = -1.0
def calc(self, val):
asin_arg = (val - self._mono_a2_pusher_offs2) / self._mono_a1_lever_length2
theta2 = self._mono_a0_enc_scale2 * asin( asin_arg ) / 3.141592 * 180.0 + self._mono_a3_enc_offs2
return theta2
class EnergyKev(VirtualSignalBase):
"""Converts the pusher motor position to energy in keV
"""
_mono_hce = 12.39852066
_mono_2d2 = 2*5.43102/sqrt(3)
def calc(self, val):
theta_deg = atan(50 / val) / 2.0 * 180.0 / 3.141592
E_keV = -self._mono_hce / self._mono_2d2 / sin(theta_deg/180.0*3.14152)
return E_keV