def grid_fly(flyer, y, ystart, ystop, ynum, x, xstart, xstop, xnum): generator = CompoundGenerator( generators=[ LineGenerator(y.name, "mm", ystart, ystop, ynum), LineGenerator(x.name, "mm", xstart, xstop, xnum), ], duration=0.1, ) mapping.configure(dict(generator=generator)) md = dict( hints=dict( gridding="rectilinear", dimensions=[([y.name], "primary"), ([x.name], "primary")], ), shape=(ynum, xnum), extents=([ystart, ystop], [xstart, xstop]), ) uid = yield from bps.open_run(md) yield from bps.kickoff(flyer, wait=True) yield from bps.collect(flyer, stream=True) yield from bps.checkpoint() yield from bps.complete(flyer, group="flyer") for _ in range(int(ynum * xnum * 0.1)): yield from bps.sleep(1) yield from bps.collect(flyer, stream=True) yield from bps.checkpoint() yield from bps.wait(group="flyer") yield from bps.collect(flyer, stream=True) yield from bps.close_run() return uid
def set_and_fly(filepaths, flyers, sleeptime=10): ''' Fly on flyers with file prefix for a certain sleep time. fileprefix: file prefix sleeptime : sleep time to let flyer run for I've written this manually for now. ''' # set the file paths for filepath, flyer in zip(filepaths, flyers): yield from bps.abs_set(flyer.filepath, filepath) yield from bps.open_run() for flyer in flyers: yield from bps.stage(flyer) grp = str(uuid4()) for flyer in flyers: yield from bps.kickoff(flyer, group=grp, wait=False) yield from bps.wait(group=grp) yield from bps.sleep(sleeptime) for flyer in flyers: yield from bps.complete(flyer, group=grp, wait=False) for flyer in flyers: yield from bps.collect(flyer) for flyer in flyers: yield from bps.unstage(flyer) yield from bps.close_run()
def fly_scan(experiment, cfg_tomo): """ Collect projections with fly motion """ det = experiment.det psofly = experiment.psofly yield from bps.mv(det.hdf1.nd_array_port, 'PG1') yield from bps.mv(det.tiff1.nd_array_port, 'PG1') # we are assuming that the global psofly is available yield from bps.mv( psofly.start, cfg_tomo['omega_start'], psofly.end, cfg_tomo['omega_end'], psofly.scan_delta, abs(cfg_tomo['omega_step']), psofly.slew_speed, cfg_tomo['slew_speed'], ) # taxi yield from bps.mv(psofly.taxi, "Taxi") yield from bps.mv( det.cam.num_images, cfg_tomo['n_projections'], det.cam.trigger_mode, "Overlapped", ) # start the fly scan yield from bps.trigger(det, group='fly') yield from bps.abs_set(psofly.fly, "Fly", group='fly') yield from bps.wait(group='fly')
def motor_dark_step(detectors, motor, step): """ Take darks while moving motors, wait for all to be finished before taking light """ yield from bps.checkpoint() print('l120') # close the shutter #yield from _close_shutter_stub() COMMENTED OUT (dark per light) print('l123') # move motors don't wait yet. # Note for Soham: use `group=None` to ramp temp after dark collected # (Broken and replaced below) yield from bps.abs_set(motor, step, group="dark_motor") yield from bps.abs_set(motor, step, group="dark_motor") print('l127') # take dark (this has an internal wait on the readback) #yield from bps.trigger_and_read(list(detectors), name="dark") COMMENTED OUT (dark per light) print('l130') # (Broken) now wait for the motors to be done too yield from bps.wait(group="dark_motor") print('l133') # open shutter yield from open_shutter_stub() print('l136') # take data yield from bps.trigger_and_read(list(detectors) + [motor]) print('l139')
def fly_body(): yield from bps.trigger_and_read([E_centers], name='energy_bins') for y in range(num_scans): # go to start of row yield from bps.mv(mono.linear, l_start) # set the fly speed yield from bps.mv(mono.linear.velocity, flyspeed) yield from bps.trigger_and_read([mono], 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_energy_{y}') # fly the motor yield from bps.abs_set(mono.linear, l_stop + a_l_step_size, group=f'fly_energy_{y}') yield from bps.wait(group=f'fly_energy_{y}') yield from bps.trigger_and_read([mono], name='row_ends') yield from bps.mv(mono.linear.velocity, 0.5) # hard coded to let the sclr count its fingers and toes yield from bps.sleep(.1) # read and save the struck yield from bps.create(name='primary') yield from bps.read(sclr) yield from bps.save()
def per_shot(dets): nonlocal start, stop yield from bps.mv(motor.velocity, abs(stop - start) / exposure) gp = short_uid("rocker") yield from bps.abs_set(motor, stop, group=gp) yield from bps.trigger_and_read(dets) yield from bps.wait(group=gp) start, stop = stop, start
def x_motion_per_step(dets, stream_name): nonlocal last_group if last_group is not None: yield from bps.wait(last_group) yield from bps.trigger_and_read(dets, stream_name) last_group = short_uid() target = start + step_size * (next(j) % num_pos) yield from bps.abs_set(motor, target, group=last_group)
def move(): yield from checkpoint() grp = short_uid("set") for motor, pos in step.items(): if pos == pos_cache[motor]: # This step does not move this motor. continue yield from abs_set(motor, pos, group=grp) pos_cache[motor] = pos yield from wait(group=grp)
def move(): yield from checkpoint() grp = short_uid('set') for motor, pos in step.items(): if pos == pos_cache[motor]: # This step does not move this motor. continue yield from abs_set(motor, pos, group=grp) pos_cache[motor] = pos yield from wait(group=grp)
def dark_plan(): yield from bps.mv(shutter, 'closed') yield from bps.unstage(det) yield from bps.stage(det) yield from bps.trigger(det, group='darkframe-trigger') yield from bps.wait('darkframe-trigger') snapshot = bluesky_darkframes.SnapshotDevice(det) yield from bps.unstage(det) yield from bps.stage(det) yield from bps.mv(shutter, 'open') return snapshot
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) # revised by YDu, no such value before #yield from bps.sleep(0) # 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") # 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}") # revised by YDu, use to be 0.1 yield from bps.sleep(1.5) # 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) # revised by YDu, use to be 0.1 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.sleep(0.2) yield from bps.save() yield from bps.sleep(0.2)
def move_to_start_fly(): "See http://nsls-ii.github.io/bluesky/plans.html#the-per-step-hook" # row_str = short_uid('row') # yield from abs_set(xmotor, row_start, group=row_str) # yield from one_1d_step([temp_nanoKB], motor, step) # yield from bps.wait(group=row_str) row_str = short_uid('row') yield from bps.checkpoint() yield from bps.abs_set(xmotor, row_start, group=row_str) yield from bps.abs_set(motor, step, group=row_str) yield from bps.wait(group=row_str) yield from bps.trigger_and_read([temp_nanoKB, motor])
def open_all_valves(valve_list): '''Open all the listed valves Parameters ---------- valve_list : sequence The valves to open ''' for v in valve_list: yield from bps.abs_set(v, 1, group='valve_set') yield from bps.wait('valve_set') # sleep might not be needed yield from bps.sleep(2)
def setup_dc(self, enable, period, off_time, verify=True): enable = 1 if enable else 0 period = int(period) off_time = int(off_time) wait_group = 'anc_set_dc' yield from bps.abs_set(self.dc_period, period, group=wait_group) yield from bps.abs_set(self.dc_off_time, off_time, group=wait_group) yield from bps.abs_set(self.dc_enable, enable, group=wait_group) if verify: yield from bps.wait(group=wait_group)
def dark_plan(detector): # Restage to ensure that dark frames goes into a separate file. yield from bps.unstage(detector) yield from bps.stage(detector) yield from bps.mv(shutter, 'closed') # The `group` parameter passed to trigger MUST start with # bluesky-darkframes-trigger. yield from bps.trigger(detector, group='bluesky-darkframes-trigger') yield from bps.wait('bluesky-darkframes-trigger') snapshot = bluesky_darkframes.SnapshotDevice(detector) yield from bps.mv(shutter, 'open') # Restage. yield from bps.unstage(detector) yield from bps.stage(detector) return snapshot
def dark_plan(cam, dark_frame_cache, obsolete_secs, shutter): if (dark_frame_cache.just_started or # first run after instantiation (dark_frame_cache.last_collected is not None and time.monotonic() - dark_frame_cache.last_collected > obsolete_secs)): tmp = yield from bps.read(shutter.status) init_shutter_state = tmp[shutter.status.name]['value'] if tmp is not None else None yield from bps.mv(shutter, 'Close') yield from bps.trigger(cam, group='cam') yield from bps.wait('cam') yield from bps.mv(shutter, init_shutter_state) teleport(cam, dark_frame_cache) dark_frame_cache.just_started = False dark_frame_cache.update_done = True else: dark_frame_cache.update_done = False
def no_run_trigger_and_wait(objects): """ count objects (presume detectors) but do not create a bluesky run Does most of bps.trigger_and_read() but does not create&save a run. Caller must call `.read()` on each object once this returns. The primary use case is to count detectors (on a scaler card) when measuring sample transmission. """ if not isinstance(objects, (tuple, set, list)): objects = [objects] group = bps._short_uid("trigger_and_wait_no_run") for obj in objects: yield from bps.trigger(obj, group=group) yield from bps.wait(group=group)
def dark_plan(detector, dark_frame_cache, max_age, shutter): if (dark_frame_cache.just_started or # first run after instantiation (dark_frame_cache.last_collected is not None and time.monotonic() - dark_frame_cache.last_collected > max_age)): init_shutter_state = shutter.get() yield from bps.mv(shutter, 0) yield from bps.trigger(detector, group='cam') yield from bps.wait('cam') yield from bps.mv(shutter, init_shutter_state) teleport(detector, dark_frame_cache) dark_frame_cache.just_started = False dark_frame_cache.update_done = True else: dark_frame_cache.update_done = False
def move_to_start_fly(): "See http://nsls-ii.github.io/bluesky/plans.html#the-per-step-hook" # row_str = short_uid('row') # yield from abs_set(xmotor, row_start, group=row_str) # yield from one_1d_step([temp_nanoKB], motor, step) # yield from bps.wait(group=row_str) print(f"Start moving to beginning of the row") row_str = short_uid('row') yield from bps.checkpoint() yield from bps.abs_set(xmotor, row_start, group=row_str) yield from bps.abs_set(motor, step, group=row_str) yield from bps.wait(group=row_str) # yield from bps.trigger_and_read([temp_nanoKB, motor]) ## Uncomment this print(f"Finished moving to the beginning of the row") print(f"Fast axis: {xmotor.read()} Slow axis: {motor.read()}")
def mv_and_wait(motor, energy, delay=2): """ Move motor to energy[eV], and wait for temperature saturation :param motor : DCM mono angle :param energy : Target Energy :param delay : wait time[sec] """ # wait for finish yield from bps.wait() # move to energy yield from bps.mv(motor, energy) # wait for temperature stabilization yield from bps.sleep(delay)
def dark_plan(self, detector): """The plan to take dark.""" # Restage to ensure that dark frames goes into a separate file. yield from bps.unstage(detector) yield from bps.stage(detector) yield from bps.mv(self.shutter, self.shutter_close) # The `group` parameter passed to trigger MUST start with # bluesky-darkframes-trigger. yield from bps.trigger(detector, group='bluesky-darkframes-trigger') yield from bps.wait('bluesky-darkframes-trigger') snapshot = SnapshotDevice(detector) yield from bps.mv(self.shutter, self.shutter_open) # Restage. yield from bps.unstage(detector) yield from bps.stage(detector) return snapshot
def x_motion_per_step(dets, stream_name): nonlocal last_group nonlocal last_pos nonlocal step_size if last_group is not None: yield from bps.wait(last_group) yield from bps.trigger_and_read(dets, stream_name) last_group = short_uid() if not start < last_pos + step_size < stop: step_size *= -1 last_pos += step_size yield from bps.abs_set(motor, last_pos, group=last_group)
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 # 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 yield from bps.save()
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)
def inner_trigger_and_read(): nonlocal group if group is None: group = short_uid('trigger') no_wait = True for obj in devices: if hasattr(obj, 'trigger'): no_wait = False yield from bps.trigger(obj, group=group) # Skip 'wait' if none of the devices implemented a trigger method. if not no_wait: yield from bps.wait(group=group) yield from bps.create(name) ret = {} # collect and return readings to give plan access to them for obj in devices: reading = (yield from bps.read(obj)) if reading is not None: ret.update(reading) yield from bps.save() return ret
def fly_once(y): # for y in range(num_scans): # go to start of row yield from bps.checkpoint() yield from bps.mv(mono.linear.velocity, 1) yield from bps.mv(mono.linear, l_start) # set the fly speed yield from bps.mv(mono.linear.velocity, flyspeed) yield from bps.trigger_and_read([mono], 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_energy_{y}") if xspress3 is not None: yield from bps.trigger(xspress3, group=f"fly_energy_{y}") # fly the motor yield from bps.abs_set(mono.linear, l_stop + a_l_step_size, group=f"fly_energy_{y}") yield from bps.wait(group=f"fly_energy_{y}") yield from bps.trigger_and_read([mono], name="row_ends") yield from bps.mv(mono.linear.velocity, flyspeed) # hard coded to let the sclr count its fingers and toes yield from bps.sleep(0.1) # read and save the struck yield from bps.create(name="primary") yield from bps.read(sclr) if xspress3 is not None: yield from bps.read(xspress3) yield from bps.save()
def fly_each_step(detectors, motor, step, firststep): "See http://nsls-ii.github.io/bluesky/plans.html#the-per-step-hook" # First, let 'scan' handle the normal y step, including a checkpoint. yield from one_1d_step(detectors, motor, step) # Now do the x steps. v = (xstop - xstart) / (xnum-1) / dwell # compute "stage speed" yield from abs_set(xmotor, xstart - delta, wait=True) # ready to move yield from abs_set(xmotor.velocity, v, wait=True) # set the "stage speed" yield from abs_set(xs.hdf5.num_capture, xnum, wait=True) yield from abs_set(xs.settings.num_images, xnum, wait=True) yield from abs_set(ion.nuse_all,xnum) # arm the Zebra (start caching x positions) yield from kickoff(flying_zebra, xstart=xstart, xstop=xstop, xnum=xnum, dwell=dwell, wait=True) yield from abs_set(ion.erase_start, 1) # 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 bps.trigger(xs, group='row') #if firststep == True: # ttime.sleep(0.) yield from bps.sleep(1.5) yield from abs_set(xmotor, xstop+1*delta, group='row') # move in x yield from bps.wait(group='row') # yield from abs_set(xs.settings.acquire, 0) # stop acquiring images yield from abs_set(ion.stop_all, 1) # stop acquiring scaler yield from complete(flying_zebra) # tell the Zebra we are done yield from collect(flying_zebra) # extract data from Zebra if ('e_tomo' in xmotor.name): v_return = 4 v_max = xmotor.velocity.high_limit if (v_return > v_max): xmotor.velocity.set(v_max) else: xmotor.velocity.set(v_return) else: yield from abs_set(xmotor.velocity, 1.0, wait=True) # set the "stage speed"
def dark_plan(detector): # stash numcapture and shutter_enabled num_capture = yield from bps.rd(detector.hdf5.num_capture) shutter_enabled = yield from bps.rd(detector.dg1.shutter_enabled) # set to 1 temporarily detector.hdf5.num_capture.put(1) # Restage to ensure that dark frames goes into a separate file. yield from bps.unstage(detector) yield from bps.stage(detector) yield from bps.mv(detector.dg1.shutter_enabled, 2) # The `group` parameter passed to trigger MUST start with # bluesky-darkframes-trigger. yield from bps.trigger(detector, group='bluesky-darkframes-trigger') yield from bps.wait('bluesky-darkframes-trigger') snapshot = bluesky_darkframes.SnapshotDevice(detector) # Restage. yield from bps.unstage(detector) # restore numcapture and shutter_enabled yield from bps.mv(detector.hdf5.num_capture, num_capture) yield from bps.mv(detector.dg1.shutter_enabled, shutter_enabled) return snapshot
def plan(): for name, position in samples.items(): # Prepare metadata. md = {'sample': name} # Move to the cetner of the sample position. x_pos, y_pos = position yield from abs_set(x, x_pos) yield from abs_set(y, y_pos) yield from wait() # Scan a grid around that position. yield from relative_outer_product_scan([detector], x, -x_range, x_range, x_num, y, -y_range, y_range, y_num, True, md=md)
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()
def scan_closure(): yield from bps.mv(det.cam.acquire_time, acquire_time) yield from bps.mv(det.cam.acquire_period, acquire_period) # ------------------- # collect white field # ------------------- # 1-1 monitor shutter status, auto-puase scan if beam is lost yield from bps.mv(A_shutter, 'open') yield from bps.install_suspender(suspend_A_shutter) # 1-2 move sample out of the way current_samx = samx.position current_samy = samy.position current_preci = preci.position dx = config['tomo']['sample_out_position']['samx'] dy = config['tomo']['sample_out_position']['samy'] dr = config['tomo']['sample_out_position']['preci'] yield from bps.mv(samx, current_samx + dx) yield from bps.mv(samy, current_samy + dy) yield from bps.mv(preci, current_preci + dr) # 1-2.5 set frame type for an organized HDF5 archive yield from bps.mv(det.cam.frame_type, 0) # 1-3 collect front white field images yield from bps.mv(det.proc1.enable, 1) yield from bps.mv(det.proc1.reset_filter, 1) yield from bps.mv(det.proc1.num_filter, n_frames) yield from bps.mv(det.cam.trigger_mode, "Internal") yield from bps.mv(det.cam.image_mode, "Multiple") yield from bps.mv(det.cam.num_images, n_frames * n_white) yield from bps.trigger_and_read([det]) # 1-4 move sample back yield from bps.mv(samx, current_samx) yield from bps.mv(samy, current_samy) yield from bps.mv(preci, current_preci) # ------------------- # collect projections # ------------------- # 1-4.5 set frame type for an organized HDF5 archive yield from bps.mv(det.cam.frame_type, 1) # 1-5 quicly reset proc1 yield from bps.mv(det.proc1.reset_filter, 1) # 1-6 collect projections yield from motor_set_modulo(preci, 360.0) # configure the psofly interface yield from bps.mv( psofly.start, config['tomo']['omega_start'], psofly.end, config['tomo']['omega_end'], psofly.scan_control, "Standard", psofly.scan_delta, config['tomo']['omega_step'], psofly.slew_speed, slew_speed, preci.velocity, ROT_STAGE_FAST_SPEED, preci.acceleration, slew_speed / accl, ) # taxi yield from bps.mv(psofly.taxi, "Taxi") yield from bps.mv(preci.velocity, slew_speed) # ??? yield from bps.mv( det.cam.num_images, n_projections, det.cam.trigger_mode, "Overlapped", ) # start the fly scan yield from bps.trigger(det, group='fly') yield from bps.abs_set(psofly.fly, "Fly", group='fly') yield from bps.wait(group='fly') # ------------------ # collect back white # ------------------ # 1-7 move the sample out of the way # NOTE: # this will return ALL motors to starting positions, we need a # smart way to calculate a shorter trajectory to move sample # out of way yield from bps.mv(preci, current_preci + dr) yield from bps.mv(samx, current_samx + dx) yield from bps.mv(samy, current_samy + dy) # 1-7.5 set frame type for an organized HDF5 archive yield from bps.mv(det.cam.frame_type, 2) # 1-8 take the back white yield from bps.mv(det.cam.num_images, n_frames * n_white) yield from bps.trigger_and_read([det]) # 1-9 move sample back yield from bps.mv(samx, current_samx) yield from bps.mv(samy, current_samy) yield from bps.mv(preci, current_preci) # ----------------- # collect back dark # ----------------- # 1-10 close the shutter yield from bps.remove_suspender(suspend_A_shutter) yield from bps.mv(A_shutter, "close") # 1-10.5 set frame type for an organized HDF5 archive yield from bps.mv(det.cam.frame_type, 3) # 1-11 collect the back dark yield from bps.mv(det.cam.num_images, n_frames * n_dark) yield from bps.trigger_and_read([det])
def fly_each_step(motor, step, row_start, row_stop): def move_to_start_fly(): "See http://nsls-ii.github.io/bluesky/plans.html#the-per-step-hook" # row_str = short_uid('row') # yield from abs_set(xmotor, row_start, group=row_str) # yield from one_1d_step([temp_nanoKB], motor, step) # yield from bps.wait(group=row_str) row_str = short_uid('row') yield from bps.checkpoint() yield from bps.abs_set(xmotor, row_start, group=row_str) yield from bps.abs_set(motor, step, group=row_str) yield from bps.wait(group=row_str) yield from bps.trigger_and_read([temp_nanoKB, motor]) if verbose: t_mvstartfly = tic() yield from move_to_start_fly() # 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 = row_start x_dial = xmotor.user_readback.get() # Get retry deadband value and check against that i = 0 DEADBAND = 0.050 # retry deadband of nPoint scanner 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, row_start) yield from bps.sleep(0.1) x_dial = xmotor.user_readback.get() if (i != 0): print('done') if verbose: toc(t_mvstartfly, str='Move to start fly each') # 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" if (v > xmotor.velocity.high_limit): raise ValueError( f'Desired motor velocity too high\nMax velocity: {xmotor.velocity.high_limit}' ) elif (v < xmotor.velocity.low_limit): raise ValueError( f'Desired motor velocity too low\nMin velocity: {xmotor.velocity.low_limit}' ) else: yield from mv(xmotor.velocity, 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, group='set') yield from abs_set(xs.settings.num_images, xnum, group='set') yield from bps.wait(group='set') # yield from mv(xs.hdf5.num_capture, xnum, # xs.settings.num_images, xnum) # xs.hdf5.num_capture.put(xnum) # xs.settings.num_images.put(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.hdf5.num_frames_chunks, 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, 2 * xnum) # arm the Zebra (start caching x positions) # @timer_wrapper def zebra_kickoff(): if row_start < row_stop: yield from kickoff(flying_zebra, xstart=xstart, xstop=xstop, xnum=xnum, dwell=dwell, wait=True) else: yield from kickoff(flying_zebra, xstart=xstop, xstop=xstart, xnum=xnum, dwell=dwell, wait=True) if verbose: t_zebkickoff = tic() yield from zebra_kickoff() if verbose: toc(t_zebkickoff, str='Zebra kickoff') if verbose: t_datacollect = tic() # 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) if verbose: toc(t_datacollect, str=' reset scaler') # trigger all of the detectors row_str = short_uid('row') if verbose: print('Data collection:') for d in flying_zebra.detectors: if verbose: print(f' triggering {d.name}') st = yield from bps.trigger(d, group=row_str) st.add_callback(lambda x: toc( t_datacollect, str= f" status object {datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S.%f')}" )) if (d.name == 'dexela'): yield from bps.sleep(1) if verbose: toc(t_datacollect, str=' trigger detectors') # yield from bps.sleep(1.5) if verbose: toc(t_datacollect, str=' sleep') # start the 'fly' def print_watch(*args, **kwargs): with open('/home/xf05id1/bluesky_output.txt', 'a') as f: f.write( datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S.%f\n')) # print(args) f.write(json.dumps(kwargs)) f.write('\n') st = yield from abs_set(xmotor, row_stop, group=row_str) # st.watch(print_watch) if verbose: toc(t_datacollect, str=' move start') if verbose and False: ttime.sleep(1) while (xmotor.motor_is_moving.get()): ttime.sleep(0.001) toc(t_datacollect, str=' move end') while (xs.settings.detector_state.get()): ttime.sleep(0.001) toc(t_datacollect, str=' xs done') while (sclr1.acquiring.get()): ttime.sleep(0.001) toc(t_datacollect, str=' sclr1 done') # wait for the motor and detectors to all agree they are done yield from bps.wait(group=row_str) st.wait() if verbose: toc(t_datacollect, str='Total time') # we still know about ion from above yield from abs_set(ion.stop_all, 1) # stop acquiring scaler # set speed back reset_scanner_velocity() # @timer_wrapper def zebra_complete(): yield from complete(flying_zebra) # tell the Zebra we are done if verbose: t_zebcomplete = tic() yield from zebra_complete() if verbose: toc(t_zebcomplete, str='Zebra complete') # @timer_wrapper def zebra_collect(): yield from collect(flying_zebra) # extract data from Zebra if verbose: t_zebcollect = tic() yield from zebra_collect() if verbose: toc(t_zebcollect, str='Zebra collect')