Exemple #1
0
    def _stage():

        _heater_status = yield from rd(mag6t.field.switch_heater)

        if _heater_status != 'On':
            # Click current ramp button
            yield from mv(mag6t.field.ramp_button, 1)

            # Wait for the supply current to match the magnet.
            target = yield from rd(mag6t.field.current)
            function = _difference_check(target, tolerance=0.01)
            yield from abs_set(signal,
                               mag6t.field.supply_current,
                               function,
                               wait=True)

            # Turn on persistance switch heater.
            yield from mv(mag6t.field.switch_heater, 'On')
            yield from sleep(2)

            # Wait for the heater to be on.
            function = _status_check(target=[3])
            yield from abs_set(signal,
                               mag6t.field.magnet_status,
                               function,
                               wait=True)

            # Click current ramp button
            yield from mv(mag6t.field.ramp_button, 1)
    def _plan(self):
        yield from bps.open_run()

        # stash numcapture and shutter_enabled
        num_capture = yield from bps.rd(self.device.hdf5.num_capture)
        shutter_enabled = yield from bps.rd(self.device.dg1.shutter_enabled)

        # set to 1 temporarily
        self.device.hdf5.num_capture.put(1)

        # Restage to ensure that dark frames goes into a separate file.
        yield from bps.stage(self.device)
        yield from bps.mv(self.device.dg1.shutter_enabled, 2)
        # The `group` parameter passed to trigger MUST start with
        # bluesky-darkframes-trigger.
        yield from bps.trigger_and_read([self.device], name='dark')
        # Restage.
        yield from bps.unstage(self.device)
        # restore numcapture and shutter_enabled
        yield from bps.mv(self.device.hdf5.num_capture, num_capture)
        yield from bps.mv(self.device.dg1.shutter_enabled, shutter_enabled)

        # Dark frames finished, moving on to data

        yield from bps.stage(self.device)
        status = yield from bps.trigger(self.device, group='primary-trigger')
        while not status.done:
            yield from bps.trigger_and_read(self.async_poll_devices,
                                            name='labview')
            yield from bps.sleep(1)
        yield from bps.create('primary')
        yield from bps.read(self.device)
        yield from bps.save()
        yield from bps.unstage(self.device)
Exemple #3
0
def test_rd_fails(hw):
    require_ophyd_1_4_0()
    obj = hw.det

    obj.noise.kind = "hinted"
    hints = obj.hints.get("fields", [])
    msg = re.escape(
        f"Your object {obj} ({obj.name}.{obj.dotted_name}) "
        + f"has {len(hints)} items hinted ({hints}).  We "
    )
    with pytest.raises(ValueError, match=msg):
        list(bps.rd(obj))

    obj.noise.kind = "normal"
    obj.val.kind = "normal"
    msg = re.escape(
        f"Your object {obj} ({obj.name}.{obj.dotted_name}) "
        + f"and has {len(obj.read_attrs)} read attrs.  We "
    )
    with pytest.raises(ValueError, match=msg):
        list(bps.rd(obj))

    obj.read_attrs = []

    msg = re.escape(
        f"Your object {obj} ({obj.name}.{obj.dotted_name}) "
        + f"and has {len(obj.read_attrs)} read attrs.  We "
    )
    with pytest.raises(ValueError, match=msg):
        list(bps.rd(obj))
def qxscan(edge_energy, time=None, *, detectors=None, md=None,
           dichro=False, lockin=False):
    """
    Scan the beamline energy using variable step size.

    It reads the `qxscan_params` device. Prior to this scan, please run
    `qxscan_params.setup` or load setttings using
    `qxscan_params.load_params_json`.

    Parameters
    ----------
    detectors : list
        list of 'readable' objects
    edge_energy : float
        Energy of the absorption edge.
    md : dict, optional
        metadata
    dichro : boolean, optional
        Flag to run a dichro energy scan. Please run pr_setup.config() prior to
        a dichro scan. Note that this will switch the x-ray polarization at
        every point using the +, -, -, + sequence, thus increasing the number
        of points, and time per energy, by a factor of 4
    lockin : boolean, optional
        Flag to run a lockin energy scan. Please run pr_setup.config() prior to
        a lockin scan.

    See Also
    --------
    :func:`moveE`
    :func:`Escan_list`
    :func:`Escan`
    """

    if not detectors:
        detectors = counters.detectors

    # Scalerd is always selected.
    if scalerd not in detectors:
        scalerd.select_plot_channels([])
        detectors += [scalerd]

    _md = {'plan_args': {'detectors': list(map(repr, detectors)),
                         'edge_energy': repr(edge_energy),
                         'dichro': dichro,
                         'lockin': lockin},
           'plan_name': 'qxscan'
           }

    _md.update(md or {})

    energy_list = yield from rd(qxscan_params.energy_list)
    energy_list = array(energy_list) + edge_energy

    _factor_list = yield from rd(qxscan_params.factor_list)

    return (yield from Escan_list(detectors, energy_list, time,
                                  factor_list=_factor_list, md=_md,
                                  dichro=dichro, lockin=lockin))
Exemple #5
0
    def tester(obj):
        nonlocal called
        direct_read = yield from bps.read(obj)
        rd_read = yield from bps.rd(obj)
        sig_read = yield from bps.rd(obj.val)

        assert rd_read == direct_read["det"]["value"]
        assert sig_read == rd_read
        called = True
Exemple #6
0
def dichro_steps(devices_to_read, take_reading):

    pr_pos = yield from rd(pr_setup.positioner)
    offset = yield from rd(pr_setup.offset)
    devices_to_read += [pr_setup.positioner]
    for sign in pr_setup.dichro_steps:
        yield from mv(pr_setup.positioner, pr_pos + sign * offset)
        yield from take_reading(devices_to_read)

    yield from mv(pr_setup.positioner, pr_pos)
Exemple #7
0
def _collect_extras(escan_flag, fourc_flag):

    extras = counters.extra_devices.copy()

    if escan_flag:
        und_track = yield from rd(undulator.downstream.tracking)
        if und_track:
            extras.append(undulator.downstream.energy)
        for pr in [pr1, pr2, pr3]:
            pr_track = yield from rd(pr.tracking)
            if pr_track:
                extras.append(pr.th)

    if fourc_flag:
        extras.append(fourc)

    return extras
Exemple #8
0
    def setup():
        if count_time < 0:
            if detectors != [scalerd]:
                raise ValueError('count_time can be < 0 only if the scalerd '
                                 'is only detector used.')
            else:
                if scalerd.monitor == 'Time':
                    raise ValueError('count_time can be < 0 only if '
                                     'scalerd.monitor is not "Time".')
                original_times[scalerd] = yield from rd(scalerd.preset_monitor)
                yield from mv(scalerd.preset_monitor, abs(count_time))

        elif count_time > 0:
            for det in detectors:
                if det == scalerd:
                    original_monitor.append(scalerd.monitor)
                    det.monitor = 'Time'
                original_times[det] = yield from rd(det.preset_monitor)
                yield from mv(det.preset_monitor, count_time)
        else:
            raise ValueError('count_time cannot be zero.')
def dark_plan(detector):
    # stash numcapture and shutter_enabled
    num_capture = yield from bps.rd(detector.hdf5.num_capture)
    shutter_enabled = yield from bps.rd(detector.dg1.shutter_enabled)

    # set to 1 temporarily
    detector.hdf5.num_capture.put(1)

    # Restage to ensure that dark frames goes into a separate file.
    yield from bps.unstage(detector)
    yield from bps.stage(detector)
    yield from bps.mv(detector.dg1.shutter_enabled, 2)
    # The `group` parameter passed to trigger MUST start with
    # bluesky-darkframes-trigger.
    yield from bps.trigger(detector, group='bluesky-darkframes-trigger')
    yield from bps.wait('bluesky-darkframes-trigger')
    snapshot = bluesky_darkframes.SnapshotDevice(detector)
    # Restage.
    yield from bps.unstage(detector)
    # restore numcapture and shutter_enabled
    yield from bps.mv(detector.hdf5.num_capture, num_capture)
    yield from bps.mv(detector.dg1.shutter_enabled, shutter_enabled)
    return snapshot
Exemple #10
0
def qxscan(edge_energy,
           time=None,
           detectors=None,
           lockin=False,
           dichro=False,
           fixq=False,
           md=None):
    """
    Energy scan with fixed delta_K steps.

    WARNING: please run qxscan_params.setup() before using this plan! It will
    use the parameters set in qxscan_params to determine the energy points.

    Parameters
    ----------
    edge_energy : float
        Absorption edge energy. The parameters in qxscan_params offset by this
        energy.
    time : float, optional
        If a number is passed, it will modify the counts over time. All
        detectors need to have a .preset_monitor signal.
    detectors : list, optional
        List of detectors to be used in the scan. If None, will use the
        detectors defined in `counters.detectors`.
    lockin : boolean, optional
        Flag to do a lock-in scan. Please run pr_setup.config() prior do a
        lock-in scan
    dichro : boolean, optional
        Flag to do a dichro scan. Please run pr_setup.config() prior do a
        dichro scan. Note that this will switch the x-ray polarization at every
        point using the +, -, -, + sequence, thus increasing the number of
        points by a factor of 4
    fixq : boolean, optional
        Flag for fixQ scans. If True, it will fix the diffractometer hkl
        position during the scan. Note that hkl is moved ~after~ the other
        motors!
    md : dictionary, optional
        Metadata to be added to the run start.

    See Also
    --------
    :func:`bluesky.plans.scan`
    :func:`lup`
    """

    if detectors is None:
        detectors = counters.detectors

    flag.dichro = dichro
    flag.fixq = fixq
    per_step = one_local_step if fixq or dichro else None

    # Get energy argument and extras
    energy_list = yield from rd(qxscan_params.energy_list)
    args = (energy, array(energy_list) + edge_energy)

    extras = yield from _collect_extras(energy in args, "fourc" in str(args))

    # Setup count time
    factor_list = yield from rd(qxscan_params.factor_list)

    # TODO: The md handling might go well in a decorator.
    # TODO: May need to add reference to stream.
    _md = {'hints': {'monitor': counters.monitor, 'detectors': []}}
    for item in detectors:
        _md['hints']['detectors'].extend(item.hints['fields'])

    if dichro:
        _md['hints']['scan_type'] = 'dichro'

    _md.update(md or {})

    _ct = {}
    if time:
        if time < 0 and detectors != [scalerd]:
            raise TypeError('time < 0 can only be used with scaler.')
        else:
            for det in detectors:
                _ct[det] = abs(time)
                args += (det.preset_monitor, abs(time) * array(factor_list))
    else:
        for det in detectors:
            _ct[det] = yield from rd(det.preset_monitor)
            args += (det.preset_monitor, _ct[det] * array(factor_list))

    @configure_counts_decorator(detectors, time)
    @stage_dichro_decorator(dichro, lockin)
    @extra_devices_decorator(extras)
    def _inner_qxscan():
        yield from list_scan(detectors + extras,
                             *args,
                             per_step=per_step,
                             md=_md)

        # put original times back.
        for det, preset in _ct.items():
            yield from mv(det.preset_monitor, preset)

    return (yield from _inner_qxscan())
Exemple #11
0
 def tester(obj, val):
     yield from bps.mv(sig, val)
     ret = yield from bps.rd(obj, default_value=object())
     assert ret == val
Exemple #12
0
 def tester(obj, dflt):
     ret = yield from bps.rd(obj, default_value=dflt)
     assert ret is dflt
def Escan_list(detectors, energy_list, count_time=None, *, factor_list=None,
               md=None, dichro=False, lockin=False):
    """
    Scan the beamline energy using a list of energies.

    Due to the undulator backlash, it is recommended for energy_list to be in
    descending order.

    Parameters
    ----------
    detectors : list
        list of 'readable' objects
    energy_list : iterable
        List of energies to be used
    factor_list: iterable, optional
        Controls the time per point by multiplying the initial count time by
        this factor. Needs to have the same length as energy_list.
    md : dict, optional
        metadata
    dichro : boolean, optional
        Flag to run a dichro energy scan. Please run pr_setup.config() prior to
        a dichro scan. Note that this will switch the x-ray polarization at
        every point using the +, -, -, + sequence, thus increasing the number
        of points, and time per energy, by a factor of 4
    lockin : boolean, optional
        Flag to run a lockin energy scan. Please run pr_setup.config() prior to
        a lockin scan.

    See Also
    --------
    :func:`moveE`
    :func:`Escan`
    :func:`qxscan`
    """
    # Create positioners list
    _positioners = [mono.energy]

    if (yield from rd(undulator.downstream.tracking)):
        _positioners.append(undulator.downstream.energy)
    for pr in [pr1, pr2, pr3]:
        if pr.tracking.get():
            _positioners.append(pr.th)

    for pr in [pr1, pr2, pr3]:
        if (yield from rd(pr.tracking)):
            _positioners.append(pr.th)
            _positioners.append(pr.energy)

    # Controls the time per point.
    if factor_list is None:
        factor_list = [1 for i in range(len(energy_list))]
    else:
        if len(factor_list) != len(energy_list):
            raise ValueError("The size of factor_list cannot be different "
                             "from the size of the energy_list")

    # Metadata
    _md = {'detectors': [det.name for det in detectors],
           'positioners': [pos.name for pos in _positioners],
           'num_points': len(energy_list),
           'num_intervals': len(energy_list) - 1,
           'plan_args': {'detectors': list(map(repr, detectors)),
                         'energy_list': list(map(repr, energy_list))},
           'plan_name': 'Escan_list',
           'hints': {'dimensions': [(['monochromator_energy'], 'primary')]},
           }

    _md.update(md or {})

    # Collects current monitor count for each detector
    dets_preset = []
    for detector in detectors:
        if count_time:
            value = abs(count_time)
        else:
            value = yield from rd(detector.preset_monitor)
        dets_preset.append(value)

    @stage_dichro_decorator(dichro, lockin)
    @configure_counts_decorator(detectors, count_time)
    @run_decorator(md=_md)
    def _inner_Escan_list():
        yield from moveE(energy_list[0]+0.001)
        for energy, factor in zip(energy_list, factor_list):
            # Change counting time
            for detector, original_preset in zip(detectors, dets_preset):
                yield from mv(detector.preset_monitor, factor*original_preset)
            # Move and scan
            grp = short_uid('set')
            yield Msg('checkpoint')
            yield from moveE(energy, group=grp)

            if dichro:
                yield from dichro_steps(detectors, _positioners,
                                        trigger_and_read)
            else:
                yield from trigger_and_read(list(detectors)+_positioners)

    return (yield from _inner_Escan_list())