This page documents distribution types for OPAL(X) input. Set the distribution type in your input file and configure the required attributes.
FROMFILE distribution
The FROMFILE distribution loads the initial particle phase space from a plain ASCII file. This is useful when importing particles from another code or from a previous OPAL/OPALX run (e.g. after converting an HDF5 phase-space dump to ASCII).
Required file format
The file must follow this structure (no variations allowed):
-
Line 1: A single integer: the number of particles
N. -
Line 2: A header line with column names (space- or tab-separated). The names define which column is position/momentum. Recognized names (case-insensitive):
x,y,z,px,py,pz(orpx/momentumx,py/momentumy,pz/momentumz). The order of columns in the file may be arbitrary; the header is used to map them. -
Lines 3..: Data lines. Each non-empty, non-comment line must contain at least 6 numeric values in the order implied by the header. Blank lines and lines starting with
#are skipped. There must be exactlyNsuch data lines.
Example file
1000 x px y py z pz 7.3797510200e-04 2.8811575176e-02 3.3682581175e-04 9.7591095318e-03 3.3682581175e-04 -2.2083905829e-02 ...
Usage
Set the distribution type to FROMFILE and set the attribute FNAME to the path of the ASCII file (relative to the input file or absolute). E.g.:
Dist1: DISTRIBUTION, TYPE=FROMFILE,
FNAME = "inputdistr.dat";
Make sure that the number of particles in the input distribution matches the number of expected particles in the BEAM element, otherwise you will get a warning.
=== Getting a correctly formatted file
The following minimal Python script converts the first phase space in an OPAL-format HDF5 file to the ASCII format required by the FROMFILE distribution (first line = N, second line = header, then data rows). It uses only the first step/snapshot in the HDF5 file.
#!/usr/bin/env python3
"""Convert the first phase space in an OPAL-format HDF5 file to the ASCII format
required by the FROMFILE distribution (N, header, data rows)."""
import h5py
import numpy as np
import sys
def first_phase_space_h5_to_ascii(h5_filename, out_filename=None):
if out_filename is None:
out_filename = h5_filename.rsplit(".", 1)[0] + "_fromfile.txt"
with h5py.File(h5_filename, "r") as f:
# Use first group that looks like a step (e.g. "Step#0" or first key)
step_key = None
for k in sorted(f.keys()):
if isinstance(f[k], h5py.Group):
step_key = k
break
if step_key is None:
raise ValueError("No step group found in HDF5 file")
g = f[step_key]
required = ["x", "px", "y", "py", "z", "pz"]
for k in required:
if k not in g:
raise ValueError(f"Missing dataset '{k}' in {step_key}")
x = g["x"][()]
px = g["px"][()]
y = g["y"][()]
py = g["py"][()]
z = g["z"][()]
pz = g["pz"][()]
n = len(x)
assert all(len(a) == n for a in (px, y, py, z, pz))
# Column order in file: x px y py z pz (matches typical OPAL H5 layout)
data = np.column_stack([x, px, y, py, z, pz])
header_names = "x px y py z pz"
with open(out_filename, "w") as out:
out.write(f"{n}\n")
out.write(header_names + "\n")
for row in data:
out.write(" ".join(f"{v:.10e}" for v in row) + "\n")
print(f"Wrote {n} particles to {out_filename}")
return out_filename
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python h5_to_fromfile_ascii.py <file.h5> [output.txt]")
sys.exit(1)
h5_path = sys.argv[1]
out_path = sys.argv[2] if len(sys.argv) > 2 else None
first_phase_space_h5_to_ascii(h5_path, out_path)
Usage: python h5_to_fromfile_ascii.py <file.h5> [output.txt]. If output.txt is omitted, the output is written to <basename>_fromfile.txt.
TODO. Consider looking at the old manual for that, but it should be the same and if not quite similar.