1
2
3
4
5
6
7
8
9
10
11
12
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
40
41
42 logger = logging.getLogger('madgraph.models')
43
44
45
46
47
49 """Object to read all parameters and couplings of a model
50 """
51
53 """The particles is changed to ParticleList"""
54 self['coupling_dict'] = {}
55 self['parameter_dict'] = {}
56 super(ModelReader, self).default_setup()
57
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
66 external_parameters = self['parameters'][('external',)]
67
68 if param_card:
69
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
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
85
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
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
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
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
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
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
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
190
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
199 couplings = sum(self['couplings'].values(), [])
200
201 for coup in couplings:
202
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
210 self.set('parameter_dict', dict([(param.name, param.value) \
211 for param in external_parameters + \
212 derived_parameters]))
213
214
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
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
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
239 """Evaluation of strong coupling constant alpha_S"""
240
241
242
243
244
245
246
247
248
249
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
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
287 b0 = [0.716197243913527, 0.66314559621623, 0.61009394851893]
288
289 c1 = [0.565884242104515, 0.49019722472304, 0.40134724779695]
290
291 c2 = [0.453013579178645, 0.30879037953664, 0.14942733137107]
292
293 d = [1.22140465909230, 0.99743079911360, 0.66077962451190]
294
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