Exemple #1
0
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()
    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()
    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)
Exemple #4
0
 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()
        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)
            #  revised by YDu, no such value before
            #yield from bps.sleep(0)
            #         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")

            # 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}")
            #  revised by YDu, use to be 0.1
            yield from bps.sleep(1.5)  # 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)
            #  revised by YDu, use to be 0.1
            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.sleep(0.2)
            yield from bps.save()
            yield from bps.sleep(0.2)
Exemple #6
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)
Exemple #7
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)

            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()
 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()
        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
            # 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
            yield from bps.save()
Exemple #10
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
Exemple #11
0
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
        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()
        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()
Exemple #14
0
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
 def custom(detector):
     for i in range(3):
         yield from create()
         yield from read(detector)
         yield from save()
 def plan(reader, expected):
     for i in range(10):
         yield from create()
         assert daq.state == expected
         yield from read(reader)
         yield from save()