{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# synApps _sscan_ as 1D Flyer\n", "\n", "In this notebook, the EPICS *sscan* record is demonstrated as a bluesky *Flyer*. The EPICS sscan record will conduct a scan as configured from bluesky. After the scan, the data will be returned to bluesky for routine inclusion in the run's documents.\n", "\n", "NOTE: This notebook is under construction!\n", "\n", "## Overview\n", "\n", "The [Bluesky](https://blueskyproject.io/bluesky) framework has support for data acquisition using an external data collector. The support is for an ophyd _fly-able_ device, which must be customized for the details of that external data collector. The design prototype collector is a _fly_ scan controller (hence the name used by bluesky), operating outside the _bluesky_ process, which performs its readings of detector(s) during continuous (_on-the-fly_) motion of one or more positioners. Triggering of the detectors must also be part of the external controller. The description is that this type of [asynchronous acquisition](https://blueskyproject.io/bluesky/async.html#asynchronous-acquisition) requires fine-grained timing beyond the capabilities of *bluesky*.\n", "\n", "> Flying means: “Let the hardware take control, cache data externally, and then transfer all the data to the RunEngine at the end.” This is essential when the data acquisition rates are faster than the RunEngine or Python can go.\n", "\n", "Note: As a consequence of the external nature of this *Flyer* device, the usual activity of the bluesky RunEngine pertaining to interruptions (pause, resume, stop, or abort) may not affect the progress of the external data collector. The RunEngine may only interrupt the external data collector as that collector allows in its interface with bluesky.\n", "\n", "_Any_ external data acquisition controller or data logger is suitable for use as a bluesky *Flyer*. It is not necessary for the external controller to conduct its acquisition at high rates.\n", "\n", "The EPICS [sscan record](https://epics.anl.gov/bcda/synApps/sscan/sscanRecord.html) is an example of an external data acquisition controller. It supports various scan types (step, list, continuous) with flexible configuration for up to four positioners and dozens of detectors, as well as scans of up to four dimensions. The *sscan* record is used by many APS beamlines for routine data collection.\n", "\n", "## References\n", "\n", "The documentation for *Flyer*s is distributed across the *bluesky* and *ophyd* packages:\n", "\n", "- Pre-assembled bluesky plans: https://blueskyproject.io/bluesky/plans.html#pre-assembled-plans\n", "- bluesky `fly()` plan: https://blueskyproject.io/bluesky/generated/bluesky.plans.fly.html#bluesky.plans.fly\n", "- asynchronous collection with fly scans: https://blueskyproject.io/bluesky/plans.html#asynchronous-plans-fly-scans-and-monitoring\n", "- Asynchronous Acquisition:https://blueskyproject.io/bluesky/async.html\n", "- ophyd flyer classes: https://blueskyproject.io/ophyd/generated/ophyd.flyers.html\n", "- ophyd Fly-able Interface (with links to the `FlyerInterface()` methods) : https://blueskyproject.io/ophyd/architecture.html#fly-able-interface\n", "## 1D step scans using sscan record\n", "\n", "Use the [*sscan* record](https://epics.anl.gov/bcda/synApps/sscan/sscanRecord.html) as an [ophyd Flyer](https://blueskyproject.io/bluesky/async.html) for data acquisition with the [bluesky](https://blueskyproject.io/bluesky) [fly](https://blueskyproject.io/bluesky/generated/bluesky.plans.fly.html#bluesky.plans.fly) plan. Consider the case of [1D step scans using sscan record](https://epics.anl.gov/bcda/synApps/sscan/sscanRecord.html#HEADING_1-1).\n", "\n", "Suggest the _noisy *v* m1_ scan, done as 1-D step scan with `sscan` record, where `noisy` is the [*swait*](https://htmlpreview.github.io/?https://raw.githubusercontent.com/epics-modules/calc/R3-6-1/documentation/swaitRecord.html) record calculating a Lorentzian peak based on `m1` (EPICS [*motor*]([*swait*](https://epics.anl.gov/bcda/synApps/motor/motorRecord.html)) record) position.\n", "\n", "We'll build a custom Python class, from [apstools.synApps.SscanRecord](https://apstools.readthedocs.io/en/latest/source/synApps/_sscan.html) (a subclass of [ophyd.Device](https://blueskyproject.io/ophyd/tutorials/device.html#define-a-custom-device)), that supports the EPICS [*sscan*](https://epics.anl.gov/bcda/synApps/sscan/sscanRecord.html) record and add the [ophyd.FlyerInterface](https://blueskyproject.io/ophyd/architecture.html#fly-able-interface) to that class. A class method will configure the Device staging to setup the sscan record for a 1-D step scan using the [m1](https://github.com/BCDA-APS/bluesky_training/blob/711baca0e4fcdffc97fb4d05ee73d4b5b93fcc3a/bluesky/instrument/devices/motors.py#L25) positioner and the [noisy](https://github.com/BCDA-APS/bluesky_training/blob/711baca0e4fcdffc97fb4d05ee73d4b5b93fcc3a/bluesky/instrument/devices/noisy_detector.py#L42) detector. `noisy` is implemented as an EPICS [*swait*](https://htmlpreview.github.io/?https://raw.githubusercontent.com/epics-modules/calc/R3-6-1/documentation/swaitRecord.html) record configured to recalculate a Lorentzian profile when the `m1` readback value changes. The center, width, and height are [set randomly](https://github.com/BCDA-APS/bluesky_training/blob/711baca0e4fcdffc97fb4d05ee73d4b5b93fcc3a/bluesky/instrument/devices/noisy_detector.py#L24-L38) as this bluesky instrument package is loaded. The center of the simulated peak will be defined somewhere between [+/- 1](https://github.com/BCDA-APS/bluesky_training/blob/711baca0e4fcdffc97fb4d05ee73d4b5b93fcc3a/bluesky/instrument/devices/noisy_detector.py#L34)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load the `instrument` package" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/home/prjemian/bluesky/instrument/_iconfig.py\n", "Activating auto-logging. Current session state plus future input saved.\n", "Filename : /home/prjemian/Documents/projects/BCDA-APS/bluesky_training/docs/source/howto/.logs/ipython_console.log\n", "Mode : rotate\n", "Output logging : True\n", "Raw input log : False\n", "Timestamping : True\n", "State : active\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "I Thu-17:53:40 - ############################################################ startup\n", "I Thu-17:53:40 - logging started\n", "I Thu-17:53:40 - logging level = 10\n", "I Thu-17:53:40 - /home/prjemian/bluesky/instrument/session_logs.py\n", "I Thu-17:53:40 - /home/prjemian/bluesky/instrument/collection.py\n", "I Thu-17:53:40 - CONDA_PREFIX = /home/prjemian/.conda/envs/bluesky_2023_2\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Exception reporting mode: Minimal\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "I Thu-17:53:40 - xmode exception level: 'Minimal'\n", "I Thu-17:53:40 - /home/prjemian/bluesky/instrument/mpl/notebook.py\n", "I Thu-17:53:40 - #### Bluesky Framework ####\n", "I Thu-17:53:40 - /home/prjemian/bluesky/instrument/framework/check_python.py\n", "I Thu-17:53:40 - /home/prjemian/bluesky/instrument/framework/check_bluesky.py\n", "I Thu-17:53:40 - /home/prjemian/bluesky/instrument/framework/initialize.py\n", "I Thu-17:53:40 - RunEngine metadata saved in directory: /home/prjemian/Bluesky_RunEngine_md\n", "I Thu-17:53:40 - using databroker catalog 'training'\n", "I Thu-17:53:40 - using ophyd control layer: pyepics\n", "I Thu-17:53:40 - /home/prjemian/bluesky/instrument/framework/metadata.py\n", "I Thu-17:53:40 - /home/prjemian/bluesky/instrument/epics_signal_config.py\n", "I Thu-17:53:40 - Using RunEngine metadata for scan_id\n", "I Thu-17:53:40 - #### Devices ####\n", "I Thu-17:53:40 - /home/prjemian/bluesky/instrument/devices/area_detector.py\n", "I Thu-17:53:40 - /home/prjemian/bluesky/instrument/devices/calculation_records.py\n", "I Thu-17:53:43 - /home/prjemian/bluesky/instrument/devices/fourc_diffractometer.py\n", "I Thu-17:53:43 - /home/prjemian/bluesky/instrument/devices/ioc_stats.py\n", "I Thu-17:53:43 - /home/prjemian/bluesky/instrument/devices/kohzu_monochromator.py\n", "I Thu-17:53:43 - /home/prjemian/bluesky/instrument/devices/motors.py\n", "I Thu-17:53:43 - /home/prjemian/bluesky/instrument/devices/noisy_detector.py\n", "I Thu-17:53:43 - /home/prjemian/bluesky/instrument/devices/scaler.py\n", "I Thu-17:53:44 - /home/prjemian/bluesky/instrument/devices/shutter_simulator.py\n", "I Thu-17:53:44 - /home/prjemian/bluesky/instrument/devices/simulated_fourc.py\n", "I Thu-17:53:44 - /home/prjemian/bluesky/instrument/devices/simulated_kappa.py\n", "I Thu-17:53:44 - /home/prjemian/bluesky/instrument/devices/slits.py\n", "I Thu-17:53:44 - /home/prjemian/bluesky/instrument/devices/sixc_diffractometer.py\n", "I Thu-17:53:44 - /home/prjemian/bluesky/instrument/devices/temperature_signal.py\n", "I Thu-17:53:44 - #### Callbacks ####\n", "I Thu-17:53:44 - /home/prjemian/bluesky/instrument/callbacks/spec_data_file_writer.py\n", "I Thu-17:53:44 - #### Plans ####\n", "I Thu-17:53:44 - /home/prjemian/bluesky/instrument/plans/lup_plan.py\n", "I Thu-17:53:44 - /home/prjemian/bluesky/instrument/plans/peak_finder_example.py\n", "I Thu-17:53:44 - /home/prjemian/bluesky/instrument/utils/image_analysis.py\n", "I Thu-17:53:45 - #### Utilities ####\n", "I Thu-17:53:45 - writing to SPEC file: /home/prjemian/Documents/projects/BCDA-APS/bluesky_training/docs/source/howto/20230413-175344.dat\n", "I Thu-17:53:45 - >>>> Using default SPEC file name <<<<\n", "I Thu-17:53:45 - file will be created when bluesky ends its next scan\n", "I Thu-17:53:45 - to change SPEC file, use command: newSpecFile('title')\n", "I Thu-17:53:45 - #### Startup is complete. ####\n" ] } ], "source": [ "%matplotlib widget\n", "\n", "import os, pathlib, sys\n", "sys.path.append(os.path.abspath(os.path.join(pathlib.Path.home(), \"bluesky\")))\n", "from instrument.collection import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add this notebook's name to the RunEngine metadata and define the IOC's prefix." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "RE.md[\"notebook\"] = \"sscan_1d_flyer\"\n", "ioc = \"gp:\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Bluesky step scan\n", "\n", "We are told that the `noisy` signal will show a peak when `m1` is moved over the range `[-1 .. +1]`. Use *bluesky* to show that peak." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "Transient Scan ID: 956 Time: 2023-04-13 17:53:45\n", "Persistent Unique Scan ID: 'cfa4afcd-bcf0-4c35-ae0d-7f4daa927238'\n", "New stream: 'label_start_motor'\n", "New stream: 'primary'\n", "+-----------+------------+------------+------------+\n", "| seq_num | time | m1 | noisy |\n", "+-----------+------------+------------+------------+\n", "| 1 | 17:53:46.8 | -1.1000 | 7442.55055 |\n", "| 2 | 17:53:47.2 | -0.9900 | 11249.11706 |\n", "| 3 | 17:53:47.6 | -0.8800 | 18986.60948 |\n", "| 4 | 17:53:48.0 | -0.7700 | 38984.13377 |\n", "| 5 | 17:53:48.4 | -0.6600 | 81758.13663 |\n", "| 6 | 17:53:48.8 | -0.5500 | 90661.67681 |\n", "| 7 | 17:53:49.2 | -0.4400 | 44616.92674 |\n", "| 8 | 17:53:49.6 | -0.3300 | 21037.26285 |\n", "| 9 | 17:53:50.0 | -0.2200 | 12314.44644 |\n", "| 10 | 17:53:50.4 | -0.1100 | 7477.76738 |\n", "| 11 | 17:53:50.8 | 0.0000 | 5304.05319 |\n", "| 12 | 17:53:51.2 | 0.1100 | 3719.11921 |\n", "| 13 | 17:53:51.6 | 0.2200 | 2812.51654 |\n", "| 14 | 17:53:52.0 | 0.3300 | 2297.41489 |\n", "| 15 | 17:53:52.4 | 0.4400 | 1785.46562 |\n", "| 16 | 17:53:52.8 | 0.5500 | 1508.59485 |\n", "| 17 | 17:53:53.2 | 0.6600 | 1209.38156 |\n", "| 18 | 17:53:53.6 | 0.7700 | 1024.83242 |\n", "| 19 | 17:53:54.0 | 0.8800 | 919.60953 |\n", "| 20 | 17:53:54.4 | 0.9900 | 765.85225 |\n", "| 21 | 17:53:54.8 | 1.1000 | 655.33053 |\n", "+-----------+------------+------------+------------+\n", "generator scan ['cfa4afcd'] (scan num: 956)\n" ] }, { "data": { "text/plain": [ "('cfa4afcd-bcf0-4c35-ae0d-7f4daa927238',)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# show a pre-assembled bluesky.plans.scan() acquisition\n", "RE(bp.scan([noisy], m1, -1.1, 1.1, 21, md=dict(purpose=\"demo bluesky scan plan\")))" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\n", "'com':\n", " {'noisy': -0.5404925440667286}\n", ",\n", "'cen':\n", " {'noisy': -0.597662063312674}\n", ",\n", "'max':\n", " {'noisy': (-0.55,\n", " 90661.67681062203)}\n", ",\n", "'min':\n", " {'noisy': (1.1,\n", " 655.3305297746574)}\n", ",\n", "'fwhm':\n", " {'noisy': 0.31034751314623277}\n", ",\n", "}\n" ] } ], "source": [ "import pprint\n", "pprint.pprint(bec.peaks)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## sscan as Bluesky Flyer\n", "\n", "Load some structures to be used." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from ophyd import DeviceStatus, Signal\n", "from ophyd.flyers import FlyerInterface\n", "from apstools.synApps import SscanRecord" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "if save data is to be used\n", "\n", "```python\n", "# TODO: if save data is to be used\n", "\n", "# # configure saveData for data collection into MDA files:\n", "# save_data.stage_sigs[\"file_system\"] = \"/tmp\"\n", "# save_data.stage_sigs[\"subdirectory\"] = \"saveData\"\n", "# save_data.stage_sigs[\"base_name\"] = \"sscan1_\"\n", "# save_data.stage_sigs[\"next_scan_number\"] = 1\n", "# save_data.stage_sigs[\"comment1\"] = \"testing\"\n", "# save_data.stage_sigs[\"comment2\"] = \"configured and run from ophyd\"\n", "```\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `setup_staging_1D_step()` method (below) configures the device's `stage_sigs` dictionary to configure the sscan record for the 1-D scan. The bluesky RunEngine will only be responsible for configuring the sscan record and telling it to start. Once it has stopped, this device will collect the data from the sscan record's array fields and `yield` it back to the RunEngine per the Bluesky [event model](https://blueskyproject.io/event-model/).\n", "\n", "- The *sscan* record will record the time stamp for each point (relative to the scan's starting time) if the text `time` or `TIME` is used as the readback of one of the positioners. At the expense of providing valuable timestamp information for the Bluesky event model interface, this reduces the number of possible positioners for use by the sscan record to three.\n", "- To record the positioner setpoint value for each point, the motor's setpoint PV (`.VAL` field) is added as an additional detector.\n", "- *This* scan is preconfigured for the `m1` positioner and the `noisy` detector." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "import time\n", "\n", "class SscanFlyer_1D_StepSimple(FlyerInterface, SscanRecord):\n", "\n", " def __init__(self, *args, **kwargs):\n", " self._acquiring = False\n", "\n", " super().__init__(*args, **kwargs)\n", "\n", " def stage(self):\n", " super().stage()\n", " self.select_channels()\n", "\n", " def unstage(self):\n", " super().unstage()\n", " self.select_channels()\n", "\n", " def setup_staging_1D_step(self, start=-1.1, finish=1.1, num=21, ddelay=0.01, pdelay=0):\n", " \"\"\"Configure sscan record for 1D step scan: noisy v. m1\"\"\"\n", " self.xref = dict(\n", " positioners=[m1, ],\n", " raw_detectors=[noisy, ],\n", " detectors=[noisy, m1.user_setpoint] # include motor setpoints array\n", " )\n", " self.stage_sigs[\"number_points\"] = num\n", " self.stage_sigs[\"pasm\"] = \"PRIOR POS\"\n", " self.stage_sigs[\"positioner_delay\"] = pdelay\n", " for i, p in enumerate(self.xref[\"positioners\"]):\n", " self.stage_sigs[f\"positioners.p{i+1}.setpoint_pv\"] = p.user_setpoint.pvname\n", " self.stage_sigs[f\"positioners.p{i+1}.readback_pv\"] = p.user_readback.pvname\n", " self.stage_sigs[f\"positioners.p{i+1}.start\"] = start\n", " self.stage_sigs[f\"positioners.p{i+1}.end\"] = finish\n", " self.stage_sigs[\"detector_delay\"] = ddelay\n", " for i, d in enumerate(self.xref[\"detectors\"]):\n", " self.stage_sigs[f\"detectors.d{i+1:02d}.input_pv\"] = d.pvname\n", "\n", " # Get timestamp of each point in the scan.\n", " # This is a sscan record feature that returns the time since the scan started.\n", " # The time returned is relative to the first point of the scan.\n", " self.stage_sigs[f\"positioners.p4.readback_pv\"] = \"time\" # or TIME (all upper case)\n", "\n", " def read_configuration(self):\n", " return {}\n", "\n", " def describe_configuration(self):\n", " return {}\n", "\n", " def kickoff(self):\n", " \"\"\"Start the sscan record.\"\"\"\n", " # self.setup_staging_1D_step()\n", " self.stage()\n", " time.sleep(0.1)\n", "\n", " # set(), do not `yield`, in kickoff()\n", " self.execute_scan.set(1) # start the sscan record\n", " self._acquiring = True\n", "\n", " status = DeviceStatus(self)\n", " status.set_finished() # means that kickoff was successful\n", " return status\n", "\n", " def complete(self):\n", " \"\"\"Wait for sscan to complete.\"\"\"\n", " logger.info(\"complete() starting\")\n", " if not self._acquiring:\n", " raise RuntimeError(\"Not acquiring\")\n", "\n", " st = DeviceStatus(self)\n", " cb_started = False\n", "\n", " def execute_scan_cb(value, timestamp, **kwargs):\n", " \"\"\"Watch ``sscan.EXSC`` for completion.\"\"\"\n", " value = int(value)\n", " if cb_started and value == 0:\n", " logger.info(\"complete() ending\")\n", " self.unstage()\n", " self._acquiring = False\n", " self.execute_scan.unsubscribe(execute_scan_cb)\n", " if not st.done:\n", " logger.info(\"Setting %s execute status to `done`.\", self.name)\n", " st.set_finished()\n", "\n", " self.execute_scan.subscribe(execute_scan_cb)\n", " # self.execute_scan.set(1)\n", " cb_started = True\n", " return st\n", "\n", " def describe_collect(self):\n", " \"\"\"\n", " Provide schema & meta-data from collect().\n", " \n", " https://blueskyproject.io/ophyd/generated/ophyd.flyers.FlyerInterface.describe_collect.html\n", " \"\"\"\n", " dd = {}\n", " dd.update(m1.describe())\n", " dd.update(noisy.describe())\n", " return {self.name: dd}\n", "\n", " def collect(self):\n", " \"\"\"\n", " Retrieve all collected data (after complete()).\n", " \n", " Retrieve data from the flyer as proto-events.\n", " https://blueskyproject.io/ophyd/generated/ophyd.flyers.FlyerInterface.collect.html\n", " \"\"\"\n", " if self._acquiring:\n", " raise RuntimeError(\"Acquisition still in progress. Call complete() first.\")\n", " \n", " def get_data_from_sscan(obj, n):\n", " \"\"\"Read a sscan array and return as Python list.\"\"\"\n", " data = obj.read()[obj.name]\n", " data[\"value\"] = list(data[\"value\"][:n])\n", " return data\n", "\n", " def mkdoc(seq_num, values):\n", " \"\"\"Bundle the dictionary of values into a raw event document.\"\"\"\n", " timestamp = values.pop(\"__ts__\")\n", " yield dict(\n", " seq_num=seq_num,\n", " time=timestamp,\n", " data={k: v for k, v in values.items()},\n", " timestamps={k: timestamp for k in values},\n", " )\n", "\n", " def read_sscan_data(scan):\n", " \"\"\"Get the sscan arrays and yield as discrete events.\"\"\"\n", " _cp = scan.current_point.read()[scan.current_point.name]\n", " n = _cp[\"value\"]\n", " ts_last_point = _cp[\"timestamp\"]\n", "\n", " # get the per-step time stamps from positioner 4\n", " ts_arr = self.positioners.p4.array.get(use_monitor=False)[:n]\n", " ts_arr = ts_last_point + ts_arr - ts_arr.max()\n", "\n", " results = dict(__ts__=list(ts_arr)) # __ts__ holds the timestamps, per point\n", "\n", " # This gets the full array for each item in one document\n", " for category, signals in scan.xref.items():\n", " for i, signal in enumerate(signals):\n", " if category == \"positioners\":\n", " item = f\"p{i+1}\"\n", " elif category == \"detectors\":\n", " item = f\"d{i+1:02d}\"\n", " else:\n", " continue\n", " data = get_data_from_sscan(\n", " getattr(scan, f\"{category}.{item}.array\"), n\n", " )\n", " results[signal.name] = data[\"value\"]\n", "\n", " # yield all results one complete step at a time\n", " for i in range(n):\n", " yield from mkdoc(i+1, {k: results[k][i] for k in results})\n", "\n", " yield from read_sscan_data(self)\n", " self.unstage()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "flyer = SscanFlyer_1D_StepSimple(f\"{ioc}scan1\", name=\"flyer\")\n", "flyer.wait_for_connection() # sscan records have _many_ channels and fields\n", "flyer.reset() # clear out any previous configuration" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "Transient Scan ID: 957 Time: 2023-04-13 17:53:56\n", "Persistent Unique Scan ID: '1802af12-916d-447d-82e7-f9d79e43e5fa'\n", "New stream: 'label_start_motor'\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "I Thu-17:53:57 - complete() starting\n", "I Thu-17:54:13 - complete() ending\n", "I Thu-17:54:13 - Setting flyer execute status to `done`.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "New stream: 'flyer'\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/home/prjemian/.conda/envs/bluesky_2023_2/lib/python3.10/site-packages/event_model/__init__.py:224: UserWarning: The document type 'bulk_events' has been deprecated in favor of 'event_page', whose structure is a transpose of 'bulk_events'.\n", " warnings.warn(\n" ] }, { "data": { "text/plain": [ "('1802af12-916d-447d-82e7-f9d79e43e5fa',)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "flyer.setup_staging_1D_step(num=71)\n", "\n", "RE(bp.fly([flyer], md=dict(purpose=\"demo bluesky fly plan with sscan record and 1-D step scan\")))" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Text(0, 0.5, 'noisy')" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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W9OfVvtBDxeiS0sx5rNFN0KtUjr1Z8XN6y5gNpuRnp6O5557zuH6SZMmITU1tcX7mEwmmEwXjnaprKx0aY1ERESt5aNSgufwdi7nxjkvV1ZWBqvViqioKIfro6KiUFRU1OJ9Vq9eDZ1OJ126d+/eEaUSERGRDBis2uHSw2KFEJc9VHb58uUwGo3SJS8vryNKJCIiIhlwKbANwsPDoVKpms1OlZSUNJvFstNqtdBqtR1RHhEREcmMM1ZtoNFokJiYiJ07dzpcv3PnTowZM0amqoiIiMhdcMaqjZ5++mkkJSVh2LBhGD16NDZv3ozc3Fw8/vjjcpdGREREMmOwaqN77rkH5eXlePHFF1FYWIiEhARs374dsbGxcpdGREREMmMfqw7GPlZERESep7Wf39xjRUREROQkDFZERERETsJgRUREROQkDFZERERETsJgRUREROQkDFZERERETsJgRUREROQkbBDawextwyorK2WuhIiIiFrL/rl9tfafDFYdrKqqCgDQvXt3mSshIiKitqqqqoJOp7vs7ey83sFsNhvOnTuHoKAgKBQKucu5osrKSnTv3h15eXnsEu9G+L64L7437onvi3vytPdFCIGqqirExMRAqbz8TirOWHUwpVKJbt26yV1GmwQHB3vEX/rOhu+L++J74574vrgnT3pfrjRTZcfN60REREROwmBFRERE5CQMVnRZWq0WK1asgFarlbsUugjfF/fF98Y98X1xT976vnDzOhEREZGTcMaKiIiIyEkYrIiIiIichMGKiIiIyEkYrIiIiIichMGKJC+99BLGjBkDf39/dOnSpVX3EUJg5cqViImJgZ+fH8aPH48jR464ttBOyGAwICkpCTqdDjqdDklJSaioqLjifR544AEoFAqHy6hRozqmYC/15ptvomfPnvD19UViYiK+//77K47fs2cPEhMT4evri169emHTpk0dVGnn05b3Zvfu3c1+NxQKBY4fP96BFXu/7777DjNmzEBMTAwUCgX+97//XfU+3vA7w2BFErPZjLvuugtPPPFEq++zdu1arF+/Hhs2bMCBAweg1+sxceJE6ZyI5Bxz5sxBZmYmUlJSkJKSgszMTCQlJV31flOmTEFhYaF02b59ewdU650++ugjLFmyBL///e+RkZGBm266CVOnTkVubm6L48+ePYvbbrsNN910EzIyMvC73/0Oixcvxscff9zBlXu/tr43didOnHD4/ejTp08HVdw51NTUYPDgwdiwYUOrxnvN74wgusSWLVuETqe76jibzSb0er1Ys2aNdF19fb3Q6XRi06ZNLqywczl69KgAIPbt2yddl5aWJgCI48ePX/Z+8+bNE7NmzeqACjuHESNGiMcff9zhun79+onnnnuuxfHPPPOM6Nevn8N1jz32mBg1apTLauys2vre7Nq1SwAQBoOhA6ojIYQAILZt23bFMd7yO8MZK2q3s2fPoqioCJMmTZKu02q1GDduHFJTU2WszLukpaVBp9Nh5MiR0nWjRo2CTqe76s959+7diIyMRN++fTF//nyUlJS4ulyvZDabkZ6e7vB3HQAmTZp02fcgLS2t2fjJkyfjp59+gsVicVmtnU173hu7IUOGIDo6GhMmTMCuXbtcWSa1grf8zjBYUbsVFRUBAKKiohyuj4qKkm6ja1dUVITIyMhm10dGRl7x5zx16lS8//77+Pbbb/Hqq6/iwIED+NWvfgWTyeTKcr1SWVkZrFZrm/6uFxUVtTi+oaEBZWVlLqu1s2nPexMdHY3Nmzfj448/xtatWxEfH48JEybgu+++64iS6TK85XfGR+4CyLVWrlyJF1544YpjDhw4gGHDhrX7ORQKhcP3Qohm11FzrX1vgOY/Y+DqP+d77rlH+johIQHDhg1DbGwsvvjiC9xxxx3trLpza+vf9ZbGt3Q9Xbu2vDfx8fGIj4+Xvh89ejTy8vKwbt063HzzzS6tk67MG35nGKy83MKFC3HvvfdecUxcXFy7Hluv1wNo/F9GdHS0dH1JSUmz/3VQc619bw4dOoTi4uJmt5WWlrbp5xwdHY3Y2FicOnWqzbV2duHh4VCpVM1mQK70d12v17c43sfHB2FhYS6rtbNpz3vTklGjRuG9995zdnnUBt7yO8Ng5eXCw8MRHh7uksfu2bMn9Ho9du7ciSFDhgBo3O+wZ88evPzyyy55Tm/S2vdm9OjRMBqN2L9/P0aMGAEA+PHHH2E0GjFmzJhWP195eTny8vIcQjC1jkajQWJiInbu3Inbb79dun7nzp2YNWtWi/cZPXo0PvvsM4frduzYgWHDhkGtVru03s6kPe9NSzIyMvi7ITOv+Z2Rc+c8uZecnByRkZEhXnjhBREYGCgyMjJERkaGqKqqksbEx8eLrVu3St+vWbNG6HQ6sXXrVnH48GFx3333iejoaFFZWSnHS/BaU6ZMEYMGDRJpaWkiLS1NDBw4UEyfPt1hzMXvTVVVlVi6dKlITU0VZ8+eFbt27RKjR48WXbt25XvTTsnJyUKtVou3335bHD16VCxZskQEBASI7OxsIYQQzz33nEhKSpLGnzlzRvj7+4vf/OY34ujRo+Ltt98WarVa/Pe//5XrJXittr43r732mti2bZs4efKkyMrKEs8995wAID7++GO5XoJXqqqqkj5HAIj169eLjIwMkZOTI4Tw3t8ZBiuSzJs3TwBodtm1a5c0BoDYsmWL9L3NZhMrVqwQer1eaLVacfPNN4vDhw93fPFerry8XMydO1cEBQWJoKAgMXfu3GaHil/83tTW1opJkyaJiIgIoVarRY8ePcS8efNEbm5uxxfvRd544w0RGxsrNBqNGDp0qNizZ49027x588S4ceMcxu/evVsMGTJEaDQaERcXJzZu3NjBFXcebXlvXn75ZdG7d2/h6+srQkJCxI033ii++OILGar2bva2Fpde5s2bJ4Tw3t8ZhRBNO8OIiIiI6Jqw3QIRERGRkzBYERERETkJgxURERGRkzBYERERETkJgxURERGRkzBYERERETkJgxURERGRkzBYERF1UuPHj8eSJUvkLoPIqzBYEZFbeeqpp5CYmAitVosbbrhB7nJk98ADD2D27NkueeytW7fiT3/6U6vHZ2dnQ6FQIDMz0yX1EHkDBisicitCCDz00EO455575C6lVSwWi9wltFtoaCiCgoLkLoPIqzBYEZHLjB8/HosWLcKSJUsQEhKCqKgobN68GTU1NXjwwQcRFBSE3r1748svv5Tu89e//hVPPvkkevXq1ebnW7lyZbNZrtdffx1xcXHS97t378aIESMQEBCALl26YOzYscjJyZFu/+yzz5CYmAhfX1/06tULL7zwAhoaGqTbFQoFNm3ahFmzZiEgIAB//vOfr1iTwWDA3LlzERERAT8/P/Tp0wdbtmyRbi8oKMA999yDkJAQhIWFYdasWcjOzpZez7vvvotPPvkECoUCCoUCu3fvlmaOkpOTMWbMGPj6+uL666/H7t27HZ57z549GDFiBLRaLaKjo/Hcc885vJZLlwLj4uKwatUqPPTQQwgKCkKPHj2wefNm6faePXsCAIYMGQKFQoHx48df8bUTdUYMVkTkUu+++y7C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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "run = cat[-1]\n", "dataset = run.flyer.read()\n", "x = dataset[\"m1_user_setpoint\"]\n", "y = dataset[\"noisy\"]\n", "\n", "plt.plot(x.values, y.values)\n", "plt.title(f\"scan_id={run.metadata['start']['scan_id']}\")\n", "plt.xlabel(x.name)\n", "plt.ylabel(y.name)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset>\n",
       "Dimensions:           (time: 71)\n",
       "Coordinates:\n",
       "  * time              (time) float64 1.681e+09 1.681e+09 ... 1.681e+09 1.681e+09\n",
       "Data variables:\n",
       "    m1                (time) float64 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0\n",
       "    m1_user_setpoint  (time) float64 -1.1 -1.069 -1.037 ... 1.037 1.069 1.1\n",
       "    noisy             (time) float64 7.078e+03 8.256e+03 ... 682.6 679.9
" ], "text/plain": [ "\n", "Dimensions: (time: 71)\n", "Coordinates:\n", " * time (time) float64 1.681e+09 1.681e+09 ... 1.681e+09 1.681e+09\n", "Data variables:\n", " m1 (time) float64 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0\n", " m1_user_setpoint (time) float64 -1.1 -1.069 -1.037 ... 1.037 1.069 1.1\n", " noisy (time) float64 7.078e+03 8.256e+03 ... 682.6 679.9" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dataset" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "centroid: -0.5366484118894111\n", "sigma: 0.6149932116936468\n" ] } ], "source": [ "# compute the centroid and sigma from first and second moments of y(x):\n", "\n", "print(f\"centroid: {((y*x).sum()/y.sum()).data}\")\n", "print(f\"sigma: {np.sqrt((y*x*x).sum()/y.sum()).data}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## References\n", "\n", "The documentation for *Flyer*s is distributed across the *bluesky* and *ophyd* packages:\n", "\n", "- Pre-assembled bluesky plans: https://blueskyproject.io/bluesky/plans.html#pre-assembled-plans\n", "- bluesky `fly()` plan: https://blueskyproject.io/bluesky/generated/bluesky.plans.fly.html#bluesky.plans.fly\n", "- asynchronous collection with fly scans: https://blueskyproject.io/bluesky/plans.html#asynchronous-plans-fly-scans-and-monitoring\n", "- Asynchronous Acquisition:https://blueskyproject.io/bluesky/async.html\n", "- ophyd flyer classes: https://blueskyproject.io/ophyd/generated/ophyd.flyers.html\n", "- ophyd Fly-able Interface (with links to the `FlyerInterface()` methods) : https://blueskyproject.io/ophyd/architecture.html#fly-able-interface" ] } ], "metadata": { "interpreter": { "hash": "fa399ef8ed4fbc3b7fe63ebf4307839a170374bf77134d519fcb3b724ac0582b" }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 4 }