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 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 wrapper(*args, **kwargs): # Get the initial positions of all the inputted devices initial_positions = {dev: dev.position for dev in devices} try: return (yield from func(*args, **kwargs)) finally: # Start returning all the devices to their initial positions if perform: group = short_uid('set') for dev, pos in initial_positions.items(): yield from abs_set(dev, pos, group=group) # Wait for all the moves to finish if they haven't already yield from plan_wait(group=group)
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 _inner_Escan_list(): yield from moveE(energy_list[0]+0.001) for energy, factor in zip(energy_list, factor_list): # Change counting time for detector, original_preset in zip(detectors, dets_preset): yield from mv(detector.preset_monitor, factor*original_preset) # Move and scan grp = short_uid('set') yield Msg('checkpoint') yield from moveE(energy, group=grp) if dichro: yield from dichro_steps(detectors, _positioners, trigger_and_read) else: yield from trigger_and_read(list(detectors)+_positioners)
def insert_dark_frame(force_read, msg=None): # Acquire a fresh Snapshot if we need one, or retrieve a cached one. state = {} for signal in self.locked_signals: reading = yield from bluesky.plan_stubs.read(signal) # Restructure # {'data_key': {'value': <value>, 'timestamp': <timestamp>}, ...} # into (('data_key', <value>) ...). values_only = tuple( (k, v['value']) for k, v in reading.items()) state[signal.name] = values_only try: snapshot = self.get_snapshot(state) except NoMatchingSnapshot: # If we are here, we either haven't taken a reading when the # locked_signals were in this state, or the last such reading # we took has aged out of the cache. We have to trigger the # hardware and get a fresh snapshot. logger.info("Taking a new %r reading for state=%r", self.stream_name, state) snapshot = yield from self._partialed_dark_plan() self.add_snapshot(snapshot, state) # If the Snapshot is the same as the one we most recently inserted, # then we don't need to create a new Event. The previous Event # still holds. snapshot_changed = snapshot is not self._current_snapshot.get_snapshot( ) if snapshot_changed or force_read: logger.info("Creating a %r Event for state=%r", self.stream_name, state) self._current_snapshot.set_snaphsot(snapshot) # Read the Snapshot. This does not actually trigger hardware, # but it goes through all the bluesky steps to generate new # Event. # The reason we handle self._current_snapshot here instead of # snapshot itself is the bluesky RunEngine notices if you give # it a different object than you had given it earlier. Thus, # bluesky will always see the "Device" self._current_snapshot # here, and it will be satisfied. yield from bps.stage(self._current_snapshot) yield from trigger_and_read([self._current_snapshot], name=self.stream_name, group=short_uid(GROUP_PREFIX)) yield from bps.unstage(self._current_snapshot) self._latch = False if msg is not None: return (yield msg)
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 stage(self): file_stem = short_uid() self._datum_counter = itertools.count() self._path_stem = os.path.join(self.save_path, file_stem) self._resource_uid = new_uid() resource = { 'spec': 'NPY_SEQ', 'root': self.save_path, 'resource_path': file_stem, 'resource_kwargs': {}, 'uid': self._resource_uid, 'path_semantics': { 'posix': 'posix', 'nt': 'windows' }[os.name] } self._asset_docs_cache.append(('resource', resource))
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 stage(self): self._file_stem = short_uid() self._path_stem = os.path.join(self.save_path, self._file_stem) self._resource_id = self.fs.insert_resource(self.filestore_spec, self._file_stem, {}, root=self.save_path)
def stage(self): self._file_stem = short_uid() self._path_stem = os.path.join(self.save_path, self._file_stem) self._resource_id = self.fs.insert_resource(self.filestore_spec, self._path_stem, {})
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')