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