Source code for ophyd_async.epics.pmac._pmac_io

from collections.abc import Sequence

import numpy as np

from ophyd_async.core import Array1D, Device, DeviceVector, StandardReadable
from ophyd_async.epics import motor
from ophyd_async.epics.core import epics_signal_r, epics_signal_rw

CS_LETTERS = "ABCUVWXYZ"


[docs] class PmacTrajectoryIO(StandardReadable): """Device that moves a PMAC Motor record.""" def __init__(self, prefix: str, name: str = "") -> None: self.time_array = epics_signal_rw( Array1D[np.float64], prefix + "ProfileTimeArray" ) self.user_array = epics_signal_rw(Array1D[np.int32], prefix + "UserArray") # 1 indexed CS axes so we can index into them from the compound motor input link self.positions = DeviceVector( { i + 1: epics_signal_rw( Array1D[np.float64], f"{prefix}{letter}:Positions" ) for i, letter in enumerate(CS_LETTERS) } ) self.use_axis = DeviceVector( { i + 1: epics_signal_rw(bool, f"{prefix}{letter}:UseAxis") for i, letter in enumerate(CS_LETTERS) } ) self.velocities = DeviceVector( { i + 1: epics_signal_rw( Array1D[np.float64], f"{prefix}{letter}:Velocities" ) for i, letter in enumerate(CS_LETTERS) } ) self.points_to_build = epics_signal_rw(int, prefix + "ProfilePointsToBuild") self.build_profile = epics_signal_rw(bool, prefix + "ProfileBuild") self.execute_profile = epics_signal_rw(bool, prefix + "ProfileExecute") self.scan_percent = epics_signal_r(float, prefix + "TscanPercent_RBV") self.abort_profile = epics_signal_rw(bool, prefix + "ProfileAbort") self.profile_cs_name = epics_signal_rw(str, prefix + "ProfileCsName") self.calculate_velocities = epics_signal_rw(bool, prefix + "ProfileCalcVel") super().__init__(name=name)
[docs] class PmacAxisAssignmentIO(Device): """A Device that (direct) moves a PMAC Coordinate System Motor. Note that this does not go through a motor record. """ def __init__(self, prefix: str, name: str = "") -> None: self.cs_axis_letter = epics_signal_r(str, f"{prefix}CsAxis_RBV") self.cs_port = epics_signal_r(str, f"{prefix}CsPort_RBV") self.cs_number = epics_signal_r(int, f"{prefix}CsRaw_RBV") super().__init__(name=name)
[docs] class PmacCoordIO(Device): """A Device that represents a Pmac Coordinate System.""" def __init__(self, prefix: str, name: str = "") -> None: self.defer_moves = epics_signal_rw(bool, f"{prefix}DeferMoves") self.cs_port = epics_signal_r(str, f"{prefix}Port") self.cs_axis_setpoint = DeviceVector( { i + 1: epics_signal_rw(np.float64, f"{prefix}M{i + 1}:DirectDemand") for i in range(len(CS_LETTERS)) } ) super().__init__(name=name)
[docs] class PmacIO(Device): """Device that represents a pmac controller.""" def __init__( self, prefix: str, raw_motors: Sequence[motor.Motor], coord_nums: Sequence[int], name: str = "", ) -> None: motor_prefixes = [motor.motor_egu.source.split(".")[0] for motor in raw_motors] self.assignment = DeviceVector( { i: PmacAxisAssignmentIO(motor_prefix) for i, motor_prefix in enumerate(motor_prefixes) } ) # Public Look up for motor to axis assignment DeviceVector index self.motor_assignment_index = {motor: i for i, motor in enumerate(raw_motors)} self.coord = DeviceVector( {coord: PmacCoordIO(prefix=f"{prefix}CS{coord}:") for coord in coord_nums} ) # Trajectory PVs have the same prefix as the pmac device self.trajectory = PmacTrajectoryIO(prefix) super().__init__(name=name)