Exemple #1
0
def laser_in(wait=False, timeout=10):
    """
    Insert the Reference Laser and clear the beampath

    Parameters
    ----------
    wait: bool, optional
        Wait and check that motion is properly completed

    timeout: float, optional
        Time to wait for motion completion if requested to do so

    Operations
    ----------
    * Insert the Reference Laser
    * Set the Wave8 out (35 mm)
    * Set the DG1 slits to 6 mm x 6 mm
    * Set the DG2 upstream slits to 6 mm x 6 mm
    * Set the DG2 midstream slits to 1 mm x 1 mm
    * Set the DG2 downstream slits to 1 mm x 1 mm
    """
    # Command motion and collect status objects
    ref = mfx_reflaser.insert(wait=False)
    w8 = mfx_dg1_wave8_motor.move(35, wait=False)
    dg1 = mfx_dg1_slits.move(6., wait=False)
    dg2_us = mfx_dg2_upstream_slits.move(6., wait=False)
    dg2_ms = mfx_dg2_midstream_slits.move(1., wait=False)
    dg2_ds = mfx_dg2_downstream_slits.move(1., wait=False)
    # Combine status and wait for completion
    if wait:
        status_wait(ref & w8 & dg1 & dg2_us & dg2_ms & dg2_ds, timeout=timeout)
Exemple #2
0
    def home(self, direction=None, wait=True, **kwargs):
        """
        Perform the configured homing function.

        This is set on the controller. Unlike other kinds of axes, only
        the single pre-programmed homing routine can be used, so the
        ``direction`` argument has no effect.
        """
        self._run_subs(sub_type=self._SUB_REQ_DONE, success=False)
        self._reset_sub(self._SUB_REQ_DONE)

        status = MoveStatus(self,
                            self.plc.home_pos.get(),
                            timeout=None,
                            settle_time=self._settle_time)
        self.plc.cmd_home.put(1)

        self.subscribe(status._finished,
                       event_type=self._SUB_REQ_DONE,
                       run=False)

        try:
            if wait:
                status_wait(status)
        except KeyboardInterrupt:
            self.stop()
            raise

        return status
Exemple #3
0
 def wait(self, status=None):
     """Wait for the inputted status to complete."""
     try:
         status = status or self.status
         status_wait(status)
     except KeyboardInterrupt:
         pass
Exemple #4
0
    def set_energy(self, E, wait=False, check_status=True):
        """
        Sets the angles of the crystals in the delay line to maximize the
        inputted energy.        
    
        Parameters
        ---------
        E : float
            Energy to use for the system.

        wait : bool, optional
            Wait for each motor to complete the motion.

        check_status : bool, optional
            Check if the motors are in a valid state to move.
        """
        # Check to make sure the motors are in a valid state to move
        if check_status:
            self.check_status(energy=E)

        # Perform the move
        status = [
            motor.move(pos, wait=False, check_status=False)
            for motor, pos in zip(self._energy_motors,
                                  self._get_move_positions(E))
        ]

        # Wait for the motions to finish
        if wait:
            for s in status:
                logger.info("Waiting for {} to finish move ...".format(
                    s.device.name))
                status_wait(s)

        return status
Exemple #5
0
    def move(self, position, moved_cb=None, timeout=None, wait=False):
        """
        Move to the desired state and return completion information.

        Parameters
        ----------
        position: ``int`` or ``str``
            The enumerate state or the corresponding integer

        moved_cb: ``function``, optional
            moved_cb(obj=self) will be called at the end of motion

        timeout: ``int`` or ``float``, optional
            Move timeout in seconds

        wait: ``bool``, optional
            If True, do not return until the motion has completed.

        Returns
        -------
        status: ``StateStatus``
            ``Status`` object that represents the move's progress.
        """
        status = self.set(position, moved_cb=moved_cb, timeout=timeout)
        if wait:
            status_wait(status)
        return status
Exemple #6
0
    def move(self, position, moved_cb=None, timeout=None, wait=False):
        """
        Move to the desired state and return completion information.

        Parameters
        ----------
        position : int or str
            The enumerate state or the corresponding integer.

        moved_cb : callable, optional
            Function to call at the end of motion. i.e. ``moved_cb(obj=self)``
            will be called when move is complete.

        timeout : int or float, optional
            Move timeout in seconds.

        wait : bool, optional
            If `True`, do not return until the motion has completed.

        Returns
        -------
        status : StateStatus
            `Status` object that represents the move's progress.
        """

        status = self.set(position, moved_cb=moved_cb, timeout=timeout)
        if wait:
            status_wait(status)
        return status
Exemple #7
0
    def home(self, direction, wait=True, **kwargs):
        '''Perform the default homing function in the desired direction

        Parameters
        ----------
        direction : HomeEnum
           Direction in which to perform the home search.
        '''
        direction = HomeEnum(direction)

        self._started_moving = False
        position = (self.low_limit+self.high_limit)/2
        status = super().move(position, **kwargs)

        if direction == HomeEnum.forward:
            self.home_forward.put(1, wait=False)
        else:
            self.home_reverse.put(1, wait=False)

        try:
            if wait:
                status_wait(status)
        except KeyboardInterrupt:
            self.stop()
            raise

        return status
    def set(self, position, *, wait=False, timeout=None, settle_time=None,
            moved_cb=None):

        # In case nothing needs to be moved, just create a finished status
        status = Status()
        status.set_finished()

        # Mono
        if abs(self.get()-position) > mono.energy.tolerance.get():
            mono_status = mono.energy.set(
                position, wait=wait, timeout=timeout, moved_cb=moved_cb
            )
            status = AndStatus(status, mono_status)

        # Phase retarders
        for pr in [pr1, pr2, pr3]:
            if pr.tracking.get():
                pr_status = pr.energy.move(
                    position, wait=wait, timeout=timeout, moved_cb=moved_cb
                )
                status = AndStatus(status, pr_status)

        # Undulator
        if undulator.downstream.tracking.get():
            und_pos = position + undulator.downstream.energy.offset.get()
            und_status = undulator.downstream.energy.move(
                und_pos, wait=wait, timeout=timeout, moved_cb=moved_cb
            )
            status = AndStatus(status, und_status)

        if wait:
            status_wait(status)

        return status
Exemple #9
0
    def reinitialize(self, wait=False):
        """
        Reinitialize the IMS motor.

        Parameters
        ----------
        wait : bool
            Wait for the motor to be fully intialized.

        Returns
        -------
        :class:`~ophyd.status.SubscriptionStatus`
            Status object reporting the initialization state of the motor.
        """
        logger.info('Reinitializing motor')
        # Issue command
        self.reinit_command.put(1)

        # Check error
        def initialize_complete(value=None, **kwargs):
            return value != 3

        # Generate a status
        st = SubscriptionStatus(self.error_severity,
                                initialize_complete,
                                settle_time=0.5)
        # Wait on status if requested
        if wait:
            status_wait(st)
        return st
Exemple #10
0
    def _clear_flag(self, flag, wait=False, timeout=10):
        """Clear flag whose information is in :attr:`._bit_flags`"""
        # Gather our flag information
        flag_info = self._bit_flags[flag]
        bit = flag_info['readback']
        mask = flag_info.get('mask', 1)

        # Create a callback function to check for bit
        def flag_is_cleared(value=None, **kwargs):
            return not bool((int(value) >> bit) & mask)

        # Check that we need to actually set the flag
        if flag_is_cleared(value=self.bit_status.get()):
            logger.debug("%s flag is not currently active", flag)
            st = DeviceStatus(self)
            st.set_finished()
            return st

        # Issue our command
        logger.info('Clearing %s flag ...', flag)
        self.seq_seln.put(flag_info['clear'])
        # Generate a status
        st = SubscriptionStatus(self.bit_status, flag_is_cleared)
        if wait:
            status_wait(st, timeout=timeout)
        return st
Exemple #11
0
def laser_out(wait=False, timeout=10):
    """
    Remove the Reference Laser and configure the beamline

    Parameters
    ----------
    wait: bool, optional
        Wait and check that motion is properly completed

    timeout: float, optional
        Time to wait for motion completion if requested to do so

    Operations
    ----------
    * Remove the Reference Laser
    * Set the Wave8 Target 3 In (5.5 mm)
    * Set the DG1 slits to 0.7 mm x 0.7 mm
    * Set the DG2 upstream slits to 0.7 mm x 0.7 mm
    * Set the DG2 midstream slits to 0.7 mm x 0.7 mm
    * Set the DG2 downstream slits to 0.7 mm x 0.7 mm
    """
    # Command motion and collect status objects
    ref = mfx_reflaser.remove(wait=False)
    w8 = mfx_dg1_wave8_motor.move(5.5, wait=False)
    dg1 = mfx_dg1_slits.move(0.7, wait=False)
    dg2_us = mfx_dg2_upstream_slits.move(0.7, wait=False)
    dg2_ms = mfx_dg2_midstream_slits.move(0.7, wait=False)
    dg2_ds = mfx_dg2_downstream_slits.move(0.7, wait=False)
    # Combine status and wait for completion
    if wait:
        status_wait(ref & w8 & dg1 & dg2_us & dg2_ms & dg2_ds, timeout=timeout)
Exemple #12
0
def test_slit_motion():
    slits = fake_slits()
    # Uneven motion
    status = slits.move((5.0, 10.0))
    assert slits.xwidth.setpoint._write_pv.get() == 5.0
    assert slits.ywidth.setpoint._write_pv.get() == 10.0
    assert not status.done
    # Manually complete move
    slits.xwidth.readback._read_pv.put(5.0)
    slits.xwidth.done._read_pv.put(1)
    slits.ywidth.readback._read_pv.put(10.0)
    slits.ywidth.done._read_pv.put(1)
    status_wait(status, timeout=5.0)
    assert status.done and status.success
    # Reset DMOV flags
    slits.xwidth.done._read_pv.put(0)
    slits.ywidth.done._read_pv.put(0)
    time.sleep(1.0)

    status = slits.remove(40.0)
    # Command was registered
    assert slits.xwidth.setpoint._write_pv.get() == 40.0
    assert slits.ywidth.setpoint._write_pv.get() == 40.0
    # Status object reports done at correct moment
    assert not status.done
    # Manually complete move
    slits.xwidth.readback._read_pv.put(40.0)
    slits.xwidth.done._read_pv.put(1)
    slits.ywidth.readback._read_pv.put(40.0)
    slits.ywidth.done._read_pv.put(1)
    status_wait(status, timeout=1)
    assert status.done and status.success
Exemple #13
0
    def _status_print(self,
                      status,
                      msg=None,
                      ret_status=False,
                      print_set=True,
                      timeout=None,
                      wait=True,
                      reraise=False):
        """
        Internal method that optionally returns the status object and optionally
        prints a message about the set. If a message is passed but print_set is
        False then the message is logged at the debug level.

        Parameters
        ----------
        status : StatusObject or list
            The inputted status object.
        
        msg : str or None, optional
            Message to print if print_set is True.

        ret_status : bool, optional
            Return the status object of the set.

        print_set : bool, optional
            Print a short statement about the set.

        wait : bool, optional
            Wait for the status to complete.

        reraise : bool, optional
            Raise the RuntimeError in the except.

        Returns
        -------
        Status
            Inputted status object.        
        """
        try:
            # Wait for the status to complete
            if wait:
                for s in as_list(status):
                    status_wait(s, timeout)

            # Notify the user
            if msg is not None:
                if print_set:
                    logger.info(msg)
                else:
                    logger.debug(msg)
            if ret_status:
                return status

        # The operation failed for some reason
        except RuntimeError:
            error = "Operation completed, but reported an error."
            logger.error(error)
            if reraise:
                raise
Exemple #14
0
    def move(self, width, height=None, *, wait=False, moved_cb=None,
             timeout=None):
        """
        Set the dimensions of the width/height of the slits gap.

        Parameters
        ---------
        size : float or tuple of float
            Target size for slits in both x and y axis. If a square gap is
            desired, a single value can be entered. Otherwise, the width and
            height can both be entered, either as separate arguments or as a
            tuple.

        wait : bool, optional
            If `True`, block until move is completed. Defaults to `False`.

        timeout : float, optional
            Maximum time for the motion. If `None` is given, the default value
            of `xwidth` and `ywidth` positioners is used.

        moved_cb : callable, optional
            Function to be run when the operation finishes. This callback
            should not expect any arguments or keywords.

        Returns
        -------
        status : AndStatus
            Logical combination of the request to both horizontal and vertical
            motors.
        """

        # Check for missing size
        if width is None and height is None:
            raise TypeError("move() missing 1 required positional "
                            "argument: 'width'")
        elif width is None:
            width = height
        # Check for rectangular setpoint
        elif isinstance(width, tuple):
            (width, height) = width
        elif height is None:
            height = width
        # Instruct both width and height then combine the output status
        x_stat = self.xwidth.move(width, wait=False, timeout=timeout)
        y_stat = self.ywidth.move(height, wait=False, timeout=timeout)
        status = x_stat & y_stat
        # Add our callback if one was given
        if moved_cb is not None:
            status.add_callback(moved_cb)
        # Wait if instructed to do so. Stop the motors if interrupted
        if wait:
            try:
                status_wait(status)
            except KeyboardInterrupt:
                self.xwidth.stop()
                self.ywidth.stop()
                raise
        return status
Exemple #15
0
def ascan(motor,
          start,
          stop,
          num,
          events_per_point=360,
          record=False,
          controls=None,
          **kwargs):
    """
    Quick re-implementation of old python for the transition
    """
    daq = snd_devices.daq
    events = events_per_point
    status = notepad_scan_status
    status.clean_fields()
    if controls is None:
        controls = {}
    start_pos = motor.position

    def get_controls(motor, extra_controls):
        out_arr = {motor.name: motor}
        out_arr.update(extra_controls)
        return out_arr

    try:
        scan_controls = get_controls(motor, controls)
        daq.configure(record=record, controls=scan_controls)

        status.isscan.put(1)
        status.nshots.put(events_per_point)
        status.nsteps.put(num)
        status.var0.put(motor.name)
        status.var0_max.put(max((start, stop)))
        status.var0_min.put(min((start, stop)))

        for i, step in enumerate(np.linspace(start, stop, num)):
            logger.info('Beginning step {}'.format(step))
            try:
                mstat = motor.set(step, verify_move=False, **kwargs)
            except TypeError:
                mstat = motor.set(step, **kwargs)
            status.istep.put(i)
            status_wait(mstat)
            scan_controls = get_controls(motor, controls)
            daq.begin(events=events, controls=scan_controls)
            logger.info('Waiting for {} events ...'.format(events))
            daq.wait()
    finally:
        logger.info('DONE!')
        status.clean_fields()
        daq.end_run()
        daq.disconnect()
        try:
            motor.set(start_pos, verify_move=False, **kwargs)
        except TypeError:
            motor.set(start_pos, **kwargs)
Exemple #16
0
 def _wait(self, sig, *goals):
     """
     Helper function to wait for a signal to reach a value. This is used
     here because most commands are only valid when mode is IDLE.
     """
     def cb(value, *args, **kwargs):
         logger.debug((value, goals))
         return value in goals
     status = SubscriptionStatus(sig, cb)
     status_wait(status)
    def move(self, *args, wait=None, moved_cb=None, timeout=None, **kwargs):

        st = self.set(*args, **kwargs)
        import functools
        from ophyd.status import wait as status_wait
        if moved_cb is not None:
            st.add_callback(functools.partial(moved_cb, obj=self))
        if wait:
            status_wait(st)
        return st
Exemple #18
0
def test_stopper_motion():
    stopper = fake_stopper()
    # Check the status object
    status = stopper.close(wait=False)
    stopper.open_limit._read_pv.put(0)
    stopper.closed_limit._read_pv.put(1)
    status_wait(status, timeout=1)
    assert status.done and status.success
    # Remove
    stopper.open(wait=False)
    # Check write PV
    assert stopper.command.value == stopper.commands.open_valve.value
Exemple #19
0
    def focus_at(self, value=None, wait=False, timeout=None, **kwargs):
        """
        Calculate a combination and insert the lenses

        Parameters
        ----------
        value: float, optional
            Chosen focal plane. Nominal sample by default

        wait : bool, optional
            Wait for the motion of the transfocator to complete

        timeout: float, optional
            Timeout for motion

        kwargs:
            All passed to :meth:`.find_best_combo`

        Returns
        -------
        StateStatus
            Status that represents whether the move is complete
        """
        # Find the best combination of lenses to match the target image
        plane = value or self.nominal_sample
        best_combo = self.find_best_combo(target=plane, **kwargs)
        # Collect status to combine
        statuses = list()
        # Only tell one XRT lens to insert
        prefocused = False
        for lens in self.xrt_lenses:
            if lens in best_combo.lenses:
                statuses.append(lens.insert(timeout=timeout))
                prefocused = True
                break
        # If we have no XRT lenses one remove will do
        if not prefocused:
            statuses.append(self.xrt_lenses[0].remove(timeout=timeout))
        # Ensure all Transfocator lenses are correct
        for lens in self.tfs_lenses:
            if lens in best_combo.lenses:
                statuses.append(lens.insert(timeout=timeout))
            else:
                statuses.append(lens.remove(timeout=timeout))
        # Conglomerate all status objects
        status = statuses.pop(0)
        for st in statuses:
            status = status & st
        # Wait if necessary
        if wait:
            status_wait(status, timeout=timeout)
        return status
Exemple #20
0
    def wait(self, timeout=None):
        """
        Pause the thread until the DAQ is done aquiring.

        Parameters
        ----------
        timeout: ``float``
            Maximum time to wait in seconds.
        """
        logger.debug('Daq.wait()')
        if self.state == 'Running':
            status = self._get_end_status()
            status_wait(status, timeout=timeout)
Exemple #21
0
    def move(self, size, wait=False, moved_cb=None, timeout=None):
        """
        Set the dimensions of the width/height of the gap to width paramater.

        Parameters
        ---------
        size : ``float``, tuple
            Target size for slits in both x and y axis. Either specify as a
            tuple for a rectangular aperture (width, height) or set both with
            single floating point value to use set a square width

        wait : ``bool``
            If true, block until move is completed


        timeout: ``float``, optional
            Maximum time for the motion. If None is given, the default value of
            `xwidth` and `ywidth` positioners is used.

        moved_cb: ``callable``, optional
            Function to be run when the operation finishes. This callback
            should not expect any arguments or keywords

        Returns
        -------
        status : ``AndStatus``
            Logical combination of the request to both horizontal and vertical
            motors
        """
        # Check for rectangular setpoint
        if isinstance(size, tuple):
            (width, height) = size
        else:
            width, height = size, size
        # Instruct both width and height then combine the output status
        x_stat = self.xwidth.move(width, wait=False, timeout=timeout)
        y_stat = self.ywidth.move(height, wait=False, timeout=timeout)
        status = x_stat & y_stat
        # Add our callback if one was given
        if moved_cb is not None:
            status.add_callback(moved_cb)
        # Wait if instructed to do so. Stop the motors if interrupted
        if wait:
            try:
                status_wait(status)
            except KeyboardInterrupt:
                self.xwidth.stop()
                self.ywidth.stop()
                raise
        return status
Exemple #22
0
    def wait(self, status=None):
        """
        Waits for the status objects to complete the motions.

        Parameters
        ----------
        status : list or None, optional
            List of status objects to wait on. If None, will wait on the
            internal status list.
        """
        status = status or self._status
        logger.info("Waiting for the motors to finish moving...")
        status_wait(status)
        logger.info("Move completed.")
Exemple #23
0
    def remove_dia(self, moved_cb=None, timeout=None, wait=False):
        """Remove all diagnostic components."""
        logger.debug('Removing %s diagnostics', self.name)
        status = NullStatus()
        for dia in (self.yag, self.dectris, self.diode, self.foil):
            status = status & dia.remove(timeout=timeout, wait=False)

        if moved_cb is not None:
            status.add_callback(functools.partial(moved_cb, obj=self))

        if wait:
            status_wait(status)

        return status
Exemple #24
0
    def clear(self, wait=False, timeout=None, passive=False, ignore=None):
        """
        Clear the beampath of all obstructions

        Parameters
        ----------
        wait : bool
            Wait for all devices to complete their motion

        timeout : float, optional
            Duration to wait for device movements

        ignore: device or iterable, optional
            Leave devices in their current state without removing them

        passive : bool, optional
            If False, devices that are inserted but don't attenuate the beam
            below :attr:`.minimum_threshold` are ignored

        Returns
        -------
        statuses :
            Returns list of status objects returned by
            :meth:`.LightInterface.remove`
        """
        logger.info('Clearing beampath %s ...', self)
        # Assemble device list
        target_devices, ignored = self._ignore(ignore, passive=passive)
        # Remove devices
        logger.info('Removing devices along the beampath ...')
        status = [
            device.remove(timeout=timeout) for device in target_devices
            if find_device_state(device) in (
                DeviceState.Inserted,
                DeviceState.Unknown) and hasattr(device, 'remove')
        ]
        # Wait parameters
        if wait:
            logger.info(
                'Waiting for all devices to be '
                'removed from the beampath %s ...', self)
            # Wait consecutively for statuses, this can be done by combining
            # statuses in the future
            for s in status:
                logger.debug('Waiting for %s to be done ...', s)
                status_wait(s, timeout=timeout)
                logger.info('Completed')

        return status
Exemple #25
0
def test_misc(daq, sig):
    """
    Blatant coverage-grab
    """
    logger.debug('test_misc')
    daq.configure(controls=dict(sig=sig))
    daq_module.pydaq = None
    with pytest.raises(ImportError):
        daq_module.Daq()
    end_status = daq._get_end_status()
    status_wait(end_status)
    daq.begin(duration=10)
    # Interrupt run with new run and we don't time out
    daq.begin(events=12)
    daq.wait()
Exemple #26
0
def fake_move_transition(att, status, goal):
    """
    Set to the PVs sort of like it would happen in the real world and check the
    status
    """
    # Set status to "MOVING"
    att.done.sim_put(1)
    # Set transmission to the goal
    att.readback.sim_put(goal)
    # Set status to "OK"
    att.done.sim_put(0)
    # Check that the object responded properly
    status_wait(status, timeout=1)
    assert status.done
    assert status.success
Exemple #27
0
    def move_3d(self, x, y, z, *, timeout=None, wait=False):
        """Move to given (x,y,z) coordinate."""
        # Move each motor to the corresponding position and collect the status
        # objects in a list
        status_list = [
            motor.move(val, timeout=timeout, wait=False)
            for motor, val in zip(self.motors, (x, y, z))
        ]

        # Reduce the list to a single AndStatus
        status = reduce(lambda s1, s2: s1 & s2, status_list)

        if wait:
            status_wait(status)
        return status
Exemple #28
0
    def move(self, position, **kwargs):
        # Just changes the sample temperature if not tracking vaporizer.
        if self.parent.track_vaporizer.get() is False:
            return super().move(position, **kwargs)

        wait = kwargs.pop('wait', True)
        sample_status = super().move(position, wait=False, **kwargs)

        vaporizer_position = self._get_vaporizer_position(position)
        # Will not wait for vaporizer.
        _ = self.root.loop1.move(vaporizer_position, wait=False, **kwargs)

        if wait:
            status_wait(sample_status)

        return sample_status
Exemple #29
0
    def wait(self, timeout=None):
        """
        Pause the thread until the DAQ is done aquiring.

        Parameters
        ----------
        timeout: ``float``
            Maximum time to wait in seconds.
        """
        logger.debug('Daq.wait()')
        if self.state == 'Running':
            if self._events or self._duration:
                status = self._get_end_status()
                status_wait(status, timeout=timeout)
            else:
                raise RuntimeError('Cannot wait, daq configured to run '
                                   'forever.')
def test_ims_reinitialize(fake_ims):
    logger.debug('test_ims_reinitialize')
    m = fake_ims
    # Do not reinitialize on auto-setup
    m.auto_setup()
    assert m.reinit_command.get() == 0
    # Check that we reinitialize
    m.error_severity.sim_put(3)
    st = m.reinitialize(wait=False)
    assert m.reinit_command.get() == 1
    # Status should not be complete until reinitialize is done
    assert not st.done
    assert not st.success
    # When error severity is no longer 3 we are reinitialized
    m.error_severity.sim_put(0)
    status_wait(st)
    assert st.done
    assert st.success