Injection / Particle Generation
This module introduces the Injection command in PASS, which is used to generate specific particle distributions at the simulation starting position and inject the beam. The injection command supports independently setting transverse distribution, longitudinal distribution, beam parameters, offsets, etc. for each bunch, and is the entry point for particle simulation.
Injection supports single-turn and multi-turn operation. The incoming distribution, injection schedule and transverse offsets determine how each batch enters the ring; time-dependent Bump magnets can vary its subsequent transverse motion.
For an executable input-generation and tracking example, see Quick start. Coordinate conventions are defined in Longitudinal coordinate and reference time below.
Interface parameters
Tables list public Python schema fields, JSON aliases and defaults. Set the sequence key to injection; the runtime command name is supplied from that key. The bunch dictionaries are generated from InjectionItem.bunches.
Python field |
JSON key |
Type |
Default |
Description / units |
|---|---|---|---|---|
|
|
|
|
Injection position in m; must be zero. |
|
|
|
|
Keep Injection. |
|
|
|
|
Positive bunch-group count; equal to the number of bunch configurations. |
|
|
|
|
Integer or None; None selects a nondeterministic seed. Reproducibility requires identical input and execution order. |
|
|
|
|
One BunchConfig per group; declare empty groups with zero real and macro particles. |
Bunch parameters
Each bunch uses bunch0 , bunch1 , … as keys, and the value is a dictionary containing all parameters of that bunch. The parameters are described below in five groups: transverse, longitudinal, beam, distribution, and offset.
For ions with mass number \(A=Z+N>1\), the reference rest energy per nucleon
is \(m_0=M_{\mathrm{ion}}c^2/A\), obtained from the bundled mass catalog by
ion_mass(A, Z, q). The catalog uses neutral-atom masses, subtracts the masses
of removed electrons, and adds their cumulative ionization energy. It does not
approximate every nucleon by one atomic mass unit. Electron/positron and
single-proton tracking retain their established constants.
This mass is shared by tracking, generated distributions, GUI energy/momentum offset conversion, the automatic design clock and input validation. Kinetic energy and momentum remain per nucleon. The stored charge-to-mass-number magnitude is \(|q|/A\); RF applies the charge sign, giving the physical energy-gain factor \(q/A\). Unsupported catalog species or charge states are reported as errors. Changing the species mass changes reference velocity and magnetic rigidity and the derived design clock. Explicitly supplied RF frequency tables are physical waveform input and are not automatically recalibrated.
Transverse parameters
Python field |
JSON key |
Type |
Unit |
Default |
Description |
|---|---|---|---|---|---|
|
|
float |
|
Horizontal Twiss parameter \(\alpha_x\) |
|
|
|
float |
|
Vertical Twiss parameter \(\alpha_y\) |
|
|
|
float |
m |
|
Horizontal Twiss parameter \(\beta_x\) |
|
|
float |
m |
|
Vertical Twiss parameter \(\beta_y\) |
|
|
float |
m·rad |
|
Horizontal RMS geometric emittance \(\varepsilon_x\) |
|
|
float |
m·rad |
|
Vertical RMS geometric emittance \(\varepsilon_y\) |
|
|
float |
m |
|
Horizontal dispersion function \(D_x\) |
|
|
float |
|
Horizontal dispersion derivative \(D_{px}\) |
|
|
|
str |
|
Transverse distribution type, options: |
Longitudinal parameters
Python field |
JSON key |
Type |
Unit |
Default |
Description |
|---|---|---|---|---|---|
|
|
float |
m |
|
Longitudinal RMS scale; full uniform interval width in coasting mode: \(\sigma_z\) |
|
|
float |
|
Momentum spread RMS value \(\sigma_{\delta}\) |
|
|
|
str |
|
Longitudinal distribution type, options: |
|
|
|
float |
V |
|
Signed physical RF voltage (required for |
|
|
float |
rad |
|
Physical waveform phase \(\phi_s\) at the matching reference event; see RF phase and charge sign in matching |
|
|
int |
|
Bunch-group index \(h_{\mathrm{id}}\), defining the nominal grouping slot \(z_{\mathrm{center}}=h_{\mathrm{id}}C/h_{\mathrm{group}}\) |
|
|
|
float |
m |
|
Longitudinal position of the RF cavity relative to the injection point, used to back-propagate the distribution generated at s_rf to the injection point s=0 |
|
|
float |
|
Bunch-level average momentum deviation \(\delta_0\) , added to each particle’s dp. Mutually exclusive with |
|
|
|
float |
eV |
|
Bunch-level kinetic energy offset, internally converted to |
Beam parameters
Python field |
JSON key |
Type |
Unit |
Default |
Description |
|---|---|---|---|---|---|
|
|
float |
eV/u |
|
Kinetic energy per nucleon |
|
|
int |
|
Planned total number of real particles over all injection events for this bunch |
|
|
|
int |
|
Planned total number of macro particles over all injection events for this bunch |
|
|
|
int |
|
Exclusive stop turn, counted from turn 0; positive integer, default 1 |
|
|
|
int |
|
Injection interval in turns; positive integer, default 1 |
Distribution parameters
Python field |
JSON key |
Type |
Unit |
Default |
Description |
|---|---|---|---|---|---|
|
|
bool |
— |
|
Whether to load particle distribution from file |
|
|
str |
— |
|
Distribution file path ( |
|
|
str |
— |
|
|
|
|
bool |
— |
|
Whether to save the initial distribution |
|
|
list |
— |
|
Replace the first rows of the first batch after offsets are applied, using |
|
|
str or null |
— |
|
TFS/HDF5 table with |
|
|
object or null |
— |
|
Cartesian x/y grid for every initial dp value; replaces first-batch rows after offsets |
Offset parameters
The horizontal offset ( Offset x ) and vertical offset ( Offset y ) have the same structure, each containing the following sub-parameters:
Python field |
JSON key |
Type |
Unit |
Default |
Description |
|---|---|---|---|---|---|
|
|
bool |
— |
|
Whether to enable offset |
|
|
bool |
— |
|
Whether to load offset data from file |
|
|
str |
— |
|
Offset data file path ( |
|
|
str |
— |
|
Legacy compatibility field; preserved on save. The offset table’s
|
|
|
float |
— |
|
Position offset |
|
|
float |
— |
|
Momentum offset |
Additional bunch options
Python field |
JSON key |
Type |
Default |
Description / units |
|---|---|---|---|---|
|
|
|
|
Initial source reference passage time in seconds; None uses the automatic design clock. |
|
|
|
|
Initial-distribution table format: hdf5-gzip1, hdf5 or tfs. |
|
|
|
|
Horizontal OffsetConfig; see the offset table above. |
|
|
|
|
Vertical OffsetConfig; see the offset table above. |
Defaults are configuration defaults, not guaranteed complete physical inputs. In particular, explicitly supply positive emittances for Gaussian generation. harmonic_number belongs to InjectionItem and is also used by matched-distribution initialization; it is not a BunchConfig field.
Input file
{
"Beam Name": "proton",
"Number of Protons": 1,
"Number of Neutrons": 0,
"Number of Charges": 1,
"Transition Gamma": 4.8,
"Number of turns": 5,
"Circumference (m)": 251.327,
"Backend (gpu/cpu)":"cpu",
"Number of GPU devices": 1,
"Device Id": [
0
],
"Output directory": "./output",
"Is plot figure": true,
"Sequence": {
"injection": {
"S (m)": 0.0,
"Command": "Injection",
"Harmonic Number": 1,
"bunch0": {
"Kinetic Energy per Nucleon (eV/u)": 45e6,
"Number of Real Particles": 100000000000,
"Number of Macro Particles": 100000,
"Is Load Distribution from File": false,
"Distribution File Path": "",
"Total Injection Turns": 1,
"Injection Interval": 1,
"Alpha x": -2.614303952,
"Alpha y": 1.57442348,
"Beta x (m)": 0.5,
"Beta y (m)": 0.5,
"RMS geometric emittance x (m'rad)": 0.00019999999999999998,
"RMS geometric emittance y (m'rad)": 9.999999999999999e-05,
"Dx (m)": 0.0,
"Dpx": 0.0,
"Sigma z (m)": 30,
"Sigma dp/p": 0.005,
"Transverse dist": "gaussian",
"Longitudinal dist": "matchz",
"RF Voltage (V)": 100e3,
"RF Phase (rad)": 0.5235987755982988,
"Harmonic ID of this bunch": 0,
"RF S Position Refer to Injection Point (m)": 0.0,
"Offset x": {
"Is Offset": false,
"Is Load From File": false,
"File Path": "",
"File Time Kind": "turn",
"Offset Position (m)": 0.0,
"Offset Momentum (rad)": 0.0
},
"Offset y": {
"Is Offset": false,
"Is Load From File": false,
"File Path": "",
"File Time Kind": "turn",
"Offset Position (m)": 0.0,
"Offset Momentum (rad)": 0.0
},
"Is Save Initial Distribution": true,
"Insert Particle Coordinate": [[0,0,0,0,0,0]]
}
},
"StatMonitor1":{
"S (m)": 0.0,
"Command": "StatMonitor"
}
}
}
Longitudinal coordinate and reference time
At a specified lattice location, bunch.t0 is the actual passage time
\(T_b\) of the ideal reference particle of bunch b. The stored, continuous
coordinate is a time difference expressed in metres:
Positive z means earlier arrival. The reference particle is neither an
automatically recentered bunch centroid nor necessarily a stable RF synchronous
particle. No particle or bunch arrival-correction state is stored. All six
particle coordinates retain the configured storage precision; timing and RF
intermediates use float64. Local phase reduction never overwrites p.z.
Reference transformations
A pure reference change at the same physical location preserves time and mechanical momentum:
Injection and regrouping apply the required coordinate conversions locally;
PASS/core/bunch.py updates the reference energy parameters. For a zero-length
RF energy kick, \(T_b'=T_b\), so z scales by the reference velocity ratio.
The particle energy also receives the physical RF kick; this is distinct from
the pure normalization transformation. See RFCavity.
Transport advances the reference event by its reference flight time. In an exact straight drift of length L, \(\Delta T_b=L/(\beta_b c)\) and \(\Delta t_i=LE_i/(cP_{s,i})\). Other transfer maps retain their documented approximations. Quadrupole strengths remain normalized by the reference momentum; see the relevant element pages for their transport maps.
Fixed macro-particle weights
All populated bunches within one beam must use the same represented real-particle
count per macro particle, given by Number of Real Particles / Number of Macro
Particles in the initial input. Different input weights are rejected. This
fixed value applies to every planned injection batch. Injection
activates reserved particles; it does not rescale their weights according to
the current population, losses, or destination bunch.
Sorting and regrouping retain this scalar weight, including in empty groups.
No per-particle weight or wake-charge array is allocated. Rounded diagnostic
real-particle counts never feed back into the weight. Slicer, SpaceCharge and
WakeField use the same fixed bunch.ratio; only particles with tag > 0
contribute. Injection and losses change the active population, never the
weight of the remaining particles.
Reference-momentum precision
The incoming momentum deviation is converted to the circulating reference as
This form avoids subtracting nearly equal unit-sized values. The shared CPU/GPU
injection path evaluates the conversion in FP64 before storing the result in the
configured particle precision. Equal reference momenta preserve the incoming
dp values exactly, including small FP32 deviations. All six particle arrays
retain their common configured FP32 or FP64 dtype.
Multi-turn injection and transverse painting
Injection schedule and particle population
Each bunch has its own injection schedule. Let Total Injection Turns be
\(T\) and Injection Interval be \(\Delta n\). Injection occurs at
The stop turn is excluded. Number of Macro Particles gives the planned
total \(N\) for the bunch. Each event receives
\(\lfloor N/N_{\mathrm{event}}\rfloor\) particles; the first event also
receives the remainder. Events assigned zero particles add no population.
The simulation must run through every event assigned particles to inject the
full population. For a nonempty source with Is Save Initial Distribution
enabled, the distribution is saved at the last scheduled event, even when that
event adds zero particles. After all particles are injected and all requested
saves have succeeded, subsequent Injection calls return immediately without
searching the event schedules or recording additional turn numbers.
Reserved particles have tag=0 and contribute neither tracking nor charge
deposition, statistics or losses. Injection activates only the current batch.
Live particles have tag>0; lost particles have tag<0 and retain their
loss coordinates. The identity abs(tag) of an injected particle remains
unchanged by sorting or loss. The fixed macro-particle weight defined above
applies throughout injection and storage.
An injection batch identifies when particles enter the ring. Longitudinal bunch
groups are specified separately by Harmonic Number and
Harmonic ID of this bunch. Completing injection ends particle loading;
circulating particles continue to follow the lattice and any active waveforms.
Incoming distribution and offsets
With Is Load Distribution from File=true, each bunch reads its own HDF5 or TFS table
with columns x, px, y, py, z and dp. Positions are in metres;
momenta use the specified injection reference momentum. Distribution File Mode
controls row selection:
sequentialconsumes consecutive rows across events. The file must contain at least the planned total number of particles for that bunch.repeatstarts at row zero at each event, taking that event’s particle count. The file must contain at least the largest batch. Reusing source coordinates still creates new particles with distinct identities.
Otherwise, Injection generates the selected transverse and longitudinal
distributions for each batch. Generated and loaded particles both receive the
configured horizontal dispersion and Offset x / Offset y. The offsets
apply only at injection. A file-based offset is linearly interpolated at the
injection turn or physical incoming reference passage time, according to its
turn or time (s) column. The latter includes the offset from an explicit
Reference arrival time (s). Turn nodes must be nonnegative integers; time
nodes in seconds may be negative. Nodes must increase strictly and all values
must be finite. The position and momentum columns are x (m) / px (rad)
or y (m) / py (rad). Preflight checks that each enabled table covers the
events at which particles are actually injected during this run. Queries outside
the table domain raise an error; endpoint values are not held beyond that domain.
Insert Particle Coordinate, Insert Particle File and Scan Grid are
mutually exclusive ways to replace the first rows of the first batch after these
offsets, before conversion to the circulating reference. The batch must contain
enough rows for these explicitly specified particles; they replace reserved rows
and do not increase the planned count or change macro-particle weights. The file
option accepts the same six lowercase coordinate columns as a distribution file,
but does not apply momentum, dispersion or transverse offsets to its rows. It
reads all rows once, only for the first batch; input tags are not imported.
Missing input rows, non-finite coordinates, or nonpositive longitudinal momentum
cause an error before the affected batch is activated. If a grid or explicit file
fills the entire first batch and distribution-file loading is disabled, the
unused random generation is skipped. Partial replacements leave the other rows
generated and offset as usual.
If manual coordinates supply the entire distribution in one active batch, unused random generation is also skipped and positive Gaussian emittances are not required. A manual replacement of only the first batch in a multi-batch source retains the existing random-number sequence for later generated batches. Skipping a complete manual bunch no longer consumes discarded random draws. Later randomly generated bunches in the same Injection command can therefore have different fixed-seed coordinates than older versions. Repeated runs with the same seed and configuration in the current version remain deterministic. Skipping a complete manual bunch no longer consumes discarded random draws. Later randomly generated bunches in the same Injection command can therefore have different fixed-seed coordinates than older versions. Repeated runs with the same seed and configuration in the current version remain deterministic.
The incoming physical momentum remains determined by the specified injection energy even when the circulating beam has accelerated. Injection converts the incoming momenta and longitudinal coordinate to the destination bunch reference while preserving physical momentum and arrival time, as defined in Longitudinal coordinate and reference time.
Cartesian scan coordinates
Scan Grid generates the full Cartesian product of the x and y axes and the
dp values list in one bunch. Every dp value receives the entire x/y grid.
The x index changes fastest, followed by y and then dp. This is initial-coordinate
generation only: the user still chooses every tracking command and effect.
"Scan Grid": {
"X range (m)": [-0.01, 0.01],
"Y range (m)": [-0.008, 0.008],
"Number of x points": 21,
"Number of y points": 17,
"dp values": [-0.01, 0.0, 0.01],
"px": 0.0,
"py": 0.0,
"z (m)": 0.0
}
This grid contains 1071 particles, so the first injection batch must have at least
1071 reserved particles. Ranges include both endpoints. A one-point axis requires
identical endpoints; a multi-point axis requires increasing endpoints. Point
counts are positive integers, dp values are finite and distinct, and every point
must satisfy \(1+\delta>\sqrt{p_x^2+p_y^2}\). The fixed px, py and
z (m) fields default to zero. Here px and py mean mechanical momenta
divided by the incoming reference momentum, not geometric slopes.
Python callers can construct ScanGridConfig or use
PASS.utils.scan_grid.generate_scan_grid(x_values, y_values, dp_values).
The latter returns coordinates with columns [x, px, y, py, z, dp],
indices with columns [dp_index, y_index, x_index], and the three axes.
It also accepts fixed px, py and z keyword arguments.
The supplied coordinates are exact in the incoming reference. Converting to a
different circulating momentum or clock can change their stored dp and
z while preserving physical momentum and arrival time. Analyse actual
post-injection initial coordinates and group scans by initial dp, since RF can
subsequently change dp. All scan particles retain the normal beam weight and
participate in the configured collective effects.
Transverse painting with Bump magnets
Painting fills transverse phase space over successive injection events by
varying the incoming beam position and momentum, the circulating orbit, or both.
Offset x and Offset y prescribe the incoming beam coordinates at the
injection point. Bump supplies horizontal and vertical pulsed
magnetic kicks along the circulating lattice. Every live particle passing a
Bump receives its kick, including particles from earlier batches.
Incoming coordinates and Bump transport use the same fixed machine coordinates.
Specify the incoming centroid at the injection plane and the physical magnet
waveforms separately; an orbit displacement is not itself a magnet kick.
In particle-time mode, the waveform is sampled at
\(t_i=t_0-z_i/(\beta_0c)\) plus the configured Time offset (s). The table
must cover the arrival times of the particles being deflected. The Bump page
defines reference-time sampling, interpolation and pulse-boundary behavior.
Injection creates or loads particles at the injection plane and applies the specified offsets. Lattice elements perform subsequent transport and loss checks. In particular, ElSeparator evaluates electric deflection and electrode or vacuum-wall contact when particles pass through that element. Particles specified at the ES exit begin tracking at that plane; Injection does not apply an additional geometric acceptance cut.
Observing injection
Place DistMonitor at the desired observation plane and turn to
save the injected population. At \(s=0\), Injection executes before the
monitor, so the snapshot includes the current batch. Enable
Include injection metadata to save particle_id, injection_turn and
injection_batch. Turn and batch indices start at zero; each source bunch
has its own batch index, so use particle_id for particle matching.
All three output formats (tfs, hdf5 and hdf5-gzip1) exclude pending slots,
retain lost particles and report NumPending. Select tag>0 when examining
the live phase-space distribution at the monitor. Coordinates of lost particles
refer to their loss locations. Use StatMonitor for the evolution
of the circulating population and its statistical moments.
Introduction to particle distribution types
In the PASS program, the initial particle distribution is implemented by the Injection command. In the Injection command, different distribution information can be set independently for each bunch.
Transverse particle distribution
Currently, the PASS program supports generating the following transverse particle distributions: horizontally-vertically decoupled 2D Gaussian distribution , 4D KV distribution , 4D waterbag distribution , 4D parabolic distribution , uniform-real , and uniform-phase.
The input emittances \(\varepsilon_x,\varepsilon_y\) are RMS geometric emittances in m rad. The names uniform-real and uniform-phase describe the defining transverse projections: a uniform spatial rectangle and independently uniform phase-space ellipses, respectively. Here “phase” means transverse phase space. The distributions below describe the intrinsic transverse coordinates before dispersion and injection offsets are added.
The KV, waterbag and parabolic distributions define a generalized hyper-ellipsoid boundary in the 4D phase space \((x, p_x, y, p_y)\). To simplify the derivation, first take zero Twiss alpha and introduce normalized coordinates :
where \(a, b, c, d\) are the maximum physical envelope boundaries (hard boundaries) of the beam in the corresponding dimensions. Under this normalized coordinate system, the 4D hyper-ellipsoid boundary simplifies to a unit hypersphere:
For nonzero Twiss alpha, the corresponding normalized momentum includes the shear \(\alpha_x x+\beta_xp_x\) (and similarly in y); rescaling the physical momentum alone does not remove the phase-space tilt.
The following describes each transverse particle distribution in detail. For 4D distributions, their projections onto the 1D plane have a unified power-law form. Let the distribution density in 4D phase space be \(f(r^2) \propto (1-r^2)^{\alpha}\) (alpha ge 0, defined within the 4D unit ball \(B^4\)), then the 1D marginal distribution for any single normalized coordinate \(u\) is:
where \(n=4\) is the phase space dimension. For distributions uniformly distributed on the \(n\)-dimensional sphere \(S^{n-1}\) (such as KV), the 1D projection is:
The 1D projections of each distribution are summarized below:
Distribution |
4D density |
\(\alpha\) |
1D projection power |
1D projection form |
|---|---|---|---|---|
uniform-real (2D squares) |
— |
— |
0 |
\(\rho(u) = \mathrm{const}\) |
uniform-phase (2D disks) |
Constant on \(B^2\times B^2\) |
— |
\(\frac{1}{2}\) |
\(\rho(u) \propto \sqrt{1-u^2}\) |
KV ( \(S^3\) sphere) |
\(\delta(r-1)\) |
— |
\(\frac{1}{2}\) |
\(\rho(u) \propto \sqrt{1-u^2}\) |
Waterbag ( \(B^4\) uniform) |
\(1\) |
0 |
\(\frac{3}{2}\) |
\(\rho(u) \propto (1-u^2)^{3/2}\) |
Parabolic ( \(B^4\) , \(1-r^2\) ) |
\((1-r^2)^1\) |
1 |
\(\frac{5}{2}\) |
\(\rho(u) \propto (1-u^2)^{5/2}\) |
The following describes each transverse particle distribution in detail:
Independent 2D Gaussian distribution (Gaussian)
In the \(x-p_x\) and \(y-p_y\) phase spaces, transverse coordinates following a Gaussian distribution are generated independently. The particle distribution in transverse phase space uses a \(4\sigma\) truncation, i.e., only particles satisfying:
\[|x| \le 4\sigma_x, \quad |y| \le 4\sigma_y\]are retained.
For the 2D phase space Gaussian distribution ( \(x-p_x\) and \(y-p_y\) ), the particle inclusion ratios corresponding to different RMS emittances are as follows:
\(\epsilon/\epsilon_{\mathrm{rms}}\)
Truncation range
Retained ratio
1
\(1\sigma\)
39.346934029%
2
\(\sqrt{2}\sigma\)
63.212055883%
4
\(2\sigma\)
86.466471676%
6
\(\sqrt{6}\sigma\)
95.021293163%
9
\(3\sigma\)
98.889100346%
16
\(4\sigma\)
99.966453737%
This table describes an elliptical cut on the phase-space invariant. The implemented independent position cuts in x and y have a different retained fraction; do not use the table as their acceptance probability.
The specific truncation ratio can be calculated using the following function:
import numpy as np def fraction_by_emittance(epsilon, epsilon_rms): fraction = 1 - np.exp(-epsilon / (2 * epsilon_rms)) print(f"eps/eps_rms = {epsilon/epsilon_rms}, particle proportion = {fraction:.9%}") for epsi in (1, 2, 4, 6, 8, 9, 16, 25, 36): fraction_by_emittance(epsilon=epsi, epsilon_rms=1)4D KV (Kapchinskij-Vladimirskij) distribution
In the \(x-p_x-y-p_y\) four-dimensional phase space, a particle distribution uniformly distributed on the surface of a four-dimensional hyper-ellipsoid is generated, which is an idealized distribution existing only on the 4D spherical shell. Under this distribution, the space charge field produced by the particles is strictly linear within the bunch, in the ideal continuous free-space transverse model. Finite sampling and conducting boundaries modify this result.
After integrating out two dimensions, the projection of the KV distribution onto any 2D plane (such as the \(x-p_x\) plane) is a uniformly filled ellipse. After further integrating out one dimension, the projection of the KV distribution onto the 1D plane is a semi-ellipse (or semi-circle) distribution. The detailed derivation is as follows: the KV distribution is uniformly distributed on the 4D hypersphere \(S^3\) ( \(r^2 = 1\) ). To obtain the 1D marginal distribution of \(u_x\), the remaining three coordinates on \(S^3\) need to be integrated:
\[\rho(u_x) \propto (1-u_x^2)^{\frac{n-3}{2}} = (1-u_x^2)^{\frac{1}{2}}\]i.e., the 1D projection power is \(\frac{1}{2}\) .
Note
According to the integration: in the \(x-p_x\) and \(y-p_y\) phase planes, the full emittance of the KV distribution is 4 times the RMS emittance.
i.e., all particles in the KV distribution are within the \(2\sigma\) truncation range. However, the program still retains particles satisfying:
\[|x| \le 4\sigma_x, \quad |y| \le 4\sigma_y\]4D Waterbag distribution
In the \(x-p_x-y-p_y\) four-dimensional phase space, a particle distribution uniformly distributed inside the four-dimensional hyper-ellipsoid is generated.
After integrating out two dimensions, the projection of the waterbag distribution onto any 2D plane (such as the \(x-p_x\) plane) follows a parabolic distribution. After further integrating out one dimension, the projection of the waterbag distribution onto the 1D plane is a \(\frac{3}{2}\) -power parabolic distribution. The detailed derivation is as follows: the waterbag distribution is uniformly distributed inside the 4D hyper-ball \(B^4\) ( \(f(r^2) = 1\) , i.e., \(\alpha = 0\) ). To obtain the 1D marginal distribution of \(u_x\), the remaining three coordinates on \(B^4\) need to be integrated, and the remaining part is a 3D ball of radius \(\sqrt{1-u_x^2}\) :
\[\rho(u_x) \propto V_3\!\left(\sqrt{1-u_x^2}\right) \propto (1-u_x^2)^{\frac{3}{2}}\]where \(V_3(R) \propto R^3\) is the 3D ball volume. i.e., the 1D projection power is \(\frac{3}{2}\) .
Note
According to the integration: in the \(x-p_x\) and \(y-p_y\) phase planes, the full emittance of the waterbag distribution is 6 times the RMS emittance.
i.e., all particles in the waterbag distribution are within the \(\sqrt{6}\sigma\) truncation range. However, the program still retains particles satisfying:
\[|x| \le 4\sigma_x, \quad |y| \le 4\sigma_y\]4D Parabolic distribution
In the \(x-p_x-y-p_y\) four-dimensional phase space, a particle distribution with density decreasing parabolically from the center outward as r increases is generated. It represents a centrally concentrated distribution within a finite phase-space boundary.
After integrating out two dimensions, the projection of the parabolic distribution onto any 2D plane (such as the \(x-p_x\) plane) follows a quadratic parabolic distribution. After further integrating out one dimension, the projection of the parabolic distribution onto the 1D plane is a \(\frac{5}{2}\) -power parabolic distribution. The detailed derivation is as follows: the 4D density of the parabolic distribution is \(f(r^2) \propto (1-r^2)^1\) ( \(\alpha = 1\) ). To obtain the 1D marginal distribution of \(u_x\):
\[\rho(u_x) \propto (1-u_x^2)^{\frac{n-1}{2}+\alpha} = (1-u_x^2)^{\frac{3}{2}+1} = (1-u_x^2)^{\frac{5}{2}}\]i.e., the 1D projection power is \(\frac{5}{2}\) .
Note
According to the integration: in the \(x-p_x\) and \(y-p_y\) phase planes, the full emittance of the parabolic distribution is 8 times the RMS emittance.
i.e., all particles in the parabolic distribution are within the \(\sqrt{8}\sigma\) truncation range. However, the program still retains particles satisfying:
\[|x| \le 4\sigma_x, \quad |y| \le 4\sigma_y\]uniform-real distribution
In the \(x-p_x\) and \(y-p_y\) phase spaces, 2D uniform square distributions are generated independently. For each transverse plane, uniform sampling is performed within the square region \([-1, 1] \times [-1, 1]\) in normalized coordinates \((u, v)\) , and then mapped to physical coordinates through Twiss parameters. The ideal continuous distribution has RMS emittance equal to the input parameter \(\varepsilon\) , the squared coordinate half-width is 3 times its variance, and the position projection lies within the \(\sqrt{3}\sigma\) truncation range. This distribution can simulate the initial beam produced by an electron gun, etc.
After integrating out one dimension, the position projection is a constant (uniform) distribution. Since \(u_x\) and \(v_x\) are independently and uniformly distributed on \([-1, 1]\) , after integrating over \(v_x\):
\[\rho(u_x) = \frac{1}{2} = \mathrm{const} \propto (1-u_x^2)^{0}\]i.e., the 1D projection power is \(0\) .
Consequently, the intrinsic \(x-y\) density is uniform on a rectangle with half-widths \(\sqrt{3\varepsilon_x\beta_x}\) and \(\sqrt{3\varepsilon_y\beta_y}\). At nonzero Twiss alpha, the physical phase-space squares become parallelograms and the momentum projections need not be uniform. Dispersion, subsequent transport and superposition of injection turns can also change the spatial density. The old
uniformtype has been replaced byuniform-realand is no longer accepted.uniform-phase distribution
Each transverse phase-space ellipse is filled uniformly and the two planes are sampled independently. With \(\gamma_u=(1+\alpha_u^2)/\beta_u\), define the Courant–Snyder invariant and action by
\[I_u=\gamma_u u^2+2\alpha_u u p_u+\beta_u p_u^2=2J_u, \qquad u\in\{x,y\}.\]The support is the product of two filled ellipses:
\[I_x\le4\varepsilon_x,\qquad I_y\le4\varepsilon_y.\]Direct area sampling uses independent \(U_u\sim\mathcal U(0,1)\) and \(\theta_u\sim\mathcal U(0,2\pi)\):
\[r_u=\sqrt{4\varepsilon_u U_u},\qquad u=\sqrt{\beta_u}\,r_u\cos\theta_u,\qquad p_u=\frac{r_u}{\sqrt{\beta_u}} \left(\sin\theta_u-\alpha_u\cos\theta_u\right).\]The resulting centered covariance is \(\varepsilon_u\begin{pmatrix}\beta_u&-\alpha_u\\-\alpha_u&\gamma_u\end{pmatrix}\), so its RMS geometric emittance equals the input \(\varepsilon_u\). The boundary invariant is four times that value. Both normalized actions \(q_u=I_u/(4\varepsilon_u)\) are independent and uniform on \([0,1]\).
The normalized-action formulas assume positive emittance in the corresponding plane. If \(\varepsilon_u=0\), that plane is generated at \(u=p_u=0\); the usual dispersion and injection offsets are added afterward.
The spatial density has rectangular support but is not uniform. For \(a=2\sqrt{\varepsilon_x\beta_x}\) and \(b=2\sqrt{\varepsilon_y\beta_y}\),
\[\rho(x,y)=\frac{4}{\pi^2ab} \sqrt{1-\frac{x^2}{a^2}}\sqrt{1-\frac{y^2}{b^2}}, \qquad |x|\le a,\quad |y|\le b,\]and it vanishes outside that rectangle. Each position projection is a semi-ellipse, with the same shape as the corresponding KV projection.
This distribution can approximate a beam after two-plane painting when independent transverse actions are an appropriate assumption. It does not generate the painting orbit or enforce correlated/anti-correlated painting. Phase mixing in uncoupled linear optics randomizes phases without removing action correlations.
A uniform-phase sample and a KV sample can have the same single-plane projections and RMS emittances, but their joint actions differ: uniform-phase fills \(0\le q_x,q_y\le1\), whereas KV satisfies \(q_x+q_y=1\). The 4D waterbag fills \(I_x/(6\varepsilon_x)+I_y/(6\varepsilon_y)\le1\) instead. The ideal action correlation coefficients are respectively \(0\), \(-1\) and \(-1/2\). Both uniform-real and uniform-phase have constant phase-space density within their own support; their names do not define mutually exclusive mathematical classes.
Longitudinal particle distribution
Currently, the PASS program supports generating the following longitudinal particle distributions: 2D Gaussian distribution , coasting beam distribution , distribution matched to RF parameters - longitudinal bunch length RMS value , distribution matched to RF parameters - momentum spread RMS value :
2D Gaussian distribution (Gaussian)
In the \(z-\delta\) phase space, longitudinal coordinates following a Gaussian distribution are generated. The particle distribution in longitudinal phase space uses a \(4\sigma\) truncation, i.e., only particles satisfying:
\[|z| \le 4\sigma_z\]are retained.
Coasting beam distribution (Coasting)
In the \(z-\delta\) phase space, longitudinal coordinates are generated where \(z\) follows a uniform distribution and \(\delta\) follows a Gaussian distribution. The uniform interval is [-sigma_z/2, sigma_z/2]; in this mode Sigma z (m) is its full width. Set sigma_z equal to the circumference for a full-ring distribution.
Distribution matched to RF parameters - longitudinal bunch length RMS value (MatchZ)
In the \(z-\delta\) phase space, longitudinal coordinates satisfying both the RF parameters and the longitudinal bunch length constraint ( \(\sigma_z\) ) are generated. The particle distribution in longitudinal phase space uses a \(2\sigma\) truncation, i.e., only particles satisfying:
\[|z| \le 2\sigma_z\]are retained.
Distribution matched to RF parameters - momentum spread RMS value (MatchDp)
In the \(z-\delta\) phase space, longitudinal coordinates satisfying both the RF parameters and the momentum spread constraint ( \(\sigma_{\delta}\) ) are generated. The particle distribution in longitudinal phase space uses a \(2\sigma\) truncation, i.e., only particles satisfying:
\[|z| \le 2\sigma_z\]are retained.
Matching solves for the normalized central moments of the continuous distribution over the full RF bucket to meet the requested RMS target. The momentum integral is evaluated analytically using incomplete gamma functions, followed by adaptive integration in z scaled by the distribution’s natural width, with explicit interval splits to resolve narrow peaks. This improves moment accuracy without changing the distribution density, RF potential, or matching target. Particle sampling applies its truncation afterward, so the RMS of the final finite sample can still differ from that target.
RF-matched sampling also enforces a 0.9 bucket-Hamiltonian acceptance bound. Requested scales above the model maximum are reduced to 0.99 of that maximum. Together with the z cut, these restrictions mean the measured sample RMS need not equal the requested matching target.
Both matched distributions generate candidates in batches, uniformly over the same RF-bucket bounding rectangle. Each candidate consumes the same three uniform random draws, in the same order, for z, momentum deviation and the acceptance threshold. A batch never exceeds the number of particles still needed, so it cannot consume surplus candidates after filling the bunch. Where compatible, a checked MT19937 state transfer enables NumPy to generate the existing Python random stream in bulk and then restores the advanced state, including the cached Gaussian value. Otherwise, sampling uses the Python random generator directly. The seed semantics and subsequent random stream are retained.
A momentum-only upper bound avoids evaluating the RF potential for candidates that must be rejected. In the stable single-harmonic bucket, write the positive Hamiltonian as
where \(\delta=(P-P_0)/P_0\) and \(f_0=\beta c/C\). With \(T=|H_0|>0\) and \(B=|H_{\max}|>0\), the existing acceptance density obeys
A candidate whose existing random threshold exceeds this upper bound is already ineligible under the full density. The implementation allows a conservative roundoff margin and falls back to the full check when the numerical conditions for the bound are unsuitable. Remaining candidates undergo the original density and Hamiltonian checks; the existing z cut can also be checked early. This changes the evaluation cost, while retaining the matching target, density and cutoffs.
RF phase and charge sign in matching
For matchz and matchdp, RF Phase (rad) is the physical RF waveform
phase at the reference arrival event at the matching RF location. For the waveform
in RFCavity, this means
\(\phi_s=\theta(t_s)=2\pi\int_0^{t_s}f(t)\,dt+\phi(t_s)\), including its clock
phase, rather than the phase-offset parameter alone. The matching input describes
this chosen event explicitly; Injection does not infer it from a tracked centroid
or add a phase from the nominal grouping coordinate z_center.
The existing matching model is a frozen, single-harmonic, small-relative-momentum model. With \(\delta=(P-P_0)/P_0\), \(\eta=\gamma_t^{-2}-\gamma^{-2}\), and \(\phi=\phi_s-2\pi h z_{\mathrm{rel}}/C\), its equations are
Here \(q\) is the signed charge number in units of the elementary charge, \(V\) is the signed input voltage, and \(E\) is total energy per particle in eV. For \(A=N_p+N_n>0\), use \(q_r=q/A\) and \(E_r=E/A\); for electrons and positrons (\(A=0\)), use \(q_r=q\) and \(E_r=E\). The stable-phase condition is therefore \(qV\eta\cos\phi_s<0\). For example, when \(V>0\) and \(\eta>0\), electrons are stable at physical phase 0 and positive charges at physical phase \(\pi\). The bucket uses the lower of the two adjacent saddle barriers on the branch containing this stable phase. Charge-sign handling does not change the matching distribution or add multi-harmonic, ramp, radiation, or collective-field matching.
Older negative-charge Injection inputs that manually added \(\pi\) to compensate for unsigned charge must remove that compensation and supply the physical phase. The GUI RF-bucket tool keeps its separate effective-phase convention: when \(qV<0\), its phase is the physical phase plus \(\pi\) modulo \(2\pi\). That GUI input convention is unchanged.
Multi-bunch Longitudinal Coordinates
The source distribution uses \(z_s=\beta_s c(T_s-t_i)\). The prescribed machine clock, injection turn and slot select its reference event; an explicit initial time is also supported, as described in Automatic design clock and initialization. Before writing to the destination bunch, PASS transforms
Mechanical momenta are rebased at the same time. Physical time and momentum are preserved; z is never folded. RF samples \(T_d-z_d/(\beta_d c)\) directly.
The nominal slot position is computed as harmonic_id*C/harmonic_number
when writing logs or output; no bunch.z_center attribute is stored.
ZCenter/zCenter output fields record this derived metadata.
The diagrams below use z_center for the same nominal position. This is
distinct from slice_table['z_center'], which stores each slice interval’s
center for slicing and wake calculations.
For a distribution matched at an RF position \(s_{rf}\) after injection, initialization retains the linear back-propagation \(z(0)=z(s_{rf})+\eta s_{rf}\delta\), where \(\eta=1/\gamma_t^2-1/\gamma^2\). This is a declared linear distribution approximation, not an exact finite-amplitude transport map.
Bunch filling scheme
Note
The bunch ID ( bunch_id ) is strictly numbered starting from 0 with a step of 1, determined by the key names bunch0 , bunch1 , … in the input file. The number of bunches is determined by the number of bunch keys in the input file.
harmonic_id values must be unique and cover \(0,1,\ldots,h_{\mathrm{group}}-1\) exactly. The number of declared bunches therefore equals Harmonic Number. An unfilled slot is represented by a declared bunch with zero macro particles. The GUI fills missing slots with these empty declarations automatically.
Full filling: every group contains particles, with centers at \(0,C/h_{\mathrm{group}},\ldots,(h_{\mathrm{group}}-1)C/h_{\mathrm{group}}\)
Partial filling: retain the complete group-index set and assign zero macro particles to the unfilled slots
A runtime slot is empty only when its allocated particle interval has zero
length (start_idx == end_idx). Particle calculations and per-bunch monitor
files are skipped for such slots. Pending injection reservations and lost
particles remain allocated records: zero surviving particles does not make a
bunch empty, and its loss statistics continue to be recorded. A later
SortBunch or ReorganizeBunch can fill an empty slot, which then participates
normally. Lightweight reference-time/energy updates and shared effect timing
remain active for empty slots so that subsequent regrouping retains valid
reference states.
The figure below illustrates bunch grouping around a ring of circumference \(C\). The marked points are nominal slots \(z_{\mathrm{center}}\), and group indices increase clockwise. The upper figure shows full filling for \(h_{\mathrm{group}}=4\); the lower figure shows partial filling for \(h_{\mathrm{group}}=5\), with groups 1, 3, and 4 represented by empty bunches:
Dispersion coupling
If the injection point has dispersion functions \(D_x\) and \(D_{px}\) , then after generating the transverse distribution, dispersion coupling is automatically applied:
where \(\delta\) is the particle’s momentum deviation. This ensures that the particle distribution and the longitudinal momentum spread are physically self-consistent.
Momentum deviation
During injection, an average momentum offset \(\delta_0\) can be applied to the entire bunch. When the particle distribution is generated, \(\delta\) follows a distribution with mean 0 (such as a Gaussian distribution \(\delta \sim \mathcal{N}(0, \sigma_\delta)\) ). After applying the offset, it becomes \(\delta \sim \mathcal{N}(\delta_0, \sigma_\delta)\) , i.e., the distribution center shifts from 0 to \(\delta_0\) . \(\delta_0\) is an additive quantity, not the total \(\delta\) of the particle. This is used to simulate scenarios such as injection energy offset and reference momentum offset.
Two input methods are supported (mutually exclusive; if both are non-zero, an error is raised):
Momentum deviation (
Momentum Offset dp): directly provides \(\delta_0\) (dimensionless, relative to the reference momentum deviation)Kinetic energy offset (
Kinetic Energy Offset (eV)): provides \(\Delta E\) (in eV), internally converted to \(\delta_0\)
Exact conversion formula
The conversion from kinetic energy offset \(\Delta E\) to momentum deviation \(\delta_0\) uses the exact relativistic energy-momentum relation:
where \(E\) is the total energy ( \(E = E_k + m_0\) ), \(p\) is the momentum, and \(m_0\) is the rest mass. The parameters of the reference particle (no deviation) are:
After applying the kinetic energy offset \(\Delta E\) , the particle’s total energy becomes \(E_1 = E_0 + \Delta E\) , and the corresponding momentum is:
Therefore, the momentum deviation is:
This formula is fully exact , with no approximations, and is consistent with the exact \(E^2 = p^2 + m_0^2\) transformation used in the RF cavity.
First-order linearization approximation
For the formula \(\delta_0 = p_1/p_0 - 1\) , a first-order Taylor expansion is performed at \(\Delta E \to 0\) . From \(E \, dE = p \, dp\) we get:
where \(\beta = p_0 c / E_0\) is the reference particle velocity. Since in PASS \(\delta = \Delta p / p_0\) is the relative momentum deviation, the reference momentum \(p_0 = \beta \gamma m_0 = \beta E_0\) , therefore:
This approximation truncates \(O(\delta_0^2)\) and higher-order terms. It has sufficient accuracy for small deviations, but significant errors for large deviations.
Comparison of exact and approximate formulas
The following table uses a proton ( \(E_k = 45\) MeV , \(\beta = 0.299\) ) as an example to show the differences between the two formulas at different \(\Delta E\) values:
\(\Delta E\) (eV) |
Exact \(\delta_0\) |
Approximate \(\delta_0\) |
Relative error |
|---|---|---|---|
1,000 |
1.137126e-5 |
1.137132e-5 |
0.000005% |
10,000 |
1.137073e-4 |
1.137132e-4 |
0.000052% |
100,000 |
1.136544e-3 |
1.137132e-3 |
0.000517% |
1,000,000 |
1.131311e-2 |
1.137132e-2 |
0.0514% |
10,000,000 |
1.084146e-1 |
1.137132e-1 |
4.89% |
50,000,000 |
4.717485e-1 |
5.685659e-1 |
20.5% |
For small deviations ( \(\Delta E < 100\) keV ), the two formulas have almost no difference, but for large deviations (e.g., \(\Delta E > 1\) MeV ), the linear approximation error exceeds 0.05%, and at \(\Delta E = 50\) MeV the error reaches 20%. PASS uses the exact formula to cover large deviation scenarios.
Application order
The momentum deviation \(\delta_0\) is applied to each particle’s \(\delta\) before the longitudinal offset:
Therefore, the subsequent rf_position back-propagation ( \(z \leftarrow z + \eta \, s_{\text{rf}} \, \delta\) ) and dispersion coupling ( \(x \leftarrow x + D_x \, \delta\) ) both use the \(\delta\) value that includes \(\delta_0\) , ensuring physical self-consistency.
Distribution selection
Based on the input file above, a bunch with a Gaussian distribution in the transverse direction and a MatchZ distribution in the longitudinal direction will be generated. By modifying the following two parameter lines, the type of generated bunch distribution can be adjusted:
"Transverse dist": "gaussian",
"Longitudinal dist": "matchz"
The values for the transverse distribution are: gaussian , kv , waterbag , parabolic , uniform-real , uniform-phase , and the values for the longitudinal distribution are: gaussian , coasting , matchz , matchdp .
When generating longitudinal gaussian and coasting distributions, RF-related parameters are not required. When generating matchz and matchdp distributions, RF parameters must be provided.
1D projection theoretical curves
The figure below shows the theoretical position projections of uniform-real, uniform-phase, KV, waterbag and parabolic distributions. All curves are normalized to \(\int_{-1}^{1} \rho(u) \, du = 1\), with position divided by its support half-width: \(u\in[-1,1]\). The uniform-phase and KV curves coincide. The increasing power trend from uniform-real (flat-top) to parabolic (peaked) can be clearly seen.
Figure 1. 1D projections of transverse distributions (theory)
Simulation results
Below, we show the simulated particle distribution figures obtained by keeping the Twiss, emittance, RF, and other parameters in the above input file unchanged and only changing the distribution type.
Transverse Gaussian distribution:
Figure 2. Transverse gaussian distribution: x-px
Figure 3. Transverse gaussian distribution: y-py
Figure 4. Transverse gaussian distribution: x-y
Transverse KV distribution:
Figure 5. Transverse KV distribution: x-px
Figure 6. Transverse KV distribution: y-py
Figure 7. Transverse KV distribution: x-y
Transverse waterbag distribution:
Figure 8. Transverse waterbag distribution: x-px
Figure 9. Transverse waterbag distribution: y-py
Figure 10. Transverse waterbag distribution: x-y
Transverse parabolic distribution:
Figure 11. Transverse parabolic distribution: x-px
Figure 12. Transverse parabolic distribution: y-py
Figure 13. Transverse parabolic distribution: x-y
Transverse uniform-real distribution:
The uniform-real and uniform-phase figures below, and their joint-action comparison, use the actual HDF5 injection output of example/01_generate_distribution (the transverse case), with 100,000 particles per distribution and Gaussian longitudinal coordinates. Their transverse inputs are \(\varepsilon_x=200\) mm mrad, \(\varepsilon_y=100\) mm mrad, \(\beta_x=\beta_y=0.5\) m, \(\alpha_x=-2.614303952\), \(\alpha_y=1.57442348\) and zero dispersion.
Figure 14. Transverse uniform-real distribution: x-px
Figure 15. Transverse uniform-real distribution: y-py
Figure 16. Transverse uniform-real distribution: x-y
Transverse uniform-phase distribution:
Figure 17. Transverse uniform-phase distribution: x-px
Figure 18. Transverse uniform-phase distribution: y-py
Figure 19. Transverse uniform-phase distribution: x-y; rectangular support with nonuniform density.
Figure 20. Joint actions \(q_x=I_x/(4\varepsilon_x)\) and \(q_y=I_y/(4\varepsilon_y)\). Red boundaries mark the uniform-phase square, waterbag triangle and KV line. Color gives measured particle counts per bin on one shared logarithmic scale.
Longitudinal MatchZ distribution:
Figure 21. Longitudinal matchz distribution: z-pz
Longitudinal MatchDp distribution:
Figure 22. Longitudinal matchdp distribution: z-pz
Longitudinal Gaussian distribution:
Figure 23. Longitudinal gaussian distribution: z-pz
Longitudinal Coasting distribution:
Figure 24. Longitudinal coasting distribution: z-pz
Initial distribution output format
When save_init_dist is enabled, each BunchConfig accepts
output_format="hdf5" (default, uncompressed),
"hdf5-gzip1" (gzip-1 + shuffle), or "tfs". The JSON key is
"Output format" inside the corresponding bunchN block.
This selects the initial-distribution output only; loading detects the
input format from its extension. See Table output formats.
At each source’s last scheduled injection event, after all sources scheduled at
that event have been injected, snapshots are saved for the current bunches that
contain this source’s particle IDs, including its lost records. Saving is not
delayed until other sources finish on future turns. A source split across several
current bunches produces one file per bunch, so each file has one consistent
current reference. Each snapshot contains the entire current bunch, including
other sources and zero-tag reservations for their future batches; rows are not
filtered by original source. Empty former slots do not produce snapshots.
The ordinary unchanged-group filename is retained. After a source moves, splits,
or changes grouping grid, _groupN identifies the current bunch in each filename.
With multi-turn injection, earlier batches may already have
been transported or lost; this file does not preserve each particle’s birth
coordinates. ParticleMonitor captures those coordinates separately at each
injection event for DA analysis. Loading a distribution reads its six coordinate
columns as a new incoming distribution; saved tags, loss history and reference
metadata are not a beam-state restore operation.
Saving first writes a complete private temporary file and then publishes it without overwriting an existing destination. An existing snapshot or input distribution at that path is preserved and reported as an error. A failed save can be retried at the interrupted injection event without injecting the same batch again. Successfully published group files are retained and skipped on retry; the source is complete only after every required group has been saved. If publication succeeds before an exception is delivered, file identity confirms the owned complete snapshot so a retry does not mistake it for an unrelated existing file. Tracking must remain paused at that event until the save succeeds.
Snapshot headers Ek and m0 describe the current bunch reference;
InjectionKineticEnergy retains the incoming source energy used for generation.
ReferenceArrivalTime (s), ReferenceBeta and ReferenceMomentum
(eV/c, per nucleon for ions) describe the reference at the post-injection save
event. Thus live-particle momentum is ReferenceMomentum * (1 + dp) and
arrival time is ReferenceArrivalTime - z / (ReferenceBeta * c).
HarmonicId, HarmonicNumber and ZCenter (m) record the current grouping;
BunchId identifies the current bunch, while SourceBunchId,
SourceHarmonicId and SourceHarmonicNumber retain the original injection
source identity. The saved z remains z_rel. These reference values apply only to live
particles: lost rows retain coordinates from their loss event. Other generation
settings such as emittance and Twiss parameters are not measured snapshot moments.
HDF5 loading reads only the current batch’s six coordinate slices and closes
the file after each batch. TFS loading caches column indices and byte offsets
at batch boundaries, then reads only the requested batch; file-size or
modification-time changes invalidate that cache. Neither path retains an open
file handle or caches the complete coordinate table. sequential advances
through the source rows; repeat restarts at the first row for each batch.
Preflight validation also scans HDF5 and TFS distributions in bounded blocks, including rows beyond the first injection batch. It checks the coordinate columns, finite values, physical longitudinal momentum and total row count, and caches only counts and diagnostics rather than the complete coordinate table. Explicit inserted-particle files use the same bounded preflight check; their runtime insertion still loads the requested complete first-batch input.