Skip to content

models: UFO vertex spinor chains keep their order and chirality (lone ProjM/ProjP were swapped) - #27

Open
ValentinHirschi wants to merge 2 commits into
mainfrom
fix/ufo-vertex-spinor-chains
Open

ValentinHirschi wants to merge 2 commits into
mainfrom
fix/ufo-vertex-spinor-chains

Conversation

@ValentinHirschi

Copy link
Copy Markdown
Collaborator

Defect

models/tensors.py lowered a UFO vertex's spinor chain in reverse. Each spinor index went on its partner leg's slot, and each bispinor tensor was passed to spenso in (column, row) order. Single Gamma, Gamma5, Identity and Sigma came out right. Gamma*ProjM/ProjP (the SM FFV couplings) came out right only because UFO ProjM/ProjP were also exchanged for spenso's projp/projm, which cancelled the reversal. Everything else in a vertex chain was wrong:

  • a lone projector had the opposite chirality: FFS1 ProjM(2,1) was evaluated as P_R, FFS3 as P_L, and FFS2 ProjM - ProjP changed sign;
  • Gamma*Gamma5 (an axial current written with Gamma5) changed sign;
  • Sigma*ProjM/ProjP (chiral dipoles) had the opposite chirality;
  • products of explicit gamma matrices were reversed.

Who is affected

Any UFO whose physical fermion-scalar couplings use lone projectors is affected. That is the usual FeynRules output for chiral Yukawas: charged and pseudoscalar Higgses (2HDM-type), scalar leptoquarks, VLQ Higgs couplings. UFOs with Gamma*Gamma5 or Sigma*Proj vertices are affected too.

The packaged Standard Model in unitary gauge is not affected. Its W/Z/photon/gluon couplings are FFV1-5, the Higgs Yukawa is FFS4 = ProjM + ProjP, and both are unchanged. Its only lone-projector vertices are the G0/G± Goldstone Yukawas, which unitary gauge absorbs.

Reproducer

The model is MadGraph's sm UFO plus H+ (300 GeV) coupling as H+ bbar (yHL P_L + yHR P_R) t + h.c., with yHL = 1 and yHR = 0.2. It is written with the sm's own FFS1/FFS3. The process is b b~ > h+ w-, which has one diagram: a t-channel top between the chiral W vertex and the H+ vertex. Its helicity sum, |M|² = yHL² A + yHR² B with A ≠ B, distinguishes the two chiralities. The comparison is against MadGraph5_aMC@NLO 3.7.0 standalone smatrix (tools/developer/madgraph_correctness.py, with the param card rewritten at full precision), at the same phase-space point.

process main 9404776 this PR MadGraph rel. diff main → PR
b b~ > h+ w- 0.1179259503614339 2.5517392015448026 2.5517392015448048 9.5e-1 → 8.7e-16
g b > t h- (blind: helicity sum invariant under yHL ↔ yHR) 2.3784605836902582e-3 2.3784605836902552e-3 2.3784605836902743e-3 6.7e-15 → 8.0e-15
e+ e- > mu+ mu- 6.520451045205551e-3 identical 6.520451045205548e-3 5.3e-16
u d~ > w+ g 5.289886199733631 identical 5.289886199733627 6.7e-16
g g > t t~ 0.5555267718906728 identical 0.555526771890673 4.0e-16
t t~ > z h 0.1442820500823878 identical 0.14428205008238146 4.4e-14

MadGraph with yHL and yHR exchanged returns 0.117925950361434 for b b~ > h+ w-, which is main's value to all digits.

Both codes are evaluated at the same momenta (pyAmpliCol's validation momenta, whose incoming legs are massless, so the massive-b and massive-top rows are off-shell but identical in both codes). The integration test below uses an on-shell point (MT = 173) and agrees with MadGraph and with an independent Dirac-trace calculation.

Fix

Vertices keep every spinor index on its own leg's slot and give spenso the (row, column) order, using UFO's own projectors. The tensor network then evaluates the chain in source order. Propagators keep their own order and are unchanged.

Compiled-model check: for the packaged sm UFO and JSON (default restriction), only 42 of 804 oriented kernels change. All 42 are G0/G± FFS1/FFS2/FFS3 kernels (V_77, V_88, V_103, V_112, V_122, V_139, V_147), plus those 9 vertex terms' Lorentz expressions. Every other IR record is byte-identical, including all FFV, FFS4, VVV, VVS and contact kernels, propagators and contractions. Without a restriction it is 156 of 1008 kernels, all of them Goldstone.

Tests

  • tests/unit/test_model_tensors.py: new UFO-identity checks after lowering:

    • lone ProjM/ProjP against (1 ∓ Gamma5)/2;
    • FFS2 against -Gamma5;
    • the axial current;
    • Sigma against its gamma commutator;
    • Sigma*ProjM.

    The projector heads in the factory test are corrected. On main, 8 of these cases fail; with this PR all 33 tests in the file pass.

  • tests/integration/test_ufo_chiral_scalar_coupling.py (6 s): builds the H+ model from the packaged sm UFO and checks b b~ > h+ w- against hard-coded MadGraph values for (yHL, yHR) = (1, 0.2) and (0.2, 1). On main it fails: for (1, 0.2) it returns MadGraph's (0.2, 1) value, 0.113229984185047.

  • The 65 model/tree test files that compile models or import tensors.py were run, one pytest process each, with a staged release native runtime and the pinned symbolica 3.0.0 / ufo-model-loader 1.0.0. 55 pass and 7 skip every test (their prerequisites are not present). Two fail identically on main because the environment has no staged C SDK / rusticol-config (OTF C API) and no profiling-campaign checkout. One is a load-dependent profile-timing test that passes on rerun.

Origin

This is ported from the loop integration branch, commit 3ae3454 ("models: vertex spinor chains keep their order and chirality"). There, the bug showed as an O(1) Feynman-vs-unitary gauge difference for t t~ > z h. The vertex-lowering hunks apply unchanged to main.

The loop line's companion commit e66b4b2 (Goldstone flag closed under charge conjugation) is not included. The faulty Particle.anti() exists only in the NLOCT-style object library of loop_qcd_qed_sm(_Gmu), which main cannot load at all ("Parameter dMB_HWcft_UV_EW has no expression and no value"); MadGraph's shipped sm passes goldstoneboson correctly. A loadable UFO with the same defective anti() would keep G- as a physical scalar next to the W- in unitary gauge.

For the reviewer

  • The UFO compile cache and compiled-IR files are invalidated automatically, because the compiler fingerprint hashes models/*.py. Prepared bundles (*.pyamplicol-model) of affected UFO models made with ≤ 1.0.1 are not: they are checked only against MODEL_COMPILER_VERSION (16), which this PR does not bump, because that would also invalidate the unaffected built-in prepared packs. Either bump it or say "rebuild prepared bundles of BSM UFOs" in the release notes.
  • Existing artifacts from affected UFOs keep the old values. Process artifacts never check which model compiler built them, so artifacts generated with 1.0.0/1.0.1 from a UFO with lone-projector, Gamma*Gamma5 or Sigma*Proj vertices still load and return the reversed-chirality results; they must be regenerated (a release-note item). Bumping MODEL_COMPILER_VERSION would not catch them either.
  • The built-in built-in-sm-heft prepared packs embed the 42 old Goldstone kernels, but no vertex binding uses them (all Goldstones are absorbed; none of the 1030 bindings involves PDG 250/±251), so their evaluation is unaffected.
  • docs/user/ufo-model-coverage.md: the 'Chiral structures' row now cites the new identity and MadGraph tests instead of the packaged Standard Model, which in unitary gauge never exercised a lone projector.

🤖 Generated with Claude Code

ValentinHirschi and others added 2 commits October 26, 2026 00:55
The Lorentz lowering of a UFO vertex put each spinor index on its partner
leg's slot and each bispinor tensor in (column, row) order, so the tensor
network evaluated a vertex's spinor chain in reverse. A single Gamma, Gamma5,
Identity or Sigma was right, and Gamma*ProjM/ProjP chains (the SM FFV
couplings) were right only because UFO ProjM/ProjP were also exchanged for
spenso's projp/projm. A lone projector therefore had the opposite chirality
(FFS1/FFS3: ProjM evaluated as P_R; FFS2 = ProjM - ProjP flipped sign),
Gamma*Gamma5 (the axial current written with Gamma5) flipped sign, Sigma times
a projector had the opposite chirality, and products of gamma matrices were
reversed.

Vertices now keep every spinor index on its own leg and pass spenso its
(row, column) order with UFO's own projectors, so the network evaluates the
chain in source order. Propagators keep their own order.

In unitary gauge the packaged Standard Model is unaffected: compiling the
sm UFO and JSON models changes only the 42 Goldstone FFS1/FFS2/FFS3 kernels
(G0, G+, G- Yukawas, absorbed in unitary gauge); every FFV, FFS4, VVV, VVS,
contact and propagator record is byte-identical. A UFO whose physical scalar
couplings use lone projectors is affected: for b b~ > h+ w- with a charged
scalar coupling as H+ bbar (yL P_L + yR P_R) t (FFS1 + FFS3), pyAmpliCol
returned 0.1179259503614339 against MadGraph5_aMC@NLO 3.7.0's
2.5517392015448048, i.e. exactly MadGraph's value with yL and yR exchanged;
now 2.5517392015448026 (relative difference 9e-16).

Tests: tests/unit/test_model_tensors.py checks UFO identities after
lowering (lone ProjM/ProjP against (1 -/+ Gamma5)/2, the FFS2 pseudoscalar,
the axial current, Sigma as its gamma commutator, Sigma*ProjM) and the
projector heads; tests/integration/test_ufo_chiral_scalar_coupling.py (6 s)
compares that b b~ > h+ w- with MadGraph for (yHL, yHR) = (1, 0.2) and
(0.2, 1).

Ported from the loop line (3ae3454); main's vertex lowering was the same
code, so the hunks apply unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…raph chiral-coupling tests

The packaged Standard Model in unitary gauge never exercises a lone
projector, so it could not validate ProjM/ProjP.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant