| 1 | #!/usr/bin/env python
|
|---|
| 2 | ##########################################################################
|
|---|
| 3 | ## ##
|
|---|
| 4 | ## MadWeight ##
|
|---|
| 5 | ## --------- ##
|
|---|
| 6 | ##########################################################################
|
|---|
| 7 | ## ##
|
|---|
| 8 | ## author: Mattelaer Olivier (CP3) ##
|
|---|
| 9 | ## email: olivier.mattelaer@uclouvain.be ##
|
|---|
| 10 | ## ##
|
|---|
| 11 | ##########################################################################
|
|---|
| 12 | ## ##
|
|---|
| 13 | ## license: GNU ##
|
|---|
| 14 | ## last-modif:08/07/08 ##
|
|---|
| 15 | ## version 1.1 ##
|
|---|
| 16 | ## ##
|
|---|
| 17 | ##########################################################################
|
|---|
| 18 | ## ##
|
|---|
| 19 | ## README: ##
|
|---|
| 20 | ## input: a regular lhe file ##
|
|---|
| 21 | ## output: a lhco file ##
|
|---|
| 22 | ## ##
|
|---|
| 23 | ## how to launch the program: ##
|
|---|
| 24 | ## $> python ./convert_lhe_lhco input_file output_file ##
|
|---|
| 25 | ## (output file we overwritted) ##
|
|---|
| 26 | ## or ##
|
|---|
| 27 | ## $> python ./convert_lhe_lhc and follows instruction ##
|
|---|
| 28 | ##########################################################################
|
|---|
| 29 | ## ##
|
|---|
| 30 | ## Content ##
|
|---|
| 31 | ## ------- ##
|
|---|
| 32 | ## ##
|
|---|
| 33 | ## + Particle ##
|
|---|
| 34 | ## | + init ##
|
|---|
| 35 | ## | + def_pid ##
|
|---|
| 36 | ## | + cal_mass ##
|
|---|
| 37 | ## | + cal_pt ##
|
|---|
| 38 | ## | + cal_phi ##
|
|---|
| 39 | ## | + cal_eta ##
|
|---|
| 40 | ## | | + check_def ##
|
|---|
| 41 | ## | + lhco_line ##
|
|---|
| 42 | ## + part_quadvec -> Particle ##
|
|---|
| 43 | ## | + init ##
|
|---|
| 44 | ## | + add ##
|
|---|
| 45 | ## + Pass_from_lhe_to_lhco ##
|
|---|
| 46 | ## | + init ##
|
|---|
| 47 | ## | + find_begin_blok ##
|
|---|
| 48 | ## | + find_end_blok ##
|
|---|
| 49 | ## | + put_in_output ##
|
|---|
| 50 | ## | | + define_particle ##
|
|---|
| 51 | ## | | + write_output ##
|
|---|
| 52 | ## ##
|
|---|
| 53 | ## ##
|
|---|
| 54 | ##########################################################################
|
|---|
| 55 | import sys
|
|---|
| 56 | import math
|
|---|
| 57 | import re
|
|---|
| 58 | ##########################################################################
|
|---|
| 59 | ## START CODE
|
|---|
| 60 | ##########################################################################
|
|---|
| 61 |
|
|---|
| 62 |
|
|---|
| 63 | #1 ########################################################################
|
|---|
| 64 | class Particle:
|
|---|
| 65 | """particle information"""
|
|---|
| 66 |
|
|---|
| 67 | #2 ########################################################################
|
|---|
| 68 | def __init__(self):
|
|---|
| 69 | """start a particle"""
|
|---|
| 70 |
|
|---|
| 71 |
|
|---|
| 72 |
|
|---|
| 73 | self.pid=''
|
|---|
| 74 | self.E=''
|
|---|
| 75 | self.px=''
|
|---|
| 76 | self.py=''
|
|---|
| 77 | self.pz=''
|
|---|
| 78 | self.pt=''
|
|---|
| 79 | self.phi=''
|
|---|
| 80 | self.y=''
|
|---|
| 81 | self.mass=''
|
|---|
| 82 |
|
|---|
| 83 | #2 ########################################################################
|
|---|
| 84 | def def_pid(self,pid):
|
|---|
| 85 | """ define pid of the particle """
|
|---|
| 86 | self.pid=int(pid)
|
|---|
| 87 |
|
|---|
| 88 | #2 ########################################################################
|
|---|
| 89 | def cal_mass(self):
|
|---|
| 90 | """ define mass from quadri impulsion """
|
|---|
| 91 |
|
|---|
| 92 | if not self.check_def(['E','px','py','pz']):
|
|---|
| 93 | sys.exit('Particle error: Quadri impulsion not define (error for mass routine)')
|
|---|
| 94 |
|
|---|
| 95 |
|
|---|
| 96 |
|
|---|
| 97 | if self.E**2-self.px**2-self.py**2-self.pz**2>1e-7: #precision problem
|
|---|
| 98 | self.mass=math.sqrt(self.E**2-self.px**2-self.py**2-self.pz**2)
|
|---|
| 99 | else:
|
|---|
| 100 | self.mass=0
|
|---|
| 101 |
|
|---|
| 102 | #2 ########################################################################
|
|---|
| 103 | def def_mass(self,mass):
|
|---|
| 104 | """ put the value for the mass """
|
|---|
| 105 |
|
|---|
| 106 | self.mass=float(mass)
|
|---|
| 107 |
|
|---|
| 108 |
|
|---|
| 109 | #2 ########################################################################
|
|---|
| 110 | def cal_pt(self):
|
|---|
| 111 | """define pt from quadri impulsion"""
|
|---|
| 112 |
|
|---|
| 113 | if not self.check_def(['E','px','py','pz']):
|
|---|
| 114 | sys.exit('Particle error: Quadri impulsion not define (error for pt routine)')
|
|---|
| 115 |
|
|---|
| 116 | self.pt =math.sqrt(self.px**2+self.py**2)
|
|---|
| 117 |
|
|---|
| 118 | #2 ########################################################################
|
|---|
| 119 | def cal_phi(self):
|
|---|
| 120 | """define phi from quadri impulsion"""
|
|---|
| 121 |
|
|---|
| 122 | if not self.check_def(['E','px','py','pz']):
|
|---|
| 123 | sys.exit('Particle error: Quadri impulsion not define (error for phi routine)')
|
|---|
| 124 |
|
|---|
| 125 | if(self.px>0):
|
|---|
| 126 | self.phi=math.atan(self.py/self.px)
|
|---|
| 127 | elif(self.px<0):
|
|---|
| 128 | self.phi=math.atan(self.py/self.px)+math.pi
|
|---|
| 129 | elif(self.py>0): #remind that p(1)=0
|
|---|
| 130 | self.phi=math.pi/2.0
|
|---|
| 131 | elif(self.py<0): # remind that p(1)=0
|
|---|
| 132 | self.phi=-math.pi/2.0
|
|---|
| 133 | else:
|
|---|
| 134 | print "Warning self.phi not properly defined put value to 0"
|
|---|
| 135 | self.phi=0
|
|---|
| 136 |
|
|---|
| 137 | if(self.phi<0):
|
|---|
| 138 | self.phi=self.phi+2*math.pi
|
|---|
| 139 |
|
|---|
| 140 | return self.phi
|
|---|
| 141 | #2 ########################################################################
|
|---|
| 142 | def cal_eta(self):
|
|---|
| 143 | """define y from quadri impulsion"""
|
|---|
| 144 |
|
|---|
| 145 | if not self.check_def(['E','px','py','pz']):
|
|---|
| 146 | sys.exit('Particle error: Quadri impulsion not define (error for eta routine)')
|
|---|
| 147 |
|
|---|
| 148 | theta=math.acos(self.pz/math.sqrt(self.px**2+self.py**2+self.pz**2))
|
|---|
| 149 | self.eta=-math.log(math.tan(theta/2.0))
|
|---|
| 150 |
|
|---|
| 151 | #3 ########################################################################
|
|---|
| 152 | def check_def(self,data_list):
|
|---|
| 153 | """ check if everything is defined """
|
|---|
| 154 |
|
|---|
| 155 | if type(data_list)!=list:
|
|---|
| 156 | data_list=[data_list]
|
|---|
| 157 |
|
|---|
| 158 | for value in data_list:
|
|---|
| 159 | if type(eval('self.'+value))==str:
|
|---|
| 160 | print "failed for", value
|
|---|
| 161 | return 0
|
|---|
| 162 | return 1
|
|---|
| 163 |
|
|---|
| 164 | #2 ########################################################################
|
|---|
| 165 | def lhco_line(self):
|
|---|
| 166 | """ define the line for the lhco line (without the initial tag)
|
|---|
| 167 | this is a first simple, trully naive, routine.
|
|---|
| 168 | """
|
|---|
| 169 | if not self.check_def(['eta','phi','pt','mass','pid']):
|
|---|
| 170 | sys.exit('Particle error: some attribute not defined')
|
|---|
| 171 |
|
|---|
| 172 | jet=[1,2,3,4,5,6,21]
|
|---|
| 173 | inv_list=[12,14,16,18,1000022,1000023,1000024,1000025,1000035]
|
|---|
| 174 |
|
|---|
| 175 | #define pid-> type
|
|---|
| 176 | pid_to_type={11:1,-11:1,13:2,-13:2,15:3,-15:3,22:0}
|
|---|
| 177 | for data in jet:
|
|---|
| 178 | pid_to_type[data]=4
|
|---|
| 179 | pid_to_type[-data]=4
|
|---|
| 180 | for data in inv_list:
|
|---|
| 181 | pid_to_type[data]=6
|
|---|
| 182 | pid_to_type[-data]=6
|
|---|
| 183 |
|
|---|
| 184 |
|
|---|
| 185 |
|
|---|
| 186 | type=''
|
|---|
| 187 | for key in pid_to_type.keys():
|
|---|
| 188 | if self.pid==key:
|
|---|
| 189 | type=pid_to_type[key]
|
|---|
| 190 | break
|
|---|
| 191 |
|
|---|
| 192 | if type=='':
|
|---|
| 193 | print 'Warning unknown type'
|
|---|
| 194 | return ''
|
|---|
| 195 |
|
|---|
| 196 | text =' '+str(type) #type LHCO
|
|---|
| 197 | text+=' '+str(self.eta) #ETA
|
|---|
| 198 | text+=' '+str(self.phi) #PHI
|
|---|
| 199 | text+=' '+str(self.pt) #PT
|
|---|
| 200 | text+=' '+str(self.mass) #JMASS
|
|---|
| 201 | if self.pid in [11,13]: #NTRK
|
|---|
| 202 | text+=' -1'
|
|---|
| 203 | else:
|
|---|
| 204 | text+=' 1'
|
|---|
| 205 | if self.pid in [-5,5]: #BTAG
|
|---|
| 206 | text+=' 2'
|
|---|
| 207 | else:
|
|---|
| 208 | text+=' 0'
|
|---|
| 209 | text+=' 0' #HAD/EM
|
|---|
| 210 | text+=' 0' #DUMMY 1
|
|---|
| 211 | text+=' 0' #DUMMY 2
|
|---|
| 212 |
|
|---|
| 213 | return text
|
|---|
| 214 |
|
|---|
| 215 | #1 ########################################################################
|
|---|
| 216 | class part_quadvec(Particle):
|
|---|
| 217 | """ particle define from quadri impulsion """
|
|---|
| 218 |
|
|---|
| 219 | #2 ########################################################################
|
|---|
| 220 | def __init__(self,E,px,py,pz):
|
|---|
| 221 | """ define from a quadri vector """
|
|---|
| 222 | Particle.__init__(self)
|
|---|
| 223 | self.E=float(E)
|
|---|
| 224 | self.px=float(px)
|
|---|
| 225 | self.py=float(py)
|
|---|
| 226 | self.pz=float(pz)
|
|---|
| 227 | self.cal_pt()
|
|---|
| 228 | self.cal_phi()
|
|---|
| 229 | self.cal_eta()
|
|---|
| 230 | #self.cal_mass()
|
|---|
| 231 | print self.E,self.px,self.py,self.pz
|
|---|
| 232 | print self.pt,self.phi,self.eta
|
|---|
| 233 |
|
|---|
| 234 | #2 ########################################################################
|
|---|
| 235 | def add(self,particle):
|
|---|
| 236 | """ add two quadri vector """
|
|---|
| 237 |
|
|---|
| 238 | if not self.check_def(['E','px','py','pz']):
|
|---|
| 239 | sys.exit('Particle error: Quadri impulsion not define')
|
|---|
| 240 | if not particle.check_def(['E','px','py','pz']):
|
|---|
| 241 | sys.exit('Particle error: Quadri impulsion not define')
|
|---|
| 242 |
|
|---|
| 243 | neut=part_quadvec(self.E+particle.E,self.px+particle.px,self.py+particle.py,self.pz+particle.pz)
|
|---|
| 244 | neut.cal_mass()
|
|---|
| 245 | return neut
|
|---|
| 246 |
|
|---|
| 247 |
|
|---|
| 248 | #1 ########################################################################
|
|---|
| 249 | class Pass_from_lhe_to_lhco:
|
|---|
| 250 |
|
|---|
| 251 |
|
|---|
| 252 | #2 ########################################################################
|
|---|
| 253 | def __init__(self,input,output):
|
|---|
| 254 |
|
|---|
| 255 | self.still_to_read=1
|
|---|
| 256 | self.nb_data=0
|
|---|
| 257 | self.input=open(input,'r')
|
|---|
| 258 | self.output=open(output,'w')
|
|---|
| 259 | while 1:
|
|---|
| 260 | self.find_begin_blok()
|
|---|
| 261 | text=self.find_end_blok()
|
|---|
| 262 | if text:
|
|---|
| 263 | self.put_in_output(text)
|
|---|
| 264 | else:
|
|---|
| 265 | break
|
|---|
| 266 |
|
|---|
| 267 | #2 ########################################################################
|
|---|
| 268 | def find_begin_blok(self):
|
|---|
| 269 |
|
|---|
| 270 | tag=re.compile('''<event>''',re.I)
|
|---|
| 271 | while 1:
|
|---|
| 272 | line=self.input.readline()
|
|---|
| 273 | if line=='':
|
|---|
| 274 | self.still_to_read=0
|
|---|
| 275 | return
|
|---|
| 276 | if tag.search(line):
|
|---|
| 277 | return
|
|---|
| 278 |
|
|---|
| 279 | #2 ########################################################################
|
|---|
| 280 | def find_end_blok(self):
|
|---|
| 281 |
|
|---|
| 282 | tag=re.compile(r'''</event>''')
|
|---|
| 283 | text=[]
|
|---|
| 284 |
|
|---|
| 285 | while 1:
|
|---|
| 286 | line=self.input.readline()
|
|---|
| 287 | if line=='':
|
|---|
| 288 | self.still_to_read=0
|
|---|
| 289 | return
|
|---|
| 290 | text.append(line)
|
|---|
| 291 | if tag.search(line):
|
|---|
| 292 | return text
|
|---|
| 293 |
|
|---|
| 294 | #2 ########################################################################
|
|---|
| 295 | def put_in_output(self,text):
|
|---|
| 296 | """ analyse the event and write the lhco """
|
|---|
| 297 |
|
|---|
| 298 | inv_list=[12,14,16,18,1000022,1000023,1000024,1000025,1000035]
|
|---|
| 299 | inv_list+=[-12,-14,-16,-18,-1000022,-1000023,-1000024,-1000025,-1000035]
|
|---|
| 300 | particle_content=[]
|
|---|
| 301 | neut=0
|
|---|
| 302 | for line in text:
|
|---|
| 303 | particle=self.define_particle(line)
|
|---|
| 304 | if particle==0:
|
|---|
| 305 | continue
|
|---|
| 306 |
|
|---|
| 307 | if particle.pid in inv_list:
|
|---|
| 308 | if neut==0:
|
|---|
| 309 | neut=particle
|
|---|
| 310 | else:
|
|---|
| 311 | neut=neut.add(particle)
|
|---|
| 312 | else:
|
|---|
| 313 | particle_content.append(particle)
|
|---|
| 314 |
|
|---|
| 315 | if neut:
|
|---|
| 316 | neut.pid=12
|
|---|
| 317 | particle_content.append(neut)
|
|---|
| 318 |
|
|---|
| 319 | self.write_output(particle_content)
|
|---|
| 320 |
|
|---|
| 321 | #3 ########################################################################
|
|---|
| 322 | def define_particle(self,line):
|
|---|
| 323 | """ define the particle from the lhe line """
|
|---|
| 324 |
|
|---|
| 325 | pattern=re.compile(r'''^\s*
|
|---|
| 326 | (?P<pid>-?\d+)\s+ #PID
|
|---|
| 327 | (?P<status>1)\s+ #status (1 for output particle)
|
|---|
| 328 | (?P<mother>-?\d+)\s+ #mother
|
|---|
| 329 | (?P=mother)\s+ #mother
|
|---|
| 330 | (?P<color1>[+-e.\d]*)\s+ #color1
|
|---|
| 331 | (?P<color2>[+-e.\d]*)\s+ #color2
|
|---|
| 332 | (?P<px>[+-e.\d]*)\s+ #px
|
|---|
| 333 | (?P<py>[+-e.\d]*)\s+ #py
|
|---|
| 334 | (?P<pz>[+-e.\d]*)\s+ #pz
|
|---|
| 335 | (?P<E>[+-e.\d]*)\s+ #E
|
|---|
| 336 | (?P<mass>[+-e.\d]*)\s+ #mass
|
|---|
| 337 | (?P<dum1>[+-e.\d]*)\s+ #dummy1
|
|---|
| 338 | (?P<dum2>[+-e.\d]*)\s* #dummy2
|
|---|
| 339 | $ #end of string
|
|---|
| 340 | ''',66) #verbose+ignore case
|
|---|
| 341 |
|
|---|
| 342 | if pattern.search(line):
|
|---|
| 343 | obj=pattern.search(line)
|
|---|
| 344 | E=obj.group('E')
|
|---|
| 345 | px=obj.group('px')
|
|---|
| 346 | py=obj.group('py')
|
|---|
| 347 | pz=obj.group('pz')
|
|---|
| 348 | particle=part_quadvec(E,px,py,pz)
|
|---|
| 349 | particle.def_mass(obj.group('mass'))
|
|---|
| 350 | particle.def_pid(obj.group('pid'))
|
|---|
| 351 | return particle
|
|---|
| 352 | else:
|
|---|
| 353 | return 0
|
|---|
| 354 |
|
|---|
| 355 |
|
|---|
| 356 |
|
|---|
| 357 | #3 ########################################################################
|
|---|
| 358 | def write_output(self,content):
|
|---|
| 359 | """ write the input from the content info """
|
|---|
| 360 | text="""# typ eta phi pt jmass ntrk btag had/em dummy dummy\n"""
|
|---|
| 361 | self.output.writelines(text)
|
|---|
| 362 | text="0 "+str(self.nb_data)+" "+str(len(content))+"\n"
|
|---|
| 363 | self.output.writelines(text)
|
|---|
| 364 |
|
|---|
| 365 | i=1
|
|---|
| 366 | for particle in content:
|
|---|
| 367 | text=str(i)+' '+particle.lhco_line()+'\n'
|
|---|
| 368 | self.output.writelines(text)
|
|---|
| 369 | i+=1
|
|---|
| 370 |
|
|---|
| 371 |
|
|---|
| 372 |
|
|---|
| 373 | ##########################################################################
|
|---|
| 374 | ## END CODE
|
|---|
| 375 | ##########################################################################
|
|---|
| 376 | if __name__=='__main__':
|
|---|
| 377 | opt=sys.argv
|
|---|
| 378 | if len(opt)!=3:
|
|---|
| 379 | input=raw_input('enter the position of the input lhe file')
|
|---|
| 380 | output=raw_input('enter the position of the output lhco file')
|
|---|
| 381 | else:
|
|---|
| 382 | input=opt[1]
|
|---|
| 383 | output=opt[2]
|
|---|
| 384 |
|
|---|
| 385 | Pass_from_lhe_to_lhco(input,output)
|
|---|