Your first Bayesian optimization with Blop#

In this tutorial, you will learn the three core concepts of Blop: DOFs (the parameters you can adjust), objectives (what you want to optimize), and the Agent (which coordinates the optimization). We’ll optimize a simple mathematical function using simulated devices—the same patterns apply to real hardware.

Setup#

First, let’s import what we need and start the data infrastructure:

import logging
import time
from typing import Any
import warnings

from blop.ax import Agent, RangeDOF, Objective

from bluesky.protocols import NamedMovable, Readable, Status, Hints, HasHints, HasParent
from bluesky.run_engine import RunEngine
from bluesky_tiled_plugins import TiledWriter
from tiled.client import from_uri
from tiled.client.container import Container
from tiled.server import SimpleTiledServer

# Suppress noisy logs from httpx 
logging.getLogger("httpx").setLevel(logging.WARNING)
# Suppress noisy dependency deprecations from within Ax
warnings.filterwarnings('ignore',category=FutureWarning)
/home/runner/work/blop/blop/.pixi/envs/docs/lib/python3.13/site-packages/torch/jit/_script.py:1491: FutureWarning: `torch.jit.script` is deprecated. Please switch to `torch.compile` or `torch.export`.
  warnings.warn(
[INFO 10-23 20:18:49] ax.storage.sqa_store.with_db_settings_base: Ax SQL storage initialized with SQLAlchemy 2.0.55
# Start a local Tiled server for data storage
tiled_server = SimpleTiledServer()

# Set up the Bluesky RunEngine and connect it to Tiled
RE = RunEngine({})
tiled_client = from_uri(tiled_server.uri)
tiled_writer = TiledWriter(tiled_client)
RE.subscribe(tiled_writer)
0

Creating simulated devices#

Bluesky controls devices through protocols. For this tutorial, we create simple simulated “movable” devices. In real experiments, you would use Ophyd devices or similar—the code below is just boilerplate to simulate hardware:

class AlwaysSuccessfulStatus(Status):
    def add_callback(self, callback) -> None:
        callback(self)
    def exception(self, timeout = 0.0):
        return None
    @property
    def done(self) -> bool:
        return True
    @property
    def success(self) -> bool:
        return True

class ReadableSignal(Readable, HasHints, HasParent):
    def __init__(self, name: str) -> None:
        self._name = name
        self._value = 0.0
    @property
    def name(self) -> str:
        return self._name
    @property
    def hints(self) -> Hints:
        return {"fields": [self._name], "dimensions": [], "gridding": "rectilinear"}
    @property
    def parent(self) -> Any | None:
        return None
    def read(self):
        return {self._name: {"value": self._value, "timestamp": time.time()}}
    def describe(self):
        return {self._name: {"source": self._name, "dtype": "number", "shape": []}}

class MovableSignal(ReadableSignal, NamedMovable):
    def __init__(self, name: str, initial_value: float = 0.0) -> None:
        super().__init__(name)
        self._value: float = initial_value
    def set(self, value: float) -> Status:
        self._value = value
        return AlwaysSuccessfulStatus()

Defining DOFs and objectives#

DOFs (degrees of freedom) are the parameters the optimizer can adjust. Objectives are what you want to optimize. Here we define two DOFs (x1 and x2) that can range from -5 to 5, and one objective (the Himmelblau function) that we want to minimize:

x1 = MovableSignal("x1", initial_value=0.1)
x2 = MovableSignal("x2", initial_value=0.23)

dofs = [
    RangeDOF(actuator=x1, bounds=(-5, 5), parameter_type="float"),
    RangeDOF(actuator=x2, bounds=(-5, 5), parameter_type="float"),
]
objectives = [
    Objective(name="himmelblau_2d", minimize=True),
]
sensors = []

Writing the evaluation function#

The evaluation function computes objective values from experimental data. Blop passes it the uid returned by the acquisition plan and the suggestions that were tried. This tutorial uses the default acquisition plan, so the uid is a Bluesky run UID and blop_acquisition_order associates measurements with outcomes.

from collections.abc import Mapping, Sequence

class Himmelblau2DEvaluation():
    def __init__(self, tiled_client: Container):
        self.tiled_client = tiled_client

    def __call__(self, uid: str, suggestions: Sequence[Mapping]) -> Sequence[Mapping]:
        run = self.tiled_client[uid]
        outcomes = []
        acquisition_order = run.start["blop_acquisition_order"]
        x1_data = run["primary/x1"].read()
        x2_data = run["primary/x2"].read()

        print("[Himmelblau] evaluating acquired order: ", acquisition_order)
        for index, suggestion_id in enumerate(acquisition_order):
            x1 = x1_data[index]
            x2 = x2_data[index]
            # Himmelblau function: has four global minima where value = 0
            outcomes.append({
                "himmelblau_2d": (x1 ** 2 + x2 - 11) ** 2 + (x1 + x2 ** 2 - 7) ** 2,
                "_id": suggestion_id
            })
        
        return outcomes

Running the optimization#

The Agent brings everything together. Create one with your DOFs, objectives, and evaluation function, then run the optimization:

agent = Agent(
    sensors=sensors,
    dofs=dofs,
    objectives=objectives,
    evaluation_function=Himmelblau2DEvaluation(tiled_client=tiled_client),
    name="simple-experiment",
    description="A simple experiment optimizing the Himmelblau function",
)

RE(agent.optimize(5,n_points=8))
╭───────────────────────────────────────────────── Optimization ──────────────────────────────────────────────────╮
│ Optimizer  AxOptimizer                                                                                          │
│ Actuators  x1, x2                                                                                               │
│ Sensors    N/A                                                                                                  │
│ Iterations 5  Points/iter 8                                                                                     │
│ Run UID    51878fa0-56ab-4f0a-a28c-e8b9493150f3                                                                 │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
[Himmelblau] evaluating acquired order:
[0, 7, 6, 3, 5, 1, 4, 2]
[Himmelblau] evaluating acquired order:
[15, 11, 13, 8, 12, 10, 9, 14]
[Himmelblau] evaluating acquired order:
[18, 22, 16, 17, 23, 20, 21, 19]
[Himmelblau] evaluating acquired order:
[24, 29, 30, 26, 31, 25, 27, 28]
[Himmelblau] evaluating acquired order:
[33, 39, 34, 38, 35, 37, 36, 32]
[INFO 10-23 20:18:53] ax.api.client: GenerationStrategy(name='Center+Sobol+MBM:fast', nodes=[CenterGenerationNode(next_node_name='Sobol', use_existing_trials_for_initialization=True), GenerationNode(name='Sobol', generator_specs=[GeneratorSpec(generator_enum=Sobol, generator_key_override=None)], transition_criteria=[MinTrials(transition_to='MBM'), MinTrials(transition_to='MBM')], suggested_experiment_status=ExperimentStatus.INITIALIZATION, pausing_criteria=[MaxTrialsAwaitingData(threshold=5)]), GenerationNode(name='MBM', generator_specs=[GeneratorSpec(generator_enum=BoTorch, generator_key_override=None)], transition_criteria=None, suggested_experiment_status=ExperimentStatus.OPTIMIZATION, pausing_criteria=None)]) chosen based on user input and problem structure.
[INFO 10-23 20:18:53] ax.api.client: Generated new trial 0 with parameters {'x1': 0.0, 'x2': 0.0} using GenerationNode CenterOfSearchSpace.
[INFO 10-23 20:18:53] ax.api.client: Generated new trial 1 with parameters {'x1': 3.271444, 'x2': -2.411433} using GenerationNode Sobol.
[INFO 10-23 20:18:53] ax.api.client: Generated new trial 2 with parameters {'x1': -0.48405, 'x2': 3.682655} using GenerationNode Sobol.
[INFO 10-23 20:18:53] ax.api.client: Generated new trial 3 with parameters {'x1': -4.579579, 'x2': -2.83189} using GenerationNode Sobol.
[INFO 10-23 20:18:53] ax.api.client: Generated new trial 4 with parameters {'x1': 1.675916, 'x2': 1.699547} using GenerationNode Sobol.
[INFO 10-23 20:18:53] ax.api.client: Generated new trial 5 with parameters {'x1': 0.151828, 'x2': -4.039678} using GenerationNode Sobol.
[INFO 10-23 20:18:53] ax.api.client: Generated new trial 6 with parameters {'x1': -3.602445, 'x2': 0.179345} using GenerationNode Sobol.
[INFO 10-23 20:18:53] ax.api.client: Generated new trial 7 with parameters {'x1': -1.459965, 'x2': -0.729816} using GenerationNode Sobol.
[INFO 10-23 20:18:54] ax.api.client: Trial 0 marked COMPLETED.
[INFO 10-23 20:18:54] ax.api.client: Trial 7 marked COMPLETED.
[INFO 10-23 20:18:54] ax.api.client: Trial 6 marked COMPLETED.
[INFO 10-23 20:18:54] ax.api.client: Trial 3 marked COMPLETED.
[INFO 10-23 20:18:54] ax.api.client: Trial 5 marked COMPLETED.
[INFO 10-23 20:18:54] ax.api.client: Trial 1 marked COMPLETED.
[INFO 10-23 20:18:54] ax.api.client: Trial 4 marked COMPLETED.
[INFO 10-23 20:18:54] ax.api.client: Trial 2 marked COMPLETED.
[INFO 10-23 20:18:56] ax.api.client: Generated new trial 8 with parameters {'x1': 3.629392, 'x2': 0.74702} using GenerationNode MBM.
[INFO 10-23 20:18:56] ax.api.client: Generated new trial 9 with parameters {'x1': 4.494566, 'x2': -4.972202} using GenerationNode MBM.
[INFO 10-23 20:18:56] ax.api.client: Generated new trial 10 with parameters {'x1': 5.0, 'x2': -1.357578} using GenerationNode MBM.
[INFO 10-23 20:18:56] ax.api.client: Generated new trial 11 with parameters {'x1': 3.071814, 'x2': 5.0} using GenerationNode MBM.
[INFO 10-23 20:18:56] ax.api.client: Generated new trial 12 with parameters {'x1': 2.93267, 'x2': -0.207415} using GenerationNode MBM.
[INFO 10-23 20:18:56] ax.api.client: Generated new trial 13 with parameters {'x1': 5.0, 'x2': 5.0} using GenerationNode MBM.
[INFO 10-23 20:18:56] ax.api.client: Generated new trial 14 with parameters {'x1': 3.460781, 'x2': -5.0} using GenerationNode MBM.
[INFO 10-23 20:18:56] ax.api.client: Generated new trial 15 with parameters {'x1': 1.415693, 'x2': 5.0} using GenerationNode MBM.
[INFO 10-23 20:18:57] ax.api.client: Trial 15 marked COMPLETED.
[INFO 10-23 20:18:57] ax.api.client: Trial 11 marked COMPLETED.
[INFO 10-23 20:18:57] ax.api.client: Trial 13 marked COMPLETED.
[INFO 10-23 20:18:57] ax.api.client: Trial 8 marked COMPLETED.
[INFO 10-23 20:18:57] ax.api.client: Trial 12 marked COMPLETED.
[INFO 10-23 20:18:57] ax.api.client: Trial 10 marked COMPLETED.
[INFO 10-23 20:18:57] ax.api.client: Trial 9 marked COMPLETED.
[INFO 10-23 20:18:57] ax.api.client: Trial 14 marked COMPLETED.
[INFO 10-23 20:19:00] ax.api.client: Generated new trial 16 with parameters {'x1': -1.624292, 'x2': 2.306385} using GenerationNode MBM.
[INFO 10-23 20:19:00] ax.api.client: Generated new trial 17 with parameters {'x1': -2.592794, 'x2': 4.296373} using GenerationNode MBM.
[INFO 10-23 20:19:00] ax.api.client: Generated new trial 18 with parameters {'x1': 2.333955, 'x2': -1.942228} using GenerationNode MBM.
[INFO 10-23 20:19:00] ax.api.client: Generated new trial 19 with parameters {'x1': -5.0, 'x2': -5.0} using GenerationNode MBM.
[INFO 10-23 20:19:00] ax.api.client: Generated new trial 20 with parameters {'x1': -5.0, 'x2': -1.218382} using GenerationNode MBM.
[INFO 10-23 20:19:00] ax.api.client: Generated new trial 21 with parameters {'x1': -3.087286, 'x2': -2.547444} using GenerationNode MBM.
[INFO 10-23 20:19:00] ax.api.client: Generated new trial 22 with parameters {'x1': -0.353183, 'x2': 2.10834} using GenerationNode MBM.
[INFO 10-23 20:19:00] ax.api.client: Generated new trial 23 with parameters {'x1': -5.0, 'x2': 3.101469} using GenerationNode MBM.
[INFO 10-23 20:19:00] ax.api.client: Trial 18 marked COMPLETED.
[INFO 10-23 20:19:00] ax.api.client: Trial 22 marked COMPLETED.
[INFO 10-23 20:19:00] ax.api.client: Trial 16 marked COMPLETED.
[INFO 10-23 20:19:00] ax.api.client: Trial 17 marked COMPLETED.
[INFO 10-23 20:19:00] ax.api.client: Trial 23 marked COMPLETED.
[INFO 10-23 20:19:00] ax.api.client: Trial 20 marked COMPLETED.
[INFO 10-23 20:19:00] ax.api.client: Trial 21 marked COMPLETED.
[INFO 10-23 20:19:00] ax.api.client: Trial 19 marked COMPLETED.
[INFO 10-23 20:19:03] ax.api.client: Generated new trial 24 with parameters {'x1': -3.418506, 'x2': -3.45645} using GenerationNode MBM.
[INFO 10-23 20:19:03] ax.api.client: Generated new trial 25 with parameters {'x1': 2.787774, 'x2': 0.930112} using GenerationNode MBM.
[INFO 10-23 20:19:03] ax.api.client: Generated new trial 26 with parameters {'x1': 3.350313, 'x2': -1.637893} using GenerationNode MBM.
[INFO 10-23 20:19:03] ax.api.client: Generated new trial 27 with parameters {'x1': 3.204781, 'x2': 1.837737} using GenerationNode MBM.
[INFO 10-23 20:19:03] ax.api.client: Generated new trial 28 with parameters {'x1': -1.959754, 'x2': 3.290527} using GenerationNode MBM.
[INFO 10-23 20:19:03] ax.api.client: Generated new trial 29 with parameters {'x1': -3.062108, 'x2': -3.852038} using GenerationNode MBM.
[INFO 10-23 20:19:03] ax.api.client: Generated new trial 30 with parameters {'x1': -2.438183, 'x2': -5.0} using GenerationNode MBM.
[INFO 10-23 20:19:03] ax.api.client: Generated new trial 31 with parameters {'x1': 2.551096, 'x2': 0.705979} using GenerationNode MBM.
[INFO 10-23 20:19:04] ax.api.client: Trial 24 marked COMPLETED.
[INFO 10-23 20:19:04] ax.api.client: Trial 29 marked COMPLETED.
[INFO 10-23 20:19:04] ax.api.client: Trial 30 marked COMPLETED.
[INFO 10-23 20:19:04] ax.api.client: Trial 26 marked COMPLETED.
[INFO 10-23 20:19:04] ax.api.client: Trial 31 marked COMPLETED.
[INFO 10-23 20:19:04] ax.api.client: Trial 25 marked COMPLETED.
[INFO 10-23 20:19:04] ax.api.client: Trial 27 marked COMPLETED.
[INFO 10-23 20:19:04] ax.api.client: Trial 28 marked COMPLETED.
[INFO 10-23 20:19:08] ax.api.client: Generated new trial 32 with parameters {'x1': -3.552535, 'x2': -3.19819} using GenerationNode MBM.
[INFO 10-23 20:19:08] ax.api.client: Generated new trial 33 with parameters {'x1': 2.524135, 'x2': 2.381407} using GenerationNode MBM.
[INFO 10-23 20:19:08] ax.api.client: Generated new trial 34 with parameters {'x1': 3.166945, 'x2': 1.456542} using GenerationNode MBM.
[INFO 10-23 20:19:08] ax.api.client: Generated new trial 35 with parameters {'x1': 5.0, 'x2': 1.703888} using GenerationNode MBM.
[INFO 10-23 20:19:08] ax.api.client: Generated new trial 36 with parameters {'x1': -3.050711, 'x2': -3.113705} using GenerationNode MBM.
[INFO 10-23 20:19:08] ax.api.client: Generated new trial 37 with parameters {'x1': 3.445227, 'x2': -1.938748} using GenerationNode MBM.
[INFO 10-23 20:19:08] ax.api.client: Generated new trial 38 with parameters {'x1': 4.210813, 'x2': 1.674938} using GenerationNode MBM.
[INFO 10-23 20:19:08] ax.api.client: Generated new trial 39 with parameters {'x1': 2.888342, 'x2': 1.746867} using GenerationNode MBM.
[INFO 10-23 20:19:08] ax.api.client: Trial 33 marked COMPLETED.
[INFO 10-23 20:19:08] ax.api.client: Trial 39 marked COMPLETED.
[INFO 10-23 20:19:08] ax.api.client: Trial 34 marked COMPLETED.
[INFO 10-23 20:19:08] ax.api.client: Trial 38 marked COMPLETED.
[INFO 10-23 20:19:08] ax.api.client: Trial 35 marked COMPLETED.
[INFO 10-23 20:19:08] ax.api.client: Trial 37 marked COMPLETED.
[INFO 10-23 20:19:08] ax.api.client: Trial 36 marked COMPLETED.
[INFO 10-23 20:19:08] ax.api.client: Trial 32 marked COMPLETED.
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Suggestion ID              ┃ x1                         ┃ x2                        ┃ himmelblau_2d             ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
└────────────────────────────┴────────────────────────────┴───────────────────────────┴───────────────────────────┘
┃                            ┃                            ┃                           ┃                           ┃
┃ 0                          ┃                          0 ┃                         0 ┃                       170 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 1                          ┃                    3.27144 ┃                  -2.41143 ┃                   11.6924 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 2                          ┃                   -0.48405 ┃                   3.68265 ┃                   87.1103 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 3                          ┃                   -4.57958 ┃                  -2.83189 ┃                   63.6623 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 4                          ┃                    1.67592 ┃                   1.69955 ┃                   48.0752 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
───────────────────────────────────────────────── Iteration 1 / 5 ─────────────────────────────────────────────────
  himmelblau_2d  min: 11.6924  max: 170  mean: 76.108
  (5 pts sampled)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┃                            ┃                            ┃                           ┃                           ┃
┃ 5                          ┃                   0.151828 ┃                  -4.03968 ┃                   315.196 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 6                          ┃                   -3.60244 ┃                  0.179345 ┃                   116.383 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 7                          ┃                   -1.45997 ┃                 -0.729816 ┃                    154.97 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 10                         ┃                          5 ┃                  -1.35758 ┃                   159.855 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 11                         ┃                    3.07181 ┃                         5 ┃                   455.828 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
───────────────────────────────────────────────── Iteration 2 / 5 ─────────────────────────────────────────────────
  himmelblau_2d  min: 11.6924  max: 455.828  mean: 158.277
  (10 pts sampled)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┃                            ┃                            ┃                           ┃                           ┃
┃ 12                         ┃                    2.93267 ┃                 -0.207415 ┃                   22.9908 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 13                         ┃                          5 ┃                         5 ┃                       890 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 14                         ┃                    3.46078 ┃                        -5 ┃                    476.75 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 15                         ┃                    1.41569 ┃                         5 ┃                   392.936 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 8                          ┃                    3.62939 ┃                   0.74702 ┃                   16.4341 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
───────────────────────────────────────────────── Iteration 2 / 5 ─────────────────────────────────────────────────
  himmelblau_2d  min: 11.6924  max: 890  mean: 225.459
  (15 pts sampled)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┃                            ┃                            ┃                           ┃                           ┃
┃ 9                          ┃                    4.49457 ┃                   -4.9722 ┃                   511.495 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 16                         ┃                   -1.62429 ┃                   2.30638 ┃                   47.5888 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 17                         ┃                   -2.59279 ┃                   4.29637 ┃                   78.6068 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 18                         ┃                    2.33396 ┃                  -1.94223 ┃                   56.9721 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 19                         ┃                         -5 ┃                        -5 ┃                       250 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
───────────────────────────────────────────────── Iteration 3 / 5 ─────────────────────────────────────────────────
  himmelblau_2d  min: 11.6924  max: 890  mean: 216.327
  (20 pts sampled)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┃                            ┃                            ┃                           ┃                           ┃
┃ 20                         ┃                         -5 ┃                  -1.21838 ┃                   273.946 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 21                         ┃                   -3.08729 ┃                  -2.54744 ┃                   29.0734 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 22                         ┃                  -0.353183 ┃                   2.10834 ┃                   85.3159 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 23                         ┃                         -5 ┃                   3.10147 ┃                   298.129 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 24                         ┃                   -3.41851 ┃                  -3.45645 ┃                   10.0108 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
───────────────────────────────────────────────── Iteration 4 / 5 ─────────────────────────────────────────────────
  himmelblau_2d  min: 10.0108  max: 890  mean: 200.921
  (25 pts sampled)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┃                            ┃                            ┃                           ┃                           ┃
┃ 25                         ┃                    2.78777 ┃                  0.930112 ┃                   16.4849 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 26                         ┃                    3.35031 ┃                  -1.63789 ┃                   2.93247 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 27                         ┃                    3.20478 ┃                   1.83774 ┃                   1.40313 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 28                         ┃                   -1.95975 ┃                   3.29053 ┃                   18.4566 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 29                         ┃                   -3.06211 ┃                  -3.85204 ┃                   52.7925 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
───────────────────────────────────────────────── Iteration 4 / 5 ─────────────────────────────────────────────────
  himmelblau_2d  min: 1.40313  max: 890  mean: 170.503
  (30 pts sampled)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┃                            ┃                            ┃                           ┃                           ┃
┃ 30                         ┃                   -2.43818 ┃                        -5 ┃                   343.278 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 31                         ┃                     2.5511 ┃                  0.705979 ┃                   29.9397 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 32                         ┃                   -3.55254 ┃                  -3.19819 ┃                   2.59414 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 33                         ┃                    2.52413 ┃                   2.38141 ┃                   6.47911 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 34                         ┃                    3.16695 ┃                   1.45654 ┃                   3.16565 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
───────────────────────────────────────────────── Iteration 5 / 5 ─────────────────────────────────────────────────
  himmelblau_2d  min: 1.40313  max: 890  mean: 157.159
  (35 pts sampled)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┃                            ┃                            ┃                           ┃                           ┃
┃ 35                         ┃                          5 ┃                   1.70389 ┃                   247.428 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 36                         ┃                   -3.05071 ┃                  -3.11371 ┃                   23.2324 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 37                         ┃                    3.44523 ┃                  -1.93875 ┃                   1.18471 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 38                         ┃                    4.21081 ┃                   1.67494 ┃                   70.6592 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
┃                            ┃                            ┃                           ┃                           ┃
┃ 39                         ┃                    2.88834 ┃                   1.74687 ┃                   1.95305 ┃
┡────────────────────────────╇────────────────────────────╇───────────────────────────╇───────────────────────────┩
───────────────────────────────────────────────── Iteration 5 / 5 ─────────────────────────────────────────────────
  himmelblau_2d  min: 1.18471  max: 890  mean: 146.125
  (40 pts sampled)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────

                           Summary Statistics                            
┏━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━┳━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━┓
┃ Name          ┃ Type    ┃     Min ┃ Max ┃      Mean ┃     Std ┃ Count ┃
┡━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━╇━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━┩
│ x1            │ param   │      -5 │   5 │  0.482552 │ 3.29446 │    40 │
│ x2            │ param   │      -5 │   5 │ -0.140149 │  3.0315 │    40 │
│ himmelblau_2d │ outcome │ 1.18471 │ 890 │   146.125 │ 191.529 │    40 │
└───────────────┴─────────┴─────────┴─────┴───────────┴─────────┴───────┘
────────────────────────────────────────────── Optimization Complete ──────────────────────────────────────────────
('51878fa0-56ab-4f0a-a28c-e8b9493150f3',
 '9d35cc02-3cb0-4f0c-9c44-7cfa9e23d428',
 'bb79c220-3516-4716-8b63-c0c5aebfd032',
 '438d80b8-a00f-4b5e-88a9-5800efa16dd5',
 '41d59885-e6e1-41d2-aa21-767e800b0012',
 '0aa2d5a0-1f07-4851-be3b-f449b2f2797c')

Viewing the results#

After optimization, visualize what the Agent learned and see the best parameters found:

agent.plot_objective("x1", "x2", "himmelblau_2d")
agent.ax_client.summarize()
himmelblau_2d (Mean) vs. x1, x2
The contour plot visualizes the predicted outcomes for himmelblau_2d across a two-dimensional parameter space, with other parameters held fixed at their best trial value (Arm 26_0). 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.
trial_index arm_name trial_status generation_node himmelblau_2d x1 x2
0 0 0_0 COMPLETED CenterOfSearchSpace 170.000000 0.000000 0.000000
1 1 1_0 COMPLETED Sobol 11.692449 3.271444 -2.411433
2 2 2_0 COMPLETED Sobol 87.110282 -0.484050 3.682655
3 3 3_0 COMPLETED Sobol 63.662306 -4.579579 -2.831890
4 4 4_0 COMPLETED Sobol 48.075204 1.675916 1.699547
5 5 5_0 COMPLETED Sobol 315.195533 0.151828 -4.039678
6 6 6_0 COMPLETED Sobol 116.383267 -3.602445 0.179345
7 7 7_0 COMPLETED Sobol 154.970324 -1.459965 -0.729816
8 8 8_0 COMPLETED MBM 16.434072 3.629392 0.747020
9 9 9_0 COMPLETED MBM 511.494999 4.494566 -4.972202
10 10 10_0 COMPLETED MBM 159.855471 5.000000 -1.357578
11 11 11_0 COMPLETED MBM 455.827749 3.071814 5.000000
12 12 12_0 COMPLETED MBM 22.990801 2.932670 -0.207415
13 13 13_0 COMPLETED MBM 890.000000 5.000000 5.000000
14 14 14_0 COMPLETED MBM 476.749605 3.460781 -5.000000
15 15 15_0 COMPLETED MBM 392.935665 1.415693 5.000000
16 16 16_0 COMPLETED MBM 47.588781 -1.624292 2.306385
17 17 17_0 COMPLETED MBM 78.606844 -2.592794 4.296373
18 18 18_0 COMPLETED MBM 56.972106 2.333955 -1.942228
19 19 19_0 COMPLETED MBM 250.000000 -5.000000 -5.000000
20 20 20_0 COMPLETED MBM 273.946482 -5.000000 -1.218382
21 21 21_0 COMPLETED MBM 29.073411 -3.087286 -2.547444
22 22 22_0 COMPLETED MBM 85.315866 -0.353183 2.108340
23 23 23_0 COMPLETED MBM 298.128879 -5.000000 3.101469
24 24 24_0 COMPLETED MBM 10.010844 -3.418506 -3.456450
25 25 25_0 COMPLETED MBM 16.484936 2.787774 0.930112
26 26 26_0 COMPLETED MBM 2.932471 3.350313 -1.637893
27 27 27_0 COMPLETED MBM 1.403131 3.204781 1.837737
28 28 28_0 COMPLETED MBM 18.456626 -1.959754 3.290527
29 29 29_0 COMPLETED MBM 52.792515 -3.062108 -3.852038
30 30 30_0 COMPLETED MBM 343.278414 -2.438183 -5.000000
31 31 31_0 COMPLETED MBM 29.939685 2.551096 0.705979
32 32 32_0 COMPLETED MBM 2.594140 -3.552535 -3.198190
33 33 33_0 COMPLETED MBM 6.479112 2.524135 2.381407
34 34 34_0 COMPLETED MBM 3.165645 3.166945 1.456542
35 35 35_0 COMPLETED MBM 247.427914 5.000000 1.703888
36 36 36_0 COMPLETED MBM 23.232392 -3.050711 -3.113705
37 37 37_0 COMPLETED MBM 1.184709 3.445227 -1.938748
38 38 38_0 COMPLETED MBM 70.659210 4.210813 1.674938
39 39 39_0 COMPLETED MBM 1.953053 2.888342 1.746867

The Himmelblau function has four global minima (all with value 0). The summarize output shows which one(s) the optimizer found.

What you learned#

You now understand the three core concepts of Blop:

  • DOFs: The parameters the optimizer adjusts (here, x1 and x2 with bounds)

  • Objectives: What you’re optimizing (here, minimizing the Himmelblau function)

  • Agent: Coordinates the optimization loop between Bluesky and the evaluation function

Next steps#

For a more comprehensive tutorial with multiple objectives and diagnostic tools, see Optimizing KB Mirrors.