Esempio n. 1
0
    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.")
Esempio n. 2
0
    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.")
Esempio n. 3
0
    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.")
Esempio n. 4
0
    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()
Esempio n. 5
0
    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()
Esempio n. 6
0
    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()
Esempio n. 7
0
    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()
Esempio n. 8
0
    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()
Esempio n. 9
0
    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()