コード例 #1
0
ファイル: plans.py プロジェクト: aps-7bm/apstools
def addDeviceDataAsStream(devices, label):
    """
    plan: add an ophyd Device as an additional document stream

    Use this within a custom plan, such as this example::

        from apstools.plans import addDeviceStream
        ...
        yield from bps.open_run()
        # ...
        yield from addDeviceDataAsStream(prescanDeviceList, "metadata_prescan")
        # ...
        yield from custom_scan_procedure()
        # ...
        yield from addDeviceDataAsStream(postscanDeviceList, "metadata_postscan")
        # ...
        yield from bps.close_run()

    """
    yield from bps.create(name=label)
    if not isinstance(devices, list):     # just in case...
        devices = [devices]
    for d in devices:
        yield from bps.read(d)
    yield from bps.save()
コード例 #2
0
    def fly_body():
        yield from bps.trigger_and_read([E_centers], name='energy_bins')

        for y in range(num_scans):
            # go to start of row
            yield from bps.mv(mono.linear, l_start)

            # set the fly speed
            yield from bps.mv(mono.linear.velocity, flyspeed)

            yield from bps.trigger_and_read([mono], name='row_ends')

            for v in ['p1600=0', 'p1600=1']:
                yield from bps.mv(dtt, v)
                yield from bps.sleep(0.1)

            # arm the struck
            yield from bps.trigger(sclr, group=f'fly_energy_{y}')
            # fly the motor
            yield from bps.abs_set(mono.linear,
                                   l_stop + a_l_step_size,
                                   group=f'fly_energy_{y}')
            yield from bps.wait(group=f'fly_energy_{y}')

            yield from bps.trigger_and_read([mono], name='row_ends')

            yield from bps.mv(mono.linear.velocity, 0.5)
            # hard coded to let the sclr count its fingers and toes
            yield from bps.sleep(.1)
            # read and save the struck
            yield from bps.create(name='primary')
            yield from bps.read(sclr)
            yield from bps.save()
コード例 #3
0
ファイル: de_optimization.py プロジェクト: NSLS-II/bloptools
def create_rand_selection_params(motors, population, intensities, bounds):
    if motors is not None and population is None:
        # hardware
        positions = []
        change_indx = intensities.index(np.min(intensities))
        indv = {}
        for elem, param in motors.items():
            indv[elem] = {}
            for param_name, elem_obj in param.items():
                indv[elem][param_name] = (yield from
                                          bps.read(elem_obj))[elem]['value']
        positions.append(indv)
        indv = {}
        for elem, param in bounds.items():
            indv[elem] = {}
            for param_name, bound in param.items():
                indv[elem][param_name] = random.uniform(bound[0], bound[1])
        positions.append(indv)
        return positions, change_indx
    elif motors is None and population is not None:
        # sirepo simulation
        positions = []
        change_indx = intensities.index(np.min(intensities))
        positions.append(population[0])
        indv = {}
        for elem, param in bounds.items():
            indv[elem] = {}
            for param_name, bound in param.items():
                indv[elem][param_name] = random.uniform(bound[0], bound[1])
        positions.append(indv)
        return positions, change_indx
コード例 #4
0
    def tester(obj):
        nonlocal called
        direct_read = yield from bps.read(obj)
        rd_read = yield from bps.rd(obj)

        assert rd_read == direct_read["det"]["value"]
        called = True
コード例 #5
0
    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)
コード例 #6
0
ファイル: plans.py プロジェクト: aps-7bm/apstools
 def _snap(md=None):
     yield from bps.open_run(md)
     yield from bps.create(name=stream)
     for obj in objects:
         # passive observation: DO NOT TRIGGER, only read
         yield from bps.read(obj)
     yield from bps.save()
     yield from bps.close_run()
コード例 #7
0
        def fly_row():
            # go to start of row
            target_y = ystart + y * a_ystep_size
            yield from bps.mv(xy_fly_stage.x, xstart, xy_fly_stage.y, target_y)
            yield from bps.mv(y_centers,
                              np.ones(num_xpixels) *
                              target_y)  # set the fly speed

            ret = yield from bps.read(xy_fly_stage.z.user_readback)  # (in mm)
            zpos = (ret[xy_fly_stage.z.user_readback.name]["value"]
                    if ret is not None else 0)
            yield from bps.mov(z_centers, np.ones(num_xpixels) * zpos)

            yield from bps.mv(xy_fly_stage.x.velocity, flyspeed)

            yield from bps.trigger_and_read([xy_fly_stage], name="row_ends")

            for v in ["p1600=0", "p1600=1"]:
                yield from bps.mv(dtt, v)
                yield from bps.sleep(0.1)

            # arm the struck
            yield from bps.trigger(sclr, group=f"fly_row_{y}")
            # maybe start the xspress3
            if xspress3 is not None:
                yield from bps.trigger(xspress3, group=f"fly_row_{y}")
            yield from bps.sleep(0.1)
            # fly the motor
            yield from bps.abs_set(xy_fly_stage.x,
                                   xstop + a_xstep_size,
                                   group=f"fly_row_{y}")
            yield from bps.wait(group=f"fly_row_{y}")

            yield from bps.trigger_and_read([xy_fly_stage], name="row_ends")
            yield from bps.mv(xy_fly_stage.x.velocity, 5.0)
            yield from bps.sleep(0.1)
            # read and save the struck
            yield from bps.create(name="primary")
            #
            yield from bps.read(sclr)
            yield from bps.read(mono)
            yield from bps.read(x_centers)
            yield from bps.read(y_centers)
            yield from bps.read(z_centers)
            yield from bps.read(xy_fly_stage.y)
            yield from bps.read(xy_fly_stage.z)
            # and maybe the xspress3
            if xspress3 is not None:
                yield from bps.read(xspress3)
            yield from bps.save()
コード例 #8
0
def change_epu_flt_link(new_target):
    v = (yield from bps.read(epu1.flt.input_pv))
    if v is None:
        return
    n = epu1.flt.input_pv.name
    cur_pv = v[n]['value']
    pts = cur_pv.split(' ', maxsplit=1)
    new_pv = ' '.join([new_target] + pts[1:])
    yield from bps.abs_set(epu1.flt.input_pv, new_pv)
コード例 #9
0
def change_epu_flt_link(new_target):
    v = (yield from bps.read(epu1.flt.input_pv))
    if v is None:
        return
    n = epu1.flt.input_pv.name
    cur_pv = v[n]['value']
    pts = cur_pv.split(' ', maxsplit=1)
    new_pv = ' '.join([new_target] + pts[1:])
    yield from bps.abs_set(epu1.flt.input_pv, new_pv)
コード例 #10
0
    def inner_dark_frame_aware_plan():
        tmp = yield from bps.read(shutter.status)
        init_shutter_state = tmp[shutter.status.name]['value'] if tmp is not None else None
        yield from bps.mv(shutter, 'Open')

        for _ in range(num_images):
            yield from check_and_take_darks()
            yield from bpp.trigger_and_read([cam], name='primary')

        yield from bps.mv(shutter, init_shutter_state)
コード例 #11
0
        def _scan(md=None):
            yield from bps.open_run(md)

            position_list = np.linspace(start, finish, num)
            signal_list = list(self.signals)
            signal_list += [
                self.axis,
            ]
            for pos in position_list:
                yield from bps.mv(self.axis, pos)
                yield from bps.trigger_and_read(signal_list)

            final_position = initial_position
            if self.peak_detected():
                self.tune_ok = True
                if self.peak_choice == "cen":
                    final_position = self.peaks.cen
                elif self.peak_choice == "com":
                    final_position = self.peaks.com
                else:
                    final_position = None
                self.center = final_position

            # add stream with results
            # yield from add_results_stream()
            stream_name = "PeakStats"
            results = Results(name=stream_name)

            results.tune_ok.put(self.tune_ok)
            results.center.put(self.center)
            results.final_position.put(final_position)
            results.initial_position.put(initial_position)
            for key in results.peakstats_attrs:
                v = getattr(self.peaks, key)
                if key in ("crossings", "min", "max"):
                    v = np.array(v)
                getattr(results, key).put(v)

            if results.tune_ok.get():
                yield from bps.create(name=stream_name)
                try:
                    yield from bps.read(results)
                except ValueError as ex:
                    separator = " " * 8 + "-" * 12
                    print(separator)
                    print(f"Error saving stream {stream_name}:\n{ex}")
                    print(separator)
                yield from bps.save()

            yield from bps.mv(self.axis, final_position)
            self.stats.append(self.peaks)
            yield from bps.close_run()

            results.report(stream_name)
コード例 #12
0
    def configure_area_det(det, exposure):
        '''Configure an area detector in "continuous mode"'''

        def _check_mini_expo(exposure, acq_time):
            if exposure < acq_time:
                raise ValueError(
                    "WARNING: total exposure time: {}s is shorter "
                    "than frame acquisition time {}s\n"
                    "you have two choices:\n"
                    "1) increase your exposure time to be at least"
                    "larger than frame acquisition time\n"
                    "2) increase the frame rate, if possible\n"
                    "    - to increase exposure time, simply resubmit"
                    " the ScanPlan with a longer exposure time\n"
                    "    - to increase frame-rate/decrease the"
                    " frame acquisition time, please use the"
                    " following command:\n"
                    "    >>> {} \n then rerun your ScanPlan definition"
                    " or rerun the xrun.\n"
                    "Note: by default, xpdAcq recommends running"
                    "the detector at its fastest frame-rate\n"
                    "(currently with a frame-acquisition time of"
                    "0.1s)\n in which case you cannot set it to a"
                    "lower value.".format(
                        exposure,
                        acq_time,
                        ">>> glbl['frame_acq_time'] = 0.5  #set" " to 0.5s",
                    )
                )

        # todo make
        ret = yield from bps.read(det.cam.acquire_time)
        if ret is None:
            acq_time = 1
        else:
            acq_time = ret[det.cam.acquire_time.name]["value"]
        _check_mini_expo(exposure, acq_time)
        if hasattr(det, "images_per_set"):
            # compute number of frames
            num_frame = np.ceil(exposure / acq_time)
            yield from bps.mov(det.images_per_set, num_frame)
        else:
            # The dexela detector does not support `images_per_set` so we just
            # use whatever the user asks for as the thing
            # TODO: maybe put in warnings if the exposure is too long?
            num_frame = 1
        computed_exposure = num_frame * acq_time

        # print exposure time
        print(
            "INFO: requested exposure time = {} - > computed exposure time"
            "= {}".format(exposure, computed_exposure)
        )
        return num_frame, acq_time, computed_exposure
コード例 #13
0
def _read_the_first_key(obj):
    """Helper to get 'the right' reading."""
    reading = yield from bps.read(obj)
    if reading is None:
        return None
    hints = obj.hints.get("fields", [])
    if len(hints):
        key, *_ = hints
    else:
        key, *_ = list(reading)
    return reading[key]["value"]
コード例 #14
0
        def fly_once(y):
            # for y in range(num_scans):
            # go to start of row

            yield from bps.checkpoint()
            yield from bps.mv(mono.linear.velocity, 1)
            yield from bps.mv(mono.linear, l_start)

            # set the fly speed
            yield from bps.mv(mono.linear.velocity, flyspeed)

            yield from bps.trigger_and_read([mono], name="row_ends")

            for v in ["p1600=0", "p1600=1"]:
                yield from bps.mv(dtt, v)
                yield from bps.sleep(0.1)

            # arm the Struck
            yield from bps.trigger(sclr, group=f"fly_energy_{y}")
            if xspress3 is not None:
                yield from bps.trigger(xspress3, group=f"fly_energy_{y}")

            # fly the motor
            yield from bps.abs_set(mono.linear,
                                   l_stop + a_l_step_size,
                                   group=f"fly_energy_{y}")
            yield from bps.wait(group=f"fly_energy_{y}")

            yield from bps.trigger_and_read([mono], name="row_ends")

            yield from bps.mv(mono.linear.velocity, flyspeed)
            # hard coded to let the sclr count its fingers and toes
            yield from bps.sleep(0.1)
            # read and save the struck
            yield from bps.create(name="primary")
            yield from bps.read(sclr)
            if xspress3 is not None:
                yield from bps.read(xspress3)

            yield from bps.save()
コード例 #15
0
        def fly_row():
            # go to start of row
            yield from bps.mv(xy_fly_stage.x, xstart, xy_fly_stage.y,
                              ystart + y * ystep_size)

            # set the fly speed
            yield from bps.mv(xy_fly_stage.x.velocity, flyspeed)

            yield from bps.trigger_and_read([xy_fly_stage], name='row_ends')

            for v in ['p1600=0', 'p1600=1']:
                yield from bps.mv(dtt, v)
                yield from bps.sleep(0.1)

            # arm the struck
            yield from bps.trigger(sclr, group=f'fly_row_{y}')
            # maybe start the xspress3
            if xspress3 is not None:
                yield from bps.trigger(xspress3, group=f'fly_row_{y}')
            yield from bps.sleep(0.1)
            # fly the motor
            yield from bps.abs_set(xy_fly_stage.x,
                                   xstop + a_xstep_size,
                                   group=f'fly_row_{y}')
            yield from bps.wait(group=f'fly_row_{y}')

            yield from bps.trigger_and_read([xy_fly_stage], name='row_ends')

            yield from bps.mv(xy_fly_stage.x.velocity, 5.0)
            yield from bps.sleep(.1)
            # read and save the struck
            yield from bps.create(name='primary')
            yield from bps.read(sclr)
            # and maybe the xspress3
            if xspress3 is not None:
                yield from bps.read(xspress3)
            yield from bps.save()
コード例 #16
0
ファイル: plans.py プロジェクト: mrakitin/apstools
        def _scan(md=None):
            yield from bps.open_run(md)

            position_list = np.linspace(start, finish, num)
            signal_list = list(self.signals)
            signal_list += [
                self.axis,
            ]
            for pos in position_list:
                yield from bps.mv(self.axis, pos)
                yield from bps.trigger_and_read(signal_list)

            final_position = initial_position
            if self.peak_detected():
                self.tune_ok = True
                if self.peak_choice == "cen":
                    final_position = self.peaks.cen
                elif self.peak_choice == "com":
                    final_position = self.peaks.com
                else:
                    final_position = None
                self.center = final_position

            # add stream with results
            # yield from add_results_stream()
            stream_name = "PeakStats"
            results = Results(name=stream_name)

            for key in "tune_ok center".split():
                getattr(results, key).put(getattr(self, key))
            results.final_position.put(final_position)
            results.initial_position.put(initial_position)
            for key in results.peakstats_attrs:
                v = getattr(self.peaks, key)
                if key in ("crossings", "min", "max"):
                    v = np.array(v)
                getattr(results, key).put(v)

            if results.tune_ok.value:
                yield from bps.create(name=stream_name)
                yield from bps.read(results)
                yield from bps.save()

            yield from bps.mv(self.axis, final_position)
            self.stats.append(self.peaks)
            yield from bps.close_run()

            results.report()
コード例 #17
0
def dark_plan(cam, dark_frame_cache, obsolete_secs, shutter):
    if (dark_frame_cache.just_started or  # first run after instantiation
        (dark_frame_cache.last_collected is not None and
         time.monotonic() - dark_frame_cache.last_collected > obsolete_secs)):
        tmp = yield from bps.read(shutter.status)
        init_shutter_state = tmp[shutter.status.name]['value'] if tmp is not None else None
        yield from bps.mv(shutter, 'Close')
        yield from bps.trigger(cam, group='cam')
        yield from bps.wait('cam')
        yield from bps.mv(shutter, init_shutter_state)

        teleport(cam, dark_frame_cache)
        dark_frame_cache.just_started = False
        dark_frame_cache.update_done = True
    else:
        dark_frame_cache.update_done = False
コード例 #18
0
ファイル: de_optimization.py プロジェクト: NSLS-II/bloptools
def create_selection_params(motors, population, cross_indv):
    if motors is not None and population is None:
        # hardware
        positions = [elm for elm in cross_indv]
        indv = {}
        for elem, param in motors.items():
            indv[elem] = {}
            for param_name, elem_obj in param.items():
                indv[elem][param_name] = (yield from
                                          bps.read(elem_obj))[elem]['value']
        positions.insert(0, indv)
        return positions
    if motors is None and population is not None:
        # sirepo simulation
        positions = [elm for elm in cross_indv]
        positions.insert(0, population[0])
        return positions
コード例 #19
0
 def dull_scan(mot, count, sig=None, sleep_time=0):
     if sig:
         thread = threading.Thread(target=sig_sequence, args=(sig, ))
         thread.start()
     for i in range(count):
         yield from checkpoint()
         try:
             yield from mv(mot, i)
         except:
             pass
         # make every step take 1s extra
         yield from sleep(sleep_time)
         yield from checkpoint()
         yield from create()
         yield from read(mot)
         yield from save()
         yield from checkpoint()
コード例 #20
0
def configure_area_det(det: typing.Any, exposure: float, acq_time: float):
    """Configure exposure time of a detector in continuous acquisition mode.

    Parameters
    ----------
    det :
        The area detector to be configured.

    exposure :
        The total exposure time. One exposure contains one or multiple frames.

    acq_time :
        The frame acquisition time. The exposure time per frame.

    Returns
    -------
    num_frame :
        Number of frames.

    real_acq_time:
        The real frame acquisition time after set.

    computed_exposure :
        The real exposure time after set.
    """
    xb._check_mini_expo(exposure, acq_time)
    yield from bps.mv(det.cam.acquire_time, acq_time)
    res = yield from bps.read(det.cam.acquire_time)
    real_acq_time = res[det.cam.acquire_time.name]["value"] if res else 1
    if hasattr(det, "images_per_set"):
        # compute number of frames
        num_frame = math.ceil(exposure / real_acq_time)
        yield from bps.mv(det.images_per_set, num_frame)
    else:
        # The dexela detector does not support `images_per_set` so we just
        # use whatever the user asks for as the thing
        num_frame = 1
    computed_exposure = num_frame * real_acq_time

    # print exposure time
    print("INFO: requested exposure time = {} - > computed exposure time"
          "= {}".format(exposure, computed_exposure))
    return num_frame, real_acq_time, computed_exposure
コード例 #21
0
 def inner_trigger_and_read():
     nonlocal group
     if group is None:
         group = short_uid('trigger')
     no_wait = True
     for obj in devices:
         if hasattr(obj, 'trigger'):
             no_wait = False
             yield from bps.trigger(obj, group=group)
     # Skip 'wait' if none of the devices implemented a trigger method.
     if not no_wait:
         yield from bps.wait(group=group)
     yield from bps.create(name)
     ret = {}  # collect and return readings to give plan access to them
     for obj in devices:
         reading = (yield from bps.read(obj))
         if reading is not None:
             ret.update(reading)
     yield from bps.save()
     return ret
コード例 #22
0
ファイル: doc_run.py プロジェクト: APS-USAXS/ipython-usaxs
def documentation_run(words, md=None, stream=None):
    """
    Save text as a bluesky run.
    """
    text = Signal(value=words, name="text")
    stream = stream or "primary"
    _md = dict(
        purpose=f"save text as bluesky run",
        plan_name="documentation_run",
    )
    _md.update(md or {})
    bec.disable_plots()
    bec.disable_table()
    uid = yield from bps.open_run(md=_md)
    yield from bps.create(stream)
    yield from bps.read(text)
    yield from bps.save()
    yield from bps.close_run()
    bec.enable_table()
    bec.enable_plots()
    return uid
コード例 #23
0
ファイル: beamtime.py プロジェクト: st3107/xpdAcq
def configure_area_det(det, exposure, acq_time):
    """Configure exposure time of a detector in continuous acquisition mode"""
    _check_mini_expo(exposure, acq_time)
    yield from bps.mv(det.cam.acquire_time, acq_time)
    res = yield from bps.read(det.cam.acquire_time)
    real_acq_time = res[det.cam.acquire_time.name]["value"] if res else 1
    if hasattr(det, "images_per_set"):
        # compute number of frames
        num_frame = np.ceil(exposure / real_acq_time)
        yield from bps.mv(det.images_per_set, num_frame)
    else:
        # The dexela detector does not support `images_per_set` so we just
        # use whatever the user asks for as the thing
        num_frame = 1
    computed_exposure = num_frame * real_acq_time

    # print exposure time
    print(
        "INFO: requested exposure time = {} - > computed exposure time"
        "= {}".format(exposure, computed_exposure)
    )
    return num_frame, real_acq_time, computed_exposure
コード例 #24
0
def _run_E_ramp(dets,
                start,
                stop,
                velocity,
                deadband,
                *,
                streamname='primary',
                md=None):
    if md is None:
        md = {}

    md = ChainMap(
        md, {
            'plan_args': {
                'dets': list(map(repr, dets)),
                'start': start,
                'stop': stop,
                'velocity': velocity,
                'deadband': deadband
            },
            'plan_name': 'E_ramp',
            'motors': [pgm.energy.name]
        })
    # put the energy at the starting value
    yield from bps.abs_set(pgm.energy, start, wait=True)

    yield from bps.abs_set(pgm.fly.start_sig, start, wait=True)
    yield from bps.abs_set(pgm.fly.stop_sig, stop, wait=True)
    yield from bps.abs_set(pgm.fly.velocity, velocity, wait=True)

    if specs in dets:
        specs.stage()

    # TODO do this with stage
    old_db = epu1.flt.output_deadband.get()
    yield from bps.abs_set(epu1.flt.output_deadband, deadband)

    # get the old vlaue
    v = (yield from bps.read(epu1.flt.input_pv))
    if v is None:
        old_link = ''
    else:
        n = epu1.flt.input_pv.name
        old_link = v[n]['value']

    # define a clean up plan
    def clean_up():
        # move the energy setpoint to where the energy really is
        yield from bps.abs_set(pgm.energy, pgm.energy.position, wait=True)
        # set the interpolator to look at what it was looking at before
        # the scan.  This should be the energy set point.
        yield from bps.abs_set(epu1.flt.input_pv, old_link, wait=True)
        yield from bps.abs_set(epu1.flt.output_deadband, old_db, wait=True)

        if specs in dets:
            specs.unstage()

    # change to track the readout energy
    yield from change_epu_flt_link(pgm_energy.readback.pvname)

    def go_plan():
        ret = (yield from bps.abs_set(pgm.fly.fly_start, 1))

        st = StatusBase()
        enum_map = pgm.fly.scan_status.describe()[
            pgm.fly.scan_status.name]['enum_strs']

        def _done_cb(value, old_value, **kwargs):
            print(f'Old value {old_value} -> new value {value}')
            print(
                f'Old value type {type(old_value)} -> new value {type(value)}')
            try:
                old_value = enum_map[int(old_value)]
            except (TypeError, ValueError):
                ...
            try:
                value = enum_map[int(value)]
            except (TypeError, ValueError):
                ...
            if old_value != value and value == 'Ready':
                st._finished()
                pgm.fly.scan_status.clear_sub(_done_cb)

        if ret is not None:
            pgm.fly.scan_status.subscribe(_done_cb, run=False)
        else:
            st._finished()
            print('SIM MODE')

        return st

    def inner_plan():
        yield from trigger_and_read(dets, name=streamname)

    print(md)
    rp = ramp_plan(go_plan(), pgm.energy, inner_plan, period=None, md=md)

    return (yield from bpp.finalize_wrapper(rp, clean_up()))
コード例 #25
0
def _run_E_ramp(dets, start, stop, velocity, deadband, *, md=None):
    if md is None:
        md = {}

    md = ChainMap(md, {'plan_args': {'dets': list(map(repr, dets)),
                                     'start': start,
                                     'stop': stop,
                                     'velocity': velocity,
                                     'deadband': deadband},
                       'plan_name': 'E_ramp',
                       'motors': [pgm.energy.name]})
    # put the energy at the starting value
    yield from bps.abs_set(pgm.energy, start, wait=True)

    yield from bps.abs_set(pgm.fly.start_sig, start, wait=True)
    yield from bps.abs_set(pgm.fly.stop_sig, stop, wait=True)
    yield from bps.abs_set(pgm.fly.velocity, velocity, wait=True)

    # TODO do this with stage
    old_db = epu1.flt.output_deadband.get()
    yield from bps.abs_set(epu1.flt.output_deadband, deadband)

    # get the old vlaue
    v = (yield from bps.read(epu1.flt.input_pv))
    if v is None:
        old_link = ''
    else:
        n = epu1.flt.input_pv.name
        old_link = v[n]['value']

    # define a clean up plan
    def clean_up():
        # move the energy setpoint to where the energy really is
        yield from bps.abs_set(pgm.energy, pgm.energy.position, wait=True)
        # set the interpolator to look at what it was looking at before
        # the scan.  This should be the energy set point.
        yield from bps.abs_set(epu1.flt.input_pv, old_link, wait=True)
        yield from bps.abs_set(epu1.flt.output_deadband, old_db, wait=True)

    # change to track the readout energy
    yield from change_epu_flt_link(pgm_energy.readback.pvname)

    def go_plan():
        ret = (yield from bps.abs_set(pgm.fly.fly_start, 1))

        st = StatusBase()
        enum_map = pgm.fly.scan_status.describe()[pgm.fly.scan_status.name]['enum_strs']
        def _done_cb(value, old_value, **kwargs):
            old_value = enum_map[int(old_value)]
            value = enum_map[int(value)]
            if old_value != value and value == 'Ready':
                st._finished()
                pgm.fly.scan_status.clear_sub(_done_cb)

        if ret is not None:
            pgm.fly.scan_status.subscribe(_done_cb, run=False)
        else:
            st._finished()
            print('SIM MODE')

        return st

    def inner_plan():
        yield from trigger_and_read(dets)

    print(md)
    rp = ramp_plan(go_plan(), pgm.energy,
                   inner_plan, period=None, md=md)

    return (yield from bpp.finalize_wrapper(rp, clean_up()))
コード例 #26
0
def xy_fly(scan_title,
           *,
           dwell_time,
           xstart,
           xstop,
           xstep_size,
           ystart,
           ystop,
           ystep_size=None,
           xspress3=None):
    """Do a x-y fly scan.

    The x-motor is the 'fast' direction.

    Parameters
    ----------
    dwell_time : float
       Target time is s on each pixel

    xstart, xstop : float
       The start and stop values in the fast direction in mm

    xstep_size :
        xstep_size is step of x movement

    ystart, ystop : float
       The start and stop values in the slow direction in mm

    ystep_size :
        ystep_size use xstep_size if it isn't passed in

    scan_title : str
       Title of scan, required.
    """
    xy_fly_stage = xy_stage
    _validate_motor_limits(xy_fly_stage.x, xstart, xstop, 'x')
    _validate_motor_limits(xy_fly_stage.y, ystart, ystop, 'y')
    ystep_size = ystep_size if ystep_size is not None else xstep_size
    assert dwell_time > 0, f'dwell_time ({dwell_time}) must be more than 0'
    assert xstep_size > 0, f'xstep_size ({xstep_size}) must be more than 0'
    assert ystep_size > 0, f'ystep_size ({ystep_size}) must be more than 0'
    ret = yield from bps.read(xy_fly_stage.x.mres)  # (in mm)
    xmres = (ret[xy_fly_stage.x.mres.name]['value']
             if ret is not None else .0003125)

    ret = yield from bps.read(xy_fly_stage.y.mres)  # (in mm)
    ymres = (ret[xy_fly_stage.y.mres.name]['value']
             if ret is not None else .0003125)

    prescale = int(np.floor((xstep_size / (5 * xmres))))
    a_xstep_size = prescale * (5 * xmres)

    a_ystep_size = int(np.floor((ystep_size / (ymres)))) * ymres

    num_xpixels = int(np.floor((xstop - xstart) / a_xstep_size))
    num_ypixels = int(np.floor((ystop - ystart) / a_ystep_size))

    flyspeed = a_xstep_size / dwell_time  # this is in mm/s

    try:
        xy_fly_stage.x.velocity.check_value(flyspeed)
    except LimitError as e:
        raise LimitError(f'You requested a range of {xstop - xstart} with '
                         f'{num_xpixels} pixels and a dwell time of '
                         f'{dwell_time}.  This requires a '
                         f'motor velocity of {flyspeed} which '
                         'is out of range.') from e

    # set up delta-tau trigger to fast motor
    for v in ['p1600=0', 'p1607=1', 'p1600=1']:
        yield from bps.mv(dtt, v)
        yield from bps.sleep(0.1)

    # TODO make this a message?
    sclr.set_mode('flying')

    # poke the struck settings
    yield from bps.mv(sclr.mcas.prescale, prescale)
    yield from bps.mv(sclr.mcas.nuse, num_xpixels)

    if xspress3 is not None:
        yield from bps.mov(xs.external_trig, True)
        yield from mov(xspress3.total_points, num_xpixels)
        yield from mov(xspress3.hdf5.num_capture, num_xpixels)
        yield from mov(xspress3.settings.num_images, num_xpixels)

    @bpp.reset_positions_decorator([xy_fly_stage.x, xy_fly_stage.y])
    @bpp.stage_decorator([sclr])
    @bpp.baseline_decorator([mono, xy_fly_stage])
    # TODO put is other meta data
    @bpp.run_decorator(md={'scan_title': scan_title})
    def fly_body():

        yield from bps.mv(xy_fly_stage.x, xstart, xy_fly_stage.y, ystart)

        @bpp.stage_decorator([x for x in [xspress3] if x is not None])
        def fly_row():
            # go to start of row
            yield from bps.mv(xy_fly_stage.x, xstart, xy_fly_stage.y,
                              ystart + y * ystep_size)

            # set the fly speed
            yield from bps.mv(xy_fly_stage.x.velocity, flyspeed)

            yield from bps.trigger_and_read([xy_fly_stage], name='row_ends')

            for v in ['p1600=0', 'p1600=1']:
                yield from bps.mv(dtt, v)
                yield from bps.sleep(0.1)

            # arm the struck
            yield from bps.trigger(sclr, group=f'fly_row_{y}')
            # maybe start the xspress3
            if xspress3 is not None:
                yield from bps.trigger(xspress3, group=f'fly_row_{y}')
            yield from bps.sleep(0.1)
            # fly the motor
            yield from bps.abs_set(xy_fly_stage.x,
                                   xstop + a_xstep_size,
                                   group=f'fly_row_{y}')
            yield from bps.wait(group=f'fly_row_{y}')

            yield from bps.trigger_and_read([xy_fly_stage], name='row_ends')

            yield from bps.mv(xy_fly_stage.x.velocity, 5.0)
            yield from bps.sleep(.1)
            # read and save the struck
            yield from bps.create(name='primary')
            yield from bps.read(sclr)
            # and maybe the xspress3
            if xspress3 is not None:
                yield from bps.read(xspress3)
            yield from bps.save()

        for y in range(num_ypixels):
            if xspress3 is not None:
                yield from bps.mov(xspress3.fly_next, True)

            yield from fly_row()

    yield from fly_body()
コード例 #27
0
ファイル: plans.py プロジェクト: aps-7bm/apstools
def sscan_1D(
        sscan,
        poll_delay_s=0.001,
        phase_timeout_s = 60.0,
        running_stream="primary",
        final_array_stream=None,
        device_settings_stream="settings",
        md=None):
    """
    simple 1-D scan using EPICS synApps sscan record

    assumes the sscan record has already been setup properly for a scan

    PARAMETERS

    sscan : Device
        one EPICS sscan record (instance of `apstools.synApps.sscanRecord`)
    running_stream : str or `None`
        (default: ``"primary"``)
        Name of document stream to write positioners and detectors data
        made available while the sscan is running.  This is typically
        the scan data, row by row.
        If set to `None`, this stream will not be written.
    final_array_stream : str or `None`
        (default: ``None``)
        Name of document stream to write positioners and detectors data
        posted *after* the sscan has ended.
        If set to `None`, this stream will not be written.
    device_settings_stream : str or `None`
        (default: ``"settings"``)
        Name of document stream to write *settings* of the sscan device.
        This is all the information returned by ``sscan.read()``.
        If set to `None`, this stream will not be written.
    poll_delay_s : float
        (default: 0.001 seconds)
        How long to sleep during each polling loop while collecting
        interim data values and waiting for sscan to complete.
        Must be a number between zero and 0.1 seconds.
    phase_timeout_s : float
        (default: 60 seconds)
        How long to wait after last update of the ``sscan.FAZE``.
        When scanning, we expect the scan phase to update regularly
        as positioners move and detectors are triggered.  If the scan
        hangs for some reason, this is a way to end the plan early.
        To cancel this feature, set it to ``None``.

    NOTE about the document stream names

    Make certain the names for the document streams are different from
    each other.  If you make them all the same (such as ``primary``),
    you will have difficulty when reading your data later on.

    *Don't cross the streams!*

    EXAMPLE

    Assume that the chosen sscan record has already been setup.

        from apstools.devices import sscanDevice
        scans = sscanDevice(P, name="scans")

        from apstools.plans import sscan_1D
        RE(sscan_1D(scans.scan1), md=dict(purpose="demo"))

    """
    global new_data, inactive_deadline

    if not (0 <= poll_delay_s <= 0.1):
        raise ValueError(
            "poll_delay_s must be a number between 0 and 0.1,"
            f" received {poll_delay_s}")

    t0 = time.time()
    sscan_status = DeviceStatus(sscan.execute_scan)
    started = False
    new_data = False
    inactive_deadline = time.time()
    if phase_timeout_s is not None:
        inactive_deadline += phase_timeout_s

    def execute_cb(value, timestamp, **kwargs):
        """watch for sscan to complete"""
        if started and value in (0, "IDLE"):
            sscan_status._finished()
            sscan.execute_scan.unsubscribe_all()
            sscan.scan_phase.unsubscribe_all()

    def phase_cb(value, timestamp, **kwargs):
        """watch for new data"""
        global new_data, inactive_deadline
        if phase_timeout_s is not None:
            inactive_deadline = time.time() + phase_timeout_s
        if value in (15, "RECORD SCALAR DATA"):
            new_data = True            # set flag for main plan

    # acquire only the channels with non-empty configuration in EPICS
    sscan.select_channels()
    # pre-identify the configured channels
    sscan_data_objects = _get_sscan_data_objects(sscan)

    # watch for sscan to complete
    sscan.execute_scan.subscribe(execute_cb)
    # watch for new data to be read out
    sscan.scan_phase.subscribe(phase_cb)

    _md = dict(plan_name="sscan_1D")
    _md.update(md or {})

    yield from bps.open_run(_md)               # start data collection
    yield from bps.mv(sscan.execute_scan, 1)   # start sscan
    started = True

    # collect and emit data, wait for sscan to end
    while not sscan_status.done or new_data:
        if new_data and running_stream is not None:
            yield from bps.create(running_stream)
            for _k, obj in sscan_data_objects.items():
                yield from bps.read(obj)
            yield from bps.save()
        new_data = False
        if phase_timeout_s is not None and time.time() > inactive_deadline:
            print(f"No change in sscan record for {phase_timeout_s} seconds.")
            print("ending plan early as unsuccessful")
            sscan_status._finished(success=False)
        yield from bps.sleep(poll_delay_s)

    # dump the complete data arrays
    if final_array_stream is not None:
        yield from bps.create(final_array_stream)
        # we have to search for the arrays since they have ``kind="omitted"``
        # (which means they do not get reported by the ``.read()`` method)
        for part in (sscan.positioners, sscan.detectors):
            for nm in part.read_attrs:
                if "." not in nm:
                    # TODO: write just the acquired data, not the FULL arrays!
                    yield from bps.read(getattr(part, nm).array)
        yield from bps.save()

    # dump the entire sscan record into another stream
    if device_settings_stream is not None:
        yield from bps.create(device_settings_stream)
        yield from bps.read(sscan)
        yield from bps.save()

    yield from bps.close_run()

    elapsed = time.time() - t0
    print(f"total time for sscan_1D: {elapsed} s")

    return sscan_status
コード例 #28
0
 def _check_signal():
     val = yield from bps.read(done_signal)
     if val is None:
         return True
     val = val[signal_key]['value']
     return bool(val)
コード例 #29
0
def xy_fly(
    scan_title,
    *,
    beamline_operator,
    dwell_time,
    xstart,
    xstop,
    xstep_size,
    ystart,
    ystop,
    ystep_size=None,
    xspress3=None,
):
    """Do a x-y fly scan.

    The x-motor is the 'fast' direction.

    Parameters
    ----------
    scan_title : str
       A name for the scan.

    beamline_operator : str
       The individual responsible for this scan. Appears in output directory path.

    dwell_time : float
       Target time is s on each pixel

    xstart, xstop : float
       The start and stop values in the fast direction in mm

    xstep_size :
        xstep_size is step of x movement

    ystart, ystop : float
       The start and stop values in the slow direction in mm

    ystep_size :
        ystep_size use xstep_size if it isn't passed in

    scan_title : str
       Title of scan, required.
    """
    xy_fly_stage = xy_stage
    _validate_motor_limits(xy_fly_stage.x, xstart, xstop, "x")
    _validate_motor_limits(xy_fly_stage.y, ystart, ystop, "y")
    ystep_size = ystep_size if ystep_size is not None else xstep_size
    assert dwell_time > 0, f"dwell_time ({dwell_time}) must be more than 0"
    assert xstep_size > 0, f"xstep_size ({xstep_size}) must be more than 0"
    assert ystep_size > 0, f"ystep_size ({ystep_size}) must be more than 0"
    ret = yield from bps.read(xy_fly_stage.x.mres)  # (in mm)
    xmres = ret[
        xy_fly_stage.x.mres.name]["value"] if ret is not None else 0.0003125

    ret = yield from bps.read(xy_fly_stage.y.mres)  # (in mm)
    ymres = ret[
        xy_fly_stage.y.mres.name]["value"] if ret is not None else 0.0003125

    prescale = int(np.floor((xstep_size / (5 * xmres))))
    a_xstep_size = prescale * (5 * xmres)

    a_ystep_size = int(np.floor((ystep_size / (ymres)))) * ymres

    num_xpixels = int(np.floor((xstop - xstart) / a_xstep_size))
    num_ypixels = int(np.floor((ystop - ystart) / a_ystep_size))

    yield from bps.mv(
        x_centers,
        a_xstep_size / 2 + xstart + np.arange(num_xpixels) * a_xstep_size)

    # SRX original roi_key = getattr(xs.channel1.rois, roi_name).value.name
    roi_livegrid_key = xs.channel1.rois.roi01.value.name
    fig = plt.figure("xs")
    fig.clf()
    roi_livegrid = LiveGrid(
        (num_ypixels + 1, num_xpixels + 1),
        roi_livegrid_key,
        clim=None,
        cmap="inferno",
        xlabel="x (mm)",
        ylabel="y (mm)",
        extent=[xstart, xstop, ystart, ystop],
        x_positive="right",
        y_positive="down",
        ax=fig.gca(),
    )

    flyspeed = a_xstep_size / dwell_time  # this is in mm/s

    try:
        xy_fly_stage.x.velocity.check_value(flyspeed)
    except LimitError as e:
        raise LimitError(f"You requested a range of {xstop - xstart} with "
                         f"{num_xpixels} pixels and a dwell time of "
                         f"{dwell_time}.  This requires a "
                         f"motor velocity of {flyspeed} which "
                         "is out of range.") from e

    # set up delta-tau trigger to fast motor
    for v in ["p1600=0", "p1607=1", "p1600=1"]:
        yield from bps.mv(dtt, v)
        yield from bps.sleep(0.1)

    # TODO make this a message?
    sclr.set_mode("flying")
    # poke the struck settings
    yield from bps.mv(sclr.mcas.prescale, prescale)
    yield from bps.mv(sclr.mcas.nuse, num_xpixels)
    if xspress3 is not None:
        yield from bps.mv(xs.external_trig, True)
        yield from bps.mv(xspress3.total_points, num_xpixels)
        yield from bps.mv(xspress3.hdf5.num_capture, num_xpixels)
        yield from bps.mv(xspress3.settings.num_images, num_xpixels)

    @bpp.reset_positions_decorator([xy_fly_stage.x, xy_fly_stage.y])
    @bpp.subs_decorator({"all": [roi_livegrid]})
    @bpp.monitor_during_decorator([xs.channel1.rois.roi01.value])
    @bpp.stage_decorator([sclr])
    @bpp.baseline_decorator([mono, xy_fly_stage])
    # TODO put is other meta data
    @bpp.run_decorator(
        md={
            "scan_title": scan_title,
            "operator": beamline_operator,
            "user_input": {
                "dwell_time": dwell_time,
                "xstart": xstart,
                "xstop": xstop,
                "xstep_size": xstep_size,
                "ystart": ystart,
                "ystep_size": ystep_size,
            },
            "derived_input": {
                "actual_ystep_size": a_ystep_size,
                "actual_xstep_size": a_xstep_size,
                "fly_velocity": flyspeed,
                "xpixels": num_xpixels,
                "ypixels": num_ypixels,
                "prescale": prescale,
            },
        })
    def fly_body():

        yield from bps.mv(xy_fly_stage.x, xstart, xy_fly_stage.y, ystart)

        @bpp.stage_decorator([x for x in [xspress3] if x is not None])
        def fly_row():
            # go to start of row
            target_y = ystart + y * a_ystep_size
            yield from bps.mv(xy_fly_stage.x, xstart, xy_fly_stage.y, target_y)
            yield from bps.mv(y_centers,
                              np.ones(num_xpixels) *
                              target_y)  # set the fly speed

            ret = yield from bps.read(xy_fly_stage.z.user_readback)  # (in mm)
            zpos = (ret[xy_fly_stage.z.user_readback.name]["value"]
                    if ret is not None else 0)
            yield from bps.mov(z_centers, np.ones(num_xpixels) * zpos)

            yield from bps.mv(xy_fly_stage.x.velocity, flyspeed)

            yield from bps.trigger_and_read([xy_fly_stage], name="row_ends")

            for v in ["p1600=0", "p1600=1"]:
                yield from bps.mv(dtt, v)
                yield from bps.sleep(0.1)

            # arm the struck
            yield from bps.trigger(sclr, group=f"fly_row_{y}")
            # maybe start the xspress3
            if xspress3 is not None:
                yield from bps.trigger(xspress3, group=f"fly_row_{y}")
            yield from bps.sleep(0.1)
            # fly the motor
            yield from bps.abs_set(xy_fly_stage.x,
                                   xstop + a_xstep_size,
                                   group=f"fly_row_{y}")
            yield from bps.wait(group=f"fly_row_{y}")

            yield from bps.trigger_and_read([xy_fly_stage], name="row_ends")
            yield from bps.mv(xy_fly_stage.x.velocity, 5.0)
            yield from bps.sleep(0.1)
            # read and save the struck
            yield from bps.create(name="primary")
            #
            yield from bps.read(sclr)
            yield from bps.read(mono)
            yield from bps.read(x_centers)
            yield from bps.read(y_centers)
            yield from bps.read(z_centers)
            yield from bps.read(xy_fly_stage.y)
            yield from bps.read(xy_fly_stage.z)
            # and maybe the xspress3
            if xspress3 is not None:
                yield from bps.read(xspress3)
            yield from bps.save()

        for y in range(num_ypixels):
            if xspress3 is not None:
                yield from bps.mv(xspress3.fly_next, True)

            yield from fly_row()

    yield from fly_body()

    # save the start document to a file for the benefit of the user
    start = db[-1].start
    dt = datetime.datetime.fromtimestamp(start["time"])
    filepath = os.path.expanduser(
        f"~/Users/Data/{start['operator']}/{dt.date().isoformat()}/xy_fly/"
        f"{start['scan_title']}-{start['scan_id']}-{start['operator']}-{dt.time().isoformat()}.log"
    )
    os.makedirs(os.path.dirname(filepath), exist_ok=True)
    with open(filepath, "wt") as output_file:
        output_file.write(pprint.pformat(start))
コード例 #30
0
def _get_v_with_dflt(sig, dflt):
    ret = yield from bps.read(sig)
    return ret[sig.name]["value"] if ret is not None else dflt
コード例 #31
0
 def custom(detector):
     for i in range(3):
         yield from create()
         yield from read(detector)
         yield from save()
コード例 #32
0
 def add_daq_read(msg):
     if msg.obj is not daq:
         yield from bps.read(daq)
     return (yield msg)