def my_list_grid_scan(detector: tp.Any,
                      *args,
                      acquire_time: float,
                      images_per_set: int,
                      wait_for_step: float = 0.,
                      wait_for_shutter: float = 0.5,
                      md: dict = None) -> tp.Generator:
    """Configure detector and run a list_grid_scan with shutter control and wait for seconds at each step."""
    if not md:
        md = {}

    def per_step(detectors, step: dict, pos_cache: dict):
        _motors = step.keys()
        yield from my_move_per_step(step, pos_cache)
        yield from bps.sleep(wait_for_step)
        yield from open_shutter_stub()
        yield from bps.sleep(wait_for_shutter)
        yield from bps.trigger_and_read(list(detectors) + list(_motors))
        yield from close_shutter_stub()

    plan = bp.list_grid_scan([detector], *args, per_step=per_step, md=md)
    motors = list(args[::2])
    plan = bpp.subs_wrapper(plan, LiveTable([detector] + motors))

    yield from configure_cam_detector(detector, acquire_time, images_per_set)
    return (yield from plan)
Beispiel #2
0
def test_list_grid_scan(RE, hw):
    expected_data = []
    for motor1_pos in [6, 7, 8]:
        for motor2_pos in [18, 28, 38]:
            expected_data.append({
                'motor2': motor2_pos,
                'motor2_setpoint': motor2_pos,
                'det': 1.0,
                'motor1': motor1_pos,
                'motor1_setpoint': motor1_pos
            })
    scan = bp.list_grid_scan([hw.det], hw.motor1, [6, 7, 8], hw.motor2,
                             [18, 28, 38])
    multi_traj_checker(RE, scan, expected_data)
Beispiel #3
0
def serp_seq_scan(shift_motor, shift_pts, fly_motor, fly_pts, seq):
    """
    Serpentine scan that triggers the event sequencer on every row.

    Parameters
    ----------
    shift_motor: Positioner
        The column axis to shift to the next fly scan row

    shift_pts:  list of floats
        The positions of the rows to scan down, e.g. [0, 1, 2, 3 ...],
        np.arange(0, 100, 1000), etc.

    fly_motor: Positioner
        The row axis to do fly collection on

    fly_pts: list of 2 floats
        The positions to fly between, e.g. [0, 100]

    seq: Sequencer
        The sequencer to start on each row.
    """
    if len(fly_pts) != 2:
        raise ValueError('Expected fly_pts to have exactly 2 points!')

    is_seq_step = False
    #is_seq_step = True

    def per_step(detectors, step, pos_cache):
        """
        Override default per_step to start the sequencer on each row.

        The first move is not a fly scan move: it moves us into the start
        position. The second move is, as is the fourth, sixth...
        """
        nonlocal is_seq_step
        if is_seq_step:
            yield from trigger(seq)
            is_seq_step = False
        else:
            is_seq_step = True
        yield from one_nd_step(detectors, step, pos_cache)

    return (yield from list_grid_scan([],
                                      shift_motor, shift_pts,
                                      fly_motor, fly_pts,
                                      snake_axes=True,
                                      per_step=per_step))
def xpdacq_list_grid_scan_with_dark(
        detectors: list,
        *args,
        snake_axes: typing.Union[bool, typing.Iterable[bool], None] = None,
        per_step: typing.Callable = xpdacq_per_step,
        md: typing.Union[dict, None] = None):
    """
    Scan over a mesh; each motor is on an independent trajectory. If there is a change in the position of the
    slow motor, take a dark image.

    Parameters
    ----------
    detectors: list
        list of 'readable' objects
    args: list
        patterned like (``motor1, position_list1,``
                        ``motor2, position_list2,``
                        ``motor3, position_list3,``
                        ``...,``
                        ``motorN, position_listN``)

        The first motor is the "slowest", the outer loop. ``position_list``'s
        are lists of positions, all lists must have the same length. Motors
        can be any 'settable' object (motor, temp controller, etc.).
    snake_axes: boolean or iterable, optional
        which axes should be snaked, either ``False`` (do not snake any axes),
        ``True`` (snake all axes) or a list of axes to snake. "Snaking" an axis
        is defined as following snake-like, winding trajectory instead of a
        simple left-to-right trajectory.The elements of the list are motors
        that are listed in `args`. The list must not contain the slowest
        (first) motor, since it can't be snaked.
    per_step: callable, optional
        hook for customizing action of inner loop (messages per step).
        See docstring of :func:`bluesky.plan_stubs.one_nd_step` (the default)
        for details.
    md: dict, optional
        metadata
    """
    if args:
        slow_motor = args[0]
        per_step = slow_dark_wrapper(per_step, slow_motor)
    yield from bp.list_grid_scan(detectors,
                                 *args,
                                 snake_axes=snake_axes,
                                 per_step=per_step,
                                 md=md)
Beispiel #5
0
def test_list_grid_scan_snake_list(RE, hw):
    expected_data = []
    for motor1_pos in [6, 7, 8]:
        if motor1_pos == 7:
            motor2_list = [38, 28, 18]
        else:
            motor2_list = [18, 28, 38]
        for motor2_pos in motor2_list:
            expected_data.append({
                'motor2': motor2_pos,
                'motor2_setpoint': motor2_pos,
                'det': 1.0,
                'motor1': motor1_pos,
                'motor1_setpoint': motor1_pos
            })

    scan = bp.list_grid_scan([hw.det],
                             hw.motor1, [6, 7, 8],
                             hw.motor2, [18, 28, 38],
                             snake_axes=[hw.motor2])
    multi_traj_checker(RE, scan, expected_data)
Beispiel #6
0
    def list2scan(self, m1, p1, m2, p3, nEvents, record=None, use_l3t=False, post=False):
        self.cleanup_RE()
        currPos1 = m1.wm()
        currPos2 = m2.wm()
        daq.configure(nEvents, record=record, controls=[m1,m2], use_l3t=use_l3t)
        try:
            RE(list_grid_scan([daq], m1,p1,m2,p3))
        except Exception:
            logger.debug('RE Exit', exc_info=True)
        finally:
            self.cleanup_RE()
        m1.mv(currPos1)
        m2.mv(currPos2)

        if post:
            run = get_run()
            message = 'grid scan with {name1} from {min1:.3f} to {max1:.3f} in {num1} steps, and {name2} from {min2:.3f} to {max2:.3f} in {num2} steps'.format(name1=m1.name,
                        min1=p1[0],max1=p1[-1],
                        num1=p1.size, name2=m2.name, 
                        min2=p2[0],max2=p2[-1],num2=p2.size)
            self.elog.post(message,run=int(run))
from bluesky.plans import list_grid_scan
from ophyd.sim import det4, motor1, motor2
dets = [det4]
RE(list_grid_scan(dets, motor1, [1, 1, 2, 3, 5], motor2, [25, 16, 9]))
def test_simple_list_grid_scan():
    RE = RunEngine()
    hardware = yaqc_bluesky.Device(39424)
    sensor = yaqc_bluesky.Device(39425)
    lis = [-10, -8, 4, 2, 10]
    RE(list_grid_scan([sensor], hardware, lis))