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 |
---|---|
|
more information about |
|
low-level command to show value of ophyd Signal named |
|
data acquisition command, includes timestamp |
|
table-version of |
|
get readback, only for motor objects |
|
alternative to |
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 |
---|---|---|
|
command line |
interactive command move MOTOR to value (command line only) |
|
command line |
interactive command relative move (command line only) |
|
ophyd command |
|
|
ophyd |
set motor |
|
bluesky plan |
move and wait for completion |
|
bluesky plan |
same |
|
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 |
---|---|
|
count all objects with label |
|
ophyd command to count SCALER |
|
bluesky plan to count |
Count time setting is different for various types of detectors:
detector |
set count time |
---|---|
scaler |
|
area detector |
|
[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',)