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
105 if set(key) != set(parameter_dict.keys()):
106
107 fail = True
108 missing_set = set(parameter_dict.keys()).difference(set(key))
109 unknow_set = set(key).difference(set(parameter_dict.keys()))
110 missing_block = ','.join(missing_set)
111 unknow_block = ','.join(unknow_set)
112
113
114 msg = '''Invalid restriction card (not same block)
115 %s != %s.
116 Missing block: %s
117 Unknown block : %s''' % (set(key), set(parameter_dict.keys()),
118 missing_block, unknow_block)
119 apply_conversion = []
120
121 if 'loop' in missing_set:
122 key.append('loop')
123 fail = False
124
125 if not missing_block:
126 logger.warning("Unknow type of information in the card: %s" % unknow_block)
127 fail = False
128 elif self['name'].startswith('mssm-') or self['name'] == 'mssm':
129 if not missing_set:
130 fail = False
131 else:
132 apply_conversion.append('to_slha2')
133 overwrite = False
134 elif missing_set == set(['fralpha']) and 'alpha' in unknow_set:
135 apply_conversion.append('alpha')
136 elif self.need_slha2(missing_set, unknow_set):
137 apply_conversion.append('to_slha2')
138 overwrite = True
139
140 if apply_conversion:
141 try:
142 if 'to_slha2' in apply_conversion:
143 if overwrite:
144 logger.error('Convention for the param_card seems to be wrong. Trying to automatically convert your file to SLHA2 format. \n'+\
145 "Please check that the conversion occurs as expected (The converter is not fully general)")
146 import time
147 time.sleep(5)
148
149 param_card = param_card.input_path
150 param_card = card_reader.convert_to_mg5card(param_card,
151 writting=overwrite)
152 key = [k for k in param_card.keys() if not k.startswith('qnumbers ')
153 and not k.startswith('decay_table')]
154 if not set(parameter_dict.keys()).difference(set(key)):
155 fail = False
156 if 'alpha' in apply_conversion:
157 logger.info("Missing block fralpha but found a block alpha, apply automatic conversion")
158 param_card.rename_blocks({'alpha':'fralpha'})
159 param_card['fralpha'].rename_keys({(): (1,)})
160 param_card.write(param_card.input_path)
161 key = [k for k in param_card.keys() if not k.startswith('qnumbers ')
162 and not k.startswith('decay_table')]
163 if not set(parameter_dict.keys()).difference(set(key)):
164 fail = False
165 except Exception:
166 raise
167 raise MadGraph5Error(msg)
168
169
170 if fail:
171 raise MadGraph5Error(msg)
172
173 for block in key:
174 if block not in parameter_dict:
175 continue
176 for pid in parameter_dict[block]:
177 try:
178 value = param_card[block].get(pid).value
179 except:
180 if block == 'loop':
181 value = param_card['mass'].get(23).value
182 else:
183 raise MadGraph5Error('%s %s not define' % (block, pid))
184
185 if isinstance(value, str) and value.lower() == 'auto':
186 value = '0.0'
187 if scale and parameter_dict[block][pid].name == 'aS':
188 runner = Alphas_Runner(value, nloop=2)
189 try:
190 value = runner(scale)
191 except ValueError as err:
192 if str(err) == 'math domain error' and scale < 1:
193 value = 0.0
194 else:
195 raise
196 except OverflowError as err:
197 if scale < 1:
198 value = 0.0
199 else:
200 raise
201
202 exec("locals()[\'%s\'] = %s" % (parameter_dict[block][pid].name,
203 value))
204 parameter_dict[block][pid].value = float(value)
205
206 else:
207
208 for param in external_parameters:
209 if scale and parameter_dict[block][id].name == 'aS':
210 runner = Alphas_Runner(value, nloop=3)
211 value = runner(scale)
212 exec("locals()[\'%s\'] = %s" % (param.name, param.value))
213
214
215
216 for func in self['functions']:
217 exec("def %s(%s):\n return %s" % (func.name,
218 ",".join(func.arguments),
219 func.expr))
220
221
222 derived_parameters = []
223 keys = [key for key in self['parameters'].keys() if \
224 key != ('external',)]
225 keys.sort(key=len)
226 for key in keys:
227 derived_parameters += self['parameters'][key]
228
229
230 for param in derived_parameters:
231 try:
232 exec("locals()[\'%s\'] = %s" % (param.name, param.expr))
233 except Exception as error:
234 msg = 'Unable to evaluate %s = %s: raise error: %s' % (param.name,param.expr, error)
235 raise MadGraph5Error(msg)
236 param.value = complex(eval(param.name))
237 if not eval(param.name) and eval(param.name) != 0:
238 logger.warning("%s has no expression: %s" % (param.name,
239 param.expr))
240
241
242
243 for particle in self.get('particles'):
244 if particle.is_fermion() and particle.get('self_antipart') and \
245 particle.get('width').lower() != 'zero' and \
246 eval(particle.get('mass')).real < 0:
247 exec("locals()[\'%(width)s\'] = -abs(%(width)s)" % \
248 {'width': particle.get('width')})
249
250
251 couplings = sum(list(self['couplings'].values()), [])
252
253 for coup in couplings:
254
255 exec("locals()[\'%s\'] = %s" % (coup.name, coup.expr))
256 coup.value = complex(eval(coup.name))
257 if not eval(coup.name) and eval(coup.name) != 0:
258 logger.warning("%s has no expression: %s" % (coup.name,
259 coup.expr))
260
261
262 self.set('parameter_dict', dict([(param.name, param.value) \
263 for param in external_parameters + \
264 derived_parameters]))
265
266
267 self.get('parameter_dict')['ZERO'] = complex(0.)
268
269 self.set('coupling_dict', dict([(coup.name, coup.value) \
270 for coup in couplings]))
271
272 return locals()
273
281
288
290
291 return all([b in missing_set for b in ['te','msl2','dsqmix','tu','selmix','msu2','msq2','usqmix','td', 'mse2','msd2']]) and\
292 all(b in unknow_set for b in ['ae','ad','sbotmix','au','modsel','staumix','stopmix'])
293
295 """Evaluation of strong coupling constant alpha_S"""
296
297
298
299
300
301
302
303
304
305
306
307
308 - def __init__(self, asmz, nloop, zmass=91.188, cmass=1.4, bmass=4.7):
309
310 self.asmz = asmz
311 self.nloop = nloop
312 self.zmass = zmass
313 self.cmass = cmass
314 self.bmass = bmass
315
316 assert asmz > 0
317 assert cmass > 0
318 assert bmass > 0
319 assert nloop > -1
320 t = 2 * math.log(bmass/zmass)
321 self.amb = self.newton1(t, asmz, 5)
322 t = 2 * math.log(cmass/bmass)
323 self.amc = self.newton1(t, self.amb, 4)
324
326 """Evaluation of strong coupling constant alpha_S at scale 'scale'."""
327 assert scale > 0
328
329
330 if scale < 0.188775276209:
331 return 0
332 elif scale < self.cmass:
333 t = 2 * math.log(scale/self.cmass)
334 return self.newton1(t, self.amc, 3)
335 elif scale < self.bmass:
336 t = 2 * math.log(scale/self.bmass)
337 return self.newton1(t, self.amb, 4)
338 else:
339 t = 2 * math.log(scale/self.zmass)
340 return self.newton1(t, self.asmz, 5)
341
342
343 b0 = [0.716197243913527, 0.66314559621623, 0.61009394851893]
344
345 c1 = [0.565884242104515, 0.49019722472304, 0.40134724779695]
346
347 c2 = [0.453013579178645, 0.30879037953664, 0.14942733137107]
348
349 d = [1.22140465909230, 0.99743079911360, 0.66077962451190]
350
351
352
354 """calculate a_out using nloop beta-function evolution
355 with nf flavours, given starting value as-in
356 given alphas and logarithmic separation between
357 input scale and output scale t.
358 Evolution is performed using Newton's method,
359 with a precision given by tol."""
360 nloop = self.nloop
361 tol = 5e-4
362 arg = nf-3
363 b0, c1, c2, d = self.b0[arg], self.c1[arg], self.c2[arg], self.d[arg]
364
365 if nloop == 2:
366 f = lambda AS: 1.0/AS+c1*math.log((c1*AS)/(1+c1*AS))
367 elif nloop == 3:
368 f = lambda AS: 1.0/AS+0.5*c1*math.log((c2*AS**2)/(1+c1*AS+c2*AS**2)) \
369 -(c1**2-2*c2)/d*math.atan((2*c2*AS+c1)/d)
370
371 a_out = alphas / (1 + alphas * b0 * t)
372 if nloop == 1:
373 return a_out
374
375 a_out = alphas/(1+b0*alphas*t+c1*alphas*math.log(1+alphas*b0*t))
376 if a_out < 0:
377 a_out = 0.3
378
379 while 1:
380 AS = a_out
381 F = b0 * t + f(alphas) -f(AS)
382 if nloop == 2:
383 FP=1/(AS**2*(1+c1*AS))
384 elif nloop == 3:
385 FP=1/(AS**2*(1+c1*AS + c2 * AS**2))
386 if FP == 0:
387 return AS
388 a_out = AS - F/FP
389 delta = abs(F/FP/AS)
390 if delta < tol:
391 break
392 return a_out
393