Interactive BlueAPI Session#
The BlueAPISession class provides a rich, interactive IPython environment on top of the standard BlueapiClient. It comes pre-configured with automatic data collection callbacks, live plotting, and convenient shortcuts for dispatching plans.
Launching the Session#
You can launch an interactive session either through the command-line interface or programmatically in Python.
CLI#
Use the sm-bluesky client command to start a session. You can specify a remote beamline configuration or provide a local YAML config file.
# Connect to a remote beamline server (e.g., p99) with a specific session ID
sm-bluesky client -b p99 -s my_session
# Connect using a local configuration file
sm-bluesky client -c ./src/yaml_config/blueapi_config.yaml -s my_session
Tip
If you omit the -s flag, you will be prompted to provide an instrument session ID, or use -d for a dummy session.
Programmatically#
You can also embed the session directly into your own Python scripts or Jupyter Notebooks:
from sm_bluesky.common.clients import BlueAPISession
from sm_bluesky.common.cli import load_config
# Load configuration for a specific beamline
config = load_config(beamline="p99")
# Initialise the session
session = BlueAPISession(config=config, instrument_session="my_session")
# Start the interactive IPython shell
session.start_shell()
The Interactive Shell Environment#
Once the interactive IPython shell is running, you have access to:
bc: The underlyingBlueapiClientinstance.pl: A shortcut to access available plans (e.g.,pl.step_scan(...)).dev: A shortcut to access available devices (e.g.,dev.dcm).show_plan(): Prints a list of all plans available on the server.show_devices(): Prints a list of all devices available on the server.scan_data: A dictionary containing all collected event data from your scans.plot(scan_id=None): Opens an interactive visualization window.
Data Collection & Live Plotting#
When you initialise a BlueAPISession, it automatically subscribes to data events from the BlueAPI server. As you run plans, data points are collected and stored in memory.
Accessing Data#
Live data is stored in the scan_data dictionary, which is keyed first by the scan_id and then by the device name.
# Run a simple count on the DCM device
pl.count(dev.dcm)
# Run a step scan
# - Detectors: [dev.idd_gap]
# - Axes & Ranges: [[dev.pgm.energy, [start=200, stop=300, step=1]]]
pl.step_scan([dev.idd_gap], [[dev.pgm.energy, [200, 300, 1]]])
# Access the collected data for the last scan
print(scan_data[<last_scan_num>])
# You can also get the last scan number by getting the last item in the dictionary
last_scan_num = next(reversed(scan_data))
Interactive Plotting#
You can visualise this data in near real-time using the built-in interactive plot window. By default, the window will attempt to open automatically, but you can also summon it manually:
# Open the plotting window for the current data
plot()
Note
The interactive plot window allows you to select which scan to view and choose different axes for your X and Y data directly from the collected device outputs. It polls for new data in the background, keeping your plot updated as the scan progresses.
Session Caching & Variable Persistence#
The interactive client automatically caches your active session ID and collected scan data so you can seamlessly resume your work after closing the terminal.
Automatic Caching#
Session ID: When you launch the client with the
-sflag (e.g.,sm-bluesky client -b i10 -s my_session), your session ID is remembered. The next time you launch the client without the-sflag, it will automatically reconnect tomy_session.Scan Data: Every time a hardware scan completes, the collected data is automatically saved to a local cache (
~/.sm-bluesky/cache/). When you restart your client and reconnect to the same session, your previousscan_datais automatically loaded back into memory, allowing you to instantly runplot()on older scans.
User Variables#
There is no easy way to restore the whole namespace as we have active network connections and thread locking is used by the client. Therefore while raw scan_data is cached automatically, any custom variables or processed data arrays you create must be manually set to be persistent.
You can save these across sessions using IPython’s built-in %store magic command:
Tip
Saving a variable:
# Create a variable
my_custom_data = scan_data["123"] * 2.5
# Store it to the local IPython cache
%store my_custom_data
Restoring a variable (after restarting the client):
# Retrieve the variable from the local IPython cache
%store -r my_custom_data
print(my_custom_data)
To view all currently stored variables, simply run %store without any arguments. You can also restore previously saved variables into your current namespace with %store -r.