Longitudinal slicing (Slicer)
The Slicer command assigns every live macro-particle in each bunch to a
longitudinal slice. It stores the result in a named SliceSet owned by the
bunch. Slicing is a local classification operation: it does not reorder any
particle array and it does not change bunch membership.
See Longitudinal coordinate and reference time for coordinate and time conventions. Choose a coordinate and named slice set, then execute Slicer before each collective-effect command that needs its updated data.
Configuration
An input entry uses the command name Slicer and a user-defined slice
set key:
{
"sc_slicer": {
"S (m)": 12.5,
"Command": "Slicer",
"Slice set": "space_charge",
"Coordinate": "z_periodic",
"Slice model": "equal_particle",
"Number of slices": 128,
"Z range mode": "auto",
"Save turns": [[0], [100, 1000, 100]]
}
}
The range configuration is mode-specific. No flat Z min, Z max or
Number of sigma fields are accepted.
autoUses the actual minimum and maximum of the current live distribution. It is the widest data-driven range and never excludes an observed outlier. If every live particle has the same selected coordinate, the range retains its true zero span; no artificial width is added.
explicitUses the fixed local interval supplied by
Explicit:"Z range mode": "explicit", "Explicit": {"Z min": -0.30, "Z max": 0.30}
All ranges are resolved at command execution. With z_rel or z_periodic, values outside an explicit
interval are clipped to the first or last slice and a warning is logged; they
are never silently dropped.
Slice IDs are ordered from high to low selected slice coordinate: slice 0 is the
largest-z interval and slice N-1 is the smallest-z interval.
Uniform-bin indexing uses FP64 arithmetic and checks the neighboring saved edge
after division, so a stored FP32 value just below a boundary keeps its correct
owner. Classification and the output table use the same generated edge array
on CPU, CUDA and the CUDA batch path. In increasing coordinate order,
equal_length bins are left-closed and right-open, except that the final bin
includes the maximum.
This does not change the precision of the particle arrays or local projections.
Interface Parameters
The following table lists the parameters accepted by a Slicer sequence
entry. JSON keys are shown in the spelling used by generated input files;
PASS normalizes key case internally.
Common command parameters
Parameter |
Key |
Type |
Default / required |
Description |
|---|---|---|---|---|
|
|
str |
Required |
Must be |
|
|
float |
Required |
Longitudinal machine position at which the slice data are updated. |
|
sequence object key |
str |
Required as sequence key |
Name of this command instance. The sequence loader also passes it to the command for diagnostics. |
|
|
str |
Required |
Name of the bunch-owned |
|
|
str |
|
Particle-to-slice mapping model. The only accepted values are
|
|
|
str |
|
|
|
|
str / str or null |
|
|
|
|
int |
10 |
Configured number of longitudinal bins. Must be at least 1; the value is retained even when the live population is smaller. |
|
|
str |
|
Selects |
|
|
list of int lists |
|
Optional snapshot selections: |
|
|
bool |
false |
Whole-ring arrival-phase projection for coasting WakeField; requires equal_length and an explicit interval of length C. |
|
|
float |
0.05 |
Maximum observed phase change per reference turn accepted by WakeField, in revolutions; (0, 0.1]. Diagnostic slicing records but does not enforce it. |
Range-mode parameters
Only the block corresponding to Z range mode is used. auto has no
mode-specific block. explicit requires the Explicit block.
Mode / parameter |
Key |
Type |
Default / required |
Description |
|---|---|---|---|---|
|
|
str |
Optional |
Uses the actual minimum and maximum of the current live distribution; observed outliers are included. |
|
|
str |
Optional |
Uses a fixed interval. |
|
|
object |
Required for explicit mode |
Mode-specific object containing |
|
|
float |
Required for explicit mode |
Lower bound in the selected slice coordinate; must be smaller than
|
|
|
float |
Required for explicit mode |
Upper bound in the selected slice coordinate; must be larger than
|
Configuration validation
At beam initialization, repeated Slicer entries referring to the same
Slice set must have identical Slice model, Number of slices, range
mode and (for explicit mode) the explicit block. A conflicting definition raises
ValueError and identifies both sequence entries. At execution, an
explicit range that does not cover all live particles produces a warning;
out-of-range particles are clipped to the first or last slice.
Within one beam, a named SliceSet may be shared by enabled consumers of
the same physical module, for example several WakeField commands. Different
modules must use different names: a wake and a beam-beam interaction cannot
consume the same set. Input validation reports the conflicting set, modules
and commands. Identical names on different beams are independent. Repeated,
compatible Slicer commands may still update the same set; this rule does not
change explicit update frequency or perform automatic reslicing. The same
input check reserves sets with Purpose=beam_beam for BeamBeam, even when
no BeamBeam command currently reads them. Commands that do not read slices,
such as a zero-interaction-length IBS, do not claim a set.
output_format (JSON "Output format") defaults to "hdf5-gzip1" and
accepts "hdf5" (uncompressed) and "tfs". The default uses gzip-1
with shuffle. The choice affects particle details only; slice summaries remain
TFS and CSV. See Table output formats for the HDF5 layout and reader.
Slice models
Use equal_particle in place of the former equal_charge or
Equal particle names; those names are no longer accepted.
equal_length divides the resolved interval into N equal-width bins:
For a nonzero range, equal_length requires finite, strictly increasing
FP64 edges. If rounding makes adjacent edges coincide, Slicer raises an error
instead of changing the interval or number of slices. This requirement applies
to both auto and explicit ranges; choose a representable interval or
fewer slices when necessary.
equal_particle sorts only temporary z values and indices, assigns IDs
by rank, and scatters those IDs back to the original particle order. The
particle pool itself is unchanged. Rank assignment keeps populations nearly
equal, including when several particles have identical coordinates. The saved
boundaries enclose these rank-assigned members; they also determine the widths
and centers consumed by SpaceCharge, WakeField and ECloud.
For \(n>0\) live particles sorted in increasing coordinate order as \(s_0,\ldots,s_{n-1}\), an interior boundary \(i=1,\ldots,N-1\) separates the ranks at \(k_i=\lceil in/N\rceil\). Starting from the linear quantile candidate \(q_i\) at fraction \(i/N\), Slicer saves
The outer edges remain \(e_0=z_{min}\) and \(e_N=z_{max}\). A candidate
already in its allowed gap is unchanged. Rank IDs and counts are unchanged,
including empty slices when \(N>n\). These intervals are closed envelopes:
slice_id determines ownership at shared endpoints and repeated coordinates.
Do not reclassify rank slices using the half-open coordinate-bin rule above.
Repeated coordinates can still produce zero-width slices; their density and
consumer requirements are described below.
With an explicit range, this enclosure applies to the clipped coordinates
used for slicing. Stored particle coordinates and actual member extrema are
unchanged. ECloud still rejects actual members outside its slice bounds; clipping
does not make such particles physically contained.
When an auto range has zero span at coordinate \(z_0\), every saved
z_min and z_max equals \(z_0\), and every delta_z is zero.
equal_length assigns all live particles to slice 0 and leaves the other
slices empty. equal_particle retains rank assignment. A bunch with no live
particles keeps its empty result.
Slots with no allocated particle records cache only zero-charge slice geometry
and refresh the observation time; they require no particle slicing and produce
no slot snapshots. This geometry lets stateful effects such as ElectronCloud
advance through zero-charge intervals. Bunches containing lost records or
reserved records for later injection still update and save their slices normally.
For an unallocated slot with an auto range, ElectronCloud uses the bunch
reference time as a zero-charge observation point instead of treating the tiny
fallback slice width as a physical pulse. Explicit empty intervals remain intact.
If the number of live particles is smaller than N, only that many slices
can be populated. The remaining slices are retained with zero count and a
warning is emitted. effective_num_slices records
\(\min(N_{live},N)\); the configured mesh size is not changed.
SliceSet data
Each bunch has a mapping such as bunch.slice_sets["space_charge"]. After
execution, slice_id is an integer array aligned with the bunch’s current
particle range; lost particles have ID -1. slice_table contains one
array per slice:
z_min,z_max,z_centerBoundaries and center in the selected slice coordinate, listed from high-z to low-z (slice
0is the high-z interval).z_particle_min,z_particle_maxActual minimum and maximum of the slice’s live macroparticle members in the selected coordinate at this Slicer execution. These values precede explicit range clipping and can therefore extend beyond the saved slice boundaries. Empty slices have NaN extrema; zero-width live slices have equal extrema. Beam-beam PIC uses these member bounds for head/tail sampling. Equal-particle rank membership, rather than quantile geometry, determines these extrema.
delta_zz_max - z_minfor each slice.macro_countNumber of live macro-particles.
real_chargeEquivalent number of real particles,
macro_count * bunch.ratio. It is not Coulombs; multiply by the signed particle charge and elementary charge when physical charge is required.lind_densityLinear real-particle density,
real_charge / delta_z. An occupied slice with zero width has undefined density, recorded as NaN; an empty slice has zero density.effective_num_slicesNumber of bins that can be populated by the current live population.
Zero-width slices remain usable for diagnostics and wake models that treat
slices as point sources. Consumers that require finite density, such as
SpaceCharge, reject occupied zero-width slices. For those consumers, use an
explicit interval with a physically justified finite width and a model such
as equal_length that gives the occupied slices finite widths. An explicit
range alone does not remove coincident interior edges in rank-based slicing.
SpaceCharge retains its existing requirement that every saved slice have positive
width, including empty slices.
Results also record valid_turn and valid_s. A subsequent global
regrouping clears all particle-dependent fields and consumers must wait for a
new Slicer execution.
Snapshots
Save turns is optional and belongs to the command instance, not the shared
SliceSet configuration. Each item is either [turn] or
[start, end, step] with inclusive endpoints. Slicing still runs on every
turn; only selected turns write files. Each selected execution writes a
same-instant particle HDF5 file (TFS when selected) (tag, z, slice_id, loss data) and a
per-slice TFS summary, also exported to CSV, to output/.../slice/. Particle and TFS summary files carry metadata that
identify the turn, position, beam, bunch, slice set, model and coordinate
convention.
An overlong end turn is clipped to the final simulated turn with a warning. A range whose start lies outside the simulated turn range is ignored with a warning. Negative starts are similarly clipped while preserving the configured step sequence; malformed ranges (an end before its start), non-integer values and non-positive steps remain errors.
Responsibilities
SortBunch and ReorganizeBunch perform global bucket assignment and may
reorder all particle arrays. They invalidate every existing SliceSet
because particle ranges can change. Slicer then recomputes the selected
set at its position in the sequence. Space-charge and beam-beam modules can
refer to different named sets and therefore use different slice meshes.
Important
After every executed SortBunch or ReorganizeBunch, run Slicer again before
using slice information. Sorting/regrouping clears the previous
slice_id and slice_table. Recompute each named SliceSet required
by subsequent commands, even if Slicer already ran earlier in the same turn.
Examples of actual execution order (each Slicer updates the set used by the following consumer):
Correct: SortBunch -> Slicer -> SpaceCharge
Correct: ReorganizeBunch -> Slicer -> WakeField
Incorrect: Slicer -> SortBunch -> SpaceCharge
The last sequence requires another Slicer between SortBunch and SpaceCharge. Consumers do not automatically rebuild invalidated slices. This rule applies on both CPU and CUDA. Slicer itself does not require a preceding SortBunch when the existing particle order and bunch grouping are unchanged.
The mapping uses current array positions: global particle index i belongs
to slice_id[i - bunch.start_idx]. tag moves with its particle during
sorting, but is not an index into slice_id. Keeping the same tags therefore
does not make an old slice mapping reusable after sorting. See Bunch Regrouping (ReorganizeBunch)
for the grouping operation.
The stored particle coordinate is the continuous bunch-relative coordinate
\(z_{rel}\). z_rel slicing uses it directly; z_periodic and
arrival_phase use temporary projections. None replaces the stored coordinate.
Slice coordinate and reuse
Coordinate=z_rel is the default: bin the continuous time-scaled coordinate
\(z=\beta_b c(T_b-t_i)\) directly for continuous wake timing.
SpaceCharge requires the separate z_periodic option described below.
The separate arrival_phase option forms a temporary periodic arrival
projection for coasting wakes. Periodic=true is an alias for that option.
ring_position is not supported: z plus a nominal slot offset cannot supply
an exact physical ring position under this coordinate definition.
The latest explicit Slicer result is authoritative. Its saved z intervals,
widths and memberships are reused until the user executes Slicer again.
RF never rescales, recenters or recomputes these arrays. A local interval of
width \(\Delta z\) in z_rel corresponds, at the current reference event, to
\(\Delta t=\Delta z/(\beta_b c)\) and center
\(T_b-z_{slice}/(\beta_b c)\). Thus saved intervals remain intervals in
the current z coordinate, not frozen physical time intervals. Reuse accuracy
is the user’s responsibility. Structural regrouping invalidates old local
indices and requires an explicit new Slicer execution.
Wake sources store their sampled physical times and widths when emitted. Subsequent reference changes cannot move historical sources. Periodic arrival-phase slices have a separately recorded common observation window; see WakeField for that approximation. Quasi-static SpaceCharge uses circumference-folded z intervals; time-scaled z is not an exact simultaneous three-dimensional spatial distribution for arbitrary velocity spread.
Z range mode remains auto or explicit. Particle storage stays in
the configured float32 or float64 precision; local bin arithmetic uses float64.
Saved slice boundaries, centers, widths and density tables use float64 on both
CPU and CUDA. CUDA promotes a local working coordinate when particle storage
is float32, so rounding the slice geometry cannot turn a uniform wake grid
into a nonuniform one. The tracked particle coordinates remain unchanged.
Snapshots preserve continuous z and record the reference time, beta and
coordinate definition. Periodic snapshots also include slice_coordinate.
The density is real-particle count per metre, not coulombs per metre.
Outside a collision frame, output metadata ZCoordinate="z_rel" describes the original particle z
column; it is output metadata, not an input option or a default assignment.
Coordinate identifies the selected slicing projection, while
CoordinateDefinition="z=beta*c*(T-t)", ReferenceArrivalTime (seconds)
and ReferenceBeta define the original particle coordinate. Arrival-phase
snapshots additionally save ObservationTime (seconds),
ObservationVelocity (metres per second), and SliceCoordinateDefinition.
Together with Circumference, these specify the saved observation window;
its time parameters can differ from the bunch reference parameters.
SliceSet runtime interface
The command configuration is converted to one SliceSet per bunch. The
following fields are available to SpaceCharge, BeamBeam and diagnostic code;
they are outputs of Slicer rather than additional JSON input parameters.
Field |
Type |
Valid before slicing |
Description |
|---|---|---|---|
|
str |
Yes |
User-defined lookup key from |
|
str |
Yes |
Normalized slice model name. |
|
int |
Yes |
Configured mesh size. |
|
str |
Yes |
Normalized range mode. |
|
|
Yes |
Canonical explicit bounds when explicit mode is selected. |
|
int array |
No |
One ID per particle in the bunch’s current particle range; lost
particles have |
|
dict of arrays |
No |
Per-slice geometry and population arrays listed in the SliceSet data section above. |
|
int or None |
No |
Simulation turn at which the result was generated. |
|
float or None |
No |
Sequence position at which the result was generated. |
Circumference-folded slicing for SpaceCharge
Coordinate=z_periodic forms the temporary coordinate
It uses the finite positive ring circumference, independently of the prescribed
clock. Both CPU and GPU support equal_length and equal_particle, with
auto or explicit ranges. auto uses the live folded-coordinate
minimum and maximum. explicit must lie within \([-C/2,C/2]\); use that
full interval for a whole-ring mesh, retaining empty bins. A narrower interval
clips out-of-range folded coordinates to boundary slices. A bunch straddling
the seam can give an auto range spanning nearly the whole ring.
SpaceCharge accepts only this coordinate. SC configuration requires "Coordinate": "z_periodic" in the corresponding Slicer. Missing coordinate metadata,
z_rel and arrival_phase are rejected by SC. This is the per-bunch
common-reference-velocity approximation; folding does not reconstruct an exact
simultaneous distribution for arbitrary velocity spread or combine overlapping
populations belonging to different bunches.
WakeField rejects z_periodic because its centers do not retain continuous
arrival times. Use separate named slice sets for SC and wakes. The
Periodic flag selects arrival_phase; Coordinate identifies
the mode, including in saved output.
Periodic arrival slicing for coasting wakes
Coordinate=arrival_phase requires equal_length, explicit and an
interval \([z_{min},z_{max}]\) of length C, for example
Explicit={"z min": -C, "z max": 0} or a centered [-C/2,C/2] interval.
At each explicit Slicer update, let \(a=n+s/C\) and let
\(\Psi(t)\) be the integrated prescribed revolution frequency. The physical
window endpoints and its linear coordinate mapping are
These windows meet exactly at their clock-cycle boundaries during acceleration; using the instantaneous frequency for their duration would create overlaps or gaps. For the centered interval, \(T_{obs}=(T_L+T_R)/2\). CPU and GPU form
The bins represent the window \([T_L,T_R)\), and retain that observation event until the next user update. Different bunch references are allowed; all populations contributing to one periodic wake must use the same saved observation window and circumference. Source bin 0 is the earliest arrival. Lost particles have ID -1; stored z is never folded. An exact seam phase maps to \(z_{phase}=z_{max}\), the start of the window and slice 0. The right-endpoint phase is periodically identified with the window start, rather than the last slice; no extra source passage is emitted. Slip diagnostics continue to use the continuous, unreduced phase \(u_i\).
Use a Slicer at the wake location with causal history. Reusing a periodic
snapshot does not advance its observation window; the user must update it for
each new physical source passage. This differs from reusing local z intervals.
SpaceCharge requires its own z_periodic SliceSet. The one-passage-per-reference-
turn approximation and convergence requirements are explained in WakeField.
Max phase slip defaults to 0.05 revolutions, with allowed values (0, 0.1].
Slicer records the continuous phase change at consecutive observations without
rejecting diagnostic output; WakeField checks the bound. Same-turn updates use
the same previous-turn baseline. Invalidation resets this diagnostic. It cannot
reconstruct unsampled crossings or prove convergence of short-wavelength modes.