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('models.model_reader') 
 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 assert isinstance(param_card, card_reader.ParamCard) 85 86 if complex_mass_scheme is None: 87 if aloha.complex_mass: 88 param_card.convert_to_complex_mass_scheme() 89 else: 90 if complex_mass_scheme: 91 param_card.convert_to_complex_mass_scheme() 92 93 key = [k for k in param_card.keys() if not k.startswith('qnumbers ') 94 and not k.startswith('decay_table') 95 and 'info' not in k] 96 param_key = [k for k in parameter_dict.keys() if 'info' not in k] 97 98 if set(key) != set(parameter_dict.keys()): 99 # the two card are different. check if this critical 100 101 fail = True 102 msg = '''Invalid restriction card (not same block) 103 %s != %s. 104 Missing block: %s 105 Unknown block : %s''' % (set(key), set(parameter_dict.keys()), 106 ','.join(set(parameter_dict.keys()).difference(set(key))), 107 ','.join(set(key).difference(set(parameter_dict.keys())))) 108 if 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" \ 109 or self['name'].startswith('mssm-') or self['name'] == 'mssm': 110 if not set(parameter_dict.keys()).difference(set(key)): 111 fail = False 112 else: 113 # FOR MSSM allow for automatic conversion to correct format 114 try: 115 param_card = param_card.input_path 116 param_card = card_reader.convert_to_mg5card(param_card, 117 writting=False) 118 key = [k for k in param_card.keys() if not k.startswith('qnumbers ') 119 and not k.startswith('decay_table')] 120 if not set(parameter_dict.keys()).difference(set(key)): 121 fail = False 122 except Exception: 123 raise MadGraph5Error, msg 124 125 if fail: 126 raise MadGraph5Error, msg 127 128 for block in key: 129 if block not in parameter_dict: 130 continue 131 for id in parameter_dict[block]: 132 try: 133 value = param_card[block].get(id).value 134 except: 135 raise MadGraph5Error, '%s %s not define' % (block, id) 136 else: 137 if isinstance(value, str) and value.lower() == 'auto': 138 value = '0.0' 139 if scale and parameter_dict[block][id].name == 'aS': 140 runner = Alphas_Runner(value, nloop=2) 141 value = runner(scale) 142 exec("locals()[\'%s\'] = %s" % (parameter_dict[block][id].name, 143 value)) 144 parameter_dict[block][id].value = float(value) 145 146 else: 147 # No param_card, use default values 148 for param in external_parameters: 149 if scale and parameter_dict[block][id].name == 'aS': 150 runner = Alphas_Runner(value, nloop=3) 151 value = runner(scale) 152 exec("locals()[\'%s\'] = %s" % (param.name, param.value)) 153 154 155 # Define all functions used 156 for func in self['functions']: 157 exec("def %s(%s):\n return %s" % (func.name, 158 ",".join(func.arguments), 159 func.expr)) 160 161 # Extract derived parameters 162 derived_parameters = [] 163 keys = [key for key in self['parameters'].keys() if \ 164 key != ('external',)] 165 keys.sort(key=len) 166 for key in keys: 167 derived_parameters += self['parameters'][key] 168 169 # Now calculate derived parameters 170 for param in derived_parameters: 171 try: 172 exec("locals()[\'%s\'] = %s" % (param.name, param.expr)) 173 except Exception as error: 174 msg = 'Unable to evaluate %s = %s: raise error: %s' % (param.name,param.expr, error) 175 raise MadGraph5Error, msg 176 param.value = complex(eval(param.name)) 177 if not eval(param.name) and eval(param.name) != 0: 178 logger.warning("%s has no expression: %s" % (param.name, 179 param.expr)) 180 181 # Correct width sign for Majorana particles (where the width 182 # and mass need to have the same sign) 183 for particle in self.get('particles'): 184 if particle.is_fermion() and particle.get('self_antipart') and \ 185 particle.get('width').lower() != 'zero' and \ 186 eval(particle.get('mass')).real < 0: 187 exec("locals()[\'%(width)s\'] = -abs(%(width)s)" % \ 188 {'width': particle.get('width')}) 189 190 # Extract couplings 191 couplings = sum(self['couplings'].values(), []) 192 # Now calculate all couplings 193 for coup in couplings: 194 #print "I execute %s = %s"%(coup.name, coup.expr) 195 exec("locals()[\'%s\'] = %s" % (coup.name, coup.expr)) 196 coup.value = complex(eval(coup.name)) 197 if not eval(coup.name) and eval(coup.name) != 0: 198 logger.warning("%s has no expression: %s" % (coup.name, 199 coup.expr)) 200 201 # Set parameter and coupling dictionaries 202 self.set('parameter_dict', dict([(param.name, param.value) \ 203 for param in external_parameters + \ 204 derived_parameters])) 205 206 # Add "zero" 207 self.get('parameter_dict')['ZERO'] = complex(0.) 208 209 self.set('coupling_dict', dict([(coup.name, coup.value) \ 210 for coup in couplings])) 211 212 return locals()
213
214 -class Alphas_Runner(object):
215 """Evaluation of strong coupling constant alpha_S""" 216 # Author: Olivier Mattelaer translated from a fortran routine 217 # written by R. K. Ellis 218 # 219 # q -- scale at which alpha_s is to be evaluated 220 # 221 # asmz -- value of alpha_s at the mass of the Z-boson 222 # nloop -- the number of loops (1,2, or 3) at which beta 223 # 224 # function is evaluated to determine running. 225 # the values of the cmass and the bmass should be set 226 #--------------------------------------------------------------------------- 227
228 - def __init__(self, asmz, nloop, zmass=91.188, cmass=1.4, bmass=4.7):
229 230 self.asmz = asmz 231 self.nloop = nloop 232 self.zmass = zmass 233 self.cmass = cmass 234 self.bmass = bmass 235 236 assert asmz > 0 237 assert cmass > 0 238 assert bmass > 0 239 assert nloop > -1 240 t = 2 * math.log(bmass/zmass) 241 self.amb = self.newton1(t, asmz, 5) 242 t = 2 * math.log(cmass/bmass) 243 self.amc = self.newton1(t, self.amb, 4)
244
245 - def __call__(self, scale):
246 """Evaluation of strong coupling constant alpha_S at scale 'scale'.""" 247 assert scale > 0 248 249 250 if scale < 0.188775276209: 251 return 0 252 elif scale < self.cmass: 253 t = 2 * math.log(scale/self.cmass) 254 return self.newton1(t, self.amc, 3) 255 elif scale < self.bmass: 256 t = 2 * math.log(scale/self.bmass) 257 return self.newton1(t, self.amb, 4) 258 else: 259 t = 2 * math.log(scale/self.zmass) 260 return self.newton1(t, self.asmz, 5)
261 262 # B0=(11.-2.*NF/3.)/4./PI 263 b0 = [0.716197243913527, 0.66314559621623, 0.61009394851893] 264 # C1=(102.D0-38.D0/3.D0*NF)/4.D0/PI/(11.D0-2.D0/3.D0*NF) 265 c1 = [0.565884242104515, 0.49019722472304, 0.40134724779695] 266 # C2=(2857.D0/2.D0-5033*NF/18.D0+325*NF**2/54)/16.D0/PI**2/(11.D0-2.D0/3.D0*NF) 267 c2 = [0.453013579178645, 0.30879037953664, 0.14942733137107] 268 # DEL=SQRT(4*C2-C1**2) 269 d = [1.22140465909230, 0.99743079911360, 0.66077962451190] 270
271 - def newton1(self, t, alphas, nf):
272 """calculate a_out using nloop beta-function evolution 273 with nf flavours, given starting value as-in 274 given alphas and logarithmic separation between 275 input scale and output scale t. 276 Evolution is performed using Newton's method, 277 with a precision given by tol.""" 278 nloop = self.nloop 279 tol = 5e-4 280 arg = nf-3 281 b0, c1, c2, d = self.b0[arg], self.c1[arg], self.c2[arg], self.d[arg] 282 283 if nloop == 2: 284 f = lambda AS: 1.0/AS+c1*math.log((c1*AS)/(1+c1*AS)) 285 elif nloop == 3: 286 f = lambda AS: 1.0/AS+0.5*c1*math.log((c2*AS**2)/(1+c1*AS+c2*AS**2)) \ 287 -(c1**2-2*c2)/d*math.atan((2*c2*AS+c1)/d) 288 289 a_out = alphas / (1 + alphas * b0 * t) 290 if nloop == 1: 291 return a_out 292 293 a_out = alphas/(1+b0*alphas*t+c1*alphas*math.log(1+alphas*b0*t)) 294 if a_out < 0: 295 a_out = 0.3 296 297 while 1: 298 AS = a_out 299 F = b0 * t + f(alphas) -f(AS) 300 if nloop == 2: 301 FP=1/(AS**2*(1+c1*AS)) 302 elif nloop == 3: 303 FP=1/(AS**2*(1+c1*AS + c2 * AS**2)) 304 if FP == 0: 305 return AS 306 a_out = AS - F/FP 307 delta = abs(F/FP/AS) 308 if delta < tol: 309 break 310 return a_out
311