Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
7df832b
add chek crossing functionality (with f2py call to fortran)
oliviermattelaer Jul 21, 2026
077c737
Extend crossing symmetry to standalone_cpp/mg7 and add check-crossing…
oliviermattelaer Jul 22, 2026
af7f5d0
Keep crossed subprocesses under --use_crossing=False (restore 3.x com…
oliviermattelaer Jul 22, 2026
0af8317
madevent crossing M0 (slice 1): SMATRIX/MATRIX crossing holes, OFF by…
oliviermattelaer Jul 22, 2026
ce366da
madevent crossing M0 (slice 2): ON path for the group SMATRIX (compil…
oliviermattelaer Jul 22, 2026
85ded67
madevent crossing M0: disable helicity recycling for a crossing output
oliviermattelaer Jul 22, 2026
2d8d1ff
madevent crossing: support helicity recycling (drop the disable)
oliviermattelaer Jul 22, 2026
1fbac01
madevent crossing #6/#7 (piece 1): partition_crossing_classes helper
oliviermattelaer Jul 22, 2026
a5e3b6a
madevent crossing #6/#7: make partition_crossing_classes per-flavor
oliviermattelaer Jul 22, 2026
d7bed92
madevent crossing M0 fix: NFLAV must be iden (max_flavor), not masks
oliviermattelaer Jul 22, 2026
262042f
madevent crossing #6/#7: per-flavor auto_dsig routing to a shared bas…
oliviermattelaer Jul 22, 2026
5411452
madevent crossing: helicity recycling + router (drop the merged-group…
oliviermattelaer Jul 22, 2026
685b2fa
madevent crossing: madevent now accepts crossing (update the gate test)
oliviermattelaer Jul 22, 2026
f0cf84c
madevent crossing: fix router LHE colour flow (COLMAP)
oliviermattelaer Jul 22, 2026
b7a1cc7
madevent crossing: block beam polarisation + EVA under crossing
oliviermattelaer Jul 22, 2026
bed7fd6
madevent crossing Track B: cross-group ME reuse via symlink (lepton/p…
oliviermattelaer Jul 22, 2026
d390d9a
madevent crossing Track B: share the base .o + parallel build of all …
oliviermattelaer Jul 22, 2026
a2c0a0c
madevent crossing Track B: event helicity (+colour) remap for cross-g…
oliviermattelaer Jul 22, 2026
e1a456a
madevent crossing Track B: share the optim too via a union good-hel
oliviermattelaer Jul 22, 2026
ab2ed1c
madevent crossing Track B: tag 'crossing' limitation for cross-group too
oliviermattelaer Jul 22, 2026
523f888
madevent crossing Track B: CONFIGMAP for the multi-channel channel
oliviermattelaer Jul 22, 2026
2184a7b
madevent crossing: degate cross-group sharing for hadronic p p
oliviermattelaer Jul 22, 2026
4ec2ae7
aloha: drop the T-channel (spacelike) propagator width at runtime
oliviermattelaer Jul 23, 2026
d0fae02
madevent cross-group crossing (Track B): fix colour selection and hel…
oliviermattelaer Jul 23, 2026
5a09d7a
madevent crossing: fix crossed-leg event helicity label (drop the ext…
oliviermattelaer Jul 23, 2026
2b22dd5
standalone helicity: replace the NHEL table with a canonical encoder/…
oliviermattelaer Jul 23, 2026
9d23414
madevent crossing: get_nhel decoder + runtime crossed-helicity encode
oliviermattelaer Jul 24, 2026
562abbb
test: madevent crossed W+ helicity asymmetry (p p > w+ j) regression
oliviermattelaer Jul 24, 2026
ba11fe7
colour: canonical colour-flow code (generator + injectivity test)
oliviermattelaer Jul 24, 2026
23ae101
colour: decoder for the canonical colour-flow code + round-trip test
oliviermattelaer Jul 24, 2026
f75fff4
test: LHE colour-flow structure + ratio for p p > t t~
oliviermattelaer Jul 24, 2026
d35498a
test: use u u~ > u u~ for the LHE colour-flow guard (strongly asymmet…
oliviermattelaer Jul 24, 2026
1f3cbbb
madevent crossing: route the router's colour translation through the …
oliviermattelaer Jul 24, 2026
48b360e
madevent: rebuild event colour tags from the canonical code, drop the…
oliviermattelaer Jul 24, 2026
4b59d3b
mg7: emit the canonical colour-flow code into subprocesses.json
oliviermattelaer Jul 24, 2026
62f3ffb
madmatrix: bake the colour-flow code into coloramps.h
oliviermattelaer Jul 24, 2026
5ead1b3
Merge remote-tracking branch 'origin/main' into claude/fortran-cross-…
oliviermattelaer Jul 24, 2026
8b7512d
crossing: unify the good-helicity remap on a runtime encode (drop the…
oliviermattelaer Jul 25, 2026
d424f1e
crossing: record crossed subprocesses as metadata instead of dropping…
oliviermattelaer Jul 25, 2026
36f74a1
crossing (standalone): fold crossed subprocesses into the base direct…
oliviermattelaer Jul 25, 2026
d3db049
crossing (madevent/grouped): reconstruct crossed subprocesses from me…
oliviermattelaer Jul 25, 2026
88b5c83
crossing: make merge_crossing='record' the default (standalone folds …
oliviermattelaer Jul 25, 2026
a7c766c
test: partition test generates unmerged (merge_crossing='record' is n…
oliviermattelaer Jul 25, 2026
c539500
crossing (check_sa): demo only the folded subprocesses, at their stan…
oliviermattelaer Jul 25, 2026
6e683be
crossing (standalone_cpp): drop the ghremap table for a runtime good-…
oliviermattelaer Jul 26, 2026
1eb6ec7
crossing (standalone_mg7): crossed-event selected helicity code [UNVA…
oliviermattelaer Jul 26, 2026
4663f18
crossing (standalone_mg7): per-lane helicity — drop the good-hel unio…
oliviermattelaer Jul 26, 2026
66e3ae0
check crossing (standalone_mg7): add --precision (f/m/d) build option
oliviermattelaer Jul 26, 2026
901eae7
crossing (standalone_mg7): fold crossed subprocesses into the base di…
oliviermattelaer Jul 26, 2026
9b8772b
crossing (standalone_mg7): check_sa demos the folded crossings at the…
oliviermattelaer Jul 26, 2026
7ca8de3
crossing (standalone): compute the crossed denominator at runtime, dr…
oliviermattelaer Jul 26, 2026
cfae5ff
crossing (standalone_mg7): zero an invalid crossing's ME instead of m…
oliviermattelaer Jul 26, 2026
879764b
crossing (standalone_cpp + standalone_mg7): decode the crossing at ru…
oliviermattelaer Jul 26, 2026
35706c9
zerowidth_external: drop the width of an external particle's internal…
oliviermattelaer Jul 27, 2026
b8c086f
goodhel (standalone): C-parity de-duplication of the helicity sum
oliviermattelaer Jul 27, 2026
9727872
Switcher interface update
oliviermattelaer Jul 27, 2026
1184f5a
goodhel (standalone_cpp): C-parity de-duplication of the helicity sum
oliviermattelaer Jul 27, 2026
b0d0fd4
goodhel (madevent): C-parity de-duplication of the init full-sum loop
oliviermattelaer Jul 27, 2026
1af4acf
goodhel (standalone_mg7): C-parity de-duplication of the helicity sum
oliviermattelaer Jul 27, 2026
c3f49fb
goodhel (madevent group): C-parity de-duplication of the init full-su…
oliviermattelaer Jul 27, 2026
6e2e1de
goodhel (madevent recycling): C-parity amplitude-drop in matrix<i>_op…
oliviermattelaer Jul 27, 2026
b7cf9aa
Merge branch 'main' into claude/fortran-cross-symmetry-3f13f3
oliviermattelaer Jul 27, 2026
8dd6dc7
update ALOHA IOTest goldens for the T-channel runtime width drop
oliviermattelaer Jul 27, 2026
6bbab77
tests(aloha): materialize reduced-expression temporaries in globals (…
oliviermattelaer Jul 27, 2026
299f6aa
crossing: fix _build_flav_pdg_tables IndexError on decay chains
oliviermattelaer Jul 27, 2026
952d727
zerowidth_external: keep the width on decay-chain resonances
oliviermattelaer Jul 27, 2026
9bcdc0a
crossing (decay chains): build tables over decay leaves, exempt the I…
oliviermattelaer Jul 27, 2026
f1a7472
tests(export_v4): update test_header + test_generate_helas_diagrams f…
oliviermattelaer Jul 27, 2026
5c9563c
tests(consistency): unblock crossing + compare 4 backends per flavor
oliviermattelaer Jul 28, 2026
808b29a
crossing (decay chains): inherit and apply production crossings
oliviermattelaer Jul 28, 2026
d2b0831
tests: madevent decay-chain crossing xsec regression
oliviermattelaer Jul 28, 2026
2849a38
madevent: skip redundant hel recycling of Track B symlinked matrices
oliviermattelaer Jul 28, 2026
bcd5457
tests(flavor): unblock crossing fallout + bump the t-channel-width re…
oliviermattelaer Jul 28, 2026
ad99cac
zerowidth_external: keep the width of off-shell-tagged fields; refres…
oliviermattelaer Jul 28, 2026
f72bebe
tests(density_mode): refresh the reference density matrices + observa…
oliviermattelaer Jul 28, 2026
89425f0
madspin: generate the decay matrix element with --use_crossing=False
oliviermattelaer Jul 28, 2026
69e5b95
madspin/mg7: fix parallel build race on aloha_object/model_object F90…
oliviermattelaer Jul 28, 2026
6dcfedd
tests(decay-chain/grouping): unblock crossing guard + refresh ALOHA g…
oliviermattelaer Jul 28, 2026
d915ff8
tests: register zerowidth_external default + unblock polarized-decay …
oliviermattelaer Jul 28, 2026
1003dc9
crossing: never cross perturbative processes; robust decay/reweight/l…
oliviermattelaer Jul 29, 2026
a9464af
fix test_mass_reweighting: refresh reference for crossing-aware tree-…
oliviermattelaer Jul 29, 2026
9dc63b2
MadSpin: consume folded crossed subprocesses in the onshell/density path
oliviermattelaer Jul 29, 2026
ca08083
tests(parallel): refresh ALOHA python goldens + short-xsec reference …
oliviermattelaer Jul 29, 2026
2ae2f5d
gauge test: treat the propagator width consistently across schemes/ga…
oliviermattelaer Jul 29, 2026
6667a9f
MadSpin: make single-top t-channel work with crossing across all spin…
oliviermattelaer Jul 29, 2026
ad6daaa
tests(decay-comparator): unblock crossing guard on the decay generations
oliviermattelaer Jul 29, 2026
233ce84
fix FD gauge link failure for massive-lepton Goldstone-Yukawa (FFVx_F…
oliviermattelaer Jul 29, 2026
6cfa00e
tests(mlm-reweight)+reweight: unblock crossing guard; fix --use_cross…
oliviermattelaer Jul 29, 2026
d19891c
crossing: expand folded crossings automatically instead of demanding …
oliviermattelaer Jul 29, 2026
2d89c93
goodhel (C-parity): make the de-duplication all-or-nothing and persis…
oliviermattelaer Jul 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 87 additions & 15 deletions MadSpin/decay.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,30 @@
logger = logging.getLogger('decay.stdout') # -> stdout
logger_stderr = logging.getLogger('decay.stderr') # ->stderr

import contextlib

@contextlib.contextmanager
def _no_merge_crossing():
"""Temporarily disable crossing-symmetry folding (merge_crossing='record')
for the enclosed MG5 generation.

MadSpin's legacy full_decay_chain (madspin_v1) and onshell_v1 paths evaluate
the production matrix element through a PDG-dispatch interface (the
standalone_msP fortran driver / smatrixhel) that cannot reach a crossing-
folded subprocess, so their generation must keep every subprocess on its own
(as before the crossing feature). The density path is crossing-aware and
keeps crossing on. MG_MERGE_CROSSING=off is the documented escape hatch
(see madgraph_interface.do_add)."""
saved = os.environ.get('MG_MERGE_CROSSING')
os.environ['MG_MERGE_CROSSING'] = 'off'
try:
yield
finally:
if saved is None:
os.environ.pop('MG_MERGE_CROSSING', None)
else:
os.environ['MG_MERGE_CROSSING'] = saved

import random
import math
from madgraph import MG5DIR, MadGraph5Error
Expand Down Expand Up @@ -3097,11 +3121,12 @@ def generate_all_matrix_element(self):

commandline = commandline.replace('add process', 'generate',1)
logger.info(commandline)

mgcmd.exec_cmd(commandline, precmd=True)

with _no_merge_crossing():
mgcmd.exec_cmd(commandline, precmd=True)
commandline = 'output standalone_msP %s %s' % \
(pjoin(path_me,'production_me'), ' '.join(list(self.list_branches.keys())))
mgcmd.exec_cmd(commandline, precmd=True)
(pjoin(path_me,'production_me'), ' '.join(list(self.list_branches.keys())))
mgcmd.exec_cmd(commandline, precmd=True)
logger.info('Done %.4g' % (time.time()-start))

# 3. Create all_ME + topology objects ----------------------------------
Expand Down Expand Up @@ -3181,7 +3206,8 @@ def generate_all_matrix_element(self):
commandline += self.get_proc_with_decay(proc, one_decay, mgcmd._curr_model, self.options)
commandline = commandline.replace('add process', 'generate',1)
logger.info(commandline)
mgcmd.exec_cmd(commandline, precmd=True)
with _no_merge_crossing():
mgcmd.exec_cmd(commandline, precmd=True)
# remove decay with 0 branching ratio.
mgcmd.remove_pointless_decay(self.banner.param_card)
commandline = 'output standalone_msF %s %s' % (pjoin(path_me,'full_me'),
Expand Down Expand Up @@ -5123,7 +5149,17 @@ def generate_all_matrix_element(self):

commandline = commandline.replace('add process', 'generate',1)
mgcmd = self.mgcmd
mgcmd.exec_cmd(commandline, precmd=True)
# The legacy onshell_v1 path (mode=='onshell') evaluates the production
# ME through smatrixhel, which dispatches on concrete PDGs and returns 0
# for a crossing-folded subprocess (-> production_me==0 -> ZeroDivision).
# Keep every subprocess on its own for it, exactly like full_decay_chain.
# The density path (mode=='density') is crossing-aware (GET_DENSITY_IDX
# via _resolve_crossed) and keeps crossing on.
if self.mode == 'onshell':
with _no_merge_crossing():
mgcmd.exec_cmd(commandline, precmd=True)
else:
mgcmd.exec_cmd(commandline, precmd=True)
# remove decay with 0 branching ratio.
#mgcmd.remove_pointless_decay(self.banner.param_card)
#
Expand All @@ -5135,16 +5171,52 @@ def generate_all_matrix_element(self):
# store information about matrix element
for matrix_element in mgcmd._curr_matrix_elements.get_matrix_elements():
me_string = matrix_element.get('processes')[0].shell_string()
for me in matrix_element.get('processes'):
dirpath = pjoin(path_me, ms_me_subdir, 'SubProcesses', "P%s" % me_string)
# get the orignal order:
initial = []
final = [l.get('id') for l in me.get_legs_with_decays()\
if l.get('state') or initial.append(l.get('id'))]

def register(leg_ids, _pdir="P%s" % me_string):
# ``leg_ids`` is the ordered list of external PDG ids (initial
# then final, in leg order). Build the (sorted) lookup tag and
# keep the natural leg order for momentum extraction. A base
# process always wins over a crossed one, so never overwrite.
initial = [i for i, l in zip(leg_ids, order_state) if not l]
final = [i for i, l in zip(leg_ids, order_state) if l]
order = (tuple(initial), tuple(final))
initial.sort(), final.sort()
tag = (tuple(initial), tuple(final))
self.all_me[tag] = {'pdir': "P%s" % me_string, 'order': order}
tag = (tuple(sorted(initial)), tuple(sorted(final)))
self.all_me.setdefault(tag, {'pdir': _pdir, 'order': order})

for me in matrix_element.get('processes'):
legs = me.get_legs_with_decays()
order_state = [l.get('state') for l in legs]
register([l.get('id') for l in legs])

# Crossed subprocesses folded into this matrix element with crossing
# symmetry on (merge_crossing='record') were NOT generated as their
# own directory: only the representative partner is on disk. Its
# crossing-aware SMATRIX (smatrixhel dispatches on the signed PDGs,
# see interface_madspin.calculate_matrix_element) can still compute
# them, so register each crossed process against the SAME pdir.
# Without this the onshell/density lookup misses e.g. the recorded
# q q~ > t t~ g (partner of the kept q g > t t~ q) and raises
# KeyError. The decays never cross (they ride on their production
# leg), so re-attach the base decay chains before expanding, exactly
# as the exporter does for the check_sa crossing demo.
try:
crossed_processes = matrix_element.get('crossed_processes')
except Exception:
crossed_processes = []
base_decays = matrix_element.get('processes')[0].get('decay_chains')
for cross_entry in crossed_processes:
proc = cross_entry[0]
if base_decays:
proc = copy.copy(proc)
proc.set('decay_chains', base_decays)
# empty LegList (same class as proc's legs) forces
# get_legs_with_decays to recompute with the re-attached decays
proc.set('legs_with_decays', proc.get('legs').__class__())
legs = proc.get_legs_with_decays()
else:
legs = proc.get('legs')
order_state = [l.get('state') for l in legs]
register([l.get('id') for l in legs])

return self.all_me

Expand Down
Loading
Loading