NLO+PS polarisation: put the MC-counterterm azimuth in the me_frame - #79
NLO+PS polarisation: put the MC-counterterm azimuth in the me_frame#79oliviermattelaer wants to merge 9 commits into
Conversation
get_mbar() took borntilde from a boosted sborn_frame but kept azifact and
the mother azimuth in the partonic c.m., so the phase multiplying the
spin-correlated Born belonged to a different frame than the Born itself.
fks_singular.f solved the same problem with azifact_me_frame; the MC
counterterms are evaluated at generic y_ij_fks, where <ij>/[ij] is regular
and can simply be recomputed on boosted momenta.
Measured on p p > z{0} j [QCD], me_frame=[3], against the covariant
collinear reference: the ISR phase error was a constant 37/63/157 degrees
all the way to 1-y = 1e-10; it now falls off like sqrt(1-y).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds test_polarised_nlo_ps_me_frame (generate_events on p p > z{0} j [QCD],
me_frame=[3]) and wires it in as acceptancetest_106. It asserts on the ratio
of the absolute to the total cross-section, which is what the MC-counterterm
azimuth controls: 2.23 before the fix, 2.00 after, while the total itself is
unchanged at 1.4 sigma.
Records M5 in the plan, including the pre-existing upstream bug that makes
test_MC pass vacuously.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- azifact_mc_frame's header no longer claims the legacy convention
unqualified: the collinear branch pre-cancels the caller's mother factor,
so azifact is <ij>/[ij] only in the generic one.
- state the identity that makes the two branches agree,
lim_{kt->0} <ij>/[ij] = -exp(2 i psi) exp(2 i phi_m).
- the collinear branch is now taken at kt exactly zero rather than below
1-y = 1e-12. The spinors are exact at any kt>0, while the kperp
reconstruction carries an O((kt/E)/betaT) error that the betamin guard
does not bound (it bounds |beta|, not betaT). Boosted path only.
- record why the legacy inline copies of the spinor azimuth stay.
- cut the three new routine headers; comment share of the Template diff
goes from 34% to 27%.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…reak Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
On hold — do not merge yet. Review of a follow-up branch found a pre-existing MadLoop-core bug that this PR can reach. Measured on This PR is reachable in principle — any run_card NLO mode whose polarised massive particle is the last Born leg, e.g. Held on Olivier's call until the |
Polarised cross-sections at NLO were validated at fixed order only. This makes the
NLO+PS (MC@NLO) path frame-consistent as well, and adds a test with a verified
negative control.
The bug
get_mbar(Template/NLO/SubProcesses/montecarlocounter.f) tookborntildefrom aboosted
sborn_framebut built the azimuthal phase entirely in the partonic c.m. —azifactfrom unboosted emission spinors,cphi_mother=±1from the mother lying onthe beam axis.
borntildeis the ±gluon-helicity interference, so the mother'slittle-group phase enters it, and that phase only cancels against the one in
azifactif both are computed in the same frame.fks_singular.fhad already solvedthis at fixed order with
azifact_me_frame.Nothing blocked NLO+PS: no guard distinguishes fixed order from event generation,
and
generate_eventsran end to end on the unfixed code. The failure was silent.Measured on
p p > z{0} j [QCD],me_frame=[3]: the ISR phase error was a constant37.4°, 63.4° and 156.6° on three collinear scans, flat down to
1-y = 1e-10. It neverconverged. After the fix it falls off like
sqrt(1-y)(10.07° → 0.97° → 0.097° →0.0003°).
The change
Three routines in
boost_to_frame.f—me_frame_born_boost,azifact_from_spinors,azifact_mc_frame— andif (me_boosted) … else <legacy verbatim> endifat bothget_mbarsites, plus the same edit inmontecarlocounter_alt.f(dead code, butleaving the two copies inconsistent is a trap). The
R_y(pi)flip is skipped when aframe is requested: it only put a
j_fks=2mother back on+z, and for a one-legframe it would also flip the polarisation axis of the leg at rest — harmless for
{0},but it would swap
{+}/{-}.The collinear branch is now taken only at exactly
1-y <= 0. At anykt>0the spinorroute is exact and the
kperproute is an approximation, so there is no case forpreferring the approximation.
Validation
generate_events aMC@NLO --parton -f, 1000 events,iseed=33, nn23lo1, fixed scales91.188, ptj 30, etaj 4.0,
me_frame=[3](FRAME_ID = 8read back fromSource/run_card.inc):The total must not move and does not (1.4 sigma) — the MC counterterm cancels between
the S and H event. The absolute cross-section must move and does, by 30 sigma: it
measures how local the subtraction is, which is what the azimuth controls. Repeated on
a fresh pair with
iseed=7717: 2.2220 → 2.0060, totals agreeing at 0.02 sigma.me_frame=[3,4]onp p > z{0} z{0} j [QCD]: 3.134e-01 ± 2.2e-03 pb, agreeing withthe fixed-order value at 1.3 sigma, 20/20 poles in all 12 P dirs.
No frame requested stays bit-identical. Two copies of one output dir differing only
in the changed files:
res_0/1/2.txtand the 2.1 MBevents.lhe.gzcompare byte forbyte.
Test
test_polarised_nlo_ps_me_frame, wired in asacceptancetest_106(the workflowinvokes tests by explicit name, so an unwired test never runs). It passes on the
branch, and with
montecarlocounter.falone reverted it fails on the intendedassertion —
AssertionError: 2.22732091828047 not less than 2.15— reproducedindependently by the reviewer.
Caveats, stated rather than omitted
MG5aMC_PY8_interfacewasbuilt against v3.5.15 and its C++ link fails on arm64, strictly after
events.lheis written. Everything this PR touches is upstream of the handover, but no showered
polarised event was produced on this machine.
test_MCis vacuous upstream and passed on the broken code — it is not evidencefor this change.
test_soft_col_limits.fassigns the samexmcsubt_wrapresult toboth sides of the comparison, so
checkres2sees a ratio of exactly 1 and returnsPASS unconditionally. Two further breaks in the same area (the split-order sub-check
comparing one ME under two jacobians, and
ilim=0aborting onMCcntcalled) arerecorded in the M5 doc. All three are pre-existing on
mainand are being handledseparately.