Package madgraph :: Package various :: Module systematics
[hide private]
[frames] | no frames]

Source Code for Module madgraph.various.systematics

  1  ################################################################################ 
  2  # 
  3  # Copyright (c) 2016 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  from __future__ import division 
 16  if __name__ == "__main__": 
 17      import sys 
 18      import os 
 19      root = os.path.dirname(__file__) 
 20      if os.path.basename(root) == 'internal': 
 21          sys.path.append(os.path.dirname(root)) 
 22      else: 
 23          sys.path.append(os.path.dirname(os.path.dirname(root))) 
 24           
 25  import lhe_parser 
 26  import banner 
 27  import banner as banner_mod 
 28  import itertools 
 29  import misc 
 30  import math 
 31  import os  
 32  import re 
 33  import sys 
 34  import time 
 35  import StringIO 
 36   
 37  pjoin = os.path.join 
 38   
39 -class SystematicsError(Exception):
40 pass
41
42 -class Systematics(object):
43
44 - def __init__(self, input_file, output_file, 45 start_event=0, stop_event=sys.maxint, write_banner=False, 46 mur=[0.5,1,2], 47 muf=[0.5,1,2], 48 alps=[1], 49 pdf='errorset', #[(id, subset)] 50 dyn=[-1,1,2,3,4], 51 together=[('mur', 'muf', 'dyn')], 52 lhapdf_config=misc.which('lhapdf-config'), 53 log=lambda x: sys.stdout.write(str(x)+'\n') 54 ):
55 56 # INPUT/OUTPUT FILE 57 if isinstance(input_file, str): 58 self.input = lhe_parser.EventFile(input_file) 59 else: 60 self.input = input_file 61 self.output_path = output_file 62 if output_file != None: 63 if isinstance(output_file, str): 64 if output_file == input_file: 65 directory,name = os.path.split(output_file) 66 new_name = pjoin(directory, '.tmp_'+name) 67 self.output = lhe_parser.EventFile(new_name, 'w') 68 else: 69 self.output = lhe_parser.EventFile(output_file, 'w') 70 else: 71 self.output = output_file 72 self.log = log 73 74 #get some information from the run_card. 75 self.banner = banner_mod.Banner(self.input.banner) 76 self.force_write_banner = bool(write_banner) 77 self.orig_dyn = self.banner.get('run_card', 'dynamical_scale_choice') 78 self.orig_pdf = self.banner.run_card.get_lhapdf_id() 79 80 #check for beam 81 beam1, beam2 = self.banner.get_pdg_beam() 82 if abs(beam1) != 2212 and abs(beam2) != 2212: 83 self.b1 = 0 84 self.b2 = 0 85 pdf = 'central' 86 #raise SystematicsError, 'can only reweight proton beam' 87 elif abs(beam1) != 2212: 88 self.b1 = 0 89 self.b2 = beam2//2212 90 elif abs(beam2) != 2212: 91 self.b1 = beam1//2212 92 self.b2 = 0 93 else: 94 self.b1 = beam1//2212 95 self.b2 = beam2//2212 96 97 if isinstance(self.banner.run_card, banner_mod.RunCardLO): 98 self.is_lo = True 99 if not self.banner.run_card['use_syst']: 100 raise SystematicsError, 'The events have not been generated with use_syst=True. Cannot evaluate systematics error on these events.' 101 else: 102 self.is_lo = False 103 if not self.banner.run_card['store_rwgt_info']: 104 raise SystematicsError, 'The events have not been generated with store_rwgt_info=True. Cannot evaluate systematics error on these events.' 105 106 # MUR/MUF/ALPS PARSING 107 if isinstance(mur, str): 108 mur = mur.split(',') 109 self.mur=[float(i) for i in mur] 110 if isinstance(muf, str): 111 muf = muf.split(',') 112 self.muf=[float(i) for i in muf] 113 114 if isinstance(alps, str): 115 alps = alps.split(',') 116 self.alps=[float(i) for i in alps] 117 118 # DYNAMICAL SCALE PARSING + together 119 if isinstance(dyn, str): 120 dyn = dyn.split(',') 121 self.dyn=[int(i) for i in dyn] 122 123 if isinstance(together, str): 124 self.together = together.split(',') 125 else: 126 self.together = together 127 128 # START/STOP EVENT 129 self.start_event=int(start_event) 130 self.stop_event=int(stop_event) 131 if start_event != 0: 132 self.log( "#starting from event #%s" % start_event) 133 if stop_event != sys.maxint: 134 self.log( "#stopping at event #%s" % stop_event) 135 136 # LHAPDF set 137 if isinstance(lhapdf_config, list): 138 lhapdf_config = lhapdf_config[0] 139 lhapdf = misc.import_python_lhapdf(lhapdf_config) 140 if not lhapdf: 141 return 142 lhapdf.setVerbosity(0) 143 self.pdfsets = {} 144 if isinstance(pdf, str): 145 pdf = pdf.split(',') 146 147 if isinstance(pdf,list) and isinstance(pdf[0],(str,int)): 148 self.pdf = [] 149 for data in pdf: 150 if data == 'errorset': 151 data = '%s' % self.orig_pdf 152 if data == 'central': 153 data = '%s@0' % self.orig_pdf 154 if '@' in data: 155 #one particular dataset 156 name, arg = data.rsplit('@',1) 157 if int(arg) == 0: 158 if name.isdigit(): 159 self.pdf.append(lhapdf.mkPDF(int(name))) 160 else: 161 self.pdf.append(lhapdf.mkPDF(name)) 162 elif name.isdigit(): 163 try: 164 self.pdf.append(lhapdf.mkPDF(int(name)+int(arg))) 165 except: 166 raise Exception, 'Individual error sets need to be called with LHAPDF NAME not with LHAGLUE NUMBER' 167 else: 168 self.pdf.append(lhapdf.mkPDF(name, int(arg))) 169 else: 170 if data.isdigit(): 171 pdfset = lhapdf.mkPDF(int(data)).set() 172 else: 173 pdfset = lhapdf.mkPDF(data).set() 174 self.pdfsets[pdfset.lhapdfID] = pdfset 175 self.pdf += pdfset.mkPDFs() 176 else: 177 self.pdf = pdf 178 179 for p in self.pdf: 180 if p.lhapdfID == self.orig_pdf: 181 self.orig_pdf = p 182 break 183 else: 184 self.orig_pdf = lhapdf.mkPDF(self.orig_pdf) 185 if not self.b1 == 0 == self.b2: 186 self.log( "# events generated with PDF: %s (%s)" %(self.orig_pdf.set().name,self.orig_pdf.lhapdfID )) 187 # create all the function that need to be called 188 self.get_all_fct() # define self.fcts and self.args 189 190 # For e+/e- type of collision initialise the running of alps 191 if self.b1 == 0 == self.b2: 192 try: 193 from models.model_reader import Alphas_Runner 194 except ImportError: 195 root_path = pjoin(root, os.pardir, os.pardir) 196 try: 197 import internal.madevent_interface as me_int 198 cmd = me_int.MadEventCmd(root_path,force_run=True) 199 except ImportError: 200 import internal.amcnlo_run_interface as me_int 201 cmd = me_int.Cmd(root_path,force_run=True) 202 if 'mg5_path' in cmd.options and cmd.options['mg5_path']: 203 sys.path.append(cmd.options['mg5_path']) 204 from models.model_reader import Alphas_Runner 205 206 if not hasattr(self.banner, 'param_card'): 207 param_card = self.banner.charge_card('param_card') 208 else: 209 param_card = self.banner.param_card 210 211 asmz = param_card.get_value('sminputs', 3, 0.13) 212 nloop =2 213 zmass = param_card.get_value('mass', 23, 91.188) 214 cmass = param_card.get_value('mass', 4, 1.4) 215 if cmass == 0: 216 cmass = 1.4 217 bmass = param_card.get_value('mass', 5, 4.7) 218 if bmass == 0: 219 bmass = 4.7 220 self.alpsrunner = Alphas_Runner(asmz, nloop, zmass, cmass, bmass)
221 222
223 - def run(self, stdout=sys.stdout):
224 """ """ 225 start_time = time.time() 226 if self.start_event == 0 or self.force_write_banner: 227 lowest_id = self.write_banner(self.output) 228 else: 229 lowest_id = self.get_id() 230 231 ids = [lowest_id+i for i in range(len(self.args)-1)] 232 all_cross = [0 for i in range(len(self.args))] 233 234 self.input.parsing = False 235 for nb_event,event in enumerate(self.input): 236 if nb_event < self.start_event: 237 continue 238 elif nb_event == self.start_event: 239 self.input.parsing = True 240 event = lhe_parser.Event(event) 241 elif nb_event >= self.stop_event: 242 if self.force_write_banner: 243 self.output.write('</LesHouchesEvents>\n') 244 break 245 246 if self.is_lo: 247 if (nb_event-self.start_event)>=0 and (nb_event-self.start_event) % 2500 ==0: 248 self.log( '# currently at event %s [elapsed time: %.2g s]' % (nb_event, time.time()-start_time)) 249 else: 250 if (nb_event-self.start_event)>=0 and (nb_event-self.start_event) % 1000 ==0: 251 self.log( '# currently at event %i [elapsed time: %.2g s]' % (nb_event, time.time()-start_time)) 252 253 self.new_event() #re-init the caching of alphas/pdf 254 if self.is_lo: 255 wgts = [self.get_lo_wgt(event, *arg) for arg in self.args] 256 else: 257 wgts = [self.get_nlo_wgt(event, *arg) for arg in self.args] 258 259 if wgts[0] == 0: 260 print wgts 261 print event 262 raise Exception 263 264 wgt = [event.wgt*wgts[i]/wgts[0] for i in range(1,len(wgts))] 265 all_cross = [(all_cross[j] + event.wgt*wgts[j]/wgts[0]) for j in range(len(wgts))] 266 267 rwgt_data = event.parse_reweight() 268 rwgt_data.update(zip(ids, wgt)) 269 event.reweight_order += ids 270 # order the 271 self.output.write(str(event)) 272 else: 273 self.output.write('</LesHouchesEvents>\n') 274 self.output.close() 275 self.print_cross_sections(all_cross, min(nb_event,self.stop_event)-self.start_event+1, stdout) 276 277 if self.output.name != self.output_path: 278 import shutil 279 shutil.move(self.output.name, self.output_path) 280 281 return all_cross
282
283 - def print_cross_sections(self, all_cross, nb_event, stdout):
284 """print the cross-section.""" 285 286 norm = self.banner.get('run_card', 'event_norm', default='sum') 287 #print "normalisation is ", norm 288 #print "nb_event is ", nb_event 289 290 max_scale, min_scale = 0,sys.maxint 291 max_alps, min_alps = 0, sys.maxint 292 max_dyn, min_dyn = 0,sys.maxint 293 pdfs = {} 294 dyns = {} # dyn : {'max': , 'min':} 295 296 if norm == 'sum': 297 norm = 1 298 elif norm == 'average': 299 norm = 1./nb_event 300 elif norm == 'unity': 301 norm = 1 302 303 all_cross = [c*norm for c in all_cross] 304 stdout.write("# mur\t\tmuf\t\talpsfact\tdynamical_scale\tpdf\t\tcross-section\n") 305 for i,arg in enumerate(self.args): 306 307 to_print = list(arg) 308 to_print[4] = to_print[4].lhapdfID 309 to_print.append(all_cross[i]) 310 to_report = [] 311 stdout.write('%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\n' % tuple(to_print)) 312 313 mur, muf, alps, dyn, pdf = arg[:5] 314 if pdf == self.orig_pdf and (dyn==self.orig_dyn or dyn==-1)\ 315 and (mur!=1 or muf!=1 or alps!=1): 316 max_scale = max(max_scale,all_cross[i]) 317 min_scale = min(min_scale,all_cross[i]) 318 if pdf == self.orig_pdf and mur==1 and muf==1 and \ 319 (dyn==self.orig_dyn or dyn==-1) and alps!=1: 320 max_alps = max(max_alps,all_cross[i]) 321 min_alps = min(min_alps,all_cross[i]) 322 323 if pdf == self.orig_pdf and mur==1 and muf==1 and alps==1: 324 max_dyn = max(max_dyn,all_cross[i]) 325 min_dyn = min(min_dyn,all_cross[i]) 326 327 if pdf == self.orig_pdf and (alps!=1 or mur!=1 or muf!=1) and \ 328 (dyn!=self.orig_dyn or dyn!=-1): 329 if dyn not in dyns: 330 dyns[dyn] = {'max':0, 'min':sys.maxint,'central':0} 331 curr = dyns[dyn] 332 curr['max'] = max(curr['max'],all_cross[i]) 333 curr['min'] = min(curr['min'],all_cross[i]) 334 if pdf == self.orig_pdf and (alps==1 and mur==1 and muf==1) and \ 335 (dyn!=self.orig_dyn or dyn!=-1): 336 if dyn not in dyns: 337 dyns[dyn] = {'max':0, 'min':sys.maxint,'central':all_cross[i]} 338 else: 339 dyns[dyn]['central'] = all_cross[i] 340 341 if alps==1 and mur==1 and muf==1 and (dyn==self.orig_dyn or dyn==-1): 342 pdfset = pdf.set() 343 if pdfset.lhapdfID in self.pdfsets: 344 if pdfset.lhapdfID not in pdfs : 345 pdfs[pdfset.lhapdfID] = [0] * pdfset.size 346 pdfs[pdfset.lhapdfID][pdf.memberID] = all_cross[i] 347 else: 348 to_report.append('# PDF %s : %s\n' % (pdf.lhapdfID, all_cross[i])) 349 350 stdout.write('\n') 351 352 resume = StringIO.StringIO() 353 354 resume.write( '#***************************************************************************\n') 355 resume.write( "#\n") 356 resume.write( '# original cross-section: %s\n' % all_cross[0]) 357 if max_scale: 358 resume.write( '# scale variation: +%2.3g%% -%2.3g%%\n' % ((max_scale-all_cross[0])/all_cross[0]*100,(all_cross[0]-min_scale)/all_cross[0]*100)) 359 if max_alps: 360 resume.write( '# emission scale variation: +%2.3g%% -%2.3g%%\n' % ((max_alps-all_cross[0])/all_cross[0]*100,(max_alps-min_scale)/all_cross[0]*100)) 361 if max_dyn and (max_dyn!= all_cross[0] or min_dyn != all_cross[0]): 362 resume.write( '# central scheme variation: +%2.3g%% -%2.3g%%\n' % ((max_dyn-all_cross[0])/all_cross[0]*100,(all_cross[0]-min_dyn)/all_cross[0]*100)) 363 if self.orig_pdf.lhapdfID in pdfs: 364 lhapdfid = self.orig_pdf.lhapdfID 365 values = pdfs[lhapdfid] 366 pdfset = self.pdfsets[lhapdfid] 367 pdferr = pdfset.uncertainty(values) 368 resume.write( '# PDF variation: +%2.3g%% -%2.3g%%\n' % (pdferr.errplus*100/all_cross[0], pdferr.errminus*100/all_cross[0])) 369 # report error/central not directly linked to the central 370 resume.write( "#\n") 371 for lhapdfid,values in pdfs.items(): 372 if lhapdfid == self.orig_pdf.lhapdfID: 373 continue 374 if len(values) == 1 : 375 continue 376 pdfset = self.pdfsets[lhapdfid] 377 378 if pdfset.errorType == 'unknown' : 379 # Don't know how to determine uncertainty for 'unknown' errorType : 380 # File "lhapdf.pyx", line 329, in lhapdf.PDFSet.uncertainty (lhapdf.cpp:6621) 381 # RuntimeError: "ErrorType: unknown" not supported by LHAPDF::PDFSet::uncertainty. 382 continue 383 pdferr = pdfset.uncertainty(values) 384 resume.write( '#PDF %s: %g +%2.3g%% -%2.3g%%\n' % (pdfset.name, pdferr.central,pdferr.errplus*100/all_cross[0], pdferr.errminus*100/all_cross[0])) 385 386 dyn_name = {1: '\sum ET', 2:'\sum\sqrt{m^2+pt^2}', 3:'0.5 \sum\sqrt{m^2+pt^2}',4:'\sqrt{\hat s}' } 387 for key, curr in dyns.items(): 388 if key ==-1: 389 continue 390 central, maxvalue, minvalue = curr['central'], curr['max'], curr['min'] 391 if central == 0: 392 continue 393 if maxvalue == 0: 394 resume.write("# dynamical scheme # %s : %g # %s\n" %(key, central, dyn_name[key])) 395 else: 396 resume.write("# dynamical scheme # %s : %g +%2.3g%% -%2.3g%% # %s\n" %(key, central, (maxvalue-central)/central*100,(central-minvalue)/central*100, dyn_name[key])) 397 398 resume.write('\n'.join(to_report)) 399 400 resume.write( '#***************************************************************************\n') 401 402 stdout.write(resume.getvalue()) 403 self.log(resume.getvalue())
404 405
406 - def write_banner(self, fsock):
407 """create the new banner with the information of the weight""" 408 409 cid = self.get_id() 410 lowest_id = cid 411 412 in_scale = False 413 in_pdf = False 414 in_alps = False 415 416 text = '' 417 418 default = self.args[0] 419 for arg in self.args[1:]: 420 mur, muf, alps, dyn, pdf = arg[:5] 421 if pdf == self.orig_pdf and alps ==1 and (mur!=1 or muf!=1 or dyn!=-1): 422 if not in_scale: 423 text += "<weightgroup name=\"Central scale variation\" combine=\"envelope\">\n" 424 in_scale=True 425 elif in_scale: 426 if (pdf == self.orig_pdf and alps ==1) and arg != default: 427 pass 428 else: 429 text += "</weightgroup> # scale\n" 430 in_scale = False 431 432 if pdf == self.orig_pdf and mur == muf == 1 and dyn==-1 and alps!=1: 433 if not in_alps: 434 text += "<weightgroup name=\"Emission scale variation\" combine=\"envelope\">\n" 435 in_alps=True 436 elif in_alps: 437 text += "</weightgroup> # ALPS\n" 438 in_alps=False 439 440 if mur == muf == 1 and dyn==-1 and alps ==1: 441 if pdf.lhapdfID < 0: 442 for central,sets in self.pdfsets.items(): 443 if pdf in sets.set(): 444 misc.sprint(central) 445 446 if pdf.lhapdfID in self.pdfsets: 447 if in_pdf: 448 text += "</weightgroup> # PDFSET -> PDFSET\n" 449 pdfset = self.pdfsets[pdf.lhapdfID] 450 descrip = pdfset.description.replace('=>',';').replace('>','.gt.').replace('<','.lt.') 451 text +="<weightgroup name=\"%s\" combine=\"%s\"> # %s: %s\n" %\ 452 (pdfset.name, pdfset.errorType,pdfset.lhapdfID, descrip) 453 in_pdf=pdf.lhapdfID 454 elif pdf.memberID == 0 and (pdf.lhapdfID - pdf.memberID) in self.pdfsets: 455 if in_pdf: 456 text += "</weightgroup> # PDFSET -> PDFSET\n" 457 pdfset = self.pdfsets[pdf.lhapdfID - 1] 458 descrip = pdfset.description.replace('=>',';').replace('>','.gt.').replace('<','.lt.') 459 text +="<weightgroup name=\"%s\" combine=\"%s\"> # %s: %s\n" %\ 460 (pdfset.name, pdfset.errorType,pdfset.lhapdfID, descrip) 461 in_pdf=pdfset.lhapdfID 462 elif in_pdf and pdf.lhapdfID - pdf.memberID != in_pdf: 463 misc.sprint(pdf.lhapdfID) 464 text += "</weightgroup> # PDFSET -> PDF\n" 465 in_pdf = False 466 elif in_pdf: 467 text += "</weightgroup> PDF \n" 468 in_pdf=False 469 470 471 472 tag, info = '','' 473 if mur!=1.: 474 tag += 'MUR="%s" ' % mur 475 info += 'MUR=%s ' % mur 476 else: 477 tag += 'MUR="%s" ' % mur 478 if muf!=1.: 479 tag += 'MUF="%s" ' % muf 480 info += 'MUF=%s ' % muf 481 else: 482 tag += 'MUF="%s" ' % muf 483 484 if alps!=1.: 485 tag += 'ALPSFACT="%s" ' % alps 486 info += 'alpsfact=%s ' % alps 487 if dyn!=-1.: 488 tag += 'DYN_SCALE="%s" ' % dyn 489 info += 'dyn_scale_choice=%s ' % {1:'sum pt', 2:'HT',3:'HT/2',4:'sqrts'}[dyn] 490 491 if pdf != self.orig_pdf: 492 tag += 'PDF="%s" ' % pdf.lhapdfID 493 info += 'PDF=%s MemberID=%s' % (pdf.lhapdfID-pdf.memberID, pdf.memberID) 494 else: 495 tag += 'PDF="%s" ' % pdf.lhapdfID 496 497 text +='<weight id="%s" %s> %s </weight>\n' % (cid, tag, info) 498 cid+=1 499 500 if in_scale or in_alps or in_pdf: 501 text += "</weightgroup>\n" 502 503 if 'initrwgt' in self.banner: 504 self.banner['initrwgt'] += text 505 else: 506 self.banner['initrwgt'] = text 507 508 509 self.banner.write(self.output, close_tag=False) 510 511 return lowest_id
512 513
514 - def get_id(self):
515 516 if 'initrwgt' in self.banner: 517 pattern = re.compile('<weight id=(?:\'|\")([_\w]+)(?:\'|\")', re.S+re.I+re.M) 518 return max([int(wid) for wid in pattern.findall(self.banner['initrwgt']) if wid.isdigit()])+1 519 else: 520 return 1
521 522 523 524
525 - def get_all_fct(self):
526 527 all_args = [] 528 default = [1.,1.,1.,-1,self.orig_pdf] 529 #all_args.append(default) 530 pos = {'mur':0, 'muf':1, 'alps':2, 'dyn':3, 'pdf':4} 531 done = set() 532 for one_block in self.together: 533 for name in one_block: 534 done.add(name) 535 for together in itertools.product(*[getattr(self,name) for name in one_block]): 536 new_args = list(default) 537 for name,value in zip(one_block, together): 538 new_args[pos[name]] = value 539 all_args.append(new_args) 540 for name in pos: 541 if name in done: 542 continue 543 for value in getattr(self, name): 544 new_args = list(default) 545 new_args[pos[name]] = value 546 all_args.append(new_args) 547 548 self.args = [default] + [arg for arg in all_args if arg!= default] 549 550 # add the default before the pdf scan to have a full grouping 551 pdfplusone = [pdf for pdf in self.pdf if pdf.lhapdfID == self.orig_pdf.lhapdfID+1] 552 if pdfplusone: 553 pdfplusone = default[:-1] + [pdfplusone[0]] 554 index = self.args.index(pdfplusone) 555 self.args.insert(index, default) 556 557 self.log( "#Will Compute %s weights per event." % (len(self.args)-1)) 558 return
559
560 - def new_event(self):
561 self.alphas = {} 562 self.pdfQ2 = {}
563 564
565 - def get_pdfQ(self, pdf, pdg, x, scale):
566 567 if pdg in [-21,-22]: 568 pdg = abs(pdg) 569 elif pdg == 0: 570 return 1 571 572 f = pdf.xfxQ(pdg, x, scale)/x 573 # if f == 0 and pdf.memberID ==0: 574 # pdfset = pdf.set() 575 # allnumber= [p.xfxQ(pdg, x, scale) for p in pdfset.mkPDFs()] 576 # f = pdfset.uncertainty(allnumber).central /x 577 return f
578
579 - def get_pdfQ2(self, pdf, pdg, x, scale):
580 581 if pdg in [-21,-22]: 582 pdg = abs(pdg) 583 elif pdg == 0: 584 return 1 585 586 if (pdf, pdg,x,scale) in self.pdfQ2: 587 return self.pdfQ2[(pdf, pdg,x,scale)] 588 f = pdf.xfxQ2(pdg, x, scale)/x 589 self.pdfQ2[(pdf, pdg,x,scale)] = f 590 return f 591 592 #one method to handle the nnpd2.3 problem -> now just move to central 593 if f == 0 and pdf.memberID ==0: 594 # to avoid problem with nnpdf2.3 in lhapdf6.1.6 595 #print 'central pdf returns 0', pdg, x, scale 596 #print self.pdfsets 597 pdfset = pdf.set() 598 allnumber= [0] + [self.get_pdfQ2(p, pdg, x, scale) for p in pdfset.mkPDFs()[1:]] 599 f = pdfset.uncertainty(allnumber).central 600 self.pdfQ2[(pdf, pdg,x,scale)] = f 601 return f
602
603 - def get_lo_wgt(self,event, Dmur, Dmuf, Dalps, dyn, pdf):
604 """ 605 pdf is a lhapdf object!""" 606 607 loinfo = event.parse_lo_weight() 608 609 if dyn == -1: 610 mur = loinfo['ren_scale'] 611 muf1 = loinfo['pdf_q1'][-1] 612 muf2 = loinfo['pdf_q2'][-1] 613 else: 614 if dyn == 1: 615 mur = event.get_et_scale(1.) 616 elif dyn == 2: 617 mur = event.get_ht_scale(1.) 618 elif dyn == 3: 619 mur = event.get_ht_scale(0.5) 620 elif dyn == 4: 621 mur = event.get_sqrts_scale(1.) 622 muf1 = mur 623 muf2 = mur 624 loinfo = dict(loinfo) 625 loinfo['pdf_q1'] = loinfo['pdf_q1'] [:-1] + [mur] 626 loinfo['pdf_q2'] = loinfo['pdf_q2'] [:-1] + [mur] 627 628 629 630 # MUR part 631 if self.b1 == 0 == self.b2: 632 if loinfo['n_qcd'] != 0: 633 wgt = self.alpsrunner(Dmur*mur)**loinfo['n_qcd'] 634 else: 635 wgt = 1.0 636 else: 637 wgt = pdf.alphasQ(Dmur*mur)**loinfo['n_qcd'] 638 # MUF/PDF part 639 wgt *= self.get_pdfQ(pdf, self.b1*loinfo['pdf_pdg_code1'][-1], loinfo['pdf_x1'][-1], Dmuf*muf1) 640 wgt *= self.get_pdfQ(pdf, self.b2*loinfo['pdf_pdg_code2'][-1], loinfo['pdf_x2'][-1], Dmuf*muf2) 641 642 for scale in loinfo['asrwt']: 643 if self.b1 == 0 == self.b2: 644 wgt = self.alpsrunner(Dalps*scale) 645 else: 646 wgt *= pdf.alphasQ(Dalps*scale) 647 648 # ALS part 649 for i in range(loinfo['n_pdfrw1']-1): 650 scale = min(Dalps*loinfo['pdf_q1'][i], Dmuf*muf1) 651 wgt *= self.get_pdfQ(pdf, self.b1*loinfo['pdf_pdg_code1'][i], loinfo['pdf_x1'][i], scale) 652 wgt /= self.get_pdfQ(pdf, self.b1*loinfo['pdf_pdg_code1'][i], loinfo['pdf_x1'][i+1], scale) 653 654 for i in range(loinfo['n_pdfrw2']-1): 655 scale = min(Dalps*loinfo['pdf_q2'][i], Dmuf*muf2) 656 wgt *= self.get_pdfQ(pdf, self.b2*loinfo['pdf_pdg_code2'][i], loinfo['pdf_x2'][i], scale) 657 wgt /= self.get_pdfQ(pdf, self.b2*loinfo['pdf_pdg_code2'][i], loinfo['pdf_x2'][i+1], scale) 658 659 return wgt
660
661 - def get_nlo_wgt(self,event, Dmur, Dmuf, Dalps, dyn, pdf):
662 """return the new weight for NLO event --with weight information-- """ 663 664 wgt = 0 665 nloinfo = event.parse_nlo_weight(real_type=(1,11,12,13)) 666 for cevent in nloinfo.cevents: 667 if dyn == 1: 668 mur2 = cevent.get_et_scale(1.)**2 669 elif dyn == 2: 670 mur2 = cevent.get_ht_scale(1.)**2 671 elif dyn == 3: 672 mur2 = cevent.get_ht_scale(0.5)**2 673 elif dyn == 4: 674 mur2 = cevent.get_sqrts_scale(event,1)**2 675 else: 676 mur2 = 0 677 muf2 = mur2 678 679 for onewgt in cevent.wgts: 680 if not __debug__ and (dyn== -1 and Dmur==1 and Dmuf==1 and pdf==self.orig_pdf): 681 wgt += onewgt.ref_wgt 682 683 if dyn == -1: 684 mur2 = onewgt.scales2[1] 685 muf2 = onewgt.scales2[2] 686 Q2 = onewgt.scales2[0] # Ellis-Sexton scale 687 688 wgtpdf = self.get_pdfQ2(pdf, self.b1*onewgt.pdgs[0], onewgt.bjks[0], 689 Dmuf**2 * muf2) 690 wgtpdf *= self.get_pdfQ2(pdf, self.b2*onewgt.pdgs[1], onewgt.bjks[1], 691 Dmuf**2 * muf2) 692 693 tmp = onewgt.pwgt[0] 694 tmp += onewgt.pwgt[1] * math.log(Dmur**2 * mur2/ Q2) 695 tmp += onewgt.pwgt[2] * math.log(Dmuf**2 * muf2/ Q2) 696 697 if self.b1 == 0 == self.b2: 698 alps = self.alpsrunner(Dmur*math.sqrt(mur2)) 699 else: 700 alps = pdf.alphasQ2(Dmur**2*mur2) 701 702 tmp *= math.sqrt(4*math.pi*alps)**onewgt.qcdpower 703 704 if wgtpdf == 0: #happens for nn23pdf due to wrong set in lhapdf 705 key = (self.b1*onewgt.pdgs[0], self.b2*onewgt.pdgs[1], onewgt.bjks[0],onewgt.bjks[1], muf2) 706 if dyn== -1 and Dmuf==1 and Dmur==1 and pdf==self.orig_pdf: 707 wgtpdf = onewgt.ref_wgt / tmp 708 self.pdfQ2[key] = wgtpdf 709 elif key in self.pdfQ2: 710 wgtpdf = self.pdfQ2[key] 711 else: 712 # real zero! 713 wgtpdf = 0 714 715 tmp *= wgtpdf 716 wgt += tmp 717 718 if __debug__ and dyn== -1 and Dmur==1 and Dmuf==1 and pdf==self.orig_pdf: 719 if not misc.equal(tmp, onewgt.ref_wgt, sig_fig=2): 720 misc.sprint(tmp, onewgt.ref_wgt, (tmp-onewgt.ref_wgt)/tmp) 721 misc.sprint(onewgt) 722 misc.sprint(cevent) 723 misc.sprint(mur2,muf2) 724 raise Exception, 'not enough agreement between stored value and computed one' 725 726 727 return wgt
728 729
730 -def call_systematics(args, result=sys.stdout, running=True, 731 log=lambda x:sys.stdout.write(str(x)+'\n')):
732 """calling systematics from a list of arguments""" 733 734 input, output = args[0:2] 735 opts = {} 736 for arg in args[2:]: 737 if '=' in arg: 738 key,values= arg.split('=') 739 key = key.replace('-','') 740 values = values.strip() 741 if values[0] in ["'",'"'] and values[-1]==values[0]: 742 values = values[1:-1] 743 values = values.split(',') 744 if key == 'together': 745 if key in opts: 746 opts[key].append(tuple(values)) 747 else: 748 opts[key]=[tuple(values)] 749 elif key == 'result': 750 result = open(values[0],'w') 751 elif key in ['start_event', 'stop_event']: 752 opts[key] = int(values[0]) 753 elif key == 'write_banner': 754 opts[key] = banner_mod.ConfigFile.format_variable(values[0], bool, 'write_banner') 755 else: 756 if key in opts: 757 opts[key] += values 758 else: 759 opts[key] = values 760 else: 761 raise SystematicsError, "unknow argument %s" % arg 762 763 #load run_card and extract parameter if needed. 764 if 'from_card' in opts: 765 if opts['from_card'] != ['internal']: 766 card = banner.RunCard(opts['from_card'][0]) 767 else: 768 for i in range(10): 769 try: 770 lhe = lhe_parser.EventFile(input) 771 break 772 except OSError,error: 773 print error 774 time.sleep(15*(i+1)) 775 else: 776 raise 777 778 card = banner.RunCard(banner.Banner(lhe.banner)['mgruncard']) 779 lhe.close() 780 781 if isinstance(card, banner.RunCardLO): 782 # LO case 783 opts['mur'] = [float(x) for x in card['sys_scalefact'].split()] 784 opts['muf'] = opts['mur'] 785 if card['sys_alpsfact'] != 'None': 786 opts['alps'] = [float(x) for x in card['sys_alpsfact'].split()] 787 else: 788 opts['alps'] = [1.0] 789 opts['together'] = [('mur','muf','alps','dyn')] 790 if '&&' in card['sys_pdf']: 791 pdfs = card['sys_pdf'].split('&&') 792 else: 793 data = card['sys_pdf'].split() 794 pdfs = [] 795 for d in data: 796 if not d.isdigit(): 797 pdfs.append(d) 798 elif int(d) > 500: 799 pdfs.append(d) 800 else: 801 pdfs[-1] = '%s %s' % (pdfs[-1], d) 802 803 opts['dyn'] = [-1,1,2,3,4] 804 opts['pdf'] = [] 805 for pdf in pdfs: 806 split = pdf.split() 807 if len(split)==1: 808 opts['pdf'].append('%s' %pdf) 809 else: 810 pdf,nb = split 811 for i in range(int(nb)): 812 opts['pdf'].append('%s@%s' % (pdf, i)) 813 if not opts['pdf']: 814 opts['pdf'] = 'central' 815 else: 816 #NLO case 817 raise Exception 818 del opts['from_card'] 819 820 821 obj = Systematics(input, output, log=log,**opts) 822 if running: 823 obj.run(result) 824 return obj
825 826 if __name__ == "__main__": 827 sys_args = sys.argv[1:] 828 for i, arg in enumerate(sys_args) : 829 if arg.startswith('--lhapdf_config=') : 830 lhapdf = misc.import_python_lhapdf(arg[len('--lhapdf_config='):]) 831 del sys_args[i] 832 break 833 834 if 'lhapdf' not in globals(): 835 lhapdf = misc.import_python_lhapdf('lhapdf-config') 836 837 if not lhapdf: 838 sys.exit('Can not run systematics since can not link python to lhapdf, specify --lhapdf-config=') 839 call_systematics(sys_args) 840