ATLAS Offline Software
MadGraphParamHelpers.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2 
3 # Helper functions for working with parameter settings in MadGraph
4 
5 from AthenaCommon import Logging
6 mgparlog = Logging.logging.getLogger('MadGraphParamHelpers')
7 
8 def parse_particle_info(process_dir):
9  """ Parses param card in process_dir (except for decays, which have different structure)
10  and returns dict with structure dict['block']['pdgid']='value'.
11  """
12  info={}
13  with open(process_dir+'/Cards/param_card.dat') as f:
14  block=None
15  for line in f:
16  if line.strip().startswith('#'):
17  continue
18  sl=line.lower().strip().split()
19  if len(sl)<2:
20  if len(sl)>0:
21  mgparlog.warning('Unexpected line in param card:')
22  mgparlog.warning(line)
23  continue
24  if sl[0]=='block':
25  block=sl[1]
26  if block not in info:
27  info[block]={}
28  continue
29  if sl[0]=='decay':
30  block=None
31  if block is None:
32  continue
33  info[block][sl[0]]=sl[1]
34  return info
35 
36 
37 def set_SM_params(process_dir,FourFS=False):
38  """ Set default SM parameters
39  Recommended parameter page from PMG:
40  https://twiki.cern.ch/twiki/bin/view/AtlasProtected/McProductionCommonParametersMC15
41  """
42 
43  param_card_settings = {
44  'mass' : {
45 '5': "0.000000",
46 '15': "1.777000e+00",
47 '23': "9.118760e+01",
48 '24': "8.039900e+01",
49 '25': "1.250000e+02",
50  },
51  'yukawa' : { '15': "1.777000e+00 # ymtau" },
52  'DECAY' : {
53 '5' : """DECAY 5 0.000000e+00""",
54 '15' : """DECAY 15 0.000000e+00""",
55 '23' : """DECAY 23 2.495200e+00""",
56 '24': """DECAY 24 2.085000e+00
57  3.377000e-01 2 -1 2
58  3.377000e-01 2 -3 4
59  1.082000e-01 2 -11 12
60  1.082000e-01 2 -13 14
61  1.082000e-01 2 -15 16""",
62  }
63  }
64  if FourFS:
65  param_card_settings['mass']['5']="4.950000e+00"
66 
67  # do not set particle mass or yukawa if parameter does not exist in card
68  existing_particle_info=parse_particle_info(process_dir)
69  for block in param_card_settings:
70  for pdgid in list(param_card_settings[block].keys()):
71  if block in existing_particle_info and pdgid not in existing_particle_info[block]:
72  mgparlog.warning('Not setting {} for {} as parameter does not exist in param card'.format(block,pdgid))
73  param_card_settings[block].pop(pdgid)
74 
75  from MadGraphControl.MadGraphUtils import modify_param_card
76  modify_param_card(process_dir=process_dir,params=param_card_settings)
77 
78 
79 def set_top_params(process_dir,mTop=172.5,FourFS=False):
80  """ Set default parameters requested by the top group
81  This is a convenience helper function
82  Recommended parameter page from PMG:
83  https://twiki.cern.ch/twiki/bin/view/AtlasProtected/McProductionCommonParametersMC15
84  """
85  # Set SM parameters
86  set_SM_params(process_dir,FourFS)
87  # Set Higgs parameters
88  set_higgs_params(process_dir)
89  # Calculate the top width based on the mass
90  # From https://gitlab.cern.ch/atlasphys-top/reco/MC/blob/master/MCinfo/get_t_width.py
91  import math
92  # ATLAS MC11 conventions == PDG2010
93  # Vtb=0.999152
94  # using Vtb=1.0 since part of the inputs was already produced using this approximation
95  Vtb=1.0
96  M_W=80.399
97  # PDG2010
98  G_F=1.16637*(math.pow(10,-5))
99  # MSbar alpha_s(mt)
100  alpha_s=0.108
101  # Born gamma coeff.
102  C1=G_F/(8*math.pi*math.sqrt(2))
103  # Born approximation (taking intermediate W-boson to be on-shell) [1]
104  wTop_B=C1*math.pow(float(mTop),3)*math.pow(Vtb,2)*pow((1-math.pow((M_W/float(mTop)),2)),2)*(1+2*pow((M_W/float(mTop)),2))
105  # EW and QCD corrections to Born: QCD dominates, EW can be neglected [1],[2],[3]
106  wTop=wTop_B*(1-0.81*alpha_s-1.81*pow(alpha_s,2))
107 
108  param_card_settings = {
109  'mass' : { '6': str(mTop) },
110  'yukawa' : { '6': "1.725000e+02 # ymt" },
111 
112  'DECAY' : { '6' : """DECAY 6 """+str(wTop)+"""
113  1.000000e+00 2 5 24 # 1.32""",
114  },
115  }
116  from MadGraphControl.MadGraphUtils import modify_param_card
117  modify_param_card(process_dir=process_dir,params=param_card_settings)
118 
119 
120 def set_higgs_params(process_dir):
121  """ Set Higgs mass and decays
122  BR from the Higgs XSec working group for a 125.0 GeV Higgs
123  https://twiki.cern.ch/twiki/pub/LHCPhysics/LHCHXSWGBRs/BR.central.dat
124  """
125  param_card_settings = {
126  'MASS' : { '25': "1.250000e+02" },
127  'DECAY': { '25': """DECAY 25 6.382339e-03
128  5.767E-01 2 5 -5 # H->bb
129  6.319E-02 2 15 -15 # H->tautau
130  2.192E-04 2 13 -13 # H->mumu
131  2.462E-04 2 3 -3 # H->ss
132  2.911E-02 2 4 -4 # H->cc
133  8.569E-02 2 21 21 # H->gg
134  2.277E-03 2 22 22 # H->gammagamma
135  1.539E-03 2 22 23 # H->Zgamma
136  2.146E-01 2 24 -24 # H->WW
137  2.641E-02 2 23 23 # H->ZZ""" }
138  }
139  from MadGraphControl.MadGraphUtils import modify_param_card
140  modify_param_card(process_dir=process_dir,params=param_card_settings)
141 
142 
143 # Functions for PMG default parameters from S Moebius
144 def do_PMG_updates(process_dir):
145  """ Update the parameters according to PMG defaults
146  Takes a process directory
147  No return value -- updates the param card in place
148  """
149  from MadGraphControl.MadGraphUtils import modify_param_card
150  param_card_settings = get_PMG_updates(process_dir)
151  modify_param_card(process_dir=process_dir,params=param_card_settings)
152 
153 
154 def check_PMG_updates(process_dir):
155  """ Check if the param card is consistent with the PMG values
156  Takes a process directory
157  Prints info in case there is an inconsistency
158  Return value is an error code (0 for all ok)
159  """
160  param_card_settings = get_PMG_updates(process_dir)
161  code = 0
162  for block in param_card_settings:
163  if len(param_card_settings[block].keys())>0:
164  mgparlog.info('Block '+block+' needs updates: '+str(param_card_settings[block]))
165  code = 1
166  return code
167 
168 
169 def get_PMG_updates(process_dir):
170  """ Get the required PMG parameter updates
171  Takes the location of a process directory
172  Returns the dictionary of changes needed for updating to the default params
173  """
174  # Load the list of masses and widths from the param card
175  param_card_loc = process_dir+'/Cards/param_card.dat'
176  masses = get_masses(param_card_loc)
177  widths = get_widths(param_card_loc)
178  yukawas = get_block(param_card_loc, 'yukawa')
179 
180  # Read in parameters from dictionary
181  from EvgenProdTools.offline_dict import parameters
182 
183  # Create translation dictionary to be able to produce dictionary that can be read by build_param_card function
184  # for now only the quarks, leptons and bosons are included
185  particles_for_update = [ '6', '5', '4', '3', '2', '1', # Quarks
186  '25', '24', '23', # Bosons
187  '11', '13', '15' ] # Leptons
188  newparamdict = {
189  'mass' : {},
190  'decay' : {},
191  'yukawa' : {},
192  }
193 
194  # Loop through parameter dictionary and fill newparamdict, which will then be used to update the param_card
195  for pid, settings in parameters['particles'].items():
196  # dictionary key is the PID of a particle
197  # settings is a dictionary with mass, width and name as keys
198  # In case we need a name for debugging or other things, it's here
199  #particle_name = settings['name']
200  if pid in particles_for_update:
201  width = settings['width']
202  mass = settings['mass']
203  # Mass: Always set it, even if it wasn't in the dictionary
204  if pid not in masses or masses[pid]!=mass:
205  newparamdict['mass'][pid] = mass
206  # Width: Always set it, even if it wasn't in the dictionary
207  if pid not in widths or widths[pid]!=width:
208  newparamdict['decay'][pid] = 'DECAY '+pid+' '+width
209  # Yukawa: Set it only if it was in the dictionary
210  # This is to protect against models that don't use Yukawa blocks as normal
211  if pid in yukawas and yukawas[pid]!=mass:
212  newparamdict['yukawa'][pid] = mass
213 
214  # Remove empty items from the dictionary for cleanliness
215  finalparamdict = { block : newparamdict[block] for block in newparamdict if len(newparamdict[block].keys())>0 }
216 
217  mgparlog.info('The parameters that will be updated are:')
218  mgparlog.info(finalparamdict)
219 
220  return finalparamdict
221 
222 
223 # Functions to get values from a param card
224 def get_masses(param_card_loc):
225  """ Function to get the masses from a param card
226  Takes the location of a param card
227  Returns a dictionary of PID key, mass (string) values
228  """
229  return get_block(param_card_loc, 'mass')
230 
231 
232 def get_widths(param_card_loc):
233  """ Function to get the widths from a param card
234  Takes the location of a param card
235  Returns a dictionary of PID key, width (string) values
236  """
237  widths = {}
238  with open(param_card_loc,'r') as param_card_in:
239  for aline in param_card_in:
240  command_bits = aline.lower().split('#')[0].split()
241  if len(command_bits)>2 and 'decay'==command_bits[0]:
242  widths[command_bits[1]] = command_bits[2]
243  return widths
244 
245 
246 def get_block(param_card_loc, block_name):
247  """ Function to get values from a block in the param card
248  Takes the location of a param card and block name
249  Returns a dictionary of key--value for that block
250  """
251  values = {}
252  in_block = False
253  with open(param_card_loc,'r') as param_card_in:
254  for aline in param_card_in:
255  command_bits = aline.lower().split('#')[0].split()
256  if len(command_bits)>1 and 'block'==command_bits[0] and block_name==command_bits[1]:
257  # Starting the requested block
258  in_block = True
259  elif len(command_bits)>1 and 'block'==command_bits[0] and in_block:
260  # Done with requested block (may not appear twice)
261  break
262  elif len(command_bits)>1 and in_block:
263  # The *key* is all but the last value
264  # The *value is only the last value
265  values[' '.join(command_bits[:-1])] = command_bits[-1]
266  return values
MadGraphUtils
vtune_athena.format
format
Definition: vtune_athena.py:14
python.MadGraphParamHelpers.do_PMG_updates
def do_PMG_updates(process_dir)
Definition: MadGraphParamHelpers.py:144
python.MadGraphParamHelpers.set_top_params
def set_top_params(process_dir, mTop=172.5, FourFS=False)
Definition: MadGraphParamHelpers.py:79
python.MadGraphUtils.modify_param_card
def modify_param_card(param_card_input=None, param_card_backup=None, process_dir=MADGRAPH_GRIDPACK_LOCATION, params={}, output_location=None)
Definition: MadGraphUtils.py:1902
python.MadGraphParamHelpers.check_PMG_updates
def check_PMG_updates(process_dir)
Definition: MadGraphParamHelpers.py:154
python.MadGraphParamHelpers.get_widths
def get_widths(param_card_loc)
Definition: MadGraphParamHelpers.py:232
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
python.MadGraphParamHelpers.get_PMG_updates
def get_PMG_updates(process_dir)
Definition: MadGraphParamHelpers.py:169
python.MadGraphParamHelpers.set_SM_params
def set_SM_params(process_dir, FourFS=False)
Definition: MadGraphParamHelpers.py:37
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:79
python.MadGraphParamHelpers.set_higgs_params
def set_higgs_params(process_dir)
Definition: MadGraphParamHelpers.py:120
Trk::open
@ open
Definition: BinningType.h:40
str
Definition: BTagTrackIpAccessor.cxx:11
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:798
python.MadGraphParamHelpers.get_block
def get_block(param_card_loc, block_name)
Definition: MadGraphParamHelpers.py:246
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
python.MadGraphParamHelpers.get_masses
def get_masses(param_card_loc)
Definition: MadGraphParamHelpers.py:224
readCCLHist.float
float
Definition: readCCLHist.py:83
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
python.MadGraphParamHelpers.parse_particle_info
def parse_particle_info(process_dir)
Definition: MadGraphParamHelpers.py:8