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 grid_fly(flyer, y, ystart, ystop, ynum, x, xstart, xstop, xnum):
    generator = CompoundGenerator(
        generators=[
            LineGenerator(y.name, "mm", ystart, ystop, ynum),
            LineGenerator(x.name, "mm", xstart, xstop, xnum),
        ],
        duration=0.1,
    )
    mapping.configure(dict(generator=generator))
    md = dict(
        hints=dict(
            gridding="rectilinear",
            dimensions=[([y.name], "primary"), ([x.name], "primary")],
        ),
        shape=(ynum, xnum),
        extents=([ystart, ystop], [xstart, xstop]),
    )
    uid = yield from bps.open_run(md)
    yield from bps.kickoff(flyer, wait=True)
    yield from bps.collect(flyer, stream=True)
    yield from bps.checkpoint()
    yield from bps.complete(flyer, group="flyer")
    for _ in range(int(ynum * xnum * 0.1)):
        yield from bps.sleep(1)
        yield from bps.collect(flyer, stream=True)
        yield from bps.checkpoint()
    yield from bps.wait(group="flyer")
    yield from bps.collect(flyer, stream=True)
    yield from bps.close_run()
    return uid
示例#3
0
 def measure_plan(detectors):
     yield from open_run()
     ret = yield from measure_average(detectors, num=250)
     assert ret['motor'] == 0.0
     assert ret['motor_setpoint'] == 0.0
     assert np.isclose(ret['noisy_det'], 1.0, atol=0.01)
     yield from close_run()
示例#4
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()
示例#5
0
 def gss():
     global region_limits
     yield from open_run()
     region_limits = yield from golden_section_search(sig,
                                                      motor,
                                                      0.01,
                                                      limits=(-10, 5))
     yield from close_run()
示例#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 measure_plan(detectors):
     yield from open_run()
     ret = yield from measure_average(detectors, num=250)
     logger.debug('Test received %s from measure_average', str(ret))
     assert ret['motor'] == 0.0
     assert ret['motor_setpoint'] == 0.0
     assert np.isclose(ret['noisy_det'], 1.0, atol=0.1)
     yield from close_run()
示例#8
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)
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)
示例#10
0
    def interlaced_plan(dets, motor):
        to_read = (motor, *dets)
        run_ids = list("abc")
        for rid in run_ids:
            yield from drw(bps.open_run(md={rid: rid}), run=rid)

        for j in range(5):
            for i, rid in enumerate(run_ids):
                yield from bps.mov(motor, j + 0.1 * i)
                yield from drw(bps.trigger_and_read(to_read), run=rid)

        for rid in run_ids:
            yield from drw(bps.close_run(), run=rid)
示例#11
0
    def interlaced_plan(dets, motor):
        to_read = (motor, *dets)
        run_names = ["run_one", "run_two", "run_three"]
        for rid in run_names:
            yield from srkw(bps.open_run(md={rid: rid}), run=rid)

        for j in range(5):
            for i, rid in enumerate(run_names):
                yield from bps.mov(motor, j + 0.1 * i)
                yield from srkw(bps.trigger_and_read(to_read), run=rid)

        for rid in run_names:
            yield from srkw(bps.close_run(), run=rid)
示例#12
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)
示例#13
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()
示例#14
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()
示例#15
0
def plan(threshold):
    yield from bps.open_run()
    yield from bps.kickoff(det, wait=True)
    target_pos = -3.0
    while True:
        yield from bps.mv(pos, target_pos)
        yield from bps.sleep(0.1)  # fake motor delay
        payload = yield from bps.collect(det, stream=True)
        for reading in payload:
            x = reading['data']['x']
            historical_pos = reading['data']['pos']
            print(
                f"current={target_pos:.3} historical={historical_pos:.3} x={x:.3}"
            )
            if x > threshold:
                yield from bps.close_run()
                print("DONE!")
                return
        target_pos += 0.1
示例#16
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
示例#17
0
 def plan():
     yield from open_run(md={'a': 1})
示例#18
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
示例#19
0
    def plan(self, md={}):
        """
        run the USAXS fly scan
        """
        bluesky_runengine_running = RE.state != "idle"

        def _report_(t):
            elapsed = struck.elapsed_real_time.get()
            channel = None
            if elapsed is not None:
                channel = struck.current_channel.get()
                if elapsed > t:  # looking at previous fly scan
                    elapsed = 0
                    channel = 0
                terms.FlyScan.elapsed_time.put(elapsed)  # for our GUI display

            values = [
                f"{t:.2f}",
            ]
            values.append(f"{a_stage.r.position:.7f}")
            values.append(f"{a_stage.y.position:.5f}")
            values.append(f"{d_stage.y.position:.5f}")
            missing = "-missing-"
            if channel is None:
                values.append(missing)
            else:
                values.append(f"{channel}")
            if elapsed is None:
                values.append(missing)
            else:
                values.append(f"{elapsed:.2f}")
            # values.append(resource_usage())
            return "  ".join([f"{s:11}" for s in values])

        @run_in_thread
        def progress_reporting():
            logger.debug("progress_reporting has arrived")
            t = time.time()
            timeout = t + self.scan_time.get(
            ) + self.timeout_s  # extra padded time
            startup = t + self.update_interval_s / 2
            while t < startup and not self.flying.get(
            ):  # wait for flyscan to start
                time.sleep(0.01)
            labels = ("flying, s", "ar, deg", "ay, mm", "dy, mm", "channel",
                      "elapsed, s")
            logger.info("  ".join([f"{s:11}" for s in labels]))
            while t < timeout and self.flying.get():
                if t > self.update_time:
                    self.update_time = t + self.update_interval_s
                    msg = _report_(t - self.t0)
                    logger.debug(msg)
                time.sleep(0.01)
                t = time.time()
            msg = _report_(time.time() - self.t0)
            logger.info(msg)
            # user_data.set_state_blocking(msg.split()[0])
            if t > timeout:
                logger.error(
                    f"{time.time()-self.t0}s - progress_reporting timeout!!")
            else:
                logger.debug(
                    f"{time.time()-self.t0}s - progress_reporting is done")

        @run_in_thread
        def prepare_HDF5_file():
            fname = os.path.abspath(self.saveFlyData_HDF5_dir)
            if not os.path.exists(fname):
                msg = f"Must save fly scan data to an existing directory.  Gave {fname}"
                fname = os.path.abspath(self.fallback_dir)
                msg += f"  Using fallback directory {self.fallback_dir}"
                logger.error(msg)

            s = self.saveFlyData_HDF5_file
            _s_ = os.path.join(fname, s)  # for testing here
            if os.path.exists(_s_):
                msg = f"File {_s_} exists.  Will not overwrite."
                s = datetime.datetime.isoformat(datetime.datetime.now(),
                                                sep="_").split(".")[0]
                s = s.replace(":", "").replace("-", "")
                # s = "flyscan_" + s + ".h5"
                _s_ = os.path.join(fname, s)
                msg += f"  Using fallback file name {_s_}"
                logger.error(msg)
            fname = os.path.join(fname, s)

            logger.info(f"HDF5 config: {self.saveFlyData_config}")
            logger.info(f"HDF5 output: {fname}")
            self._output_HDF5_file_ = fname
            user_data.set_state_blocking("FlyScanning: " +
                                         os.path.split(fname)[-1])

            # logger.debug(resource_usage("before SaveFlyScan()"))
            self.saveFlyData = SaveFlyScan(fname,
                                           config_file=self.saveFlyData_config)
            # logger.debug(resource_usage("before saveFlyData.preliminaryWriteFile()"))
            self.saveFlyData.preliminaryWriteFile()
            # logger.debug(resource_usage("after saveFlyData.preliminaryWriteFile()"))

        @run_in_thread
        def finish_HDF5_file():
            if self.saveFlyData is None:
                raise RuntimeError("Must first call prepare_HDF5_file()")
            self.saveFlyData.saveFile()

            logger.info(f"HDF5 output complete: {self._output_HDF5_file_}")
            self.saveFlyData = None

        ######################################################################
        # plan starts here
        global specwriter

        # remember our starting conditions
        self.ar0 = a_stage.r.position
        self.ay0 = a_stage.y.position
        self.dy0 = d_stage.y.position

        _md = OrderedDict()
        _md.update(md or {})
        _md["hdf5_file"] = self.saveFlyData_HDF5_file
        _md["hdf5_path"] = self.saveFlyData_HDF5_dir

        yield from bps.open_run(md=_md)
        specwriter._cmt("start", "start USAXS Fly scan")
        yield from bps.mv(
            upd_controls.auto.mode,
            AutorangeSettings.auto_background,
        )

        self.t0 = time.time()
        self.update_time = self.t0 + self.update_interval_s
        if self.flying.get():
            yield from bps.abs_set(self.flying, False)
        else:
            logger.warning("Was not flying but should be.")

        if bluesky_runengine_running:
            prepare_HDF5_file(
            )  # prepare HDF5 file to save fly scan data (background thread)
        # path = os.path.abspath(self.saveFlyData_HDF5_dir)
        specwriter._cmt("start",
                        f"HDF5 configuration file: {self.saveFlyData_config}")

        g = uuid.uuid4()
        yield from bps.abs_set(
            self.busy,
            BusyStatus.busy,
            group=g,  # waits until done
            timeout=self.scan_time.get() + self.timeout_s)

        if bluesky_runengine_running:
            progress_reporting()

        if self.flying._status is not None and not self.flying._status.done:
            # per https://github.com/APS-USAXS/ipython-usaxs/issues/499
            logger.warning(
                "Clearing unfinished status object on 'usaxs_flyscan/flying'")
            self.flying._status.set_finished()
        if not self.flying.get():
            yield from bps.abs_set(self.flying, True)
        else:
            logger.warning("Already flying, should not be flying now.")

        yield from bps.wait(group=g)
        if not self.flying.get():
            yield from bps.abs_set(self.flying, False)
        else:
            logger.warning(
                "Already flying (after wait), should not be flying now.")
        elapsed = time.time() - self.t0
        specwriter._cmt("stop", f"fly scan completed in {elapsed} s")

        if bluesky_runengine_running:
            msg = f"writing fly scan HDF5 file: {self._output_HDF5_file_}"
            logger.debug(msg)
            try:
                yield from user_data.set_state_plan(
                    "writing fly scan HDF5 file")
            except Exception as exc:
                # do not fail the scan just because of updating program state
                logger.warning("Non-fatal error while %s\n%s\nPlan continues",
                               msg, exc)
                # FIXME: hack to avoid `Another set() call is still in progress`
                # see: https://github.com/APS-USAXS/ipython-usaxs/issues/417
                user_data.state._set_thread = None
            # logger.debug(resource_usage("before saveFlyData.finish_HDF5_file()"))
            finish_HDF5_file(
            )  # finish saving data to HDF5 file (background thread)
            # logger.debug(resource_usage("after saveFlyData.finish_HDF5_file()"))
            specwriter._cmt("stop", f"finished {msg}")
            logger.info(f"finished {msg}")

        yield from bps.mv(
            a_stage.r.user_setpoint,
            self.ar0,
            a_stage.y.user_setpoint,
            self.ay0,
            d_stage.y.user_setpoint,
            self.dy0,
            upd_controls.auto.mode,
            AutorangeSettings.auto_background,
            ti_filter_shutter,
            "close",
        )

        yield from addDeviceDataAsStream(
            [struck.mca1, struck.mca2, struck.mca3], "mca")
        logger.debug(f"after return: {time.time() - self.t0}s")

        yield from user_data.set_state_plan("fly scan finished")
        yield from bps.close_run()
示例#20
0
 def interlaced_plan(dets, motor):
     run_ids = list("abc")
     for rid in run_ids:
         yield from drw(bps.open_run(md={rid: rid}), run=rid)
     raise Exception("womp womp")
示例#21
0
 def plan():
     yield from open_run(md={'a': 1})
示例#22
0
def plan_simultaneously(x_centroid,
                        y_centroid,
                        x,
                        y,
                        atol,
                        x_target=None,
                        y_target=None):
    """
     
    This BlueSky plan aligns the laser's centroid with the x-ray's centroid.
     
    This plan implements 'walk_to_pixel' from the pswalker (a beam alignment module). The plan uses an iterative procedure to  align any beam to a position on a screen, when two motors move the beam along the two axes. Liveplots are updated and show the paths taken to achieve alignment.

    
    Parameters
    ----------
    x_centroid, y_centroid : 
        These represent the x_centroid and y_centroid 
    x, y: 
        These respresnt the x_motor and y_motor
    x_target, y_target : int
        Target value on the x-axis and y-axis
        
    """

    #Create a figure
    fig = plt.figure(figsize=(15, 10))
    fig.subplots_adjust(hspace=0.3, wspace=0.4)

    #The first subplot, which plots the y_centroid vs x_centroid
    ax1 = fig.add_subplot(2, 2, 1)
    ax1.invert_yaxis()
    x_centroid_y_centroid = LivePlot(y_centroid.name,
                                     x_centroid.name,
                                     ax=ax1,
                                     marker='x',
                                     markersize=7,
                                     color='orange')

    #The second subplot, which plots the y_centroid and x_centroid with same x-axis (y_motor)
    ax2 = fig.add_subplot(2, 2, 3)
    ax2.set_ylabel(y_centroid.name, color='red')
    ax3 = ax2.twinx()
    #     ax2.invert_yaxis()
    #     ax3.invert_yaxis()
    ax3.set_ylabel(x_centroid.name, color='blue')
    y_plot_y_centroid = LivePlot(y_centroid.name,
                                 y.name,
                                 ax=ax2,
                                 marker='x',
                                 markersize=6,
                                 color='red')
    y_plot_x_centroid = LivePlot(x_centroid.name,
                                 y.name,
                                 ax=ax3,
                                 marker='o',
                                 markersize=6,
                                 color='blue')

    #The third subplot, which plots the y_centroid and x_centroid with same x-axis (x_motor)
    ax4 = fig.add_subplot(2, 2, 4)
    ax4.set_ylabel(y_centroid.name, color='green')
    ax5 = ax4.twinx()
    ax5.set_ylabel(x_centroid.name, color='purple')
    x_plot_y_centroid = LivePlot(y_centroid.name,
                                 x.name,
                                 ax=ax4,
                                 marker='x',
                                 markersize=6,
                                 color='green')
    x_plot_x_centroid = LivePlot(x_centroid.name,
                                 x.name,
                                 ax=ax5,
                                 marker='o',
                                 markersize=6,
                                 color='purple')

    #Subscribe the plots
    token_x_centroid_y_centroid = yield from subscribe('all',
                                                       x_centroid_y_centroid)
    token_y_plot_x_centroid = yield from subscribe('all', y_plot_x_centroid)
    token_y_plot_y_centroid = yield from subscribe('all', y_plot_y_centroid)
    token_x_plot_x_centroid = yield from subscribe('all', x_plot_x_centroid)
    token_x_plot_y_centroid = yield from subscribe('all', x_plot_y_centroid)

    #Start a new run
    yield from open_run(
        md={
            'detectors': [(x_centroid.name), (y_centroid.name)],
            'motors': [(x.name), (y.name)],
            'hints': {
                'dimensions': [(x.hints['fields'],
                                'primary'), (y.hints['fields'], 'primary')]
            }
        })

    #Ask for the target values
    if x_target is None:
        x_target = int(input('Enter the x value: '))
    if y_target is None:
        y_target = int(input('Enter the y value: '))

    #Iteratively move until x_target and x-centroid are within a certain threshold of each other
    while True:
        if not np.isclose(x_target, x_centroid.get(), atol):
            yield from walk_to_pixel(x_centroid,
                                     x,
                                     x_target,
                                     first_step=0.1,
                                     target_fields=[x_centroid.name, x.name],
                                     tolerance=atol,
                                     average=5,
                                     system=[y, y_centroid])
        elif not np.isclose(y_target, y_centroid.get(), atol):
            yield from walk_to_pixel(y_centroid,
                                     y,
                                     y_target,
                                     first_step=0.1,
                                     tolerance=atol,
                                     average=5,
                                     target_fields=[y_centroid.name, y.name],
                                     system=[x, x_centroid])
        else:
            break


#     plt.show(block=True)

#Close the run
    yield from close_run()
    #Unsubscribe the plots
    yield from unsubscribe(token_x_centroid_y_centroid)
    yield from unsubscribe(token_y_plot_x_centroid)
    yield from unsubscribe(token_y_plot_y_centroid)
    yield from unsubscribe(token_x_plot_x_centroid)
    yield from unsubscribe(token_x_plot_y_centroid)
示例#23
0
文件: plans.py 项目: teddyrendahl/mfx
def tfs_scan(start, stop):
    yield from open_run()
    yield from mv(tfs_trans, start)
    yield from mv(tfs_trans, stop)
    yield from close_run()
示例#24
0
def move_and_count(motor, target):
    yield from bps.open_run(None)
    yield from bps.mv(motor, target)
    yield from bps.close_run()
示例#25
0
 def interlaced_plan(dets, motor):
     run_names = ["run_one", "run_two", "run_three"]
     for rid in run_names:
         yield from srkw(bps.open_run(md={rid: rid}), run=rid)
     raise Exception("womp womp")
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()
示例#27
0
 def plan():
     yield from open_run()
     yield from stage(m)
     yield from unstage(m)
     yield from close_run()
示例#28
0
def ud_crab_plan(pu, us_u, us_l, ds_u, ds_l, other_dets=None):
    '''A generator plan for crabbing the undulator to new position

    This is a single-use plan for moving the undulator to a new position ::

       plan = ud_crab_plan(pu, a, 6.46, 6.46, 6.46, [ut])
       gs.RE(plan)

    This plan round-robin moves the motors to the desired positions taking
    readings of all the motor positions and any additional detectors and ~1Hz

    Parameters
    ----------
    pu : PowerUndulator
        Bucket of undulator motors

    us_u : float
        The target upstream upper motor position

    us_l : float
        The target upstream lower motor position

    ds_u : float
        The target downstream upper motor position

    ds_l : float
        The target downstream lower motor position

    other_dets : list, optional
        List of other detectors to read
    '''
    pu.stop()
    if other_dets is None:
        other_dets = []
    # magic goes here
    #if abs(us_u - ds_u) > CRAB_LIMIT:
    if abs(us_u - ds_u) > TILT_LIMIT:
        raise ValueError("exceded tilt limit on upper |{} - {}| > {}".format(
                us_u,  ds_u, TILT_LIMIT))

    #if abs(us_l - ds_l) > CRAB_LIMIT:
    if abs(us_l - ds_l) > TILT_LIMIT:
        raise ValueError("exceded tilt limit on lower |{} - {}| > {}".format(
                us_l,  ds_l, TILT_LIMIT))

    def limit_position(pos, pair_pos, target, pair_target):
        if abs(pair_pos - pair_target) < TARGET_THRESH:
            # on final step
            limit = TILT_LIMIT
        else:
            limit = CRAB_LIMIT
        # moving out
        if target > pos:
            return min(target, pair_pos + limit)
        else:
            return max(target, pair_pos - limit)

    def traj(pu):
        while True:
            done_count = 0
            # MOVE THE UPSTREAM UPPER
            cur_usu = pu.us_upper.position
            cur_dsu = pu.ds_upper.position
            if abs(cur_usu - us_u) > TARGET_THRESH:
                target = limit_position(cur_usu, cur_dsu, us_u, ds_u)
                yield pu.us_upper, target
            else:
                done_count += 1

            # MOVE THE DOWNSTREAM UPPER
            cur_usu = pu.us_upper.position
            cur_dsu = pu.ds_upper.position
            if abs(cur_dsu - ds_u) > TARGET_THRESH:
                target = limit_position(cur_dsu, cur_usu, ds_u, us_u)
                yield pu.ds_upper, target
            else:
                done_count += 1

            # MOVE THE UPSTREAM lower
            cur_usl = pu.us_lower.position
            cur_dsl = pu.ds_lower.position
            if abs(cur_usl - us_l) > TARGET_THRESH:
                target = limit_position(cur_usl, cur_dsl, us_l, ds_l)
                yield pu.us_lower, target
            else:
                done_count += 1

            # MOVE THE DOWNSTREAM lower
            cur_usl = pu.us_lower.position
            cur_dsl = pu.ds_lower.position
            if abs(cur_dsl - ds_l) > TARGET_THRESH:
                target = limit_position(cur_dsl, cur_usl, ds_l, us_l)
                yield pu.ds_lower, target
            else:
                done_count += 1

            if done_count == 4:
                return

    yield from open_run()
    yield from trigger_and_read([pu] + other_dets)
    for mot, target in traj(pu):
        print("About to move {} to {}".format(mot.name, target))
        # yield Msg('checkpoint', None)
        # yield Msg('pause', None)
        # yield Msg('clear_checkpoint', None)
        st = yield Msg('set', mot, target, timeout=None)
        # move the motor
        # speed is mm / s measured on us lower 2016-06-02
        # timeout is 3 * max_crab / speed
        fail_time = ttime.time() + (TILT_LIMIT / .0003) * 4
        while not st.done:
            yield from trigger_and_read([pu] + other_dets)
            if ttime.time() > fail_time:
                mot.stop()
                raise RuntimeError("Undulator move timed out")
            yield Msg('checkpoint')
            yield Msg('sleep', None, 1)

        if st.error > .002:
            raise RuntimeError("only got with in {} of target {}".
                               format(st.error, st.target))
        yield Msg('checkpoint')
        for j in range(2):
            yield Msg('sleep', None, 1)
            yield from trigger_and_read([pu] + other_dets)
        yield Msg('checkpoint')
    yield from close_run()
示例#29
0
    def scan_closure():
        # -------------------
        # collect white field
        # -------------------
        # 1-1 monitor shutter status, auto-puase scan if beam is lost
        yield from bps.open_run()
        yield from bps.mv(A_shutter, 'open')
        yield from bps.install_suspender(suspend_A_shutter)

        #1-1.5 configure output plugins     edited by Jason 07/19/2019
        for me in [det.tiff1, det.hdf1]:
            yield from bps.mv(me.file_path, fp)
            yield from bps.mv(me.file_name, fn)
            yield from bps.mv(me.file_write_mode, 2)
            yield from bps.mv(me.num_capture, total_images)
            yield from bps.mv(
                me.file_template,
                ".".join([r"%s%s_%06d", config['output']['type'].lower()]))

        if config['output']['type'] in ['tif', 'tiff']:
            yield from bps.mv(det.tiff1.enable, 1)
            yield from bps.mv(det.tiff1.capture, 1)
            yield from bps.mv(det.hdf1.enable, 0)
        elif config['output']['type'] in ['hdf', 'hdf1', 'hdf5']:
            yield from bps.mv(det.tiff1.enable, 0)
            yield from bps.mv(det.hdf1.enable, 1)
            yield from bps.mv(det.hdf1.capture, 1)
        else:
            raise ValueError(f"Unsupported output type {output_dict['type']}")

        # 1-2 move sample out of the way
        initial_samx = samX.position
        initial_samy = samY.position
        initial_preci = preci.position
        dx = config['tomo']['sample_out_position']['samX']
        dy = config['tomo']['sample_out_position']['samY']
        r = config['tomo']['sample_out_position']['preci']
        yield from bps.mv(samX, initial_samx + dx)
        yield from bps.mv(samY, initial_samy + dy)
        yield from bps.mv(preci, r)

        # 1-2.5 set frame type for an organized HDF5 archive
        yield from bps.mv(det.cam.frame_type, 0)

        # 1-3 collect front white field images
        yield from bps.mv(det.hdf1.nd_array_port, 'PROC1')
        yield from bps.mv(det.tiff1.nd_array_port, 'PROC1')
        yield from bps.mv(det.proc1.enable, 1)
        yield from bps.mv(det.proc1.reset_filter, 1)
        yield from bps.mv(det.proc1.num_filter, n_frames)
        yield from bps.mv(det.cam.trigger_mode, "Internal")
        yield from bps.mv(det.cam.image_mode, "Multiple")
        yield from bps.mv(det.cam.num_images, n_frames * n_white)
        yield from bps.mv(det.cam.acquire_time, acquire_time)
        yield from bps.mv(det.cam.acquire_period, acquire_period)
        yield from bps.trigger_and_read([det])

        # 1-4 move sample back
        yield from bps.mv(samX, initial_samx)
        yield from bps.mv(samY, initial_samy)
        #yield from bps.mv(preci, initial_preci)

        # -------------------
        # collect projections
        # -------------------
        # 1-5 set frame type for an organized HDF5 archive
        yield from bps.mv(det.cam.frame_type, 1)
        # 1-6 step and fly scan are differnt
        if config['tomo']['type'].lower() == 'step':
            yield from bps.mv(det.proc1.reset_filter, 1)
            yield from bps.mv(det.cam.num_images, n_frames)
            # 1-6 collect projections
            for ang in angs:
                yield from bps.checkpoint()
                yield from bps.mv(preci, ang)
                yield from bps.trigger_and_read([det])
        elif config['tomo']['type'].lower() == 'fly':
            yield from bps.mv(det.proc1.num_filter, 1)
            yield from bps.mv(det.hdf1.nd_array_port, 'PG1')
            yield from bps.mv(det.tiff1.nd_array_port, 'PG1')
            yield from bps.mv(
                psofly.start,
                config['tomo']['omega_start'],
                psofly.end,
                config['tomo']['omega_end'],
                psofly.scan_delta,
                abs(config['tomo']['omega_step']),
                psofly.slew_speed,
                slew_speed,
            )
            # taxi
            yield from bps.mv(psofly.taxi, "Taxi")
            # setup detector to overlap for fly scan
            yield from bps.mv(
                det.cam.num_images,
                n_projections,
                det.cam.trigger_mode,
                "Overlapped",
            )
            # start the fly scan
            print("before trigger")
            yield from bps.trigger(det, group='trigger')
            print("waiting for trigger")
            # yield from bps.wait(group='trigger')
            print("before plan()")
            try:
                yield from psofly.plan()
            except NotEnoughTriggers as err:
                reason = (
                    f"{err.expected:.0f} were expected but {err.actual:.0f} were received."
                )
                yield from bps.close_run('fail', reason=reason)
                return  # short-circuit

            # fly scan finished. switch image port and trigger_mode back
            yield from bps.mv(det.cam.trigger_mode, "Internal")
            yield from bps.mv(det.hdf1.nd_array_port, 'PROC1')
            yield from bps.mv(det.tiff1.nd_array_port, 'PROC1')
        else:
            raise ValueError(f"Unknown scan type: {config['tomo']['type']}")

        # ------------------
        # collect back white
        # ------------------
        # 1-7 move the sample out of the way
        # NOTE:
        # this will return ALL motors to starting positions, we need a
        # smart way to calculate a shorter trajectory to move sample
        # out of way
        yield from bps.mv(preci, r)
        yield from bps.mv(samX, initial_samx + dx)
        yield from bps.mv(samY, initial_samy + dy)

        # 1-7.5 set frame type for an organized HDF5 archive
        yield from bps.mv(det.cam.frame_type, 2)

        # 1-8 take the back white
        yield from bps.mv(det.proc1.num_filter, n_frames)
        yield from bps.mv(det.cam.num_images, n_frames * n_white)
        yield from bps.trigger_and_read([det])

        # 1-9 move sample back
        yield from bps.mv(samX, initial_samx)
        yield from bps.mv(samY, initial_samy)

        # -----------------
        # collect back dark
        # -----------------
        # 1-10 close the shutter
        yield from bps.remove_suspender(suspend_A_shutter)
        yield from bps.mv(A_shutter, "close")

        # 1-10.5 set frame type for an organized HDF5 archive
        yield from bps.mv(det.cam.frame_type, 3)

        # 1-11 collect the back dark
        yield from bps.mv(det.cam.num_images, n_frames * n_dark)
        yield from bps.trigger_and_read([det])
        yield from bps.close_run('success')
示例#30
0
def plan():
    yield from open_run()
    yield from sleep(1)
    yield from pause()
    yield from close_run()