Simulated KB Mirror Demo¶
This notebook introduces the use of Blop to tune a KB mirror pair to optimize the quality of a simulated beam read by a detector.
Blop uses Ax as its optimization and experiment tracking backend.
Ax provides:
Experiment tracking
Analysis & visualization
Bayesian optimization (through BoTorch)
Blop provides:
Native integration with Bluesky & its ecosystem
Specialized kernels and methods common to beamline optimization problems
These features make it simple to optimize your beamline using both Bluesky & Ax.
Preparing a test environment¶
Here we prepare the RunEngine.
from datetime import datetime
import logging
import bluesky.plan_stubs as bps # noqa F401
import bluesky.plans as bp # noqa F401
import databroker # type: ignore[import-untyped]
import matplotlib.pyplot as plt
from bluesky.callbacks import best_effort
from bluesky.callbacks.tiled_writer import TiledWriter
from bluesky.run_engine import RunEngine
from databroker import Broker
from ophyd.utils import make_dir_tree # type: ignore[import-untyped]
from tiled.client import from_uri # type: ignore[import-untyped]
from tiled.client.container import Container
from tiled.server import SimpleTiledServer
from blop.sim import HDF5Handler
from blop.sim.beamline import DatabrokerBeamline, TiledBeamline
# Suppress noisy logs from httpx
logging.getLogger("httpx").setLevel(logging.WARNING)
DETECTOR_STORAGE = "/tmp/blop/sim"
tiled_server = SimpleTiledServer(readable_storage=[DETECTOR_STORAGE])
tiled_client = from_uri(tiled_server.uri)
tiled_writer = TiledWriter(tiled_client)
def setup_re_env(db_type="default", root_dir="/default/path", method="tiled"):
RE = RunEngine({})
bec = best_effort.BestEffortCallback()
RE.subscribe(bec)
_ = make_dir_tree(datetime.now().year, base_path=root_dir)
if method.lower() == "tiled":
RE.subscribe(tiled_writer)
return {"RE": RE, "db": tiled_client, "bec": bec}
elif method.lower() == "databroker":
db = Broker.named(db_type)
db.reg.register_handler("HDF5", HDF5Handler, overwrite=True)
try:
databroker.assets.utils.install_sentinels(db.reg.config, version=1)
except Exception:
pass
RE.subscribe(db.insert)
return {"RE": RE, "db": db, "bec": bec, }
else:
raise ValueError("The method for data storage used is not supported")
def register_handlers(db, handlers):
for handler_spec, handler_class in handlers.items():
db.reg.register_handler(handler_spec, handler_class, overwrite=True)
env = setup_re_env(db_type="temp", root_dir="/tmp/blop/sim", method="tiled")
globals().update(env)
bec.disable_plots()
2025-10-13 20:39:36.088 INFO: Subprocess stdout:
2025-10-13 20:39:36.090 INFO: Subprocess stderr: Database sqlite+aiosqlite:////tmp/tmpj_regtqn/catalog.db is new. Creating tables.
Database initialized.
Tiled version 0.1.6
2025-10-13 20:39:36.407 INFO: Tiled version 0.1.6
2025-10-13 20:39:36.413 INFO: Context impl SQLiteImpl.
2025-10-13 20:39:36.413 INFO: Will assume non-transactional DDL.
Simulated beamline with KB mirror pair¶
Here we describe an analytical simulated beamline with a KB mirror pair. This is implemented as an Ophyd device for ease-of-use with Bluesky.
if isinstance(db, Container):
beamline = TiledBeamline(name="bl")
elif isinstance(db, databroker.v1.Broker):
beamline = DatabrokerBeamline(name="bl")
Create a Blop-Ax experiment¶
Now we can define the experiment we plan to run.
This involves setting 4 parameters that simulate motor positions controlling two KB mirrors. The objectives of the experiment are to maximize the beam intensity while minimizing the area of the beam.
from blop.ax import Agent
from blop.dofs import DOF
from blop.objectives import Objective
dofs = [
DOF(movable=beamline.kbv_dsv, type="continuous", search_domain=(-5.0, 5.0)),
DOF(movable=beamline.kbv_usv, type="continuous", search_domain=(-5.0, 5.0)),
DOF(movable=beamline.kbh_dsh, type="continuous", search_domain=(-5.0, 5.0)),
DOF(movable=beamline.kbh_ush, type="continuous", search_domain=(-5.0, 5.0)),
]
objectives = [
Objective(name="bl_det_sum", target="max"),
Objective(name="bl_det_wid_x", target="min"),
Objective(name="bl_det_wid_y", target="min"),
]
agent = Agent(
readables=[beamline.det],
dofs=dofs,
objectives=objectives,
db=db,
)
agent.configure_experiment(name="test_ax_agent", description="Test the AxAgent")
[WARNING 10-13 20:39:37] ax.service.utils.with_db_settings_base: Ax currently requires a sqlalchemy version below 2.0. This will be addressed in a future release. Disabling SQL storage in Ax for now, if you would like to use SQL storage please install Ax with mysql extras via `pip install ax-platform[mysql]`.
2025-10-13 20:39:37.686 INFO: Configuring optimization with objective: bl_det_sum, -bl_det_wid_x, -bl_det_wid_y and outcome constraints: []
Optimization¶
With all of our experimental setup done, we can optimize the DOFs to satisfy our objectives.
For this example, Ax will optimize the 4 motor positions to produce the greatest intensity beam with the smallest beam width and height (smallest area). It does this by first running a couple of trials which are random samples, then the remainder using Bayesian optimization through BoTorch.
RE(agent.learn(iterations=25, n=1))
Transient Scan ID: 1 Time: 2025-10-13 20:39:37
Persistent Unique Scan ID: 'af22a361-5e19-4c6b-8c65-dd2ae87cae11'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:39:37.9 | 0.000 | 0.000 | 0.000 | 0.000 | 542.712 | 198.987 | 149.000 | 31.155 | 39.897 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['af22a361'] (scan num: 1)
Found duckdb shared library at /home/runner/work/blop/blop/.pixi/envs/docs/lib/python3.12/site-packages/_duckdb.cpython-312-x86_64-linux-gnu.so
Transient Scan ID: 2 Time: 2025-10-13 20:39:39
Persistent Unique Scan ID: 'a2573a0f-9535-49eb-96bd-144968cdba87'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:39:39.1 | 0.388 | 2.833 | -1.689 | -1.154 | 504.803 | 210.594 | 185.515 | 101.792 | 25.291 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['a2573a0f'] (scan num: 2)
Transient Scan ID: 3 Time: 2025-10-13 20:39:39
Persistent Unique Scan ID: '2414bb42-d148-4b3b-be66-e4f381b6487d'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:39:39.7 | -3.457 | -3.937 | 4.304 | 4.034 | 0.914 | 197.811 | 167.230 | 231.813 | 165.560 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['2414bb42'] (scan num: 3)
Transient Scan ID: 4 Time: 2025-10-13 20:39:40
Persistent Unique Scan ID: 'c6c411fd-11a0-4f43-b4a0-84ccff0fad56'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:39:40.4 | -0.792 | 1.089 | -4.330 | -4.621 | 54.650 | 197.411 | 176.977 | 174.096 | 32.375 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['c6c411fd'] (scan num: 4)
Transient Scan ID: 5 Time: 2025-10-13 20:39:41
Persistent Unique Scan ID: '2b270a12-4a64-42c3-8a89-e843ea0fa818'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:39:41.1 | 2.702 | -2.172 | 1.712 | 0.489 | 304.754 | 174.500 | 83.798 | 35.307 | 17.252 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['2b270a12'] (scan num: 5)
Transient Scan ID: 6 Time: 2025-10-13 20:39:45
Persistent Unique Scan ID: 'cde20903-f3ce-468b-a613-5825d02d65d1'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:39:45.1 | 2.259 | -0.084 | -0.808 | 0.166 | 543.465 | 218.500 | 113.778 | 45.875 | 9.267 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['cde20903'] (scan num: 6)
Transient Scan ID: 7 Time: 2025-10-13 20:39:50
Persistent Unique Scan ID: 'abcde7c8-20bb-452c-bbc5-23e7569a105f'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:39:50.5 | 1.995 | -3.585 | -0.495 | -0.164 | 204.108 | 205.460 | 90.390 | 45.080 | 29.220 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['abcde7c8'] (scan num: 7)
Transient Scan ID: 8 Time: 2025-10-13 20:39:56
Persistent Unique Scan ID: '27e36073-7ee8-4d6f-8ec2-d2ab9430dfbe'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:39:56.8 | 2.330 | 1.482 | 3.476 | 0.111 | 460.098 | 135.266 | 136.323 | 62.884 | 37.293 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['27e36073'] (scan num: 8)
Transient Scan ID: 9 Time: 2025-10-13 20:40:02
Persistent Unique Scan ID: '45ad787e-9627-4617-8b16-95b4ce4dad2d'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:40:02.7 | 2.486 | 0.643 | 0.540 | 0.296 | 544.872 | 194.043 | 121.500 | 17.348 | 23.562 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['45ad787e'] (scan num: 9)
Transient Scan ID: 10 Time: 2025-10-13 20:40:08
Persistent Unique Scan ID: 'dcef7eb2-7c07-4742-8554-f77f4a40ccf2'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:40:08.2 | 2.699 | -0.650 | 0.246 | 0.091 | 548.939 | 195.938 | 98.986 | 24.100 | 8.781 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['dcef7eb2'] (scan num: 10)
Transient Scan ID: 11 Time: 2025-10-13 20:40:13
Persistent Unique Scan ID: 'f93560eb-7460-468e-aa02-aad6883bba99'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:40:14.0 | 2.943 | 0.158 | 0.777 | -0.545 | 547.403 | 172.640 | 107.440 | 26.420 | 23.342 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['f93560eb'] (scan num: 11)
Transient Scan ID: 12 Time: 2025-10-13 20:40:20
Persistent Unique Scan ID: '73ed172c-4068-479b-9190-48a401b689d0'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:40:20.8 | 2.088 | 0.146 | 0.085 | -0.116 | 550.309 | 194.900 | 119.963 | 31.040 | 10.275 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['73ed172c'] (scan num: 12)
Transient Scan ID: 13 Time: 2025-10-13 20:40:26
Persistent Unique Scan ID: 'a86458b0-a054-4627-906a-9fae1336e514'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:40:26.8 | 2.543 | -1.236 | -5.000 | 5.000 | 0.294 | 167.680 | 150.424 | 297.451 | 285.852 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['a86458b0'] (scan num: 13)
Transient Scan ID: 14 Time: 2025-10-13 20:40:36
Persistent Unique Scan ID: 'a17ecfec-cb53-4d6b-9848-2aec409e15c4'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:40:37.0 | 5.000 | 0.475 | 0.109 | 0.189 | 327.826 | 200.527 | 97.350 | 25.078 | 41.628 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['a17ecfec'] (scan num: 14)
Transient Scan ID: 15 Time: 2025-10-13 20:40:49
Persistent Unique Scan ID: '61d963e2-dc5b-4337-ad1c-1fb72ab88710'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:40:49.8 | 1.789 | 0.303 | 0.617 | -0.243 | 552.263 | 181.750 | 126.971 | 23.100 | 8.797 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['61d963e2'] (scan num: 15)
Transient Scan ID: 16 Time: 2025-10-13 20:40:59
Persistent Unique Scan ID: '0fddb6df-f24a-4262-af7d-b06a14acaa2d'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:40:59.9 | 1.519 | 0.158 | 0.300 | -0.549 | 548.204 | 182.000 | 128.625 | 36.200 | 11.083 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['0fddb6df'] (scan num: 16)
Transient Scan ID: 17 Time: 2025-10-13 20:41:09
Persistent Unique Scan ID: '1dbdbfba-ac72-4ad8-94c3-8a2364923ea9'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:41:09.4 | 1.965 | -0.271 | 1.075 | -0.077 | 552.602 | 176.000 | 115.570 | 16.600 | 10.977 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['1dbdbfba'] (scan num: 17)
Transient Scan ID: 18 Time: 2025-10-13 20:41:20
Persistent Unique Scan ID: 'a83a1053-2101-41be-af4b-7bf4c8fade2c'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:41:20.3 | -1.410 | 1.841 | 1.939 | -1.119 | 548.360 | 138.000 | 197.500 | 17.381 | 31.925 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['a83a1053'] (scan num: 18)
Transient Scan ID: 19 Time: 2025-10-13 20:41:33
Persistent Unique Scan ID: '14260c3d-2d12-44b9-8d62-91ec31d7c256'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:41:33.1 | -0.651 | -0.520 | 3.933 | -1.947 | 30.412 | 101.128 | 151.750 | 5.082 | 60.400 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['14260c3d'] (scan num: 19)
Transient Scan ID: 20 Time: 2025-10-13 20:41:47
Persistent Unique Scan ID: '3a1ec5ac-4608-4053-bc49-f6d91d8ae38f'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:41:47.7 | -1.037 | 3.027 | 3.408 | -1.682 | 239.744 | 105.430 | 209.874 | 11.174 | 8.567 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['3a1ec5ac'] (scan num: 20)
Transient Scan ID: 21 Time: 2025-10-13 20:42:00
Persistent Unique Scan ID: '706e387c-3e58-4415-bb36-3af86e03d484'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:42:00.5 | -1.757 | 2.294 | 3.770 | -2.558 | 2.308 | 169.714 | 149.200 | 308.153 | 281.992 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['706e387c'] (scan num: 21)
Transient Scan ID: 22 Time: 2025-10-13 20:42:16
Persistent Unique Scan ID: '117d5443-fb13-40da-ae83-d3c584e81e89'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:42:16.8 | -0.851 | 0.645 | 3.222 | -1.481 | 378.249 | 109.373 | 171.412 | 18.269 | 44.212 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['117d5443'] (scan num: 22)
Transient Scan ID: 23 Time: 2025-10-13 20:42:36
Persistent Unique Scan ID: '2e7197dd-1bcf-4a6e-9c0c-022969ab32a3'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:42:36.6 | 0.126 | 2.205 | 3.241 | -0.766 | 483.691 | 121.323 | 180.009 | 38.113 | 10.656 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['2e7197dd'] (scan num: 23)
Transient Scan ID: 24 Time: 2025-10-13 20:42:58
Persistent Unique Scan ID: '1571883a-a0aa-4970-999d-01f1e3e82f31'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:42:58.8 | 0.344 | 2.858 | 5.000 | -1.716 | 44.841 | 103.713 | 186.664 | 8.434 | 24.071 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['1571883a'] (scan num: 24)
Transient Scan ID: 25 Time: 2025-10-13 20:43:22
Persistent Unique Scan ID: 'a89f3d52-095c-4e3f-98d1-03ac4aad50b0'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:43:23.0 | -2.156 | 1.602 | 4.175 | -1.769 | 44.300 | 102.947 | 200.861 | 7.086 | 39.940 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['a89f3d52'] (scan num: 25)
2025-10-13 20:39:37.785 INFO: Executing plan <generator object Agent.learn at 0x7f5c134d4440>
2025-10-13 20:39:37.787 INFO: Change state on <bluesky.run_engine.RunEngine object at 0x7f5c24d282c0> from 'idle' -> 'running'
2025-10-13 20:43:23.626 INFO: Change state on <bluesky.run_engine.RunEngine object at 0x7f5c24d282c0> from 'running' -> 'idle'
2025-10-13 20:43:23.627 INFO: Cleaned up from plan <generator object Agent.learn at 0x7f5c134d4440>
('af22a361-5e19-4c6b-8c65-dd2ae87cae11',
'a2573a0f-9535-49eb-96bd-144968cdba87',
'2414bb42-d148-4b3b-be66-e4f381b6487d',
'c6c411fd-11a0-4f43-b4a0-84ccff0fad56',
'2b270a12-4a64-42c3-8a89-e843ea0fa818',
'cde20903-f3ce-468b-a613-5825d02d65d1',
'abcde7c8-20bb-452c-bbc5-23e7569a105f',
'27e36073-7ee8-4d6f-8ec2-d2ab9430dfbe',
'45ad787e-9627-4617-8b16-95b4ce4dad2d',
'dcef7eb2-7c07-4742-8554-f77f4a40ccf2',
'f93560eb-7460-468e-aa02-aad6883bba99',
'73ed172c-4068-479b-9190-48a401b689d0',
'a86458b0-a054-4627-906a-9fae1336e514',
'a17ecfec-cb53-4d6b-9848-2aec409e15c4',
'61d963e2-dc5b-4337-ad1c-1fb72ab88710',
'0fddb6df-f24a-4262-af7d-b06a14acaa2d',
'1dbdbfba-ac72-4ad8-94c3-8a2364923ea9',
'a83a1053-2101-41be-af4b-7bf4c8fade2c',
'14260c3d-2d12-44b9-8d62-91ec31d7c256',
'3a1ec5ac-4608-4053-bc49-f6d91d8ae38f',
'706e387c-3e58-4415-bb36-3af86e03d484',
'117d5443-fb13-40da-ae83-d3c584e81e89',
'2e7197dd-1bcf-4a6e-9c0c-022969ab32a3',
'1571883a-a0aa-4970-999d-01f1e3e82f31',
'a89f3d52-095c-4e3f-98d1-03ac4aad50b0')
Analyze Results¶
We can start by summarizing each step of the optimization procedure and whether trials were successful or not.
agent.summarize()
| trial_index | arm_name | trial_status | generation_node | bl_det_sum | bl_det_wid_x | bl_det_wid_y | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0_0 | COMPLETED | CenterOfSearchSpace | 542.712122 | 31.155263 | 39.896667 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 1 | 1 | 1_0 | COMPLETED | Sobol | 504.802752 | 101.792083 | 25.290845 | 0.388068 | 2.832910 | -1.688840 | -1.154414 |
| 2 | 2 | 2_0 | COMPLETED | Sobol | 0.913969 | 231.813312 | 165.560000 | -3.457393 | -3.936744 | 4.304256 | 4.033780 |
| 3 | 3 | 3_0 | COMPLETED | Sobol | 54.649728 | 174.095764 | 32.374964 | -0.792014 | 1.088601 | -4.330241 | -4.621093 |
| 4 | 4 | 4_0 | COMPLETED | Sobol | 304.753981 | 35.306667 | 17.252343 | 2.702014 | -2.172295 | 1.711588 | 0.488674 |
| 5 | 5 | 5_0 | COMPLETED | MBM | 543.465048 | 45.875000 | 9.266667 | 2.259250 | -0.084356 | -0.807512 | 0.165584 |
| 6 | 6 | 6_0 | COMPLETED | MBM | 204.107678 | 45.080000 | 29.220000 | 1.995411 | -3.585023 | -0.495463 | -0.163657 |
| 7 | 7 | 7_0 | COMPLETED | MBM | 460.098285 | 62.883603 | 37.292918 | 2.329860 | 1.481609 | 3.476035 | 0.111130 |
| 8 | 8 | 8_0 | COMPLETED | MBM | 544.871822 | 17.347826 | 23.562500 | 2.486284 | 0.643419 | 0.540389 | 0.296320 |
| 9 | 9 | 9_0 | COMPLETED | MBM | 548.938586 | 24.100000 | 8.780736 | 2.699220 | -0.650062 | 0.246055 | 0.090791 |
| 10 | 10 | 10_0 | COMPLETED | MBM | 547.402721 | 26.420455 | 23.342120 | 2.942696 | 0.158414 | 0.776900 | -0.545334 |
| 11 | 11 | 11_0 | COMPLETED | MBM | 550.308800 | 31.040000 | 10.275000 | 2.087681 | 0.146121 | 0.085052 | -0.116252 |
| 12 | 12 | 12_0 | COMPLETED | MBM | 0.293539 | 297.451357 | 285.852000 | 2.543189 | -1.235738 | -5.000000 | 5.000000 |
| 13 | 13 | 13_0 | COMPLETED | MBM | 327.825930 | 25.078378 | 41.628079 | 5.000000 | 0.475322 | 0.109249 | 0.188853 |
| 14 | 14 | 14_0 | COMPLETED | MBM | 552.262807 | 23.100000 | 8.797273 | 1.788778 | 0.302634 | 0.616639 | -0.243461 |
| 15 | 15 | 15_0 | COMPLETED | MBM | 548.203657 | 36.200000 | 11.083333 | 1.518592 | 0.158256 | 0.299756 | -0.549303 |
| 16 | 16 | 16_0 | COMPLETED | MBM | 552.602047 | 16.600000 | 10.977083 | 1.965290 | -0.270726 | 1.074727 | -0.076958 |
| 17 | 17 | 17_0 | COMPLETED | MBM | 548.359956 | 17.380645 | 31.925000 | -1.410045 | 1.840920 | 1.939233 | -1.118664 |
| 18 | 18 | 18_0 | COMPLETED | MBM | 30.412337 | 5.081994 | 60.400000 | -0.651036 | -0.520203 | 3.933421 | -1.947015 |
| 19 | 19 | 19_0 | COMPLETED | MBM | 239.743787 | 11.173810 | 8.567143 | -1.036562 | 3.027000 | 3.407781 | -1.682057 |
| 20 | 20 | 20_0 | COMPLETED | MBM | 2.308160 | 308.152500 | 281.992000 | -1.757053 | 2.293543 | 3.770426 | -2.557876 |
| 21 | 21 | 21_0 | COMPLETED | MBM | 378.248846 | 18.269394 | 44.211765 | -0.851234 | 0.645122 | 3.221665 | -1.480581 |
| 22 | 22 | 22_0 | COMPLETED | MBM | 483.690947 | 38.113333 | 10.655761 | 0.125681 | 2.205469 | 3.241256 | -0.766060 |
| 23 | 23 | 23_0 | COMPLETED | MBM | 44.840899 | 8.434000 | 24.071429 | 0.343580 | 2.857935 | 5.000000 | -1.715955 |
| 24 | 24 | 24_0 | COMPLETED | MBM | 44.299519 | 7.086218 | 39.939583 | -2.155716 | 1.602125 | 4.175039 | -1.769257 |
Plotting¶
We also can plot slices of the parameter space with respect to our objectives.
from ax.analysis import SlicePlot
_ = agent.compute_analyses(analyses=[SlicePlot("bl_kbv_dsv", "bl_det_sum")])
The slice plot provides a one-dimensional view of predicted outcomes for bl_det_sum as a function of a single parameter, while keeping all other parameters fixed at their status_quo value (or mean value if status_quo is unavailable). This visualization helps in understanding the sensitivity and impact of changes in the selected parameter on the predicted metric outcomes.
_ = agent.compute_analyses(analyses=[SlicePlot("bl_kbv_dsv", "bl_det_wid_x")])
The slice plot provides a one-dimensional view of predicted outcomes for bl_det_wid_x as a function of a single parameter, while keeping all other parameters fixed at their status_quo value (or mean value if status_quo is unavailable). This visualization helps in understanding the sensitivity and impact of changes in the selected parameter on the predicted metric outcomes.
More comprehensive analyses¶
Ax provides many analysis tools that can help understand optimization results.
from ax.analysis import TopSurfacesAnalysis
_ = agent.compute_analyses(analyses=[TopSurfacesAnalysis("bl_det_sum")])
Understand how each parameter affects bl_det_sum according to a second-order sensitivity analysis.
The slice plot provides a one-dimensional view of predicted outcomes for bl_det_sum as a function of a single parameter, while keeping all other parameters fixed at their status_quo value (or mean value if status_quo is unavailable). This visualization helps in understanding the sensitivity and impact of changes in the selected parameter on the predicted metric outcomes.
The contour plot visualizes the predicted outcomes for bl_det_sum across a two-dimensional parameter space, with other parameters held fixed at their status_quo value (or mean value if status_quo is unavailable). This plot helps in identifying regions of optimal performance and understanding how changes in the selected parameters influence the predicted outcomes. Contour lines represent levels of constant predicted values, providing insights into the gradient and potential optima within the parameter space.
The slice plot provides a one-dimensional view of predicted outcomes for bl_det_sum as a function of a single parameter, while keeping all other parameters fixed at their status_quo value (or mean value if status_quo is unavailable). This visualization helps in understanding the sensitivity and impact of changes in the selected parameter on the predicted metric outcomes.
The contour plot visualizes the predicted outcomes for bl_det_sum across a two-dimensional parameter space, with other parameters held fixed at their status_quo value (or mean value if status_quo is unavailable). This plot helps in identifying regions of optimal performance and understanding how changes in the selected parameters influence the predicted outcomes. Contour lines represent levels of constant predicted values, providing insights into the gradient and potential optima within the parameter space.
The contour plot visualizes the predicted outcomes for bl_det_sum across a two-dimensional parameter space, with other parameters held fixed at their status_quo value (or mean value if status_quo is unavailable). This plot helps in identifying regions of optimal performance and understanding how changes in the selected parameters influence the predicted outcomes. Contour lines represent levels of constant predicted values, providing insights into the gradient and potential optima within the parameter space.
Visualizing the optimal beam¶
Below we get the optimal parameters, move the motors to their optimal positions, and observe the resulting beam.
optimal_parameters = next(iter(agent.client.get_pareto_frontier()))[0]
optimal_parameters
[INFO 10-13 20:43:30] ax.service.utils.best_point: Using inferred objective thresholds: [ObjectiveThreshold(bl_det_sum >= -8.552646286745016), ObjectiveThreshold(bl_det_wid_x <= 25.747033186890405), ObjectiveThreshold(bl_det_wid_y <= 41.975180427658756)], as objective thresholds were not specified as part of the optimization configuration on the experiment.
{'bl_kbv_dsv': 1.9652896444564145,
'bl_kbv_usv': -0.27072600397546304,
'bl_kbh_dsh': 1.074727342610785,
'bl_kbh_ush': -0.07695790969598545}
from bluesky.plans import list_scan
scan_motor_params = []
for motor in [beamline.kbv_dsv, beamline.kbv_usv, beamline.kbh_dsh, beamline.kbh_ush]:
scan_motor_params.append(motor)
scan_motor_params.append([optimal_parameters[motor.name]])
uid = RE(list_scan([beamline.det], *scan_motor_params))
Transient Scan ID: 26 Time: 2025-10-13 20:43:30
Persistent Unique Scan ID: '1088a572-27a2-4bb3-b685-fc0c1fdb29ae'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| seq_num | time | bl_kbv_dsv | bl_kbv_usv | bl_kbh_dsh | bl_kbh_ush | bl_det_sum | bl_det_cen_x | bl_det_cen_y | bl_det_wid_x | bl_det_wid_y |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
| 1 | 20:43:30.2 | 1.965 | -0.271 | 1.075 | -0.077 | 549.689 | 176.000 | 115.570 | 16.600 | 10.977 |
+-----------+------------+------------+------------+------------+------------+------------+--------------+--------------+--------------+--------------+
generator list_scan ['1088a572'] (scan num: 26)
2025-10-13 20:43:30.167 INFO: Executing plan <generator object list_scan at 0x7f5bdb302d40>
2025-10-13 20:43:30.168 INFO: Change state on <bluesky.run_engine.RunEngine object at 0x7f5c24d282c0> from 'idle' -> 'running'
2025-10-13 20:43:30.540 INFO: Change state on <bluesky.run_engine.RunEngine object at 0x7f5c24d282c0> from 'running' -> 'idle'
2025-10-13 20:43:30.541 INFO: Cleaned up from plan <generator object list_scan at 0x7f5bdb302d40>