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