def MED(init_gas, other_gas, minT, maxT, num_steps, num_steady, num_trans, num_loops=2):
    """
    1. Start flowing the initial gas.
    2. Scan the temperature from minT to maxT in `num_steps` evenly-spaced steps.
    3. Hold temperature at maxT and take  `num_steady` images.
    4. Repeat (2) and (3) `num_loops` times.
    5. Switch the gas to `other_gas` and take `num_trans` acquisitions.
    6. Switch it back and take another `num_trans` acquisitions.

    Example
    -------
    Set the gasses. They can be in any other, nothing to do with
    the order they are used in the plan.
    >>> gas.gas_list = ['O2', 'CO2']

    Optionally, preview the plan.
    >>> print_summary(MED('O2', 'C02', 200, 300, 21, 20, 60))

    Execute it.
    >>> RE(MED('O2', 'C02', 200, 300, 21, 20, 60))

    """
    # Step 1
    yield from abs_set(gas, init_gas)
    # Steps 2 and 3 in a loop.
    for _ in range(num_loops):
        yield from subs_wrapper(scan([pe1, gas.current_gas], eurotherm, minT, maxT, num_steps),
                            LiveTable([eurotherm, gas.current_gas]))
        yield from subs_wrapper(count([pe1], num_steady), LiveTable([]))
    # Step 4
    yield from abs_set(gas, other_gas)
    yield from subs_wrapper(count([pe1], num_steady), LiveTable([]))
    # Step 6
    yield from abs_set(gas, init_gas)
    yield from subs_wrapper(count([pe1], num_steady), LiveTable([]))
Beispiel #2
0
def count_with_calib(detectors: list, num: int = 1, delay: float = None, *, calibration_md: dict = None,
                     md: dict = None) -> typing.Generator:
    """
    Take one or more readings from detectors with shutter control and calibration metadata injection.

    Parameters
    ----------
    detectors : list
        list of 'readable' objects

    num : integer, optional
        number of readings to take; default is 1

        If None, capture data until canceled

    delay : iterable or scalar, optional
        Time delay in seconds between successive readings; default is 0.

    calibration_md :
        The calibration data in a dictionary. If not applied, the function is a normal `bluesky.plans.count`.

    md : dict, optional
        metadata

    Notes
    -----
    If ``delay`` is an iterable, it must have at least ``num - 1`` entries or
    the plan will raise a ``ValueError`` during iteration.
    """
    if md is None:
        md = dict()
    if calibration_md is not None:
        md["calibration_md"] = calibration_md

    def _per_shot(_detectors):
        yield from open_shutter_stub()
        yield from bps.one_shot(_detectors)
        yield from close_shutter_stub()
        return

    prev_state = glbl["auto_load_calib"]
    glbl["auto_load_calib"] = False
    try:
        plan = bp.count(detectors, num, delay, md=md, per_shot=_per_shot)
        bpp.subs_wrapper(plan, LiveTable(detectors))
        sts = yield from plan
    except Exception as error:
        glbl["auto_load_calib"] = prev_state
        raise error
    glbl["auto_load_calib"] = prev_state
    return sts
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 #4
0
def simple_ct(dets, exposure, *, md=None):
    """A minimal wrapper around count that adjusts exposure time."""
    md = md or {}

    # setting up area_detector
    (ad, ) = (d for d in dets if hasattr(d, "cam"))
    (num_frame, acq_time,
     computed_exposure) = yield from configure_area_det(ad, exposure)

    sp = {
        "time_per_frame": acq_time,
        "num_frames": num_frame,
        "requested_exposure": exposure,
        "computed_exposure": computed_exposure,
        "type": "ct",
        "uid": str(uuid.uuid4()),
        "plan_name": "ct",
    }

    # update md
    _md = {"sp": sp, **{f"sp_{k}": v for k, v in sp.items()}}
    _md.update(md)
    plan = bp.count(dets, md=_md)
    plan = bpp.subs_wrapper(plan, LiveTable([]))
    return (yield from plan)
Beispiel #5
0
def learner_callback_plan(dets, motors, learner, goal, **kwargs):
    queue = Queue()
    callback = AdaptiveCallback(learner, goal, queue)

    return (yield from
            bpp.subs_wrapper(intra_plan_learner(dets, motors, queue, **kwargs),
                             callback))
Beispiel #6
0
def escan(start, stop, num, md=None):
    """
    Scan the mono_energy while reading the scaler.

    Parameters
    ----------
    start : number
    stop : number
    num : integer
        number of data points (i.e. number of strides + 1)
    md : dictionary, optional
    """
    dets = [sclr]
    motor = mono.energy
    cols = ['I0', 'fbratio', 'It', 'If_tot']
    x = 'mono_energy'
    fig, axes = plt.subplots(2, sharex=True)

    plan = bp.scan(dets, motor, start, stop, num, md=md)
    plan2 = bpp.subs_wrapper(plan, [
        LiveTable(cols),
        LivePlot('If_tot', x, ax=axes[0]),
        LivePlot('I0', x, ax=axes[1])
    ])
    yield from plan2
Beispiel #7
0
def cryo_test(numpt=5, delay_time=2, preamp_acqtime=0.5):

    det = [
        current_preamp, cryo_v19, cryo_lt19, cryo_pt1, hdcm_Si111_1stXtalrtd,
        hdcm_Si111_2ndXtal_rtd, hdcm_1stXtal_ThermStab_rtd, hdcm_ln2out_rtd,
        hdcm_water_rtd, dBPM_h, dBPM_v, dBPM_t, dBPM_i, dBPM_o, dBPM_b
    ]

    current_preamp.exp_time.put(preamp_acqtime)

    livecallbacks = []
    livetableitem = [
        current_preamp.ch0, current_preamp.ch2, cryo_v19, cryo_lt19, cryo_pt1,
        hdcm_Si111_1stXtalrtd, hdcm_Si111_2ndXtal_rtd,
        hdcm_1stXtal_ThermStab_rtd, hdcm_ln2out_rtd, hdcm_water_rtd, dBPM_h,
        dBPM_v, dBPM_t, dBPM_i, dBPM_o, dBPM_b
    ]
    livecallbacks.append(LiveTable(livetableitem))

    for det_item in livetableitem:
        liveploty = det_item
        liveplotfig = plt.figure(det_item.name)
        livecallbacks.append(LivePlot(liveploty, fig=liveplotfig))

    yield from subs_wrapper(count(det, num=numpt, delay=delay_time),
                            livecallbacks)
Beispiel #8
0
def take_dark():
    """a plan for taking a single dark frame"""
    print("INFO: closing shutter...")
    yield from close_shutter_stub()
    print("INFO: taking dark frame....")
    # upto this stage, area_det has been configured to so exposure time is
    # correct
    area_det = xpd_configuration["area_det"]
    acq_time = area_det.cam.acquire_time.get()
    if hasattr(area_det, 'images_per_set'):
        num_frame = area_det.images_per_set.get()
    else:
        num_frame = 1
    computed_exposure = acq_time * num_frame
    # update md
    _md = {
        "sp_time_per_frame": acq_time,
        "sp_num_frames": num_frame,
        "sp_computed_exposure": computed_exposure,
        "sp_type": "ct",
        "sp_plan_name": "dark_{}".format(computed_exposure),
        "dark_frame": True,
    }
    c = bp.count([area_det], md=_md)
    yield from bpp.subs_wrapper(c, {"stop": [_update_dark_dict_list]})
    # TODO: remove this, since it kinda depends on what happens next?
    print("opening shutter...")
Beispiel #9
0
def take_dark():
    """a plan for taking a single dark frame"""
    print("INFO: closing shutter...")
    yield from bps.abs_set(xpd_configuration.get("shutter"),
                           XPD_SHUTTER_CONF["close"],
                           wait=True)
    print("INFO: taking dark frame....")
    # upto this stage, area_det has been configured to so exposure time is
    # correct
    area_det = xpd_configuration["area_det"]
    acq_time = area_det.cam.acquire_time.get()
    num_frame = area_det.images_per_set.get()
    computed_exposure = acq_time * num_frame
    # update md
    _md = {
        "sp_time_per_frame": acq_time,
        "sp_num_frames": num_frame,
        "sp_computed_exposure": computed_exposure,
        "sp_type": "ct",
        "sp_plan_name": "dark_{}".format(computed_exposure),
        "dark_frame": True,
    }
    c = bp.count([area_det], md=_md)
    yield from bpp.subs_wrapper(c, {"stop": [_update_dark_dict_list]})
    print("opening shutter...")
Beispiel #10
0
    def my_plan():
        motor = hw.motor
        det = hw.det

        motor.delay = 1

        plan = bp.scan([det], motor, -5, 5, 25)
        plan = subs_wrapper(bp.scan([det], motor, -5, 5, 25),
                            LivePlot(det.name, motor.name))
        return (yield from plan)
Beispiel #11
0
def ct(sample, exposure):
    """
    Capture how many exposures are needed to get a total exposure
    of the given value, and sum those into one file before saving.
    """
    pe1c.images_per_set.put(1)
    pe1c.number_of_sets.put(1)
    plan = subs_wrapper(count([pe1c], num=1), LiveTable([]))
    # plan = robot_wrapper(plan, sample)
    yield from plan
Beispiel #12
0
def tomo_xrf_proj_realmotor(xcen,
                            zcen,
                            hstepsize,
                            hnumstep,
                            ycen,
                            ystepsize,
                            ynumstep,
                            dets=[]):
    '''
    collect an XRF 'projection' map at the current angle
    zcen should be defined as the position when the sample is in focus at zero degree; if it is not given, the program should take the current z position
    '''
    theta = tomo_stage.theta.position

    #horizontal axes
    x_motor = tomo_stage.finex_top
    z_motor = tomo_stage.finez_top

    #vertical axis
    y_motor = tomo_stage.finey_top

    #stepsize setup
    xstepsize = hstepsize * numpy.cos(numpy.deg2rad(theta))
    zstepsize = hstepsize * numpy.sin(numpy.deg2rad(theta))

    #start and end point setup

    xstart = xcen - xstepsize * hnumstep / 2
    xstop = xcen + xstepsize * hnumstep / 2

    zstart = zcen - zstepsize * hnumstep / 2
    zstop = zcen + zstepsize * hnumstep / 2

    ystart = ycen - ystepsize * ynumstep / 2
    ystop = ycen + ystepsize * ynumstep / 2

    xlist = numpy.linspace(xstart, xstop,
                           hnumstep + 1)  #some theta dependent function
    zlist = numpy.linspace(zstart, zstop, hnumstep + 1)

    ylist = numpy.linspace(ystart, ystop, ynumstep + 1)

    xz_cycler = cycler(x_motor, xlist) + cycler(z_motor, zlist)
    yxz_cycler = cycler(y_motor, ylist) * xz_cycler

    # The scan_nd plan expects a list of detectors and a cycler.
    plan = scan_nd(dets, yxz_cycler)
    # Optionally, add subscritpions.

    #TO-DO: need to figure out how to add LiveRaster with the new x/z axis
    plan = subs_wrapper(plan, [LiveTable([x_motor, y_motor, z_motor])])
    #                                         LiveMesh(...)]
    scaninfo = yield from plan
    return scaninfo
 def count_dets(_dets, _full_md):
     _count_plan = bp.count(_dets, md=_full_md)
     _count_plan = bpp.subs_wrapper(_count_plan, LiveTable(_dets))
     _count_plan = bpp.finalize_wrapper(
         _count_plan,
         bps.abs_set(xpd_configuration['shutter'],
                     XPD_SHUTTER_CONF['close'],
                     wait=True))
     yield from bps.abs_set(xpd_configuration['shutter'],
                            XPD_SHUTTER_CONF['open'],
                            wait=True)
     yield from _count_plan
Beispiel #14
0
def tseries(sample, exposure, num):
    """
    Capture how ever many exposures are needed to get a total exposure
    of the given value, and divide those into files of 'num' exposures
    each, summed.
    """
    if pe1c.cam.acquire_time.get() != 0.1:
        raise RuntimeError("We expect pe1c.cam.acquire_time to be 0.1")
    pe1c.images_per_set.put(num)
    pe1c.number_of_sets.put(exposure // num)
    plan = subs_wrapper(count([pe1c], num=1), LiveTable([]))
    i  # plan = robot_wrapper(plan, sample)
    yield from plan
Beispiel #15
0
 def cls_plan():
     current_settings = {}
     for key, val in kwargs.items():
         current_settings[key] = getattr(self, key)
         setattr(self, key, val)
     try:
         plan = self._gen()
         plan = bpp.subs_wrapper(plan, subs)
         plan = bpp.stage_wrapper(plan, flyers)
         plan = bpp.fly_during_wrapper(plan, flyers)
         return (yield from plan)
     finally:
         for key, val in current_settings.items():
             setattr(self, key, val)
Beispiel #16
0
def ct(dets, exposure):
    """
    Take one reading from area detector with given exposure time

    Parameters
    ----------
    dets : list
        list of 'readable' objects. default to area detector
        linked to xpdAcq.
    exposure : float
        total time of exposrue in seconds

    Notes
    -----
    area detector being triggered will  always be the one configured
    in global state. To find out which these are, please using
    following commands:

        >>> xpd_configuration['area_det']

    to see which device is being linked
    """

    pe1c, = dets
    md = {}
    # setting up area_detector
    (num_frame, acq_time, computed_exposure) = yield from _configure_area_det(
        exposure
    )
    area_det = xpd_configuration["area_det"]
    # update md
    _md = ChainMap(
        md,
        {
            "sp_time_per_frame": acq_time,
            "sp_num_frames": num_frame,
            "sp_requested_exposure": exposure,
            "sp_computed_exposure": computed_exposure,
            "sp_type": "ct",
            "sp_uid": str(uuid.uuid4()),
            "sp_plan_name": "ct",
        },
    )
    plan = bp.count([area_det], md=_md)
    plan = bpp.subs_wrapper(plan, LiveTable([]))
    yield from plan
def check_tth():
    '''Align the spectrometer rotation angle'''
    yield from bps.mv(geo.det_mode, 1)
    yield from bps.mv(abs2, 6)
    yield from mabt(0, 0, 0)
    tmp1 = geo.tth.position
    print('resetting tth')
    yield from bps.mv(sh, -1)
    yield from bps.mv(shutter, 1)  # open shutter
    local_peaks = PeakStats(tth.user_readback.name,
                            quadem.current3.mean_value.name)
    #yield from bp.rel_scan([quadem],tth,-0.1,0.1,21)
    yield from bpp.subs_wrapper(bp.rel_scan([quadem], tth, -0.1, 0.1, 21),
                                local_peaks)
    tmp2 = local_peaks.cen  #get the height for roi2 of quadem with a max intens
    yield from bps.mv(tth, tmp2)
    yield from set_tth(tmp1)
    yield from bps.mv(shutter, 0)  # close shutter
def check_astth(detector=lambda_det):
    '''Align the detector arm rotation angle'''
    yield from bps.mv(geo.det_mode, 1)
    yield from bps.mv(abs2, 6)
    yield from mabt(0.0, 0.0, 0)
    tmp1 = geo.astth.position
    yield from bps.mvr(sh, -1)
    print('setting astth')
    yield from bps.mv(shutter, 1)  # open shutter
    #    yield from bp.rel_scan([detector],astth,-0.1,0.1,21)
    #   tmp2=peaks.cen['%s_stats2_total'%detector.name]
    local_peaks = PeakStats(astth.user_readback.name,
                            '%s_stats2_total' % detector.name)
    yield from bpp.subs_wrapper(bp.rel_scan([detector], astth, -0.1, 0.1, 21),
                                local_peaks)
    tmp2 = local_peaks.cen  #get the height for roi2 of detector.name with max intens
    yield from bps.mv(astth, tmp2)
    yield from bps.mv(shutter, 0)  # close shutter
    yield from set_astth(tmp1)
Beispiel #19
0
def test_interrupted_with_callbacks(RE, int_meth, stop_num, msg_num):

    docs = defaultdict(list)

    def collector_cb(name, doc):
        nonlocal docs
        docs[name].append(doc)

    RE.msg_hook = MsgCollector()

    with pytest.raises(RunEngineInterrupted):
        RE(subs_wrapper(run_wrapper(pause()), {"all": collector_cb}))
    getattr(RE, int_meth)()

    assert len(docs["start"]) == 1
    assert len(docs["event"]) == 0
    assert len(docs["descriptor"]) == 0
    assert len(docs["stop"]) == stop_num
    assert len(RE.msg_hook.msgs) == msg_num
Beispiel #20
0
def test_interrupted_with_callbacks(RE, int_meth, stop_num, msg_num):

    docs = defaultdict(list)

    def collector_cb(name, doc):
        nonlocal docs
        docs[name].append(doc)

    RE.msg_hook = MsgCollector()

    with pytest.raises(RunEngineInterrupted):
        RE(subs_wrapper(run_wrapper(pause()), {"all": collector_cb}))
    getattr(RE, int_meth)()

    assert len(docs["start"]) == 1
    assert len(docs["event"]) == 0
    assert len(docs["descriptor"]) == 0
    assert len(docs["stop"]) == stop_num
    assert len(RE.msg_hook.msgs) == msg_num
def check_ih():
    '''Align the Align the spectrometer stage height
    '''
    yield from bps.mv(geo.det_mode, 1)  #move lamda detector in ?
    yield from bps.mv(abs2, 6)  #move the second absorber in
    yield from mabt(0, 0, 0)  # don't understand???,
    yield from bps.mv(sh, -1)  # move the Sample vertical translation to -1
    yield from bps.mv(shutter, 1)  # open shutter
    print('resetting ih')
    #yield from bp.rel_scan([quadem],ih,-0.15,0.15,16)  #scan the quadem detector against XtalDfl-height
    #tmp=peaks.cen['quadem_current3_mean_value']  #get the height for roi2 of quadem with a max intensity
    local_peaks = PeakStats(ih.user_readback.name,
                            quadem.current3.mean_value.name)
    yield from bpp.subs_wrapper(bp.rel_scan([quadem], ih, -0.15, 0.15, 16),
                                local_peaks)
    tmp = local_peaks.cen  #get the height for roi2 of quadem with a max intens
    yield from bps.mv(ih, tmp)  #move the XtalDfl to this height
    yield from set_ih(0)  #set this height as 0
    yield from bps.mv(shutter, 0)  # close shutter
Beispiel #22
0
def config_det_and_count(motors: List[object], sample_md: dict, exposure: float):
    """
    Take one reading from area detector with given exposure time and motors. Save the motor reading results in
    the start document.

    Parameters
    ----------
    motors : List[float]
        A list of readable motors.
    sample_md
        The metadata of the sample.
    exposure
        The exposure time in seconds.

    Yields
    -------
        Message to configure the detector and run the scan.

    """
    # setting up area_detector
    _md = {}
    num_frame, acq_time, computed_exposure = yield from _configure_area_det(exposure)
    area_det = xpd_configuration["area_det"]
    # update md
    _md.update(**sample_md)
    plan_md = {
        "sp_time_per_frame": acq_time,
        "sp_num_frames": num_frame,
        "sp_requested_exposure": exposure,
        "sp_computed_exposure": computed_exposure,
        "sp_type": "cryostat",
        "sp_uid": str(uuid.uuid4()),
        "sp_plan_name": "cryostat"
    }
    _md.update(**plan_md)
    motor_md = {motor.name: dict(motor.read()) for motor in motors}
    _md.update(**motor_md)
    # yield plan
    dets = [area_det] + motors
    plan = count(dets, md=_md)
    plan = subs_wrapper(plan, LiveTable([]))
    yield from plan
def check_sh_coarse(value=0, detector=lambda_det):
    '''
    Aligh the sample height
    '''
    yield from bps.mv(geo.det_mode, 1)
    yield from bps.mv(abs2, 6)
    yield from mabt(value, value, 0)
    tmp1 = geo.sh.position
    #Msg('reset_settle_time', sh.settle_time, 2)
    print('Start the height scan before GID')
    #    yield from bp.rel_scan([detector],sh,-1,1,21,per_step=shutter_flash_scan)
    #    tmp2=peaks.cen['%s_stats2_total'%detector.name]
    local_peaks = PeakStats(sh.user_readback.name,
                            '%s_stats2_total' % detector.name)
    yield from bpp.subs_wrapper(
        bp.rel_scan([detector], sh, -1, 1, 21, per_step=shutter_flash_scan),
        local_peaks)
    tmp2 = local_peaks.cen  #get the height for roi2 of detector.name with max intens   )
    yield from bps.mv(sh, tmp2)
    yield from set_sh(tmp1)
    Msg('reset_settle_time', sh.settle_time, 0)
Beispiel #24
0
def dummy_edge_scan(sample_name, edge, md=None):
    from bluesky.examples import det, motor, det2

    if md is None:
        md = {}
    local_md = {'plan_name': 'edge_ascan'}
    md = ChainMap(md, local_md)

    e_scan_params = EDGE_MAP[edge]
    # TODO configure the vortex

    sample_props = SAMPLE_MAP[sample_name]
    # sample_props = list(sample_manager.find(sample_name))[0]
    local_md.update(sample_props)
    lp_list = []
    for n in ['det', 'det2']:
        fig = plt.figure(edge + ': ' + n)
        lp = bs.callbacks.LivePlot(n, 'motor', fig=fig)
        lp_list.append(lp)
    yield from bpp.subs_wrapper(bp.relative_scan([det, det2], motor, -5, 5, 15, md=md),
                               lp_list)
Beispiel #25
0
def test_subs():

    def cb(name, doc):
        pass

    def plan(*args, **kwargs):
        # check that args to plan are passed through
        yield from [Msg('null', None, *args, **kwargs)]

    processed_plan = list(subs_wrapper(plan('test_arg', test_kwarg='val'),
                                       {'all': cb}))

    expected = [Msg('subscribe', None, cb, 'all'),
                Msg('null', None, 'test_arg', test_kwarg='val'),
                Msg('unsubscribe', token=None)]

    assert processed_plan == expected

    processed_plan = list(subs_decorator({'all': cb})(plan)('test_arg',
                                                            test_kwarg='val'))
    assert processed_plan == expected
def dummy_edge_scan(sample_name, edge, md=None):
    from bluesky.examples import det, motor, det2

    if md is None:
        md = {}
    local_md = {'plan_name': 'edge_ascan'}
    md = ChainMap(md, local_md)

    e_scan_params = EDGE_MAP[edge]
    # TODO configure the vortex

    sample_props = SAMPLE_MAP[sample_name]
    # sample_props = list(sample_manager.find(sample_name))[0]
    local_md.update(sample_props)
    lp_list = []
    for n in ['det', 'det2']:
        fig = plt.figure(edge + ': ' + n)
        lp = bs.callbacks.LivePlot(n, 'motor', fig=fig)
        lp_list.append(lp)
    yield from bpp.subs_wrapper(bp.relative_scan([det, det2], motor, -5, 5, 15, md=md),
                               lp_list)
Beispiel #27
0
def test_subs():

    def cb(name, doc):
        pass

    def plan(*args, **kwargs):
        # check that args to plan are passed through
        yield from [Msg('null', None, *args, **kwargs)]

    processed_plan = list(subs_wrapper(plan('test_arg', test_kwarg='val'),
                                       {'all': cb}))

    expected = [Msg('subscribe', None, cb, 'all'),
                Msg('null', None, 'test_arg', test_kwarg='val'),
                Msg('unsubscribe', token=None)]

    assert processed_plan == expected

    processed_plan = list(subs_decorator({'all': cb})(plan)('test_arg',
                                                            test_kwarg='val'))
    assert processed_plan == expected
Beispiel #28
0
def test_evil_table_names(RE):
    from ophyd import Signal
    sigs = [
        Signal(value=0, name="a:b"),
        Signal(value=0, name="a,b"),
        Signal(value=0, name="a'b"),
        Signal(value=0, name="🐍"),
    ]
    table = LiveTable([s.name for s in sigs],
                      min_width=5,
                      extra_pad=2,
                      separator_lines=False)
    with _print_redirect() as fout:
        print()  # get a blank line in camptured output
        RE(bpp.subs_wrapper(bp.count(sigs, num=2), table))
    reference = """
+------------+--------------+--------+--------+--------+--------+
|   seq_num  |        time  |   a:b  |   a,b  |   a'b  |     🐍  |
+------------+--------------+--------+--------+--------+--------+
|         1  |  12:47:09.7  |     0  |     0  |     0  |     0  |
|         2  |  12:47:09.7  |     0  |     0  |     0  |     0  |
+------------+--------------+--------+--------+--------+--------+"""
    _compare_tables(fout, reference)
def check_sh_fine(value=0.05, detector=lambda_det):
    yield from bps.mv(geo.det_mode, 1)
    yield from bps.mv(abs2, 5)
    yield from mabt(value, value, 0)
    tmp1 = geo.sh.position
    print('Start the height scan before GID')
    #  Msg('reset_settle_time', sh.settle_time, value)
    #   yield from bp.rel_scan([detector],sh,-0.1,0.1,21,per_step=shutter_flash_scan)
    #   tmp2=peaks.cen['%s_stats2_total'%detector.name]
    local_peaks = PeakStats(sh.user_readback.name,
                            '%s_stats2_total' % detector.name)
    yield from bpp.subs_wrapper(
        bp.rel_scan([detector],
                    sh,
                    -0.15,
                    0.15,
                    16,
                    per_step=shutter_flash_scan), local_peaks)
    print("at #1")
    tmp2 = local_peaks.cen  #get the height for roi2 of detector.name with max intens
    print("at #2")
    yield from bps.mv(sh, tmp2)
    yield from set_sh(tmp1)
    Msg('reset_settle_time', sh.settle_time, 0)
def edge_ascan(sample_name, edge, md=None):
    '''Run a multi-edge nexafs scan for single sample and edge

    Parameters
    ----------
    sample_name : str
        Base sample name

    sample_position : float
        Postion of sample on manipulator arm

    edge : str
        Key into EDGE_MAP


    '''
    if md is None:
        md = {}
    local_md = {'plan_name': 'edge_ascan'}
    local_md['edge'] = edge
    md = ChainMap(md, local_md)

    e_scan_params = EDGE_MAP[edge]
    # TODO configure the vortex
    det_settings = DET_SETTINGS[edge]
    sample_props = SAMPLE_MAP[sample_name]
#    sample_props = list(sample_manager.find(name=sample_name))
    local_md.update(sample_props)

    # init_group = 'ME_INIT_' + str(uuid.uuid4())
    yield from bps.abs_set(ioxas_x, sample_props['pos'], wait=True)
#    yield from bps.mov(appes_x, sample_props['pos_x'])
#    yield from bps.mov(appes_y, sample_props['pos_y'])
    yield from bps.abs_set(feedback, 0, wait=True)
    yield from bps.abs_set(pgm_energy, e_scan_params['start'], wait=True)
    yield from bps.abs_set(epu1table, e_scan_params['epu_table'], wait=True)
    yield from bps.abs_set(epu1offset, e_scan_params['epu1offset'], wait=True)
    yield from bps.sleep(15)
    yield from bps.abs_set(m1b1_fp, 100)
    yield from bps.abs_set(feedback, 1, wait=True)
    yield from bps.sleep(5)
    yield from bps.abs_set(feedback, 0, wait=True)
    yield from bps.abs_set(vortex_x, det_settings['vortex_pos'], wait=True)
    yield from bps.abs_set(sample_sclr_gain, det_settings['samplegain'], wait=True)
    yield from bps.abs_set(sample_sclr_decade, det_settings['sampledecade'], wait=True)
    yield from bps.abs_set(aumesh_sclr_gain, det_settings['aumeshgain'], wait=True)
    yield from bps.abs_set(aumesh_sclr_decade, det_settings['aumeshdecade'], wait=True)
    yield from bps.abs_set(sclr_time, det_settings['sclr_time'], wait=True)

 #   yield from open_all_valves(all_valves)
    # yield from bp.wait(init_group)

# TODO make this an ohypd obj!!!!!!
    #caput('XF:23IDA-PPS:2{PSh}Cmd:Opn-Cmd',1)
#   yield from bp.sleep(2)
    # TODO make this an ohypd obj!!!!!!
    # TODO ask stuart
    #caput('XF:23IDA-OP:2{Mir:1A-Ax:FPit}Mtr_POS_SP',50)
    yield from bps.sleep(5)

#    yield from bps.configure(vortex, VORTEX_SETTINGS[edge])
#    yield from bps.sleep(2)
    yield from bps.abs_set(vortex.mca.rois.roi4.lo_chan, det_settings['vortex_low'], wait=True)
    yield from bps.abs_set(vortex.mca.rois.roi4.hi_chan, det_settings['vortex_high'], wait=True)
    yield from bps.abs_set(vortex.mca.preset_real_time, det_settings['vortex_time'], wait=True)

#    lp_list = []
#    for n in ['sclr_ch4', 'vortex_mca_rois_roi4_count']:
#        fig = plt.figure(edge + ': ' + n)
#        lp = bs.callbacks.LivePlot(n, 'pgm_energy_readback', fig=fig)
#        lp_list.append(lp)

#    class norm_plot(bs.callbacks.LivePlot):
#        def event(self,doc):
#            try:
#                doc.data['norm_intensity'] = doc.data['sclr_ch4']/doc.data['sclr_ch3']
#            except KeyError:
#                pass
#            super().event(doc)

#    for n in ['sclr_ch4']:
#        fig = plt.figure(edge + ': ' + n)
#        lp = bs.callbacks.LivePlot(n, 'pgm_energy_readback', fig=fig)
#        lp = norm_plot('norm_intensity', 'pgm_energy_readback', fig=fig)
#        lp_list.append(lp)
    dets = [sclr, vortex, norm_ch4, ring_curr]
    for channel in ['mca.rois.roi2.count','mca.rois.roi3.count','mca.rois.roi4.count']:
            getattr(vortex, channel).kind = 'hinted'
    for channel in ['mca.rois.roi2.count','mca.rois.roi3.count']:
            getattr(vortex, channel).kind = 'normal'
    for channel in ['channels.chan3','channels.chan4']:
        getattr(sclr, channel).kind = 'hinted'
    for channel in ['channels.chan2']:
        getattr(sclr, channel).kind = 'normal'
    
    scan_kwargs = {'start': e_scan_params['stop'],
                   'stop': e_scan_params['start'],
                   'velocity': e_scan_params['velocity'],
                   'deadband': e_scan_params['deadband'],
                   'md': md}
    ret = []
    for j in range(e_scan_params['scan_count']):
        tmp_pos = sample_props['pos'] + (j-((e_scan_params['scan_count']-1)/2))*e_scan_params['intervals']
#        yield from bps.mov(appes_y, tmp_pos)
        yield from bps.mov(ioxas_x, tmp_pos)
        yield from bps.abs_set(pgm_energy, e_scan_params['stop'], wait=True)
        yield from open_all_valves(all_valves)
        res = yield from bpp.subs_wrapper(E_ramp(dets, **scan_kwargs), {'stop': save_csv})
        yield from bps.abs_set(valve_diag3_close, 1, wait=True)
        yield from bps.abs_set(valve_mir3_close, 1, wait=True)
        yield from bps.sleep(5)
        if res is None:
            res = []
        ret.extend(res)
        if not ret:
            return ret


    # hdr = db[ret[0]]
    # redo_count = how_many_more_times_to_take_data(hdr)
    # for j in range(redo_count):
    #     res = yield from bpp.subs_wrapper(ascan(*scan_args, md=md), lp)
    #     ret.extend(res)


    # new_count_time = compute_new_count_time(hdr, old_count_time)
    # if new_count_time != old_count_time:
    #     yield from bps.configure(vortex, {'count_time': new_count_time})
    #     res = yield from bpp.subs_wrapper(ascan(*scan_args, md=md), lp)
    #     ret.extend(res)

    return ret
Beispiel #31
0
 def custom_subs(plan):
     yield from subs_wrapper(plan, my_sub)
def xanes_plan(erange=[],
               estep=[],
               harmonic=1,
               correct_c2_x=True,
               correct_c1_r=False,
               detune=None,
               acqtime=1.,
               roinum=1,
               delaytime=0.00,
               struck=True,
               fluor=True,
               samplename='',
               filename='',
               shutter=True,
               align=False,
               align_at=None,
               per_step=None):
    '''
    erange (list of floats): energy ranges for XANES in eV, e.g. erange = [7112-50, 7112-20, 7112+50, 7112+120]
    estep  (list of floats): energy step size for each energy range in eV, e.g. estep = [2, 1, 5]
    
    harmonic (odd integer): when set to 1, use the highest harmonic achievable automatically. 
                                    when set to an odd integer, force the XANES scan to use that harmonic
    correct_c2_x (boolean or float): when True, automatically correct the c2x 
                                     when False, c2x will not be moved during the XANES scan
    correct_c1_r (False or float): when False, c1r will not be moved during a XANES scan
                                   when set to a float, c1r will be set to that value before a XANES scan but will remain the same during the whole scan
    detune:  add this value to the gap of the undulator to reduce flux [mm]

    acqtime (float): acqusition time to be set for both xspress3 and preamplifier                                   
    roinum: select the roi to be used to calculate the XANES spectrum
    delaytime:  reduce acquisition time of F460 by this value [sec]
    struck:  Use the SRS and Struck scaler for the ion chamber and diode.  Set to False to use the F460.
    fluorescence:  indicate the presence of fluorescence data [bool]

    samplename (string): sample name to be saved in the scan metadata
    filename (string): filename to be added to the scan id as the text output filename

    shutter:  instruct the scan to control the B shutter [bool]
    align:  control the tuning of the DCM pointing before each XANES scan [bool]
    align_at:  energy at which to align, default is the first energy point 
    '''

    ept = numpy.array([])
    det = []
    filename = filename
    last_time_pt = time.time()
    ringbuf = collections.deque(maxlen=10)
    c2pitch_kill = EpicsSignal("XF:05IDA-OP:1{Mono:HDCM-Ax:P2}Cmd:Kill-Cmd")
    xs.external_trig.put(False)

    #make sure user provided correct input
    if erange is []:
        raise AttributeError(
            "An energy range must be provided in a list by means of the 'erange' keyword."
        )
    if estep is []:
        raise AttributeError(
            "A list of energy steps must be provided by means of the 'esteps' keyword."
        )
    if (not isinstance(erange, list)) or (not isinstance(estep, list)):
        raise TypeError("The keywords 'estep' and 'erange' must be lists.")
    if len(erange) - len(estep) is not 1:
        raise ValueError("The 'erange' and 'estep' lists are inconsistent;"\
                         +'c.f., erange = [7000, 7100, 7150, 7500], estep = [2, 0.5, 5] ')
    if type(roinum) is not list:
        roinum = [roinum]
    if detune is not None:
        yield from abs_set(energy.detune, detune)

    #record relevant meta data in the Start document, defined in 90-usersetup.py
    metadata_record()
    #add user meta data
    RE.md['sample'] = {'name': samplename}
    RE.md['scaninfo'] = {
        'type': 'XANES',
        'ROI': roinum,
        'raster': False,
        'dwell': acqtime
    }
    RE.md['scan_input'] = str(np.around(erange, 2)) + ', ' + str(
        np.around(estep, 2))

    #convert erange and estep to numpy array
    erange = numpy.array(erange)
    estep = numpy.array(estep)
    #calculation for the energy points
    for i in range(len(estep)):
        ept = numpy.append(ept, numpy.arange(erange[i], erange[i + 1],
                                             estep[i]))
    ept = numpy.append(ept, numpy.array(erange[-1]))

    # Debugging
    # Convert energy to bragg angle
    egap = np.array(())
    ebragg = np.array(())
    exgap = np.array(())
    for i in ept:
        # Convert from eV to keV
        # if (i > 4500):
        #    i = i / 1000
        # Convert keV to bragg angle
        #b, _, _ = energy.energy_to_positions(i, 5, 0)
        eg, eb, ex = energy.forward(i)
        egap = np.append(egap, eg)
        ebragg = np.append(ebragg, eb)
        exgap = np.append(exgap, ex)
        # print(ebragg)

    #register the detectors
    det = [ring_current]
    if struck == True:
        det.append(sclr1)
    else:
        det.append(current_preamp)
    if fluor == True:
        det.append(xs)
        #setup xspress3
        yield from abs_set(xs.settings.acquire_time, acqtime)
        yield from abs_set(xs.total_points, len(ept))

    #setup the preamp
    if struck == True:
        yield from abs_set(sclr1.preset_time, acqtime)
    else:
        yield from abs_set(current_preamp.exp_time, acqtime - delaytime)
    #setup dcm/energy options
    if correct_c2_x is False:
        yield from abs_set(energy.move_c2_x, False)
    if correct_c1_r is not False:
        yield from abs_set(dcm.c1_roll, correct_c1_r)
    if harmonic != 1:
        yield from abs_set(energy.harmonic, harmonic)
    #prepare to peak up DCM at first scan point
    if align_at is not None:
        align = True
    if align is True:
        if align_at == None:
            yield from abs_set(energy, ept[0], wait=True)
        else:
            print("aligning at ", align_at)
            yield from abs_set(energy, float(align_at), wait=True)
    # energy.u_gap.corrfunc_dis.put(1)
    #open b shutter
    if shutter is True:
        #shut_b.open()
        yield from mv(shut_b, 'Open')
        #yield from abs_set(shut_b,1,wait=True)
    #peak up DCM at first scan point
    if align is True:
        ps = PeakStats(dcm.c2_pitch.name, 'sclr_i0')
        e_value = energy.energy.get()[1]
        #        if e_value < 10.:
        #            yield from abs_set(sclr1.preset_time,0.1, wait = True)
        #            peakup = scan([sclr1], dcm.c2_pitch, -19.335, -19.305, 31)
        #        else:
        #            yield from abs_set(sclr1.preset_time,1., wait = True)
        #            peakup = scan([sclr1], dcm.c2_pitch, -19.355, -19.320, 36)
        if e_value < 14.:
            sclr1.preset_time.put(0.1)
        else:
            sclr1.preset_time.put(1.)
        peakup = scan([sclr1], dcm.c2_pitch, -19.320, -19.360, 41)
        peakup = subs_wrapper(peakup, ps)
        yield from peakup
        yield from abs_set(dcm.c2_pitch, ps.cen, wait=True)
        #ttime.sleep(10)
        #yield from abs_set(c2pitch_kill, 1)

    #setup the live callbacks
    myscan = list_scan(det, energy, list(ept), per_step=per_step)
    livecallbacks = []
    livetableitem = ['energy_energy']
    if struck == True:
        livetableitem = livetableitem + ['sclr_i0', 'sclr_it']
    else:
        livetableitem = livetableitem + [
            'current_preamp_ch0', 'current_preamp_ch2'
        ]
    if fluor == True:
        roi_name = 'roi{:02}'.format(roinum[0])
        roi_key = []
        roi_key.append(getattr(xs.channel1.rois, roi_name).value.name)
        roi_key.append(getattr(xs.channel2.rois, roi_name).value.name)
        roi_key.append(getattr(xs.channel3.rois, roi_name).value.name)
        livetableitem.append(roi_key[0])
        livecallbacks.append(LiveTable(livetableitem))
        liveploty = roi_key[0]
        liveplotx = energy.energy.name
        liveplotfig = plt.figure('raw xanes')
    elif struck == True:
        liveploty = 'sclr_it'
        liveplotx = energy.energy.name
        liveplotfig = plt.figure('raw xanes')

    # livecallbacks.append(LiveTable([sclr1, xs, energy]))
    livecallbacks.append(LivePlot(liveploty, x=liveplotx, fig=liveplotfig))
    #livecallbacks.append(LivePlot(liveploty, x=liveplotx, ax=plt.gca(title='raw xanes')))

    if struck == True:
        liveploty = 'sclr_i0'
        i0 = 'sclr_i0'
    else:
        liveploty = 'current_preamp_ch2'
        i0 = 'current_preamp_ch2'
    liveplotfig2 = plt.figure('i0')
    livecallbacks.append(LivePlot(liveploty, x=liveplotx, fig=liveplotfig2))
    #livecallbacks.append(LivePlot(liveploty, x=liveplotx, ax=plt.gca(title='incident intensity')))
    livenormfig = plt.figure('normalized xanes')
    if fluor == True:
        livecallbacks.append(
            NormalizeLivePlot(roi_key[0],
                              x=liveplotx,
                              norm_key=i0,
                              fig=livenormfig))
        #livecallbacks.append(NormalizeLivePlot(roi_key[0], x=liveplotx, norm_key = i0, ax=plt.gca(title='normalized xanes')))
    else:
        livecallbacks.append(
            NormalizeLivePlot('sclr_it',
                              x=liveplotx,
                              norm_key=i0,
                              fig=livenormfig))
        #livecallbacks.append(NormalizeLivePlot(roi_key[0], x=liveplotx, norm_key = i0, ax=plt.gca(title='normalized xanes')))
    def after_scan(name, doc):
        if name != 'stop':
            print(
                "You must export this scan data manually: xanes_afterscan_plan(doc[-1], <filename>, <roinum>)"
            )
            return
        xanes_afterscan_plan(doc['run_start'], filename, roinum)
        logscan_detailed('xanes')

    def at_scan(name, doc):
        scanrecord.current_scan.put(doc['uid'][:6])
        scanrecord.current_scan_id.put(str(doc['scan_id']))
        scanrecord.current_type.put(RE.md['scaninfo']['type'])
        scanrecord.scanning.put(True)

    def finalize_scan():
        # yield from abs_set(energy.u_gap.corrfunc_en,1)  # disabled to test if
        # undulator gets stuck -AMK
        yield from abs_set(energy.move_c2_x, True)
        yield from abs_set(energy.harmonic, 1)
        scanrecord.scanning.put(False)
        if shutter == True:
            yield from mv(shut_b, 'Close')
        if detune is not None:
            energy.detune.put(0)
        del RE.md['sample']['name']
        del RE.md['scaninfo']

    myscan = list_scan(det, energy, list(ept), per_step=per_step)
    # myscan = list_scan(det, energy, list(ept), per_step=per_step(detectors, motor, step))
    # myscan = list_scan(det, energy.bragg, list(ebragg), energy.u_gap, list(egap), energy.c2_x, list(exgap))
    # myscan = scan_nd(det, energy.bragg, list(ebragg), energy.u_gap, list(egap), energy.c2_x, list(exgap))
    myscan = finalize_wrapper(myscan, finalize_scan)

    return (yield from subs_wrapper(myscan, {
        'all': livecallbacks,
        'stop': after_scan,
        'start': at_scan
    }))
Beispiel #33
0
def nano_xrf(xstart,
             xstop,
             xstep,
             ystart,
             ystop,
             ystep,
             dwell,
             shutter=True,
             extra_dets=None,
             xmotor=nano_stage.sx,
             ymotor=nano_stage.sy,
             flag_snake=True):

    # calculate number of points
    xnum = np.int(np.abs(np.round((xstop - xstart) / xstep)) + 1)
    ynum = np.int(np.abs(np.round((ystop - ystart) / ystep)) + 1)

    # Setup detectors
    if extra_dets is None:
        extra_dets = []
    dets = [sclr1, xs, xbpm2, xmotor, ymotor] + extra_dets

    # Record relevant metadata in the Start document, defined in 90-usersetup.py
    scan_md = {}
    get_stock_md(scan_md)
    # scan_md['scan_input'] = str([xstart, xstop, xstep, ystart, ystop, ystep, dwell])
    # scan_md['scaninfo']  = {'type': 'XRF',
    #                         'raster' : True}
    scan_md['scan']['type'] = 'XRF_STEP'
    scan_md['scan']['scan_input'] = [
        xstart, xstop, xstep, ystart, ystop, ystep, dwell
    ]
    scan_md['scan']['detectors'] = [d.name for d in dets]
    scan_md['scan']['fast_axis'] = {
        'motor_name': xmotor.name,
        'units': xmotor.motor_egu.get()
    }
    scan_md['scan']['slow_axis'] = {
        'motor_name': ymotor.name,
        'units': ymotor.motor_egu.get()
    }
    scan_md['scan']['theta'] = {
        'val': nano_stage.th.user_readback.get(),
        'units': nano_stage.th.motor_egu.get()
    }
    scan_md['scan']['delta'] = {'val': 0, 'units': xmotor.motor_egu.get()}
    scan_md['scan']['snake'] = 1 if flag_snake else 0
    scan_md['scan']['shape'] = (xnum, ynum)

    # Set counting time
    sclr1.preset_time.put(dwell)
    xs.external_trig.put(False)
    xs.settings.acquire_time.put(dwell)
    xs.total_points.put(xnum * ynum)
    if (merlin in dets):
        merlin.cam.acquire_time.put(dwell)
        merlin.cam.acquire_period.put(dwell + 0.005)
        merlin.hdf5.stage_sigs['num_capture'] = xnum * ynum
        scan_md['scan']['merlin'] = {
            'merlin_exp_time': dwell,
            'merlin_exp_period': dwell + 0.005
        }

    # LiveGrid
    livecallbacks = []
    livecallbacks.append(LiveTable([xmotor.name, ymotor.name]))
    roi_name = 'roi{:02}'.format(1)
    roi_key = getattr(xs.channel1.rois, roi_name).value.name
    livecallbacks.append(
        LiveGrid((ynum, xnum),
                 roi_key,
                 clim=None,
                 cmap='viridis',
                 xlabel='x [um]',
                 ylabel='y [um]',
                 extent=[xstart, xstop, ystart, ystop],
                 x_positive='right',
                 y_positive='down'))

    myplan = grid_scan(dets,
                       ymotor,
                       ystart,
                       ystop,
                       ynum,
                       xmotor,
                       xstart,
                       xstop,
                       xnum,
                       flag_snake,
                       md=scan_md)
    myplan = subs_wrapper(myplan, {'all': livecallbacks})

    # Open shutter
    # if (shutter):
    #     yield from mv(shut_b,'Open')
    yield from check_shutters(shutter, 'Open')

    # grid scan
    uid = yield from myplan

    # Close shutter
    # if (shutter):
    #     yield from mv(shut_b,'Close')
    yield from check_shutters(shutter, 'Close')

    return uid
Beispiel #34
0
def hf2dxrf(*,
            xstart,
            xnumstep,
            xstepsize,
            ystart,
            ynumstep,
            ystepsize,
            acqtime,
            shutter=True,
            align=False,
            xmotor=hf_stage.x,
            ymotor=hf_stage.y,
            numrois=1,
            extra_dets=[],
            setenergy=None,
            u_detune=None,
            echange_waittime=10,
            samplename=None,
            snake=True):
    '''input:
        xstart, xnumstep, xstepsize : float
        ystart, ynumstep, ystepsize : float
        acqtime : float
             acqusition time to be set for both xspress3 and F460
        numrois : integer
            number of ROIs set to display in the live raster scans.
            This is for display ONLY.  The actualy number of ROIs
            saved depend on how many are enabled and set in the
            read_attr However noramlly one cares only the raw XRF
            spectra which are all saved and will be used for fitting.
        energy (float): set energy, use with caution, hdcm might
            become misaligned
        u_detune (float): amount of undulator to
            detune in the unit of keV

    '''
    # Record relevant metadata in the Start document, defined in 90-usersetup.py
    scan_md = {}
    get_stock_md(scan_md)
    scan_md['sample'] = {'name': samplename}
    scan_md['scan_input'] = str(
        [xstart, xnumstep, xstepsize, ystart, ynumstep, ystepsize, acqtime])
    scan_md['scaninfo'] = {'type': 'XRF', 'raster': True}

    # Setup detectors
    dets = [sclr1, xs]
    dets = dets + extra_dets
    dets_by_name = {d.name: d for d in dets}
    # Scaler
    if (acqtime < 0.001):
        acqtime = 0.001
    sclr1.preset_time.put(acqtime)
    # XS3
    xs.external_trig.put(False)
    xs.settings.acquire_time.put(acqtime)
    xs.total_points.put((xnumstep + 1) * (ynumstep + 1))

    if ('merlin' in dets_by_name):
        dpc = dets_by_name['merlin']

        # Setup Merlin
        dpc.cam.trigger_mode.put(0)
        dpc.cam.acquire_time.put(acqtime)
        dpc.cam.acquire_period.put(acqtime + 0.005)
        dpc.cam.num_images.put(1)
        dpc.hdf5.stage_sigs['num_capture'] = (xnumstep + 1) * (ynumstep + 1)
        dpc._mode = SRXMode.step
        dpc.total_points.put((xnumstep + 1) * (ynumstep + 1))

    if ('xs2' in dets_by_name):
        xs2 = dets_by_name['xs2']
        xs2.external_trig.put(False)
        xs2.settings.acquire_time.put(acqtime)
        xs2.total_points.put((xnumstep + 1) * (ynumstep + 1))

    # Setup the live callbacks
    livecallbacks = []

    # Setup scanbroker to update time remaining
    def time_per_point(name, doc, st=ttime.time()):
        if ('seq_num' in doc.keys()):
            scanrecord.scan0.tpp.put((doc['time'] - st) / doc['seq_num'])
            scanrecord.scan0.curpt.put(int(doc['seq_num']))
            scanrecord.time_remaining.put(
                (doc['time'] - st) / doc['seq_num'] *
                ((xnumstep + 1) * (ynumstep + 1) - doc['seq_num']) / 3600)

    livecallbacks.append(time_per_point)

    # Setup LiveTable
    livetableitem = [xmotor.name, ymotor.name, i0.name]
    xstop = xstart + xnumstep * xstepsize
    ystop = ystart + ynumstep * ystepsize

    for roi_idx in range(numrois):
        roi_name = 'roi{:02}'.format(roi_idx + 1)
        roi_key = getattr(xs.channel1.rois, roi_name).value.name
        livetableitem.append(roi_key)
        roimap = LiveGrid((ynumstep + 1, xnumstep + 1),
                          roi_key,
                          clim=None,
                          cmap='viridis',
                          xlabel='x (mm)',
                          ylabel='y (mm)',
                          extent=[xstart, xstop, ystart, ystop],
                          x_positive='right',
                          y_positive='down')
        livecallbacks.append(roimap)

    if ('xs2' in dets_by_name):
        for roi_idx in range(numrois):
            roi_key = getattr(xs2.channel1.rois, roi_name).value.name
            livetableitem.append(roi_key)
            fig = plt.figure('xs2_ROI{:02}'.format(roi_idx + 1))
            fig.clf()
            roimap = LiveGrid((ynumstep + 1, xnumstep + 1),
                              roi_key,
                              clim=None,
                              cmap='viridis',
                              xlabel='x (mm)',
                              ylabel='y (mm)',
                              extent=[xstart, xstop, ystart, ystop],
                              x_positive='right',
                              y_positive='down',
                              ax=fig.gca())
            livecallbacks.append(roimap)

    if ('merlin' in dets_by_name) and (hasattr(dpc, 'stats1')):
        fig = plt.figure('DPC')
        fig.clf()
        dpc_tmap = LiveGrid((ynumstep + 1, xnumstep + 1),
                            dpc.stats1.total.name,
                            clim=None,
                            cmap='viridis',
                            xlabel='x (mm)',
                            ylabel='y (mm)',
                            x_positive='right',
                            y_positive='down',
                            extent=[xstart, xstop, ystart, ystop],
                            ax=fig.gca())
        livecallbacks.append(dpc_tmap)

    # Change energy (if provided)
    if (setenergy is not None):
        if (u_detune is not None):
            energy.detune.put(u_detune)
        print('Changing energy to ', setenergy)
        yield from mv(energy, setenergy)
        print('Waiting time (s) ', echange_waittime)
        yield from bps.sleep(echange_waittime)

    def at_scan(name, doc):
        scanrecord.current_scan.put(doc['uid'][:6])
        scanrecord.current_scan_id.put(str(doc['scan_id']))
        scanrecord.current_type.put(scan_md['scaninfo']['type'])
        scanrecord.scanning.put(True)

    def finalize_scan(name, doc):
        scanrecord.scanning.put(False)

    # Setup the scan
    hf2dxrf_scanplan = outer_product_scan(dets,
                                          ymotor,
                                          ystart,
                                          ystop,
                                          ynumstep + 1,
                                          xmotor,
                                          xstart,
                                          xstop,
                                          xnumstep + 1,
                                          snake,
                                          md=scan_md)
    hf2dxrf_scanplan = subs_wrapper(hf2dxrf_scanplan, {
        'all': livecallbacks,
        'start': at_scan,
        'stop': finalize_scan
    })
    # Move to starting position
    yield from mv(xmotor, xstart, ymotor, ystart)

    # Peak up monochromator at this energy
    if (align):
        yield from peakup_fine(shutter=shutter)

    # Open shutter
    if (shutter):
        yield from mv(shut_b, 'Open')

    # Run the scan
    scaninfo = yield from hf2dxrf_scanplan

    #TO-DO: implement fast shutter control (close)
    if (shutter):
        yield from mv(shut_b, 'Close')

    # Write to scan log
    if ('merlin' in dets_by_name):
        logscan_event0info('2dxrf_withdpc')
        # Should this be here?
        merlin.hdf5.stage_sigs['num_capture'] = 0
    else:
        logscan_detailed('2dxrf')

    return scaninfo
Beispiel #35
0
def nano_xrf(xstart,
             xstop,
             xstep,
             ystart,
             ystop,
             ystep,
             acqtime,
             shutter=True,
             extra_dets=None,
             xmotor=nano_stage.sx,
             ymotor=nano_stage.sy):

    # define motors
    # xmotor = nano_stage.x
    # ymotor = nano_stage.y

    # Record relevant metadata in the Start document, defined in 90-usersetup.py
    scan_md = {}
    get_stock_md(scan_md)
    scan_md['scan_input'] = str(
        [xstart, xstop, xstep, ystart, ystop, ystep, acqtime])
    scan_md['scaninfo'] = {'type': 'XRF', 'raster': True}

    # calculate number of points
    xnum = np.int(np.abs(np.round((xstop - xstart) / xstep)) + 1)
    ynum = np.int(np.abs(np.round((ystop - ystart) / ystep)) + 1)

    # Setup detectors
    if extra_dets is None:
        extra_dets = []
    dets = [sclr1, xs, xbpm2, xmotor, ymotor] + extra_dets

    # Set counting time
    sclr1.preset_time.put(acqtime)
    xs.external_trig.put(False)
    xs.settings.acquire_time.put(acqtime)
    xs.total_points.put(xnum * ynum)
    if (merlin in dets):
        merlin.cam.acquire_time.put(acqtime)
        merlin.cam.acquire_period.put(acqtime + 0.005)
        merlin.hdf5.stage_sigs['num_capture'] = xnum * ynum
        scan_md['merlin'] = {
            'merlin_exp_time': acqtime,
            'merlin_exp_period': acqtime + 0.005
        }

    # LiveGrid
    livecallbacks = []
    livecallbacks.append(LiveTable([xmotor.name, ymotor.name]))
    roi_name = 'roi{:02}'.format(1)
    roi_key = getattr(xs.channel1.rois, roi_name).value.name
    livecallbacks.append(
        LiveGrid((ynum, xnum),
                 roi_key,
                 clim=None,
                 cmap='viridis',
                 xlabel='x [um]',
                 ylabel='y [um]',
                 extent=[xstart, xstop, ystart, ystop],
                 x_positive='right',
                 y_positive='down'))

    myplan = grid_scan(dets,
                       ymotor,
                       ystart,
                       ystop,
                       ynum,
                       xmotor,
                       xstart,
                       xstop,
                       xnum,
                       True,
                       md=scan_md)
    myplan = subs_wrapper(myplan, {'all': livecallbacks})

    # Open shutter
    if (shutter):
        yield from mv(shut_b, 'Open')

    # grid scan
    uid = yield from myplan

    # Open shutter
    if (shutter):
        yield from mv(shut_b, 'Close')

    return uid