Skip to content

FieldMap (1-D / 2-D)

A FieldMap element integrates particles through a tabulated field (static B/E or RF B/E) read from external files. Used for realistic cavity and solenoid models that go beyond the hard-edge analytical matrices. HELIX implements the full TraceWin FIELD_MAP spec including the 5-digit geom encoding, every channel (static/RF × electric/magnetic), file-naming convention, and the FIELD_MAP_PATH directive.

TL;DR (TraceWin users)

FIELD_MAP  geom  L  θᵢ  R  kb  ke  Ki  Ka  FileName  [p_flag]
Param Meaning HELIX kw
geom 5-digit channel encoding (see below) geom (int)
L element length (mm) length
θᵢ RF phase offset (deg) phase
R aperture radius (mm) aperture
kb B-field amplitude scale kb
ke E-field amplitude scale ke
Ki space-charge compensation scale ki
Ka aperture flag (0/1/2) ka
FileName field-data file prefix resolved by the parser; stored as field_file
p_flag 0 = relative phase, 1 = SET_SYNC_PHASE calibration p_flag

HELIX honours every parameter exactly as TraceWin specifies them. Two that deserve a closer look:

  • Ki only rescales space-charge kicks: when Ki > 0 and a FileName.scc compensation table is present, the tracker applies a local SC fraction 1 − Ki·scc(z) inside the map. It therefore needs an active space-charge solver to have any effect — with no SC solver (or no .scc file) Ki is a no-op.
  • p_flag = 1 triggers the SET_SYNC_PHASE iterative phase calibration (a scan-fit for the entrance phase offset that makes phase behave as the synchronous phase). It is not an "absolute phase" switch; the parser forces p_flag=1 on maps under an active SET_SYNC_PHASE directive.

Tutorial

The geom 5-digit encoding

geom = aper·10⁴ + rf_B·10³ + rf_E·10² + stat_B·10 + stat_E

Each digit selects the geometry of one of five channels:

Digit Value Channel Common geometry
10⁰ E_static static electric 0 (absent), 1 (on-axis), 4 (2-D Er/Ez)
10¹ B_static static magnetic 0, 1 (on-axis Bz), 5 (2-D Br/Bz), 9 (quad gradient)
10² E_RF RF electric 0, 1 (on-axis Ez(z)), 4 (2-D Er, Ez)
10³ B_RF RF magnetic 0, 5 (2-D Br, Bz)
10⁴ aperture aperture profile from .ouv file 0 or 1

Examples:

  • geom = 100 — RF electric on-axis only. Common for SRF cavities modeled by Ez(z).
  • geom = 7700 — full 3-D RF, both E and B from 3-D Cartesian files. See FieldMap3D.
  • geom = 50 — 2-D static B-type (solenoid Br, Bz).
  • geom = 90 — 1-D static B as quad gradient G(z) — used to model PMQs (permanent magnet quadrupoles).

File naming

For a FileName of MyCavity and geom = 100 (RF electric on-axis), HELIX expects:

MyCavity.edz       # 1-D E_z(z) RF electric

Suffixes follow the three-letter TraceWin scheme .{e|b}{s|d}{x|y|z|r|q} — field letter (e electric / b magnetic), type letter (s static / d dynamic = RF), then the component (x, y, z, r, or q = θ):

Channel Type letter 1-D on-axis suffix
static E s .esz
static B s .bsz (also digit 9, quad gradient G(z))
RF E d .edz
RF B d .bdz

For a 2-D cylindrical RF E (geom digit 4), expect MyCavity.edr and MyCavity.edz (plus MyCavity.bdq for the TM-mode Bθ). A 2-D cylindrical B channel (digit 5) uses .b{s,d}r / .b{s,d}z (plus .edq for the TE-mode Eθ when RF).

The aperture file (when geom 10⁴ digit is 1) is MyCavity.ouv.

ASCII and binary map files

TraceWin writes field maps in ASCII or, after a conversion on its Chart page, in a binary form with the same file extensions. HELIX reads both and detects the binary form from the file content (an ASCII map is plain text; a binary map starts with a 4-byte integer). The binary layout is the one in the TraceWin manual — little-endian, packed:

Map Header Data
1-D int32 nz, float64 zmax, float64 norm (nz+1) × float32
2-D cylindrical int32 nz, float64 zmax, int32 nr, float64 rmax, float64 norm z outer, r inner, float32
3-D Cartesian int32 nz, float64 zmax, int32 nx, float64 xmin, float64 xmax, int32 ny, float64 ymin, float64 ymax, float64 norm z outer, y, x inner, float32

The file size must match the header exactly; a truncated file is refused with an error naming it. The manual gives no binary layout for 2-D Cartesian maps, so a binary file of that type is refused rather than guessed — use its ASCII version. Binary values are single precision: the PIP-II maps read in binary agree with their ASCII originals to within 1 × 10⁻⁷ of the peak field.

A missing map on a card with no field

A FIELD_MAP card whose map files are missing is dropped from the lattice with a warning — its field, and therefore the downstream energy and optics, would be wrong. The exception is a card with kb = ke = 0 and Ki = Ka = 0 (an unpowered corrector placeholder, common on PIP-II solenoids): it carries nothing but its length, so HELIX keeps that — as a drift, or as the span of the SUPERPOSE_MAP cluster it belongs to (at position 0 it still supplies the cluster aperture) — and reports the missing files once. Strict parsing still refuses any missing map file.

FIELD_MAP_PATH directive

Field-map files often live in a separate directory. The TraceWin FIELD_MAP_PATH directive sets the search path:

FIELD_MAP_PATH ../Fields
FIELD_MAP 100  300  -30  0  1.0  1.0  0  1  HWR_cavity

HELIX honours this directive — paths are resolved relative to the .dat file's directory, then the FIELD_MAP_PATH (most recent wins).

Tracking through a FieldMap

The 1-D / 2-D FieldMap element integrates with a single first-order midpoint kick-drift scheme: at each slice, all channels are sampled at the slice midpoint, the longitudinal energy kick and the transverse Lorentz kick are applied, then the particles drift to the slice end. There is no integrator selector on this element — the KD / DKD choice exists only on FieldMap3D. The step density is set by n_steps or by the lattice's PARTRAN_STEP global (whichever is finer).

The reference particle's W and φ_s are updated at every substep, so the FieldMap correctly accelerates the design beam.

Compiled step for 1-D maps

When every channel of the map is 1-D on axis (geometry 1, as in solenoid maps), the particle part of each slice -- the paraxial fields, the energy kick, the adiabatic damping, the phase slip, the Lorentz kick and the drift -- runs in one compiled pass over the particles (fm1d_step in linac_gen._fieldmap_kernels) on the CPU threads setting, instead of a long sequence of numpy array operations. It gives the numpy code's results bit for bit for every value that is not NaN, at any thread count: the same expressions in the same order, with the cos/sin phasors, the radius and the on-axis field samples still computed by numpy (tests/elements/test_fieldmap1d_step.py). A particle that already holds a NaN keeps NaN, but its sign bit may differ on some platforms, and for non-finite values (NaN, ±inf) numpy's floating-point warnings are not raised, nor errors under numpy.errstate(all="raise"). Maps with a 2-D or quadrupole-gradient channel keep the numpy code.

Time per slice of a 1-D solenoid map on a 14-core Mac (2026-10-12; the kernel takes about √(n / 1 500) of the threads, so the envelope's twelve probes stay on one):

Particles numpy Compiled
12 (the envelope's probes) 56 µs 20 µs
5,000 489 µs 85 µs
50,000 4.55 ms 0.54 ms

LINAC_GEN_FIELDMAP1D_KERNEL=0 keeps the numpy code, as does a compiled module built before the step existed.

Transfer matrix and per-step Lorentz integration

Unlike Drift, Quadrupole, and Solenoid, a FieldMap has no closed- form 6×6 transfer matrix — its dynamics are nonlinear in (x, y, z) because the field varies in space and (for RF) time.

The element instead integrates the equations of motion at each substep i ∈ [1, n_steps]:

\[ \begin{aligned} \frac{d\mathbf{p}}{dt} &= q\,(\mathbf{E}(\mathbf{r}, t) + \mathbf{v} \times \mathbf{B}(\mathbf{r}, t)) \\ \frac{d\mathbf{r}}{dt} &= \frac{\mathbf{p}}{\gamma m} \end{aligned} \]

For envelope-mode tracking and matching, HELIX builds a local 6×6 Jacobian at each substep by finite-differencing the integrator (the auto-diff variant is reserved for v2):

\[ M^{(i)} = \frac{\partial \, \mathbf{X}_{i+1}}{\partial \, \mathbf{X}_i} \quad\text{(6×6, evaluated at the synchronous particle)} \]

The substep matrices are chained — M_total = ∏ M^{(i)} — to give the element-level transfer matrix exposed via FieldMap.transfer_matrix(ref). This is what the matching and envelope workflows consume.

Block Effect
(x, x', y, y') 4×4 depends on field shape: Bz solenoid → coupled focus; on-axis Ez → adiabatic damping + RF defocus
(Δφ, ΔW) 2×2 acceleration + longitudinal RF focusing
Cross blocks non-zero whenever the field has off-axis structure (3-D maps, tilted solenoid, etc.)

Example: a PIP-II HWR cavity

The parser builds FieldMap objects from FIELD_MAP cards automatically; to construct one programmatically, use the FieldMap.from_file classmethod, which loads the field data for you:

API reference

Parameter Default Units Notes
name (required) — identifier
length (required) mm physical length of the field-map region
field_data (required) — FieldMapData; channel geometry 1, 4, 5, or 9
scale 1.0 — global field amplitude multiplier
kb 1.0 — additional magnetic-channel amplitude factor
ke 1.0 — additional electric-channel amplitude factor
ki 0.0 — SC compensation intensity (needs .scc + active SC solver)
ka 1 int aperture flag (1 = use .ouv profile if present)
phase 0.0 deg RF phase offset
frequency 0.0 MHz RF frequency
aperture 0.0 mm round-aperture radius; 0 = no check
n_steps 100 — integration sub-steps
p_flag 0 int 1 = SET_SYNC_PHASE iterative phase calibration
dx..yaw_deg 0.0 mm/deg misalignment (Misalignment mixin)
voltage_rel 0.0 — LLRF amplitude jitter (multiplies ke/kb)
phase_offset 0.0 deg LLRF phase jitter (adds to phase)
frequency_offset 0.0 MHz LLRF frequency jitter (adds to frequency)
field_file None — resolved field-file prefix (set by the parser)
geom None int raw geom code (set by the parser)

The FieldMap.from_file(name, filepath, length=None, scale=1.0, kb=1.0, ke=1.0, ki=0.0, ka=1, phase=0.0, frequency=0.0, aperture=0.0, n_steps=100, fm_type=1, p_flag=0) classmethod loads a single field-map file (fm_type: 1 = 1-D, 2 = 2-D electric, 7 = 2-D E+B) and infers length from the z table when omitted.

Source

linac_gen/elements/field_map.py:141 (constructor), :210 (from_file), linac_gen/io/tracewin_geom.py (geom decoder), linac_gen/io/field_map_reader.py (file loaders).

For the complete spec see docs/fieldmap_guide.md in the HELIX repo, which has the full TraceWin-compatibility detail.

See also

  • FieldMap3D — full 3-D Cartesian variant.
  • RFGap — thin-kick alternative.
  • PIP-II MEBT worked example — uses 4 QWR cavity field maps.

← RFGap · Continue to FieldMap3D →