MLM: choose the clustering history per diagram (beam.clustering_history) - #157
Open
oliviermattelaer wants to merge 4 commits into
Open
oliviermattelaer wants to merge 4 commits into
oliviermattelaer wants to merge 4 commits into
Conversation
MLMClustering takes a clustering_history. Under all_diagrams (the default) nothing changes. Otherwise every diagram also gets a state machine of its own, built from that diagram's lines only and appended after the one over every diagram. The union keeps the first flavour it meets on a mask, so the W/Z of a VBF diagram can end up read as gluon fusion's gluon; the per-diagram machines keep each diagram's own. The kernel takes a start state per event, and a history_mode. Under madevent it walks the diagram and the union, and keeps the union unless the two call a different number of legs merging jets, as setclscales does when it reclusters along the channel. MLMClusteringAlongDiagram exposes the walk from Python. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
With a clustering_history other than all_diagrams, the union history only serves the pdf prior for the flavour sampling. The matrix element is evaluated at its scales for the normalised diagram weights. One diagram is picked from them, the event is clustered along it, and the matrix element is evaluated again at that history's scales, with its pdfs, merging cut and alpha_s and pdf reweighting. The second evaluation keeps mixed coupling orders exact, where a rescaling by alpha_s ratios would not be. The channel weights come from the first evaluation. The xqcut, alpha_s and pdf reweighting factors move into Integrand::mlm_weights so both paths share them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
all_diagrams (default, unchanged), diagram or madevent, passed to MLMClustering by the launcher. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…event setclscales stores a leg's clustering scale only from jet vertices its line is still a good jet at, and a line stops being one at the first leg iqjets does not call a merging jet. Every other leg is written at sqrt(s), which tells the shower's MLM matching to leave that parton alone. The kernel booked every QCD vertex onto the legs instead. So a VBF tagging quark that radiated a gluon kept the scale of that emission and was matched as a merging jet: in madevent 0% of the p p > h j j j (QCD=1) weight has only one of the two tagging quarks non-merging and the gluon merging, in madspace 20%. Only under scale_scheme = madevent with the production jet scale scheme, which is madevent's. The emission scheme keeps its booking. Cross sections do not move; only pt_clust does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
oliviermattelaer
force-pushed
the
claude/mlm-diagram-history
branch
from
September 15, 2026 23:45
fa05dcf to
2dc49ed
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
beam.clustering_historyto the mg7 MLM back-clustering. It chooses which diagrams a clustering history may follow:all_diagrams(default)diagrammadeventall_diagramshistory unless it calls a different number of legs merging jets than the picked diagram does, and fall back to the diagram thenIt also ports madevent's
ptclusrule for the LHEpt_clust_iunderscale_scheme = "madevent", as a separate commit. Only legs that iqjets calls merging jets take a clustering scale; every other leg is written at sqrt(s).Depends on
beam.clustering_measure(87c4967, already on the base branch). All validation below usesclustering_measure = "madevent".Implementation
MLMClustering(mlm_clustering.cpp): under a per-diagram history, compiles one state machine per diagram from that diagram's own lines and appends it after the union machine.diagram_start_states()maps a diagram index to its root offset (0 = none, use the union).Kernel (
kernels/mlm.hpp): the walk takes a per-eventstart_stateand returns its merging-jet count. The newhistory_modeinput implements the madevent rule by walking the diagram, then the union, and re-walking the diagram if the counts differ.Integrand: under a per-diagram history the union clustering only feeds the pdf prior for the flavour sampling. Then:The second evaluation keeps mixed coupling orders (gluon fusion + VBF) exact; rescaling by alpha_s ratios would not. The shared weight factors moved into
Integrand::mlm_weights.Run card:
beam.clustering_historyinRunCardMG7andrun_card.toml, wired inlaunch.py.Restriction: a single matrix element per integrand (throws otherwise).
Validation
Parton-level cross sections, madspace / madevent
Same cards on both sides (
ickkw=1, NNPDF23_lo_as_0130_qed, maxjetflavor 4,dynamical scales, jet_radius 1.0),
clustering_measure = "madevent",scale_scheme = "madevent". 100k events (W 150k, tt~ 50k, VBF 30k).p p > h +0-3j, h > ta+ ta-(15)qq>qq(the VBF-like channel)QED=0(15)h j j QCD=0+h j j j QCD=1(20)p p > e+ ve +0-3j(15)p p > t t~ +0-3j(20)tt~ in
diagrammode is 7% low by design: inside a single diagram an FSR gluonoff a top cannot be taken into the beam instead, so its scales and pdf ladder
change. madevent only reclusters along the channel when the merging-jet count
differs, which is what the
madeventmode does.Showered, MLM-matched rates (MG5aMC_PY8_interface), HEFT, xqcut 15
Ratio to madevent of the merged cross section and of the per-multiplicity rates.
The 0.547 at qcut 75 is the effect this branch is about: madspace's VBF-like jets
were matched and vetoed because they had been clustered as gluon-fusion jets.
DJR spectra (kT, R=1) around the matching transition at qcut 75, ratio to
madevent: all_diagrams 0.82-0.90, diagram 0.98-1.00, madevent 0.99-1.01.
pt_clust (second commit)
Fraction of the p p > h j j j (QCD=1) weight where only one of the two tagging
quarks is non-merging (
pt_clust = 13000), i.e. a tagging quark the shower isallowed to veto on:
A residual difference stays in the classes where the two quarks come from a
W/Z decay: madevent puts 3.3% of the weight in "gluon merging, one decay quark
merging", madspace 0.1-0.4%.
W+jets, fraction of events with one non-merging leg, after the commit:
madevent 0.305 (2j) / 0.405 (3j), all_diagrams 0.014 / 0.042 (unchanged by the
commit - none of these legs sits at a jet vertex the union history calls
non-merging), diagram 0.318 / 0.441, madevent-history 0.300 / 0.402.
HEFT 3j non-merging-leg distribution after the commit (0/1/2/3 legs):
madevent 0.752/0.122/0.121/0.004, diagram 0.742/0.124/0.130/0.004
(0.784/0.122/0.090/0.004 before).
The ported samples are bit-identical to the pre-port ones in every event record
apart from the
<scales>line, for all three history modes (VBF and HEFT), sothe commit moves no cross section: VBF stays at 1.011 / 0.999 / 1.004
(all_diagrams / diagram / madevent). The fraction of outgoing partons written
at sqrt(s) over the whole VBF sample goes from 0.849 (all_diagrams) and 0.840
(diagram) to 0.868 / 0.875 / 0.875, against madevent's 0.871.
Showered, MLM-matched rates, pure VBF, xqcut 20
Ratio to madevent, before and after the ptclus commit (30k events, so the 3j
rates carry 1.6-2.4% statistical errors).
The showered 3j deficit reported for pure VBF was the pt_clust bookkeeping, not
the history selection: it is gone in
all_diagramstoo.Showered, MLM-matched rates, W + 0-3j, xqcut 15
Ratio to madevent, with the ptclus commit in (150k events).
The 3j rates carry 2-4% statistical errors.
Cost
Generation-phase CPU, per-diagram modes vs all_diagrams: HEFT 1.6x, W 1.25x,
VBF 2.2x (two matrix-element evaluations per event, plus a second clustering).
Test plan
madspace/tests/test_mlm.py: 120 passed. The new tests cover: per-diagram machines extend the union machine; the union walk is unchanged; the walk along a diagram reports that diagram; a one-diagram process clusters the same both ways; the madevent history is always the union or the diagram; each diagram uses its own line flavours; ptclus for a non-merging radiating quark.all_diagramsruns are bit-identical (event records) to samples generated before this change with the same seed and cards (VBF, HEFT, HEFT QED=0)./tests/test_manager.py): 1549 tests, 3 pre-existing reds(
test_output_standalone_accepts_loop_induced,test_output_standalone_cpp_refuses_loop_induced, MadLooptestIO_UnitProcOutputIOTests), none of them touching the run card or bannerRebased onto
claude/madspace-madevent-scalesat 8a1b37c (which carries themain merge and the updated
feat-mlm); all four commits applied cleanly, andboth suites above were re-run on the merged base.
The generation runs were made with these four commits on 87c4967, i.e. before
the rebase, which changed no clustering, scale or integrand code. Re-checked on
the merged base (62897e4), 30k events of the VBF process:
all_diagramson this branch and the base branch alone, same build, giveidentical event records and the same integral (0.19522 pb). The only
difference anywhere is
pt_cluston jet legs (1257 of 30000 events), from theptclus commit;
mur,muf,muf1andmuf2are untouched.diagramgives 0.19283 pb against 0.19288 before the rebase, andall_diagrams0.19522 against 0.19518 - both within 2.5e-4, far inside the0.17% statistical error, so the ratios to madevent above are unchanged.
(The base branch could not run MLM at all until 62897e4: the main merge
renamed the madspace observable
m_invtopair_masswhileapply_auto_ptj_mjjstill asked for
jet-m_inv, so everyxqcut > 0run raised TypeError. Diagnosedhere, fixed by the branch owner.)
Test plan
madspace/tests/test_mlm.py: 120 passed. The new tests cover: per-diagram machines extend the union machine; the union walk is unchanged; the walk along a diagram reports that diagram; a one-diagram process clusters the same both ways; the madevent history is always the union or the diagram; each diagram uses its own line flavours; ptclus for a non-merging radiating quark.all_diagramsruns are bit-identical (event records) to samples generated before this change with the same seed and cards (VBF, HEFT, HEFT QED=0)./tests/test_manager.py): 1549 tests, 3 pre-existing reds(
test_output_standalone_accepts_loop_induced,test_output_standalone_cpp_refuses_loop_induced, MadLooptestIO_UnitProcOutputIOTests), none of them touching the run card or bannerRebased onto
claude/madspace-madevent-scalesat 8a1b37c (which carries themain merge and the updated
feat-mlm); all four commits applied cleanly, andboth suites above were re-run on the merged base.
The generation runs were made with these four commits on 87c4967, i.e. before
that rebase. They cannot currently be repeated on the merged base: any mg7 run
with
phasespace.xqcut > 0fails there, before any of this code is reached.The main merge renamed the madspace observable
m_invtopair_mass, whileapply_auto_ptj_mjjin mg7/launch.py still doesso
ms.Observable(all_pids, observable='m_inv', ...)raises TypeError for everyMLM run -
setdefaultcreates that cut even for a card that never had one, sofresh process directories are affected too. Confirmed to be pre-existing and
untouched by this PR: 8a1b37c checked out on its own, with its own madspace
built from source, fails identically on the same process directory (reported to
the branch owner). The rebase changed no clustering, scale or
integrand code, so the numbers above stand; I will re-run the VBF cross-check on
the merged base once that is fixed.
🤖 Generated with Claude Code