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 except OverflowError, err:
185 if scale < 1:
186 value = 0.0
187 else:
188 raise
189 exec("locals()[\'%s\'] = %s" % (parameter_dict[block][pid].name,
190 value))
191 parameter_dict[block][pid].value = float(value)
192
193 else:
194
195 for param in external_parameters:
196 if scale and parameter_dict[block][id].name == 'aS':
197 runner = Alphas_Runner(value, nloop=3)
198 value = runner(scale)
199 exec("locals()[\'%s\'] = %s" % (param.name, param.value))
200
201
202
203 for func in self['functions']:
204 exec("def %s(%s):\n return %s" % (func.name,
205 ",".join(func.arguments),
206 func.expr))
207
208
209 derived_parameters = []
210 keys = [key for key in self['parameters'].keys() if \
211 key != ('external',)]
212 keys.sort(key=len)
213 for key in keys:
214 derived_parameters += self['parameters'][key]
215
216
217 for param in derived_parameters:
218 try:
219 exec("locals()[\'%s\'] = %s" % (param.name, param.expr))
220 except Exception as error:
221 msg = 'Unable to evaluate %s = %s: raise error: %s' % (param.name,param.expr, error)
222 raise MadGraph5Error, msg
223 param.value = complex(eval(param.name))
224 if not eval(param.name) and eval(param.name) != 0:
225 logger.warning("%s has no expression: %s" % (param.name,
226 param.expr))
227
228
229
230 for particle in self.get('particles'):
231 if particle.is_fermion() and particle.get('self_antipart') and \
232 particle.get('width').lower() != 'zero' and \
233 eval(particle.get('mass')).real < 0:
234 exec("locals()[\'%(width)s\'] = -abs(%(width)s)" % \
235 {'width': particle.get('width')})
236
237
238 couplings = sum(self['couplings'].values(), [])
239
240 for coup in couplings:
241
242 exec("locals()[\'%s\'] = %s" % (coup.name, coup.expr))
243 coup.value = complex(eval(coup.name))
244 if not eval(coup.name) and eval(coup.name) != 0:
245 logger.warning("%s has no expression: %s" % (coup.name,
246 coup.expr))
247
248
249 self.set('parameter_dict', dict([(param.name, param.value) \
250 for param in external_parameters + \
251 derived_parameters]))
252
253
254 self.get('parameter_dict')['ZERO'] = complex(0.)
255
256 self.set('coupling_dict', dict([(coup.name, coup.value) \
257 for coup in couplings]))
258
259 return locals()
260
268
275
277
278 return all([b in missing_set for b in ['te','msl2','dsqmix','tu','selmix','msu2','msq2','usqmix','td', 'mse2','msd2']]) and\
279 all(b in unknow_set for b in ['ae','ad','sbotmix','au','modsel','staumix','stopmix'])
280
282 """Evaluation of strong coupling constant alpha_S"""
283
284
285
286
287
288
289
290
291
292
293
294
295 - def __init__(self, asmz, nloop, zmass=91.188, cmass=1.4, bmass=4.7):
296
297 self.asmz = asmz
298 self.nloop = nloop
299 self.zmass = zmass
300 self.cmass = cmass
301 self.bmass = bmass
302
303 assert asmz > 0
304 assert cmass > 0
305 assert bmass > 0
306 assert nloop > -1
307 t = 2 * math.log(bmass/zmass)
308 self.amb = self.newton1(t, asmz, 5)
309 t = 2 * math.log(cmass/bmass)
310 self.amc = self.newton1(t, self.amb, 4)
311
313 """Evaluation of strong coupling constant alpha_S at scale 'scale'."""
314 assert scale > 0
315
316
317 if scale < 0.188775276209:
318 return 0
319 elif scale < self.cmass:
320 t = 2 * math.log(scale/self.cmass)
321 return self.newton1(t, self.amc, 3)
322 elif scale < self.bmass:
323 t = 2 * math.log(scale/self.bmass)
324 return self.newton1(t, self.amb, 4)
325 else:
326 t = 2 * math.log(scale/self.zmass)
327 return self.newton1(t, self.asmz, 5)
328
329
330 b0 = [0.716197243913527, 0.66314559621623, 0.61009394851893]
331
332 c1 = [0.565884242104515, 0.49019722472304, 0.40134724779695]
333
334 c2 = [0.453013579178645, 0.30879037953664, 0.14942733137107]
335
336 d = [1.22140465909230, 0.99743079911360, 0.66077962451190]
337
338
339
341 """calculate a_out using nloop beta-function evolution
342 with nf flavours, given starting value as-in
343 given alphas and logarithmic separation between
344 input scale and output scale t.
345 Evolution is performed using Newton's method,
346 with a precision given by tol."""
347 nloop = self.nloop
348 tol = 5e-4
349 arg = nf-3
350 b0, c1, c2, d = self.b0[arg], self.c1[arg], self.c2[arg], self.d[arg]
351
352 if nloop == 2:
353 f = lambda AS: 1.0/AS+c1*math.log((c1*AS)/(1+c1*AS))
354 elif nloop == 3:
355 f = lambda AS: 1.0/AS+0.5*c1*math.log((c2*AS**2)/(1+c1*AS+c2*AS**2)) \
356 -(c1**2-2*c2)/d*math.atan((2*c2*AS+c1)/d)
357
358 a_out = alphas / (1 + alphas * b0 * t)
359 if nloop == 1:
360 return a_out
361
362 a_out = alphas/(1+b0*alphas*t+c1*alphas*math.log(1+alphas*b0*t))
363 if a_out < 0:
364 a_out = 0.3
365
366 while 1:
367 AS = a_out
368 F = b0 * t + f(alphas) -f(AS)
369 if nloop == 2:
370 FP=1/(AS**2*(1+c1*AS))
371 elif nloop == 3:
372 FP=1/(AS**2*(1+c1*AS + c2 * AS**2))
373 if FP == 0:
374 return AS
375 a_out = AS - F/FP
376 delta = abs(F/FP/AS)
377 if delta < tol:
378 break
379 return a_out
380