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 # Organize the data 57 self.external = self.model['parameters'][('external',)] 58 self.param_dict = self.create_param_dict() 59 self.define_not_dep_param() 60 61 if filepath: 62 self.define_output_file(filepath) 63 self.write_card()
64 65
66 - def create_param_dict(self):
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
80 - def define_not_dep_param(self):
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 # one loop for the mass 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 # one loop for the width 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
126 - def order_param(obj1, obj2):
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 #identical up to the first finish 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
159 - def define_output_file(self, path, mode='w'):
160 """ initialize the file""" 161 162 if isinstance(path, str): 163 self.fsock = open(path, mode) 164 else: 165 self.fsock = path # prebuild file/IOstring 166 167 self.fsock.write(self.header)
168
169 - def write_card(self, path=None):
170 """schedular for writing a card""" 171 172 if path: 173 self.define_input_file(path) 174 175 # order the parameter in a smart way 176 self.external.sort(self.order_param) 177 todo_block= ['MASS', 'DECAY'] # ensure that those two block are always written 178 179 cur_lhablock = '' 180 for param in self.external: 181 #check if we change of lhablock 182 if cur_lhablock != param.lhablock.upper(): 183 # check if some dependent param should be written 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 # write the header of the new block 189 self.write_block(cur_lhablock) 190 #write the parameter 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
198 - def write_block(self, name):
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
209 - def write_param(self, param, lhablock):
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 # avoid to keep special value used to avoid restriction 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
238 - def write_dep_param_block(self, lhablock):
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 # don't write the width of ghosts particles 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 # Add duplicate parameter 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
296 - def write_qnumber(self):
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 # don't write ghosts in the QNumbers block 311 #if part["type"] == 'ghost': 312 # continue 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