Package models :: Module write_param_card
[hide private]
[frames] | no frames]

Source Code for Module models.write_param_card

  1  ############################################################################### 
  2  # 
  3  # Copyright (c) 2010 The MadGraph5_aMC@NLO Development team and Contributors 
  4  # 
  5  # This file is a part of the MadGraph5_aMC@NLO project, an application which  
  6  # automatically generates Feynman diagrams and matrix elements for arbitrary 
  7  # high-energy processes in the Standard Model and beyond. 
  8  # 
  9  # It is subject to the MadGraph5_aMC@NLO license which should accompany this  
 10  # distribution. 
 11  # 
 12  # For more information, visit madgraph.phys.ucl.ac.be and amcatnlo.web.cern.ch 
 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 
18 19 -class ParamCardWriterError(Exception):
20 """ a error class for this file """
21
22 -class ParamCardWriter(object):
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):
45 """ model is a valid MG5 model, filepath is the path were to write the 46 param_card.dat """ 47 48 # Compute the value of all dependant parameter 49 if isinstance(model, model_reader.ModelReader): 50 self.model = model 51 else: 52 self.model = model_reader.ModelReader(model) 53 self.model.set_parameters_and_couplings() 54 55 56 assert self.model['parameter_dict'] 57 58 # Organize the data 59 self.external = self.model['parameters'][('external',)] 60 self.param_dict = self.create_param_dict() 61 self.define_not_dep_param() 62 63 if filepath: 64 self.define_output_file(filepath) 65 self.write_card()
66 67
68 - def create_param_dict(self):
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
82 - def define_not_dep_param(self):
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 # one loop for the mass 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 # one loop for the width 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
128 - def order_param(obj1, obj2):
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 #identical up to the first finish 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
161 - def define_output_file(self, path, mode='w'):
162 """ initialize the file""" 163 164 if isinstance(path, str): 165 self.fsock = open(path, mode) 166 else: 167 self.fsock = path # prebuild file/IOstring 168 169 self.fsock.write(self.header)
170
171 - def write_card(self, path=None):
172 """schedular for writing a card""" 173 174 if path: 175 self.define_input_file(path) 176 177 # order the parameter in a smart way 178 self.external.sort(self.order_param) 179 todo_block= ['MASS', 'DECAY'] # ensure that those two block are always written 180 181 cur_lhablock = '' 182 for param in self.external: 183 #check if we change of lhablock 184 if cur_lhablock != param.lhablock.upper(): 185 # check if some dependent param should be written 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 # write the header of the new block 191 self.write_block(cur_lhablock) 192 #write the parameter 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
200 - def write_block(self, name):
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
211 - def write_param(self, param, lhablock):
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 # avoid to keep special value used to avoid restriction 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
240 - def write_dep_param_block(self, lhablock):
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 # don't write the width of ghosts particles 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 # Add duplicate parameter 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
298 - def write_qnumber(self):
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 # don't write ghosts in the QNumbers block 313 #if part["type"] == 'ghost': 314 # continue 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