Skip to content

Track optimization steps using event-model#236

Merged
thopkins32 merged 14 commits intomainfrom
multi-run-plans
Feb 11, 2026
Merged

Track optimization steps using event-model#236
thopkins32 merged 14 commits intomainfrom
multi-run-plans

Conversation

@thopkins32
Copy link
Collaborator

@thopkins32 thopkins32 commented Jan 30, 2026

Summary

Changed blop.plans.optimize to open a Bluesky run of its own to track suggestions and outcomes in the Blueksy event-model.

Closes #220

Goals

Enable the use of Bluesky callbacks on each optimization step. Allows for live plots, writing to Tiled, etc.

Implications

Currently, blop.plans.default_acquire opens a Bluesky run, since internally it is a list_scan. After this change, we have a nested run structure. For example,

>>> RE(agent.optimize(iterations=5, num_points=2))
... open_run -> "optimize" run open
...    open_run -> "default_acquire" run open
...        event -> acquire raw data point 1
...        event -> acquire raw data point 2
...    close_run -> "default_acquire" run closed
...    # <---- UID of the closed run is used here to fetch raw data and compute outcomes
...    event -> record 2 suggestions and 2 outcomes as arrays
...    open_run -> "default_acquire" run open
...        event -> acquire raw data point 1
...        event -> acquire raw data point 2
...    close_run -> "default_acquire" run closed
...    # <---- UID of the closed run is used here to fetch raw data and compute outcomes
...    event -> record 2 suggestions and 2 outcomes as arrays
...    # Repeat again 3 more times for a total of 5 iterations
... close_run -> "optimize" run closed    

blop.plans.default_acquire is optional, and users can plug-in any acquisition plan they would like here, possibly opening/closing as many BlueskyRuns as they need.

Forcing a flat run structure is not practical for the following reasons:

  • TiledWriter callbacks would require use with a batch size of 1 since Tiled is frequently use to fetch data and compute optimization outcomes.
  • It would require potentially opening multiple data streams to account for the different event contents and frequency
  • It would break the ability to plug-in custom acquisition plans in place of default_acquire
  • It would require a custom list_scan plan or stripping out the open/close run documents from default_acquire

Combining the entire optimization process into a single run is tempting since it can reduce the total number of UIDs needed to track. However, I'm not yet convinced that it is bad to have so many UIDs.

Follow-up changes

  • blop.protocols.EvaluationFunction should be more flexible. Instead of accepting a uid: str it should accept a more general run_md: dict containing all metadata necessary to fetch the acquired data.
  • blop.protocols.AcquisitionPlan must in turn change to return a run_md: dict instead of just a uid: str.

@thopkins32 thopkins32 marked this pull request as draft January 30, 2026 21:46
@thopkins32 thopkins32 marked this pull request as ready for review February 11, 2026 19:28
@thopkins32 thopkins32 merged commit 6456d84 into main Feb 11, 2026
18 checks passed
@thopkins32 thopkins32 deleted the multi-run-plans branch February 11, 2026 22:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Considering multi-run plans (RunEngine only)

1 participant