Quickstart¶
InĀ [1]:
Copied!
import matplotlib.pyplot as plt
from genesis.version4 import Genesis4
import genesis.version4 as g4
%config InlineBackend.figure_format = 'retina' # Nicer plots
import matplotlib.pyplot as plt
from genesis.version4 import Genesis4
import genesis.version4 as g4
%config InlineBackend.figure_format = 'retina' # Nicer plots
Load an existing main input file and run Genesis4¶
Load a pre-existing Genesis 4 main input file - "Example 1: Steady State" from Sven's documentation. The lattice file will be determined automatically from its &setup namelist.
InĀ [2]:
Copied!
G = Genesis4("data/example1-steadystate/Example1.in")
G.verbose = True
G = Genesis4("data/example1-steadystate/Example1.in")
G.verbose = True
InĀ [3]:
Copied!
output = G.run()
output = G.run()
Configured to run in: /tmp/tmpwp40ebp2 Running Genesis4 in /tmp/tmpwp40ebp2 /home/runner/miniconda3/envs/lume-genesis-dev/bin/genesis4 -l Example1.lat genesis4.in
--------------------------------------------- GENESIS - Version 4.6.12 has started... Compile info: Compiled by conda at 2026-04-16 21:17:54 [UTC] from Git Commit ID: 0aebc9ac63203f44436686151dfd856526bde43e Starting Time: Wed Apr 22 21:44:05 2026 MPI-Comm Size: 1 node Opened input file genesis4.in Parsing lattice file Example1.lat ... Matching for periodic solution between z = 0 and z = 9.5 : betax (m) : 8.53711 alphax : -0.703306 phix (deg): 45.818 betay (m) : 17.3899 alphay : 1.40348 phiy (deg): 45.818 Generating input radiation field for HARM = 1 ... Generating input particle distribution... Running Core Simulation... Steady-state run Initial analysis of electron beam and radiation field... Calculation: 0% done
Calculation: 10% done
Calculation: 20% done
Calculation: 30% done
Calculation: 40% done
Calculation: 50% done
Calculation: 60% done
Calculation: 70% done
Calculation: 80% done
Calculation: 90% done
Calculation: 100% done Writing output file... Core Simulation done. End of Track Program is terminating... Ending Time: Wed Apr 22 21:44:13 2026 Total Wall Clock Time: 7.13878 seconds ------------------------------------- Success - execution took 8.55s.
LUME-Genesis offers a plotting helpers on the Genesis4 object (and Genesis4Output itself) to work with the output data.
You can specify individual data keys to plot the output data and the layout below.
InĀ [4]:
Copied!
G.plot(["beam_xsize", "beam_ysize", "field_xsize", "field_ysize"])
G.plot(["beam_xsize", "beam_ysize", "field_xsize", "field_ysize"])
InĀ [5]:
Copied!
output.lattice.plot();
output.lattice.plot();
Beam and field sizes¶
InĀ [6]:
Copied!
zplot = output.lattice.zplot
field = output.field
plt.plot(zplot, output.beam.xsize * 1e6, label=r"Beam: $\sigma_x$")
plt.plot(zplot, output.beam.ysize * 1e6, label=r"Beam: $\sigma_y$")
plt.plot(zplot, field.xsize * 1e6, label=r"Field: $\sigma_x$")
plt.plot(zplot, field.ysize * 1e6, label=r"Field: $\sigma_y$")
plt.legend()
plt.xlabel(r"$z$ (m)")
plt.ylabel(r"$\sigma_{x,y}$ ($\mu$m)")
plt.ylim([0, 60])
plt.show()
zplot = output.lattice.zplot
field = output.field
plt.plot(zplot, output.beam.xsize * 1e6, label=r"Beam: $\sigma_x$")
plt.plot(zplot, output.beam.ysize * 1e6, label=r"Beam: $\sigma_y$")
plt.plot(zplot, field.xsize * 1e6, label=r"Field: $\sigma_x$")
plt.plot(zplot, field.ysize * 1e6, label=r"Field: $\sigma_y$")
plt.legend()
plt.xlabel(r"$z$ (m)")
plt.ylabel(r"$\sigma_{x,y}$ ($\mu$m)")
plt.ylim([0, 60])
plt.show()
Make your own input¶
This section replicates the above Genesis 4-format input entirely in Python.
InĀ [7]:
Copied!
main = g4.MainInput(
[
g4.Setup(
rootname="Example1",
beamline="FEL",
gamma0=11357.82,
delz=0.045,
nbins=8,
shotnoise=False,
),
g4.LatticeNamelist(zmatch=9.5),
g4.Field(power=5000.0, waist_size=3e-05, dgrid=0.0002, ngrid=255),
g4.Beam(delgam=1.0, current=3000.0, ex=4e-07, ey=4e-07),
g4.Track(),
],
)
lattice = g4.Lattice(
{
"D1": g4.Drift(L=0.44),
"D2": g4.Drift(L=0.24),
"FEL": g4.Line(elements=["FODO"] * 6),
"FODO": g4.Line(
elements=["UND", "D1", "QF", "D2", "UND", "D1", "QD", "D2"],
),
"QD": g4.Quadrupole(L=0.08, k1=-2.0),
"QF": g4.Quadrupole(L=0.08, k1=2.0),
"UND": g4.Undulator(aw=0.84853, lambdau=0.015, nwig=266, helical=True),
}
)
main = g4.MainInput(
[
g4.Setup(
rootname="Example1",
beamline="FEL",
gamma0=11357.82,
delz=0.045,
nbins=8,
shotnoise=False,
),
g4.LatticeNamelist(zmatch=9.5),
g4.Field(power=5000.0, waist_size=3e-05, dgrid=0.0002, ngrid=255),
g4.Beam(delgam=1.0, current=3000.0, ex=4e-07, ey=4e-07),
g4.Track(),
],
)
lattice = g4.Lattice(
{
"D1": g4.Drift(L=0.44),
"D2": g4.Drift(L=0.24),
"FEL": g4.Line(elements=["FODO"] * 6),
"FODO": g4.Line(
elements=["UND", "D1", "QF", "D2", "UND", "D1", "QD", "D2"],
),
"QD": g4.Quadrupole(L=0.08, k1=-2.0),
"QF": g4.Quadrupole(L=0.08, k1=2.0),
"UND": g4.Undulator(aw=0.84853, lambdau=0.015, nwig=266, helical=True),
}
)
InĀ [8]:
Copied!
G = Genesis4(main, lattice)
G.verbose = True
G = Genesis4(main, lattice)
G.verbose = True
InĀ [9]:
Copied!
output = G.run()
output = G.run()
Configured to run in: /tmp/tmpa_z_7qy4 Running Genesis4 in /tmp/tmpa_z_7qy4 /home/runner/miniconda3/envs/lume-genesis-dev/bin/genesis4 -l genesis.lat genesis4.in
--------------------------------------------- GENESIS - Version 4.6.12 has started... Compile info: Compiled by conda at 2026-04-16 21:17:54 [UTC] from Git Commit ID: 0aebc9ac63203f44436686151dfd856526bde43e Starting Time: Wed Apr 22 21:44:15 2026 MPI-Comm Size: 1 node Opened input file genesis4.in Parsing lattice file genesis.lat ... Matching for periodic solution between z = 0 and z = 9.5 : betax (m) : 8.53711 alphax : -0.703306 phix (deg): 45.818 betay (m) : 17.3899 alphay : 1.40348 phiy (deg): 45.818 Generating input radiation field for HARM = 1 ... Generating input particle distribution... Running Core Simulation... Steady-state run Initial analysis of electron beam and radiation field... Calculation: 0% done
Calculation: 10% done
Calculation: 20% done
Calculation: 30% done
Calculation: 40% done
Calculation: 50% done
Calculation: 60% done
Calculation: 70% done
Calculation: 80% done
Calculation: 90% done
Calculation: 100% done Writing output file... Core Simulation done. End of Track Program is terminating... Ending Time: Wed Apr 22 21:44:22 2026 Total Wall Clock Time: 7.11634 seconds ------------------------------------- Success - execution took 8.42s.
InĀ [10]:
Copied!
G.plot(["beam_xsize", "beam_ysize", "field_xsize", "field_ysize"])
G.plot(["beam_xsize", "beam_ysize", "field_xsize", "field_ysize"])
View available output data¶
InĀ [11]:
Copied!
output.info(limit=20)
# **NOTE**: there is a lot more here! Use `output.info()` with the default `limit=None` to see everything.
output.info(limit=20)
# **NOTE**: there is a lot more here! Use `output.info()` with the default `limit=None` to see everything.
Out[11]:
| Key | Units | Shape | Description |
|---|---|---|---|
| alphax | rad | (1, 1) | Twiss alpha horizontal. Evaluated only at the beginning. (output.beam.alphax) |
| alphay | rad | (1, 1) | Twiss alpha vertical. Evaluated only at the beginning. (output.beam.alphay) |
| aw | (1104,) | The dimensionless rms undulator parameter. For planar undulator this value is smaller by a factor $1 / \sqrt{2}$ than its K-value, while for helical undulator rms and peak values are identical. (output.lattice.aw) | |
| ax | m | (1104,) | Offset of the undulator module in $x$. (output.lattice.ax) |
| ay | m | (1104,) | Offset of the undulator module in $y$. (output.lattice.ay) |
| beam_alphax | rad | (1, 1) | Twiss alpha horizontal. Evaluated only at the beginning. (output.beam.alphax) |
| beam_alphay | rad | (1, 1) | Twiss alpha vertical. Evaluated only at the beginning. (output.beam.alphay) |
| beam_betax | m | (1, 1) | Twiss beta horizontal. Evaluated only at the beginning. (output.beam.betax) |
| beam_betay | m | (1, 1) | Twiss beta vertical. Evaluated only at the beginning. (output.beam.betay) |
| beam_bunching | (1105, 1) | Evaluated at each integration step. [unitless] (output.beam.bunching) | |
| beam_bunchingphase | rad | (1105, 1) | Evaluated at each integration step. (output.beam.bunchingphase) |
| beam_current | A | (1, 1) | Beam current. Evaluated only at the beginning. (output.beam.current) |
| beam_efield | eV/m | (1105, 1) | Efield, internally eloss+longESC (output.beam.efield) |
| beam_emax | eV | (1105, 1) | Particle energy maximum. Genesis4 mc^2 units are automatically converted to eV in LUME-Genesis. (output.beam.emax) |
| beam_emin | eV | (1105, 1) | Particle energy minimum. Genesis4 mc^2 units are automatically converted to eV in LUME-Genesis. (output.beam.emin) |
| beam_emitx | m | (1, 1) | Beam horizontal emittance. Evaluated only at the beginning. (output.beam.emitx) |
| beam_emity | m | (1, 1) | Beam vertical emittance. Evaluated only at the beginning. (output.beam.emity) |
| beam_energy | eV | (1105, 1) | Evaluated at each integration step. Genesis4 mc^2 units are automatically converted to eV in LUME-Genesis. (output.beam.energy) |
| beam_energyspread | eV | (1105, 1) | Evaluated at each integration step. Genesis4 mc^2 units are automatically converted to eV in LUME-Genesis. (output.beam.energyspread) |
| beam_globals_energy | eV | (0,) | Average beam energy (output.beam.globals.energy) |
InĀ [12]:
Copied!
# Uncomment this to see everything available in the output.
# output.info(limit=None)
# Uncomment this to see everything available in the output.
# output.info(limit=None)
InĀ [13]:
Copied!
output["beam_energy"]
output["beam_energy"]
Out[13]:
array([[5.8038341e+09],
[5.8038341e+09],
[5.8038341e+09],
...,
[5.8035302e+09],
[5.8035302e+09],
[5.8035302e+09]], shape=(1105, 1))
Archive the results to an HDF5 file¶
InĀ [14]:
Copied!
G.archive("quickstart-results.h5")
G.archive("quickstart-results.h5")
InĀ [15]:
Copied!
restored = Genesis4.from_archive("quickstart-results.h5")
restored = Genesis4.from_archive("quickstart-results.h5")
InĀ [16]:
Copied!
restored.output.plot()
restored.output.plot()
InĀ [17]:
Copied!
G == restored
G == restored
Out[17]:
True
Archive the results to a MessagePack file¶
Saving and loading from MessagePack can be much faster, however it is less introspectable than HDF5. The choice is yours as to which to use.
Simply use the .msgpack file extension (or set format="msgpack") when archiving.
InĀ [18]:
Copied!
G.archive("quickstart-results.msgpack")
G.archive("quickstart-results.msgpack")
InĀ [19]:
Copied!
restored = Genesis4.from_archive("quickstart-results.msgpack")
restored = Genesis4.from_archive("quickstart-results.msgpack")
InĀ [20]:
Copied!
restored.output.plot()
restored.output.plot()
InĀ [21]:
Copied!
G == restored
G == restored
Out[21]:
True