Esempio n. 1
0
    def plan():
        # TODO move this to stage sigs
        for d in flying_zebra.detectors:
            yield from bps.mov(d.total_points, xnum)
        # added to "prime" the detector
        #yield from abs_set(xs.settings.trigger_mode, 'TTL Veto Only')

        # TODO move this to stage sigs
        yield from bps.mov(xs.external_trig, True)
        ystep = 0

        for step in np.linspace(ystart, ystop, ynum):
            yield from abs_set(scanrecord.time_remaining,
                               (ynum - ystep) * (dwell * xnum + 3.8) / 3600.)
            ystep = ystep + 1
            # 'arm' the all of the detectors for outputting fly data
            for d in flying_zebra.detectors:
                yield from bps.mov(d.fly_next, True)
            # print('h5 armed\t',time.time())
            yield from fly_each_step(ymotor, step)
            # print('return from step\t',time.time())

        # TODO this should be taken care of by stage sigs
        ion = flying_zebra.sclr
        yield from bps.mov(xs.external_trig, False, ion.count_mode, 1)
Esempio n. 2
0
def my_xanes(x_motor=0,
             y_motor=0,
             z_motor=0,
             e_range=[],
             e_steps=[],
             E_0=0.,
             k_range=[],
             k_steps=[],
             dwell=1,
             samplename='',
             filename='',
             ax11=None,
             ax22=None,
             ax33=None):
    # hf_stage.x.move(x_motor)
    # hf_stage.y.move(y_motor)
    # hf_stage.z.move(z_motor)
    yield from bps.mov(hf_stage.x, x_motor)
    yield from bps.mov(hf_stage.y, y_motor)
    yield from bps.mov(hf_stage.z, z_motor)

    yield from exafs_plan(erange=e_range,
                          estep=e_steps,
                          E0=E_0,
                          krange=k_range,
                          kstep=k_steps,
                          acqtime=dwell,
                          ax1=ax11,
                          ax2=ax22,
                          ax3=ax33)
Esempio n. 3
0
    def plan():
        yield from bps.mov(xs.total_points, xnum)
        # added to "prime" the detector
        #yield from abs_set(xs.settings.trigger_mode, 'TTL Veto Only')

        yield from bps.mov(xs.external_trig, True)
        ystep = 0

        for step in np.linspace(ystart, ystop, ynum):
            yield from abs_set(scanrecord.time_remaining,
                               (ynum - ystep) * ( dwell * xnum + 3.8 ) / 3600.)
            ystep = ystep + 1
            # 'arm' the xs for outputting fly data
            yield from bps.mov(xs.fly_next, True)
#            print('h5 armed\t',time.time())
            if step == ystart:
                firststep = True
            else:
                firststep = False
            yield from fly_each_step([], ymotor, step, firststep)
#            print('return from step\t',time.time())
        yield from bps.mov(xs.external_trig, False,
                          ion.count_mode, 1)
        if shutter is True:
            yield from mv(shut_b, 'Close')
Esempio n. 4
0
def sim_plan_outer(npts):
    for j in range(int(npts / 2)):
        yield from bps.mov(hw.motor, j * 0.2)
        yield from bps.trigger_and_read([hw.motor, hw.det])

    yield from sim_plan_inner(npts + 1)

    for j in range(int(npts / 2), npts):
        yield from bps.mov(hw.motor, j * 0.2)
        yield from bps.trigger_and_read([hw.motor, hw.det])
Esempio n. 5
0
def sim_multirun_plan_nested(npts: int, delay: float = 1.0):
    for j in range(int(npts / 2)):
        yield from bps.mov(motor, j * 0.2)
        yield from bps.trigger_and_read([motor, det])
        yield from bps.sleep(delay)

    yield from _sim_plan_inner(npts + 1, delay)

    for j in range(int(npts / 2), npts):
        yield from bps.mov(motor, j * 0.2)
        yield from bps.trigger_and_read([motor, det])
        yield from bps.sleep(delay)
Esempio n. 6
0
        def plan(npts):

            for j in range(int(npts/2)):
                yield from bps.mov(hw.motor1, j * 0.2)
                yield from bps.trigger_and_read([hw.motor1, hw.det1])

            # Different parameter values may be passed to the recursively called plans
            yield from sim_plan_recursive(npts + 2)

            for j in range(int(npts/2), npts):
                yield from bps.mov(hw.motor1, j * 0.2)
                yield from bps.trigger_and_read([hw.motor1, hw.det1])
Esempio n. 7
0
    def plan():
        # TODO move this to stage sigs
        for d in flying_zebra.detectors:
            yield from bps.mov(d.total_points, xnum)

        # TODO move this to stage sigs
        # yield from bps.mov(xs.external_trig, True)  ## Uncomment this

        ystep = 0
        for step in np.linspace(ystart, ystop, ynum):
            # yield from abs_set(scanrecord.time_remaining,  ## Uncomment this
            #                    (ynum - ystep) * ( dwell * xnum + 3.8 ) / 3600.)  ## Uncomment this
            # 'arm' the all of the detectors for outputting fly data
            print(f"Starting the next row")
            for d in flying_zebra.detectors:
                if d:
                    yield from bps.mov(d.fly_next, True)
            # print('h5 armed\t',time.time())
            if (snake is False):
                direction = 0
                start = row_start
                stop = row_stop
            else:
                if ystep % 2 == 0:
                    direction = 0
                    start = row_start
                    stop = row_stop
                else:
                    direction = 1
                    start = row_stop
                    stop = row_start
            # Do work
            if verbose:
                print(f'Direction = {direction}')
                print(f'Start = {start}')
                print(f'Stop  = {stop}')
            flying_zebra._encoder.pc.dir.set(direction)
            yield from fly_each_step(ymotor, step, start, stop)
            # print('return from step\t',time.time())
            ystep = ystep + 1

        # TODO this should be taken care of by stage sigs
        # ion = flying_zebra.sclr
        # if ion:
        #     yield from bps.mov(xs.external_trig, False,
        #                        ion.count_mode, 1)
        yield from mv(nano_stage.sx, 0, nano_stage.sy, 0, nano_stage.sz, 0)
        yield from bps.sleep(2)
Esempio n. 8
0
    def gp_inner_plan():
        # drain the queue in case there is anything left over from a previous
        # run
        while True:
            try:
                from_recommender.get(block=False)
            except Empty:
                break
        uids = []
        next_point = first_point
        for j in itertools.count():
            # this assumes that m.name == the key in Event
            target = {m: next_point[m.name] for m in motors}
            motor_position_pairs = itertools.chain(*target.items())

            yield from bps.mov(*motor_position_pairs)
            uid = yield from take_reading(dets + motors,
                                          md={
                                              **_md, "batch_count": j
                                          })
            uids.append(uid)

            next_point = from_recommender.get(timeout=1)
            if next_point is None:
                return

        return uids
Esempio n. 9
0
def exp_time_plan(det, timeList=[1]):
    '''
    Run count with each exposure time in time list.  
    Specific to Dexela Detector, only run with single detector
    return uids from each count

    # TO-DO: Fix so both are under the same start document
    '''
    primary_det = det
    dets = []
    if I0 not in dets:
        dets.append(I0)
    if I1 not in dets:
        dets.append(I1)

    dets.append(primary_det)
    md = {'acquire_time': 0, 'plan_name': 'exp_time_plan'}
    uids = []
    for time in timeList:
        # set acquire time
        yield from bps.mov(primary_det.cam.acquire_time, time)
        md['acquire_time'] = time
        uid = yield from bp.count(dets, md=md)

        yield from bps.sleep(1)
        uids.append(uid)
   
    return uids
Esempio n. 10
0
 def move():
     yield Msg('checkpoint')
     for motor, pos in step.items():
         if pos == pos_cache[motor]:
             # This step does not move this motor.
             continue
         yield from bps.mov(motor, pos)
         pos_cache[motor] = pos
Esempio n. 11
0
    def configure_area_det(det, exposure):
        '''Configure an area detector in "continuous mode"'''

        def _check_mini_expo(exposure, acq_time):
            if exposure < acq_time:
                raise ValueError(
                    "WARNING: total exposure time: {}s is shorter "
                    "than frame acquisition time {}s\n"
                    "you have two choices:\n"
                    "1) increase your exposure time to be at least"
                    "larger than frame acquisition time\n"
                    "2) increase the frame rate, if possible\n"
                    "    - to increase exposure time, simply resubmit"
                    " the ScanPlan with a longer exposure time\n"
                    "    - to increase frame-rate/decrease the"
                    " frame acquisition time, please use the"
                    " following command:\n"
                    "    >>> {} \n then rerun your ScanPlan definition"
                    " or rerun the xrun.\n"
                    "Note: by default, xpdAcq recommends running"
                    "the detector at its fastest frame-rate\n"
                    "(currently with a frame-acquisition time of"
                    "0.1s)\n in which case you cannot set it to a"
                    "lower value.".format(
                        exposure,
                        acq_time,
                        ">>> glbl['frame_acq_time'] = 0.5  #set" " to 0.5s",
                    )
                )

        # todo make
        ret = yield from bps.read(det.cam.acquire_time)
        if ret is None:
            acq_time = 1
        else:
            acq_time = ret[det.cam.acquire_time.name]["value"]
        _check_mini_expo(exposure, acq_time)
        if hasattr(det, "images_per_set"):
            # compute number of frames
            num_frame = np.ceil(exposure / acq_time)
            yield from bps.mov(det.images_per_set, num_frame)
        else:
            # The dexela detector does not support `images_per_set` so we just
            # use whatever the user asks for as the thing
            # TODO: maybe put in warnings if the exposure is too long?
            num_frame = 1
        computed_exposure = num_frame * acq_time

        # print exposure time
        print(
            "INFO: requested exposure time = {} - > computed exposure time"
            "= {}".format(exposure, computed_exposure)
        )
        return num_frame, acq_time, computed_exposure
Esempio n. 12
0
    def interlaced_plan(dets, motor):
        to_read = (motor, *dets)
        run_ids = list("abc")
        for rid in run_ids:
            yield from drw(bps.open_run(md={rid: rid}), run=rid)

        for j in range(5):
            for i, rid in enumerate(run_ids):
                yield from bps.mov(motor, j + 0.1 * i)
                yield from drw(bps.trigger_and_read(to_read), run=rid)

        for rid in run_ids:
            yield from drw(bps.close_run(), run=rid)
Esempio n. 13
0
    def interlaced_plan(dets, motor):
        to_read = (motor, *dets)
        run_names = ["run_one", "run_two", "run_three"]
        for rid in run_names:
            yield from srkw(bps.open_run(md={rid: rid}), run=rid)

        for j in range(5):
            for i, rid in enumerate(run_names):
                yield from bps.mov(motor, j + 0.1 * i)
                yield from srkw(bps.trigger_and_read(to_read), run=rid)

        for rid in run_names:
            yield from srkw(bps.close_run(), run=rid)
Esempio n. 14
0
        def fly_row():
            # go to start of row
            target_y = ystart + y * a_ystep_size
            yield from bps.mv(xy_fly_stage.x, xstart, xy_fly_stage.y, target_y)
            yield from bps.mv(y_centers,
                              np.ones(num_xpixels) *
                              target_y)  # set the fly speed

            ret = yield from bps.read(xy_fly_stage.z.user_readback)  # (in mm)
            zpos = (ret[xy_fly_stage.z.user_readback.name]["value"]
                    if ret is not None else 0)
            yield from bps.mov(z_centers, np.ones(num_xpixels) * zpos)

            yield from bps.mv(xy_fly_stage.x.velocity, flyspeed)

            yield from bps.trigger_and_read([xy_fly_stage], name="row_ends")

            for v in ["p1600=0", "p1600=1"]:
                yield from bps.mv(dtt, v)
                yield from bps.sleep(0.1)

            # arm the struck
            yield from bps.trigger(sclr, group=f"fly_row_{y}")
            # maybe start the xspress3
            if xspress3 is not None:
                yield from bps.trigger(xspress3, group=f"fly_row_{y}")
            yield from bps.sleep(0.1)
            # fly the motor
            yield from bps.abs_set(xy_fly_stage.x,
                                   xstop + a_xstep_size,
                                   group=f"fly_row_{y}")
            yield from bps.wait(group=f"fly_row_{y}")

            yield from bps.trigger_and_read([xy_fly_stage], name="row_ends")
            yield from bps.mv(xy_fly_stage.x.velocity, 5.0)
            yield from bps.sleep(0.1)
            # read and save the struck
            yield from bps.create(name="primary")
            #
            yield from bps.read(sclr)
            yield from bps.read(mono)
            yield from bps.read(x_centers)
            yield from bps.read(y_centers)
            yield from bps.read(z_centers)
            yield from bps.read(xy_fly_stage.y)
            yield from bps.read(xy_fly_stage.z)
            # and maybe the xspress3
            if xspress3 is not None:
                yield from bps.read(xspress3)
            yield from bps.save()
    def fly_body():

        yield from bps.mv(xy_fly_stage.x, xstart, xy_fly_stage.y, ystart)

        @bpp.stage_decorator([x for x in [xspress3] if x is not None])
        def fly_row():
            # go to start of row
            yield from bps.mv(xy_fly_stage.x, xstart, xy_fly_stage.y,
                              ystart + y * ystep_size)

            # set the fly speed
            yield from bps.mv(xy_fly_stage.x.velocity, flyspeed)

            yield from bps.trigger_and_read([xy_fly_stage], name='row_ends')

            for v in ['p1600=0', 'p1600=1']:
                yield from bps.mv(dtt, v)
                yield from bps.sleep(0.1)

            # arm the struck
            yield from bps.trigger(sclr, group=f'fly_row_{y}')
            # maybe start the xspress3
            if xspress3 is not None:
                yield from bps.trigger(xspress3, group=f'fly_row_{y}')
            yield from bps.sleep(0.1)
            # fly the motor
            yield from bps.abs_set(xy_fly_stage.x,
                                   xstop + a_xstep_size,
                                   group=f'fly_row_{y}')
            yield from bps.wait(group=f'fly_row_{y}')

            yield from bps.trigger_and_read([xy_fly_stage], name='row_ends')

            yield from bps.mv(xy_fly_stage.x.velocity, 5.0)
            yield from bps.sleep(.1)
            # read and save the struck
            yield from bps.create(name='primary')
            yield from bps.read(sclr)
            # and maybe the xspress3
            if xspress3 is not None:
                yield from bps.read(xspress3)
            yield from bps.save()

        for y in range(num_ypixels):
            if xspress3 is not None:
                yield from bps.mov(xspress3.fly_next, True)

            yield from fly_row()
Esempio n. 16
0
def test_plot_ints(RE):
    from ophyd import Signal
    from bluesky.callbacks.best_effort import BestEffortCallback
    from bluesky.plans import count
    import bluesky.plan_stubs as bps

    bec = BestEffortCallback()
    RE.subscribe(bec)

    s = Signal(name='s')
    RE(bps.mov(s, int(0)))
    assert s.describe()['s']['dtype'] == 'integer'
    s.kind = 'hinted'
    with pytest.warns(None) as record:
        RE(count([s], num=35))

    assert len(record) == 0
Esempio n. 17
0
def test_plot_ints(RE):
    from ophyd import Signal
    from bluesky.callbacks.best_effort import BestEffortCallback
    from bluesky.plans import count
    import bluesky.plan_stubs as bps

    bec = BestEffortCallback()
    RE.subscribe(bec)

    s = Signal(name='s')
    RE(bps.mov(s, int(0)))
    assert s.describe()['s']['dtype'] == 'integer'
    s.kind = 'hinted'
    with pytest.warns(None) as record:
        RE(count([s], num=35))

    assert len(record) == 0
    def _pe_acquisition_plan():
        for det in dets:
            if images_per_set is not None:
                yield from bps.mov(det.images_per_set, images_per_set)

        for det in dets:
            yield from bps.stage(det)

        yield from bps.sleep(1)

        # close fast shutter, now take a dark
        # yield from bps.mov(fs, 0)
        yield from bpp.trigger_and_read(dets, name='dark')

        # open fast shutter
        # yield from bps.mov(fs, 1)
        yield from bpp.trigger_and_read(dets, name='primary')

        for det in dets:
            yield from bps.unstage(det)
Esempio n. 19
0
    def inner():

        gen = generator(learner, goal)
        # have to "prime the pump"
        xy = None
        while True:
            try:
                x = gen.send(xy)
            except StopIteration:
                break
            yield from bps.mov(*itertools.chain(*zip(motors, x)))
            ret = yield from bps.trigger_and_read(dets + motors)

            # handle simulated case
            if ret:
                y = tuple(ret[k]["value"] for k in exogenous_keys)
                x = tuple(ret[k]["value"] for k in endogenous_keys)
            else:
                y = tuple(x[:1]) * len(exogenous_keys)
                x = x

            xy = (x, y)
Esempio n. 20
0

def cleanup():
    shutil.rmtree(tempdir)


db = Broker.from_config(config)

RE = RunEngine({})
# subscribe BEC
bec = BestEffortCallback()
RE.subscribe(bec)
RE.subscribe(db.insert)

# move motor to a reproducible location
RE(mov(motor1, 0))
RE(mov(motor2, 0))
RE(
    relative_outer_product_scan([det4], motor1, -1, 0, 10, motor2, -2, 0, 20,
                                True))
RE(outer_product_scan([det4], motor1, -1, 0, 10, motor2, -2, 0, 20, True))

# move motor to a reproducible location
RE(mov(motor1, 0))
RE(mov(motor2, 0))
RE(relative_inner_product_scan([det4], 10, motor1, -1, 0, motor2, -2, 0))
RE(inner_product_scan([det4], 10, motor1, -1, 0, motor2, -2, 0))

# do it manually
from cycler import cycler
Esempio n. 21
0
 def empty_plan():
     yield from bps.mov(hw.motor, 5)
Esempio n. 22
0
 def some_plan():
     """This plan is called on each level of nesting"""
     for j in range(5):
         yield from bps.mov(hw.motor, j)
         yield from bps.trigger_and_read(to_read)
Esempio n. 23
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
Esempio n. 24
0
 def step_plan(motors, x):
     yield from bps.mov(*itertools.chain(*zip(motors, x)))
Esempio n. 25
0
def _dc_toggle(axis, enable, freq, dc_period, off_time):
    print('Axis {} {}: '.format(axis.axis_num, axis.desc.value), end='')
    yield from bps.mov(axis.frequency, freq)
    print('frequency={}'.format(axis.frequency.get()))
Esempio n. 26
0
 def sequence():
     for n in range(5):
         yield from bps.mov(hw.motor, n * 0.1 + 1)
         yield from bps.trigger_and_read([hw.det1])
Esempio n. 27
0
def flash_step(VIT_table,
               total_exposure,
               md,
               *,
               dets=None,
               delay=1,
               mm_mode='Current',
               per_step=bps.trigger_and_read,
               control_shutter=True):
    """
    Run a step-series of current/voltage.

    The current/voltage profile will look something like: ┌┐_┌┐_┌┐_

    Parameters
    ----------
    VIT_table : pd.DataFrame
       The required columns are {"I", "V", "t"} which are
       the current, voltage, and hold time respectively.

    total_exposure : float
        The total exposure time for the detector.

        This is set via _configure_area_detector which is
        implicitly coupled to xpd_configuration['area_det']

    md : dict
        The metadata to put into the runstart.  Will have
        some defaults added

    dets : List[OphydObj], optional
        The detectors to trigger at each point.

        If None, defaults to::

          [xpd_configuration['area_det']]

    delay : float, optional
        The time lag between subsequent data acquisition

    mm_mode : {'Current', 'Voltage'}, optional
        The thing to measure from the Keithly multimeter.

    per_step : Callable[List[OphydObj], Optional[str]] -> Generator[Msg], optional
        The inner-most data acquisition loop.

        This plan will be repeated as many times as possible (with
        the target *delay* between starting the plan.

        If the plan take longer than *delay* to run it will
        immediately be restarted.

    control_shutter : bool, optional
        If the plan should try to open and close the shutter

        defaults to True
    """
    if total_exposure > delay:
        raise RuntimeError(f"You asked for total_exposure={total_exposure} "
                           f"with a delay of delay={delay} which is less ")
    if dets is None:
        dets = [xpd_configuration['area_det']]

    all_dets = dets + [flash_power, eurotherm]
    req_cols = ['I', 'V', 't']
    if not all(k in VIT_table for k in req_cols):
        raise ValueError(f"input table must have {req_cols}")

    monitor_during = yield from _setup_mm(mm_mode)

    VIT_table = pd.DataFrame(VIT_table)
    # TODO put in default meta-data
    md.setdefault('hints', {})
    md['hints'].setdefault('dimensions', [(('time', ), 'primary')])
    md['plan_name'] = 'flash_step'
    md['plan_args'] = {
        'VIT_table': {k: v.values
                      for k, v in VIT_table.items()},
        'delay': delay,
        'total_exposure': total_exposure
    }
    md['detectors'] = [det.name for det in dets]

    @subs_decorator(bec)
    # paranoia to be very sure we turn the PSU off
    @finalize_decorator(lambda: bps.mov(flash_power.enabled, 0))
    # this arms the detectors
    @stage_decorator(all_dets)
    # this sets up the monitors of the multi-meter
    @monitor_during_decorator(monitor_during)
    # this opens the run and puts the meta-data in it
    @run_decorator(md=md)
    def flash_step_field_inner():
        # set everything to zero at the top
        yield from bps.mv(flash_power.current_sp, 0, flash_power.voltage_sp, 0)
        # put in "Duty Cycle" mode so current changes immediately
        yield from bps.mv(flash_power.mode, 'Duty-Cycle')

        # take a measurement on the way in
        yield from per_step(all_dets, 'primary')

        # turn it on!
        yield from bps.mv(flash_power.enabled, 1)

        last_I = last_V = np.nan
        for _, row in VIT_table.iterrows():
            tau = row['t']
            exposure_count = int(max(1, tau // delay))
            print('initial per step call')
            yield from per_step(all_dets, 'primary')
            next_I = row['I']
            next_V = row['V']
            print('set IV')
            if next_I != last_I:
                yield from bps.mv(flash_power.current_sp, next_I)
                last_I = next_I
            if next_V != last_V:
                yield from bps.mv(flash_power.voltage_sp, next_V)
                last_V = next_V
            print('finsh setting IV')
            deadline = time.monotonic() + tau
            yield from _inner_loop(all_dets, exposure_count, delay, deadline,
                                   per_step, 'primary')
            print('finished inner loop call')

        print('final shot')
        # take a measurement on the way out
        yield from per_step(all_dets, 'primary')

        print('turning off')
        # turn it off!
        # there are several other places we turn this off, but better safe
        yield from bps.mv(flash_power.enabled, 0)

    # HACK to get at global state
    yield from _configure_area_det(total_exposure)
    plan = flash_step_field_inner()
    if control_shutter:
        return (yield from bpp.plan_mutator(plan, inner_shutter_control))
    else:
        return (yield from plan)
Esempio n. 28
0
def _sim_plan_inner(npts: int, delay: float = 1.0):
    for j in range(npts):
        yield from bps.mov(motor1, j * 0.1 + 1, motor2, j * 0.2 - 2)
        yield from bps.trigger_and_read([motor1, motor2, det2])
        yield from bps.sleep(delay)
Esempio n. 29
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.abs_set(diag3_y, sample_props['diag3_y'], 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.mov(au_mesh, e_scan_params['au_mesh'])
#    yield from bps.mov(appes_t, sample_props['pos_theta'])
    yield from bps.abs_set(feedback, 0, wait=True)
    yield from bps.abs_set(pgm_energy, e_scan_params['e_align'], 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(5)
#    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 bps.abs_set(pd_sclr_gain, det_settings['pd_gain'], wait=True)
    yield from bps.abs_set(pd_sclr_decade, det_settings['pd_decade'], 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)
    yield from bps.abs_set(sample_sclr_decade, det_settings['sampledecade'], wait=True)
    yield from bps.abs_set(aumesh_sclr_decade, det_settings['aumeshdecade'], wait=True)
    yield from bps.abs_set(pd_sclr_decade, det_settings['pd_decade'], 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.abs_set(ioxas_x, tmp_pos, wait=True)
        yield from bps.abs_set(feedback, 0, wait=True)
        yield from bps.abs_set(pgm_energy, e_scan_params['e_align'], 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(20)
#       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(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
def scan_and_fly_base(detectors, xstart, xstop, xnum, ystart, ystop, ynum, dwell, *,
                      flying_zebra, xmotor, ymotor,
                      delta=None, shutter=True, align=False,
                      md=None):
    """Read IO from SIS3820.
    Zebra buffers x(t) points as a flyer.
    Xpress3 is our detector.
    The aerotech has the x and y positioners.
    delta should be chosen so that it takes about 0.5 sec to reach the gate??
    ymotor  slow axis
    xmotor  fast axis

    Parameters
    ----------
    Detectors : List[Device]
       These detectors must be known to the zebra

    xstart, xstop : float
    xnum : int
    ystart, ystop : float
    ynum : int
    dwell : float
       Dwell time in seconds

    flying_zebra : SRXFlyer1Axis

    xmotor, ymotor : EpicsMotor, kwarg only
        These should be known to the zebra
        # TODO sort out how to check this

    delta : float, optional, kwarg only
       offset on the ystage start position.  If not given, derive from
       dwell + pixel size
    align : bool, optional, kwarg only
       If True, try to align the beamline
    shutter : bool, optional, kwarg only
       If True, try to open the shutter
    """

    # t_setup = tic()

    # Check for negative number of points
    if (xnum < 1 or ynum < 1):
        print('Error: Number of points is negative.')
        return

    # Set metadata
    if md is None:
        md = {}

    # Change retry deadband for hf_stage.x and hf_stage.y
    if (hf_stage.x in (xmotor, ymotor)):
        OLD_RDBD_X = hf_stage.RETRY_DEADBAND_X.get()
        NEW_RDBD_X = 2e-4
        hf_stage.RETRY_DEADBAND_X.put(NEW_RDBD_X)
    if (hf_stage.y in (xmotor, ymotor)):
        OLD_RDBD_Y = hf_stage.RETRY_DEADBAND_Y.get()
        NEW_RDBD_Y = 2e-4
        hf_stage.RETRY_DEADBAND_Y.put(NEW_RDBD_Y)

    # assign detectors to flying_zebra, this may fail
    flying_zebra.detectors = detectors
    # Setup detectors, combine the zebra, sclr, and the just set detector list
    detectors = (flying_zebra.encoder, flying_zebra.sclr) + flying_zebra.detectors

    dets_by_name = {d.name : d
                    for d in detectors}

    # set up the merlin
    if 'merlin' in dets_by_name:
        dpc = dets_by_name['merlin']
        # TODO use stage sigs
        # Set trigger mode
        # dpc.cam.trigger_mode.put(2)
        # Make sure we respect whatever the exposure time is set to
        if (dwell < 0.0066392):
            print('The Merlin should not operate faster than 7 ms.')
            print('Changing the scan dwell time to 7 ms.')
            dwell = 0.007
        # According to Ken's comments in hxntools, this is a de-bounce time
        # when in external trigger mode
        dpc.cam.stage_sigs['acquire_time'] = 0.50 * dwell - 0.0016392
        dpc.cam.stage_sigs['acquire_period'] = 0.75 * dwell
        dpc.cam.stage_sigs['num_images'] = 1
        dpc.stage_sigs['total_points'] = xnum
        dpc.hdf5.stage_sigs['num_capture'] = xnum
        del dpc

    # Setup dexela
    if ('dexela' in dets_by_name):
        xrd = dets_by_name['dexela']
        xrd.cam.stage_sigs['acquire_time'] = 0.50 * dwell - 0.050
        xrd.cam.stage_sigs['acquire_period'] = 0.50 * dwell - 0.020
        del xrd

    # If delta is None, set delta based on time for acceleration
    if (delta is None):
        if (flying_zebra.encoder.pc.egu.get() == 'mm'):
            MIN_DELTA = 0.002  # old default value
            v = ((xstop - xstart) / (xnum-1)) / dwell  # compute "stage speed"
            t_acc = 1.0  # acceleration time, default 1.0 s
            delta = t_acc * v  # distance the stage will travel in t_acc
            delta = np.amax((delta, MIN_DELTA))
        else:
            delta = 0.500 #was 2.5 when npoint scanner drifted

    # Move to start scanning location
    #if ('nano_stage' in xmotor.name):
    #    yield from mv(xmotor.velocity, 30)
    #    yield from mv(xmotor.velocity, 30)
    yield from mv(xmotor, xstart - delta,
                  ymotor, ystart)

    # Run a peakup before the map?
    if (align):
        yield from peakup_fine(shutter=shutter)

    md = ChainMap(md, {
        'plan_name': 'scan_and_fly',
        'detectors': [d.name for d in detectors],
        'dwell': dwell,
        'shape': (xnum, ynum),
        'scaninfo': {'type': 'XRF_fly',
                     'raster': False,
                     'fast_axis': flying_zebra.fast_axis.get()},
                     # 'slow_axis': flying_zebra.slow_axis.get(),
                     # 'theta': hf_stage.th.position}
        'scan_params': [xstart, xstop, xnum, ystart, ystop, ynum, dwell],
        'scan_input': [xstart, xstop, xnum, ystart, ystop, ynum, dwell],
        'delta': delta,
        'beamline_status' : {'energy' : energy.position.energy}
        }
    )

    if ('xs2' in dets_by_name):
        md['scaninfo']['type'] = 'XRF_E_tomo_fly'

    @stage_decorator(flying_zebra.detectors)
    def fly_each_step(motor, step):
        def move_to_start_fly():
            "See http://nsls-ii.github.io/bluesky/plans.html#the-per-step-hook"
            yield from abs_set(xmotor, xstart-delta, group='row')
            yield from one_1d_step([temp_nanoKB], motor, step)
            yield from bps.wait(group='row')

        # t_mvstartfly = tic()
        yield from move_to_start_fly()
        # toc(t_mvstartfly, str='Move to start fly each')

        # TODO  Why are we re-trying the move?  This should be fixed at
        # a lower level
        # yield from bps.sleep(1.0)  # wait for the "x motor" to move
        x_set = xstart - delta
        x_dial = xmotor.user_readback.get()
        # Get retry deadband value and check against that
        i = 0
        if (xmotor.egu == 'mm'):
            DEADBAND = 0.0005
        else:
            DEADBAND = 0.02
        while (np.abs(x_set - x_dial) > DEADBAND):
            if (i == 0):
                print('Waiting for motor to reach starting position...',
                      end='', flush=True)
            i = i + 1
            yield from mv(xmotor, xstart - delta)
            yield from bps.sleep(0.1)
            x_dial = xmotor.user_readback.get()
        if (i != 0):
            print('done')

        # Set the scan speed
        # Is abs_set(wait=True) or mv() faster?
        v = ((xstop - xstart) / (xnum-1)) / dwell  # compute "stage speed"
        # yield from abs_set(xmotor.velocity, v, wait=True)  # set the "stage speed"
        yield from mv(xmotor.velocity, v)
        # Change backlash speed for hf_stage.x and hf_stage.y
        if (hf_stage.x is xmotor):
            yield from mv(hf_stage.BACKLASH_SPEED_X, v)
        if (hf_stage.y is xmotor):
            yield from mv(hf_stage.BACKLASH_SPEED_Y, v)

        # set up all of the detectors
        # TODO we should be able to move this out of the per-line call?!
        if ('xs' in dets_by_name):
            xs = dets_by_name['xs']
            # yield from abs_set(xs.hdf5.num_capture, xnum, wait=True)
            # yield from abs_set(xs.settings.num_images, xnum, wait=True)
            yield from mv(xs.hdf5.num_capture, xnum,
                          xs.settings.num_images, xnum)

        if ('xs2' in dets_by_name):
            xs2 = dets_by_name['xs2']
            # yield from abs_set(xs2.hdf5.num_capture, xnum, wait=True)
            # yield from abs_set(xs2.settings.num_images, xnum, wait=True)
            yield from mv(xs2.hdf5.num_capture, xnum,
                          xs2.settings.num_images, xnum)

        if ('merlin' in dets_by_name):
            merlin = dets_by_name['merlin']
            yield from abs_set(merlin.hdf5.num_capture, xnum, wait=True)
            yield from abs_set(merlin.cam.num_images, xnum, wait=True)

        if ('dexela' in dets_by_name):
            dexela = dets_by_name['dexela']
            yield from abs_set(dexela.hdf5.num_capture, xnum, wait=True)
            yield from abs_set(dexela.cam.num_images, xnum, wait=True)

        ion = flying_zebra.sclr
        yield from abs_set(ion.nuse_all,xnum)

        # arm the Zebra (start caching x positions)
        # @timer_wrapper
        def zebra_kickoff():
            yield from kickoff(flying_zebra,
                               xstart=xstart, xstop=xstop, xnum=xnum, dwell=dwell,
                               wait=True)
        # t_zebkickoff = tic()
        yield from zebra_kickoff()
        # toc(t_zebkickoff, str='Zebra kickoff')

        # arm SIS3820, note that there is a 1 sec delay in setting X
        # into motion so the first point *in each row* won't
        # normalize...
        yield from abs_set(ion.erase_start, 1)

        # trigger all of the detectors
        for d in flying_zebra.detectors:
            yield from bps.trigger(d, group='row')
            if (d.name == 'dexela'):
                yield from bps.sleep(1)

        yield from bps.sleep(1.5)
        # start the 'fly'
        yield from abs_set(xmotor, xstop + 1*delta, group='row')  # move in x
        # wait for the motor and detectors to all agree they are done
        yield from bps.wait(group='row')

        # we still know about ion from above
        yield from abs_set(ion.stop_all, 1)  # stop acquiring scaler

        # @timer_wrapper
        def zebra_complete():
            yield from complete(flying_zebra)  # tell the Zebra we are done
        # t_zebcomplete = tic()
        yield from zebra_complete()
        # toc(t_zebcomplete, str='Zebra complete')


        # @timer_wrapper
        def zebra_collect():
            yield from collect(flying_zebra)  # extract data from Zebra
        # t_zebcollect = tic()
        yield from zebra_collect()
        # toc(t_zebcollect, str='Zebra collect')

        # TODO what?
        if ('e_tomo' in xmotor.name):
            v_return = min(4, xmotor.velocity.high_limit)
            yield from mv(xmotor.velocity, v_return)
        if ('nano_stage' in xmotor.name):
            yield from mv(xmotor.velocity, 30)
        else:
            # set the "stage speed"
            yield from mv(xmotor.velocity, 1.0)

    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(md['scaninfo']['type'])
        scanrecord.scanning.put(True)
        scanrecord.time_remaining.put((dwell*xnum + 3.8)/3600)

    def finalize_scan(name, doc):
        logscan_detailed('xrf_fly')
        scanrecord.scanning.put(False)
        scanrecord.time_remaining.put(0)

        if (hf_stage.x in (xmotor, ymotor)):
            hf_stage.RETRY_DEADBAND_X.put(OLD_RDBD_X)
        if (hf_stage.y in (xmotor, ymotor)):
            hf_stage.RETRY_DEADBAND_Y.put(OLD_RDBD_Y)

    # TODO remove this eventually?
    # xs = dets_by_name['xs']
    # xs = dets_by_name['xs2']
    # Not sure if this is always true
    xs = dets_by_name[flying_zebra.detectors[0].name]

    yield from mv(xs.erase, 0)

    # Setup LivePlot
    if (ynum == 1):
        # livepopup = LivePlot(xs.channel1.rois.roi01.value.name)
        livepopup = SRX1DFlyerPlot(xs.channel1.rois.roi01.value.name,
                                   xstart=xstart,
                                   xstep=(xstop-xstart)/(xnum-1),
                                   xlabel=xmotor.name)
    else:
        livepopup = LiveGrid((ynum, xnum+1),
                             xs.channel1.rois.roi01.value.name,
                             extent=(xstart, xstop, ystart, ystop),
                             x_positive='right', y_positive='down')
        # livepopup = ArrayCounterLiveGrid(
        #     (ynum, xnum + 1),
        #     xs.channel1.rois.roi01.value.name,
        #     array_counter_key=xs.array_counter.name,
        #     extent=(xstart, xstop, ystart, ystop),
        #     x_positive='right', y_positive='down'
        # )
    @subs_decorator([livepopup])
    @subs_decorator({'start': at_scan})
    @subs_decorator({'stop': finalize_scan})
    # monitor values from xs
    # @monitor_during_decorator([xs.channel1.rois.roi01.value])
    @monitor_during_decorator([xs.channel1.rois.roi01.value, xs.array_counter])
    @stage_decorator([flying_zebra])  # Below, 'scan' stage ymotor.
    @run_decorator(md=md)
    def plan():
        # TODO move this to stage sigs
        for d in flying_zebra.detectors:
            yield from bps.mov(d.total_points, xnum)

        # TODO move this to stage sigs
        yield from bps.mov(xs.external_trig, True)
        ystep = 0

        for step in np.linspace(ystart, ystop, ynum):
            yield from abs_set(scanrecord.time_remaining,
                               (ynum - ystep) * ( dwell * xnum + 3.8 ) / 3600.)
            ystep = ystep + 1
            # 'arm' the all of the detectors for outputting fly data
            for d in flying_zebra.detectors:
                yield from bps.mov(d.fly_next, True)
            # print('h5 armed\t',time.time())
            yield from fly_each_step(ymotor, step)
            # print('return from step\t',time.time())

        # TODO this should be taken care of by stage sigs
        ion = flying_zebra.sclr
        yield from bps.mov(xs.external_trig, False,
                           ion.count_mode, 1)
    # toc(t_setup, str='Setup time')

    # Setup the final scan plan
    if shutter:
        final_plan = finalize_wrapper(plan(),
                                      bps.mov(shut_b, 'Close'))
    else:
        final_plan = plan()

    # Open the shutter
    if shutter:
        # t_open = tic()
        yield from mv(shut_b, 'Open')
        # toc(t_open, str='Open shutter')

    # Run the scan
    uid = yield from final_plan

    # Close the shutter
    # if shutter:
    #     # t_close = tic()
    #     yield from mv(shut_b, 'Close')
    #     # toc(t_close, str='Close shutter')

    # Return sample stage defaults
    if ('hf_stage' in xmotor.name):
        hf_stage.reset_stage_defaults()

    return uid
Esempio n. 31
0
def flash_ramp(start_I,
               stop_I,
               ramp_rate,
               voltage,
               total_exposure,
               md,
               *,
               dets=None,
               delay=1,
               mm_mode='Current',
               hold_time=0,
               per_step=bps.trigger_and_read,
               control_shutter=True):
    """
    Run a current ramp

    The current profile will look something like: /|

    Parameters
    ----------
    start_I, stop_I : float
        The start and end points of the current ramp

        In mA

    ramp_rate : float
        The rate of current change.

        In mA/min

    voltage : float
        The voltage limit through the current ramp.

    total_exposure : float
        The total exposure time for the detector.

        This is set via _configure_area_detector which is
        implicitly coupled to xpd_configuration['area_det']

    md : dict
        The metadata to put into the runstart.  Will have
        some defaults added

    dets : List[OphydObj], optional
        The detectors to trigger at each point.

        If None, defaults to::

          [xpd_configuration['area_det']]

    delay : float, optional
        The time lag between subsequent data acquisition

    mm_mode : {'Current', 'Voltage'}, optional
        The thing to measure from the Keithly multimeter.

    hold_time : float, optional
       How long to hold at the top of the ramp, defalts to 0

    per_step : Callable[List[OphydObj], Optional[str]] -> Generator[Msg], optional
        The inner-most data acquisition loop.

        This plan will be repeated as many times as possible (with
        the target *delay* between starting the plan.

        If the plan take longer than *delay* to run it will
        immediately be restarted.

    control_shutter : bool, optional
        If the plan should try to open and close the shutter

        defaults to True
    """
    if dets is None:
        dets = [xpd_configuration['area_det']]
    if total_exposure > delay:
        raise RuntimeError(f"You asked for total_exposure={total_exposure} "
                           f"with a delay of delay={delay} which is less ")
    # mA -> A
    start_I = start_I / 1000
    stop_I = stop_I / 1000
    if stop_I < start_I:
        raise ValueError("IOC can not ramp backwards")
    fudge_factor = 1
    ramp_rate *= fudge_factor
    all_dets = dets + [flash_power, eurotherm]
    monitor_during = yield from _setup_mm(mm_mode)

    expected_time = abs(
        (stop_I - start_I) / (ramp_rate / (fudge_factor * 60 * 1000)))
    exposure_count = int(max(1, expected_time // delay))

    md.setdefault('hints', {})
    md['hints'].setdefault('dimensions', [(('time', ), 'primary')])
    md['plan_name'] = 'flash_ramp'
    md['plan_args'] = {
        'start_I': start_I,
        'stop_I': stop_I,
        'ramp_rate': ramp_rate,
        'voltage': voltage,
        'delay': delay,
        'total_exposure': total_exposure
    }
    md['detectors'] = [det.name for det in dets]

    @subs_decorator(bec)
    # paranoia to be very sure we turn the PSU off
    @finalize_decorator(lambda: bps.mov(flash_power.enabled, 0))
    # this arms the detectors
    @stage_decorator(all_dets)
    # this sets up the monitors of the multi-meter
    @monitor_during_decorator(monitor_during)
    # this opens the run and puts the meta-data in it
    @run_decorator(md=md)
    def flash_ramp_inner():
        # set everything to zero at the top
        yield from bps.mv(flash_power.current_sp, 0, flash_power.voltage_sp, 0,
                          flash_power.ramp_rate, ramp_rate)
        # put in "Duty Cycle" mode so current changes immediately
        yield from bps.mv(flash_power.mode, 'Duty-Cycle')
        # take one shot on the way in
        yield from per_step(all_dets, 'primary')
        # turn it on!
        yield from bps.mv(flash_power.enabled, 1)

        # TODO
        # what voltage limit to start with ?!
        yield from bps.mv(flash_power.current_sp, start_I,
                          flash_power.voltage_sp, voltage)
        # put in "Current Ramp" to start the ramp
        yield from bps.mv(flash_power.mode, 'Current Ramping')
        # set the target to let it go
        gid = short_uid()
        yield from bps.abs_set(flash_power.current_sp, stop_I, group=gid)
        yield from bps.mv(flash_power.voltage_sp, voltage)

        yield from _inner_loop(all_dets,
                               exposure_count,
                               delay,
                               time.monotonic() + expected_time * 1.1,
                               per_step,
                               'primary',
                               done_signal=flash_power.ramp_done)

        if hold_time > 0:
            yield from _inner_loop(all_dets, int(max(1, hold_time // delay)),
                                   delay,
                                   time.monotonic() + hold_time, per_step,
                                   'primary')

        # take one shot on the way out
        yield from per_step(all_dets, 'primary')
        yield from bps.wait(gid)
        # turn it off!
        # there are several other places we turn this off, but better safe
        yield from bps.mv(flash_power.enabled, 0)

    # HACK to get at global state
    yield from _configure_area_det(total_exposure)
    plan = flash_ramp_inner()
    if control_shutter:
        return (yield from bpp.plan_mutator(plan, inner_shutter_control))
    else:
        return (yield from plan)
Esempio n. 32
0
def sim_plan_inner(npts):
    for j in range(npts):
        yield from bps.mov(hw.motor1, j * 0.1 + 1, hw.motor2, j * 0.2 - 2)
        yield from bps.trigger_and_read([hw.motor1, hw.motor2, hw.det2])
Esempio n. 33
0
def batch_scan(
    dets,
    sample_points,
    *,
    ti_range=5.0,
    points=10,
    rocking_range=0.5,
    rocking_num=3,
    real_motors,
    exposure=20,
    take_data=stepping_ct,
    transform_pair
):
    # unpack the real motors
    x_motor, y_motor = real_motors
    # make the soft pseudo axis
    ctrl = Control(name="ctrl")
    pseudo_axes = tuple(getattr(ctrl, k) for k in ctrl.component_names)
    _md = {
        "batch_id": str(uuid.uuid4()),
        "batch_scan": {
            "rocking_range": rocking_range,
            "take_data": take_data.__name__,
            "rocking_num": rocking_num,
            "points": points,
            "ti_range": ti_range,
        },
        'sample_points': sample_points
    }

    for p in sample_points:
        ti, *strip = p
        for j, ti_m in enumerate(np.linspace(ti-(ti_range/2), ti+(ti_range/2), points)):
            try:
                real_target = transform_pair.forward(ti_m, *strip)
                print(f"real target: {real_target}")
            except ValueError as ve:
                print("ValueError!")
                continue

            # move to the new position
            t0 = time.time()
            yield from bps.mov(*itertools.chain(*zip(real_motors, real_target)))
            t1 = time.time()
            print(f"move to target took {t1-t0:0.2f}s")

            # read back where the motors really are
            real_x = yield from _read_the_first_key(x_motor)
            real_y = yield from _read_the_first_key(y_motor)
            print(f"real x and y: {real_x}, {real_y}")
            if real_x is None:
                real_x, real_y = real_target
            # compute the new (actual) pseudo positions
            pseudo_target = transform_pair.inverse(real_x, real_y)
            print(f"pseudo target: {pseudo_target}")
            # and set our local synthetic object to them
            yield from bps.mv(*itertools.chain(*zip(pseudo_axes, pseudo_target)))

            uid = yield from take_data(
                dets + list(real_motors) + [ctrl],
                exposure,
                y_motor,
                real_y - rocking_range,
                real_y + rocking_range,
                md={
                    **_md,
                    "center_point": p,
                    "inner_count": j,
                },
                num=rocking_num
            )
Esempio n. 34
0
    def gp_inner_plan():
        # drain the queue in case there is anything left over from a previous
        # run
        while True:
            try:
                from_recommender.get(block=False)
            except Empty:
                break
        uids = []
        next_point = first_point
        for j in itertools.count():
            # extract the target position as a tuple
            target = tuple(next_point[k.name] for k in pseudo_axes)
            print(f"next point: {pprint.pformat(next_point)}")
            # if we have a snapping function use it
            if snap_function is not None:
                target = snap_function(*target)
            print(f"snapped target: {target}")
            # compute the real target
            real_target = transform_pair.forward(*target)
            print(f"real target: {real_target}")

            # move to the new position
            t0 = time.time()
            yield from bps.mov(*itertools.chain(*zip(real_motors, real_target)))
            t1 = time.time()
            print(f"move to target took {t1-t0:0.2f}s")

            # read back where the motors really are
            real_x = yield from _read_the_first_key(x_motor)
            real_y = yield from _read_the_first_key(y_motor)
            print(f"real x and y: {real_x}, {real_y}")

            # compute the new (actual) pseudo positions
            pseudo_target = transform_pair.inverse(real_x, real_y)
            print(f"pseudo target: {pseudo_target}")
            # and set our local synthetic object to them
            yield from bps.mv(*itertools.chain(*zip(pseudo_axes, pseudo_target)))

            # kick off the next actually measurement!
            uid = yield from take_data(
                dets + list(real_motors) + [ctrl],
                exposure,
                y_motor,
                real_y - rocking_range,
                real_y + rocking_range,
                md={
                    **_md,
                    "batch_count": j,
                    "adaptive_step": {
                        "requested": next_point,
                        "snapped": {k.name: v for k, v in zip(pseudo_axes, target)},
                    },
                },
                **take_data_kwargs,
            )
            uids.append(uid)

            # ask the reccomender what to do next
            t0 = time.time()
            next_point = from_recommender.get(timeout=reccomender_timeout)
            t1 = time.time()
            print(f"waited {t1-t0:.2f}s for recommendation")

            print(f"batch count: {j}")
            if next_point is None:
                print("no recommendation - stopping")
                return
            elif j > 10:
                print(f"stopping after batch_count reached {j}")
                return
            else:
                print(f"keep going!")

        return uids
Esempio n. 35
0
def cleanup():
    shutil.rmtree(tempdir)

db = Broker.from_config(config)


RE = RunEngine({})
# subscribe BEC
bec = BestEffortCallback()
RE.subscribe(bec)
RE.subscribe(db.insert)



# move motor to a reproducible location
RE(mov(motor1, 0))
RE(mov(motor2, 0))
RE(relative_outer_product_scan([det4], motor1, -1, 0, 10, motor2, -2,
                               0, 20, True))
RE(outer_product_scan([det4], motor1, -1, 0, 10, motor2, -2, 0, 20,
                      True))

# move motor to a reproducible location
RE(mov(motor1, 0))
RE(mov(motor2, 0))
RE(relative_inner_product_scan([det4], 10, motor1, -1, 0, motor2, -2,
                               0))
RE(inner_product_scan([det4], 10, motor1, -1, 0, motor2, -2, 0))


# do it manually