Skip to content

2023 NX School

Pete R Jemian edited this page Oct 18, 2023 · 12 revisions

X30: Beamline Control and Data Acquisition with Bluesky

2023 NX School

Starting page: APS Bluesky Training

QR code

Introduction

  • Presenters
  • Participants

What is beamline control?

Basics:

  • move positioners
  • read detectors
  • keep a record of that

What is Bluesky?

Introduction

Bluesky is a Python framework to make scientific measurements and store the data. Bluesky enables scientists to leverage the scientific Python ecosystem at every stage of the experiment from data acquistion through data analysis.

It's an international collaboration, started at NSLS-II (BNL).

As users, what do you need to know?

  • What are the devices? (ophyd Signals and Devices)
  • What are the measurement procedures? (bluesky plans)
  • How are they used? (execute measurements with bluesky RE)
  • How to get to the data? (databroker)
  • How to take data away? (SPEC data files & HDF5 files for area detector images)

General cheat sheet shows the interactive commands.

Start working with Bluesky

We'll cover those commands and then start to run some plans.

First, create your own working directory:

mkdir ~/YOUR_NAME
cd ~/YOUR_NAME

Your choice to use command or notebook. I recommend a Jupyter notebook for a class since it creates a single document you can take away with you, complete with input, output, and graphs.

IPython command-line

Start a session from the command line:

blueskyStarter.sh
# IPython starts, lots of printout, 
# ends with    #### Startup is complete. ####
# Then, prompt appears.

Jupyter notebook

Start session(s) using Jupyter notebook:

blueskyStarter.sh lab
# Jupyter server starts, lots of printout, web browser appears
# In the browser, create a new notebook by clicking "bluesky_2023_2"
# startup the session with these lines of Python

import pathlib, sys
sys.path.append(str(pathlib.Path.home() / "bluesky"))
from instrument.collection import *

# ends with    #### Startup is complete. ####

Hello, World!

Run the simplest bluesky plan. It tests that the infrastructure is working.

%run -i ~/bluesky/user/quick_hello.py
RE(hello_world())

Look at the data from the run:

run = cat[-1]  # reference the last run in the databroker catalog
dataset = run.primary.read()  # read the data from the primary stream
dataset  # print an overview of the data

Look at the metadata from the run:

run.metadata

Show the most recent runs in the databroker catalog:

listruns()

Show the bluesky Python objects:

listobjects()

1-D scan

notebook

The simulated instrument has a special detector named noisy that changes in response to the position of motor m1. The simulation makes a pseudo-voigt peak positioned at random somewhere between:

m1: -1 .. peak .. +1

Find that peak. This command moves m1 from -2 to 2 in 11 points (10 steps) and measures noisy at each point.

RE(bp.scan([noisy], m1, -2, 2, 11))

bp.scan() is one of the standard pre-assembled bluesky plans.

List the standard bluesky plans (provided by bp):

listplans(bp)

Find the m1 position where the noisy detector is its maximum and move to that position:

m1.move(0.5)  # or wherever the max

Re-scan closer to that maximum. Use a relative scan. It starts and ends relative to the inital position.

RE(bp.rel_scan([noisy], m1, -0.5, 0.5, 11))

Again, move m1 to the peak.

m1.move(0.45)  # or wherever the max

Map out the peak with lots of points. Again, use a relative scan.

RE(bp.rel_scan([noisy], m1, -0.15, 0.15, 41))

This notebook has more examples using noisy and m1.

Your instrument has a custom lup() (lineup) plan. You could try that instead. If lup() detects a peak, the positioner is moved to the centroid after the scan.

Plot and get statistics

Plot the last three scans together using the plotxy() function. The first argument is a list of the scans to be plotted. Values in this list are references: -1 is the most recent, -2 is the 2nd most recent, -3 is the 2rd most recent. The next two arguments are the names of the x and y data.

plotxy([-3, -2, -1], "m1", "noisy")

The console will show summary statistics computed for each scan, identified by the Scan ID. A plot will appear.

Get the numbers for the last run

run = cat[-1]  # reference the last run in the databroker catalog
dataset = run.primary.read()  # read the data from the primary stream
dataset  # print an overview of the data

With the dataset object, get numpy arrays for each axis.

signal Python
m1 dataset["m1"].values
noisy dataset["noisy"].values

Data files

In the working directory, there is a SPEC data file (202308DD-HHMMSS.dat) with the data for the runs in this session. This file may be re-imported into Python using the spec2nexus package. spec2nexus can also convert this file into a NeXus HDF5 file at your choice.

You can view the HDF5 file using nexpy.

2-D Area Detector

notebook

The adsimdet device simulates a monochrome 1k x 1k image detector using EPICS ADSimDetector. It is preconfigured for use with Bluesky data collection and to write the images to NeXus/HDF5 files. The files are located in a date-stamped subdirectory of /tmp/docker_ioc/iocadN/tmp/adsimdet/YYYY/MM/DD/ (where N is the number of the IOC in your workstation).

The simulation provides a 2-D peak on the area detector. The position and intensity of the peak is dithered randomly using EPICS software running in the background.

Follow this notebook to collect images and find the 2-D center of this peak.

Use punx to print the structure of the HDF5 file, or use nexpy to view the images in a GUI.

Once data acquisition is over, only the databroker package is needed to access data from the catalog. A notebook shows you how to access data after the measurement.