def ech_background(self, nshots=1, record=True): """ Returns a BlueSky plan to perform an echelon background run. Collects a number of short pulse shots with THz generation blocked. Parameters: ----------- nshots : int <default: 1> The number of shots that you would like to take in the run. record : bool <default: True> Flag to record the data (or not). """ # end_run : bool <default: True> # Flag to end the run after completion (or not). logging.debug("Calling User.ech_background with parameters:") logging.debug("nshots: {}".format(nshots)) logging.debug("record: {}".format(record)) # logging.debug("end_run: {}".format(end_run)) print("Closing shutters...") for shutter in self.shutters: self._shutters[shutter].close() # Block THz generation print("Blocking THz generation...") yield from bps.mv(self.thz_motor, self.thz_blocked_pos, wait=True) # Block SPL print("Un-Blocking Short Pulse...") yield from bps.mv(self.spl_motor, self.spl_passed_pos, wait=True) # print("Configuring DAQ...") # daq.configure(events=nshots, record=record) daq.configure(record=record) print("Configuring sequencer...") # Setup the pulse picker for single shots in flip flop mode pp.flipflop(wait=True) # Setup sequencer for requested rate sync_mark = int(self._sync_markers[5]) seq.sync_marker.put(sync_mark) seq.play_mode.put(1) # Run multiple times seq.rep_count.put(nshots) # Setup sequence self._seq.rate = 5 s = self._seq.opticalSequence(1, 'shortpulse') seq.sequence.put_seq(s) print("Now run 'daq.begin_infinite()' and press 'start' on the", "sequencer.")
def longpulse_shot(self, record=True): """ Returns a BlueSky plan to perform a long pulse laser shot. Collects a long pulse laser only shot. Parameters: ----------- record : bool <default: True> Flag to record the data (or not). """ # end_run : bool <default: True> # Flag to end the run after completion (or not). logging.debug("Calling User.longpulse_shot with parameters:") logging.debug("record: {}".format(record)) # logging.debug("end_run: {}".format(end_run)) print("Closing shutters...") for shutter in self.shutters: self._shutters[shutter].close() # Block THz generation # print("Blocking THz generation...") # yield from bps.mv(self.thz_motor, self.thz_blocked_pos, wait=True) # # # Block SPL # print("Blocking Short Pulse...") # yield from bps.mv(self.spl_motor, self.spl_blocked_pos, wait=True) print("Configuring DAQ...") # daq.configure(events=1, record=record) daq.configure(record=record) print("Configuring sequencer...") # Setup the pulse picker for single shots in flip flop mode pp.flipflop(wait=True) # Setup sequencer for requested rate sync_mark = int(self._sync_markers[10]) seq.sync_marker.put(sync_mark) seq.play_mode.put(0) # Run sequence once # Setup sequence self._seq.rate = 10 # s = self._seq.opticalSequence(1, 'longpulse') s = self._seq.duringSequence(1, 'longpulse') seq.sequence.put_seq(s) print("Now run 'daq.begin_infinite()' and press 'start' on the", "sequencer.")
def thz_drive(self, record=True): """ Returns a BlueSky plan to perform a shot with the short pulse, THz generation, and long pulse drive, with the XFEL. Takes a single shot. Parameters: ----------- record : bool <default: True> Flag to record the data (or not). """ # end_run : bool <default: True> # Flag to end the run after completion (or not). logging.debug("Calling User.thz_drive with parameters:") logging.debug("record: {}".format(record)) #logging.debug("end_run: {}".format(end_run)) # Un-Block THz generation print("Un-Blocking THz generation...") yield from bps.mv(self.thz_motor, self.thz_passed_pos, wait=True) # Un-Block SPL print("Un-Blocking Short Pulse...") print("Configuring DAQ...") #daq.configure(events=1, record=record) daq.configure(record=record) print("Configuring sequencer...") # Setup the pulse picker for single shots in flip flop mode pp.flipflop(wait=True) # Setup sequencer for requested rate sync_mark = int(self._sync_markers[10]) seq.sync_marker.put(sync_mark) seq.play_mode.put(0) # Run once # Setup sequence self._seq.rate = 10 s = self._seq.dualDuringSequence() seq.sequence.put_seq(s) print("Now run 'daq.begin_infinite()' and press 'start' on the", "sequencer.")
def _single_shot_plan(self, record=True, use_l3t=False, controls=[], end_run=True): """Definition of plan for taking laser shots with the MEC laser.""" # TODO: Add attenuator control logging.debug("Generating shot plan using _shot_plan.") logging.debug("_shot_plan config:") logging.debug("{}".format(self._config)) logging.debug("Record: {}".format(record)) logging.debug("use_l3t: {}".format(use_l3t)) logging.debug("controls: {}".format(controls)) # Make sure that any updates to configuration are applied self.configure(self._config) # Setup the daq based on config total_shots = 1 print("Configured for {} total shots.".format(total_shots)) logging.debug("Total shots: {}".format(total_shots)) yield from bps.configure(daq, begin_sleep=2, record=record, use_l3t=use_l3t, controls=controls) # Add sequencer, DAQ to detectors for shots dets = [daq, seq] for det in dets: yield from bps.stage(det) # Check for slow cameras, stage if requested if self._config['slowcam']: from .slowcams import SlowCameras self._slowcams = SlowCameras() dets.append(self._slowcams) # Add this in to auto-unstage later yield from bps.stage(self._slowcams) # Setup the pulse picker for single shots in flip flop mode pp.flipflop(wait=True) # Setup sequencer for requested rate sync_mark = int(self._sync_markers[self._config['rate']]) seq.sync_marker.put(sync_mark) seq.play_mode.put(0) # Run sequence once # Dual (FSL + NSL + XFEL) shots shots = total_shots logging.debug("Configuring for {} dual shots".format(shots)) yield from bps.configure(daq, events=shots) # Preshot dark, so use preshot laser marker dual_seq = self._seq.dualDuringSequence() seq.sequence.put_seq(dual_seq) # Number of shots is determined by sequencer, so just trigger/read print("Taking {} shots shots ... ".format(shots)) yield from bps.trigger_and_read(dets) for det in dets: yield from bps.unstage(det) if end_run: daq.end_run()
def _single_shot_plan(self, record=True, use_l3t=False, controls=[], end_run=True): """Definition of plan for taking laser shots with the MEC laser.""" # TODO: Add attenuator control logging.debug("Generating shot plan using _shot_plan.") logging.debug("_shot_plan config:") logging.debug("{}".format(self._config)) logging.debug("Record: {}".format(record)) logging.debug("use_l3t: {}".format(use_l3t)) logging.debug("controls: {}".format(controls)) # Make sure that any updates to configuration are applied self.configure(self._config) # Check number of shots for long pulse laser if self._config['laser'] == 'longpulse': lpl_shots = self._config['preo'] + self._config['during'] + \ self._config['posto'] if lpl_shots > 1: m = ("Cannot shoot the long pulse laser more than once in a " "sequence! Please reduce the number of optical shots " "requested to 1!") raise Exception(m) # Setup the daq based on config total_shots = self._config['predark'] + self._config['prex'] + \ self._config['preo'] + self._config['postdark'] + \ self._config['postx'] + self._config['posto'] + \ self._config['during'] print("Configured for {} total shots.".format(total_shots)) logging.debug("Total shots: {}".format(total_shots)) yield from bps.configure(daq, events=0, begin_sleep=2, record=record, use_l3t=use_l3t, controls=controls) # Add sequencer, DAQ to detectors for shots dets = [daq, seq] for det in dets: yield from bps.stage(det) # Check for slow cameras, stage if requested if self._config['slowcam']: from .slowcams import SlowCameras self._slowcams = SlowCameras() dets.append(self._slowcams) # Add this in to auto-unstage later yield from bps.stage(self._slowcams) # Setup the pulse picker for single shots in flip flop mode pp.flipflop(wait=True) # Setup sequencer for requested rate sync_mark = int(self._sync_markers[self._config['rate']]) seq.sync_marker.put(sync_mark) seq.play_mode.put(0) # Run sequence once # Dark (no optical laser, no XFEL) shots if self._config['predark'] > 0: # Get number of predark shots shots = self._config['predark'] logging.debug("Configuring for {} predark shots".format(shots)) # yield from bps.configure(daq, events=shots) # Preshot dark, so use preshot laser marker pre_dark_seq = self._seq.darkSequence(shots, preshot=True) seq.sequence.put_seq(pre_dark_seq) # Number of shots is determined by sequencer, so just trigger/read print("Taking {} predark shots ... ".format(self._config['predark'])) yield from bps.trigger_and_read(dets) # Pre-xray (no optical laser, XFEL only) shots if self._config['prex'] > 0: # Get number of prex shots shots = self._config['prex'] logging.debug("Configuring for {} prex shots".format(shots)) # yield from bps.configure(daq, events=shots) # Preshot x-ray only shots, so use preshot laser marker prex_seq = self._seq.darkXraySequence(shots, preshot=True) seq.sequence.put_seq(prex_seq) # Number of shots is determined by sequencer, so just trigger/read print("Taking {} prex shots ... ".format(shots)) yield from bps.trigger_and_read(dets) # Pre-optical (optical laser only, no XFEL) shots if self._config['preo'] > 0: # Get number of preo shots shots = self._config['preo'] logging.debug("Configuring for {} preo shots".format(shots)) # yield from bps.configure(daq, events=shots) # Optical only shot, with defined laser preo_seq = self._seq.opticalSequence(shots, self._config['laser'],\ preshot=True) seq.sequence.put_seq(preo_seq) # Number of shots is determined by sequencer, so just take 1 count print("Taking {} preo shots ... ".format(shots)) yield from bps.trigger_and_read(dets) # 'During' (optical laser + XFEL) shots if self._config['during'] > 0: # Get number of during shots shots = self._config['during'] logging.debug("Configuring for {} during shots".format(shots)) # yield from bps.configure(daq, events=shots) # During shot, with defined laser during_seq = self._seq.duringSequence(shots, self._config['laser']) seq.sequence.put_seq(during_seq) # Number of shots is determined by sequencer, so just take 1 count print("Taking {} during shots ... ".format(shots)) yield from bps.trigger_and_read(dets) # Post-optical (optical laser only, no XFEL) shots if self._config['posto'] > 0: # Get number of post optical shots shots = self._config['posto'] logging.debug("Configuring for {} posto shots".format(shots)) # yield from bps.configure(daq, events=shots) # Optical only shot, with defined laser posto_seq = self._seq.opticalSequence(shots, self._config['laser'],\ preshot=False) seq.sequence.put_seq(posto_seq) # Number of shots is determined by sequencer, so just take 1 count print("Taking {} posto shots ... ".format(shots)) yield from bps.trigger_and_read(dets) # Post-xray (no optical laser, XFEL only) shots if self._config['postx'] > 0: # Get number of postx shots shots = self._config['postx'] logging.debug("Configuring for {} postx shots".format(shots)) # yield from bps.configure(daq, events=shots) # Postshot x-ray only shots, so use postshot laser marker postx_seq = self._seq.darkXraySequence(shots, preshot=False) seq.sequence.put_seq(postx_seq) # Number of shots is determined by sequencer, so just take 1 count print("Taking {} postx shots ... ".format(shots)) yield from bps.trigger_and_read(dets) # Dark (no optical laser, no XFEL) shots if self._config['postdark'] > 0: # Get number of postdark shots shots = self._config['postdark'] logging.debug("Configuring for {} postdark shots".format(shots)) # yield from bps.configure(daq, events=shots) # Postshot dark, so use postshot laser marker post_dark_seq = self._seq.darkSequence(shots, preshot=False) seq.sequence.put_seq(post_dark_seq) # Number of shots is determined by sequencer, so just take 1 count print("Taking {} postdark shots ... ".format(shots)) yield from bps.trigger_and_read(dets) for det in dets: yield from bps.unstage(det) if end_run: daq.end_run()
def uxi_shot(self, delta=0.3, record=True, lasps=True): """ Returns a BlueSky plan to run a scan for the LV08 experiment. Used for the UXI camera which requires near continuous acquisition for stable camera behavior. The following shots are combined in a single run. Shot sequence: -------------- 1) 10 dark frames # Warm up camera 2) 10 X-ray frames 3) Sample moves in 4) 10 dark frames # Warm up camera 5) 1 X-ray + Optical laser frame 6) 10 dark frames 7) Sample moves out 8) 10 dark frames # Warm up camera 9) 10 X-ray frames Parameters: ----------- delta : float <default: 0.3> The relative distance in mm to move the sample in and out. record : bool <default: True> Flag to record the data (or not). lasps : bool <default: True> Flag to perform pre-and post shot pulse shaping routines. """ logging.debug("Calling User.shot with parameters:") logging.debug("delta: {}".format(delta)) logging.debug("record: {}".format(record)) logging.debug("lasps: {}".format(lasps)) print("Configuring DAQ...") # yield from bps.configure(daq,events=0, record=record) # run infinitely, let sequencer # control number of events daq.begin_infinite(record=record) long_seq = [[0, 240, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] print("Configuring sequencer...") # Setup the pulse picker for single shots in flip flop mode pp.flipflop(wait=True) # Setup sequencer for requested rate sync_mark = int(self._sync_markers[0.5]) seq.sync_marker.put(sync_mark) seq.play_mode.put(1) # Run N times seq.rep_count.put(10) # Setup sequence self._seq.rate = 0.5 # close the shutters specified by the user for shutter in self.shutters: self._shutters[shutter].close() # Shutters are slow; give them time to close time.sleep(5) if lasps: print("Running mecps.pspreshot()...") pspreshot() # Run 10 Pre-laser dark shots (step 1 above) s = self._seq.darkSequence(1, preshot=False) # seq.sequence.put_seq(long_seq) # seq.sequence.put_seq(s) self.scalar_sequence_write(s) print("Taking 10 dark shots...") time.sleep(1) seq.start() self.seq_wait() # yield from bps.trigger_and_read([daq, seq]) # Run 10 Pre-laser x-ray shots (step 2 above) s = self._seq.darkXraySequence(1, preshot=False) # seq.sequence.put_seq(long_seq) # seq.sequence.put_seq(s) self.scalar_sequence_write(s) print("Taking 10 x-ray shots...") time.sleep(1) seq.start() self.seq_wait() #yield from bps.trigger_and_read([daq, seq]) # Move sample in (step 3 above) print("Moving sample in...") yield from bps.mvr(self.target_x, delta) #TODO Check direction # Run 10 Pre-laser dark shots (step 4 above) print("Taking 10 dark shots...") s = self._seq.darkSequence(1, preshot=False) # seq.sequence.put_seq(long_seq) # seq.sequence.put_seq(s) self.scalar_sequence_write(s) time.sleep(1) seq.start() self.seq_wait() # yield from bps.trigger_and_read([daq, seq]) # Run x-ray + optical sequence (step 5 above) print("Taking optical laser shots...") seq.rep_count.put(1) s = self._seq.duringSequence(1, 'longpulse') # seq.sequence.put_seq(long_seq) # seq.sequence.put_seq(s) self.scalar_sequence_write(s) time.sleep(1) seq.start() self.seq_wait() # yield from bps.trigger_and_read([daq, seq]) # Run 10 Post-laser dark shots (step 6 above) print("Taking 10 dark shots...") seq.rep_count.put(10) s = self._seq.darkSequence(1, preshot=False) # seq.sequence.put_seq(long_seq) # seq.sequence.put_seq(s) self.scalar_sequence_write(s) time.sleep(1) seq.start() self.seq_wait() # yield from bps.trigger_and_read([daq, seq]) # Move sample out (step 7 above) print("Moving sample out...") yield from bps.mvr(self.target_x, -delta) #TODO Check direction # Run 10 Pre-x-ray dark shots (step 8 above) print("Taking 10 dark shots...") seq.rep_count.put(10) s = self._seq.darkSequence(1, preshot=False) # seq.sequence.put_seq(long_seq) # seq.sequence.put_seq(s) self.scalar_sequence_write(s) time.sleep(1) seq.start() self.seq_wait() # yield from bps.trigger_and_read([daq, seq]) # Run 10 Pre-laser x-ray shots (step 9 above) print("Taking 10 x-ray shots...") s = self._seq.darkXraySequence(1, preshot=False) # seq.sequence.put_seq(long_seq) # seq.sequence.put_seq(s) self.scalar_sequence_write(s) time.sleep(1) seq.start() self.seq_wait() # yield from bps.trigger_and_read([daq, seq]) daq.end_run() if lasps: print("Running mecps.pspostshot()...") pspostshot() # open the shutters specified by the user for shutter in self.shutters: self._shutters[shutter].open()
def x_scan(self, nshots=1, record=True, xrays=False, carriage_return=False): """ Returns a BlueSky plan to perform a scan in X. Collects a number of short pulse laser shots while moving from target to target. Parameters: ----------- nshots : int <default: 1> The number of shots that you would like to take in the run. record : bool <default: True> Flag to record the data (or not). xrays : bool <default: False> Flag to do an optical or x-ray shot. If False, does an optical only shot. If True, you do a optical + x-ray shot. carriage_return : bool <default: False> Flag to return to initial position. """ logging.debug("Calling User.x_scan with parameters:") logging.debug("nshots: {}".format(nshots)) logging.debug("record: {}".format(record)) logging.debug("xrays: {}".format(xrays)) print("Configuring DAQ...") daq.configure(events=0, record=record) # run infinitely # daq.begin_infinite() print("Configuring sequencer...") # Setup the pulse picker for single shots in flip flop mode pp.flipflop(wait=True) # Setup sequencer for requested rate sync_mark = int(self._sync_markers[5]) seq.sync_marker.put(sync_mark) seq.play_mode.put(0) # Run once # Setup sequence self._seq.rate = 5 if xrays: s = self._seq.duringSequence(1, 'shortpulse') else: s = self._seq.opticalSequence(1, 'shortpulse') seq.sequence.put_seq(s) self._shutters[6].close() time.sleep(5) # Get starting positions start = self.grid.wm() yield from scan([daq, seq], self.grid.x, start['x'], (start['x'] + self.grid.x_spacing * (nshots - 1)), num=nshots) if carriage_return: # Return to start print("Returning to starting position") yield from bps.mv(self.grid.x, start['x']) yield from bps.mv(self.grid.y, start['y']) daq.end_run() self._shutters[6].open()
def xy_fly_scan(self, nshots, nrows=2, y_distance=None, rate=5, record=True, xrays=True): """ Plan for doing a 2D fly scan. Uses the target x motor as the flying axis, running for a specified distance at a specified velocity, taking shots at a specified rate. Parameters ---------- nshots : int The number of shots to take in the x scan. rate : int <default : 5> The rate at which to take shots (120, 30, 10, 5, 1) y_distance : float <default : x.grid.y_spacing> The distance to move the y stage down. nrows : int <default : 2> The number of "rows" to scan the x stage on. record : bool <default : True> Flag to record the data. xrays : bool <default : True> Flag to take an x-ray + optical (True) shot or optical only (False). """ logging.debug("rate: {}".format(rate)) logging.debug("nshots: {}".format(nshots)) logging.debug("nrows: {}".format(nrows)) logging.debug("record: {}".format(record)) logging.debug("xrays: {}".format(xrays)) if not y_distance: y_distance = self.grid.y_spacing logging.debug("y_distance: {}".format(y_distance)) assert rate in [120, 30, 10, 5, 1], "Please choose a rate in {120, 30, 10,5,1}" print("Configuring DAQ...") daq.configure(events=0, record=record) # run infinitely daq.begin_infinite() print("Configuring sequencer...") # Setup the pulse picker for single shots in flip flop mode pp.flipflop(wait=True) # Setup sequencer for requested rate sync_mark = int(self._sync_markers[rate]) seq.sync_marker.put(sync_mark) seq.play_mode.put(1) # Run for n shots seq.rep_count.put(nshots) # Setup sequence self._seq.rate = rate if xrays: s = self._seq.duringSequence(1, 'shortpulse') else: s = self._seq.opticalSequence(1, 'shortpulse') seq.sequence.put_seq(s) # Get starting positions start = self.grid.wm() # Calculate and set velocity vel = self.grid.x_spacing * rate # mm * (1/s) = mm/s self.grid.x.velocity.put(vel) # Estimate distance to move given requested shots and rate dist = (nshots / rate) * vel # (shots/(shots/sec))*mm/s = mm # Close shutter 6 (requested) self._shutters[6].close() time.sleep(5) for i in range(nrows): if i != 0: yield from bps.mvr(self.grid.y, y_distance) # Play the sequencer seq.play_control.put(1) # Start the move yield from bps.mvr(self.grid.x, dist) # Waits for move to complete # Make sure the sequencer stopped seq.play_control.put(0) yield from bps.mv(self.grid.x, start['x']) # Return to start print("Returning to starting position") yield from bps.mv(self.grid.x, start['x']) yield from bps.mv(self.grid.y, start['y']) daq.end_run() self._shutters[6].open()
def xy_scan(self, nxshots=1, nyshots=1, record=True, xrays=False, carriage_return=False): """ Returns a BlueSky plan to perform a scan in X and Y. Collects a number of short pulse laser shots while moving from target to target. Parameters: ----------- nxshots : int <default: 1> The number of shots that you would like to take on the x axis for each "line" on the target stage. nyshots : int <default: 1> The number of lines that you want to move on the y axis. record : bool <default: True> Flag to record the data (or not). xrays : bool <default: False> Flag to do an optical or x-ray shot. If false, does an optical only shot. If true, you do a optical + x-ray shot. carriage_return : bool <default: False> Flag to return to initial position. """ logging.debug("Calling User.xy_scan with parameters:") logging.debug("nxshots: {}".format(nxshots)) logging.debug("nyshots: {}".format(nyshots)) logging.debug("record: {}".format(record)) logging.debug("xrays: {}".format(xrays)) print("Configuring DAQ...") daq.configure(events=0, record=record) # run infinitely # daq.begin_infinite() print("Configuring sequencer...") # Setup the pulse picker for single shots in flip flop mode pp.flipflop(wait=True) # Setup sequencer for requested rate sync_mark = int(self._sync_markers[5]) seq.sync_marker.put(sync_mark) seq.play_mode.put(0) # Run once # Setup sequence self._seq.rate = 5 if xrays: s = self._seq.duringSequence(1, 'shortpulse') else: s = self._seq.opticalSequence(1, 'shortpulse') seq.sequence.put_seq(s) # Get starting positions start = self.grid.wm() # Get lists of scan positions xl, yl = self._list_scan_positions(start['x'], self.grid.x_spacing, start['y'], self.grid.y_spacing, nxshots, nyshots, dxx=0.0, dxy=self.grid.x_comp, dyy=0.0, dyx=self.grid.y_comp) # Close shutter 6 (requested) self._shutters[6].close() time.sleep(5) # Scan the thing def inner(): yield from list_scan([daq, seq], self.grid.y, yl, self.grid.x, xl) yield from inner() if carriage_return: # Return to start print("Returning to starting position") yield from bps.mv(self.grid.x, start['x']) yield from bps.mv(self.grid.y, start['y']) daq.end_run() self._shutters[6].open()