コード例 #1
0
ファイル: valve.py プロジェクト: mrakitin/pcdsdevices
class Stopper(InOutPVStatePositioner):
    """
    Controls Stopper

    A base class for a device with two limits switches controlled via an
    external command PV. This fully encompasses the controls `Stopper`
    installations as well as un-interlocked `GateValves`

    Parameters
    ----------
    prefix : ``str``
        Full PPS Stopper PV

    name : ``str``
        Alias for the stopper

    Attributes
    ----------
    commands : ``Enum``
        An enum with integer values for ``open_valve``, ``close_valve`` values
    """
    # Default attributes
    _default_read_attrs = ['open_limit', 'closed_limit']

    # Limit-based states
    open_limit = C(EpicsSignalRO, ':OPEN')
    closed_limit = C(EpicsSignalRO, ':CLOSE')

    # Information on device control
    command = C(EpicsSignal, ':CMD')
    commands = Commands

    _state_logic = {
        'open_limit': {
            0: 'defer',
            1: 'OUT'
        },
        'closed_limit': {
            0: 'defer',
            1: 'IN'
        }
    }

    def _do_move(self, state):
        if state.name == 'IN':
            self.command.put(self.commands.close_valve.value)
        elif state.name == 'OUT':
            self.command.put(self.commands.open_valve.value)

    def open(self, **kwargs):
        """
        Open the stopper
        """
        return self.remove(**kwargs)

    def close(self, **kwargs):
        """
        Close the stopper
        """
        return self.insert(**kwargs)
コード例 #2
0
ファイル: laser_devices.py プロジェクト: slactjohnson/mec
class Highland(Device):
    """Class for the MEC Highland pulse shaper."""

    # Epics Signals
    pulse_heights = C(EpicsSignal, ':PulseHeights')
    pulse_heights_rbv = C(EpicsSignalRO, ':PulseHeights_RBV')
    fiducial_delay_rbv = C(EpicsSignalRO, ':FiducialDelay_RBV')
    fiducial_height_rbv = C(EpicsSignalRO, ':FiducialHeight_RBV')

    def write_pulse(self, pulse):
        """Write list of pulse heights to Highland."""
        self.pulse_heights.put(pulse)

    @property
    def pulse_rbv(self):
        """Returns list of current pulse heights."""
        heights = self.pulse_heights_rbv.get()
        return heights

    @property
    def fiducial_delay(self):
        """Return current fiducial delay."""
        delay = self.fiducial_delay_rbv.get()
        return delay

    @property
    def fiducial_height(self):
        """Return current fiducial height."""
        height = self.fiducial_height_rbv.get()
        return height
コード例 #3
0
ファイル: valve.py プロジェクト: mrakitin/pcdsdevices
class GateValve(Stopper):
    """
    Basic Vacuum Valve

    This inherits directly from :class:`.Stopper` but adds additional logic to
    check the state of the interlock before requesting motion. This is not a
    safety feature, just a notice to the operator.
    """
    # Limit based states
    open_limit = C(EpicsSignalRO, ':OPN_DI')
    closed_limit = C(EpicsSignalRO, ':CLS_DI')

    # Commands and Interlock information
    command = C(EpicsSignal, ':OPN_SW')
    interlock = C(EpicsSignalRO, ':OPN_OK')

    @property
    def interlocked(self):
        """
        Whether the interlock on the valve is active, preventing the valve from
        opening
        """
        return bool(self.interlock.get())

    def remove(self, **kwargs):
        """
        Remove the valve from the beam
        """
        if self.interlocked:
            raise InterlockError('Valve is currently forced closed')

        return super().remove(**kwargs)
コード例 #4
0
class SrxXspress3Detector(XspressTrigger, Xspress3Detector):
    roi_data = Cpt(PluginBase, 'ROIDATA:')
    channel1 = C(Xspress3Channel, 'C1_', channel_num=1, read_attrs=['rois'])
    channel2 = C(Xspress3Channel, 'C2_', channel_num=2, read_attrs=['rois'])
    channel3 = C(Xspress3Channel, 'C3_', channel_num=3, read_attrs=['rois'])
    channel4 = C(Xspress3Channel, 'C4_', channel_num=4, read_attrs=['rois'])
    # create_dir = Cpt(EpicsSignal, 'HDF5:FileCreateDir')

    hdf5 = Cpt(Xspress3FileStore, 'HDF5:',
               read_path_template='/nsls2/xf04bm/data/x3m/%Y/%m/%d/',
               root='/nsls2/xf04bm/data/',
               write_path_template='/nsls2/xf04bm/data/x3m/%Y/%m/%d/',
               )

    def __init__(self, prefix, *, configuration_attrs=None, read_attrs=None,
                 **kwargs):
        if configuration_attrs is None:
            configuration_attrs = ['external_trig', 'total_points',
                                   'spectra_per_point', 'settings',
                                   'rewindable']
        if read_attrs is None:
            read_attrs = ['channel1', 'channel2', 'channel3', 'channel4', 'hdf5']
        super().__init__(prefix, configuration_attrs=configuration_attrs,
                         read_attrs=read_attrs, **kwargs)
        # self.create_dir.put(-3)

    def stop(self):
        ret = super().stop()
        self.hdf5.stop()
        return ret

    def stage(self):
        ret = super().stage()
        # self._resource_uid = self._resource
        return ret
コード例 #5
0
ファイル: test_pvpositioner.py プロジェクト: bsobhani/ophyd
        class MyPositioner(PVPositioner):
            '''Setpoint, readback, done, stop. No put completion'''
            setpoint = C(EpicsSignal, '.VAL')
            readback = C(EpicsSignalRO, '.RBV')
            done = C(EpicsSignalRO, '.MOVN')
            stop_signal = C(EpicsSignal, '.STOP')

            stop_value = 1
            done_value = 0
コード例 #6
0
class XPDShutter(Device):
    cmd = C(EpicsSignal, 'Cmd-Cmd')
    close_sts = C(EpicsSignalRO, 'Sw:Cls1-Sts')
    open_sts = C(EpicsSignalRO, 'Sw:Opn1-Sts')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._st = None
        self._target = None
        self.close_sts.subscribe(self._watcher_close,
                                 self.close_sts.SUB_VALUE)

        self.open_sts.subscribe(self._watcher_open,
                                 self.open_sts.SUB_VALUE)

    def set(self, value, *, wait=False, **kwargs):
        if value not in ('Open', 'Close'):
            raise ValueError(
                "must be 'Open' or 'Close', not {!r}".format(value))
        if wait:
            raise RuntimeError()
        if self._st is not None:
            raise RuntimeError()
        self._target = value
        self._st = st = DeviceStatus(self, timeout=None)
        self.cmd.put(value)

        return st

    def _watcher_open(self, *, old_value=None, value=None, **kwargs):
        print("in open watcher", old_value, value)
        if self._target != 'Open':
            return
        if self._st is None:
            return

        if new_value:
            self._st._finished()
            self._target = None
            self._st = None
        print("in open watcher")

    def _watcher_close(self, *, old_value=None, value=None, **kwargs):
        print("in close watcher", old_value, value)
        if self._target != 'Close':
            return

        if self._st is None:
            return

        if new_value:
            self._st._finished()
            self._target = None
            self._st = None

        pass
コード例 #7
0
class MPSLimits(MPSBase, Device):
    """
    Logical combination of two MPS bits

    For devices that are inserted and removed from the beam, the MPS system

    The MPSLimits class is to determine what action is to be taken based on the
    MPS values of a device pertaining to a single device. If a device has two
    MPS values, there is certain logic that needs to be followed to determine
    whether or not the beam is allowed through.

    Parameters
    ----------
    prefix : ``str``
        Base of the MPS PVs

    name : ``str``
        Name of the MPS combination

    logic: ``callable``
        Determine whether the MPS is faulted based on the state of each limit.
        The function signature should look like:

        .. code::

            def logic(in_limit: bool, out_limit: bool) -> bool
    """
    # Individual limits
    in_limit = C(MPS, '_IN')
    out_limit = C(MPS, '_OUT')

    def __init__(self, prefix, logic, **kwargs):
        self.logic = logic
        super().__init__(prefix, **kwargs)

    @property
    def faulted(self):
        """
        This property determines whether the two MPS values are faulted and
        applies a logic function depending on the states of mps_A and mps_B.
        """
        return self.logic(self.in_limit.faulted, self.out_limit.faulted)

    @property
    def bypassed(self):
        """
        Whether either limit is bypassed
        """
        return self.in_limit.bypassed or self.out_limit.bypassed

    def _sub_to_children(self):
        self.in_limit.subscribe(self._fault_change,
                                event_type=self.in_limit.SUB_FAULT_CH)
        self.in_limit.subscribe(self._fault_change,
                                event_type=self.out_limit.SUB_FAULT_CH)
コード例 #8
0
class MPS(MPSBase, Device):
    """
    Class to interpret a single bit of MPS information

    There are three major attributes of each MPS bit that are relevant to
    operations; :attr:`.faulted` , :attr:`.bypassed` and :attr:`.veto_capable`.
    The first is the most obvious, when the device is faulted it reports as
    such to the MPS system. However, how this is actually interpreted by the
    MPS is determined by whether the bit is bypassed, and if there is a
    ``veto`` device upstream such that the fault can be safely ignored. The
    summary of both the `bypass` and `fault` signals is contained within
    :attr:`.tripped`.  The bypassed state is reported through EPICS as well but
    unfortunately whether a device is considered capable of  "veto-ing" or is
    vetoed by another device is not broadcast by EPICS so this is held within
    this device and the ``lighpath`` module

    Parameters
    ----------
    prefix : ``str``
        PV prefix of MPS information

    name : ``str``, required keyword
        Name of MPS bit

    veto : ``bool``, optional
        Whether or not the the device is capable of vetoing downstream faults
    """
    # Signals
    fault = C(EpicsSignalRO, '_MPSC')
    bypass = C(EpicsSignal, '_BYPS')

    # Default read and configuration attributes
    _default_read_attrs = ['read']
    _default_configuration_attrs = ['bypass']

    @property
    def faulted(self):
        """
        Whether the MPS bit is faulted or not
        """
        return bool(self.fault.value)

    @property
    def bypassed(self):
        """
        Bypass state of the MPS bit
        """
        return bool(self.bypass.value)

    def _sub_to_children(self):
        """
        Subscribe to child signals
        """
        self.fault.subscribe(self._fault_change, run=False)
        self.bypass.subscribe(self._fault_change, run=False)
コード例 #9
0
class M824_Axis(PVPositionerComparator):
    """Axis subclass for PI_M824_Hexapod class."""
    setpoint = C(EpicsSignal, '')
    readback = C(EpicsSignal, ':rbv')
    atol = 0.001  # one micron seems close enough

    def done_comparator(self, readback, setpoint):
        if setpoint - self.atol < readback and readback < setpoint + self.atol:
            return True
        else:
            return False
コード例 #10
0
ファイル: test_pvpositioner.py プロジェクト: bsobhani/ophyd
        class MyPositioner(PVPositioner):
            '''Setpoint, readback, no put completion. No done pv.'''
            setpoint = C(EpicsSignal, fm['setpoint'])
            readback = C(EpicsSignalRO, fm['readback'])
            actuate = C(EpicsSignal, fm['actuate'])
            stop_signal = C(EpicsSignal, fm['stop'])
            done = C(EpicsSignal, fm['moving'])

            actuate_value = 1
            stop_value = 1
            done_value = 1
コード例 #11
0
class PI_M824_Hexapod(Device):
    """Class for the main MEC TC hexapod. Model M-824 from PI."""
    def __init__(self, prefix, **kwargs):
        # Setup axes
        self.x = M824_Axis(prefix + ':Xpr', name='x', limits=(-22.5, 22.5))
        # Hexapod "Z", LUSI "Y"
        self.y = M824_Axis(prefix + ':Ypr', name='y', limits=(-12.5, 12.5))
        # Hexapod "Y", LUSI "Z"
        self.z = M824_Axis(prefix + ':Zpr', name='z', limits=(-22.5, 22.5))
        self.u = M824_Axis(prefix + ':Upr', name='u', limits=(-7.5, 7.5))
        # Hexapod "Z", LUSI "Y"
        self.v = M824_Axis(prefix + ':Vpr', name='v', limits=(-12.5, 12.5))
        # Hexapod "Y", LUSI "Z"
        self.w = M824_Axis(prefix + ':Wpr', name='w', limits=(-7.5, 7.5))
        super().__init__(prefix, **kwargs)

    # Setup controller level properties
    moving_rbk = C(EpicsSignal, ':moving.RVAL')
    velocity = C(EpicsSignal, ':vel')
    velocity_rbk = C(EpicsSignal, ':vel:rbv')
    error_rbk = C(EpicsSignal, ':error.RVAL')

    # Control functions
    def vel(self, velo):
        """Set velocity, e.g. hexapod.velo(5.0)"""
        self.velocity.put(velo)

    @property
    def vel(self):
        """Returns the current velocity."""
        velocity = self.velocity_rbk.get()
        return velocity

    @property
    def moving(self):
        """Returns True if hexapod is moving, False otherwise."""
        moving = self.moving_rbk.get()
        if moving == 1:
            return True
        elif moving == 0:
            return False
        else:
            print("Unknown moving status of %d" % moving)

    @property
    def haserror(self):
        """Returns current error status. True if error, False otherwise."""
        error = self.error_rbk.get()
        if error != 0:
            return True
        else:
            return False
コード例 #12
0
ファイル: laser_devices.py プロジェクト: slactjohnson/mec
class PolyScienceChiller(Device):
    """Class for the MEC Polyscience chillers."""

    # Epics Signals
    presure_psi = C(EpicsSignalRO, ':PressurePSI')
    presure_kpa = C(EpicsSignalRO, ':PressureKPA')
    temp_setpoint = C(EpicsSignal, ':TempSetpoint')
    temp_rbv = C(EpicsSignalRO, ':CurrentTemp')
    on_off = C(EpicsSignal, ':TurnOnOff')
    run_status = C(EpicsSignalRO, ':RunStatus')
    fault_code = C(EpicsSignalRO, ':FaultStatusCode')
    fault_status = C(EpicsSignalRO, ':FaultStatus')

    def set_temp(self, temp):
        """Set temperature setpoint (in Celsius)."""
        self.temp_setpoint.put(temp)

    def turn_on(self):
        """Turn on the chiller."""
        self.on_off.put(1)

    def turn_off(self):
        """Turn off the chiller."""
        self.on_off.put(0)

    @property
    def temp(self):
        """Readback the current temperature (in Celsius)."""
        curr_temp = self.temp_rbv.get()
        return curr_temp

    @property
    def status(self):
        """Readback the run status."""
        stat = self.run_status.get()
        return stat

    @property
    def pressure_psi(self):
        """Readback of the pressure in PSI."""
        psi = self.pressure_psi.get()
        return psi

    @property
    def pressure_kpa(self):
        """Readback of the pressure in KPA."""
        kpa = self.pressure_kpa.get()
        return kpa

    @property
    def fault_status(self):
        """Readback of the current fault status string."""
        string = self.fault_status.get()
        return string

    @property
    def fault_code(self):
        """Readback of the current fault code."""
        code = self.fault_code.get()
        return code
コード例 #13
0
class XPDPerkinElmer2(XPDPerkinElmer):
    tiff = C(
        XPDTIFFPlugin,
        'TIFF1:',  #- MA
        #write_path_template='Z:/data/pe2_data/%Y/%m/%d', #- DO
        write_path_template='Z:\\data\\pe2_data\\%Y\\%m\\%d\\',  #- DO
        #write_path_template='Z:/img/%Y/%m/%d/', #- MA
        #read_path_template='/SHARE/img/%Y/%m/%d/', #- MA
        read_path_template='/nsls2/xf28id1/data/pe2_data/%Y/%m/%d/',  #- DO
        root='/nsls2/xf28id1/data/pe2_data/',  #-DO
        #root='/SHARE/img/', #-MA
        cam_name='cam',  # used to configure "tiff squashing" #-MA
        proc_name='proc',  # ditto #-MA
        read_attrs=[],  #- MA
        #tiff = C(XPDTIFFPlugin, 'TIFF1:',
        #write_path_template='/home/xf28id1/Documents/Milinda/PE1Data',
        #read_path_template='/SHARE/img/%Y/%m/%d/',
        #root='/SHARE/img/',
        #cam_name='cam',  # used to configure "tiff squashing"
        #proc_name='proc',  # ditto
        #read_attrs=[],

        # TODO: switch to this configuration using GPFS later
        # once G:\ drive is mounted to the Windows IOC
        # (a new Windows 10 machine in the rack upstairs)
        # write_path_template='G:\\img\\%Y\\%m\\%d\\',
        # read_path_template='/nsls2/xf28id1/data/pe2_data/%Y/%m/%d/',
        # root='/nsls2/xf28id1/data/pe1_data',
    )
コード例 #14
0
ファイル: devices.py プロジェクト: teddyrendahl/mfx
class LaserShutter(InOutPositioner):
    """Controls shutter controlled by Analog Output"""
    # EpicsSignals
    voltage = C(EpicsSignal, '')
    state = FC(AttributeSignal, 'voltage_check')
    # Constants
    out_voltage = 5.0
    in_voltage = 0.0
    barrier_voltage = 1.4

    @property
    def voltage_check(self):
        """Return the position we believe shutter based on the channel"""
        if self.voltage.get() >= self.barrier_voltage:
            return 'OUT'
        else:
            return 'IN'

    def _do_move(self, state):
        """Override to just put to the channel"""
        if state.name == 'IN':
            self.voltage.put(self.in_voltage)
        elif state.name == 'OUT':
            self.voltage.put(self.out_voltage)
        else:
            raise ValueError("%s is in an invalid state", state)
コード例 #15
0
class LedLights(Device):
    """LED lights controlled by turning AC PDU channel on/off"""
    # Epics Signals
    control_pv = C(EpicsSignal, ':SetControlAction')
    on_value = 1
    off_value = 2

    # Control functions
    def on(self):
        self.control_pv.put(self.on_value)

    def off(self):
        self.control_pv.put(self.off_value)

    @property
    def ison(self):
        if self.control_pv.get() == self.on_value:
            return True
        else:
            return False

    @property
    def isoff(self):
        if self.control_pv.get() == self.off_value:
            return True
        else:
            return False
コード例 #16
0
class CS700TemperatureController(PVPositioner):
    readback = C(EpicsSignalRO, 'T-I')
    setpoint = C(EpicsSignal, 'T-SP')
    done = C(EpicsSignalRO, 'Cmd-Busy')
    stop_signal = C(EpicsSignal, 'Cmd-Cmd')

    def set(self, *args, timeout=None, **kwargs):
        return super().set(*args, timeout=timeout, **kwargs)

    def trigger(self):
        # There is nothing to do. Just report that we are done.
        # Note: This really should not necessary to do --
        # future changes to PVPositioner may obviate this code.
        status = DeviceStatus(self)
        status._finished()
        return status
コード例 #17
0
ファイル: devices.py プロジェクト: ZLLentz/mfx
class Piezo(Device):
    """
    Device for controlling piezo injector motors
    """
    velocity =  C(EpicsSignalRO, ':VELOCITYGET')
    req_velocity = C(EpicsSignal, ':VELOCITYSET')
    open_loop_step = C(EpicsSignal, ':OPENLOOPSTEP')

    _default_read_attrs = ['open_loop_step']
    _default_configuration_attrs = ['velocity']

    def tweak(self, distance):
        """
        Tweak the Piezo by a distance
        """
        return self.open_loop_step.set(distance)
コード例 #18
0
class SlitPositioner(FltMvInterface, PVPositioner, Device):
    """
    Abstraction of Slit Axis

    Each adjustable parameter of the slit (center, width) can be modeled as a
    motor in itself, even though each controls two different actual motors in
    reality, this gives a convienent interface for adjusting the aperture size
    and location with out backwards calculating motor positions

    Parameters
    ----------
    prefix : ``str``
        The prefix location of the slits, i.e MFX:DG2

    slit_type : ``'XWIDTH'``, ``'YWIDTH'``, ``'XCENTER'``, ``'YCENTER'``
        The aspect of the slit position you would like to control with this
        specific motor

    name : ``str``
        Alias for the axis

    limits : ``tuple``, optional
        Limits on the motion of the positioner. By default, the limits on the
        setpoint PV are used if None is given.

    See Also
    --------
    ``ophyd.PVPositioner``
        ``SlitPositioner`` inherits directly from ``PVPositioner``.
    """
    setpoint = FC(EpicsSignal, "{self.prefix}:{self._dirshort}_REQ")
    readback = FC(EpicsSignalRO, "{self.prefix}:ACTUAL_{self._dirlong}")
    done = C(EpicsSignalRO, ":DMOV")

    _default_read_attrs = ['readback']

    def __init__(self,
                 prefix,
                 *,
                 slit_type="",
                 name=None,
                 limits=None,
                 **kwargs):
        # Private PV names to deal with complex naming schema
        self._dirlong = slit_type
        self._dirshort = slit_type[:4]
        # Initalize PVPositioner
        super().__init__(prefix, limits=limits, name=name, **kwargs)

    @property
    def egu(self):
        """Engineering units"""
        return self._egu or self.readback._read_pv.units

    def _setup_move(self, position):
        # This is subclassed because we need `wait` to be set to False unlike
        # the default PVPositioner method. `wait` set to True will not return
        # until the move has completed
        logger.debug('%s.setpoint = %s', self.name, position)
        self.setpoint.put(position, wait=False)
コード例 #19
0
class PI_M824_Hexapod(Device):
    """Class for the main MEC TC hexapod. Model M-824 from PI."""
    # Setup axes
    x = C(M824_Axis, ':Xpr')
    y = C(M824_Axis, ':Ypr')
    z = C(M824_Axis, ':Zpr')
    u = C(M824_Axis, ':Upr')
    v = C(M824_Axis, ':Vpr')
    w = C(M824_Axis, ':Wpr')

    # Setup controller level properties
    moving_rbk = C(EpicsSignal, ':moving.RVAL')
    velocity = C(EpicsSignal, ':vel')
    velocity_rbk = C(EpicsSignal, ':vel:rbv')
    error_rbk = C(EpicsSignal, ':error.RVAL')


    # Control functions
    def vel(self, velo):
        """Set velocity, e.g. hexapod.velo(5.0)"""
        self.velocity.put(velo)

    @property
    def vel(self):
        """Returns the current velocity."""
        velocity = self.velocity_rbk.get() 
        return velocity 

    @property
    def moving(self):
        """Returns True if hexapod is moving, False otherwise."""
        moving = self.moving_rbk.get()
        if moving == 1:
            return True
        elif moving == 0:
            return False
        else:
            print("Unknown moving status of %d" % moving)
    
    @property
    def haserror(self):
        """Returns current error status. True if error, False otherwise."""
        error = self.error_rbk.get()
        if error != 0:
            return True 
        else:
            return False
コード例 #20
0
ファイル: test_pseudopos.py プロジェクト: ronpandolfi/ophyd
class Pseudo1x3(PseudoPositioner):
    pseudo1 = C(PseudoSingle, limits=(-10, 10))
    real1 = C(EpicsMotor, motor_recs[0])
    real2 = C(EpicsMotor, motor_recs[1])
    real3 = C(EpicsMotor, motor_recs[2])

    def forward(self, pseudo_pos):
        pseudo_pos = self.PseudoPosition(*pseudo_pos)
        # logger.debug('forward %s', pseudo_pos)
        return self.RealPosition(real1=-pseudo_pos.pseudo1,
                                 real2=-pseudo_pos.pseudo1,
                                 real3=-pseudo_pos.pseudo1)

    def inverse(self, real_pos):
        real_pos = self.RealPosition(*real_pos)
        # logger.debug('inverse %s', real_pos)
        return self.PseudoPosition(pseudo1=-real_pos.real1)
コード例 #21
0
class LinkamFurnace(PVPositioner):
    readback = C(EpicsSignalRO, 'TEMP')
    setpoint = C(EpicsSignal, 'RAMP:LIMIT:SET')
    done = C(EpicsSignalRO, 'STATUS')
    stop_signal = C(EpicsSignal, 'RAMP:CTRL:SET')
    temperature = C(EpicsSignal, "TEMP")

    def set(self, *args, timeout=None, **kwargs):
        
        return super().set(*args, timeout=timeout, **kwargs)

    def trigger(self):
        # There is nothing to do. Just report that we are done.
        # Note: This really should not necessary to do --
        # future changes to PVPositioner may obviate this code.
        status = DeviceStatus(self)
        status._finished()
        return status
コード例 #22
0
ファイル: mirror.py プロジェクト: barronjmont/pcdsdevices
class OMMotor(FltMvInterface, PVPositioner):
    """
    Base class for each motor in the LCLS offset mirror system.
    """
    __doc__ += basic_positioner_init

    # position
    readback = C(EpicsSignalRO, ':RBV', auto_monitor=True)
    setpoint = C(EpicsSignal, ':VAL', limits=True)
    done = C(EpicsSignalRO, ':DMOV', auto_monitor=True)
    motor_egu = C(EpicsSignal, ':RBV.EGU')

    # status
    interlock = C(EpicsSignalRO, ':INTERLOCK')
    enabled = C(EpicsSignalRO, ':ENABLED')
    # limit switches
    low_limit_switch = C(EpicsSignalRO, ":LLS")
    high_limit_switch = C(EpicsSignalRO, ":HLS")

    @property
    def egu(self):
        """
        Engineering units of the readback PV, as reported by EPICS.

        Returns
        -------
        egu: ``str``
        """
        return self.motor_egu.get()

    def check_value(self, position):
        """
        Checks to make sure the inputted value is both valid and within the
        soft limits of the motor.

        Parameters
        ----------
        position: ``float``
            Position to check for validity

        Raises
        ------
        ``ValueError``
            If position is ``None``, ``NaN`` or ``Inf``

        ``LimitError``
            If the position is outside the soft limits
        """
        # Check that we do not have a NaN or an Inf as those will
        # will make the PLC very unhappy ...
        if position is None or np.isnan(position) or np.isinf(position):
            raise ValueError("Invalid value inputted: '{0}'".format(position))
        # Use the built-in PVPositioner check_value
        super().check_value(position)
コード例 #23
0
    class SPseudo1x3(PseudoPositioner):
        pseudo1 = C(PseudoSingle, limits=(-10, 10))
        real1 = C(SoftPositioner, init_pos=0)
        real2 = C(SoftPositioner, init_pos=0)
        real3 = C(SoftPositioner, init_pos=0)

        @pseudo_position_argument
        def forward(self, pseudo_pos):
            pseudo_pos = self.PseudoPosition(*pseudo_pos)
            # logger.debug('forward %s', pseudo_pos)
            return self.RealPosition(real1=-pseudo_pos.pseudo1,
                                     real2=-pseudo_pos.pseudo1,
                                     real3=-pseudo_pos.pseudo1)

        @real_position_argument
        def inverse(self, real_pos):
            real_pos = self.RealPosition(*real_pos)
            # logger.debug('inverse %s', real_pos)
            return self.PseudoPosition(pseudo1=-real_pos.real1)
コード例 #24
0
class SrxXspress3Detector(XspressTrigger, Xspress3Detector):
    # TODO: garth, the ioc is missing some PVs?
    #   det_settings.erase_array_counters
    #       (XF:05IDD-ES{Xsp:1}:ERASE_ArrayCounters)
    #   det_settings.erase_attr_reset (XF:05IDD-ES{Xsp:1}:ERASE_AttrReset)
    #   det_settings.erase_proc_reset_filter
    #       (XF:05IDD-ES{Xsp:1}:ERASE_PROC_ResetFilter)
    #   det_settings.update_attr (XF:05IDD-ES{Xsp:1}:UPDATE_AttrUpdate)
    #   det_settings.update (XF:05IDD-ES{Xsp:1}:UPDATE)

    channel1 = C(Xspress3Channel, 'C1_', channel_num=1, read_attrs=['rois'])
    channel2 = C(Xspress3Channel, 'C2_', channel_num=2, read_attrs=['rois'])
    channel3 = C(Xspress3Channel, 'C3_', channel_num=3, read_attrs=['rois'])

    hdf5 = Cpt(Xspress3FileStore,
               'HDF5:',
               read_path_template='/data/XSPRESS3/2016-1/',
               write_path_template='/epics/data/2016-1/',
               root='/data')

    def __init__(self,
                 prefix,
                 *,
                 configuration_attrs=None,
                 read_attrs=None,
                 **kwargs):
        if configuration_attrs is None:
            configuration_attrs = [
                'external_trig', 'total_points', 'spectra_per_point',
                'settings'
            ]
        if read_attrs is None:
            read_attrs = ['channel1', 'channel2', 'channel3', 'hdf5']
        super().__init__(prefix,
                         configuration_attrs=configuration_attrs,
                         read_attrs=read_attrs,
                         **kwargs)

    def stop(self):
        ret = super.stop()
        self.hdf5.stop()
        return ret
コード例 #25
0
class M824_Axis(Device):
    """Axis subclass for PI_M824_Hexapod class."""
    
    axis = C(EpicsSignal, '')
    axis_rbv = C(EpicsSignal, ':rbv')

    def mv(self, pos):
        """Absolute move to specified position."""
        self.axis.put(pos)
    
    def mvr(self, inc):
        """Move relative distance."""
        curr_pos = self.axis_rbv.get()
        next_pos = curr_pos + inc
        self.axis.put(next_pos)

    def wm(self):
        """Return current axis position (where motor)."""
        curr_pos = self.axis_rbv.get()
        return curr_pos
コード例 #26
0
class LinkamFurnace(PVPositioner):
    readback = C(EpicsSignalRO, 'TEMP')
    setpoint = C(EpicsSignal, 'RAMP:LIMIT:SET')
    done = C(EpicsSignalRO, 'STATUS')
    stop_signal = C(EpicsSignal, 'RAMP:CTRL:SET')
    ramp_rate = C(EpicsSignal, 'RAMP:RATE:SET')

    def set(self, new_position, *args, timeout=None, **kwargs):
        if abs(new_position - self.setpoint.value) < 1:
            return DeviceStatus(self, done=True, success=True)
        else:
            return super().set(new_position, *args, timeout=timeout, **kwargs)

    def trigger(self):
        # There is nothing to do. Just report that we are done.
        # Note: This really should not necessary to do --
        # future changes to PVPositioner may obviate this code.
        status = DeviceStatus(self)
        status._finished()
        return status
コード例 #27
0
class BPMCam(SingleTrigger, AreaDetector):
    cam = C(AreaDetectorCam, '')
    image_plugin = C(ImagePlugin, 'image1:')

    # tiff = C(SRXTIFFPlugin, 'TIFF1:',
    #          #write_path_template='/epicsdata/bpm1-cam1/2016/2/24/')
    #          #write_path_template='/epicsdata/bpm1-cam1/%Y/%m/%d/',
    #          #root='/epicsdata', reg=db.reg)
    #          write_path_template='/nsls2/xf05id1/data/bpm1-cam1/%Y/%m/%d/',
    #          root='/nsls2/xf05id1')
    roi1 = C(ROIPlugin, 'ROI1:')
    roi2 = C(ROIPlugin, 'ROI2:')
    roi3 = C(ROIPlugin, 'ROI3:')
    roi4 = C(ROIPlugin, 'ROI4:')
    stats1 = C(StatsPlugin, 'Stats1:')
    stats2 = C(StatsPlugin, 'Stats2:')
    stats3 = C(StatsPlugin, 'Stats3:')
    stats4 = C(StatsPlugin, 'Stats4:')
    # this is flakey?
    # stats5 = C(StatsPlugin, 'Stats5:')
    pass
コード例 #28
0
class tstEpicsMotor(EpicsMotor):
    user_readback = C(CustomAlarmEpicsSignalRO, '.RBV')
    high_limit_switch = C(Signal, value=0)
    low_limit_switch = C(Signal, value=0)
    direction_of_travel = C(Signal, value=0)
    high_limit_value = C(EpicsSignalRO, '.HLM')
    low_limit_value = C(EpicsSignalRO, '.LLM')
コード例 #29
0
ファイル: test_epicsmotor.py プロジェクト: pawanon61/ophyd
class tstEpicsMotor(EpicsMotor):
    user_readback = C(CustomAlarmEpicsSignalRO, '.RBV', kind='hinted')
    high_limit_switch = C(Signal, value=0, kind='omitted')
    low_limit_switch = C(Signal, value=0, kind='omitted')
    direction_of_travel = C(Signal, value=0, kind='omitted')
    high_limit_value = C(EpicsSignalRO, '.HLM', kind='config')
    low_limit_value = C(EpicsSignalRO, '.LLM', kind='config')
コード例 #30
0
class SRXHFVLMCam(SingleTrigger, AreaDetector):
    cam = C(AreaDetectorCam, '')
    image_plugin = C(ImagePlugin, 'image1:')
    stats1 = C(StatsPlugin, 'Stats1:')
    stats2 = C(StatsPlugin, 'Stats2:')
    stats3 = C(StatsPlugin, 'Stats3:')
    stats4 = C(StatsPlugin, 'Stats4:')
    tiff = C(SRXTIFFPlugin,
             'TIFF1:',
             write_path_template='/epicsdata/hfvlm/%Y/%m/%d/',
             root='/epicsdata')