class User(): target_x = Motor('MEC:USR:MMS:17', name='target_x_motor') YFEon = YFEon YFEoff = YFEoff HWPon = HWPon SHG_opt = SHG_opt save_scope_to_eLog = save_scope_to_eLog def start_seq(self, rate=120, wLPLaser=False): if rate == 120: sync_mark = 6 #int(_sync_markers[120]) elif rate == 60: sync_mark = 5 elif rate == 30: sync_mark = 4 elif rate == 10: sync_mark = 3 elif rate == 5: sync_mark = 2 elif rate == 1: sync_mark = 1 elif rate == 0.5: sync_mark = 0 seq.sync_marker.put(sync_mark) seq.play_mode.put(2) # Run sequence forever ff_seq = [[169, 0, 0, 0]] if wLPLaser: ff_seq.append([182, 0, 0, 0]) seq.sequence.put_seq(ff_seq) seq.start() _seq = Sequence() _sync_markers = {0.5: 0, 1: 1, 5: 2, 10: 3, 30: 4, 60: 5, 120: 6, 360: 7} nsl = NanoSecondLaser() fsl = FemtoSecondLaser() shutters = [1, 2, 3, 4, 5, 6] _shutters = { 1: shutter1, 2: shutter2, 3: shutter3, 4: shutter4, 5: shutter5, 6: shutter6 } seq_a_pvs = [ EpicsSignal('MEC:ECS:IOC:01:EC_6:00'), EpicsSignal('MEC:ECS:IOC:01:EC_6:01'), EpicsSignal('MEC:ECS:IOC:01:EC_6:02'), EpicsSignal('MEC:ECS:IOC:01:EC_6:03'), EpicsSignal('MEC:ECS:IOC:01:EC_6:04'), EpicsSignal('MEC:ECS:IOC:01:EC_6:05'), EpicsSignal('MEC:ECS:IOC:01:EC_6:06'), EpicsSignal('MEC:ECS:IOC:01:EC_6:07'), EpicsSignal('MEC:ECS:IOC:01:EC_6:08'), EpicsSignal('MEC:ECS:IOC:01:EC_6:09') ] seq_b_pvs = [ EpicsSignal('MEC:ECS:IOC:01:BD_6:00'), EpicsSignal('MEC:ECS:IOC:01:BD_6:01'), EpicsSignal('MEC:ECS:IOC:01:BD_6:02'), EpicsSignal('MEC:ECS:IOC:01:BD_6:03'), EpicsSignal('MEC:ECS:IOC:01:BD_6:04'), EpicsSignal('MEC:ECS:IOC:01:BD_6:05'), EpicsSignal('MEC:ECS:IOC:01:BD_6:06'), EpicsSignal('MEC:ECS:IOC:01:BD_6:07'), EpicsSignal('MEC:ECS:IOC:01:BD_6:08'), EpicsSignal('MEC:ECS:IOC:01:BD_6:09') ] def open_shutters(self): print("Opening shutters...") for shutter in self.shutters: self._shutters[shutter].open() time.sleep(5) def close_shutters(self): print("Closing shutters...") for shutter in self.shutters: self._shutters[shutter].close() time.sleep(5) def seq_wait(self): time.sleep(0.5) while seq.play_status.get() != 0: time.sleep(0.5) def scalar_sequence_write(self, s): for i in range(len(s)): self.seq_a_pvs[i].put(s[i][0]) for j in range(len(s)): self.seq_b_pvs[j].put(s[j][1]) seq.sequence_length.put(len(s))
class User(): target_x = Motor('MEC:USR:MMS:17', name='target_x_motor') YFEon = YFEon YFEoff = YFEoff HWPon = HWPon SHG_opt = SHG_opt save_scope_to_eLog = save_scope_to_eLog def start_seq(self, rate=120, wLPLaser=False): if rate==120: sync_mark = 6#int(_sync_markers[120]) elif rate==60: sync_mark = 5 elif rate==30: sync_mark = 4 elif rate==10: sync_mark = 3 elif rate==5: sync_mark = 2 elif rate==1: sync_mark = 1 elif rate==0.5: sync_mark = 0 seq.sync_marker.put(sync_mark) seq.play_mode.put(2) # Run sequence forever ff_seq = [[169, 0, 0, 0]] if wLPLaser: ff_seq.append([182, 0, 0, 0]) seq.sequence.put_seq(ff_seq) seq.start() def start_seq_120Hz(self): #self.start_seq_120Hz(120) sync_mark = 6#int(_sync_markers[120]) seq.sync_marker.put(sync_mark) seq.play_mode.put(2) # Run sequence forever ff_seq = [[169, 0, 0, 0]] seq.sequence.put_seq(ff_seq) seq.start() def start_seq_10Hz(self, wLPLaser=False): sync_mark = 3#int(_sync_markers[10]) seq.sync_marker.put(sync_mark) seq.play_mode.put(2) # Run sequence forever ff_seq = [[169, 0, 0, 0]] if wLPLaser: ff_seq.append([182, 0, 0, 0]) seq.sequence.put_seq(ff_seq) seq.start() _seq = Sequence() _sync_markers = {0.5:0, 1:1, 5:2, 10:3, 30:4, 60:5, 120:6, 360:7} nsl = NanoSecondLaser() fsl = FemtoSecondLaser() shutters = [1,2,3,4,5,6] _shutters = {1: shutter1, 2: shutter2, 3: shutter3, 4: shutter4, 5: shutter5, 6: shutter6} seq_a_pvs = [EpicsSignal('MEC:ECS:IOC:01:EC_6:00'), EpicsSignal('MEC:ECS:IOC:01:EC_6:01'), EpicsSignal('MEC:ECS:IOC:01:EC_6:02'), EpicsSignal('MEC:ECS:IOC:01:EC_6:03'), EpicsSignal('MEC:ECS:IOC:01:EC_6:04'), EpicsSignal('MEC:ECS:IOC:01:EC_6:05'), EpicsSignal('MEC:ECS:IOC:01:EC_6:06'), EpicsSignal('MEC:ECS:IOC:01:EC_6:07'), EpicsSignal('MEC:ECS:IOC:01:EC_6:08'), EpicsSignal('MEC:ECS:IOC:01:EC_6:09')] seq_b_pvs = [EpicsSignal('MEC:ECS:IOC:01:BD_6:00'), EpicsSignal('MEC:ECS:IOC:01:BD_6:01'), EpicsSignal('MEC:ECS:IOC:01:BD_6:02'), EpicsSignal('MEC:ECS:IOC:01:BD_6:03'), EpicsSignal('MEC:ECS:IOC:01:BD_6:04'), EpicsSignal('MEC:ECS:IOC:01:BD_6:05'), EpicsSignal('MEC:ECS:IOC:01:BD_6:06'), EpicsSignal('MEC:ECS:IOC:01:BD_6:07'), EpicsSignal('MEC:ECS:IOC:01:BD_6:08'), EpicsSignal('MEC:ECS:IOC:01:BD_6:09')] def open_shutters(self): print("Opening shutters...") for shutter in self.shutters: self._shutters[shutter].open() time.sleep(5) def close_shutters(self): print("Closing shutters...") for shutter in self.shutters: self._shutters[shutter].close() time.sleep(5) def seq_wait(self): time.sleep(0.5) while seq.play_status.get() != 0: time.sleep(0.5) def scalar_sequence_write(self, s): for i in range(len(s)): self.seq_a_pvs[i].put(s[i][0]) for j in range(len(s)): self.seq_b_pvs[j].put(s[j][1]) seq.sequence_length.put(len(s)) 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()
class User(): thz_blocked_pos = 10.0 thz_passed_pos = 50.0 spl_blocked_pos = 5.94 spl_passed_pos = 2.5 thz_motor = thz_motor spl_motor = spl_motor shutters = [1, 2, 3, 4, 5, 6] _shutters = { 1: shutter1, 2: shutter2, 3: shutter3, 4: shutter4, 5: shutter5, 6: shutter6 } _seq = Sequence() _sync_markers = {0.5: 0, 1: 1, 5: 2, 10: 3, 30: 4, 60: 5, 120: 6, 360: 7} nstiming = nstiming fstiming = fstiming def lpl_save_master_timing(self): lpl_save_master_timing() def open_shutters(self): print("Opening shutters...") for shutter in self.shutters: self._shutters[shutter].open() def close_shutters(self): print("Closing shutters...") for shutter in self.shutters: self._shutters[shutter].close() # def longpulse_shot(self, record=True, end_run=True): 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.") # yield from count([daq, seq], num=1) # # if end_run: # time.sleep(3) # daq.end_run() # # # print("Opening shutters...") # for shutter in self.shutters: # self._shutters[shutter].open() # def xrd_cal(self, nshots=1, record=True, end_run=True): def xrd_cal(self, nshots=1, record=True): """ Returns a BlueSky plan to perform an XRD calibration run. Collects a number of X-ray only shots. 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.xrd_cal 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("Blocking Short Pulse...") # yield from bps.mv(self.spl_motor, self.spl_blocked_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.darkXraySequence(1) seq.sequence.put_seq(s) print("Now run 'daq.begin_infinite()' and press 'start' on the", "sequencer.") # yield from count([daq, seq], num=1) # # if end_run: # time.sleep(3) # daq.end_run() # print("Opening shutters...") # for shutter in self.shutters: # self._shutters[shutter].open() # def ech_background(self, nshots=1, record=True, end_run=True): 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.") # yield from count([daq, seq], num=1) # # if end_run: # time.sleep(3) # daq.end_run() # print("Opening shutters...") # for shutter in self.shutters: # self._shutters[shutter].open() # def thz_reference(self, nshots=1, record=True, end_run=True): def thz_reference(self, nshots=1, record=True): """ Returns a BlueSky plan to perform an THz reference run. Collects a number of short pulse laser shots with THz generation un-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.thz_reference with parameters:") logging.debug("nshots: {}".format(nshots)) 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...") 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.") # yield from count([daq, seq], num=1) # # if end_run: # time.sleep(3) # daq.end_run() # # print("Opening shutters...") # for shutter in self.shutters: # self._shutters[shutter].open() # def thz_drive(self, record=True, end_run=True): 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.")
class User(): grid = XYTargetGrid(x=tx_motor, y=ty_motor, x_init=0.0, y_init=0.0, x_spacing=-0.363, y_spacing=0.363, x_comp=0.01, y_comp=0.01, name='lv25_targetgrid') _seq = Sequence() _sync_markers = {0.5: 0, 1: 1, 5: 2, 10: 3, 30: 4, 60: 5, 120: 6, 360: 7} shutters = [1, 2, 3, 4, 5, 6] _shutters = { 1: shutter1, 2: shutter2, 3: shutter3, 4: shutter4, 5: shutter5, 6: shutter6 } def open_shutters(self): print("Opening shutters...") for shutter in self.shutters: self._shutters[shutter].open() time.sleep(5) def close_shutters(self): print("Closing shutters...") for shutter in self.shutters: self._shutters[shutter].close() time.sleep(5) 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 _x_position(self, xstart, xspacing, ix, iy, dxx=0.0, dxy=0.0): """ Determine the appropriate X position of a motor on a grid, given regular, measured deviations from the ideal grid due to mounting, etc. If deviations are omitted, then this will simply return the ideal grid position given the defined spacing. Parameters ---------- xstart : float Initial x position (e.g. x position of target "zero"). xspacing : float Ideal spacing for grid. ix : int Zero-indexed target x-index. iy : int Zero-indexed target y-index. dxx : float (default=0.0) Deviation in x position per x-index from ideal. dxy : float (deafult=0.0) Deviation in x position per y-index from ideal. """ return xstart + (xspacing + dxx) * ix + dxy * iy def _y_position(self, ystart, yspacing, ix, iy, dyy=0.0, dyx=0.0): """ Determine the appropriate Y position of a motor on a grid, given regular, measured deviations from the ideal grid due to mounting, etc. If deviations are omitted, then this will simply return the ideal grid position given the defined spacing. Parameters ---------- ystart : float Initial y position (e.g. y position of target "zero"). yspacing : float Ideal spacing for grid. ix : int Zero-indexed target x-index. iy : int Zero-indexed target y-index. dyy : float (default=0.0) Deviation in y position per y-index from ideal. dyx : float (deafult=0.0) Deviation in y position per x-index from ideal. """ return ystart + (yspacing + dyy) * iy + dyx * ix def _list_scan_positions(self, xstart, xspacing, ystart, yspacing, nx, ny, dxx=0.0, dxy=0.0, dyy=0.0, dyx=0.0): """ Return lists of x and y positions for use in a BlueSky list_scan plan. Calculates x and y positions for a sample grid given any non-idealities in the grid alignment. Parameters ---------- xstart : float Initial x position (e.g. x position of target "zero"). xspacing : float Ideal spacing for grid. ystart : float Initial y position (e.g. y position of target "zero"). yspacing : float Ideal spacing for grid. nx : int The number of x positions in the grid. ny : int The number of y positions in the grid. dxx : float (default=0.0) Deviation in x position per x-index from ideal. dxy : float (deafult=0.0) Deviation in x position per y-index from ideal. dyy : float (default=0.0) Deviation in y position per y-index from ideal. dyx : float (deafult=0.0) Deviation in y position per x-index from ideal. """ xl = [] yl = [] for i in range(ny): for j in range(nx): xl.append( self._x_position(xstart, xspacing, j, i, dxx=dxx, dxy=dxy)) yl.append( self._y_position(ystart, yspacing, j, i, dyy=dyy, dyx=dyx)) return xl, yl 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() 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 __init__(self, laser_config): self.laser_config = laser_config self.alias = "LASER_SIM" self._seq = Sequence() self._cdb = pycdb.Db(daq._control.dbpath()) self.parent = None
def __init__(self): self.alias = "LASER_SIM" self._seq = Sequence() self._cdb = pycdb.Db(daq._control.dbpath())