Review of Bluesky commands#

From APS Python Training for Bluesky Data Acquisition.

Objective

In this notebook, the commands described in the Bluesky Cheat Sheet, are demonstrated using the instrument package.

Start the instrument package#

Our instrument package is in the bluesky subdirectory here so we add that to the search path before importing it.

[1]:
import pathlib, sys
sys.path.append(str(pathlib.Path.home() / "bluesky"))
from instrument.collection import *
/home/prjemian/bluesky/instrument/_iconfig.py
Activating auto-logging. Current session state plus future input saved.
Filename       : /home/prjemian/Documents/projects/BCDA-APS/bluesky_training/docs/source/reference/.logs/ipython_console.log
Mode           : rotate
Output logging : True
Raw input log  : False
Timestamping   : True
State          : active
I Thu-14:38:42 - ############################################################ startup
I Thu-14:38:42 - logging started
I Thu-14:38:42 - logging level = 10
I Thu-14:38:42 - /home/prjemian/bluesky/instrument/session_logs.py
I Thu-14:38:42 - /home/prjemian/bluesky/instrument/collection.py
I Thu-14:38:42 - CONDA_PREFIX = /home/prjemian/.conda/envs/bluesky_2023_2
Exception reporting mode: Minimal
I Thu-14:38:42 - xmode exception level: 'Minimal'
I Thu-14:38:42 - /home/prjemian/bluesky/instrument/mpl/notebook.py
I Thu-14:38:42 - #### Bluesky Framework ####
I Thu-14:38:42 - /home/prjemian/bluesky/instrument/framework/check_python.py
I Thu-14:38:42 - /home/prjemian/bluesky/instrument/framework/check_bluesky.py
I Thu-14:38:42 - /home/prjemian/bluesky/instrument/framework/initialize.py
I Thu-14:38:42 - RunEngine metadata saved in directory: /home/prjemian/Bluesky_RunEngine_md
I Thu-14:38:42 - using databroker catalog 'training'
I Thu-14:38:42 - using ophyd control layer: pyepics
I Thu-14:38:42 - /home/prjemian/bluesky/instrument/framework/metadata.py
I Thu-14:38:42 - /home/prjemian/bluesky/instrument/epics_signal_config.py
I Thu-14:38:42 - Using RunEngine metadata for scan_id
I Thu-14:38:42 - #### Devices ####
I Thu-14:38:42 - /home/prjemian/bluesky/instrument/devices/area_detector.py
I Thu-14:38:42 - /home/prjemian/bluesky/instrument/devices/calculation_records.py
I Thu-14:38:44 - /home/prjemian/bluesky/instrument/devices/fourc_diffractometer.py
I Thu-14:38:44 - /home/prjemian/bluesky/instrument/devices/ioc_stats.py
I Thu-14:38:44 - /home/prjemian/bluesky/instrument/devices/kohzu_monochromator.py
I Thu-14:38:44 - /home/prjemian/bluesky/instrument/devices/motors.py
I Thu-14:38:45 - /home/prjemian/bluesky/instrument/devices/noisy_detector.py
I Thu-14:38:45 - /home/prjemian/bluesky/instrument/devices/scaler.py
I Thu-14:38:46 - /home/prjemian/bluesky/instrument/devices/shutter_simulator.py
I Thu-14:38:46 - /home/prjemian/bluesky/instrument/devices/simulated_fourc.py
I Thu-14:38:46 - /home/prjemian/bluesky/instrument/devices/simulated_kappa.py
I Thu-14:38:46 - /home/prjemian/bluesky/instrument/devices/slits.py
I Thu-14:38:46 - /home/prjemian/bluesky/instrument/devices/sixc_diffractometer.py
I Thu-14:38:46 - /home/prjemian/bluesky/instrument/devices/temperature_signal.py
I Thu-14:38:46 - #### Callbacks ####
I Thu-14:38:46 - /home/prjemian/bluesky/instrument/callbacks/spec_data_file_writer.py
I Thu-14:38:46 - #### Plans ####
I Thu-14:38:46 - /home/prjemian/bluesky/instrument/plans/lup_plan.py
I Thu-14:38:46 - /home/prjemian/bluesky/instrument/plans/peak_finder_example.py
I Thu-14:38:46 - /home/prjemian/bluesky/instrument/utils/image_analysis.py
I Thu-14:38:46 - #### Utilities ####
I Thu-14:38:46 - writing to SPEC file: /home/prjemian/Documents/projects/BCDA-APS/bluesky_training/docs/source/reference/20230413-143846.dat
I Thu-14:38:46 -    >>>>   Using default SPEC file name   <<<<
I Thu-14:38:46 -    file will be created when bluesky ends its next scan
I Thu-14:38:46 -    to change SPEC file, use command:   newSpecFile('title')
I Thu-14:38:46 - #### Startup is complete. ####

List, Describe, Summary#

On the command line, there is an IPython magic command from the bluesky package to print the current value of labeled items: %wa

[2]:
%wa
area_detector
  Local variable name                    Ophyd name (to be recorded as metadata)
  adsimdet                               adsimdet

motor
  Positioner                     Value       Low Limit   High Limit  Offset
  dcm_m_theta                    0.0         -1000.0     1000.0      0.0
  dcm_m_y                        0.0         -1000.0     1000.0      0.0
  dcm_m_z                        0.0         -1000.0     1000.0      0.0
  fourc_chi                      0.0         -1000.0     1000.0      0.0
  fourc_omega                    0.0         -1000.0     1000.0      0.0
  fourc_phi                      0.0         -1000.0     1000.0      0.0
  fourc_tth                      0.0         -1000.0     1000.0      0.0
  m1                             1.0         -1000.0     1000.0      0.0
  m10                            0.0         -1000.0     1000.0      0.0
  m11                            0.0         -1000.0     1000.0      0.0
  m12                            0.0         -1000.0     1000.0      0.0
  m13                            0.0         -1000.0     1000.0      0.0
  m14                            0.0         -1000.0     1000.0      0.0
  m15                            0.0         -1000.0     1000.0      0.0
  m16                            0.0         -1000.0     1000.0      0.0
  m2                             6.0         -1000.0     1000.0      0.0
  m3                             0.0         -1000.0     1000.0      0.0
  m4                             0.0         -1000.0     1000.0      0.0
  m7                             0.0         -1000.0     1000.0      0.0
  m8                             0.0         -1000.0     1000.0      0.0
  m9                             0.0         -1000.0     1000.0      0.0
  sixc_chi                       0.0         -1000.0     1000.0      0.0
  sixc_delta                     0.0         -1000.0     1000.0      0.0
  sixc_gamma                     0.0         -1000.0     1000.0      0.0
  sixc_mu                        0.0         -1000.0     1000.0      0.0
  sixc_omega                     0.0         -1000.0     1000.0      0.0
  sixc_phi                       0.0         -1000.0     1000.0      0.0

  Local variable name                    Ophyd name (to be recorded as metadata)
  dcm.m_theta                            dcm_m_theta
  dcm.m_y                                dcm_m_y
  dcm.m_z                                dcm_m_z
  fourc.chi                              fourc_chi
  fourc.omega                            fourc_omega
  fourc.phi                              fourc_phi
  fourc.tth                              fourc_tth
  m1                                     m1
  m10                                    m10
  m11                                    m11
  m12                                    m12
  m13                                    m13
  m14                                    m14
  m15                                    m15
  m16                                    m16
  m2                                     m2
  m3                                     m3
  m4                                     m4
  m7                                     m7
  m8                                     m8
  m9                                     m9
  sixc.chi                               sixc_chi
  sixc.delta                             sixc_delta
  sixc.gamma                             sixc_gamma
  sixc.mu                                sixc_mu
  sixc.omega                             sixc_omega
  sixc.phi                               sixc_phi

detectors
  Local variable name                    Ophyd name (to be recorded as metadata)
  noisy                                  noisy
  scaler1                                scaler1

simulator
  Local variable name                    Ophyd name (to be recorded as metadata)
  noisy                                  noisy

scalers
  Local variable name                    Ophyd name (to be recorded as metadata)
  scaler1                                scaler1

counter
  Local variable name                    Ophyd name (to be recorded as metadata)
  I0                                     I0
  I00                                    I00
  I000                                   I000
  diode                                  scint
  scaler1.channels.chan01.s              timebase
  scaler1.channels.chan02.s              I0
  scaler1.channels.chan04.s              scint
  scaler1.channels.chan05.s              I000
  scaler1.channels.chan06.s              I00
  scint                                  scint
  timebase                               timebase

channel
  Local variable name                    Ophyd name (to be recorded as metadata)
  I0                                     I0
  I00                                    I00
  I000                                   I000
  diode                                  scint
  scaler1.channels.chan01.s              timebase
  scaler1.channels.chan02.s              I0
  scaler1.channels.chan04.s              scint
  scaler1.channels.chan05.s              I000
  scaler1.channels.chan06.s              I00
  scint                                  scint
  timebase                               timebase

shutters
  Local variable name                    Ophyd name (to be recorded as metadata)
  shutter                                shutter

Might be a good idea to know now what ophyd symbols are available. The apstools package provides a listobjects() command that prints a table of all the known objects (in the global namespace of the session). The columns provide the ophyd name (the name you use to call this in Python), the name of the ophyd structure, the EPICS PV (if relevant), and any labels (as used in %wa above).

[3]:
listobjects()
[3]:
=========== ================================ ============== ===================
name        class                            PV (or prefix) label(s)
=========== ================================ ============== ===================
I0          EpicsSignalRO                    gp:scaler1.S2  counter channel
I00         EpicsSignalRO                    gp:scaler1.S6  counter channel
I000        EpicsSignalRO                    gp:scaler1.S5  counter channel
adsimdet    SimDetector_V34                  ad:            area_detector
calcouts    UserCalcoutDevice                gp:
calcs       UserCalcsDevice                  gp:
dcm         MyKohzu                          gp:
diode       EpicsSignalRO                    gp:scaler1.S4  counter channel
fourc       FourCircle                       gp:
gp_stats    IocInfoDevice                    gp:
m1          MyEpicsMotor                     gp:m1          motor
m10         MyEpicsMotor                     gp:m10         motor
m11         MyEpicsMotor                     gp:m11         motor
m12         MyEpicsMotor                     gp:m12         motor
m13         MyEpicsMotor                     gp:m13         motor
m14         MyEpicsMotor                     gp:m14         motor
m15         MyEpicsMotor                     gp:m15         motor
m16         MyEpicsMotor                     gp:m16         motor
m2          MyEpicsMotor                     gp:m2          motor
m3          MyEpicsMotor                     gp:m3          motor
m4          MyEpicsMotor                     gp:m4          motor
m7          MyEpicsMotor                     gp:m7          motor
m8          MyEpicsMotor                     gp:m8          motor
m9          MyEpicsMotor                     gp:m9          motor
noisy       EpicsSignalRO                    gp:userCalc1   detectors simulator
scaler1     ScalerCH                         gp:scaler1     detectors scalers
scint       EpicsSignalRO                    gp:scaler1.S3  counter channel
shutter     SimulatedApsPssShutterWithStatus                shutters
sim4c       SimulatedE4CV
simk4c      SimulatedK4CV
simk6c      SimulatedK6C
sixc        SixCircle                        gp:
slit1       Optics2Slit2D_HV                 gp:Slit1
temperature MyPvPositioner                   gp:userCalc8
timebase    EpicsSignalRO                    gp:scaler1.S1  counter channel
=========== ================================ ============== ===================

Read#

We’ll use the temperature and m1 objects to demonstrate the various commands described in the cheat sheet

command

description

OBJECT.summary()

more information about OBJECT

OBJECT.get()

low-level command to show value of ophyd Signal named OBJECT

OBJECT.read()

data acquisition command, includes timestamp

listdevice(OBJECT)

table-version of .read()

MOTOR.position

get readback, only for motor objects

MOTOR.user_readback.get()

alternative to MOTOR.position

temperature#

[4]:
temperature.summary()
data keys (* hints)
-------------------
*temperature
 temperature_calculation
 temperature_description
 temperature_done
 temperature_max_change
 temperature_noise
 temperature_previous_value_pv
 temperature_scanning_rate
 temperature_setpoint
 temperature_tolerance

read attrs
----------
setpoint             EpicsSignal         ('temperature_setpoint')
readback             EpicsSignal         ('temperature')
done                 Signal              ('temperature_done')
calculation          EpicsSignal         ('temperature_calculation')
description          EpicsSignal         ('temperature_description')
max_change           EpicsSignal         ('temperature_max_change')
noise                EpicsSignal         ('temperature_noise')
previous_value_pv    EpicsSignal         ('temperature_previous_value_pv')
scanning_rate        EpicsSignal         ('temperature_scanning_rate')
tolerance            EpicsSignal         ('temperature_tolerance')

config keys
-----------

configuration attrs
-------------------

unused attrs
------------
report_dmov_changes  Signal              ('temperature_report_dmov_changes')

[5]:
temperature.readback.get()
[5]:
25.0
[6]:
temperature.read()
[6]:
OrderedDict([('temperature_setpoint',
              {'value': 25.0, 'timestamp': 1681414726.718176}),
             ('temperature', {'value': 25.0, 'timestamp': 1681414726.721922}),
             ('temperature_done',
              {'value': True, 'timestamp': 1681414726.7284272}),
             ('temperature_calculation',
              {'value': 'A+max(-D,min(D,(B-A)))+C*(RNDM-0.5)',
               'timestamp': 1681414726.723668}),
             ('temperature_description',
              {'value': 'temperature', 'timestamp': 1681414726.716164}),
             ('temperature_max_change',
              {'value': 2.0, 'timestamp': 1681414726.7226}),
             ('temperature_noise',
              {'value': 1.0, 'timestamp': 1681414726.721922}),
             ('temperature_previous_value_pv',
              {'value': 'gp:userCalc8.VAL', 'timestamp': 1681414726.716164}),
             ('temperature_scanning_rate',
              {'value': 5, 'timestamp': 1681414726.723668}),
             ('temperature_tolerance',
              {'value': 1.0, 'timestamp': 1681414726.723668})])
[7]:
listdevice(temperature)
[7]:
=============================== =================================== ==========================
data name                       value                               timestamp
=============================== =================================== ==========================
temperature_setpoint            25.0                                2023-04-13 14:38:46.718176
temperature                     25.0                                2023-04-13 14:38:46.721922
temperature_done                True                                2023-04-13 14:38:46.728427
temperature_calculation         A+max(-D,min(D,(B-A)))+C*(RNDM-0.5) 2023-04-13 14:38:46.723668
temperature_description         temperature                         2023-04-13 14:38:46.716164
temperature_max_change          2.0                                 2023-04-13 14:38:46.722600
temperature_noise               1.0                                 2023-04-13 14:38:46.721922
temperature_previous_value_pv   gp:userCalc8.VAL                    2023-04-13 14:38:46.716164
temperature_scanning_rate       5                                   2023-04-13 14:38:46.723668
temperature_tolerance           1.0                                 2023-04-13 14:38:46.723668
temperature_report_dmov_changes False                               2023-04-13 14:38:46.717620
=============================== =================================== ==========================

motor#

[8]:
m1.position
[8]:
1.0
[9]:
m1.user_readback.get()
[9]:
1.0

Move#

command

mode

description

%mov MOTOR value

command line

interactive command move MOTOR to value (command line only)

%movr MOTOR value

command line

interactive command relative move (command line only)

MOTOR.move(value)

ophyd command

%mov

MOTOR.user_setpoint.put(value)

ophyd

set motor .VAL field but not wait

bps.mv(MOTOR, value)

bluesky plan

move and wait for completion

bps.mv(MOTOR.user_setpoint, value)

bluesky plan

same

bps.mvr(MOTOR, value)

bluesky plan

relative move

[10]:
%mov m1 1.55
m1.position
m1:  35%|█████████▎                 | 0.1905/0.55 [00:00<00:00,  1.71degrees/s]
m1:  70%|███████████████████        | 0.3873/0.55 [00:00<00:00,  1.83degrees/s]
m1:  94%|█████████████████████████▎ | 0.5158/0.55 [00:00<00:00,  1.64degrees/s]
m1: 100%|█████████████████████████████| 0.55/0.55 [00:00<00:00,  1.33degrees/s]
m1 [In progress. No progress bar available.]

[10]:
1.55
[11]:
%movr m1 -.1
m1.position
m1: 100%|███████████████████████████▉| 0.0999/0.1 [00:00<00:00,  1.63s/degrees]
m1: 100%|███████████████████████████████| 0.1/0.1 [00:00<00:00,  2.63s/degrees]
m1 [In progress. No progress bar available.]

[11]:
1.4500000000000002
[12]:
m1.move(.5)
m1.position
[12]:
0.5
[13]:
m1.user_setpoint.put(0)
m1.position, m1.user_setpoint.get()
[13]:
(0.5, 0.0)
[14]:
%mov temperature 26

temperature:  58%|█████████████▊          | 0.396/0.687 [00:01<00:00,  2.78s/C]
temperature [In progress. No progress bar available.]

[15]:
%movr temperature -1  m1 .2
temperature.position, m1.position
m1:  81%|██████████████████████▌     | 0.1616/0.2 [00:00<00:00,  1.27degrees/s]

m1: 100%|███████████████████████████████| 0.2/0.2 [00:00<00:00,  1.15s/degrees]

m1 [In progress. No progress bar available.]

m1 [In progress. No progress bar available.]
temperature: 100%|████████████████████████████| 1.0/1.0 [00:01<00:00,  1.93s/C]
m1 [In progress. No progress bar available.]
temperature [In progress. No progress bar available.]


[15]:
(24.23994811932555, 0.2)

bluesky#

[16]:
RE(bps.mv(m1, 1))
m1.position
[16]:
1.0
[17]:
RE(bps.mvr(m1, .1))
m1.position
[17]:
1.1
[18]:
RE(bps.mv(m1.user_setpoint, 1, temperature.setpoint, 25))
m1.position, temperature.position
[18]:
(1.1, 24.23994811932555)

Count#

command

description

%ct

count all objects with label detectors and format output (command line only)

SCALER.trigger().wait(); SCALER.read()

ophyd command to count SCALER

bp.count([SCALER])

bluesky plan to count

Count time setting is different for various types of detectors:

detector

set count time

scaler

SCALER.preset_time.put(COUNT_TIME_S)

area detector

AD.cam.acquire_time.put(COUNT_TIME_S)

[19]:
%ct
[This data will not be saved. Use the RunEngine to collect data.]
noisy                          34560.47582292199
timebase                       16000000.0
I0                             9.0
scint                          6.0
I000                           8.0
I00                            5.0
roi1                           7.0
scaler1_time                   1.6
[20]:
%ct scalers
[This data will not be saved. Use the RunEngine to collect data.]
timebase                       16000000.0
I0                             8.0
scint                          4.0
I000                           9.0
I00                            9.0
roi1                           8.0
scaler1_time                   1.6
[21]:
scaler1.trigger().wait(); scaler1.read()
[21]:
OrderedDict([('timebase',
              {'value': 16000000.0, 'timestamp': 1681414738.568649}),
             ('I0', {'value': 7.0, 'timestamp': 1681414738.568649}),
             ('scint', {'value': 7.0, 'timestamp': 1681414738.568649}),
             ('I000', {'value': 7.0, 'timestamp': 1681414738.568649}),
             ('I00', {'value': 7.0, 'timestamp': 1681414738.568649}),
             ('roi1', {'value': 5.0, 'timestamp': 1681414738.568649}),
             ('scaler1_time', {'value': 1.6, 'timestamp': 1681414736.984263})])
[22]:
RE(bp.count([scaler1]))


Transient Scan ID: 935     Time: 2023-04-13 14:38:58
Persistent Unique Scan ID: '8cfb6fe7-0338-42af-9288-b3c4e2c7cb63'
New stream: 'label_start_motor'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+------------+
|   seq_num |       time |   timebase |         I0 |      scint |       I000 |        I00 |       roi1 |
+-----------+------------+------------+------------+------------+------------+------------+------------+
|         1 | 14:39:00.5 |   16000000 |          8 |          9 |          8 |          8 |          9 |
+-----------+------------+------------+------------+------------+------------+------------+------------+
generator count ['8cfb6fe7'] (scan num: 935)
[22]:
('8cfb6fe7-0338-42af-9288-b3c4e2c7cb63',)
[23]:
def my_plan():
    yield from bp.count([scaler1])

RE(my_plan())


Transient Scan ID: 936     Time: 2023-04-13 14:39:00
Persistent Unique Scan ID: '3718e73c-d07a-4591-a41d-5979c3cd1b66'
New stream: 'label_start_motor'
New stream: 'primary'
+-----------+------------+------------+------------+------------+------------+------------+------------+
|   seq_num |       time |   timebase |         I0 |      scint |       I000 |        I00 |       roi1 |
+-----------+------------+------------+------------+------------+------------+------------+------------+
|         1 | 14:39:02.5 |   16000000 |          7 |          7 |          8 |          8 |          7 |
+-----------+------------+------------+------------+------------+------------+------------+------------+
generator count ['3718e73c'] (scan num: 936)
[23]:
('3718e73c-d07a-4591-a41d-5979c3cd1b66',)