Package models :: Module model_reader
[hide private]
[frames] | no frames]

Source Code for Module models.model_reader

  1  ################################################################################ 
  2  # 
  3  # Copyright (c) 2010 The MadGraph5_aMC@NLO Development team and Contributors 
  4  # 
  5  # This file is a part of the MadGraph5_aMC@NLO project, an application which  
  6  # automatically generates Feynman diagrams and matrix elements for arbitrary 
  7  # high-energy processes in the Standard Model and beyond. 
  8  # 
  9  # It is subject to the MadGraph5_aMC@NLO license which should accompany this  
 10  # distribution. 
 11  # 
 12  # For more information, visit madgraph.phys.ucl.ac.be and amcatnlo.web.cern.ch 
 13  # 
 14  ################################################################################ 
 15  """Module to allow reading a param_card and setting all parameters and 
 16  couplings for a model""" 
 17   
 18  from __future__ import division 
 19   
 20  import array 
 21  import cmath 
 22  import copy 
 23  import itertools 
 24  import logging 
 25  import math 
 26  import os 
 27  import re 
 28  import aloha 
 29   
 30  import madgraph.core.base_objects as base_objects 
 31  import madgraph.loop.loop_base_objects as loop_base_objects 
 32  import models.check_param_card as card_reader 
 33  from madgraph import MadGraph5Error, MG5DIR 
 34  import madgraph.various.misc as misc 
 35   
 36  ZERO = 0 
 37   
 38  #=============================================================================== 
 39  # Logger for model_reader 
 40  #=============================================================================== 
 41   
 42  logger = logging.getLogger('madgraph.models') 
 43   
 44  #=============================================================================== 
 45  # ModelReader: Used to read a param_card and calculate parameters and 
 46  #              couplings of the model. 
 47  #=============================================================================== 
48 -class ModelReader(loop_base_objects.LoopModel):
49 """Object to read all parameters and couplings of a model 50 """ 51
52 - def default_setup(self):
53 """The particles is changed to ParticleList""" 54 self['coupling_dict'] = {} 55 self['parameter_dict'] = {} 56 super(ModelReader, self).default_setup()
57
58 - def set_parameters_and_couplings(self, param_card = None, scale=None, 59 complex_mass_scheme=None):
60 """Read a param_card and calculate all parameters and 61 couplings. Set values directly in the parameters and 62 couplings, plus add new dictionary coupling_dict from 63 parameter name to value.""" 64 65 # Extract external parameters 66 external_parameters = self['parameters'][('external',)] 67 # Read in param_card 68 if param_card: 69 # Create a dictionary from LHA block name and code to parameter name 70 parameter_dict = {} 71 for param in external_parameters: 72 try: 73 dictionary = parameter_dict[param.lhablock.lower()] 74 except KeyError: 75 dictionary = {} 76 parameter_dict[param.lhablock.lower()] = dictionary 77 dictionary[tuple(param.lhacode)] = param 78 79 if isinstance(param_card, basestring): 80 # Check that param_card exists 81 if not os.path.isfile(param_card): 82 raise MadGraph5Error, "No such file %s" % param_card 83 param_card = card_reader.ParamCard(param_card) 84 # misc.sprint(type(param_card), card_reader.ParamCard, isinstance(param_card, card_reader.ParamCard)) 85 # assert isinstance(param_card, card_reader.ParamCard),'%s is not a ParamCard: %s' % (type(param_card), isinstance(param_card, card_reader.ParamCard)) 86 87 if complex_mass_scheme is None: 88 if aloha.complex_mass: 89 param_card.convert_to_complex_mass_scheme() 90 else: 91 if complex_mass_scheme: 92 param_card.convert_to_complex_mass_scheme() 93 94 key = [k for k in param_card.keys() if not k.startswith('qnumbers ') 95 and not k.startswith('decay_table') 96 and 'info' not in k] 97 param_key = [k for k in parameter_dict.keys() if 'info' not in k] 98 99 if set(key) != set(parameter_dict.keys()): 100 # the two card are different. check if this critical 101 102 fail = True 103 missing_block = ','.join(set(parameter_dict.keys()).difference(set(key))) 104 unknow_block = ','.join(set(key).difference(set(parameter_dict.keys()))) 105 106 107 108 msg = '''Invalid restriction card (not same block) 109 %s != %s. 110 Missing block: %s 111 Unknown block : %s''' % (set(key), set(parameter_dict.keys()), 112 missing_block, unknow_block) 113 if not missing_block: 114 logger.warning("Unknow type of information in the card: %s" % unknow_block) 115 fail = False 116 elif msg =="Invalid restriction card (not same block)\n set(['yu', 'umix', 'ae', 'ad', 'decay', 'nmix', 'ye', 'sbotmix', 'msoft', 'yd', 'vmix', 'au', 'mass', 'alpha', 'modsel', 'sminputs', 'staumix', 'stopmix', 'hmix']) != set(['umix', 'msoft', 'msu2', 'fralpha', 'msd2', 'msl2', 'decay', 'tu', 'selmix', 'td', 'te', 'usqmix', 'dsqmix', 'ye', 'yd', 'sminputs', 'yu', 'mse2', 'nmix', 'vmix', 'msq2', 'mass', 'hmix']).\n Missing block: te,msl2,dsqmix,tu,selmix,msu2,msq2,usqmix,td,fralpha,mse2,msd2\n Unknown block : ae,ad,sbotmix,au,alpha,modsel,staumix,stopmix" \ 117 or self['name'].startswith('mssm-') or self['name'] == 'mssm': 118 if not set(parameter_dict.keys()).difference(set(key)): 119 fail = False 120 else: 121 # FOR MSSM allow for automatic conversion to correct format 122 try: 123 param_card = param_card.input_path 124 param_card = card_reader.convert_to_mg5card(param_card, 125 writting=False) 126 key = [k for k in param_card.keys() if not k.startswith('qnumbers ') 127 and not k.startswith('decay_table')] 128 if not set(parameter_dict.keys()).difference(set(key)): 129 fail = False 130 except Exception: 131 raise MadGraph5Error, msg 132 133 if fail: 134 raise MadGraph5Error, msg 135 136 for block in key: 137 if block not in parameter_dict: 138 continue 139 for id in parameter_dict[block]: 140 try: 141 value = param_card[block].get(id).value 142 except: 143 raise MadGraph5Error, '%s %s not define' % (block, id) 144 else: 145 if isinstance(value, str) and value.lower() == 'auto': 146 value = '0.0' 147 if scale and parameter_dict[block][id].name == 'aS': 148 runner = Alphas_Runner(value, nloop=2) 149 value = runner(scale) 150 exec("locals()[\'%s\'] = %s" % (parameter_dict[block][id].name, 151 value)) 152 parameter_dict[block][id].value = float(value) 153 154 else: 155 # No param_card, use default values 156 for param in external_parameters: 157 if scale and parameter_dict[block][id].name == 'aS': 158 runner = Alphas_Runner(value, nloop=3) 159 value = runner(scale) 160 exec("locals()[\'%s\'] = %s" % (param.name, param.value)) 161 162 163 # Define all functions used 164 for func in self['functions']: 165 exec("def %s(%s):\n return %s" % (func.name, 166 ",".join(func.arguments), 167 func.expr)) 168 169 # Extract derived parameters 170 derived_parameters = [] 171 keys = [key for key in self['parameters'].keys() if \ 172 key != ('external',)] 173 keys.sort(key=len) 174 for key in keys: 175 derived_parameters += self['parameters'][key] 176 177 # Now calculate derived parameters 178 for param in derived_parameters: 179 try: 180 exec("locals()[\'%s\'] = %s" % (param.name, param.expr)) 181 except Exception as error: 182 msg = 'Unable to evaluate %s = %s: raise error: %s' % (param.name,param.expr, error) 183 raise MadGraph5Error, msg 184 param.value = complex(eval(param.name)) 185 if not eval(param.name) and eval(param.name) != 0: 186 logger.warning("%s has no expression: %s" % (param.name, 187 param.expr)) 188 189 # Correct width sign for Majorana particles (where the width 190 # and mass need to have the same sign) 191 for particle in self.get('particles'): 192 if particle.is_fermion() and particle.get('self_antipart') and \ 193 particle.get('width').lower() != 'zero' and \ 194 eval(particle.get('mass')).real < 0: 195 exec("locals()[\'%(width)s\'] = -abs(%(width)s)" % \ 196 {'width': particle.get('width')}) 197 198 # Extract couplings 199 couplings = sum(self['couplings'].values(), []) 200 # Now calculate all couplings 201 for coup in couplings: 202 #print "I execute %s = %s"%(coup.name, coup.expr) 203 exec("locals()[\'%s\'] = %s" % (coup.name, coup.expr)) 204 coup.value = complex(eval(coup.name)) 205 if not eval(coup.name) and eval(coup.name) != 0: 206 logger.warning("%s has no expression: %s" % (coup.name, 207 coup.expr)) 208 209 # Set parameter and coupling dictionaries 210 self.set('parameter_dict', dict([(param.name, param.value) \ 211 for param in external_parameters + \ 212 derived_parameters])) 213 214 # Add "zero" 215 self.get('parameter_dict')['ZERO'] = complex(0.) 216 217 self.set('coupling_dict', dict([(coup.name, coup.value) \ 218 for coup in couplings])) 219 220 return locals()
221
222 - def get_mass(self, pdg_code):
223 """easy way to have access to a mass value""" 224 225 if isinstance(pdg_code, (int,str)): 226 return self.get('parameter_dict')[self.get_particle(pdg_code).get('mass')].real 227 else: 228 return self.get('parameter_dict')[pdg_code.get('mass')].real
229
230 - def get_width(self, pdg_code):
231 """easy way to have access to a width value""" 232 if isinstance(pdg_code, (int,str)): 233 return self.get('parameter_dict')[self.get_particle(pdg_code).get('width')].real 234 else: 235 return self.get('parameter_dict')[pdg_code.get('mass')].real
236 237
238 -class Alphas_Runner(object):
239 """Evaluation of strong coupling constant alpha_S""" 240 # Author: Olivier Mattelaer translated from a fortran routine 241 # written by R. K. Ellis 242 # 243 # q -- scale at which alpha_s is to be evaluated 244 # 245 # asmz -- value of alpha_s at the mass of the Z-boson 246 # nloop -- the number of loops (1,2, or 3) at which beta 247 # 248 # function is evaluated to determine running. 249 # the values of the cmass and the bmass should be set 250 #--------------------------------------------------------------------------- 251
252 - def __init__(self, asmz, nloop, zmass=91.188, cmass=1.4, bmass=4.7):
253 254 self.asmz = asmz 255 self.nloop = nloop 256 self.zmass = zmass 257 self.cmass = cmass 258 self.bmass = bmass 259 260 assert asmz > 0 261 assert cmass > 0 262 assert bmass > 0 263 assert nloop > -1 264 t = 2 * math.log(bmass/zmass) 265 self.amb = self.newton1(t, asmz, 5) 266 t = 2 * math.log(cmass/bmass) 267 self.amc = self.newton1(t, self.amb, 4)
268
269 - def __call__(self, scale):
270 """Evaluation of strong coupling constant alpha_S at scale 'scale'.""" 271 assert scale > 0 272 273 274 if scale < 0.188775276209: 275 return 0 276 elif scale < self.cmass: 277 t = 2 * math.log(scale/self.cmass) 278 return self.newton1(t, self.amc, 3) 279 elif scale < self.bmass: 280 t = 2 * math.log(scale/self.bmass) 281 return self.newton1(t, self.amb, 4) 282 else: 283 t = 2 * math.log(scale/self.zmass) 284 return self.newton1(t, self.asmz, 5)
285 286 # B0=(11.-2.*NF/3.)/4./PI 287 b0 = [0.716197243913527, 0.66314559621623, 0.61009394851893] 288 # C1=(102.D0-38.D0/3.D0*NF)/4.D0/PI/(11.D0-2.D0/3.D0*NF) 289 c1 = [0.565884242104515, 0.49019722472304, 0.40134724779695] 290 # C2=(2857.D0/2.D0-5033*NF/18.D0+325*NF**2/54)/16.D0/PI**2/(11.D0-2.D0/3.D0*NF) 291 c2 = [0.453013579178645, 0.30879037953664, 0.14942733137107] 292 # DEL=SQRT(4*C2-C1**2) 293 d = [1.22140465909230, 0.99743079911360, 0.66077962451190] 294
295 - def newton1(self, t, alphas, nf):
296 """calculate a_out using nloop beta-function evolution 297 with nf flavours, given starting value as-in 298 given alphas and logarithmic separation between 299 input scale and output scale t. 300 Evolution is performed using Newton's method, 301 with a precision given by tol.""" 302 nloop = self.nloop 303 tol = 5e-4 304 arg = nf-3 305 b0, c1, c2, d = self.b0[arg], self.c1[arg], self.c2[arg], self.d[arg] 306 307 if nloop == 2: 308 f = lambda AS: 1.0/AS+c1*math.log((c1*AS)/(1+c1*AS)) 309 elif nloop == 3: 310 f = lambda AS: 1.0/AS+0.5*c1*math.log((c2*AS**2)/(1+c1*AS+c2*AS**2)) \ 311 -(c1**2-2*c2)/d*math.atan((2*c2*AS+c1)/d) 312 313 a_out = alphas / (1 + alphas * b0 * t) 314 if nloop == 1: 315 return a_out 316 317 a_out = alphas/(1+b0*alphas*t+c1*alphas*math.log(1+alphas*b0*t)) 318 if a_out < 0: 319 a_out = 0.3 320 321 while 1: 322 AS = a_out 323 F = b0 * t + f(alphas) -f(AS) 324 if nloop == 2: 325 FP=1/(AS**2*(1+c1*AS)) 326 elif nloop == 3: 327 FP=1/(AS**2*(1+c1*AS + c2 * AS**2)) 328 if FP == 0: 329 return AS 330 a_out = AS - F/FP 331 delta = abs(F/FP/AS) 332 if delta < tol: 333 break 334 return a_out
335