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: β 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.