SRW Simulations#

This section is based on the TES and ARI beamline examples.

Hint: See the List of predefined simulations in Sirepo for examples of identifiers for different beamlines.

Run “Beamline” SRW simulations#

In this example, we scan the horizontal size of the aperture and collect the resulting averaged intensities and corresponding 2D intensity distributions from the “Watchpoint” report on the “Beamline” page of the Sirepo/SRW app.

Start ipython and run the following where sim_id is the UID for the simulation we are working with:

[1]:
from sirepo_bluesky import prepare_re_env

%run -i $prepare_re_env.__file__

from sirepo_bluesky.sirepo_bluesky import SirepoBluesky
from sirepo_bluesky.sirepo_ophyd import create_classes

connection = SirepoBluesky("http://localhost:8000")

data, schema = connection.auth("srw", sim_id="00000002")
classes, objects = create_classes(connection=connection)
globals().update(**objects)

aperture.horizontalSize.kind = "hinted"
w9.duration.kind = "hinted"

(uid,) = RE(bp.scan([w9], aperture.horizontalSize, 0, 2, 6))

hdr = db[uid]
tbl = hdr.table(fill=True)
print(tbl)

w9_image = np.array(list(hdr.data("w9_image")))


Transient Scan ID: 1     Time: 2023-08-19 16:57:34
Persistent Unique Scan ID: '6126f53f-40fc-49e4-9fa7-c3621d03e520'
New stream: 'primary'
+-----------+------------+-------------------------+-------------+------------+
|   seq_num |       time | aperture_horizontalSize | w9_duration |    w9_flux |
+-----------+------------+-------------------------+-------------+------------+
|         1 | 16:58:03.0 |                   0.000 |      28.225 |      0.000 |
|         2 | 16:58:30.5 |                   0.400 |      27.304 | 18526369890570088.000 |
|         3 | 16:58:58.0 |                   0.800 |      27.310 | 875180761407870848.000 |
|         4 | 16:59:25.5 |                   1.200 |      27.312 | 2835215383578687488.000 |
|         5 | 16:59:53.1 |                   1.600 |      27.319 | 6790620360429310976.000 |
|         6 | 17:00:20.6 |                   2.000 |      27.397 | 13986015521742526464.000 |
+-----------+------------+-------------------------+-------------+------------+
generator scan ['6126f53f'] (scan num: 1)



                                 time  aperture_horizontalSize  \
seq_num
1       2023-08-19 16:58:03.096503496                      0.0
2       2023-08-19 16:58:30.599914789                      0.4
3       2023-08-19 16:58:58.099466085                      0.8
4       2023-08-19 16:59:25.595795631                      1.2
5       2023-08-19 16:59:53.104821920                      1.6
6       2023-08-19 17:00:20.696308136                      2.0

                                       w9_sirepo_data_json  \
seq_num
1        {"models": {"arbitraryMagField": {"interpolati...
2        {"models": {"arbitraryMagField": {"interpolati...
3        {"models": {"arbitraryMagField": {"interpolati...
4        {"models": {"arbitraryMagField": {"interpolati...
5        {"models": {"arbitraryMagField": {"interpolati...
6        {"models": {"arbitraryMagField": {"interpolati...

                                       w9_sirepo_data_hash  w9_duration  \
seq_num
1        047eb85878c27c3165864c4e7fc180d5b399dbbd0e8801...    28.224578
2        89764dace87dcc26f52d9089cd083808d4ce01101cdd2e...    27.304115
3        1256afb97668467b0ff356a3135da3a54769bc0722bf06...    27.309898
4        27a64c6a971fa63b9d8225532d332e9f5dc81fc98b5492...    27.312175
5        5c33991278d7a36bc54609343da1932d9b68ac08fbcb2d...    27.319178
6        180a2a6153d01ecbb4d9d805a86a02d2fa5b0c1ca5df82...    27.396652

                                                  w9_image   w9_shape  \
seq_num
1        [[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,...  [42, 960]
2        [[88.9896469116211, 90.30567169189453, 89.9160...  [42, 960]
3        [[259953.59375, 261614.125, 263485.9375, 26631...  [42, 960]
4        [[9238843.0, 9838710.0, 9552324.0, 9303515.0, ...  [42, 960]
5        [[68400960.0, 68992840.0, 69654168.0, 70279808...  [42, 960]
6        [[980697920.0, 1007002496.0, 1032909120.0, 103...  [42, 960]

              w9_flux       w9_mean          w9_x          w9_y  w9_fwhm_x  \
seq_num
1        0.000000e+00  0.000000e+00           NaN           NaN        NaN
2        1.852637e+16  4.594834e+11 -9.046412e-07  2.967016e-07   0.000001
3        8.751808e+17  2.170587e+13 -2.024554e-07  2.583469e-07   0.000001
4        2.835215e+18  7.031784e+13  1.189526e-08  2.134382e-07   0.000002
5        6.790620e+18  1.684182e+14  2.282297e-08  1.655073e-07   0.000002
6        1.398602e+19  3.468754e+14  1.569344e-08  1.041249e-07   0.000002

         w9_fwhm_y  w9_photon_energy  \
seq_num
1              NaN            2500.0
2         0.000010            2500.0
3         0.000010            2500.0
4         0.000009            2500.0
5         0.000008            2500.0
6         0.000008            2500.0

                                      w9_horizontal_extent  \
seq_num
1        [-2.1254114436366436e-06, -9.098470371627117e-07]
2         [-0.0003455044933673651, 0.00034048111593430996]
3          [-9.497909538938273e-05, 9.223270409422599e-05]
4         [-4.719082396641057e-05, 4.4254846231433526e-05]
5          [-2.815987725485224e-05, 2.514591016781304e-05]
6         [-1.880166558286725e-05, 1.5761422775379623e-05]

                                        w9_vertical_extent  w9_id w9_title  \
seq_num
1           [-6.735306985152392e-07, 6.90416995865796e-07]   15.0       W9
2        [-1.7898270041274756e-05, 1.7460512118472577e-05]   15.0       W9
3          [-1.788263286486139e-05, 1.744525739789714e-05]   15.0       W9
4         [-1.737099036964788e-05, 1.6946128712979616e-05]   15.0       W9
5        [-1.6659548548370817e-05, 1.6252087416622406e-05]   15.0       W9
6          [-1.556055992165305e-05, 1.517997797863667e-05]   15.0       W9

        w9_type  w9_element_position
seq_num
1         watch               57.142
2         watch               57.142
3         watch               57.142
4         watch               57.142
5         watch               57.142
6         watch               57.142
../_images/notebooks_srw_3_1.png
[2]:
from mpl_toolkits.axes_grid1 import ImageGrid

print(f"Data shape: {w9_image.shape}")
num_frames = w9_image.shape[0]
ncols = 2
nrows = int(np.ceil(num_frames / ncols))

fig = plt.figure()
grid = ImageGrid(
    fig,
    (1, 2, ncols, nrows),
    nrows_ncols=(nrows, ncols),
    axes_pad=0.5,
    aspect=False,
)

for ax, im in zip(grid, w9_image[:, ...]):
    ax.imshow(im, aspect="auto")
Data shape: (6, 42, 960)
../_images/notebooks_srw_4_1.png

SRW Propagation as Ophyd Objects#

This example repeats the above simulation in “Optical Elements as Ophyd Objects”, but instead scans the horizontal and vertical resolution modification factors of the “Final Post Propagation” on the “Beamline” page of the Sirepo/SRW app.

Hint: See the “SRW Propagation Parameters” wiki page for a list of available propagation parameters.

[3]:
from sirepo_bluesky import prepare_re_env

%run -i $prepare_re_env.__file__

from sirepo_bluesky.sirepo_bluesky import SirepoBluesky
from sirepo_bluesky.sirepo_ophyd import create_classes

connection = SirepoBluesky("http://localhost:8000")

data, schema = connection.auth("srw", sim_id="00000002")
classes, objects = create_classes(connection=connection)
globals().update(**objects)

post_propagation.hres_mod.kind = "hinted"
post_propagation.vres_mod.kind = "hinted"
w9.duration.kind = "hinted"

(uid,) = RE(
    bp.list_scan(
        [w9],
        post_propagation.hres_mod,
        [0.1, 0.25, 0.5, 1, 2, 5],
        post_propagation.vres_mod,
        [0.1, 0.25, 0.5, 1, 2, 5],
    )
)

hdr = db[uid]
tbl = hdr.table(fill=True)
print(tbl)

w9_image = []
for im in list(hdr.data("w9_image")):
    w9_image.append(im)


Transient Scan ID: 1     Time: 2023-08-19 17:00:23
Persistent Unique Scan ID: 'eea68bd8-ccfa-4974-be88-8662e0ff8a94'
New stream: 'primary'
+-----------+------------+---------------------------+---------------------------+-------------+------------+
|   seq_num |       time | post_propagation_hres_mod | post_propagation_vres_mod | w9_duration |    w9_flux |
+-----------+------------+---------------------------+---------------------------+-------------+------------+
|         1 | 17:00:50.1 |                     0.100 |                     0.100 |      26.304 | 1073586585333243904.000 |
|         2 | 17:01:17.5 |                     0.250 |                     0.250 |      27.308 | 9175272414847424512.000 |
|         3 | 17:01:44.0 |                     0.500 |                     0.500 |      26.324 | 34882168960161890304.000 |
|         4 | 17:02:11.6 |                     1.000 |                     1.000 |      27.366 | 135695489249894498304.000 |
|         5 | 17:02:39.6 |                     2.000 |                     2.000 |      27.651 | 548121885006057046016.000 |
|         6 | 17:03:12.8 |                     5.000 |                     5.000 |      31.660 | 3411478534323461160960.000 |
+-----------+------------+---------------------------+---------------------------+-------------+------------+
generator list_scan ['eea68bd8'] (scan num: 1)



                                 time  \
seq_num
1       2023-08-19 17:00:50.134056330
2       2023-08-19 17:01:17.594286442
3       2023-08-19 17:01:44.090910196
4       2023-08-19 17:02:11.650974751
5       2023-08-19 17:02:39.667309046
6       2023-08-19 17:03:12.854381323

                                       w9_sirepo_data_json  \
seq_num
1        {"models": {"arbitraryMagField": {"interpolati...
2        {"models": {"arbitraryMagField": {"interpolati...
3        {"models": {"arbitraryMagField": {"interpolati...
4        {"models": {"arbitraryMagField": {"interpolati...
5        {"models": {"arbitraryMagField": {"interpolati...
6        {"models": {"arbitraryMagField": {"interpolati...

                                       w9_sirepo_data_hash  w9_duration  \
seq_num
1        444ff37a841f1eae5e760102e175dc700123f10466d9ab...    26.304120
2        ea9b1201ec7bfbd1b4b2e9bd5f9f6c3631ad953c85aebf...    27.307690
3        0fb266f27def0adc59d1ad4610be25219edb661bb6823e...    26.323790
4        5f0866aa47391d345216aa6c4506ebe7de5b1fec2c1a3a...    27.365714
5        f796c332c8b40b67dcd40751ed332ad7ec6499b3f78055...    27.651106
6        ec7b6a8487eabe1007b13f10d6bafe21a5b4a5a42b4db4...    31.659634

                                                  w9_image     w9_shape  \
seq_num
1        [[1721896192.0, 2558392064.0, 4199006208.0, 76...      [4, 96]
2        [[1721896192.0, 2017554816.0, 2349399808.0, 28...    [12, 240]
3        [[1721896192.0, 1859565440.0, 2017218560.0, 21...    [22, 480]
4        [[1729820288.0, 1829252736.0, 1847327872.0, 19...    [42, 960]
5        [[1721896192.0, 1753946112.0, 1798868992.0, 18...   [84, 1920]
6        [[1721896192.0, 1734087168.0, 1747285888.0, 17...  [210, 4752]

              w9_flux       w9_mean          w9_x          w9_y  ...  \
seq_num                                                          ...
1        1.073587e+18  2.795798e+15  1.000970e-08  1.216330e-06  ...
2        9.175272e+18  3.185858e+15  3.416623e-08  9.122925e-07  ...
3        3.488217e+19  3.303236e+15  3.608676e-08  8.955650e-07  ...
4        1.356955e+20  3.365464e+15  3.642247e-08  8.798182e-07  ...
5        5.481219e+20  3.398573e+15  3.638440e-08  8.797063e-07  ...
6        3.411479e+21  3.418589e+15  3.638517e-08  8.763118e-07  ...

         w9_fwhm_y  w9_photon_energy  \
seq_num
1         0.000002            2500.0
2         0.000003            2500.0
3         0.000002            2500.0
4         0.000002            2500.0
5         0.000002            2500.0
6         0.000002            2500.0

                                     w9_horizontal_extent  \
seq_num
1        [-1.539735979953162e-05, 1.2266423752247285e-05]
2        [-1.539735979953162e-05, 1.2266423752247285e-05]
3        [-1.539735979953162e-05, 1.2266423752247285e-05]
4        [-1.552692914676393e-05, 1.2395993099479593e-05]
5        [-1.539735979953162e-05, 1.2266423752247285e-05]
6        [-1.539735979953162e-05, 1.2266423752247285e-05]

                                       w9_vertical_extent w9_id  w9_title  \
seq_num
1        [-3.1233386249489396e-06, 3.200689687176562e-06]  15.0        W9
2        [-3.1233386249489396e-06, 3.200689687176561e-06]  15.0        W9
3        [-3.1233386249489396e-06, 3.200689687176562e-06]  15.0        W9
4         [-3.0852420688517978e-06, 3.16259313107942e-06]  15.0        W9
5        [-3.1233386249489396e-06, 3.200689687176562e-06]  15.0        W9
6        [-3.1233386249489396e-06, 3.200689687176562e-06]  15.0        W9

        w9_type w9_element_position  post_propagation_hres_mod  \
seq_num
1         watch              57.142                       0.10
2         watch              57.142                       0.25
3         watch              57.142                       0.50
4         watch              57.142                       1.00
5         watch              57.142                       2.00
6         watch              57.142                       5.00

         post_propagation_vres_mod
seq_num
1                             0.10
2                             0.25
3                             0.50
4                             1.00
5                             2.00
6                             5.00

[6 rows x 21 columns]
../_images/notebooks_srw_6_1.png
[4]:
from mpl_toolkits.axes_grid1 import ImageGrid

num_frames = len(w9_image)
ncols = 2
nrows = int(np.ceil(num_frames / ncols))

fig = plt.figure()
grid = ImageGrid(
    fig,
    (1, 2, ncols, nrows),
    nrows_ncols=(nrows, ncols),
    axes_pad=0.5,
    aspect=False,
)

for ax, im in zip(grid, w9_image):
    h_dims = 1e6 * w9.horizontal_extent.get()
    v_dims = 1e6 * w9.vertical_extent.get()
    ax.imshow(
        im, interpolation="nearest", aspect="auto", extent=(*h_dims[:], *v_dims[:])
    )
../_images/notebooks_srw_7_0.png

Using Run Engine to Generate Spectrum Reports#

In this example, we scan the vertical amplitude of the undulator’s magnetic field and collect the “Single Electron Spectrum” report from the “Beamline” page of the Sirepo/SRW app. Afterwards, we plot the peaks of the spectra. This section is based on the ARI beamline example.

Hint: See the List of predefined simulations in Sirepo for examples of identifiers for different beamlines.

[5]:
from sirepo_bluesky import prepare_re_env

%run -i $prepare_re_env.__file__

from sirepo_bluesky.sirepo_bluesky import SirepoBluesky
from sirepo_bluesky.sirepo_ophyd import create_classes

connection = SirepoBluesky("http://localhost:8000")

data, schema = connection.auth("srw", sim_id="00000003")
classes, objects = create_classes(
    connection=connection, extra_model_fields=["undulator", "intensityReport"]
)
globals().update(**objects)

undulator.verticalAmplitude.kind = "hinted"
single_electron_spectrum.duration.kind = "hinted"
single_electron_spectrum.flux.kind = "hinted"

single_electron_spectrum.initialEnergy.get()
single_electron_spectrum.initialEnergy.put(20)
single_electron_spectrum.finalEnergy.put(1100)

num_steps = 6

(uid,) = RE(
    bp.scan(
        [single_electron_spectrum],
        undulator.verticalAmplitude,
        0.2,
        1.2,
        num_steps,
    )
)

hdr = db[uid]
tbl = hdr.table()
print(tbl)

ses_data = np.array(list(hdr.data("single_electron_spectrum_image")))
ampl_data = np.array(list(hdr.data("undulator_verticalAmplitude")))


Transient Scan ID: 1     Time: 2023-08-19 17:03:17
Persistent Unique Scan ID: 'f74655bf-9b14-4de9-9c1d-403fc690ed44'
New stream: 'primary'
+-----------+------------+-----------------------------+-----------------------------------+-------------------------------+
|   seq_num |       time | undulator_verticalAmplitude | single_electron_spectrum_duration | single_electron_spectrum_flux |
+-----------+------------+-----------------------------+-----------------------------------+-------------------------------+
|         1 | 17:03:22.2 |                       0.200 |                             4.071 |         11582410813310422.000 |
|         2 | 17:03:26.4 |                       0.400 |                             4.064 |          7511914020931007.000 |
|         3 | 17:03:30.6 |                       0.600 |                             4.062 |          6133644985399308.000 |
|         4 | 17:03:34.8 |                       0.800 |                             4.066 |          5528586337089524.000 |
|         5 | 17:03:39.0 |                       1.000 |                             4.064 |          4389188523218694.000 |
|         6 | 17:03:43.2 |                       1.200 |                             4.069 |          3839228997372156.500 |
+-----------+------------+-----------------------------+-----------------------------------+-------------------------------+
generator scan ['f74655bf'] (scan num: 1)



                                 time  \
seq_num
1       2023-08-19 17:03:22.213392973
2       2023-08-19 17:03:26.425994635
3       2023-08-19 17:03:30.637144804
4       2023-08-19 17:03:34.842891932
5       2023-08-19 17:03:39.060551643
6       2023-08-19 17:03:43.279510736

        single_electron_spectrum_sirepo_data_json  \
seq_num
1
2
3
4
5
6

        single_electron_spectrum_sirepo_data_hash  \
seq_num
1
2
3
4
5
6

         single_electron_spectrum_duration  \
seq_num
1                                 4.070882
2                                 4.064391
3                                 4.062473
4                                 4.065910
5                                 4.063592
6                                 4.068893

                 single_electron_spectrum_image  \
seq_num
1        5fc1661d-78a2-4498-b84f-585d2981c0e3/0
2        19b5a36a-6f35-4587-80a8-44bb085aded4/0
3        d4e2da0a-b428-4c7e-a74e-15dc78661724/0
4        1ef5f3d1-e060-435b-a46f-5fd31065f8ad/0
5        e994ebd9-8ea0-4eff-9ef4-cb6351b775c8/0
6        02208608-2269-4da4-a88d-6e5af0d41f02/0

        single_electron_spectrum_shape  single_electron_spectrum_flux  \
seq_num
1                               [2000]                   1.158241e+16
2                               [2000]                   7.511914e+15
3                               [2000]                   6.133645e+15
4                               [2000]                   5.528586e+15
5                               [2000]                   4.389189e+15
6                               [2000]                   3.839229e+15

         single_electron_spectrum_mean  single_electron_spectrum_x  \
seq_num
1                         5.791205e+12                         NaN
2                         3.755957e+12                         NaN
3                         3.066822e+12                         NaN
4                         2.764293e+12                         NaN
5                         2.194594e+12                         NaN
6                         1.919614e+12                         NaN

         single_electron_spectrum_y  ...  single_electron_spectrum_method  \
seq_num                              ...
1                               NaN  ...                                1
2                               NaN  ...                                1
3                               NaN  ...                                1
4                               NaN  ...                                1
5                               NaN  ...                                1
6                               NaN  ...                                1

         single_electron_spectrum_notes  \
seq_num
1
2
3
4
5
6

        single_electron_spectrum_photonEnergyPointCount  \
seq_num
1                                                2000.0
2                                                2000.0
3                                                2000.0
4                                                2000.0
5                                                2000.0
6                                                2000.0

        single_electron_spectrum_plotScale  \
seq_num
1                                   linear
2                                   linear
3                                   linear
4                                   linear
5                                   linear
6                                   linear

        single_electron_spectrum_polarization  \
seq_num
1                                         6.0
2                                         6.0
3                                         6.0
4                                         6.0
5                                         6.0
6                                         6.0

         single_electron_spectrum_precision  \
seq_num
1                                      0.01
2                                      0.01
3                                      0.01
4                                      0.01
5                                      0.01
6                                      0.01

        single_electron_spectrum_verticalPosition  \
seq_num
1                                             0.0
2                                             0.0
3                                             0.0
4                                             0.0
5                                             0.0
6                                             0.0

         single_electron_spectrum_title single_electron_spectrum_type  \
seq_num
1                SingleElectronSpectrum               intensityReport
2                SingleElectronSpectrum               intensityReport
3                SingleElectronSpectrum               intensityReport
4                SingleElectronSpectrum               intensityReport
5                SingleElectronSpectrum               intensityReport
6                SingleElectronSpectrum               intensityReport

         undulator_verticalAmplitude
seq_num
1                                0.2
2                                0.4
3                                0.6
4                                0.8
5                                1.0
6                                1.2

[6 rows x 31 columns]
../_images/notebooks_srw_9_1.png
[6]:
import peakutils
from mpl_toolkits.axes_grid1 import ImageGrid

ncols = 2
nrows = int(np.ceil((num_steps) / ncols))

fig = plt.figure()
grid = ImageGrid(
    fig,
    (1, 2, ncols, nrows),
    nrows_ncols=(nrows, ncols),
    axes_pad=0.5,
    aspect=False,
)

for i in range(num_steps):
    ax = grid[i]
    ax.grid(True)
    ax.plot(ses_data[i, :])
    peak = peakutils.indexes(ses_data[i, :], thres=0.07)
    ax.scatter(peak, ses_data[i, peak], c="orange")
    ax.set_xlabel("Photon energy [eV]")
    ax.set_ylabel("Intensity [Sirepo units]")
    ax.set_title(
        f"Single-Electron Spectrum at Vertical Magnetic Field = {ampl_data[i]:.1f}T"
    )

plt.figure()
plt.xlabel("Photon energy [eV]")
plt.ylabel("Frame number")
plt.imshow(ses_data, aspect="auto")
[6]:
<matplotlib.image.AxesImage at 0x7fad67f8b160>
../_images/notebooks_srw_10_1.png
../_images/notebooks_srw_10_2.png