1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 import models.model_reader as model_reader
16 import madgraph.core.base_objects as base_objects
17 import madgraph.various.misc as misc
20 """ a error class for this file """
21
23 """ A class for writting an update param_card for a given model """
24
25 header = \
26 "######################################################################\n" + \
27 "## PARAM_CARD AUTOMATICALY GENERATED BY MG5 FOLLOWING UFO MODEL ####\n" + \
28 "######################################################################\n" + \
29 "## ##\n" + \
30 "## Width set on Auto will be computed following the information ##\n" + \
31 "## present in the decay.py files of the model. ##\n" + \
32 '## See arXiv:1402.1178 for more details. ##\n' + \
33 "## ##\n" + \
34 "######################################################################\n"
35
36 sm_pdg = [1,2,3,4,5,6,11,12,13,13,14,15,16,21,22,23,24,25]
37 qnumber_str ="""Block QNUMBERS %(pdg)d # %(name)s
38 1 %(charge)g # 3 times electric charge
39 2 %(spin)d # number of spin states (2S+1)
40 3 %(color)d # colour rep (1: singlet, 3: triplet, 8: octet)
41 4 %(antipart)d # Particle/Antiparticle distinction (0=own anti)\n"""
42
43
44 - def __init__(self, model, filepath=None):
64
65
67 """ return {'name': parameterObject}"""
68
69 out = {}
70 for key, params in self.model['parameters'].items():
71 for param in params:
72 out[param.name] = param
73
74 if 'ZERO' not in out.keys():
75 zero = base_objects.ModelVariable('ZERO', '0', 'real')
76 out['ZERO'] = zero
77 return out
78
79
81 """define self.dep_mass and self.dep_width in case that they are
82 requested in the param_card.dat"""
83
84 all_particles = self.model['particles']
85
86
87 self.dep_mass, self.dep_width = [] , []
88 self.duplicate_mass, self.duplicate_width = [], []
89
90 def_param = []
91
92 for p in all_particles:
93 mass = self.param_dict[p["mass"]]
94 if isinstance(mass, base_objects.ParamCardVariable):
95 if mass.lhacode[0] != p['pdg_code']:
96 self.duplicate_mass.append((p, mass))
97 continue
98 if mass in def_param:
99 self.duplicate_mass.append((p, mass))
100 continue
101 elif p["mass"] != 'ZERO':
102 def_param.append(mass)
103 if p['mass'] not in self.external:
104 self.dep_mass.append((p, mass))
105
106
107 def_param = []
108 for p in all_particles:
109 width = self.param_dict[p["width"]]
110 if isinstance(width, base_objects.ParamCardVariable):
111 if width.lhacode[0] != p['pdg_code']:
112 self.duplicate_width.append((p, width))
113 continue
114 if width in def_param:
115 self.duplicate_width.append((p, width))
116 continue
117 else:
118 if p["width"] != 'ZERO':
119 def_param.append(width)
120 if p['width'] not in self.external:
121 self.dep_width.append((p, width))
122
123
124
125 @staticmethod
127 """ order parameter of a given block """
128
129 block1 = obj1.lhablock.upper()
130 block2 = obj2.lhablock.upper()
131
132 if block1 == block2:
133 pass
134 elif block1 == 'DECAY':
135 return 1
136 elif block2 == 'DECAY':
137 return -1
138 elif block1 < block2:
139 return -1
140 elif block1 != block2:
141 return 1
142
143 maxlen = min([len(obj1.lhacode), len(obj2.lhacode)])
144
145 for i in range(maxlen):
146 if obj1.lhacode[i] < obj2.lhacode[i]:
147 return -1
148 elif obj1.lhacode[i] > obj2.lhacode[i]:
149 return 1
150
151
152 if len(obj1.lhacode) > len(obj2.lhacode):
153 return 1
154 elif len(obj1.lhacode) == len(obj2.lhacode):
155 return 0
156 else:
157 return -1
158
168
170 """schedular for writing a card"""
171
172 if path:
173 self.define_input_file(path)
174
175
176 self.external.sort(self.order_param)
177 todo_block= ['MASS', 'DECAY']
178
179 cur_lhablock = ''
180 for param in self.external:
181
182 if cur_lhablock != param.lhablock.upper():
183
184 self.write_dep_param_block(cur_lhablock)
185 cur_lhablock = param.lhablock.upper()
186 if cur_lhablock in todo_block:
187 todo_block.remove(cur_lhablock)
188
189 self.write_block(cur_lhablock)
190
191 self.write_param(param, cur_lhablock)
192 self.write_dep_param_block(cur_lhablock)
193 for cur_lhablock in todo_block:
194 self.write_block(cur_lhablock)
195 self.write_dep_param_block(cur_lhablock)
196 self.write_qnumber()
197
199 """ write a comment for a block"""
200
201 self.fsock.writelines(
202 """\n###################################""" + \
203 """\n## INFORMATION FOR %s""" % name.upper() +\
204 """\n###################################\n"""
205 )
206 if name!='DECAY':
207 self.fsock.write("""Block %s \n""" % name.lower())
208
210 """ write the line corresponding to a given parameter """
211
212 if hasattr(param, 'info'):
213 info = param.info
214 else:
215 info = param.name
216 if info.startswith('mdl_'):
217 info = info[4:]
218
219 if param.value.imag != 0:
220 raise ParamCardWriterError, 'All External Parameter should be real (not the case for %s)'%param.name
221
222
223
224 if param.value == 9.999999e-1:
225 param.value = 1
226 elif param.value == 0.000001e-99:
227 param.value = 0
228
229
230 lhacode=' '.join(['%3s' % key for key in param.lhacode])
231 if lhablock != 'DECAY':
232 text = """ %s %e # %s \n""" % (lhacode, param.value.real, info)
233 else:
234 text = '''DECAY %s %e # %s \n''' % (lhacode, param.value.real, info)
235 self.fsock.write(text)
236
237
239 """writing the requested LHA parameter"""
240
241 if lhablock == 'MASS':
242 data = self.dep_mass
243 prefix = " "
244 elif lhablock == 'DECAY':
245 data = self.dep_width
246 prefix = "DECAY "
247 else:
248 return
249
250 text = ""
251 def sort(el1, el2):
252 (p1,n) =el1
253 (p2,n) = el2
254 if (p1["pdg_code"] -p2["pdg_code"]) > 0:
255 return 1
256 else:
257 return -1
258
259 data.sort(sort)
260 for part, param in data:
261
262 if part["type"] == "ghost":
263 continue
264 if self.model['parameter_dict'][param.name].imag:
265 raise ParamCardWriterError, 'All Mass/Width Parameter should be real (not the case for %s)'%param.name
266 value = complex(self.model['parameter_dict'][param.name]).real
267 text += """%s %s %f # %s : %s \n""" %(prefix, part["pdg_code"],
268 value, part["name"], param.expr.replace('mdl_',''))
269
270
271 if lhablock == 'MASS':
272 data = self.duplicate_mass
273 name = 'mass'
274 elif lhablock == 'DECAY':
275 data = self.duplicate_width
276 name = 'width'
277
278 for part, param in data:
279 if self.model['parameter_dict'][param.name].imag:
280 raise ParamCardWriterError, 'All Mass/Width Parameter should be real'
281 value = complex(self.model['parameter_dict'][param.name]).real
282 text += """%s %s %f # %s : %s \n""" %(prefix, part["pdg_code"],
283 value, part["name"], part[name].replace('mdl_',''))
284
285 if not text:
286 return
287
288 pretext = "## Dependent parameters, given by model restrictions.\n"
289 pretext += "## Those values should be edited following the \n"
290 pretext += "## analytical expression. MG5 ignores those values \n"
291 pretext += "## but they are important for interfacing the output of MG5\n"
292 pretext += "## to external program such as Pythia.\n"
293 self.fsock.write(pretext + text)
294
295
297 """ write qnumber """
298
299 def is_anti(logical):
300 if logical:
301 return 0
302 else:
303 return 1
304
305
306 text = ""
307 for part in self.model['particles']:
308 if part["pdg_code"] in self.sm_pdg or part["pdg_code"] < 0:
309 continue
310
311
312
313 text += self.qnumber_str % {'pdg': part["pdg_code"],
314 'name': part["name"],
315 'charge': 3 * part["charge"],
316 'spin': part["spin"],
317 'color': part["color"],
318 'antipart': is_anti(part['self_antipart'])}
319
320 if text:
321 pretext="""#===========================================================\n"""
322 pretext += """# QUANTUM NUMBERS OF NEW STATE(S) (NON SM PDG CODE)\n"""
323 pretext += """#===========================================================\n\n"""
324
325 self.fsock.write(pretext + text)
326
327
328
329
330
331
332
333
334 if '__main__' == __name__:
335 ParamCardWriter('./param_card.dat', generic=True)
336 print 'write ./param_card.dat'
337