Skip to content

Ring-mode benchmark cases

Every ring-mode benchmark case, by level: what it checks, its reference, the tolerance with the result measured, and the test that keeps it — the list in benchmarks/ring/cases.yaml, from which this page is generated (python benchmarks/ring/report.py). The results are discussed in Ring-mode benchmarks; the reference codes are named there as here, by letter.

Analytic results and bookkeeping

Case What Reference Tolerance and result Test
L0.detect (M0) ring detection with negative controls (open spiral, half ring, straight line) analytic geometry — tests/ring/test_detect_config_particles.py
L0.coords (M0) exact coordinate conversions (HELIX, time lag, MAD-X), reference change, H- stripping reference code A's particle model (stored numbers); 50-digit mpmath round-off (atol 1e-15 vs the reference; <= 2 ulp vs mpmath) tests/ring/test_coords.py
L0.programs (M3) energy programs (resonant cycle, tables in three quantities), voltage and phase programs, validation; the phase rule, its mirror above transition, the cap and the refusal; paraphasing below and above transition, by number and by name pattern, and its refusals (cancelling, overlapping, beyond the ring); negative voltages (an H- deck, one reversed cavity) and other harmonics; a turn written into the node table; steerers that keep their field analytic 1e-14 (phase rule), 1e-13 (program ends) tests/ring/test_programs.py
L0.running_totals (M3) over 2000 turns the turn times add up to the reference's clock and the cavities' gains to its energy; turns to the end on the program's clock; the reference change exact and an identity without gain; the one-turn map's determinant over ramped turns analytic (sums; det = (p_start/p_end)^3, vertical block p_start/p_end) sums 1e-13; det 2e-6 (6-D, central differences) and 1e-10 (vertical) tests/ring/test_programs.py

Element maps and ring optics

Case What Reference Tolerance and result Test
L1.import_line_booster (M0) the simple Booster deck (LINE, inherited magnets) imported directly; one-turn optics MAD-X TWISS (RF voltage zero in both) Q, beta, alpha, Dx within 1e-9 tests/io/test_madx_lines.py::test_simple_booster_line_import_matches_madx
L1.import_deferred (M0) deferred (:=) attributes and elem->attr evaluated at use, as MAD-X MAD-X exact element lengths tests/io/test_madx_lines.py::test_deferred_semantics_match_madx
L1.kernels_reference_a (M1) each ring kernel against the same element of reference code A (24 cases), plain Python and compiled reference code A (stored; dev-only generator) 1e-13 relative (zeta 1e-14 m); three cases set by the reference's own rounding, documented in the test tests/ring/test_kernels_cartesian_reference.py
L1.symplectic (M1) every node's map symplectic in canonical coordinates (28 maps, 50-digit Jacobians; a non-symplectic map as the negative control) analytic (J^T S J = S) 1e-12 (measured <= 2e-16) tests/ring/test_kernels_symplectic.py
L1.ring_optics (M1) ring kernels' optics on the simple Booster (Q incl. integer part, Twiss and dispersion at 72 points, Q' with and without the bends' K2, alpha_c, gamma_t, 6-D Qs); pole-face models against reference code A's own optics MAD-X 5.09 TWISS and PTC_TWISS; reference code A (stored) Q 1e-6, beta/alpha/D 1e-6, Q' 0.02 vs MAD-X TWISS and 2e-3 vs PTC_TWISS, alpha_c 1e-6 (measured Q 2e-9, Q' 0.003) tests/ring/test_optics_booster.py
L1.fodo_analytic (M1) thin-lens FODO ring, exact and paraxial drifts analytic (2x2 cell matrix; thin-lens chromaticity sum) Q, beta, alpha 1e-12; Q' 1e-6 tests/ring/test_optics_fodo.py
L1.one_turn_contract (M1) every element's ring map linearized at the reference vs HELIX's own linac element matrix; the whole turn HELIX compute_transfer_matrix / get_element_matrix 1e-10 per element (50-digit Jacobians); whole turn 2e-8 (float64 finite-difference floor) tests/ring/test_one_turn_contract.py
L1.curvilinear_reference (M1) 1000 protons, two turns of the simple Booster, particle by particle; single elements; the reference's tunes and chromaticity; the curvilinear-vs-Cartesian difference explained as a sextupole -h k1 reference code B (stored; dev-only generator) x 2e-11 m, y 5e-14 m, ct 5e-12 m after two turns (the reference's own rounding, measured against a 40-digit run; 1e-12 relative is not reachable); single elements 1e-15 relative, beyond it only where the reference rounds differently (measured against 40-digit evaluations, at most 2.9e-10 m); Q 3e-8, Q' 2e-3 tests/ring/test_curvilinear_reference.py
L1.backends (M1) compiled serial, multi-core and plain-Python kernels bit for bit; the CUDA kernel in numba's simulator the CPU kernels bit for bit; CUDA simulator 1e-15 relative tests/ring/test_kernels_backends.py
L1.psb_chicane (M1) PSB injection chicane vs reference code A's pins (closed orbit -45.739596 mm, Q 4.396759/4.474427) reference code A's test data (PSB chicane) status: blocked — the PSB deck nests sequences and CALLs its strengths, which the MAD-X importer does not read (an importer gap kept out of M1) —

Single particles over many turns, the ramp

Case What Reference Tolerance and result Test
L2.invariants (M2) a small-amplitude particle in a thin-lens FODO ring, 10^6 turns through the turn loop; its Courant-Snyder invariants at the end vs the start (measured 3.6e-12) analytic (symplectic map, no drift) 1e-9 relative tests/ring/test_engine.py::test_invariants_do_not_drift
L2.fodo_ring_tune (M2) a FODO ring from reference code B's examples — tune by NAFF over 100 periods (0.188242184, the cell's to 2.2e-12), alpha_x, beta_x at the start the reference's published numbers (Q 0.1883, alpha -1.59050035, beta 2.82161941; its rtol 1e-3); the thick-lens cell analytically rtol 1e-3 against the reference; analytic 1e-12; NAFF vs the cell 1e-6 tests/ring/test_storage_benchmarks.py
L2.naff_tunes (M2) simple Booster, 1000 turns, one probe — NAFF tunes = the 6-D one-turn map's eigentunes (RF on; measured Qx 4.8e-10, Qy 2.0e-9, Qs 2.2e-10) and = the 4-D tunes (RF off; 1.1e-9, 2.2e-9); NAFF itself on pure tones to rounding from 3 periods on (tests/ring/test_naff.py) the ring optics (one-turn map) 1e-8 (Qs 1e-7); the plan asks 1e-4 tests/ring/test_engine.py::test_probe_tunes_are_the_one_turn_maps
L2.rf_bucket (M2) stationary bucket — started at zeta 0, 0.97 of the bucket height oscillates, 1.03 never turns back; above transition the 180-degree bucket and Qs the analytic separatrix (rf_bucket) — tests/ring/test_engine.py::test_the_separatrix_separates; tests/ring/test_optics_edges.py
L2.restart (M2) a run restarted from its checkpoint vs the uninterrupted run (also with every particle lost at the checkpoint's turn); one thread vs all; a checkpoint of another ring, or a restart with other probes or statistics interval, refused the uninterrupted run bit for bit tests/ring/test_engine.py
L2.ramp_follows (M3) 300 turns of a bunch through a resonant cycle — the run's reference record vs the reference alone; adiabatic damping (normalized vertical emittance and longitudinal emittance in eV s conserved while beta0 gamma0 grows 3 %; measured 3.3e-4 and 3.7e-4); Qs of the first turn's RF focusing vs the accelerating bucket (1.2e-3) and the probe's NAFF Qs within 2 % of the range between the bucket's at the start and end analytic (adiabatic invariant, accelerating-bucket Qs); the reference alone bit for bit (reference); emittance 2e-3; Qs 2e-3 (map), 2 % (tracked) tests/ring/test_ramp.py
L2.bucket_accelerating (M3) reference code A's accelerating bucket (Qs 0.0032729 below / 0.00176525 above transition, its ends -8.33333 / 4.7699056 m and mirrored); particles at 0.97 of the separatrix stay in every turn's bucket for 2.5 synchrotron periods of a 0.2 MV ramp at phi_s 30 deg, at 1.03 every one leaves reference code A's test of a bucket with a changing reference energy (its pinned numbers); the analytic separatrix Qs 1e-7, ends 1e-4 m (the reference's own); measured Qs 6.3e-8 tests/ring/test_ramp.py::test_the_accelerating_bucket_against_reference_code_a; tests/ring/test_ramp.py::test_the_accelerating_separatrix_separates
L2.transition (M3) a bunch started 150 turns below transition — the phase jumps to 180 deg - phi_s on the first turn above gamma_t, the bunch is shortest within 50 turns of it, no loss; a ramp started above transition reports no crossing, a decelerating one the downward crossing; a flat ramp is the fixed-energy ring (centroid 1e-12, moments 1e-9); restart bit for bit and refused with another ramp; threads bit for bit; the CUDA kernel in numba's simulator (1e-14) analytic; the fixed-energy ring; the uninterrupted run — tests/ring/test_ramp.py
L2.ramp_reference_b (M3) a generic ramp of the simple Booster (15 Hz cycle 800 MeV - 6 GeV, voltage table) in two segments, from the start (600 turns) and across transition (400 turns), 200 protons — the reference's gamma and time every turn, the bunch at the recorded turns reference code B (stored; dev-only generator, the ramp rule written again for it) gamma and time 1e-12 relative (measured 8e-15, 1.1e-13); bunch ten times the measured difference, growing with the turns (x 2.5e-12 m after a turn, 5.9e-11 after 600, 1.0e-10 m and c t 6.3e-10 m across transition) tests/ring/test_ramp_reference.py

Space charge

Case What Reference Tolerance and result Test
L3.gaussian_field (M4) the 2.5-D field solve (cell-integrated Green's functions, doubled grid) on the exact cell charges of a Gaussian, round and 3:1, inside 3 rms sizes; the round beam's potential Bassetti-Erskine (analytic); -(E1(r^2/2s^2) + ln r^2)/2 1e-3 of the largest field on 128 x 128 (measured 7.0e-4 / 8.0e-4; 3.0e-3 / 3.4e-3 on 64 x 64; second order in the cell) tests/ring/test_space_charge.py
L3.self_force (M4) a particle alone feels no kick; a bunch's kicks conserve its transverse momentum; the Green's functions are exactly antisymmetric (TSC and CIC) exact 1e-12 (FFT rounding) tests/ring/test_space_charge.py
L3.kick_2p5d (M4) one kick of a cold round Gaussian bunch, 400 000 particles, 96 x 96, 256 line-density bins J. Qiang, PRAB 28, 114602 (2025), eqs. 31-32 (analytic); reference code B's own test of this case allows 2 % / 20 % rms 1e-2 rms transverse, 5e-2 rms longitudinal (measured 4.5e-3, 2.6e-2) tests/ring/test_space_charge.py
L3.pipe_images (M4) round pipe (exact images), rectangle (32 fitted harmonics) against the exact series, rectangle and ellipse grounding the wall, an ellipse of equal axes against the round pipe image charges b^2/conj(w); the Fourier series of a grounded rectangle (analytic) round 1e-11 field (4e-16 measured); rectangle 1e-9 potential, 1e-6 field (6e-11, 1e-8); wall 2e-3 of the span; ellipse = round 1e-9 tests/ring/test_space_charge.py
L3.longitudinal (M4) the longitudinal kick of a uniform round beam in a round pipe from the potential, and from the geometry factor g = 1 + 2 ln(b/a); none when off or coasting -K_l f'(zeta) [(1 - r^2/a^2)/2 + ln(b/a)] (analytic; the line density as the bins and the filter see it) 1e-2 (measured 1.0014, 1.0018) tests/ring/test_space_charge.py
L3.laslett (M4) the incoherent tune shift of a coasting round beam in a ring focusing both planes alike (the integral C/(2 eps) exactly), NAFF of a probe over 256 turns; KV (PIC 100 000, 32 x 32, probe 0.5 sigma), Gaussian (PIC 100 000, 64 x 64, probe 0.2 sigma), Gaussian frozen (20 000, probe 0.1 sigma) Laslett 1963 (analytic), with the round Gaussian beam's detuning at the probe's amplitude KV 2 % (measured 0.998 / 0.999), Gaussian 3 % on the mean of the planes (0.976 / 0.994), frozen 2 % (0.998 / 0.991) tests/ring/test_space_charge.py (slow)
L3.bitwise (M4) the same bits for 1 and 4 threads; a restart (PIC, frozen, through a ramp) bit for bit; CUDA simulator deposit and moments the CPU's integers, kicks 1e-14; the CUDA session's space-charge step (for a real GPU — not yet run on one) exact bit for bit; 1e-14 tests/ring/test_space_charge.py, tests/ring/test_cuda_session.py
L3.cross_code_bunch_in_bucket (M4) the simple Booster at 800 MeV, RF on, a generic bunch matched inside the 200 kV bucket (1.5e10, 0.01 eV s as 6 pi times the rms, beta_t 1160.25 m; longitudinal space charge at the centre about as strong as the RF focusing, the bunch length swinging between 0.30 and 0.41 m), the same 50 000 initial particles in every code; HELIX against reference code A (Cartesian model at its settings) and reference code B (curvilinear model at its settings, two seeds, 1000 turns) reference code A (averaged 2.5-D, longitudinal kick on; the 150 turns it reached on one thread); reference code B (2.5-D, 128 line-density bins over the extent) bench test, 20 turns — against reference code A the bunch length, energy spread and longitudinal emittance to 5e-3, the betatron emittances to 1.5e-3 (measured over 150 turns 4.2e-3, 2.9e-3, 2.2e-3, 9e-4); against reference code B the betatron emittances to 1e-3 (7e-4 over 100 turns) and the bunch length at turn 5 to 5e-3; over 1000 turns the betatron growth 0.17-0.34 % (HELIX) against 0.40-0.52 % (reference code B), about the spread between seeds; reference code B's longitudinal growth (91-96 %, HELIX 2.6 %) is its line density (5.3 % instead of 48 % over 300 turns with 32 bins); HELIX converged over 200 turns in particles (25k/50k/100k, longitudinal 3.8/3.5/3.5 %, betatron x 0.090/0.061/0.052 % - noise heating), grid (128 x 128), line-density bins (128) and kicks (96) tests/ring/test_space_charge_booster_bench.py (bench)
L3.cross_code_example_bunch (M4) the simple Booster at 800 MeV, RF on, reference code B's example bunch (5e10, 0.1 eV s as 6 pi times the rms, partly outside the 200 kV bucket), the same 50 000 initial particles in every code, 1000 turns; HELIX against reference code B (curvilinear model at its settings) and reference code A (Cartesian model, the turns it reached), with diagnostics of the difference reference code B (2.5-D, 128 line-density bins over the extent); reference code A (averaged 2.5-D, longitudinal kick on) the first 10 turns to 1e-3 (measured 2.4e-4 longitudinal, 1.8e-4 betatron); reference code B's longitudinal growth (+18 % after turn 10, HELIX -0.1 %) traced to its line density — none without its longitudinal kick, +0.25 % instead of +2.4 % in 300 turns with 32 bins, HELIX +1.6 % with a line density as noisy; reference code A flat as HELIX (+0.2 % against -0.1 % over 150 turns); the longitudinal kick off in both, 6e-5 longitudinal and 3e-3 betatron over 300 turns benchmarks/ring/dev/sc_booster_compare.py --case generic (the runs dev-only) — a developers' check, not distributed with HELIX

Injection

Case What Reference Tolerance and result Test
L4.injection_analytic (M5) an H- stripped to a proton of the same velocity (800 MeV to 799.1296 MeV, delta -7.067e-4 against an 800 MeV proton), the injected centroid placed exactly, the ledger exact (injected = circulating + lost + waste), the macroparticles' weight I T / e over the filled buckets, the linac bunches of a turn and the chopper window, a beam missing the foil left as waste, the two-step stripping's waste, restart bit for bit in the middle of the injection, the same bits for any number of threads, the CUDA path in the simulator the formulas exact, or binomial 3 sigma (stripping); the CUDA simulator to 1e-14 tests/ring/test_injection.py
L4.foil_statistics (M5) 10^6 crossings of a 6 mg/cm2 carbon foil at 800 MeV, and a matched beam crossing a foil element every turn for 20 turns (its vertical action, no vertical dispersion) Highland's theta0 and the foil element's mean loss; the action growth beta theta0(N x)^2 / 2 after N crossings, Highland at the total thickness (1.37 times 20 one-crossing kicks here) theta0 and the mean loss to 0.5 %, the stripping fractions binomial 3 sigma; the action growth to 5 % tests/ring/test_injection.py
L4.bump_and_painting (M5) a closed bump of four thick kickers (20 mrad, 0.3 m) as exact straight-frame dipoles around a foil in the simple Booster — its height at the foil, in the optics and in the run's closed-orbit record turn by turn as the waveform takes it down; painting with a square-root waveform under a beam injected at the bump's full height the exact height of the arcs, 2 L theta/(1 + pz) + (gap - L) theta/pz; the actions of each turn's particles, gamma_y dy_k^2 / 2 the height to 1e-14 m; the mean action to 1 % tests/ring/test_injection.py
L4.bump_dipole_reference (M5) a thick kicker compiled as a bump dipole (exact, in a straight frame, hard-edge dipole fringe and pole faces) — horizontal and vertical, with and without fringe, with face angles, both signs — 48 particles crossing it at up to 70 mrad reference code A (a dipole in a straight frame, dipole-only pole faces) 1e-14 relative and 1e-14 m in the positions and zeta (the reference's position update (pz' - pz)/k0 rounds at about 1e-16/k0) — measured 3e-15 m tests/ring/test_injection_dipole_reference.py
L4.foil_scattering_reference (M5) a pencil beam of 800 MeV protons through carbon foils of 380 ug/cm2 to 20 mg/cm2 reference code C — its multiple scattering as single screened-Rutherford scatters, and its full model (with nuclear scattering and ionization loss) the core width (a Gaussian of the central 98 %, Highland's definition) to 2 % of HELIX's theta0 (Lynch & Dahl's form) at 6 and 20 mg/cm2 (measured 0.3-1.1 %) and to 7 % at 380 and 600 ug/cm2 (4.7-6.0 %, the formula extrapolated two orders below its fitted range); the distribution's central 68 % 17-20 % narrower at thin foils, its tail not modelled; HELIX's Bethe mean loss to 5 % of the full model's (2.7 %), the default tabulated rate 19 % lower; the full model's multiple scattering is Rossi's width, without Highland's logarithmic term tests/ring/test_injection_foil_reference.py
L4.psb_chicane_injection (M5) the CERN PS Booster (ring 1, 160 MeV, flattened by MAD-X), the measured injected distribution seven particles a turn for 142 turns, the four-magnet chicane collapsing over 500 turns (the table's times divided by 10), no RF, no foil reference code A (thick, the same bend integration, the chicane magnets as straight-frame dipoles with dipole-only faces, the particles in the file's order) the closed orbit at the injection point to 1e-9 m (measured 9e-12 m over the bump from 46 mm to 0); the tunes with the chicane at full strength to 1e-8 (6e-10 — Qy 4.4706 against 4.45 without, the chicane's edge focusing); the centroid within 2 % of the rms size (0.3 % x, 1.1 % y) and the rms sizes within 2 % (0.35 %, 1 %), turn by turn tests/ring/dev/test_psb_injection.py (HELIX_PSB_DATA) — a developers' check, not distributed with HELIX
L4.cuda_foil_step (M6) a CUDA run's foil step — the particles inside the foil found on the GPU, only those moved to the host and back and the injected slots sent to the GPU — with circulating particles crossing the foil turn after turn and statistics every third turn (numba's CUDA simulator) the same run on the CPU the foil's record (injected, hits, stripped, missed) and the ledger exactly; the particles and the energy left in the foil to 1e-14 and 1e-12; the beam never copied back whole, and the particles gathered at the foil the circulating hits recorded tests/ring/test_injection.py::test_a_cuda_runs_foil_step_moves_only_the_particles_at_the_foil

Many turns: losses and space charge through transition, painting

Case What Reference Tolerance and result Test
L5.losses_transition_reference_b (M6) the generic ramp from 300 turns before transition for 600 turns, a rectangular aperture (19 mm x 4 mm half widths) at the start of every cell (the dispersion 3.19 m there), 1000 protons in a bunch not matched to the bucket (its momentum spread swings to 2.7e-3 within 100 turns) reference code B, tracked cell by cell so that each loss has its cell the same particles lost, each on the same turn at the same cell (584 — 483 before transition, 101 after); the survivors within 2e-9 m (measured 1.6e-10 m in x, 3.7e-11 m in y, 1.2e-10 m in zeta); the reference particle's gamma within 1e-13 tests/ring/test_ramp_aperture_reference.py
L5.sc_transition_reference_b (M6) space charge through transition on the generic ramp of the simple Booster, from 300 turns before it for 600 turns — 5000 protons standing for 1.5e10 in a bunch 0.1 m long (rms) with about a third of the momentum spread its bucket matches, so that it rotates to 3.4 cm (turn 146) while the spread swells; 2.5-D space charge with the transverse kick alone (the reference's longitudinal kick heats a bunch by itself, L3); the line density over 4096 bins of the RF period (1.4 mm) reference code B (its 2.5-D space charge — 64 x 64 cells over 1.1 times the beam's extent, 128 line-density bins over the bunch) turn by turn, the horizontal betatron emittance within 4 % (measured 2.7 %; +44 % to transition against the reference's +47 %), the vertical within 1 % (0.64 %), the bunch length within 0.3 % (0.15 %), the energy spread within 0.5 % (0.30 %), the longitudinal emittance within 3 % (1.8 %; 16 times its start in both at the end), the reference particle's gamma within 1e-13; with 256 bins HELIX's peak line density is 20 % low at the shortest bunch and the growth to transition +13 %; at 5000 particles and fixed bins, four samples of the bunch +39.2 to +42.9 % with 2048 bins and +44.7 to +49.9 % with 4096 (the line density's noise); at 20 000 particles (dev runs) +41 % against +42 % with 4096 bins, all five within 1 % turn by turn; the default line density ("auto") +36.2 % at 5000 (34.4 to 37.9 %) and +36.1 % at 20 000 tests/ring/test_sc_ramp_reference_bench.py (bench — HELIX_RUN_BENCH=1)
L5.painting_reference_c (M6) a generic FODO ring (12 cells, 201.6 m, 800 MeV, coasting; its quadrupoles without the reference's hard-edge fringe, HELIX's drifts expanded as the reference's), a vertical bump of four thin kickers (6 mm at the foil) falling as 1 - sqrt(t/T) over 300 turns, held through each turn; 20 protons a turn injected 6 mm above the final orbit, the same 6000 in both codes in the same order and at the same energies; a foil that only counts its hits, and one of 600 ug/cm2 carbon; 400 turns reference code C (thick elements; its foil's single scatters) counting foil — the same particles circulate (5996); the hits per turn within 3 % + 5 (at most 7 apart) and in all within 1e-4 (604 089 against 604 109), per particle within 1e-4 (100.75); the emittances turn by turn within 2e-5 in y (3.1e-6) and 1e-4 in x (1.7e-5); each particle's final vertical action at the median within 5e-6 (5.6e-7), at the 99th percentile within 5e-5 (6.4e-6); the action quantiles within 2e-5 in y and 5e-5 in x (2.0e-6, 4.1e-6). 600 ug/cm2 — repeated crossings (about 100 a particle), each the growth of Highland's theta0^2 from one thickness to the next (kicks of the one-crossing width would be 1.30 times too narrow for 99 crossings) — the reference's foil share of the median horizontal betatron action 0.75-1.10 times HELIX's (measured 0.88; 0.84-0.90 over five reference runs, its foil's random numbers not seeded; a single-scatter estimate gives 0.88 — Highland at the total thickness 6 % wider than the single scatters' core, and the crossings' different betatron phases 5 %), the painted vertical action at the median within 5 % (1.2 %; -1.4 to +0.8 %) tests/ring/test_painting_reference.py

Speed

Case What Reference Tolerance and result Test
PT4 (M4) the simple Booster with 2.5-D space charge, 14-core Mac, 5 000 particles, 100 kicks a turn, 64 x 64, the default model, statistics every turn and a tune probe, 1000 turns — 1195 s (1.20 s a turn) with other runs on the machine at lower priority (load average 43 to 84) the target of the plan <= 60 min for 1000 turns — met (20 min) —
PT1 (M2) simple Booster, no space charge, 14-core Mac, 5 000 particles (the count chosen for the Booster runs, 2026-10-22) — per turn reference code B 0.323 s (14 threads; 6th order x 6 steps in bends and quads, 4th order x 5 in sextupoles), HELIX curvilinear model at 6th order x 6 in every magnet 0.207 s, cartesian with expanded bends 0.176 s, cartesian with exact bends (default) 0.300 s, a whole default run (statistics every turn, one probe) 0.320 s = 1000 turns in 5.3 min (reference 5.4); at 58 000 particles 2.16 / 2.46 / 2.10 / 3.56 s reference code B timed on the same machine and threads <= 10 min for 1000 turns and <= 1.5x the reference — met at 5 000 particles (5.3 min, 0.99x; curvilinear model 0.64x; the same run at M6 5.4 min); at 58 000 particles the 10 min is out of reach for both codes (reference 36 min) —
PT5 (M6) the GUI's event loop during a ring run started from the Run button — the simple Booster, 5 000 particles, 200 turns, every thread of the 14-core Mac, live updates on — a 5 ms timer on the GUI thread, five runs the target of the plan gaps < 100 ms — met (2026-10-25, the run shown in the Results tab, the Ring tab's live strip); three runs (the simple Booster, 5000 particles, 200 turns, 14 threads) - 99 % of the gaps under 11.1-11.3 ms, the largest 78.9-81.5 ms, Python's garbage collections during the run; the end of the run 49.2-50.7 ms - the Results tab's view of the run (1.4-1.6 ms), its tiles (39 ms) and the strip (0.5 ms). A run of 100 000 statistics rows - the end of the run 1.5 s (the view 0.44 s, the tiles 1.0 s), a turn-by-turn window opened in 0.2-0.8 s, a lattice edit with the ring run shown 0.38 s. At M7, not met by a small margin - the largest gaps 104.6-109.8 ms, each at the end of the run, the dashboard's redraw (about 15 ms of drawing) holding Python's full garbage collection (about 90 ms over the GUI's 455 000 objects); with the objects of the GUI's start-up frozen out of the collector's walks (gc.freeze, measured, a one-line change at the GUI's start-up, proposed), the largest gaps were 49.8-64.3 ms and the redraw 12-13 ms —
PT6 (M6) the linac workloads (the bit-identity probe's 61 run cases, one thread, best of two) and the GUI's start-up (to the main window shown and its first events processed, median of five), this tree against the release before ring mode, alternated the release before ring mode (master) within 5 % — met; the run cases 48.4 s in all against 48.7 s (each case over 2 s within 0.97-1.00), the start-up 2.17 s against 2.17 s —