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