Source code for apstools.devices.xia_slit

"""
XIA Slit from EPICS synApps optics: xia_slit.db
+++++++++++++++++++++++++++++++++++++++++++++++

Coordinates (viewing from detector towards source)::

        top
    inb     out
        bot

Each blade [#]_ (in the XIA slit controller) travels in a _cylindrical_
coordinate system.  Positive motion moves a blade **outwards** from the center
with a backlash correction. No backlash correction is applied for negative
motion (as the blades close).  Size and center are computed
by the underlying EPICS support.

    hsize = inb + out
    vsize = top + bot

..  [#] Note that the blade names here are different than the EPICS support.
    The difference is to make the names of the blades consistent with other
    slits with the Bluesky framework.

USAGE:

    slit = XiaSlitController("IOC:hsc1:", name="slit")
    print(slit.geometry)

.. autosummary::

   ~XiaSlit2D
"""

from ophyd import Component
from ophyd import Device
from ophyd import EpicsSignal
from ophyd import EpicsSignalRO
from ophyd import Signal

from ..devices import PVPositionerSoftDone
from ..utils import SlitGeometry


[docs]class XiaSlit2D(Device): """ EPICS synApps optics xia_slit.db 2D support: inb out bot top ... """ inb = Component(PVPositionerSoftDone, "", setpoint_pv="l", readback_pv="lRB") out = Component(PVPositionerSoftDone, "", setpoint_pv="r", readback_pv="rRB") bot = Component(PVPositionerSoftDone, "", setpoint_pv="b", readback_pv="bRB") top = Component(PVPositionerSoftDone, "", setpoint_pv="t", readback_pv="tRB") hsize = Component(PVPositionerSoftDone, "", setpoint_pv="width", readback_pv="widthRB") vsize = Component(PVPositionerSoftDone, "", setpoint_pv="height", readback_pv="heightRB") hcenter = Component(PVPositionerSoftDone, "", setpoint_pv="h0", readback_pv="h0RB") vcenter = Component(PVPositionerSoftDone, "", setpoint_pv="v0", readback_pv="v0RB") hID = Component(EpicsSignal, "hID", kind="config", string=True) horientation = Component(EpicsSignal, "hOrient", kind="config", string=True) hbusy = Component(EpicsSignalRO, "hBusy", kind="omitted", string=True) vID = Component(EpicsSignal, "vID", kind="config", string=True) vorientation = Component(EpicsSignal, "vOrient", kind="config", string=True) vbusy = Component(EpicsSignalRO, "vBusy", kind="omitted", string=True) enable = Component(EpicsSignal, "enable", kind="config", string=True) # diagnostics error_code = Component(EpicsSignalRO, "err", kind="config") error_message = Component(EpicsSignalRO, "errMsg", kind="config", string=True) message1 = Component(EpicsSignalRO, "msg1", kind="config", string=True) message2 = Component(EpicsSignalRO, "msg2", kind="config", string=True) message3 = Component(EpicsSignalRO, "msg3", kind="config", string=True) # configuration calibrate = Component(EpicsSignal, "calib", kind="omitted", put_complete=True) initialize = Component(EpicsSignal, "init", kind="omitted", put_complete=True) locate = Component(EpicsSignal, "locate", kind="omitted", put_complete=True) stop_button = Component(EpicsSignal, "stop", kind="omitted", put_complete=True) precision = Component(Signal, value=3, kind="config") @property def geometry(self): """Return the slit 2D size and center as a namedtuple.""" pppp = [ round(obj.position, self.precision.get()) for obj in (self.hsize, self.vsize, self.hcenter, self.vcenter) ] return SlitGeometry(*pppp) @geometry.setter def geometry(self, value): # first, test the input by assigning it to local vars width, height, x, y = value self.hsize.move(width) self.vsize.move(height) self.hcenter.move(x) self.vcenter.move(y)
# ----------------------------------------------------------------------------- # :author: Pete R. Jemian # :email: jemian@anl.gov # :copyright: (c) 2017-2024, UChicago Argonne, LLC # # Distributed under the terms of the Argonne National Laboratory Open Source License. # # The full license is in the file LICENSE.txt, distributed with this software. # -----------------------------------------------------------------------------