Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
]
},
install_requires=['pyyaml', 'ckmutil>=0.3.2', 'pandas',
'wilson'],
'wilson', 'pylha>=0.4'],
extras_require={
'testing': ['nose'],
},
Expand All @@ -33,6 +33,7 @@
'wcxf2dsixtools = wcxf.cli:wcxf2dsixtools',
'dsixtools2wcxf = wcxf.cli:dsixtools2wcxf',
'wcxf2smeftsim = wcxf.cli:smeftsim',
'wcxf2smeftfr = wcxf.cli:wcxf2smeftfr',
]
},
)
19 changes: 19 additions & 0 deletions wcxf/cli.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,22 @@ def dsixtools2wcxf():
args = parser.parse_args()
dsixtools.dsixtools2wcxf(tuple(f for f in args.FILE), stream=args.output)
return 0


def wcxf2smeftfr():
from wcxf.converters import smeftfr
parser = argparse.ArgumentParser(description="""Command line script to convert a WCxf file to a MadGraph param_card file for SmeftFR.""",
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument("FILE", nargs='?', help="Input file. If \"-\", read from standard input",
type=argparse.FileType('r'), default=sys.stdin)
parser.add_argument("--card", required=True, help="Path to a SmeftFR parameter card necessary to define the output format",
type=argparse.FileType('r'))
parser.add_argument("--output", nargs='?', help="Output file. If absent, print to standard output",
type=argparse.FileType('w'), default=sys.stdout)
args = parser.parse_args()
card = pylha.load(args.card, comments=True)
info_dict = smeftfr.analyze_smeftfr_param_card(card)
wc = wcxf.WC.load(args.FILE)
wc.validate()
smeftfr.wcxf2smeftfr(wc, info_dict, card, stream=args.output)
return 0
96 changes: 96 additions & 0 deletions wcxf/converters/smeftfr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import pylha
import json
import pkgutil
import re
from wilson.util import smeftutil


def format_smeftfr(s):
"""Recast the string representation of SMEFT WCs used in SmeftFR's line
comments to WCxf Warsaw-basis format."""
t = s[1:] # drop 'C'
t = t.replace('w__2', 'W') # special case: 'W' Wilson coefficient
t = re.sub(r'(\w)(\d)x(\d)x(\d)x(\d)', r'\1_\2\3\4\5', t) # 4-fermion
t = re.sub(r'(\w)(\d)x(\d)', r'\1_\2\3', t) # 2-fermion
# DeltaL=1
t = t.replace('vv_', 'llphiphi_')
# DeltaB=1
t = t.replace('duq_', 'duql_')
t = t.replace('qqu_', 'qque_')
t = t.replace('qqq_', 'qqql_')
t = t.replace('duu_', 'duue_')
return t


def analyze_smeftfr_param_card(card_dict):
"""Read a `param_card_default.dat` generated by SmeftFR and return a
dictionary mapping the LHA blocks and indices to WCxf Wilson coefficients.

The input is expected to be a dictionary as returned by `pylha.load`.

This is needed for the generation of custom parameter cards."""
d = {}
for bname, block in card_dict['BLOCK'].items():
d[bname] = []
for line in block['values']:
comment = line[-1]
if comment[2] != 'C':
continue
value = line[-2]
index = line[:-2]
coeff = format_smeftfr(comment.strip()[2:])
d[bname].append({'index': index, 'coeff': coeff, 'comment': comment})
if not d[bname]: # remove empty entries
del d[bname]
return d


def wcxf2smeftfr_dict(wc, info_dict):
"""Take a WC instance and turn it into a dictionary suitable for producing
and LHA file for SmeftFR using pylha."""
# go from flat dict to dict of arrays, symmetrizing them
C = smeftutil.wcxf2arrays_symmetrized(wc.dict)
# go back to flat dict but keeping non-redundant WCs an symm. fac.s
d = smeftutil.arrays2wcxf(C)
# rearrange to dict in right format for SmeftFR
card = {}
for block_name, block in info_dict.items():
card[block_name] = {'values': []}
for info in block:
line = [*info['index'], d[info['coeff']].real, info['comment']]
card[block_name]['values'].append(line)
return card


def wcxf2smeftfr(wc, info_dict, card_dict, stream):
"""Take a WC instance and dump it into an LHA file (or return as string)
in a format suitable for use as `param_card.dat` file for MadGraph
with SmeftFR.

Parameters:

- wc: `WC` instance
- info_dict: dictionary as returned by `analyze_smeftfr_param_card`
- strem: output file-like object
"""
if (wc.eft, wc.basis) == ('SMEFT', 'Warsaw mass'):
wc_m = wc
else:
if wc.eft != 'SMEFT':
raise ValueError("wcxf2smeftfr only support SMEFT Wilson coefficients")
else:
try:
wc_m = wc.translate('Warsaw mass')
except ValueError:
raise ValueError("wcxf2smeftfr requires a basis that can be translated to the Warsaw mass basis")
card = {}
card['DECAY'] = card_dict['DECAY'].copy()
card['BLOCK'] = wcxf2smeftfr_dict(wc_m, info_dict)
for name, block in card_dict['BLOCK'].items():
if name not in card['BLOCK']:
card['BLOCK'][name] = card_dict['BLOCK'][name].copy()
# else:
# for k, v in block.items():
# if k not in card['BLOCK'][name]:
# card['BLOCK'][name][k] = v
return pylha.dump(card, fmt='lha', stream=stream)
Loading