Run a simple experiment with Bluesky#
This guide will walk you through the process of running a simple experiment using Blop, Bluesky, and Tiled. See https://blueskyproject.io/ for more information on the Bluesky ecosystem and how these tools work together.
Bluesky along with a data access backend (either Tiled or Databroker) are not necessary for using Blop, but are fully integrated into the package.
We’ll start by importing the necessary libraries.
import logging
import time
from typing import Any
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.callbacks.tiled_writer import TiledWriter
from bluesky.callbacks.best_effort import BestEffortCallback
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)
[WARNING 12-08 20:34:10] 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]`.
First, we will start up a Tiled server. This will act as our data access service which Bluesky will write to and that Blop can read from.
tiled_server = SimpleTiledServer()
2025-12-08 20:34:14.645 INFO: Subprocess stdout:
2025-12-08 20:34:14.646 INFO: Subprocess stderr: Database sqlite+aiosqlite:////tmp/tmp6_g6_y2a/catalog.db is new. Creating tables.
Database initialized.
Tiled version 0.2.2
2025-12-08 20:34:15.071 INFO: Tiled version 0.2.2
2025-12-08 20:34:15.077 INFO: Context impl SQLiteImpl.
2025-12-08 20:34:15.078 INFO: Will assume non-transactional DDL.
Next, we’ll set up the Bluesky run engine and connect to the local Tiled server.
RE = RunEngine({})
tiled_client = from_uri(tiled_server.uri)
tiled_writer = TiledWriter(tiled_client)
RE.subscribe(tiled_writer)
bec = BestEffortCallback()
bec.disable_plots()
RE.subscribe(bec)
1
In order to control parameters and acquire data with Bluesky, we must follow the NamedMovable and Readable protocols. To do this, we implement a simple class that implements both protocols. An alternative to implementing these protocols yourself is to use Ophyd. The additional AlwaysSuccessfulStatus is necessary to tell the Bluesky RunEngine when a move is complete. For the purposes of this tutorial, every move is successful and complete immediately.
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()
Next, we’ll define the DOFs and optimization objective. Since we can calculate our objective based on the two movable signals, there is no need to acquire data using an extra readable. With the movables already configured via the DOFs, it is implicitly added as a readable during the data acquisition.
x1 = MovableSignal("x1", initial_value=0.1)
x2 = MovableSignal("x2", initial_value=0.23)
dofs = [
RangeDOF(movable=x1, bounds=(-5, 5), parameter_type="float"),
RangeDOF(movable=x2, bounds=(-5, 5), parameter_type="float"),
]
objectives = [
Objective(name="himmelblau_2d", minimize=True),
]
readables = []
Note
Additional readables are typically added as a list of devices that produce data, such as detectors, to help with computing the desired outcome via the evaluation function.
Next, we will define the evaluation function. This is initialized with a tiled_client. Notice the care we take in handling
the evaluation of individual suggestions based on the "_id" key. This is important to consider when acquiring data for multiple suggestions in the same Bluesky run.
class Himmelblau2DEvaluation():
def __init__(self, tiled_client: Container):
self.tiled_client = tiled_client
def __call__(self, uid: str, suggestions: list[dict]) -> list[dict]:
run = self.tiled_client[uid]
outcomes = []
x1_data = run["primary/x1"].read()
x2_data = run["primary/x2"].read()
for suggestion in suggestions:
# Special key to identify a suggestion
suggestion_id = suggestion["_id"]
x1 = x1_data[suggestion_id % len(x1_data)]
x2 = x2_data[suggestion_id % len(x2_data)]
outcomes.append({"himmelblau_2d": (x1 ** 2 + x2 - 11) ** 2 + (x1 + x2 ** 2 - 7) ** 2, "_id": suggestion_id})
return outcomes
Next, we will setup the agent and perform the optimization using the run engine.
agent = Agent(
readables=readables,
dofs=dofs,
objectives=objectives,
evaluation=Himmelblau2DEvaluation(
tiled_client=tiled_client,
),
name="simple-experiment",
description="A simple experiment optimizing the Himmelblau function",
)
RE(agent.optimize(30))
Transient Scan ID: 1 Time: 2025-12-08 20:34:15
Persistent Unique Scan ID: '2e503210-963c-4e04-84ed-a2cd043a0fbc'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:15.4 | 0.000 | 0.000 |
+-----------+------------+------------+------------+
generator list_scan ['2e503210'] (scan num: 1)
Transient Scan ID: 2 Time: 2025-12-08 20:34:15
Persistent Unique Scan ID: '4f36874f-dc5b-4975-8cd8-f42247b400f7'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:16.0 | -2.775 | -4.527 |
+-----------+------------+------------+------------+
generator list_scan ['4f36874f'] (scan num: 2)
Transient Scan ID: 3 Time: 2025-12-08 20:34:16
Persistent Unique Scan ID: '8f0f61ee-b4b9-4a5b-afa0-801cfcb14925'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:16.4 | 0.311 | 3.237 |
+-----------+------------+------------+------------+
generator list_scan ['8f0f61ee'] (scan num: 3)
Transient Scan ID: 4 Time: 2025-12-08 20:34:16
Persistent Unique Scan ID: '0bab2aaf-77b1-4675-b746-188ef0cd932a'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:16.8 | 3.826 | -1.062 |
+-----------+------------+------------+------------+
generator list_scan ['0bab2aaf'] (scan num: 4)
Transient Scan ID: 5 Time: 2025-12-08 20:34:17
Persistent Unique Scan ID: '75850c36-4bb7-471a-8df2-2a60beaf2fd4'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:17.5 | -1.291 | 2.273 |
+-----------+------------+------------+------------+
generator list_scan ['75850c36'] (scan num: 5)
Transient Scan ID: 6 Time: 2025-12-08 20:34:18
Persistent Unique Scan ID: 'ed308954-0fef-429d-98f5-823e9c29df78'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:19.0 | 5.000 | -1.400 |
+-----------+------------+------------+------------+
generator list_scan ['ed308954'] (scan num: 6)
Transient Scan ID: 7 Time: 2025-12-08 20:34:21
Persistent Unique Scan ID: 'cd10ace1-9d75-4af5-b674-1605af89fab8'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:21.0 | 3.462 | -0.957 |
+-----------+------------+------------+------------+
generator list_scan ['cd10ace1'] (scan num: 7)
Transient Scan ID: 8 Time: 2025-12-08 20:34:22
Persistent Unique Scan ID: '19c540ae-13f1-4cd4-887f-876125d1d073'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:23.0 | 3.484 | -1.939 |
+-----------+------------+------------+------------+
generator list_scan ['19c540ae'] (scan num: 8)
Transient Scan ID: 9 Time: 2025-12-08 20:34:24
Persistent Unique Scan ID: 'cd95f9ef-60a3-4b9b-a5df-672d50cd38a6'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:24.1 | -0.673 | 5.000 |
+-----------+------------+------------+------------+
generator list_scan ['cd95f9ef'] (scan num: 9)
Transient Scan ID: 10 Time: 2025-12-08 20:34:25
Persistent Unique Scan ID: 'befbd13d-9b23-44cd-86c0-1690073c70ba'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:25.5 | 3.245 | -1.522 |
+-----------+------------+------------+------------+
generator list_scan ['befbd13d'] (scan num: 10)
Transient Scan ID: 11 Time: 2025-12-08 20:34:26
Persistent Unique Scan ID: 'bab97c06-9cd8-421c-b1c7-e9f27495e3da'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:26.6 | 1.538 | 2.449 |
+-----------+------------+------------+------------+
generator list_scan ['bab97c06'] (scan num: 11)
Transient Scan ID: 12 Time: 2025-12-08 20:34:27
Persistent Unique Scan ID: 'df9421ec-d385-4293-ac4a-a0bb0bb94439'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:27.7 | 0.338 | 2.034 |
+-----------+------------+------------+------------+
generator list_scan ['df9421ec'] (scan num: 12)
Transient Scan ID: 13 Time: 2025-12-08 20:34:28
Persistent Unique Scan ID: 'd4d5bc1f-ca13-4f42-a2c4-35bbff3c19ac'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:28.9 | 1.828 | 3.944 |
+-----------+------------+------------+------------+
generator list_scan ['d4d5bc1f'] (scan num: 13)
Transient Scan ID: 14 Time: 2025-12-08 20:34:29
Persistent Unique Scan ID: 'd7e5ef5d-d3ed-4597-93d1-1b6e6baac873'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:30.0 | 2.904 | 1.484 |
+-----------+------------+------------+------------+
generator list_scan ['d7e5ef5d'] (scan num: 14)
Transient Scan ID: 15 Time: 2025-12-08 20:34:31
Persistent Unique Scan ID: '83c56376-a3a4-4d79-b789-8b15908c28df'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:31.2 | 3.805 | 0.897 |
+-----------+------------+------------+------------+
generator list_scan ['83c56376'] (scan num: 15)
Transient Scan ID: 16 Time: 2025-12-08 20:34:32
Persistent Unique Scan ID: '35173580-3d90-43a0-b0b8-bf04cfe91309'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:32.5 | 1.105 | 5.000 |
+-----------+------------+------------+------------+
generator list_scan ['35173580'] (scan num: 16)
Transient Scan ID: 17 Time: 2025-12-08 20:34:33
Persistent Unique Scan ID: '4207b303-3221-4b4e-aa9c-af04753e4c03'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:33.6 | 3.312 | 2.757 |
+-----------+------------+------------+------------+
generator list_scan ['4207b303'] (scan num: 17)
Transient Scan ID: 18 Time: 2025-12-08 20:34:34
Persistent Unique Scan ID: '31a6658f-db67-4675-b6b3-5243ae54496f'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:34.7 | 2.977 | -3.423 |
+-----------+------------+------------+------------+
generator list_scan ['31a6658f'] (scan num: 18)
Transient Scan ID: 19 Time: 2025-12-08 20:34:36
Persistent Unique Scan ID: '1c7a5052-c776-445c-b2ac-d4a15afec633'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:36.0 | 3.042 | 0.312 |
+-----------+------------+------------+------------+
generator list_scan ['1c7a5052'] (scan num: 19)
Transient Scan ID: 20 Time: 2025-12-08 20:34:37
Persistent Unique Scan ID: '1a776383-ca54-4414-89f1-17e9c1a1f5b0'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:37.2 | -3.766 | 2.602 |
+-----------+------------+------------+------------+
generator list_scan ['1a776383'] (scan num: 20)
Transient Scan ID: 21 Time: 2025-12-08 20:34:38
Persistent Unique Scan ID: 'a3f40812-b869-4437-b78a-8911e7a2a480'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:38.2 | -3.611 | 0.940 |
+-----------+------------+------------+------------+
generator list_scan ['a3f40812'] (scan num: 21)
Transient Scan ID: 22 Time: 2025-12-08 20:34:39
Persistent Unique Scan ID: '29286001-dd8c-4609-8238-64b6fcbbd0af'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:39.3 | -5.000 | 4.164 |
+-----------+------------+------------+------------+
generator list_scan ['29286001'] (scan num: 22)
Transient Scan ID: 23 Time: 2025-12-08 20:34:40
Persistent Unique Scan ID: 'e1bb22cc-fdc6-424e-93aa-1f741c1acadd'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:40.4 | -2.547 | 2.832 |
+-----------+------------+------------+------------+
generator list_scan ['e1bb22cc'] (scan num: 23)
Transient Scan ID: 24 Time: 2025-12-08 20:34:41
Persistent Unique Scan ID: '54302ea5-7db8-44ac-b481-adcd9548ab94'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:41.7 | -2.841 | 2.275 |
+-----------+------------+------------+------------+
generator list_scan ['54302ea5'] (scan num: 24)
Transient Scan ID: 25 Time: 2025-12-08 20:34:43
Persistent Unique Scan ID: '7681342b-40fd-4e31-8ec6-4d276bd7a106'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:43.5 | 1.042 | -1.673 |
+-----------+------------+------------+------------+
generator list_scan ['7681342b'] (scan num: 25)
Transient Scan ID: 26 Time: 2025-12-08 20:34:45
Persistent Unique Scan ID: 'dbef7430-08f0-404e-890c-b0b22ebd2d30'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:45.4 | 1.543 | -2.512 |
+-----------+------------+------------+------------+
generator list_scan ['dbef7430'] (scan num: 26)
Transient Scan ID: 27 Time: 2025-12-08 20:34:46
Persistent Unique Scan ID: '8409a246-b0b3-442b-ada9-9de22e7ee907'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:46.6 | 5.000 | 4.694 |
+-----------+------------+------------+------------+
generator list_scan ['8409a246'] (scan num: 27)
Transient Scan ID: 28 Time: 2025-12-08 20:34:47
Persistent Unique Scan ID: 'ecbb4bdc-f4b0-4ab4-b2bd-8d14dddbdfbe'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:47.8 | 2.783 | 2.374 |
+-----------+------------+------------+------------+
generator list_scan ['ecbb4bdc'] (scan num: 28)
Transient Scan ID: 29 Time: 2025-12-08 20:34:48
Persistent Unique Scan ID: 'c40b008f-bdfb-4309-83a2-ccede1c18b0e'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:48.9 | -4.902 | -2.400 |
+-----------+------------+------------+------------+
generator list_scan ['c40b008f'] (scan num: 29)
Transient Scan ID: 30 Time: 2025-12-08 20:34:50
Persistent Unique Scan ID: '3a0dd807-68b6-4372-b130-5d4eefafc335'
New stream: 'primary'
+-----------+------------+------------+------------+
| seq_num | time | x1 | x2 |
+-----------+------------+------------+------------+
| 1 | 20:34:50.1 | -2.417 | -2.168 |
+-----------+------------+------------+------------+
generator list_scan ['3a0dd807'] (scan num: 30)
2025-12-08 20:34:15.368 INFO: Executing plan <generator object Agent.optimize at 0x7f70c8ada7a0>
2025-12-08 20:34:15.369 INFO: Change state on <bluesky.run_engine.RunEngine object at 0x7f70c9f81df0> from 'idle' -> 'running'
2025-12-08 20:34:50.473 INFO: Change state on <bluesky.run_engine.RunEngine object at 0x7f70c9f81df0> from 'running' -> 'idle'
2025-12-08 20:34:50.474 INFO: Cleaned up from plan <generator object Agent.optimize at 0x7f70c8ada7a0>
('2e503210-963c-4e04-84ed-a2cd043a0fbc',
'4f36874f-dc5b-4975-8cd8-f42247b400f7',
'8f0f61ee-b4b9-4a5b-afa0-801cfcb14925',
'0bab2aaf-77b1-4675-b746-188ef0cd932a',
'75850c36-4bb7-471a-8df2-2a60beaf2fd4',
'ed308954-0fef-429d-98f5-823e9c29df78',
'cd10ace1-9d75-4af5-b674-1605af89fab8',
'19c540ae-13f1-4cd4-887f-876125d1d073',
'cd95f9ef-60a3-4b9b-a5df-672d50cd38a6',
'befbd13d-9b23-44cd-86c0-1690073c70ba',
'bab97c06-9cd8-421c-b1c7-e9f27495e3da',
'df9421ec-d385-4293-ac4a-a0bb0bb94439',
'd4d5bc1f-ca13-4f42-a2c4-35bbff3c19ac',
'd7e5ef5d-d3ed-4597-93d1-1b6e6baac873',
'83c56376-a3a4-4d79-b789-8b15908c28df',
'35173580-3d90-43a0-b0b8-bf04cfe91309',
'4207b303-3221-4b4e-aa9c-af04753e4c03',
'31a6658f-db67-4675-b6b3-5243ae54496f',
'1c7a5052-c776-445c-b2ac-d4a15afec633',
'1a776383-ca54-4414-89f1-17e9c1a1f5b0',
'a3f40812-b869-4437-b78a-8911e7a2a480',
'29286001-dd8c-4609-8238-64b6fcbbd0af',
'e1bb22cc-fdc6-424e-93aa-1f741c1acadd',
'54302ea5-7db8-44ac-b481-adcd9548ab94',
'7681342b-40fd-4e31-8ec6-4d276bd7a106',
'dbef7430-08f0-404e-890c-b0b22ebd2d30',
'8409a246-b0b3-442b-ada9-9de22e7ee907',
'ecbb4bdc-f4b0-4ab4-b2bd-8d14dddbdfbe',
'c40b008f-bdfb-4309-83a2-ccede1c18b0e',
'3a0dd807-68b6-4372-b130-5d4eefafc335')
Now we can view the results.
agent.plot_objective("x1", "x2", "himmelblau_2d")
agent.ax_client.summarize()
The contour plot visualizes the predicted outcomes for himmelblau_2d 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.
| 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 | 176.015773 | -2.775333 | -4.526564 |
| 2 | 2 | 2_0 | COMPLETED | Sobol | 73.146589 | 0.310519 | 3.237475 |
| 3 | 3 | 3_0 | COMPLETED | Sobol | 10.838652 | 3.826351 | -1.061835 |
| 4 | 4 | 4_0 | COMPLETED | Sobol | 59.629079 | -1.290774 | 2.272722 |
| 5 | 5 | 5_0 | COMPLETED | MBM | 158.758882 | 5.000000 | -1.400107 |
| 6 | 6 | 6_0 | COMPLETED | MBM | 6.882814 | 3.461520 | -0.956605 |
| 7 | 7 | 7_0 | COMPLETED | MBM | 0.701075 | 3.484084 | -1.939396 |
| 8 | 8 | 8_0 | COMPLETED | MBM | 330.987327 | -0.673153 | 5.000000 |
| 9 | 9 | 9_0 | COMPLETED | MBM | 6.045521 | 3.244797 | -1.521500 |
| 10 | 10 | 10_0 | COMPLETED | MBM | 38.538222 | 1.538331 | 2.448651 |
| 11 | 11 | 11_0 | COMPLETED | MBM | 84.719553 | 0.338065 | 2.034203 |
| 12 | 12 | 12_0 | COMPLETED | MBM | 121.673691 | 1.827899 | 3.944426 |
| 13 | 13 | 13_0 | COMPLETED | MBM | 4.768492 | 2.903551 | 1.483817 |
| 14 | 14 | 14_0 | COMPLETED | MBM | 24.832067 | 3.804632 | 0.896932 |
| 15 | 15 | 15_0 | COMPLETED | MBM | 387.832524 | 1.104584 | 5.000000 |
| 16 | 16 | 16_0 | COMPLETED | MBM | 22.728563 | 3.312160 | 2.756519 |
| 17 | 17 | 17_0 | COMPLETED | MBM | 90.096225 | 2.977144 | -3.422899 |
| 18 | 18 | 18_0 | COMPLETED | MBM | 16.966757 | 3.041728 | 0.312233 |
| 19 | 19 | 19_0 | COMPLETED | MBM | 49.441166 | -3.766186 | 2.602156 |
| 20 | 20 | 20_0 | COMPLETED | MBM | 103.488034 | -3.610816 | 0.939972 |
| 21 | 21 | 21_0 | COMPLETED | MBM | 358.484639 | -5.000000 | 4.164399 |
| 22 | 22 | 22_0 | COMPLETED | MBM | 5.152117 | -2.546594 | 2.832470 |
| 23 | 23 | 23_0 | COMPLETED | MBM | 22.214296 | -2.840797 | 2.274506 |
| 24 | 24 | 24_0 | COMPLETED | MBM | 144.232328 | 1.042218 | -1.673242 |
| 25 | 25 | 25_0 | COMPLETED | MBM | 124.618244 | 1.543269 | -2.512191 |
| 26 | 26 | 26_0 | COMPLETED | MBM | 750.617698 | 5.000000 | 4.693530 |
| 27 | 27 | 27_0 | COMPLETED | MBM | 2.787073 | 2.783403 | 2.374056 |
| 28 | 28 | 28_0 | COMPLETED | MBM | 150.849618 | -4.902469 | -2.399584 |
| 29 | 29 | 29_0 | COMPLETED | MBM | 75.900661 | -2.417186 | -2.168296 |