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):
66
67
69 """ return {'name': parameterObject}"""
70
71 out = {}
72 for key, params in self.model['parameters'].items():
73 for param in params:
74 out[param.name] = param
75
76 if 'ZERO' not in out.keys():
77 zero = base_objects.ModelVariable('ZERO', '0', 'real')
78 out['ZERO'] = zero
79 return out
80
81
83 """define self.dep_mass and self.dep_width in case that they are
84 requested in the param_card.dat"""
85
86 all_particles = self.model['particles']
87
88
89 self.dep_mass, self.dep_width = [] , []
90 self.duplicate_mass, self.duplicate_width = [], []
91
92 def_param = []
93
94 for p in all_particles:
95 mass = self.param_dict[p["mass"]]
96 if isinstance(mass, base_objects.ParamCardVariable):
97 if mass.lhacode[0] != p['pdg_code']:
98 self.duplicate_mass.append((p, mass))
99 continue
100 if mass in def_param:
101 self.duplicate_mass.append((p, mass))
102 continue
103 elif p["mass"] != 'ZERO':
104 def_param.append(mass)
105 if p['mass'] not in self.external:
106 self.dep_mass.append((p, mass))
107
108
109 def_param = []
110 for p in all_particles:
111 width = self.param_dict[p["width"]]
112 if isinstance(width, base_objects.ParamCardVariable):
113 if width.lhacode[0] != p['pdg_code']:
114 self.duplicate_width.append((p, width))
115 continue
116 if width in def_param:
117 self.duplicate_width.append((p, width))
118 continue
119 else:
120 if p["width"] != 'ZERO':
121 def_param.append(width)
122 if p['width'] not in self.external:
123 self.dep_width.append((p, width))
124
125
126
127 @staticmethod
129 """ order parameter of a given block """
130
131 block1 = obj1.lhablock.upper()
132 block2 = obj2.lhablock.upper()
133
134 if block1 == block2:
135 pass
136 elif block1 == 'DECAY':
137 return 1
138 elif block2 == 'DECAY':
139 return -1
140 elif block1 < block2:
141 return -1
142 elif block1 != block2:
143 return 1
144
145 maxlen = min([len(obj1.lhacode), len(obj2.lhacode)])
146
147 for i in range(maxlen):
148 if obj1.lhacode[i] < obj2.lhacode[i]:
149 return -1
150 elif obj1.lhacode[i] > obj2.lhacode[i]:
151 return 1
152
153
154 if len(obj1.lhacode) > len(obj2.lhacode):
155 return 1
156 elif len(obj1.lhacode) == len(obj2.lhacode):
157 return 0
158 else:
159 return -1
160
170
172 """schedular for writing a card"""
173
174 if path:
175 self.define_input_file(path)
176
177
178 self.external.sort(self.order_param)
179 todo_block= ['MASS', 'DECAY']
180
181 cur_lhablock = ''
182 for param in self.external:
183
184 if cur_lhablock != param.lhablock.upper():
185
186 self.write_dep_param_block(cur_lhablock)
187 cur_lhablock = param.lhablock.upper()
188 if cur_lhablock in todo_block:
189 todo_block.remove(cur_lhablock)
190
191 self.write_block(cur_lhablock)
192
193 self.write_param(param, cur_lhablock)
194 self.write_dep_param_block(cur_lhablock)
195 for cur_lhablock in todo_block:
196 self.write_block(cur_lhablock)
197 self.write_dep_param_block(cur_lhablock)
198 self.write_qnumber()
199
201 """ write a comment for a block"""
202
203 self.fsock.writelines(
204 """\n###################################""" + \
205 """\n## INFORMATION FOR %s""" % name.upper() +\
206 """\n###################################\n"""
207 )
208 if name!='DECAY':
209 self.fsock.write("""Block %s \n""" % name.lower())
210
212 """ write the line corresponding to a given parameter """
213
214 if hasattr(param, 'info'):
215 info = param.info
216 else:
217 info = param.name
218 if info.startswith('mdl_'):
219 info = info[4:]
220
221 if param.value.imag != 0:
222 raise ParamCardWriterError, 'All External Parameter should be real (not the case for %s)'%param.name
223
224
225
226 if param.value == 9.999999e-1:
227 param.value = 1
228 elif param.value == 0.000001e-99:
229 param.value = 0
230
231
232 lhacode=' '.join(['%3s' % key for key in param.lhacode])
233 if lhablock != 'DECAY':
234 text = """ %s %e # %s \n""" % (lhacode, param.value.real, info)
235 else:
236 text = '''DECAY %s %e # %s \n''' % (lhacode, param.value.real, info)
237 self.fsock.write(text)
238
239
241 """writing the requested LHA parameter"""
242
243 if lhablock == 'MASS':
244 data = self.dep_mass
245 prefix = " "
246 elif lhablock == 'DECAY':
247 data = self.dep_width
248 prefix = "DECAY "
249 else:
250 return
251
252 text = ""
253 def sort(el1, el2):
254 (p1,n) =el1
255 (p2,n) = el2
256 if (p1["pdg_code"] -p2["pdg_code"]) > 0:
257 return 1
258 else:
259 return -1
260
261 data.sort(sort)
262 for part, param in data:
263
264 if part["type"] == "ghost":
265 continue
266 if self.model['parameter_dict'][param.name].imag:
267 raise ParamCardWriterError, 'All Mass/Width Parameter should be real (not the case for %s)'%param.name
268 value = complex(self.model['parameter_dict'][param.name]).real
269 text += """%s %s %f # %s : %s \n""" %(prefix, part["pdg_code"],
270 value, part["name"], param.expr.replace('mdl_',''))
271
272
273 if lhablock == 'MASS':
274 data = self.duplicate_mass
275 name = 'mass'
276 elif lhablock == 'DECAY':
277 data = self.duplicate_width
278 name = 'width'
279
280 for part, param in data:
281 if self.model['parameter_dict'][param.name].imag:
282 raise ParamCardWriterError, 'All Mass/Width Parameter should be real'
283 value = complex(self.model['parameter_dict'][param.name]).real
284 text += """%s %s %f # %s : %s \n""" %(prefix, part["pdg_code"],
285 value, part["name"], part[name].replace('mdl_',''))
286
287 if not text:
288 return
289
290 pretext = "## Dependent parameters, given by model restrictions.\n"
291 pretext += "## Those values should be edited following the \n"
292 pretext += "## analytical expression. MG5 ignores those values \n"
293 pretext += "## but they are important for interfacing the output of MG5\n"
294 pretext += "## to external program such as Pythia.\n"
295 self.fsock.write(pretext + text)
296
297
299 """ write qnumber """
300
301 def is_anti(logical):
302 if logical:
303 return 0
304 else:
305 return 1
306
307
308 text = ""
309 for part in self.model['particles']:
310 if part["pdg_code"] in self.sm_pdg or part["pdg_code"] < 0:
311 continue
312
313
314
315 text += self.qnumber_str % {'pdg': part["pdg_code"],
316 'name': part["name"],
317 'charge': 3 * part["charge"],
318 'spin': part["spin"],
319 'color': part["color"],
320 'antipart': is_anti(part['self_antipart'])}
321
322 if text:
323 pretext="""#===========================================================\n"""
324 pretext += """# QUANTUM NUMBERS OF NEW STATE(S) (NON SM PDG CODE)\n"""
325 pretext += """#===========================================================\n\n"""
326
327 self.fsock.write(pretext + text)
328
329
330
331
332
333
334
335
336 if '__main__' == __name__:
337 ParamCardWriter('./param_card.dat', generic=True)
338 print 'write ./param_card.dat'
339