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)
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)
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')
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])
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)
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])
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)
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
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
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
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
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)
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)
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()
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)
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)
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
def empty_plan(): yield from bps.mov(hw.motor, 5)
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)
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
def step_plan(motors, x): yield from bps.mov(*itertools.chain(*zip(motors, x)))
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()))
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])
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)
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)
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
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)
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])
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 )
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
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