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 from __future__ import absolute_import
21 import array
22 import cmath
23 import copy
24 import itertools
25 import logging
26 import math
27 import os
28 import re
29 import aloha
30
31 import madgraph.core.base_objects as base_objects
32 import madgraph.loop.loop_base_objects as loop_base_objects
33 import models.check_param_card as card_reader
34 from madgraph import MadGraph5Error, MG5DIR
35 import madgraph.various.misc as misc
36 import six
37
38 ZERO = 0
39
40
41
42
43
44 logger = logging.getLogger('madgraph.models')
45
46
47
48
49
51 """Object to read all parameters and couplings of a model
52 """
53
55 """The particles is changed to ParticleList"""
56 self['coupling_dict'] = {}
57 self['parameter_dict'] = {}
58 super(ModelReader, self).default_setup()
59
63 """Read a param_card and calculate all parameters and
64 couplings. Set values directly in the parameters and
65 couplings, plus add new dictionary coupling_dict from
66 parameter name to value."""
67
68 param_card_text = None
69
70 external_parameters = self['parameters'][('external',)]
71
72 if param_card:
73
74 parameter_dict = {}
75 for param in external_parameters:
76 try:
77 dictionary = parameter_dict[param.lhablock.lower()]
78 except KeyError:
79 dictionary = {}
80 parameter_dict[param.lhablock.lower()] = dictionary
81 dictionary[tuple(param.lhacode)] = param
82 if isinstance(param_card, six.string_types):
83
84 if not os.path.isfile(param_card):
85 raise MadGraph5Error("No such file %s" % param_card)
86 param_card_text = param_card
87 param_card = card_reader.ParamCard(param_card)
88 for param in param_card.get('decay'):
89 if str(param.value).lower() == 'auto':
90 param.value = auto_width(param_card, param.lhacode)
91
92
93
94 if complex_mass_scheme is None:
95 if aloha.complex_mass:
96 param_card.convert_to_complex_mass_scheme()
97 else:
98 if complex_mass_scheme:
99 param_card.convert_to_complex_mass_scheme()
100
101 key = [k for k in param_card.keys() if not k.startswith('qnumbers ')
102 and not k.startswith('decay_table')
103 and 'info' not in k]
104 param_key = [k for k in parameter_dict.keys() if 'info' not in k]
105
106 if set(key) != set(parameter_dict.keys()):
107
108 fail = True
109 missing_set = set(parameter_dict.keys()).difference(set(key))
110 unknow_set = set(key).difference(set(parameter_dict.keys()))
111 missing_block = ','.join(missing_set)
112 unknow_block = ','.join(unknow_set)
113
114
115 msg = '''Invalid restriction card (not same block)
116 %s != %s.
117 Missing block: %s
118 Unknown block : %s''' % (set(key), set(parameter_dict.keys()),
119 missing_block, unknow_block)
120 apply_conversion = []
121
122 if 'loop' in missing_set:
123 key.append('loop')
124 fail = False
125
126 if not missing_block:
127 logger.warning("Unknow type of information in the card: %s" % unknow_block)
128 fail = False
129 elif self['name'].startswith('mssm-') or self['name'] == 'mssm':
130 if not missing_set:
131 fail = False
132 else:
133 apply_conversion.append('to_slha2')
134 overwrite = False
135 elif missing_set == set(['fralpha']) and 'alpha' in unknow_set:
136 apply_conversion.append('alpha')
137 elif self.need_slha2(missing_set, unknow_set):
138 apply_conversion.append('to_slha2')
139 overwrite = True
140
141 if apply_conversion:
142 try:
143 if 'to_slha2' in apply_conversion:
144 if overwrite:
145 logger.error('Convention for the param_card seems to be wrong. Trying to automatically convert your file to SLHA2 format. \n'+\
146 "Please check that the conversion occurs as expected (The converter is not fully general)")
147 import time
148 time.sleep(5)
149
150 param_card = param_card.input_path
151 param_card = card_reader.convert_to_mg5card(param_card,
152 writting=overwrite)
153 key = [k for k in param_card.keys() if not k.startswith('qnumbers ')
154 and not k.startswith('decay_table')]
155 if not set(parameter_dict.keys()).difference(set(key)):
156 fail = False
157 if 'alpha' in apply_conversion:
158 logger.info("Missing block fralpha but found a block alpha, apply automatic conversion")
159 param_card.rename_blocks({'alpha':'fralpha'})
160 param_card['fralpha'].rename_keys({(): (1,)})
161 param_card.write(param_card.input_path)
162 key = [k for k in param_card.keys() if not k.startswith('qnumbers ')
163 and not k.startswith('decay_table')]
164 if not set(parameter_dict.keys()).difference(set(key)):
165 fail = False
166 except Exception:
167 raise
168 raise MadGraph5Error(msg)
169
170
171 if fail:
172 raise MadGraph5Error(msg)
173
174 for block in key:
175 if block not in parameter_dict:
176 continue
177 for pid in parameter_dict[block]:
178 try:
179 value = param_card[block].get(pid).value
180 except:
181 if block == 'loop':
182 value = param_card['mass'].get(23).value
183 else:
184 raise MadGraph5Error('%s %s not define' % (block, pid))
185
186 if isinstance(value, str) and value.lower() == 'auto':
187 value = '0.0'
188 if scale and parameter_dict[block][pid].name == 'aS':
189 runner = Alphas_Runner(value, nloop=2)
190 try:
191 value = runner(scale)
192 except ValueError as err:
193 if str(err) == 'math domain error' and scale < 1:
194 value = 0.0
195 else:
196 raise
197 except OverflowError as err:
198 if scale < 1:
199 value = 0.0
200 else:
201 raise
202
203 exec("locals()[\'%s\'] = %s" % (parameter_dict[block][pid].name,
204 value))
205 parameter_dict[block][pid].value = float(value)
206
207 else:
208
209 for param in external_parameters:
210 if scale and parameter_dict[block][id].name == 'aS':
211 runner = Alphas_Runner(value, nloop=3)
212 value = runner(scale)
213 exec("locals()[\'%s\'] = %s" % (param.name, param.value))
214
215
216
217 for func in self['functions']:
218 exec("def %s(%s):\n return %s" % (func.name,
219 ",".join(func.arguments),
220 func.expr))
221
222
223 derived_parameters = []
224 keys = [key for key in self['parameters'].keys() if \
225 key != ('external',)]
226 keys.sort(key=len)
227 for key in keys:
228 derived_parameters += self['parameters'][key]
229
230
231 for param in derived_parameters:
232 try:
233 exec("locals()[\'%s\'] = %s" % (param.name, param.expr))
234 except Exception as error:
235 msg = 'Unable to evaluate %s = %s: raise error: %s' % (param.name,param.expr, error)
236 raise MadGraph5Error(msg)
237 param.value = complex(eval(param.name))
238 if not eval(param.name) and eval(param.name) != 0:
239 logger.warning("%s has no expression: %s" % (param.name,
240 param.expr))
241
242
243
244 for particle in self.get('particles'):
245 if particle.is_fermion() and particle.get('self_antipart') and \
246 particle.get('width').lower() != 'zero' and \
247 eval(particle.get('mass')).real < 0:
248 exec("locals()[\'%(width)s\'] = -abs(%(width)s)" % \
249 {'width': particle.get('width')})
250
251
252 couplings = sum(list(self['couplings'].values()), [])
253
254 for coup in couplings:
255
256 exec("locals()[\'%s\'] = %s" % (coup.name, coup.expr))
257 coup.value = complex(eval(coup.name))
258 if not eval(coup.name) and eval(coup.name) != 0:
259 logger.warning("%s has no expression: %s" % (coup.name,
260 coup.expr))
261
262
263 self.set('parameter_dict', dict([(param.name, param.value) \
264 for param in external_parameters + \
265 derived_parameters]))
266
267
268 self.get('parameter_dict')['ZERO'] = complex(0.)
269
270 self.set('coupling_dict', dict([(coup.name, coup.value) \
271 for coup in couplings]))
272
273 return locals()
274
282
289
291
292 return all([b in missing_set for b in ['te','msl2','dsqmix','tu','selmix','msu2','msq2','usqmix','td', 'mse2','msd2']]) and\
293 all(b in unknow_set for b in ['ae','ad','sbotmix','au','modsel','staumix','stopmix'])
294
296 """Evaluation of strong coupling constant alpha_S"""
297
298
299
300
301
302
303
304
305
306
307
308
309 - def __init__(self, asmz, nloop, zmass=91.188, cmass=1.4, bmass=4.7):
310
311 self.asmz = asmz
312 self.nloop = nloop
313 self.zmass = zmass
314 self.cmass = cmass
315 self.bmass = bmass
316
317 assert asmz > 0
318 assert cmass > 0
319 assert bmass > 0
320 assert nloop > -1
321 t = 2 * math.log(bmass/zmass)
322 self.amb = self.newton1(t, asmz, 5)
323 t = 2 * math.log(cmass/bmass)
324 self.amc = self.newton1(t, self.amb, 4)
325
327 """Evaluation of strong coupling constant alpha_S at scale 'scale'."""
328 assert scale > 0
329
330
331 if scale < 0.188775276209:
332 return 0
333 elif scale < self.cmass:
334 t = 2 * math.log(scale/self.cmass)
335 return self.newton1(t, self.amc, 3)
336 elif scale < self.bmass:
337 t = 2 * math.log(scale/self.bmass)
338 return self.newton1(t, self.amb, 4)
339 else:
340 t = 2 * math.log(scale/self.zmass)
341 return self.newton1(t, self.asmz, 5)
342
343
344 b0 = [0.716197243913527, 0.66314559621623, 0.61009394851893]
345
346 c1 = [0.565884242104515, 0.49019722472304, 0.40134724779695]
347
348 c2 = [0.453013579178645, 0.30879037953664, 0.14942733137107]
349
350 d = [1.22140465909230, 0.99743079911360, 0.66077962451190]
351
352
353
355 """calculate a_out using nloop beta-function evolution
356 with nf flavours, given starting value as-in
357 given alphas and logarithmic separation between
358 input scale and output scale t.
359 Evolution is performed using Newton's method,
360 with a precision given by tol."""
361 nloop = self.nloop
362 tol = 5e-4
363 arg = nf-3
364 b0, c1, c2, d = self.b0[arg], self.c1[arg], self.c2[arg], self.d[arg]
365
366 if nloop == 2:
367 f = lambda AS: 1.0/AS+c1*math.log((c1*AS)/(1+c1*AS))
368 elif nloop == 3:
369 f = lambda AS: 1.0/AS+0.5*c1*math.log((c2*AS**2)/(1+c1*AS+c2*AS**2)) \
370 -(c1**2-2*c2)/d*math.atan((2*c2*AS+c1)/d)
371
372 a_out = alphas / (1 + alphas * b0 * t)
373 if nloop == 1:
374 return a_out
375
376 a_out = alphas/(1+b0*alphas*t+c1*alphas*math.log(1+alphas*b0*t))
377 if a_out < 0:
378 a_out = 0.3
379
380 while 1:
381 AS = a_out
382 F = b0 * t + f(alphas) -f(AS)
383 if nloop == 2:
384 FP=1/(AS**2*(1+c1*AS))
385 elif nloop == 3:
386 FP=1/(AS**2*(1+c1*AS + c2 * AS**2))
387 if FP == 0:
388 return AS
389 a_out = AS - F/FP
390 delta = abs(F/FP/AS)
391 if delta < tol:
392 break
393 return a_out
394