Пример #1
0
    def __single_shot(self, gasdelay=0.05, shotdelay=10.0, record=True,
                      use_l3t=False, controls=[], end_run=True):
        logging.debug("Calling __single_shot with the folling parameters:")
        logging.debug("gasdelay: {}".format(gasdelay))
        logging.debug("shotdelay: {}".format(shotdelay))
        logging.debug("record: {}".format(record))
        logging.debug("use_l3t: {}".format(use_l3t))
        logging.debug("controls: {}".format(controls))
        logging.debug("end_run: {}".format(end_run))

        nshots = 1

        yield from bps.configure(daq, begin_sleep=2, record=record, use_l3t=use_l3t, controls=controls)
        yield from bps.configure(daq, events=nshots)

        # Add sequencer, DAQ to detectors for shots
        dets = [daq, seq]

        for det in dets:
            yield from bps.stage(det)

        # Setup sequencer for requested rate
        sync_mark = int(self._sync_markers[self._rate])
        seq.sync_marker.put(sync_mark)
        seq.play_mode.put(0) # Run sequence once
    
        # Determine the different sequences needed
        gdelay = int(gasdelay*120)  # 120 beam delays/second    
        sdelay = int(shotdelay*120) # 120 beam delays/second
        slow_cam_seq = [[167, 0, 0, 0]]
        gas_jet_seq = [[177, 0, 0, 0],
                       [176, gdelay, 0, 0],
                       [169, 0, 0, 0],
                       [0, sdelay, 0, 0]]

        s = slow_cam_seq + gas_jet_seq

        logging.debug("Sequence: {}".format(s))
                  
        # Get exposure time in beam deltas from number of shots
        exposure = nshots * (int(shotdelay/120.0) + int(gasdelay/120.0))
        logging.debug("Exposure time: {}".format(exposure*120.0))
        
        # Stage and add in slow cameras *after* daq is staged and configured
        slowcams = SlowCameras()
        # The camera delay and number of 'during' shots are the same in this case (I think)
        config = {'slowcamdelay': exposure, 'during': exposure} 
        dets.append(slowcams) # Add this in to auto-unstage later
        slowcams.stage(config)

        seq.sequence.put_seq(s) 

        yield from bps.trigger_and_read(dets)                

        # If this is the last move in the scan, check cleanup settings
        if end_run:
            daq.end_run() 
Пример #2
0
 def plan():
     # working around 'yield from' here which breaks py2
     for msg in configure(det, {'z': 3}):  # no-op
         yield msg
     for msg in trigger_and_read([det]):
         yield msg
     # changing the config after a read generates a new Event Descriptor
     for msg in configure(det, {'z': 4}):
         yield msg
     for msg in trigger_and_read([det]):
         yield msg
Пример #3
0
 def daq_during_plan():
     yield from bps.configure(daq,
                              events=0,
                              record=record,
                              use_l3t=use_l3t,
                              controls=controls)
     return (yield from bpp.fly_during_wrapper(plan, flyers=[daq]))
Пример #4
0
 def daq_first_cycle(msg):
     yield from bps.configure(daq,
                              events=events,
                              duration=duration,
                              record=record,
                              use_l3t=use_l3t,
                              controls=list(motor_cache))
     return (yield from add_daq_trigger(msg))
Пример #5
0
    def __1DScan(self, motor, start, end, npoints, ndaq, record):
        # Setup the event sequencer for the scan
        logging.debug("Setting up the sequencer for %s daq points", ndaq)
        self.__setup_sequencer(ndaq)

        # Setup the pulse picker
        if pp.mode.get() == 3:
            logging.debug("The pulse picker is already in burst mode")
        else:
            logging.debug("Setting up the pulse picker for burst mode")
            pp.burst(wait=True)

        # Setup the DAQ
        daq.record = record
        daq.configure(events=ndaq)
        bps.configure(daq, events=ndaq)  # For plan introspection

        # Add sequencer, DAQ to detectors for scan
        dets = [daq, seq]

        # Log stuff
        logging.debug("Returning __1DScan with the following parameters:")
        logging.debug("motor: {}".format(motor))
        logging.debug("start: {}".format(start))
        logging.debug("end: {}".format(end))
        logging.debug("npoints: {}".format(npoints))
        logging.debug("ndaq: {}".format(ndaq))
        logging.debug("record: {}".format(record))
        logging.debug("detectors: {}".format(dets))

        # Return the plan
        scan_plan = scan(dets, motor, start, end, npoints)

        final_plan = bpp.finalize_wrapper(scan_plan, self.__cleanup_plan())

        return final_plan
Пример #6
0
def daq_during_wrapper(plan, record=None, use_l3t=False, controls=None):
    """
    Run a plan with the `Daq`.

    This can be used with an ordinary ``bluesky`` plan that you'd like the daq
    to run along with. This also stages the daq so that the run start/stop
    will be synchronized with the bluesky runs.

    This must be applied outside the ``run_wrapper``. All configuration must
    be done by supplying config kwargs to this wrapper.

    The `daq_during_decorator` is the same as the `daq_during_wrapper`,
    but it is meant to be used as a function decorator.

    Parameters
    ----------
    plan: ``plan``
        The ``plan`` to use the daq in

    record: ``bool``, optional
        If ``True``, we'll record the data. Otherwise, we'll run without
        recording. Defaults to ``False``, or the last set value for
        ``record``.

    use_l3t: ``bool``, optional
        If ``True``, an ``events`` argument to begin will be reinterpreted
        to only count events that pass the level 3 trigger. Defaults to
        ``False``.

    controls: ``dict{name: device}`` or ``list[device...]``, optional
        If provided, values from these will make it into the DAQ data
        stream as variables. We will check ``device.position`` and
        ``device.value`` for quantities to use and we will update these
        values each time begin is called. To provide a list, all devices
        must have a ``name`` attribute.
    """
    daq = get_daq()
    yield from configure(daq,
                         events=None,
                         duration=None,
                         record=record,
                         use_l3t=use_l3t,
                         controls=controls)
    yield from stage_wrapper(fly_during_wrapper(plan, flyers=[daq]), [daq])
Пример #7
0
def config_by_ai(cb: CalibrationData, ai: pyFAI.AzimuthalIntegrator) -> tp.Generator:
    """Configure the calibration data in an area detector using the AzimuthalIntegrator.

    Parameters
    ----------
    cb : CalibrationData
        The device that hold the calibration data.

    ai : AzimuthalIntegrator
        The pyFAI AzimuthalIntegrator

    Yields
    ------
    Msg : Msg
        The bluesky message.
    """
    return (
        yield from bps.configure(cb, {"dist": ai.dist, "poni1": ai.poni1, "poni2": ai.poni2, "rot1": ai.rot1,
                                      "rot2": ai.rot2, "rot3": ai.rot3, "detector": ai.detector.name,
                                      "wavelength": ai.wavelength, "pixel1": ai.pixel1, "pixel2": ai.pixel2})
    )
Пример #8
0
def Tramp2(dets: list,
           exposure: float,
           Tstart: float,
           Tstop: float,
           Tstep: float,
           *,
           ramp_rate: float = None):
    """A temperature ramping plan with ramping rate configuration.

    The ramping rate will be configured before the ramping start. The ramping will be done continuously
    without holding temperature at exposure.

    Parameters
    ----------
    dets : list
        A list of detectors. Dummy. Not used.

    exposure : float
        The exposure time in second.

    Tstart : float
        The start temperature in K (included).

    Tstop : float
        The stop temperature in K (incldued)

    Tstep : float
        The temperature step in K.

    ramp_rate : float
        The temperature ramping rate. Make sure the temperature controller has the `velocity` configuration.

    Yields
    ------
    Bluesky plan.
    """
    temp_controller: SynAxis = xpd_configuration["temp_controller"]
    if ramp_rate is not None:
        yield from bps.configure(temp_controller, {"velocity": ramp_rate})
    yield from Tramp(dets, exposure, Tstart, Tstop, Tstep)
Пример #9
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,
                                 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()
Пример #10
0
 def _internal_plan(dets):
     yield from trigger_and_read(dets)
     for det in dets:
         yield from configure(det, {})
     yield from trigger_and_read(dets)
Пример #11
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()
Пример #12
0
    def __jet_scan(self, motor1, m1start, m1end, m1step, motor2, m2start,
                   m2end, m2step, gasdelay=0.05, shotdelay=10.0,
                   record=True, use_l3t=False, controls=[], end_run=True,
                   carriage_return=True):
        """
        Scan for the LU60 gas jet experiment. 

        Parameters:
        -----------
        motor1 : motor
            The first motor on which to run the scan.

        m1start : float
            The position to start the scan for motor1. The motor will travel to
            this position prior to beginning the scan.

        m1end : float
            The position to end the scan on for motor1.

        m1steps : float
            The number of steps for motor 1

        motor2 : motor
            The second motor on which to run the scan.

        m2start : float
            The position to start the scan for motor2. The motor will travel to
            this position prior to beginning the scan.

        m2end : float
            The position to end the scan on for motor 2.

        m2steps : float
            The number of steps for motor 2.

        gasdelay : float (default: 0.05)
            The number of seconds to wait for the gas jet to be ready after the
            trigger.

        shotdelay : float (default: 10.0)
            The number of seconds to wait between shots. This is empirically
            derived, and is used to allow the chamber pressure to equillibrate
            following a gas jet puff.  

        record : bool (default: True)
            Option to record the scan in the DAQ (or not).

        use_l3t : bool (default: False)
            Option to use a level 3 trigger (or not) in the scan.

        controls : list (default: [])
            Optional list of devices to add to the DAQ data stream. Devices 
            added in this way will have their device.position or device.value
            quantities added to the scan.

        end_run : bool (default: True)
            Option to end the run after the scan. This will cause a new run to
            be initiated during the next scan.
        """

        logging.debug("Calling __jet_scan with the folling parameters:")
        logging.debug("motor1: {}".format(motor1))
        logging.debug("m1start: {}".format(m1start))
        logging.debug("m1end: {}".format(m1end))
        logging.debug("m1step: {}".format(m1step))
        logging.debug("motor2: {}".format(motor2))
        logging.debug("m2start: {}".format(m2start))
        logging.debug("m2end: {}".format(m2end))
        logging.debug("m2step: {}".format(m2step))
        logging.debug("gasdelay: {}".format(gasdelay))
        logging.debug("shotdelay: {}".format(shotdelay))
        logging.debug("record: {}".format(record))
        logging.debug("use_l3t: {}".format(use_l3t))
        logging.debug("controls: {}".format(controls))
        logging.debug("end_run: {}".format(end_run))

        nshots = m1steps * m2steps
        logging.debug("nsteps: {}".format(nsteps))
        print("Configured scan for {} steps...".format(nsteps))
        if ((nsteps * 4) + 1) > 2048:
            raise ValueError("The number of steps cannot be greater than 2048!")

        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)

        # 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
    
        # TODO: determine the different sequences needed.
        gdelay = int(gasdelay*120)  # 120 beam delays/second    
        sdelay = int(shotdelay*120) # 120 beam delays/second
        slow_cam_seq = [[167, 0, 0, 0]]
        gas_jet_seq = [[177, 0, 0, 0],
                       [176, gdelay, 0, 0],
                       [169, 0, 0, 0],
                       [0, sdelay, 0, 0]]
        
        # TODO: Configure the slow cameras
        # Get exposure time in beam deltas from number of shots
        exposure = nshots * (int(shotdelay/120.0) + int(gasdelay/120.0))
        logging.debug("Exposure time: {}".format(exposure))
        
        # Stage and add in slow cameras *after* daq is staged and configured
        slowcams = SlowCameras()
        # The camera delay and number of 'during' shots are the same in this case
        config = {'slowcamdelay': exposure, 'during': exposure} 
        dets.append(slowcams) # Add this in to auto-unstage later
        slowcams.stage(config)

        m1_step_size = (m1_end-m1_start)/(m1_steps-1)
        logging.debug("m1 step size: {}".format(m1_step_size))
        m2_step_size = (m2_end-m2_start)/(m2_steps-1)
        logging.debug("m2 step size: {}".format(m2_step_size))
        for i in range(m2_steps):
            new_m2 = m2_start+m2_step_size*i
            logging.debug("Moving motor2 to {}".format(new_m2))
            yield from bps.mv(motor2, new_m2)
            for j in range(m1_steps):
                new_m1 = m1_start+m1_step_size*j
                logging.debug("Moving motor1 to {}".format(new_m1))
                yield from bps.mv(motor1, new_m1)

                # If this is the first shot, use slow cam in sequence
                if (i == 0) and (j == 0):
                    s = slow_cam_seq + gas_jet_seq
                else:
                    s = gas_jet_seq
                  
                # TODO: set this up to run only if the sequence is different?
                # Do many puts to the test EVG program cause problems? 
                seq.sequence.put_seq(s) 

                
                # If this is the last move in the scan, check cleanup settings
                if (i == (m1_steps-1)) and (j == (m2_steps -1)):
                    if carriage_return: # Then go back to start
                        yield from bps.mv(motor1, m1_start)
                        yield from bps.mv(motor2, m2_start)
                    if end_run:
                        daq.end_run() 
Пример #13
0
    def __grid_scan(self,
                    x_motor,
                    x_start,
                    x_end,
                    xsteps,
                    y_motor,
                    y_start,
                    y_end,
                    ysteps,
                    z_motor,
                    angle,
                    ndaq,
                    record=True):
        logging.debug("Setting up the sequencer for %s daq points", ndaq)
        self.__setup_sequencer(ndaq)

        # Setup the pulse picker
        if pp.mode.get() == 3:
            logging.debug("The pulse picker is already in burst mode")
        else:
            logging.debug("Setting up the pulse picker for burst mode")
            pp.burst(wait=True)

        # Setup the DAQ
        daq.record = record
        daq.configure(events=ndaq)
        bps.configure(daq, events=ndaq)  # For plan introspection

        # Add sequencer, DAQ to detectors for scan
        dets = [daq, seq]

        # Log stuff
        logging.debug("Returning __grid_scan with the following parameters:")
        logging.debug("x_start: {}".format(x_start))
        logging.debug("x_end: {}".format(x_end))
        logging.debug("xsteps: {}".format(xsteps))
        logging.debug("y_start: {}".format(y_start))
        logging.debug("y_end: {}".format(y_end))
        logging.debug("y_steps: {}".format(ysteps))
        logging.debug("angle: {}".format(angle))
        logging.debug("ndaq: {}".format(ndaq))
        logging.debug("record: {}".format(record))
        logging.debug("detectors: {}".format(dets))

        z_start = z_motor.wm()

        x_step_size = (x_end - x_start) / (xsteps - 1)
        logging.debug("X step size: {}".format(x_step_size))
        y_step_size = (y_end - y_start) / (ysteps - 1)
        logging.debug("Y step size: {}".format(y_step_size))
        z_step = self.__comp_z(y_step_size, angle)
        logging.debug("Z step size: {}".format(z_step))
        for i in range(ysteps):
            new_y = y_start + y_step_size * i
            logging.debug("Moving Y to {}".format(new_y))
            yield from bps.mv(y_motor, new_y)
            if i != 0:  # Skip first step; assume focus is fine there
                logging.debug("Moving Z by {}".format(z_step))
                yield from bps.mvr(z_motor, z_step)
            yield from scan(dets, x_motor, x_start, x_end, xsteps)

        # Return to original positions
        yield from bps.mv(x_motor, x_start)
        yield from bps.mv(y_motor, y_start)
        yield from bps.mv(z_motor, z_start)