Example

Refer to the following examples to get started with spectra-ui.

Python Script Examples

The following python scripts instruct the usage of the classes and functions in spectra-ui to set the parameters and configurations and how to visualize the results of pre- and post-processing. The sample files are available here.

In the 1st example, SPECTRA is launched in the interactive mode with the Chrome browser, and the calculation of spectrum is repeated at three different transverse positions. Then, the results are plotted to see how the spectral profile changes as the observation position. Finally, the comparative data is exported as an ASCII file.

Example 1

  • calculate spectra of undulator radiation with three different observation positions

  • compare the three in the post-processor and export an ASCII file

import sys
isjupyter = "ipykernel" in sys.modules

import spectra
if isjupyter:
    # start with CLI mode
    spectra.Start(mode="c")
    import plotly.io as pio
    pio.renderers.default = "notebook" # to enable exporting as an HTML file
else:
    # start with default settings
    # Mode = interactive, Browser = Chrome, Source Files = remote
    spectra.Start()

# open "sample.json" in the current directory
spectra.Open("sample.json")

if isjupyter:
    # display the parameters
    from IPython.display import display, HTML
    display(HTML("<h2> Parameters and configurations"))
    spectra.DisplayParameters(fontfamily="arial", fontsize="10px")

# select calculation: "Far Field & Ideal Condition::Energy Dependence::Angular Flux Density"
spectra.SelectCalculation("far", "energy", "fdensa")

# start calculation with an output file of "./output/sample1-1.json"
spectra.StartCalculation(folder="./output", prefix="sample1", serial=1)

# check the result; plot the spectrum of angular flux density
if isjupyter:
    display(HTML("<h2> Example of undulator-radiation spectrum"))
    spectra.PostProcessCLI.Plot(item="Flux Density")
else:
    spectra.ShowPostProcessor()

# change the paramter, vertical position shifted to y=1mm
spectra.Set("config", "xyfix", [0, 1])

# start calculation with an output file of "sample1-2.json"
# same folder and prefix
# serial number automatically incremented
spectra.StartCalculation()

# horizontal position shifted to x=1mm; output file "sample1-3.json"
spectra.Set("config", "xyfix", [1, 0])
spectra.StartCalculation()

# check the result; compare with the former result
if isjupyter:
    display(HTML("<h2> Comparison between three different observation positions"))
    spectra.PostProcessCLI.Plot(data=["sample1-1", "sample1-2", "sample1-3"], item="Flux Density")
    spectra.PostProcessCLI.Plot(data=["sample1-1", "sample1-2", "sample1-3"], item="Flux Density", xrange=[5000,6500])
else:
    spectra.PostProcess.SelectData("sample1-1")
    spectra.PostProcess.ComparativePlot("sample1-2", "sample1-3")
    spectra.PostProcess.DuplicatePlot()
    # export the comparative plot as an ASCII file
    spectra.PostProcess.Export("./output/comparative.txt")

    # expand the fundamental radiation
    spectra.PostProcess.PlotRange(x=[5000,6500])

if not isjupyter:
    # wait for the user's response
    input("Completed. Press enter to exit. ")
# exit
spectra.Exit()

Example 2

  • plot betatron functions in the pre-processor and export as an ASCII file

  • calculate spectra of BM radiation with two different magnetic strengths

import sys
isjupyter = "ipykernel" in sys.modules

import spectra
if isjupyter:
    spectra.Start(mode="c")
    import plotly.io as pio
    pio.renderers.default = "notebook"
else:
    spectra.Start(src="l")

# open "std.json" in the current directory
spectra.Open("sample.json")

# switch to BM beamline
spectra.SelectBL("BM-BL")

# try pre-processing: betatron functions
if  isjupyter:
    from IPython.display import display, HTML
    display(HTML("<h2>Pre-Processing example: &beta; function"))
spectra.PreProcess.Plot("betatron Functions")

if not isjupyter:
    # export the pre-processing result
    spectra.PreProcess.Export("./output/beta.txt")

# select calculation: "Far Field & Ideal Condition::Energy Dependence::Partial Flux::Rectangular Slit"
spectra.SelectCalculation("far", "energy", "pflux", "slitrect")

# start calculation with an output file of "./ouutput/sample2-1.json"
spectra.StartCalculation(folder="./output", prefix="sample2", serial=1)

# check the result; plot the spectrum of angular flux density
if  isjupyter:
    display(HTML("<h2>Spectrum of bending magnet radiation"))
    spectra.PostProcessCLI.Plot(item="Flux")
else:
    spectra.ShowPostProcessor()

# enhance the magnetic field (1 Tesla)
spectra.Set("src", "b", 1)

# start calculation with an output file of "sample2-2.json"
spectra.StartCalculation(prefix="sample2")

# check the result; compare with the former result
if  isjupyter:
    display(HTML("<h2>Comparison with a stronger-field condition"))
    spectra.PostProcessCLI.Plot(data=["sample2-2", "sample2-1"], item="Flux")
else:
    spectra.ShowPostProcessor()
    spectra.PostProcess.ComparativePlot("sample2-1")

if not isjupyter:
    input("Completed. Press enter to exit. ")
spectra.Exit()

Example 3

  • calculate brilliance curves of 4 different BLs for comparison

import sys
isjupyter = "ipykernel" in sys.modules

import spectra
if isjupyter:
    spectra.Start(mode="c")
    import plotly.io as pio
    pio.renderers.default = "notebook"
else:
    spectra.Start(src="l")

spectra.Open("sample.json")

ublnames = ["SX-BL", "X-ray-BL"]
bmblnames = ["BM-BL", "Wiggler-BL"]

# brilliance curve for undulator beamlines
for ubl in ublnames:
    spectra.SelectBL(ubl)
    spectra.SelectCalculation("far", "Kvalue", "simpcalc", "allharm")
    spectra.StartCalculation(folder="./output", prefix=ubl, serial=-1)

# spectrum for BM/Wiggler beamlines
for bmbl in bmblnames:
    spectra.SelectBL(bmbl)
    spectra.SelectCalculation("far", "energy", "simpcalc")
    spectra.StartCalculation(prefix=bmbl, serial=-1)

# compare the brilliance
if isjupyter:
    from IPython.display import display, HTML
    display(HTML("<h2>Brilliance curves for different sources"))
    spectra.ConfigurePlot(xscale="Logarithmic", yscale="Logarithmic")
    spectra.PostProcessCLI.Plot(data=[*ublnames, *bmblnames], item="GA. Brilliance")
else:
    spectra.ShowPostProcessor()
    spectra.PostProcess.Plot("GA. Brilliance")
    spectra.PostProcess.ComparativePlot(*ublnames, *bmblnames)
    spectra.PostProcess.PlotScale(x="log", y="log")

if not isjupyter:
    input("Completed. Press enter to exit. ")
spectra.Exit()

Example 4

  • examine how to improve the numerical accuracy

import sys
isjupyter = "ipykernel" in sys.modules

import spectra
if isjupyter:
    spectra.Start(mode="c")
    import plotly.io as pio
    pio.renderers.default = "notebook"
else:
    spectra.Start(src="l")

spectra.Open("sample.json")
spectra.SelectBL("X-ray-BL")
spectra.SelectCalculation("near", "energy", "pflux", "slitrect")
if not isjupyter:
    spectra.FitWindow()
spectra.Set("src", "e1st", 10000)
spectra.Set("config", "erange", [9000, 11000])

# modify aperture conditions
spectra.Set("config", "slit_dist", 5)
spectra.Set("config", "slitapt", [0.4, 0.4])

spectra.StartCalculation(folder="./output", prefix="sample4", serial=1)

# try to improve the numerical accuracy
spectra.Set("config", "accuracy", "Custom")
# "accinobs" = Integration Step in Transverse Grid (default = 1)
spectra.SetAccuracy("accinobs", 2)
# "acclimobs" = Integration Range in Transverse Grid (default = 1)
spectra.SetAccuracy("acclimobs", 2)
spectra.StartCalculation() # needs a bit more CPU time

# compare the result
if isjupyter:
    from IPython.display import display, HTML
    display(HTML("<h2>Example to improve the calculation accuracy"))
    spectra.PostProcessCLI.Plot(data=["sample4-1", "sample4-2"])
else:
    spectra.ShowPostProcessor()
    spectra.PostProcess.SelectData("sample4-1")
    spectra.PostProcess.ComparativePlot("sample4-2")

if not isjupyter:
    input("Completed. Press enter to exit. ")
spectra.Exit()

Example 5

  • import a data file (magnetic distribution of an undulator)

  • check the phase error and compare with an ideal case

import sys
isjupyter = "ipykernel" in sys.modules

import spectra
if isjupyter:
    spectra.Start(mode="c")
    import plotly.io as pio
    pio.renderers.default = "notebook"
else:
    spectra.Start(src="l")

spectra.Open("sample.json")
spectra.SelectBL("X-ray-BL")
spectra.SelectCalculation("near", "energy", "fdenss")

# calculation with an ideal condition
spectra.StartCalculation(folder="./output", prefix="sample5", serial=1)

# evaluate the effects due to a randome field error
# change the source type
spectra.Set("src", "type", "User Defined")
# set the unit (longitudinal coordinate in m)
spectra.PreProcess.SetUnit("zpos", "m")
# import the undualtor data with a random error
spectra.PreProcess.Import("Field Profile", "uerror_model.dat")

# evaluate the electron orbit and phase error
if isjupyter:
    from IPython.display import display, HTML
    display(HTML("<h2>Pre-Processing the imported undulator field data"))
spectra.PreProcess.Plot("2nd Integral")
if not isjupyter:
    spectra.PreProcess.DuplicatePlot("Electron Orbit")
spectra.PreProcess.Plot("Phase Error")
if not isjupyter:
    spectra.PreProcess.DuplicatePlot("Phase Error")

# calculation with the error condition
if not isjupyter:
    spectra.ShowMain()
spectra.StartCalculation()

# compare the result
if isjupyter:
    from IPython.display import display, HTML
    display(HTML("<h2>Comparison between the ideal and practical conditions"))
    spectra.ConfigurePlot(yscale="Logarithmic")
    spectra.PostProcessCLI.Plot(data=["sample5-1", "sample5-2"])
else:
    spectra.ShowPostProcessor()
    spectra.PostProcess.SelectData("sample5-1")
    spectra.PostProcess.ComparativePlot("sample5-2")
    spectra.PostProcess.PlotScale(y="log")

if not isjupyter:
    input("Completed. Press enter to exit. ")
spectra.Exit()

Example 6

  • scan a parameter and visualize the result as an animation in the post-processor

  • variation of the spatial profile as the change of the photon energy

import sys
isjupyter = "ipykernel" in sys.modules

import spectra
if isjupyter:
    spectra.Start(mode="c")
    import plotly.io as pio
    pio.renderers.default = "notebook"
else:
    spectra.Start(src="l")

spectra.Open("sample.json")
spectra.SelectBL("X-ray-BL")

# flux spatial profile
spectra.SelectCalculation("far", "spatial", "fdensa", "meshxy")

# define the photon energy by the normalized value (by e1st)
spectra.Set("config", "normenergy", True)

# expand the observation range
spectra.Set("config", "xrange", [-1.5, 1.5])
spectra.Set("config", "yrange", [-1.5, 1.5])

# scan the photon energy to observe
spectra.Scan("config", "nefix", 0.9, 1.05, 21, folder="./output", prefix="sample6", serial=-1)

# visualize the results
if isjupyter:
    from IPython.display import display, HTML
    display(HTML("<h2>Animation to show how the spatial profile changes"))
    spectra.ConfigurePlot(normalize="For Each", type2d="Surface (Color Map)")
    spectra.PostProcessCLI.Plot()
else:
    spectra.PostProcess.SurfacePlot()
    spectra.PostProcess.NormalizePlot(True)
    spectra.PostProcess.StartAnimation()

if not isjupyter:
    input("Completed. Press enter to exit. ")
spectra.Exit()

Example 7

  • run SPECTRA without GUI

  • calculate radiation power after transmitting various filters

import sys
isjupyter = "ipykernel" in sys.modules

import spectra

# start without GUI (CLI mode)
spectra.Start(mode="c")

spectra.Open("sample.json")
spectra.SelectBL("X-ray-BL")

# partial power through 1x1mm^2 FE  slit
spectra.SelectCalculation("fixed", "far", "ppower", "slitrect")
spectra.Set("config", "slitapt", [1,1])
spectra.StartCalculation(folder="./output", prefix="sample7", serial=-1)
result = spectra.GetResult()

total = ["None", result["Partial Power"]*1000]

spectra.Set("config", "filter", "Generic Filter")

filters = [
    ["Be", 1],
    ["Be", 10],
    ["C", 1],
    ["C", 10],
    ["Al", 1],
    ["Al", 10],
    ["Cu", 1],
    ["Cu", 10],
    ["Pb", 1],
    ["Pb", 10],
]

pp  = []
for filter in filters:
    spectra.Set("config", "fmateri", [filter])
    spectra.StartCalculation()
    result = spectra.GetResult()
    pp.append([*filter, result["Filtered Power"]*1000])

if isjupyter:
    from IPython.display import display, HTML
    htmlc = "<table><caption>Power after various filters</caption>\n"
    htmlc += "<thead><tr><th>Filter Type</th><th>Power (W)</th></tr></thead><tbody>\n"
    htmlc += "<tr><td>{0:5}</td><td>{1:.1f}</td></tr>\n".format(total[0], total[1])
    for item in pp:
        htmlc += "<tr><td>{0:3}{1:.0f}t</td><td>{2:.1f}</td></tr>\n".format(item[0], item[1], item[2])
    htmlc += "</tbody></table>"
    display(HTML(htmlc))
else:
    print("Power (W) after various filters")
    print("{0:5}  {1:6.1f}".format(total[0], total[1]))
    for item in pp:
        print("{0:3}{1:2.0f}t {2:6.1f}".format(item[0], item[1], item[2]))

# exit
spectra.Exit()

Example 8

  • calculate a Wigner function on the vertical (y,’y) phase space

  • load the Wigner function and perform CMD (coherent mode decomposition)

import sys
isjupyter = "ipykernel" in sys.modules

import spectra
if isjupyter:
    spectra.Start(mode="c")
    import plotly.io as pio
    pio.renderers.default = "notebook"
else:
    spectra.Start(src="l")

spectra.Open("sample.json")
spectra.SelectBL("X-ray-BL")

# flux spatial profile
spectra.SelectCalculation("srcpoint", "wigner", "phasespace", "YYpprj")

# transverse range auto configuration
spectra.Set("config", "autot", True)

# compute the Wigner function
spectra.StartCalculation(folder="./output", prefix="sample8", serial=1)

# load the Wigner function for CMD
spectra.LoadWigner4CMD("./output/sample8-1.json")

# export the modal profile with finer grid and wider range
spectra.Set("config", "CMDfld", "JSON")
spectra.Set("config", "fieldrangey", 0.05)
spectra.Set("config", "fieldgridy", 0.0005)

# perform CMD
spectra.StartCalculation(prefix="sample8", serial=2)

# check modal intensity
if isjupyter:
    from IPython.display import display, HTML
    display(HTML("<h2>CMD result: integrated modal flux"))
    spectra.PostProcessCLI.Plot(item="Integrated Modal Flux")
else:
    spectra.ShowPostProcessor()
    spectra.PostProcess.Plot("Integrated Modal Flux")
    spectra.PostProcess.DuplicatePlot("Integrated Modal Flux")

# check modal intensity
if isjupyter:
    display(HTML("<h2>CMD result: spatial profile of each mode"))
    spectra.PostProcessCLI.Plot(type="Modal Profile", item="Modal Amplitude Real")
else:
    spectra.PostProcess.SetDataType("Modal Profile")
    spectra.PostProcess.Plot("Modal Amplitude Real")

if not isjupyter:
    input("Completed. Press enter to exit. ")
spectra.Exit()

Example 9

  • calculate a Wigner function in the 4D phase space

  • verify how the spatial profile varies after a double slit using the Wigner function

import sys
isjupyter = "ipykernel" in sys.modules

import spectra
if isjupyter:
    spectra.Start(mode="c")
    import plotly.io as pio
    pio.renderers.default = "notebook"
else:
    spectra.Start(src="l")

spectra.Open("sample.json")
spectra.SelectBL("X-ray-BL")

# enable parallel computing with multithread
spectra.SetParallel("Multithread", 4)

# flux spatial profile
spectra.SelectCalculation("srcpoint", "wigner", "phasespace", "XXpYYp")

# transverse range auto configuration
spectra.Set("config", "autot", True)

# compute the Wigner function
spectra.StartCalculation(folder="./output", prefix="sample9", serial=1)

# load the Wigner function for CMD
spectra.LoadWigner4Propagation("./output/sample9-1.json")

# horizontally separated double slit
spectra.Set("config", "zrange", [18, 50])
spectra.Set("config", "zmesh", 17)
spectra.Set("config", "optics", "Double Slit")
spectra.Set("config", "optpos", 20)
spectra.Set("config", "aptxy", [0.1, 0.5])
spectra.Set("config", "aptdistxy", [0.3, 0])
spectra.StartCalculation(folder="./output", prefix="sample9", serial=2)

# vertically separated double slit
spectra.Set("config", "aptxy", [0.5, 0.02])
spectra.Set("config", "aptdistxy", [0, 0.06])
spectra.StartCalculation(folder="./output", prefix="sample9", serial=3)

# compare the two results
if isjupyter:
    from IPython.display import display, HTML
    display(HTML("<h2>Wavefront propagation after the horizontal and vertical double slit"))
    spectra.ConfigurePlot(type2d="Contour")
    spectra.PostProcessCLI.Plot(data=["sample9-2", "sample9-3"], xrange=[-0.8,0.8], yrange=[-0.4,0.4])
else:
    spectra.PostProcess.SelectData("sample9-2")
    spectra.PostProcess.ContourPlot()
    spectra.PostProcess.ComparativePlot("sample9-3")
    spectra.PostProcess.ComparativePlotCols(2)
    spectra.PostProcess.PlotRange(x=[-0.8,0.8], y=[-0.4,0.4])
    spectra.PostProcess.NormalizePlot(True)
    spectra.PostProcess.StartAnimation()

if not isjupyter:
    input("Completed. Press enter to exit. ")
spectra.Exit()

Jupyter Output Examples

The above python scripts can be executed in the Jupyter notebook as well; for reference, Jupyter notebook outputs for respective examples are exported as HTML files and are shown below.