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