def mvr(*args, group=None, **kwargs): """ Move one or more devices to a relative setpoint. Wait for all to complete. If more than one device is specified, the movements are done in parallel. Parameters ---------- args : device1, value1, device2, value2, ... group : string, optional Used to mark these as a unit to be waited on. kwargs : passed to obj.set() Yields ------ msg : Msg See Also -------- :func:`bluesky.plan_stubs.rel_set` :func:`bluesky.plan_stubs.mv` """ objs = [] for obj, val in partition(2, args): objs.append(obj) from .preprocessors import relative_set_decorator @relative_set_decorator(objs) def inner_mvr(): return (yield from mv(*args, group=group, **kwargs)) return (yield from inner_mvr())
def mvr(*args, **kwargs): """ Move one or more devices to a relative setpoint. Wait for all to complete. If more than one device is specified, the movements are done in parallel. This is a local version of `bluesky.plan_stubs.mvr`. Parameters ---------- args : device1, value1, device2, value2, ... kwargs : passed to bluesky.plan_stub.mvr Yields ------ msg : Msg See Also -------- :func:`bluesky.plan_stubs.rel_set` :func:`bluesky.plan_stubs.mv` """ objs = [] for obj, _ in partition(2, args): objs.append(obj) @relative_set_decorator(objs) def _inner_mvr(): return (yield from mv(*args, **kwargs)) return (yield from _inner_mvr())
def chunk_outer_product_args(args): '''Scan over a mesh; each motor is on an independent trajectory. Parameters ---------- args patterned like (``motor1, start1, stop1, num1,``` ``motor2, start2, stop2, num2, snake2,`` ``motor3, start3, stop3, num3, snake3,`` ... ``motorN, startN, stopN, numN, snakeN``) The first motor is the "slowest", the outer loop. For all motors except the first motor, there is a "snake" argument: a boolean indicating whether to following snake-like, winding trajectory or a simple left-to-right trajectory. See Also -------- `bluesky.plan_patterns.outer_product` Yields ------ (motor, start, stop, num, snake) ''' args = list(args) # The first (slowest) axis is never "snaked." Insert False to # make it easy to iterate over the chunks or args.. args.insert(4, False) if len(args) % 5 != 0: raise ValueError("Wrong number of positional arguments " "for 'chunk_outer_product_args'") yield from partition(5, args)
def mv(*args): """ Move one or more devices to a setpoint. Wait for all to complete. If more than one device is specifed, the movements are done in parallel. Parameters ---------- args : device1, value1, device2, value2, ... Yields ------ msg : Msg See Also -------- :func:`bluesky.plan_stubs.abs_set` :func:`bluesky.plan_stubs.mvr` """ group = str(uuid.uuid4()) status_objects = [] cyl = reduce(operator.add, [cycler(obj, [val]) for obj, val in partition(2, args)]) step, = utils.merge_cycler(cyl) for obj, val in step.items(): ret = yield Msg('set', obj, val, group=group) status_objects.append(ret) yield Msg('wait', None, group=group) return tuple(status_objects)
def inner_product(num, args): '''Scan over one multi-motor trajectory. Parameters ---------- num : integer number of steps args : list of {Positioner, Positioner, int} patterned like (``motor1, start1, stop1, ..., motorN, startN, stopN``) Motors can be any 'setable' object (motor, temp controller, etc.) Returns ------- cyc : cycler ''' if len(args) % 3 != 0: raise ValueError("Wrong number of positional arguments for " "'inner_product'") cyclers = [] for motor, start, stop, in partition(3, args): steps = np.linspace(start, stop, num=num, endpoint=True) c = cycler(motor, steps) cyclers.append(c) return functools.reduce(operator.add, cyclers)
def inner_list_product(args): '''Scan over one multi-motor trajectory. Parameters ---------- args : list patterned like (``motor1, position_list1,`` ``...,`` ``motorN, position_listN``) Motors can be any 'settable' object (motor, temp controller, etc.) ``position_list``'s are lists of positions, all lists must have the same length. Returns ------- cyc : cycler ''' if len(args) % 2 != 0: raise ValueError("Wrong number of positional arguments for " "'inner_list_product'") cyclers = [] for motor, pos_list, in partition(2, args): c = cycler(motor, pos_list) cyclers.append(c) return functools.reduce(operator.add, cyclers)
def mv(*args, group=None, **kwargs): """ Move one or more devices to a setpoint. Wait for all to complete. If more than one device is specified, the movements are done in parallel. Parameters ---------- args : device1, value1, device2, value2, ... group : string, optional Used to mark these as a unit to be waited on. kwargs : passed to obj.set() Yields ------ msg : Msg See Also -------- :func:`bluesky.plan_stubs.abs_set` :func:`bluesky.plan_stubs.mvr` """ group = group or str(uuid.uuid4()) status_objects = [] cyl = reduce(operator.add, [cycler(obj, [val]) for obj, val in partition(2, args)]) (step,) = utils.merge_cycler(cyl) for obj, val in step.items(): ret = yield Msg('set', obj, val, group=group, **kwargs) status_objects.append(ret) yield Msg('wait', None, group=group) return tuple(status_objects)
def d2scan(*args, time=None, md=None): """ Scan over one multi-motor trajectory relative to current positions. Parameters ---------- *args patterned like (``motor1, start1, stop1,`` ..., ``motorN, startN, stopN, intervals``) where 'intervals' in the number of strides (number of points - 1) Motors can be any 'setable' object (motor, temp controller, etc.) time : float, optional applied to any detectors that have a `count_time` setting md : dict, optional metadata """ if len(args) % 3 != 1: raise ValueError("wrong number of positional arguments") motors = [] for motor, start, stop, in partition(3, args[:-1]): motors.append(motor) intervals = list(args)[-1] num = 1 + intervals inner = inner_spec_decorator('d2scan', time, motors=motors)(relative_inner_product_scan) return (yield from inner(gs.DETS, num, *(args[:-1]), md=md))
def mvr(*args): """ Move one or more devices to a relative setpoint. Wait for all to complete. If more than one device is specifed, the movements are done in parallel. Parameters ---------- args : device1, value1, device2, value2, ... Yields ------ msg : Msg See Also -------- :func:`bluesky.plan_stubs.rel_set` :func:`bluesky.plan_stubs.mv` """ objs = [] for obj, val in partition(2, args): objs.append(obj) from .preprocessors import relative_set_decorator @relative_set_decorator(objs) def inner_mvr(): return (yield from mv(*args)) return (yield from inner_mvr())
def mvr(*args): """ Move one or more devices to a relative setpoint. Wait for all to complete. If more than one device is specifed, the movements are done in parallel. Parameters ---------- args : device1, value1, device2, value2, ... Yields ------ msg : Msg See Also -------- :func:`bluesky.plans.rel_set` :func:`bluesky.plans.mv` """ objs = [] for obj, val in partition(2, args): objs.append(obj) from .preprocessors import relative_set_decorator @relative_set_decorator(objs) def inner_mvr(): return (yield from mv(*args)) return (yield from inner_mvr())
def mv(*args): """ Move one or more devices to a setpoint. Wait for all to complete. If more than one device is specifed, the movements are done in parallel. Parameters ---------- args : device1, value1, device2, value2, ... Yields ------ msg : Msg See Also -------- :func:`bluesky.plans.abs_set` :func:`bluesky.plans.mvr` """ group = str(uuid.uuid4()) status_objects = [] cyl = reduce(operator.add, [cycler(obj, [val]) for obj, val in partition(2, args)]) step, = utils.merge_cycler(cyl) for obj, val in step.items(): ret = yield Msg('set', obj, val, group=group) status_objects.append(ret) yield Msg('wait', None, group=group) return tuple(status_objects)
def chunk_outer_product_args(args): '''Scan over a mesh; each motor is on an independent trajectory. Parameters ---------- args patterned like (``motor1, start1, stop1, num1,``` ``motor2, start2, stop2, num2, snake2,`` ``motor3, start3, stop3, num3, snake3,`` ... ``motorN, startN, stopN, numN, snakeN``) The first motor is the "slowest", the outer loop. For all motors except the first motor, there is a "snake" argument: a boolean indicating whether to following snake-like, winding trajectory or a simple left-to-right trajectory. See Also -------- `bluesky.plan_patterns.outer_product` Yields ------ (motor, start, stop, num, snake) ''' args = list(args) # The first (slowest) axis is never "snaked." Insert False to # make it easy to iterate over the chunks or args.. args.insert(4, False) if len(args) % 5 != 0: raise ValueError("wrong number of positional arguments") yield from partition(5, args)
def outer_list_product(args, snake_axes): '''Scan over a mesh; each motor is on an independent trajectory. Parameters ---------- args 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. . snake_axes 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. See Also -------- :func:`bluesky.plan_patterns.inner_list_product` Returns ------- cyc : cycler ''' snaking = [] cyclers = [] for motor, pos_list in partition(2, args): if not snake_axes: snaking.append(False) elif isinstance(snake_axes, collections.abc.Iterable): if motor in snake_axes: snaking.append(True) else: snaking.append(False) elif snake_axes: if not snaking: snaking.append(False) else: snaking.append(True) else: raise ValueError('The snake_axes arg to ``outer_list_product`` ' 'must be either "False" (do not snake any axes), ' '"True" (snake all axes) or a list of axes to ' 'snake. Instead it is {}.'.format(snake_axes)) c = cycler(motor, pos_list) cyclers.append(c) return snake_cyclers(cyclers, snaking)
def mesh(*args, time=None, md=None): """ Scan over a mesh; each motor is on an independent trajectory. Parameters ---------- *args patterned like (``motor1, start1, stop1, num1,``` ``motor2, start2, stop2, num2,,`` ``motor3, start3, stop3, num3,,`` ... ``motorN, startN, stopN, numN,``) The first motor is the "slowest", the outer loop. md : dict, optional metadata """ if len(args) % 4 != 0: raise ValueError("wrong number of positional arguments") motors = [] shape = [] extents = [] for motor, start, stop, num, in partition(4, args): motors.append(motor) shape.append(num) extents.append([start, stop]) # outer_product_scan expects a 'snake' param for all but fist motor chunked_args = iter(partition(4, args)) new_args = list(next(chunked_args)) for chunk in chunked_args: new_args.extend(list(chunk) + [False]) # shape goes in (rr, cc) # extents go in (x, y) inner = inner_spec_decorator( 'mesh', time, motors=motors, shape=shape, extent=list(chain(*extents[::-1])))(outer_product_scan) return (yield from inner(gs.DETS, *new_args, md=md))
def movr(self, line): if len(line.split()) % 2 != 0: raise TypeError("Wrong parameters. Expected: " "%mov motor position (or several pairs like that)") args = [] for motor, pos in partition(2, line.split()): args.append(eval(motor, self.shell.user_ns)) args.append(eval(pos, self.shell.user_ns)) plan = bp.mvr(*args) self.RE.waiting_hook = self.pbar_manager self.RE(plan) self.RE.waiting_hook = None self._ensure_idle() return None
def inner_product(num, args): '''Scan over one multi-motor trajectory. Parameters ---------- num : integer number of steps args : list of {Positioner, Positioner, int} patterned like (``motor1, start1, stop1, ..., motorN, startN, stopN``) Motors can be any 'setable' object (motor, temp controller, etc.) Returns ------- cyc : cycler ''' if len(args) % 3 != 0: raise ValueError("wrong number of positional arguments") cyclers = [] for motor, start, stop, in partition(3, args): steps = np.linspace(start, stop, num=num, endpoint=True) c = cycler(motor, steps) cyclers.append(c) return functools.reduce(operator.add, cyclers)
def chunk_outer_product_args(args, pattern=None): '''Scan over a mesh; each motor is on an independent trajectory. Parameters ---------- args: iterable Two patterns are supported: Pattern 1: (``motor1, start1, stop1, num1,``` ``motor2, start2, stop2, num2,`` ``motor3, start3, stop3, num3,`` ... ``motorN, startN, stopN, numN``) Pattern 2: (``motor1, start1, stop1, num1,``` ``motor2, start2, stop2, num2, snake2,`` ``motor3, start3, stop3, num3, snake3,`` ... ``motorN, startN, stopN, numN, snakeN``) All elements 'motorX' must be movable objects. There must be no movable objects in the other positions in the list. In Pattern 2, the first motor is the "slowest", the outer loop. For all motors except the first motor, there is a "snakeX" argument: a boolean indicating whether to following snake-like, winding trajectory or a simple left-to-right trajectory. pattern: OuterProductArgsPattern If pattern of 'args' is known, then it can be explicitely specified. In this case the automated recognition of the pattern is not performed and consistency of the argument list is not verified. Use `classify_outer_product_args_pattern` to verify consistency of `args`. See Also -------- `bluesky.plan_patterns.outer_product` `bluesky.plan_patterns.classify_outer_product_args_pattern` Yields ------ (motor, start, stop, num, snake) The `snake` value is always `False` for Pattern 1 ''' if pattern is None: pattern = classify_outer_product_args_pattern(args) else: if not isinstance(pattern, OuterProductArgsPattern): raise ValueError( "The parameter 'pattern' must have type OuterProductArgsPattern: " f"{type(pattern)} ") args = list(args) if pattern == OuterProductArgsPattern.PATTERN_1: # Set 'snaked' to False for every motor for n in range(1, int(len(args) / 4) + 1): args.insert(5 * n - 1, False) elif pattern == OuterProductArgsPattern.PATTERN_2: # The first (slowest) axis is never "snaked." Insert False to # make it easy to iterate over the chunks or args.. args.insert(4, False) else: raise RuntimeError(f"Unsupported pattern: {pattern}. This is a bug. " f"You shouldn't have ended up on this branch.") yield from partition(5, args)