def _plan(self):
        yield from bps.open_run()

        # stash numcapture and shutter_enabled
        num_capture = yield from bps.rd(self.device.hdf5.num_capture)
        shutter_enabled = yield from bps.rd(self.device.dg1.shutter_enabled)

        # set to 1 temporarily
        self.device.hdf5.num_capture.put(1)

        # Restage to ensure that dark frames goes into a separate file.
        yield from bps.stage(self.device)
        yield from bps.mv(self.device.dg1.shutter_enabled, 2)
        # The `group` parameter passed to trigger MUST start with
        # bluesky-darkframes-trigger.
        yield from bps.trigger_and_read([self.device], name='dark')
        # Restage.
        yield from bps.unstage(self.device)
        # restore numcapture and shutter_enabled
        yield from bps.mv(self.device.hdf5.num_capture, num_capture)
        yield from bps.mv(self.device.dg1.shutter_enabled, shutter_enabled)

        # Dark frames finished, moving on to data

        yield from bps.stage(self.device)
        status = yield from bps.trigger(self.device, group='primary-trigger')
        while not status.done:
            yield from bps.trigger_and_read(self.async_poll_devices,
                                            name='labview')
            yield from bps.sleep(1)
        yield from bps.create('primary')
        yield from bps.read(self.device)
        yield from bps.save()
        yield from bps.unstage(self.device)
示例#2
0
def moveE(energy):

    args_list = []

    args_list.append((mono.energy, energy))

    if undulator.downstream.tracking is True:

        target_energy = undulator.downstream.offset + energy
        current_energy = undulator.downstream.energy.get(
        ) + undulator.downstream.deadband

        if current_energy < target_energy:
            args_list[0] += (undulator.downstream.energy,
                             target_energy + undulator.downstream.backlash)
            args_list[0] += (undulator.downstream.start_button, 1)

            args_list.append((undulator.downstream.energy, target_energy))
            args_list[-1] += (undulator.downstream.start_button, 1)

        else:
            args_list[0] += (undulator.downstream.energy, target_energy)
            args_list[0] += (undulator.downstream.start_button, 1)

    stage(mono)
    for args in args_list:
        yield from mv(*args)
示例#3
0
def dark_plan():
    yield from bps.mv(shutter, 'closed')
    yield from bps.unstage(det)
    yield from bps.stage(det)
    yield from bps.trigger(det, group='darkframe-trigger')
    yield from bps.wait('darkframe-trigger')
    snapshot = bluesky_darkframes.SnapshotDevice(det)
    yield from bps.unstage(det)
    yield from bps.stage(det)
    yield from bps.mv(shutter, 'open')
    return snapshot
def dark_plan(detector):
    # Restage to ensure that dark frames goes into a separate file.
    yield from bps.unstage(detector)
    yield from bps.stage(detector)
    yield from bps.mv(shutter, 'closed')
    # The `group` parameter passed to trigger MUST start with
    # bluesky-darkframes-trigger.
    yield from bps.trigger(detector, group='bluesky-darkframes-trigger')
    yield from bps.wait('bluesky-darkframes-trigger')
    snapshot = bluesky_darkframes.SnapshotDevice(detector)
    yield from bps.mv(shutter, 'open')
    # Restage.
    yield from bps.unstage(detector)
    yield from bps.stage(detector)
    return snapshot
示例#5
0
def set_and_fly(filepaths, flyers, sleeptime=10):
    '''
        Fly on flyers with file prefix for a certain sleep time.
        fileprefix: file prefix
        sleeptime : sleep time to let flyer run for


        I've written this manually for now.
    '''

    # set the file paths
    for filepath, flyer in zip(filepaths, flyers):
        yield from bps.abs_set(flyer.filepath, filepath)

    yield from bps.open_run()
    for flyer in flyers:
        yield from bps.stage(flyer)

    grp = str(uuid4())
    for flyer in flyers:
        yield from bps.kickoff(flyer, group=grp, wait=False)

    yield from bps.wait(group=grp)
    yield from bps.sleep(sleeptime)

    for flyer in flyers:
        yield from bps.complete(flyer, group=grp, wait=False)

    for flyer in flyers:
        yield from bps.collect(flyer)

    for flyer in flyers:
        yield from bps.unstage(flyer)

    yield from bps.close_run()
示例#6
0
 def insert_dark_frame(force_read, msg=None):
     # Acquire a fresh Snapshot if we need one, or retrieve a cached one.
     state = {}
     for signal in self.locked_signals:
         reading = yield from bluesky.plan_stubs.read(signal)
         # Restructure
         # {'data_key': {'value': <value>, 'timestamp': <timestamp>}, ...}
         # into (('data_key', <value>) ...).
         values_only = tuple(
             (k, v['value']) for k, v in reading.items())
         state[signal.name] = values_only
     if self._current_state != state:
         self._current_state = state
         snapshot_changed = True
     else:
         snapshot_changed = False
     try:
         snapshot = self.get_snapshot(state)
     except NoMatchingSnapshot:
         logger.info(f"Taking a new dark frame for state=%r", state)
         snapshot = yield from self.dark_plan()
         self.add_snapshot(snapshot, state)
     if snapshot_changed or force_read:
         logger.info(f"Creating a 'dark' Event for state=%r", state)
         self._current_snapshot.set_snaphsot(snapshot)
         # Read the Snapshot into the 'dark' Event stream.
         yield from bps.stage(self._current_snapshot)
         yield from bps.trigger_and_read([self._current_snapshot],
                                         name=self.stream_name)
         yield from bps.unstage(self._current_snapshot)
     self._latch = False
     if msg is not None:
         return (yield msg)
示例#7
0
    def insert_take_dark(msg):
        nonlocal need_dark
        qualified_dark_uid = _validate_dark(expire_time=glbl["dk_window"])
        area_det = xpd_configuration["area_det"]

        if (not need_dark) and (not qualified_dark_uid):
            need_dark = True
        if need_dark and (
                not qualified_dark_uid) and msg.command == "open_run" and (
                    "dark_frame" not in msg.kwargs):
            # We are about to start a new 'run' (e.g., a count or a scan).
            # Insert a dark frame run first.
            need_dark = False
            # Annoying detail: the detector was probably already staged.
            # Unstage it (if it wasn't staged, nothing will happen) and
            # then take_dark() and then re-stage it.
            return (
                bpp.pchain(
                    bps.unstage(area_det),
                    take_dark(),
                    bps.stage(area_det),
                    bpp.single_gen(msg),
                    open_shutter_stub(),
                ),
                None,
            )
        elif msg.command == "open_run" and "dark_frame" not in msg.kwargs:
            return (
                bpp.pchain(bpp.single_gen(msg), open_shutter_stub()),
                None,
            )
        else:
            # do nothing if (not need_dark)
            return None, None
示例#8
0
文件: plans.py 项目: st3107/xpdAcq
 def dark_plan(self, detector):
     """The plan to take dark."""
     # Restage to ensure that dark frames goes into a separate file.
     yield from bps.unstage(detector)
     yield from bps.stage(detector)
     yield from bps.mv(self.shutter, self.shutter_close)
     # The `group` parameter passed to trigger MUST start with
     # bluesky-darkframes-trigger.
     yield from bps.trigger(detector, group='bluesky-darkframes-trigger')
     yield from bps.wait('bluesky-darkframes-trigger')
     snapshot = SnapshotDevice(detector)
     yield from bps.mv(self.shutter, self.shutter_open)
     # Restage.
     yield from bps.unstage(detector)
     yield from bps.stage(detector)
     return snapshot
示例#9
0
def xpdacq_ramp_count(motor: typing.Any,
                      value: typing.Any,
                      inner_plan: typing.Callable,
                      take_pre_data=True,
                      timeout=None,
                      period=None,
                      md=None) -> typing.Generator:
    """
    Take data while ramping one or more motors.

    Parameters
    ----------
    inner_plan :
        The plan to repeat in loop. It returns a generator inner_plan().

    motor :
        A positioner to ramp up.

    value:
        A value to ramp up to.

    timeout : float, optional
        If not None, the maximum time the ramp can run.

        In seconds

    take_pre_data: Bool, optional
        If True, add a pre data at beginning

    period : float, optional
        If not None, take data no faster than this.  If None, take
        data as fast as possible

        If running the inner plan takes longer than `period` than take
        data with no dead time.

        In seconds.

    md : dict
        The metadata of this plan.
    """
    for detector in detectors:
        yield from bps.stage(detector)

    def go_plan():
        status, = yield from bps.mv(motor, value)
        return status

    yield from bp.ramp_plan(go_plan(),
                            motor,
                            inner_plan,
                            take_pre_data=take_pre_data,
                            timeout=timeout,
                            period=period,
                            md=md)

    for detector in detectors:
        yield from bps.unstage(detector)
示例#10
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() 
def manual_count(det=eiger1m_single):
    detectors = [det]
    for det in detectors:
        yield from stage(det)
        yield from open_run()
        print("All slow setup code has been run. "
              "Type RE.resume() when ready to acquire.")
        yield from pause()
        yield from trigger_and_read(detectors)
        yield from close_run()
        for det in detectors:
            yield from unstage(det)
示例#12
0
 def insert_reference_to_dark_frame(msg):
     if msg.command == 'open_run':
         return (
             bluesky.preprocessors.pchain(
                 bluesky.preprocessors.single_gen(msg),
                 bps.stage(self.dark_frame_cache),
                 bps.trigger_and_read([self.dark_frame_cache], name='dark'),
                 bps.unstage(self.dark_frame_cache)
             ),
             None,
         )
     else:
         return None, None
示例#13
0
def filter_opt_count(det, target_count=100000, md={}):
    """ filter_opt_count
    OPtimize counts using filters 
    Assumes mu=0.2, x = [0.89, 2.52, 3.83, 10.87]
    I = I_o \exp(-mu*x) 

    Only takes one detector, since we are optimizing based on it alone
    target is mean+2std
    """
    dc = DocumentCache()
    token = yield from bps.subscribe('all', dc)
    yield from bps.stage(det)

    md = {}

    yield from bps.open_run(md=md)
    # BlueskyRun object allows interaction with documents similar to db.v2,
    # but documents are in memory
    run = BlueskyRun(dc)
    yield from bps.trigger_and_read([det, filter1, filter2, filter3, filter4])

    data = run.primary.read()['pilatus300k_image']
    mean = data[-1].mean().values.item()  # xarray.DataArray methods
    std = data[-1].std().values.item()  # xarray.DataArray methods
    curr_counts = mean + 2 * std

    # gather filter information and solve
    filter_status = [
        round(filter1.get() / 5),
        round(filter2.get() / 5),
        round(filter3.get() / 5),
        round(filter4.get() / 5)
    ]
    print(filter_status)
    filter_status = [not e for e in filter_status]
    new_filters = solve_filter_setup(filter_status, curr_counts, target_count)
    # invert again to reflect filter status
    new_filters = [not e for e in new_filters]
    print(new_filters)
    # set new filters and read.  For some reason hangs on bps.mv when going high
    filter1.put(new_filters[0] * 4.9)
    filter2.put(new_filters[1] * 4.9)
    filter3.put(new_filters[2] * 4.9)
    filter4.put(new_filters[3] * 4.9)

    yield from bps.trigger_and_read([det, filter1, filter2, filter3, filter4])

    # close out run
    yield from bps.close_run()
    yield from bps.unsubscribe(token)
    yield from bps.unstage(det)
示例#14
0
 def tail():
     # Acquire a fresh Snapshot if we need one, or retrieve a cached one.
     state = {}
     for signal in self.locked_signals:
         reading = yield bluesky.plan_stubs.read(signal)
         state[signal.name] = reading
     try:
         snapshot = self.get_snapshot(state)
     except NoMatchingSnapshot:
         snapshot = yield from self.dark_plan()
         self.add_snapshot(snapshot, state)
     # Read the Snapshot into the 'dark' Event stream.
     yield from bps.stage(snapshot)
     yield from bps.trigger_and_read([snapshot], name=self.stream_name)
     yield from bps.unstage(snapshot)
示例#15
0
 def plan():
     yield from bps.open_run()
     yield from bps.stage(det)
     yield from bps.mv(det.exposure_time, 0.01)
     yield from bps.trigger_and_read([det])  # should prompt new dark Event
     yield from bps.trigger_and_read([det])
     yield from bps.mv(det.exposure_time, 0.02)
     yield from bps.trigger_and_read([det])  # should prompt new dark Event
     yield from bps.trigger_and_read([det])
     yield from bps.mv(det.exposure_time, 0.01)
     yield from bps.trigger_and_read([det])  # should prompt new dark Event
     yield from bps.trigger_and_read([det])
     yield from bps.trigger_and_read([det])
     yield from bps.unstage(det)
     yield from bps.close_run()
示例#16
0
 def insert_dark_frame(force_read, msg=None):
     # Acquire a fresh Snapshot if we need one, or retrieve a cached one.
     state = {}
     for signal in self.locked_signals:
         reading = yield from bluesky.plan_stubs.read(signal)
         # Restructure
         # {'data_key': {'value': <value>, 'timestamp': <timestamp>}, ...}
         # into (('data_key', <value>) ...).
         values_only = tuple(
             (k, v['value']) for k, v in reading.items())
         state[signal.name] = values_only
     try:
         snapshot = self.get_snapshot(state)
     except NoMatchingSnapshot:
         # If we are here, we either haven't taken a reading when the
         # locked_signals were in this state, or the last such reading
         # we took has aged out of the cache. We have to trigger the
         # hardware and get a fresh snapshot.
         logger.info("Taking a new %r reading for state=%r",
                     self.stream_name, state)
         snapshot = yield from self._partialed_dark_plan()
         self.add_snapshot(snapshot, state)
     # If the Snapshot is the same as the one we most recently inserted,
     # then we don't need to create a new Event. The previous Event
     # still holds.
     snapshot_changed = snapshot is not self._current_snapshot.get_snapshot(
     )
     if snapshot_changed or force_read:
         logger.info("Creating a %r Event for state=%r",
                     self.stream_name, state)
         self._current_snapshot.set_snaphsot(snapshot)
         # Read the Snapshot. This does not actually trigger hardware,
         # but it goes through all the bluesky steps to generate new
         # Event.
         # The reason we handle self._current_snapshot here instead of
         # snapshot itself is the bluesky RunEngine notices if you give
         # it a different object than you had given it earlier. Thus,
         # bluesky will always see the "Device" self._current_snapshot
         # here, and it will be satisfied.
         yield from bps.stage(self._current_snapshot)
         yield from trigger_and_read([self._current_snapshot],
                                     name=self.stream_name,
                                     group=short_uid(GROUP_PREFIX))
         yield from bps.unstage(self._current_snapshot)
     self._latch = False
     if msg is not None:
         return (yield msg)
    def _pe_acquisition_plan():
        for det in dets:
            if images_per_set is not None:
                yield from bps.mov(det.images_per_set, images_per_set)

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

        yield from bps.sleep(1)

        # close fast shutter, now take a dark
        # yield from bps.mov(fs, 0)
        yield from bpp.trigger_and_read(dets, name='dark')

        # open fast shutter
        # yield from bps.mov(fs, 1)
        yield from bpp.trigger_and_read(dets, name='primary')

        for det in dets:
            yield from bps.unstage(det)
示例#18
0
 def tail():
     # Acquire a fresh Snapshot if we need one, or retrieve a cached one.
     state = {}
     for signal in self.locked_signals:
         reading = yield from bluesky.plan_stubs.read(signal)
         # Restructure
         # {'data_key': {'value': <value>, 'timestamp': <timestamp>}, ...}
         # into (('data_key', <value>) ...).
         values_only = tuple(
             (k, v['value']) for k, v in reading.items())
         state[signal.name] = values_only
     try:
         snapshot = self.get_snapshot(state)
     except NoMatchingSnapshot:
         snapshot = yield from self.dark_plan()
         self.add_snapshot(snapshot, state)
     # Read the Snapshot into the 'dark' Event stream.
     yield from bps.stage(snapshot)
     yield from bps.trigger_and_read([snapshot], name=self.stream_name)
     yield from bps.unstage(snapshot)
示例#19
0
def dark_plan(detector):
    # stash numcapture and shutter_enabled
    num_capture = yield from bps.rd(detector.hdf5.num_capture)
    shutter_enabled = yield from bps.rd(detector.dg1.shutter_enabled)

    # set to 1 temporarily
    detector.hdf5.num_capture.put(1)

    # Restage to ensure that dark frames goes into a separate file.
    yield from bps.unstage(detector)
    yield from bps.stage(detector)
    yield from bps.mv(detector.dg1.shutter_enabled, 2)
    # The `group` parameter passed to trigger MUST start with
    # bluesky-darkframes-trigger.
    yield from bps.trigger(detector, group='bluesky-darkframes-trigger')
    yield from bps.wait('bluesky-darkframes-trigger')
    snapshot = bluesky_darkframes.SnapshotDevice(detector)
    # Restage.
    yield from bps.unstage(detector)
    # restore numcapture and shutter_enabled
    yield from bps.mv(detector.hdf5.num_capture, num_capture)
    yield from bps.mv(detector.dg1.shutter_enabled, shutter_enabled)
    return snapshot
示例#20
0
def max_pixel_count(dets, sat_count=60000, md={}):
    """max_pixel_count 

    Adjust acquisition time based on max pixel count
    Assume each det in dets has an attribute det.max_count.
    Assume counts are linear with time. 
    Scale acquisition time to make det.max_count.get()=sat_count
    """

    for det in dets:
        yield from bps.stage(det)
        yield from bps.trigger_and_read(det)
        curr_acq_time = det.cam.acquire_time.get()
        # =================== BIG IF, DOES THIS EXIST
        curr_max_counts = det.max_count.get()
        # ============================================
        new_acq_time = round(sat_count / curr_max_counts * curr_acquire_time,
                             2)

        yield from bps.mv(det.cam.acquire_time, new_acq_time)

    # run standard count plan with new acquire times
    yield from bp.count(dets, md=md)
示例#21
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()
def pe_count(
    filename="",
    exposure=1,
    num_images: int = 1,
    num_dark_images: int = 1,
    num_repetitions: int = 5,
    delay=60,
):

    year = "2020"  # RE.md["year"]
    cycle = "C2"  # RE.md["cycle"]
    proposal = "67890"  # RE.md["PROPOSAL"]

    # write_path_template = 'Z:\\data\\pe1_data\\%Y\\%m\\%d\\'
    # write_path_template = f"Z:\\users\\{year}\\{cycle}\\{proposal}XRD\\"
    # file_path = datetime.now().strftime(write_path_template)
    # filename = filename + str(uuid.uuid4())[:6]

    # this is an example of what would be used at the beamline
    pe_detector.tiff_writer.resource_root_path = PureWindowsPath(
        f"Z:\\users\\")
    pe_detector.tiff_writer.relative_write_path = PureWindowsPath(
        f"{year}\\{cycle}\\{proposal}XRD\\")

    # for testing
    pe_detector.tiff_writer.resource_root_path = Path("/tmp/")
    pe_detector.tiff_writer.relative_write_path = Path(
        f"perkin_elmer/detector/{year}/{cycle}/XRD{proposal}"  # remove "XRD" from the end?
    )

    # start the run
    yield from bps.open_run()

    # stage the detector
    yield from bps.stage(pe_detector)

    yield from bps.mv(pe_detector.tiff_writer.file_number, 1)
    tiff_full_file_path = (pe_detector.tiff_writer.resource_root_path /
                           pe_detector.tiff_writer.relative_write_path)

    print(f"tiff_full_file_path: {str(tiff_full_file_path)}")
    yield from bps.mv(pe_detector.tiff_writer.file_path,
                      str(tiff_full_file_path))

    for repetition_index in range(int(num_repetitions)):

        print("\n")
        print(
            "<<<<<<<<<<<<<<<<< Doing repetition {} out of {} >>>>>>>>>>>>>>>>>"
            .format(repetition_index + 1, num_repetitions))

        # TiffWriter or similar plugin should do this
        yield from bps.mv(pe_detector.tiff_writer.file_name,
                          filename + str(uuid.uuid4()))

        if num_dark_images > 0:
            # originally used pe_detector.num_dark_images
            # but this is really pe_num_offset_frames
            yield from bps.mv(pe_detector.cam.pe_num_offset_frames,
                              num_dark_images)
            yield from bps.mv(
                pe_detector.cam.image_mode,
                PerkinElmerCamera.PerkinElmerImageMode.AVERAGE,
            )
            # yield from bps.mv(fast_shutter, "Close")
            yield from bps.sleep(0.5)
            yield from bps.mv(pe_detector.tiff_writer.file_write_mode,
                              NDFile.FileWriteMode.SINGLE)

            # acquire a "dark frame"
            pe_acquire_offset_status = SubscriptionStatus(
                pe_detector.cam.pe_acquire_offset,
                high_to_low_pe_acquire_offset)
            yield from bps.abs_set(
                pe_detector.cam.pe_acquire_offset,
                PerkinElmerCamera.AcquireOffset.ACQUIRE,
                wait=False,
            )
            yield Msg("wait_for_status", None, pe_acquire_offset_status)

            yield from bps.mv(pe_detector.tiff_writer.write_file,
                              NDFile.WriteFile.WRITE)

        # yield from bps.mv(
        #  pe1.cam.image_mode,
        #  NewPerkinElmerDetector.ImageMode.MULTIPLE
        # )
        yield from bps.mv(
            pe_detector.cam.image_mode,
            PerkinElmerCamera.PerkinElmerImageMode.AVERAGE,
        )
        yield from bps.mv(pe_detector.cam.acquire_time, exposure)
        yield from bps.mv(pe_detector.cam.num_images, num_images)

        # yield from bps.mv(fast_shutter, "Open")
        yield from bps.sleep(0.5)

        ## Below 'Capture' mode is used with 'Multiple' image_mode
        # yield from bps.mv(pe1.tiff_writer.file_write_mode, 'Capture')

        ## Below 'Single' mode is used with 'Average' image_mode
        yield from bps.mv(
            pe_detector.tiff_writer.file_write_mode,
            NDFile.FileWriteMode.SINGLE,  # "Single"
        )

        ## Uncomment 'capture' bit settings when used in 'Capture' mode
        # yield from bps.mv(pe1.tiff_writer.capture, 1)

        # this was the old way to initiate the acquisition
        # yield from bps.mv(pe_detector, "acquire_light")

        yield from bps.trigger_and_read([pe_detector], name="primary")

        # can TiffWriter or similar plugin do this?
        ##Below write_file is needed when used in 'Average' mode
        yield from bps.mv(
            pe_detector.tiff_writer.write_file,
            NDFile.WriteFile.WRITE  # 1
        )

        yield from bps.sleep(delay)

    # unstage the detector
    yield from bps.unstage(pe_detector)

    # end the run
    yield from bps.close_run()
示例#23
0
文件: laser.py 项目: ZryletTC/mec
    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()
示例#24
0
 def drop_daq_msg(msg):
     if msg.command == 'stage':
         return (yield from bps.stage(_Dummy()))
     if msg.command == 'unstage':
         return (yield from bps.unstage(_Dummy()))
示例#25
0
 def take_image(self):
     yield from bps.stage(self)
     yield from bps.trigger(self, wait=True)
     yield from bps.unstage(self)
示例#26
0
 def plan():
     yield from open_run()
     yield from stage(m)
     yield from unstage(m)
     yield from close_run()
示例#27
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()