Example of python source codes

Refer to the following python source codes to get started with spectra-ui.

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

if __name__ == "__main__":
    import spectra

# start with default settings
# Mode = interactive, Browser = Chrome, Source Files = remote
    spectra.Start()

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

# 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
spectra.PostProcess.Plot("Flux Density")

# 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
spectra.PostProcess.SelectData("sample1-1")
spectra.PostProcess.Plot("Flux Density")
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 __name__ == "__main__":

# 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

if __name__ == "__main__":
    import spectra
# start with local source files
    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
spectra.PreProcess.Plot("betatron Functions")

# 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
spectra.PostProcess.Plot("Flux")

# 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
spectra.PostProcess.Plot("Flux")
spectra.PostProcess.ComparativePlot("sample2-1")

if __name__ == "__main__":
    input("Completed. Press enter to exit. ")
    spectra.Exit()

Example 3

  • calculate brilliance curves of 4 different BLs for comparison

if __name__ == "__main__":
    import spectra
    spectra.Start()

spectra.Open("sample.json")

ublnames = ["X-ray-BL", "SX-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
spectra.PostProcess.SelectData(ublnames[0])
spectra.PostProcess.Plot("GA. Brilliance")
spectra.PostProcess.ComparativePlot(*ublnames, *bmblnames)
spectra.PostProcess.PlotScale(x="log", y="log")

if __name__ == "__main__":
    input("Completed. Press enter to exit. ")
    spectra.Exit()

Example 4

  • examine how to improve the numerical accuracy

if __name__ == "__main__":
    import spectra
    spectra.Start()

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

# expand the aperture to check the accuracy of spatial integration
spectra.Set("config", "slitapt", [2, 2])
spectra.StartCalculation(folder="./output", prefix="sample4", serial=1)

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

# compare the result
spectra.PostProcess.Plot("Flux")
spectra.PostProcess.SelectData("sample4-1")
spectra.PostProcess.ComparativePlot("sample4-2", "sample4-3")

if __name__ == "__main__":
    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 time

if __name__ == "__main__":
    import spectra
    spectra.Start()

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
spectra.PreProcess.Plot("2nd Integral")
spectra.PreProcess.DuplicatePlot("Electron Orbit")
spectra.PreProcess.Plot("Phase Error")
spectra.PreProcess.DuplicatePlot("Phase Error")

# calculation with the error condition
spectra.ShowMain()
spectra.StartCalculation()

# compare the result
spectra.PostProcess.Plot("Flux Density")
spectra.PostProcess.SelectData("sample5-1")
spectra.PostProcess.ComparativePlot("sample5-2")
spectra.PostProcess.PlotScale(y="log")

if __name__ == "__main__":
    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

if __name__ == "__main__":
    import spectra
    spectra.Start()

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
spectra.PostProcess.SurfacePlot()
spectra.PostProcess.NormalizePlot(True)
spectra.PostProcess.StartAnimation()

if __name__ == "__main__":
    input("Completed. Press enter to exit. ")
    spectra.Exit()

Example 7

  • run SPECTRA without GUI

  • calculate the Wigner function (projected on Y-Y’) for different photon energies

  • import and analyze the output result to evaluate the light source performance

  • the result of analysis is printed in console

  • Note: this example does not run in the GUI or interactive mode

import spectra
import math

ONE_ANGSTROM_eV = 12398.4247

def GetSrcSpecs(ep, xy, data):
    wavel = ONE_ANGSTROM_eV/ep/1.0e+10
    Dxy = [0, 0]
    xymesh = [0, 0]
    for j in range(2):
        Dxy[j] = xy[j][1]-xy[j][0]
        xymesh[j] = len(xy[j])

    tf = normxy = size = div = 0
    for n1 in range(xymesh[1]):
        for n0 in range(xymesh[0]):
            index = n1*xymesh[0]+n0
            normxy += data[index]*data[index]*Dxy[0]*Dxy[1]
            tf += data[index]
            size += data[index]*xy[0][n0]*xy[0][n0]
            div += data[index]*xy[1][n1]*xy[1][n1]

    size = math.sqrt(size/tf)
    div = math.sqrt(div/tf)
    tf *= Dxy[0]*Dxy[1]

    normxy *= 1.0e+6 # (/mm/mrad) -> (/m/rad)
    cohdeg = wavel*normxy/tf/tf
    return [ep, tf, size, div, cohdeg]

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

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

# photon density in the vertical phase space (y,y') by Wigner function
spectra.SelectCalculation("srcpoint", "wigner", "phasespace", "YYpprj")

dataname = "sample7"
irange = range(-15, 5)
specs = []
for i in irange:
    detune = i*0.002
    spectra.Set("config", "detune", detune)
    energy = spectra.Get("config", "efix")
    spectra.StartCalculation(folder="./output", prefix=dataname, serial=-1)
    if i == irange[0]:
        axisvar = spectra.CLI.GetAxis(dataname)
        titles = spectra.CLI.GetTitle(dataname)
        units = spectra.CLI.GetUnit(dataname)
    data = spectra.CLI.GetData(dataname, 0)
    specs.append(GetSrcSpecs(energy, axisvar, data))

print("{0:11} {1:10} {2:10} {3:10} {4:10}".\
    format("Energy", "Flux", "Size", "Divergence", "Coherence"))
for spec in specs:
    print(f"{spec[0]:<11.4e} {spec[1]:<10.3e} {spec[2]:<10.3e} {spec[3]:<10.3e} {spec[4]:<10.3e}")

input("Completed. Press enter to exit. ")

# 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)

if __name__ == "__main__":
    import spectra
    spectra.Start()

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
spectra.PostProcess.SetCategory("Modal Flux")
spectra.PostProcess.Plot("Integrated Modal Flux")
spectra.PostProcess.DuplicatePlot("Integrated Modal Flux")

# check modal intensity
spectra.PostProcess.SetCategory("Modal Profile")
spectra.PostProcess.Plot("Modal Amplitude Real")

if __name__ == "__main__":
    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

if __name__ == "__main__":
    import spectra
    spectra.Start()

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

# 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", "aptx", 0.1)
spectra.Set("config", "aptdistx", 0.3)
spectra.Set("config", "apty", 0.5)
spectra.Set("config", "aptdisty", 0)
spectra.StartCalculation(folder="./output", prefix="sample9", serial=2)

# vertically separated double slit
spectra.Set("config", "aptx", 0.5)
spectra.Set("config", "aptdistx", 00)
spectra.Set("config", "apty", 0.02)
spectra.Set("config", "aptdisty", 0.06)
spectra.StartCalculation(folder="./output", prefix="sample9", serial=3)

# compare the two results
spectra.PostProcess.Import("./output/sample9-2.json")
spectra.PostProcess.Import("./output/sample9-3.json")
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 __name__ == "__main__":
    input("Completed. Press enter to exit. ")
    spectra.Exit()