Package madgraph :: Package interface :: Module reweight_interface
[hide private]
[frames] | no frames]

Source Code for Module madgraph.interface.reweight_interface

   1  ################################################################################ 
   2  # 
   3  # Copyright (c) 2009 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  """ Command interface for Re-Weighting """ 
  16  from __future__ import division 
  17  import difflib 
  18  import logging 
  19  import math 
  20  import os 
  21  import re 
  22  import shutil 
  23  import sys 
  24  import tempfile 
  25  import time 
  26  import subprocess 
  27  from subprocess import Popen, PIPE, STDOUT 
  28   
  29   
  30  pjoin = os.path.join 
  31   
  32  import madgraph.interface.extended_cmd as extended_cmd 
  33  import madgraph.interface.madgraph_interface as mg_interface 
  34  import madgraph.interface.master_interface as master_interface 
  35  import madgraph.interface.common_run_interface as common_run_interface 
  36  import madgraph.interface.madevent_interface as madevent_interface 
  37  import madgraph.iolibs.files as files 
  38  #import MadSpin.interface_madspin as madspin_interface 
  39  import madgraph.various.misc as misc 
  40  import madgraph.various.banner as banner 
  41  import madgraph.various.lhe_parser as lhe_parser 
  42  import madgraph.various.combine_plots as combine_plots 
  43  import madgraph.various.cluster as cluster 
  44  import madgraph.fks.fks_common as fks_common 
  45  import madgraph.core.diagram_generation as diagram_generation 
  46   
  47  import models.import_ufo as import_ufo 
  48  import models.check_param_card as check_param_card  
  49  #import MadSpin.decay as madspin 
  50   
  51   
  52  logger = logging.getLogger('decay.stdout') # -> stdout 
  53  logger_stderr = logging.getLogger('decay.stderr') # ->stderr 
  54  cmd_logger = logging.getLogger('cmdprint2') # -> print 
  55   
  56  # global to check which f2py module have been already loaded. (to avoid border effect) 
  57  dir_to_f2py_free_mod = {} 
  58  nb_f2py_module = 0 # each time the process/model is changed this number is modified to  
59 # forced the python module to re-create an executable 60 61 #lhapdf = None 62 63 64 -class ReweightInterface(extended_cmd.Cmd):
65 """Basic interface for reweighting operation""" 66 67 prompt = 'Reweight>' 68 debug_output = 'Reweight_debug' 69 rwgt_dir_possibility = ['rw_me','rw_me_second','rw_mevirt','rw_mevirt_second'] 70 71 @misc.mute_logger()
72 - def __init__(self, event_path=None, allow_madspin=False, mother=None, *completekey, **stdin):
73 """initialize the interface with potentially an event_path""" 74 75 76 self.me_dir = os.getcwd() 77 if not event_path: 78 cmd_logger.info('************************************************************') 79 cmd_logger.info('* *') 80 cmd_logger.info('* Welcome to Reweight Module *') 81 cmd_logger.info('* *') 82 cmd_logger.info('************************************************************') 83 extended_cmd.Cmd.__init__(self, *completekey, **stdin) 84 85 self.model = None 86 self.has_standalone_dir = False 87 self.mother= mother # calling interface 88 self.multicore=False 89 90 self.options = {'curr_dir': os.path.realpath(os.getcwd()), 91 'rwgt_name':None, 92 "allow_missing_finalstate":False} 93 94 self.events_file = None 95 self.processes = {} 96 self.f2pylib = {} 97 self.second_model = None 98 self.second_process = None 99 self.dedicated_path = {} 100 self.soft_threshold = None 101 self.systematics = False # allow to run systematics in ouput2.0 mode 102 self.boost_event = False 103 self.mg5cmd = master_interface.MasterCmd() 104 if mother: 105 self.mg5cmd.options.update(mother.options) 106 self.seed = None 107 self.output_type = "default" 108 self.helicity_reweighting = True 109 self.rwgt_mode = '' # can be LO, NLO, NLO_tree, '' is default 110 self.has_nlo = False 111 self.rwgt_dir = None 112 self.exitted = False # Flag to know if do_quit was already called. 113 self.keep_ordering = False 114 if event_path: 115 logger.info("Extracting the banner ...") 116 self.do_import(event_path, allow_madspin=allow_madspin) 117 118 # dictionary to fortan evaluator 119 self.calculator = {} 120 self.calculator_nbcall = {} 121 122 #all the cross-section for convenience 123 self.all_cross_section = {}
124
125 - def do_import(self, inputfile, allow_madspin=False):
126 """import the event file""" 127 128 args = self.split_arg(inputfile) 129 if not args: 130 return self.InvalidCmd, 'import requires arguments' 131 132 # change directory where to write the output 133 self.options['curr_dir'] = os.path.realpath(os.path.dirname(inputfile)) 134 if os.path.basename(os.path.dirname(os.path.dirname(inputfile))) == 'Events': 135 self.options['curr_dir'] = pjoin(self.options['curr_dir'], 136 os.path.pardir, os.pardir) 137 138 139 if not os.path.exists(inputfile): 140 if inputfile.endswith('.gz'): 141 if not os.path.exists(inputfile[:-3]): 142 raise self.InvalidCmd('No such file or directory : %s' % inputfile) 143 else: 144 inputfile = inputfile[:-3] 145 elif os.path.exists(inputfile + '.gz'): 146 inputfile = inputfile + '.gz' 147 else: 148 raise self.InvalidCmd('No such file or directory : %s' % inputfile) 149 150 if inputfile.endswith('.gz'): 151 misc.gunzip(inputfile) 152 inputfile = inputfile[:-3] 153 154 # Read the banner of the inputfile 155 self.lhe_input = lhe_parser.EventFile(os.path.realpath(inputfile)) 156 if not self.lhe_input.banner: 157 value = self.ask("What is the path to banner", 0, [0], "please enter a path", timeout=0) 158 self.lhe_input.banner = open(value).read() 159 self.banner = self.lhe_input.get_banner() 160 161 #get original cross-section/error 162 if 'init' not in self.banner: 163 self.orig_cross = (0,0) 164 #raise self.InvalidCmd('Event file does not contain init information') 165 else: 166 for line in self.banner['init'].split('\n'): 167 split = line.split() 168 if len(split) == 4: 169 cross, error = float(split[0]), float(split[1]) 170 self.orig_cross = (cross, error) 171 172 173 174 # Check the validity of the banner: 175 if 'slha' not in self.banner: 176 self.events_file = None 177 raise self.InvalidCmd('Event file does not contain model information') 178 elif 'mg5proccard' not in self.banner: 179 self.events_file = None 180 raise self.InvalidCmd('Event file does not contain generation information') 181 182 if 'madspin' in self.banner and not allow_madspin: 183 raise self.InvalidCmd('Reweight should be done before running MadSpin') 184 185 186 # load information 187 process = self.banner.get_detail('proc_card', 'generate') 188 if '[' in process and isinstance(self.banner.get('run_card'), banner.RunCardNLO): 189 if not self.banner.get_detail('run_card', 'store_rwgt_info'): 190 logger.warning("The information to perform a proper NLO reweighting is not present in the event file.") 191 logger.warning(" We will perform a LO reweighting instead. This does not guarantee NLO precision.") 192 self.rwgt_mode = 'LO' 193 194 if self.mother and 'OLP' in self.mother.options: 195 if self.mother.options['OLP'].lower() != 'madloop': 196 logger.warning("Accurate NLO mode only works for OLP=MadLoop not for OLP=%s. An approximate (LO) reweighting will be performed instead") 197 self.rwgt_mode = 'LO' 198 199 if self.mother and 'lhapdf' in self.mother.options and not self.mother.options['lhapdf']: 200 logger.warning('NLO accurate reweighting requires lhapdf to be installed. Pass in approximate LO mode.') 201 self.rwgt_mode = 'LO' 202 else: 203 self.rwgt_mode = 'LO' 204 205 if not process: 206 msg = 'Invalid proc_card information in the file (no generate line):\n %s' % self.banner['mg5proccard'] 207 raise Exception, msg 208 process, option = mg_interface.MadGraphCmd.split_process_line(process) 209 self.proc_option = option 210 self.is_decay = len(process.split('>',1)[0].split()) == 1 211 212 logger.info("process: %s" % process) 213 logger.info("options: %s" % option)
214 215 216 @staticmethod
217 - def get_LO_definition_from_NLO(proc, model, real_only=False):
218 """return the LO definitions of the process corresponding to the born/real""" 219 220 # split the line definition with the part before and after the NLO tag 221 process, order, final = re.split('\[\s*(.*)\s*\]', proc) 222 if process.strip().startswith(('generate', 'add process')): 223 process = process.replace('generate', '') 224 process = process.replace('add process','') 225 226 # add the part without any additional jet. 227 commandline="add process %s %s --no_warning=duplicate;" % (process, final) 228 if not order: 229 #NO NLO tag => nothing to do actually return input 230 return proc 231 elif not order.startswith(('virt','LOonly','noborn')): 232 # OK this a standard NLO process 233 if real_only: 234 commandline= '' 235 236 if '=' in order: 237 # get the type NLO QCD/QED/... 238 order = order.split('=',1)[1].strip() 239 240 # define the list of particles that are needed for the radiation 241 pert = fks_common.find_pert_particles_interactions(model, 242 pert_order = order)['soft_particles'] 243 commandline += "define pert_%s = %s;" % (order.replace(' ',''), ' '.join(map(str,pert)) ) 244 245 # check if we have to increase by one the born order 246 247 if '%s=' % order in process or '%s<=' % order in process: 248 result=re.split(' ',process) 249 process='' 250 for r in result: 251 if '%s=' % order in r: 252 ior=re.split('=',r) 253 r='QCD=%i' % (int(ior[1])+1) 254 elif '%s<=' % order in r: 255 ior=re.split('=',r) 256 r='QCD<=%i' % (int(ior[1])+1) 257 process=process+r+' ' 258 #handle special tag $ | / @ 259 result = re.split('([/$@]|\w+(?:^2)?(?:=|<=|>)+\w+)', process, 1) 260 if len(result) ==3: 261 process, split, rest = result 262 commandline+="add process %s pert_%s %s%s %s --no_warning=duplicate;" % (process, order.replace(' ','') ,split, rest, final) 263 else: 264 commandline +='add process %s pert_%s %s --no_warning=duplicate;' % (process,order.replace(' ',''), final) 265 elif order.startswith(('noborn=')): 266 # pass in sqrvirt= 267 return "add process %s [%s] %s;" % (process, order.replace('noborn=', 'sqrvirt='), final) 268 elif order.startswith('LOonly'): 269 #remove [LOonly] flag 270 return "add process %s %s;" % (process, final) 271 else: 272 #just return the input. since this Madloop. 273 if order: 274 return "add process %s [%s] %s ;" % (process, order,final) 275 else: 276 return "add process %s %s ;" % (process, final) 277 return commandline
278 279
280 - def check_events(self):
281 """Check some basic property of the events file""" 282 283 sum_of_weight = 0 284 sum_of_abs_weight = 0 285 negative_event = 0 286 positive_event = 0 287 288 start = time.time() 289 for event_nb,event in enumerate(self.lhe_input): 290 #control logger 291 if (event_nb % max(int(10**int(math.log10(float(event_nb)+1))),10)==0): 292 running_time = misc.format_timer(time.time()-start) 293 logger.info('Event nb %s %s' % (event_nb, running_time)) 294 if (event_nb==10001): logger.info('reducing number of print status. Next status update in 10000 events') 295 296 try: 297 event.check() #check 4 momenta/... 298 except Exception, error: 299 print event 300 raise error 301 sum_of_weight += event.wgt 302 sum_of_abs_weight += abs(event.wgt) 303 if event.wgt < 0 : 304 negative_event +=1 305 else: 306 positive_event +=1 307 308 logger.info("total cross-section: %s" % sum_of_weight) 309 logger.info("total abs cross-section: %s" % sum_of_abs_weight) 310 logger.info("fraction of negative event %s", negative_event/(negative_event+positive_event)) 311 logger.info("total number of events %s", (negative_event+positive_event)) 312 logger.info("negative event %s", negative_event)
313 314 315 316 317 @extended_cmd.debug()
318 - def complete_import(self, text, line, begidx, endidx):
319 "Complete the import command" 320 321 args=self.split_arg(line[0:begidx]) 322 323 if len(args) == 1: 324 base_dir = '.' 325 else: 326 base_dir = args[1] 327 328 return self.path_completion(text, base_dir) 329 330 # Directory continuation 331 if os.path.sep in args[-1] + text: 332 return self.path_completion(text, 333 pjoin(*[a for a in args if \ 334 a.endswith(os.path.sep)]))
335
336 - def help_change(self):
337 """help for change command""" 338 339 print "change model X :use model X for the reweighting" 340 print "change process p p > e+ e-: use a new process for the reweighting" 341 print "change process p p > mu+ mu- --add : add one new process to existing ones" 342 print "change output [default|2.0|unweight]:" 343 print " default: add weight(s) to the current file"
344
345 - def do_change(self, line):
346 """allow to define a second model/processes""" 347 348 global nb_f2py_module 349 350 args = self.split_arg(line) 351 if len(args)<2: 352 logger.critical("not enough argument (need at least two). Discard line") 353 if args[0] == "model": 354 nb_f2py_module += 1 # tag to force the f2py to reload 355 self.second_model = " ".join(args[1:]) 356 if self.has_standalone_dir: 357 self.terminate_fortran_executables() 358 self.has_standalone_dir = False 359 elif args[0] == "keep_ordering": 360 self.keep_ordering = banner.ConfigFile.format_variable(args[1], bool, "keep_ordering") 361 elif args[0] == "allow_missing_finalstate": 362 self.options["allow_missing_finalstate"] = banner.ConfigFile.format_variable(args[1], bool, "allow_missing_finalstate") 363 elif args[0] == "process": 364 nb_f2py_module += 1 365 if self.has_standalone_dir: 366 self.terminate_fortran_executables() 367 self.has_standalone_dir = False 368 if args[-1] == "--add": 369 self.second_process.append(" ".join(args[1:-1])) 370 else: 371 self.second_process = [" ".join(args[1:])] 372 elif args[0] == "boost": 373 self.boost_event = eval(' '.join(args[1:])) 374 elif args[0] in ['virtual_path', 'tree_path']: 375 self.dedicated_path[args[0]] = os.path.abspath(args[1]) 376 elif args[0] == "output": 377 if args[1] in ['default', '2.0', 'unweight']: 378 self.output_type = args[1] 379 elif args[0] == "helicity": 380 self.helicity_reweighting = banner.ConfigFile.format_variable(args[1], bool, "helicity") 381 elif args[0] == "mode": 382 if args[1] != 'LO': 383 if 'OLP' in self.mother.options and self.mother.options['OLP'].lower() != 'madloop': 384 logger.warning("Only LO reweighting is allowed for OLP!=MadLoop. Keeping the mode to LO.") 385 self.rwgt_mode = 'LO' 386 elif not self.banner.get_detail('run_card','store_rwgt_info', default=False): 387 logger.warning("Missing information for NLO type of reweighting. Keeping the mode to LO.") 388 self.rwgt_mode = 'LO' 389 elif 'lhapdf' in self.mother.options and not self.mother.options['lhapdf']: 390 logger.warning('NLO accurate reweighting requires lhapdf to be installed. Pass in approximate LO mode.') 391 self.rwgt_mode = 'LO' 392 else: 393 self.rwgt_mode = args[1] 394 else: 395 self.rwgt_mode = args[1] 396 elif args[0] == "rwgt_dir": 397 self.rwgt_dir = args[1] 398 if not os.path.exists(self.rwgt_dir): 399 os.mkdir(self.rwgt_dir) 400 self.rwgt_dir = os.path.abspath(self.rwgt_dir) 401 elif args[0] == 'systematics': 402 if self.output_type == 'default' and args[1].lower() not in ['none', 'off']: 403 logger.warning('systematics can only be computed for non default output type. pass to output mode \'2.0\'') 404 self.output_type = '2.0' 405 if len(args) == 2: 406 try: 407 self.systematics = banner.ConfigFile.format_variable(args[1], bool) 408 except Exception, error: 409 self.systematics = args[1:] 410 else: 411 self.systematics = args[1:] 412 elif args[0] == 'soft_threshold': 413 self.soft_threshold = banner.ConfigFile.format_variable(args[1], float, 'soft_threshold') 414 elif args[0] == 'multicore': 415 pass 416 # this line is meant to be parsed by common_run_interface and change the way this class is called. 417 #It has no direct impact on this class. 418 else: 419 logger.critical("unknown option! %s. Discard line." % args[0])
420 421
422 - def check_launch(self, args):
423 """check the validity of the launch command""" 424 425 if not self.lhe_input: 426 if isinstance(self.lhe_input, lhe_parser.EventFile): 427 self.lhe_input = lhe_parser.EventFile(self.lhe_input.name) 428 else: 429 raise self.InvalidCmd("No events files defined.") 430 431 opts = {'rwgt_name':None, 'rwgt_info':None} 432 if any(a.startswith('--') for a in args): 433 for a in args[:]: 434 if a.startswith('--') and '=' in a: 435 key,value = a[2:].split('=') 436 opts[key] = value .replace("'","") .replace('"','') 437 438 return opts
439
440 - def help_launch(self):
441 """help for the launch command""" 442 443 logger.info('''Add to the loaded events a weight associated to a 444 new param_card (to be define). The weight returned is the ratio of the 445 square matrix element by the squared matrix element of production. 446 All scale are kept fix for this re-weighting.''')
447 448
449 - def get_weight_names(self):
450 """ return the various name for the computed weights """ 451 452 if self.rwgt_mode == 'LO': 453 return [''] 454 elif self.rwgt_mode == 'NLO': 455 return ['_nlo'] 456 elif self.rwgt_mode == 'LO+NLO': 457 return ['_lo', '_nlo'] 458 elif self.rwgt_mode == 'NLO_tree': 459 return ['_tree'] 460 elif not self.rwgt_mode and self.has_nlo : 461 return ['_nlo'] 462 else: 463 return ['']
464 465 @misc.mute_logger()
466 - def do_launch(self, line):
467 """end of the configuration launched the code""" 468 469 args = self.split_arg(line) 470 opts = self.check_launch(args) 471 if opts['rwgt_name']: 472 self.options['rwgt_name'] = opts['rwgt_name'] 473 if opts['rwgt_info']: 474 self.options['rwgt_info'] = opts['rwgt_info'] 475 model_line = self.banner.get('proc_card', 'full_model_line') 476 477 if not self.has_standalone_dir: 478 if self.rwgt_dir and os.path.exists(pjoin(self.rwgt_dir,'rw_me','rwgt.pkl')): 479 self.load_from_pickle() 480 if opts['rwgt_name']: 481 self.options['rwgt_name'] = opts['rwgt_name'] 482 if not self.rwgt_dir: 483 self.me_dir = self.rwgt_dir 484 self.load_module() # load the fortran information from the f2py module 485 elif self.multicore == 'wait': 486 i=0 487 while not os.path.exists(pjoin(self.me_dir,'rw_me','rwgt.pkl')): 488 time.sleep(10+i) 489 i+=5 490 print 'wait for pickle' 491 print "loading from pickle" 492 if not self.rwgt_dir: 493 self.rwgt_dir = self.me_dir 494 self.load_from_pickle(keep_name=True) 495 self.load_module() 496 else: 497 self.create_standalone_directory() 498 self.compile() 499 self.load_module() 500 if self.multicore == 'create': 501 self.load_module() 502 if not self.rwgt_dir: 503 self.rwgt_dir = self.me_dir 504 self.save_to_pickle() 505 506 # get the mode of reweighting #LO/NLO/NLO_tree/... 507 type_rwgt = self.get_weight_names() 508 # get iterator over param_card and the name associated to the current reweighting. 509 param_card_iterator, tag_name = self.handle_param_card(model_line, args, type_rwgt) 510 511 if self.rwgt_dir: 512 path_me =self.rwgt_dir 513 else: 514 path_me = self.me_dir 515 516 if self.second_model or self.second_process or self.dedicated_path: 517 rw_dir = pjoin(path_me, 'rw_me_second') 518 else: 519 rw_dir = pjoin(path_me, 'rw_me') 520 521 start = time.time() 522 # initialize the collector for the various re-weighting 523 cross, ratio, ratio_square,error = {},{},{}, {} 524 for name in type_rwgt + ['orig']: 525 cross[name], error[name] = 0.,0. 526 ratio[name],ratio_square[name] = 0., 0.# to compute the variance and associate error 527 528 if self.output_type == "default": 529 output = open( self.lhe_input.name +'rw', 'w') 530 #write the banner to the output file 531 self.banner.write(output, close_tag=False) 532 else: 533 output = {} 534 if tag_name.isdigit(): 535 name_tag= 'rwgt_%s' % tag_name 536 else: 537 name_tag = tag_name 538 base = os.path.dirname(self.lhe_input.name) 539 for rwgttype in type_rwgt: 540 output[(name_tag,rwgttype)] = lhe_parser.EventFile(pjoin(base,'rwgt_events%s_%s.lhe.gz' %(rwgttype,tag_name)), 'w') 541 #write the banner to the output file 542 self.banner.write(output[(name_tag,rwgttype)], close_tag=False) 543 544 if self.lhe_input.closed: 545 self.lhe_input = lhe_parser.EventFile(self.lhe_input.name) 546 547 self.lhe_input.seek(0) 548 for event_nb,event in enumerate(self.lhe_input): 549 #control logger 550 if (event_nb % max(int(10**int(math.log10(float(event_nb)+1))),10)==0): 551 running_time = misc.format_timer(time.time()-start) 552 logger.info('Event nb %s %s' % (event_nb, running_time)) 553 if (event_nb==10001): logger.info('reducing number of print status. Next status update in 10000 events') 554 if (event_nb==100001): logger.info('reducing number of print status. Next status update in 100000 events') 555 556 weight = self.calculate_weight(event) 557 if not isinstance(weight, dict): 558 weight = {'':weight} 559 560 for name in weight: 561 cross[name] += weight[name] 562 ratio[name] += weight[name]/event.wgt 563 ratio_square[name] += (weight[name]/event.wgt)**2 564 565 # ensure to have a consistent order of the weights. new one are put 566 # at the back, remove old position if already defines 567 for tag in type_rwgt: 568 try: 569 event.reweight_order.remove('%s%s' % (tag_name,tag)) 570 except ValueError: 571 continue 572 573 event.reweight_order += ['%s%s' % (tag_name,name) for name in type_rwgt] 574 if self.output_type == "default": 575 for name in weight: 576 if 'orig' in name: 577 continue 578 event.reweight_data['%s%s' % (tag_name,name)] = weight[name] 579 #write this event with weight 580 output.write(str(event)) 581 else: 582 for i,name in enumerate(weight): 583 if 'orig' in name: 584 continue 585 if weight[name] == 0: 586 continue 587 new_evt = lhe_parser.Event(str(event)) 588 new_evt.wgt = weight[name] 589 new_evt.parse_reweight() 590 new_evt.reweight_data = {} 591 output[(tag_name,name)].write(str(new_evt)) 592 593 # check normalisation of the events: 594 if 'event_norm' in self.run_card: 595 if self.run_card['event_norm'] in ['average','bias']: 596 for key, value in cross.items(): 597 cross[key] = value / (event_nb+1) 598 599 running_time = misc.format_timer(time.time()-start) 600 logger.info('All event done (nb_event: %s) %s' % (event_nb+1, running_time)) 601 602 603 if self.output_type == "default": 604 output.write('</LesHouchesEvents>\n') 605 output.close() 606 else: 607 for key in output: 608 output[key].write('</LesHouchesEvents>\n') 609 output[key].close() 610 if self.systematics and len(output) ==1: 611 try: 612 logger.info('running systematics computation') 613 import madgraph.various.systematics as syst 614 615 if not isinstance(self.systematics, bool): 616 args = [output[key].name, output[key].name] + self.systematics 617 else: 618 args = [output[key].name, output[key].name] 619 if self.mother and self.mother.options['lhapdf']: 620 args.append('--lhapdf_config=%s' % self.mother.options['lhapdf']) 621 syst.call_systematics(args, result=open('rwg_syst_%s.result' % key[0],'w'), 622 log=logger.info) 623 except Exception: 624 logger.error('fail to add systematics') 625 raise 626 # add output information 627 if self.mother and hasattr(self.mother, 'results'): 628 run_name = self.mother.run_name 629 results = self.mother.results 630 results.add_run(run_name, self.run_card, current=True) 631 results.add_detail('nb_event', event_nb+1) 632 name = type_rwgt[0] 633 results.add_detail('cross', cross[name]) 634 event_nb +=1 635 for name in type_rwgt: 636 variance = ratio_square[name]/event_nb - (ratio[name]/event_nb)**2 637 orig_cross, orig_error = self.orig_cross 638 error[name] = math.sqrt(max(0,variance/math.sqrt(event_nb))) * orig_cross + ratio[name]/event_nb * orig_error 639 results.add_detail('error', error[type_rwgt[0]]) 640 import madgraph.interface.madevent_interface as ME_interface 641 642 self.lhe_input.close() 643 if not self.mother: 644 name, ext = self.lhe_input.name.rsplit('.',1) 645 target = '%s_out.%s' % (name, ext) 646 elif self.output_type != "default" : 647 target = pjoin(self.mother.me_dir, 'Events', run_name, 'events.lhe') 648 else: 649 target = self.lhe_input.name 650 651 if self.output_type == "default": 652 files.mv(output.name, target) 653 logger.info('Event %s have now the additional weight' % self.lhe_input.name) 654 elif self.output_type == "unweight": 655 for key in output: 656 #output[key].write('</LesHouchesEvents>\n') 657 #output.close() 658 lhe = lhe_parser.EventFile(output[key].name) 659 nb_event = lhe.unweight(target) 660 if self.mother and hasattr(self.mother, 'results'): 661 results = self.mother.results 662 results.add_detail('nb_event', nb_event) 663 results.current.parton.append('lhe') 664 logger.info('Event %s is now unweighted under the new theory: %s(%s)' % (lhe.name, target, nb_event)) 665 else: 666 if self.mother and hasattr(self.mother, 'results'): 667 results = self.mother.results 668 results.current.parton.append('lhe') 669 logger.info('Eventfiles is/are now created with new central weight') 670 671 if self.multicore != 'create': 672 for name in cross: 673 if name == 'orig': 674 continue 675 logger.info('new cross-section is %s: %g pb (indicative error: %g pb)' %\ 676 ('(%s)' %name if name else '',cross[name], error[name])) 677 678 self.terminate_fortran_executables(new_card_only=True) 679 #store result 680 for name in cross: 681 if name == 'orig': 682 self.all_cross_section[name] = (cross[name], error[name]) 683 else: 684 self.all_cross_section[(tag_name,name)] = (cross[name], error[name]) 685 686 # perform the scanning 687 if param_card_iterator: 688 for i,card in enumerate(param_card_iterator): 689 if self.options['rwgt_name']: 690 self.options['rwgt_name'] = '%s_%s' % (self.options['rwgt_name'].rsplit('_',1)[0], i+1) 691 self.new_param_card = card 692 #card.write(pjoin(rw_dir, 'Cards', 'param_card.dat')) 693 self.exec_cmd("launch --keep_card", printcmd=False, precmd=True) 694 695 self.options['rwgt_name'] = None
696 697
698 - def handle_param_card(self, model_line, args, type_rwgt):
699 700 if self.rwgt_dir: 701 path_me =self.rwgt_dir 702 else: 703 path_me = self.me_dir 704 705 if self.second_model or self.second_process or self.dedicated_path: 706 rw_dir = pjoin(path_me, 'rw_me_second') 707 else: 708 rw_dir = pjoin(path_me, 'rw_me') 709 710 711 if not '--keep_card' in args: 712 if self.has_nlo and self.rwgt_mode != "LO": 713 rwdir_virt = rw_dir.replace('rw_me', 'rw_mevirt') 714 715 out, cmd = common_run_interface.CommonRunCmd.ask_edit_card_static(cards=['param_card.dat'], 716 ask=self.ask, pwd=rw_dir, first_cmd=self.stored_line, 717 write_file=False, return_instance=True 718 ) 719 self.stored_line = None 720 card = cmd.param_card 721 new_card = card.write() 722 elif self.new_param_card: 723 new_card = self.new_param_card.write() 724 else: 725 new_card = open(pjoin(rw_dir, 'Cards', 'param_card.dat')).read() 726 727 # check for potential scan in the new card 728 pattern_scan = re.compile(r'''^(decay)?[\s\d]*scan''', re.I+re.M) 729 param_card_iterator = [] 730 if pattern_scan.search(new_card): 731 try: 732 import internal.extended_cmd as extended_internal 733 Shell_internal = extended_internal.CmdShell 734 except: 735 Shell_internal = None 736 import madgraph.interface.extended_cmd as extended_cmd 737 if not isinstance(self.mother, (extended_cmd.CmdShell, Shell_internal)): 738 raise Exception, "scan are not allowed on the Web" 739 # at least one scan parameter found. create an iterator to go trough the cards 740 main_card = check_param_card.ParamCardIterator(new_card) 741 if self.options['rwgt_name']: 742 self.options['rwgt_name'] = '%s_0' % self.options['rwgt_name'] 743 744 param_card_iterator = main_card 745 first_card = param_card_iterator.next(autostart=True) 746 new_card = first_card.write() 747 self.new_param_card = first_card 748 #first_card.write(pjoin(rw_dir, 'Cards', 'param_card.dat')) 749 750 # check if "Auto" is present for a width parameter) 751 tmp_card = new_card.lower().split('block',1)[1] 752 if "auto" in tmp_card: 753 if param_card_iterator: 754 first_card.write(pjoin(rw_dir, 'Cards', 'param_card.dat')) 755 else: 756 ff = open(pjoin(rw_dir, 'Cards', 'param_card.dat'),'w') 757 ff.write(new_card) 758 ff.close() 759 760 self.mother.check_param_card(pjoin(rw_dir, 'Cards', 'param_card.dat')) 761 new_card = open(pjoin(rw_dir, 'Cards', 'param_card.dat')).read() 762 763 764 # Find new tag in the banner and add information if needed 765 if 'initrwgt' in self.banner and self.output_type == 'default': 766 if 'name=\'mg_reweighting\'' in self.banner['initrwgt']: 767 blockpat = re.compile(r'''<weightgroup name=\'mg_reweighting\'\s*weight_name_strategy=\'includeIdInWeightName\'>(?P<text>.*?)</weightgroup>''', re.I+re.M+re.S) 768 before, content, after = blockpat.split(self.banner['initrwgt']) 769 header_rwgt_other = before + after 770 pattern = re.compile('<weight id=\'(?:rwgt_(?P<id>\d+)|(?P<id2>[_\w]+))(?P<rwgttype>\s*|_\w+)\'>(?P<info>.*?)</weight>', re.S+re.I+re.M) 771 mg_rwgt_info = pattern.findall(content) 772 773 maxid = 0 774 for k,(i, fulltag, nlotype, diff) in enumerate(mg_rwgt_info): 775 if i: 776 if int(i) > maxid: 777 maxid = int(i) 778 mg_rwgt_info[k] = (i, nlotype, diff) # remove the pointless fulltag tag 779 else: 780 mg_rwgt_info[k] = (fulltag, nlotype, diff) # remove the pointless id tag 781 782 maxid += 1 783 rewgtid = maxid 784 if self.options['rwgt_name']: 785 #ensure that the entry is not already define if so overwrites it 786 for (i, nlotype, diff) in mg_rwgt_info[:]: 787 for flag in type_rwgt: 788 if 'rwgt_%s' % i == '%s%s' %(self.options['rwgt_name'],flag) or \ 789 i == '%s%s' % (self.options['rwgt_name'], flag): 790 logger.warning("tag %s%s already defines, will replace it", self.options['rwgt_name'],flag) 791 mg_rwgt_info.remove((i, nlotype, diff)) 792 793 else: 794 header_rwgt_other = self.banner['initrwgt'] 795 mg_rwgt_info = [] 796 rewgtid = 1 797 else: 798 self.banner['initrwgt'] = '' 799 header_rwgt_other = '' 800 mg_rwgt_info = [] 801 rewgtid = 1 802 803 # add the reweighting in the banner information: 804 #starts by computing the difference in the cards. 805 s_orig = self.banner['slha'] 806 self.orig_param_card_text = s_orig 807 s_new = new_card 808 self.new_param_card = check_param_card.ParamCard(s_new.splitlines()) 809 810 #define tag for the run 811 if self.options['rwgt_name']: 812 tag = self.options['rwgt_name'] 813 else: 814 tag = str(rewgtid) 815 816 if 'rwgt_info' in self.options and self.options['rwgt_info']: 817 card_diff = self.options['rwgt_info'] 818 for name in type_rwgt: 819 mg_rwgt_info.append((tag, name, self.options['rwgt_info'])) 820 elif not self.second_model and not self.dedicated_path: 821 old_param = check_param_card.ParamCard(s_orig.splitlines()) 822 new_param = self.new_param_card 823 card_diff = old_param.create_diff(new_param) 824 if card_diff == '' and not self.second_process: 825 logger.warning(' REWEIGHTING: original card and new card are identical.') 826 try: 827 if old_param['sminputs'].get(3)- new_param['sminputs'].get(3) > 1e-3 * new_param['sminputs'].get(3): 828 logger.warning("We found different value of alpha_s. Note that the value of alpha_s used is the one associate with the event and not the one from the cards.") 829 except Exception, error: 830 logger.debug("error in check of alphas: %s" % str(error)) 831 pass #this is a security 832 if not self.second_process: 833 for name in type_rwgt: 834 mg_rwgt_info.append((tag, name, card_diff)) 835 else: 836 str_proc = "\n change process ".join([""]+self.second_process) 837 for name in type_rwgt: 838 mg_rwgt_info.append((tag, name, str_proc + '\n'+ card_diff)) 839 else: 840 if self.second_model: 841 str_info = "change model %s" % self.second_model 842 else: 843 str_info ='' 844 if self.second_process: 845 str_info += "\n change process ".join([""]+self.second_process) 846 if self.dedicated_path: 847 for k,v in self.dedicated_path.items(): 848 str_info += "\n change %s %s" % (k,v) 849 card_diff = str_info 850 str_info += '\n' + s_new 851 for name in type_rwgt: 852 mg_rwgt_info.append((tag, name, str_info)) 853 # re-create the banner. 854 self.banner['initrwgt'] = header_rwgt_other 855 if self.output_type == 'default': 856 self.banner['initrwgt'] += '\n<weightgroup name=\'mg_reweighting\' weight_name_strategy=\'includeIdInWeightName\'>\n' 857 else: 858 self.banner['initrwgt'] += '\n<weightgroup name=\'main\'>\n' 859 for tag, rwgttype, diff in mg_rwgt_info: 860 if tag.isdigit(): 861 self.banner['initrwgt'] += '<weight id=\'rwgt_%s%s\'>%s</weight>\n' % \ 862 (tag, rwgttype, diff) 863 else: 864 self.banner['initrwgt'] += '<weight id=\'%s%s\'>%s</weight>\n' % \ 865 (tag, rwgttype, diff) 866 self.banner['initrwgt'] += '\n</weightgroup>\n' 867 self.banner['initrwgt'] = self.banner['initrwgt'].replace('\n\n', '\n') 868 869 logger.info('starts to compute weight for events with the following modification to the param_card:') 870 logger.info(card_diff.replace('\n','\nKEEP:')) 871 self.run_card = banner.Banner(self.banner).charge_card('run_card') 872 873 if self.options['rwgt_name']: 874 tag_name = self.options['rwgt_name'] 875 else: 876 tag_name = 'rwgt_%s' % rewgtid 877 878 879 #initialise module. 880 for (path,tag), module in self.f2pylib.items(): 881 with misc.chdir(pjoin(os.path.dirname(rw_dir), path)): 882 with misc.stdchannel_redirected(sys.stdout, os.devnull): 883 if 'second' in path or tag == 3: 884 param_card = self.new_param_card 885 else: 886 param_card = check_param_card.ParamCard(self.orig_param_card_text) 887 888 for block in param_card: 889 890 for param in param_card[block]: 891 lhacode = param.lhacode 892 value = param.value 893 name = '%s_%s' % (block.upper(), '_'.join([str(i) for i in lhacode])) 894 module.change_para(name, value) 895 module.update_all_coup() 896 897 return param_card_iterator, tag_name
898 899
900 - def do_set(self, line):
901 "Not in help" 902 903 logger.warning("Invalid Syntax. The command 'set' should be placed after the 'launch' one. Continuing by adding automatically 'launch'") 904 self.stored_line = "set %s" % line 905 return self.exec_cmd("launch")
906
907 - def default(self, line, log=True):
908 """Default action if line is not recognized""" 909 910 if os.path.isfile(line): 911 if log: 912 logger.warning("Invalid Syntax. The path to a param_card' should be placed after the 'launch' command. Continuing by adding automatically 'launch'") 913 self.stored_line = line 914 return self.exec_cmd("launch") 915 else: 916 return super(ReweightInterface,self).default(line, log=log)
917
918 - def write_reweighted_event(self, event, tag_name, **opt):
919 """a function for running in multicore""" 920 921 if not hasattr(opt['thread_space'], "calculator"): 922 opt['thread_space'].calculator = {} 923 opt['thread_space'].calculator_nbcall = {} 924 opt['thread_space'].cross = 0 925 opt['thread_space'].output = open( self.lhe_input.name +'rw.%s' % opt['thread_id'], 'w') 926 if self.mother: 927 out_path = pjoin(self.mother.me_dir, 'Events', 'reweight.lhe.%s' % opt['thread_id']) 928 opt['thread_space'].output2 = open(out_path, 'w') 929 930 weight = self.calculate_weight(event, space=opt['thread_space']) 931 opt['thread_space'].cross += weight 932 if self.output_type == "default": 933 event.reweight_data[tag_name] = weight 934 #write this event with weight 935 opt['thread_space'].output.write(str(event)) 936 if self.mother: 937 event.wgt = weight 938 event.reweight_data = {} 939 opt['thread_space'].output2.write(str(event)) 940 else: 941 event.wgt = weight 942 event.reweight_data = {} 943 if self.mother: 944 opt['thread_space'].output2.write(str(event)) 945 else: 946 opt['thread_space'].output.write(str(event)) 947 948 return 0
949
950 - def do_compute_widths(self, line):
951 return self.mother.do_compute_widths(line)
952 953 954 dynamical_scale_warning=True
955 - def change_kinematics(self, event):
956 957 958 if isinstance(self.run_card, banner.RunCardLO): 959 jac = event.change_ext_mass(self.new_param_card) 960 new_event = event 961 else: 962 jac =1 963 new_event = event 964 965 if jac != 1: 966 if self.output_type == 'default': 967 logger.critical('mass reweighting requires dedicated lhe output!. Please include "change output 2.0" in your reweight_card') 968 raise Exception 969 mode = self.run_card['dynamical_scale_choice'] 970 if mode == -1: 971 if self.dynamical_scale_warning: 972 logger.warning('dynamical_scale is set to -1. New sample will be with HT/2 dynamical scale for renormalisation scale') 973 mode = 3 974 new_event.scale = event.get_scale(mode) 975 new_event.aqcd = self.lhe_input.get_alphas(new_event.scale, lhapdf_config=self.mother.options['lhapdf']) 976 977 return jac, new_event
978 979
980 - def calculate_weight(self, event):
981 """space defines where to find the calculator (in multicore)""" 982 983 if not hasattr(self,'pdf'): 984 lhapdf = misc.import_python_lhapdf(self.mg5cmd.options['lhapdf']) 985 self.pdf = lhapdf.mkPDF(self.banner.run_card.get_lhapdf_id()) 986 987 if self.has_nlo and self.rwgt_mode != "LO": 988 return self.calculate_nlo_weight(event) 989 990 event.parse_reweight() 991 orig_wgt = event.wgt 992 # LO reweighting 993 w_orig = self.calculate_matrix_element(event, 0) 994 995 # reshuffle event for mass effect # external mass only 996 # carefull that new_event can sometimes be = to event 997 # (i.e. change can be in place) 998 jac, new_event = self.change_kinematics(event) 999 1000 1001 if event.wgt != 0: # impossible reshuffling 1002 w_new = self.calculate_matrix_element(new_event, 1) 1003 else: 1004 w_new = 0 1005 1006 if w_orig == 0: 1007 tag, order = event.get_tag_and_order() 1008 orig_order, Pdir, hel_dict = self.id_to_path[tag] 1009 misc.sprint(w_orig, w_new) 1010 misc.sprint(event) 1011 misc.sprint(self.invert_momenta(event.get_momenta(orig_order))) 1012 misc.sprint(event.get_momenta(orig_order)) 1013 misc.sprint(event.aqcd) 1014 hel_order = event.get_helicity(orig_order) 1015 if self.helicity_reweighting and 9 not in hel_order: 1016 nhel = hel_dict[tuple(hel_order)] 1017 else: 1018 nhel = 0 1019 misc.sprint(nhel, Pdir, hel_dict) 1020 raise Exception, "Invalid matrix element for original computation (weight=0)" 1021 1022 return {'orig': orig_wgt, '': w_new/w_orig*orig_wgt*jac}
1023
1024 - def calculate_nlo_weight(self, event):
1025 1026 1027 type_nlo = self.get_weight_names() 1028 final_weight = {'orig': event.wgt} 1029 1030 event.parse_reweight() 1031 event.parse_nlo_weight(threshold=self.soft_threshold) 1032 if self.output_type != 'default': 1033 event.nloweight.modified = True # the internal info will be changed 1034 # so set this flage to True to change 1035 # the writting of those data 1036 1037 #initialise the input to the function which recompute the weight 1038 scales2 = [] 1039 pdg = [] 1040 bjx = [] 1041 wgt_tree = [] # reweight for loop-improved type 1042 wgt_virt = [] #reweight b+v together 1043 base_wgt = [] 1044 gs=[] 1045 qcdpower = [] 1046 ref_wgts = [] #for debugging 1047 1048 orig_wgt = 0 1049 for cevent in event.nloweight.cevents: 1050 #check if we need to compute the virtual for that cevent 1051 need_V = False # the real is nothing else than the born for a N+1 config 1052 all_ctype = [w.type for w in cevent.wgts] 1053 if '_nlo' in type_nlo and any(c in all_ctype for c in [2,14,15]): 1054 need_V =True 1055 1056 w_orig = self.calculate_matrix_element(cevent, 0) 1057 w_new = self.calculate_matrix_element(cevent, 1) 1058 ratio_T = w_new/w_orig 1059 if need_V: 1060 scale2 = cevent.wgts[0].scales2[0] 1061 #for scale2 in set(c.scales2[1] for c in cevent.wgts): 1062 w_origV = self.calculate_matrix_element(cevent, 'V0', scale2=scale2) 1063 w_newV = self.calculate_matrix_element(cevent, 'V1', scale2=scale2) 1064 ratio_BV = (w_newV + w_new) / (w_origV + w_orig) 1065 ratio_V = w_newV/w_origV 1066 else: 1067 ratio_V = "should not be used" 1068 ratio_BV = "should not be used" 1069 for c_wgt in cevent.wgts: 1070 orig_wgt += c_wgt.ref_wgt 1071 #add the information to the input 1072 scales2.append(c_wgt.scales2) 1073 pdg.append(c_wgt.pdgs[:2]) 1074 1075 bjx.append(c_wgt.bjks) 1076 qcdpower.append(c_wgt.qcdpower) 1077 gs.append(c_wgt.gs) 1078 ref_wgts.append(c_wgt.ref_wgt) 1079 1080 if '_nlo' in type_nlo: 1081 if c_wgt.type in [2,14,15]: 1082 R = ratio_BV 1083 else: 1084 R = ratio_T 1085 1086 new_wgt = [c_wgt.pwgt[0] * R, 1087 c_wgt.pwgt[1] * ratio_T, 1088 c_wgt.pwgt[2] * ratio_T] 1089 wgt_virt.append(new_wgt) 1090 1091 if '_tree' in type_nlo: 1092 new_wgt = [c_wgt.pwgt[0] * ratio_T, 1093 c_wgt.pwgt[1] * ratio_T, 1094 c_wgt.pwgt[2] * ratio_T] 1095 wgt_tree.append(new_wgt) 1096 1097 base_wgt.append(c_wgt.pwgt[:3]) 1098 1099 1100 orig_wgt_check, partial_check = self.combine_wgt_local(scales2, pdg, bjx, base_wgt, gs, qcdpower, self.pdf) 1101 #change the ordering to the fortran one: 1102 #scales2_i = self.invert_momenta(scales2) 1103 #pdg_i = self.invert_momenta(pdg) 1104 #bjx_i = self.invert_momenta(bjx) 1105 # re-compute original weight to reduce numerical inacurracy 1106 #base_wgt_i = self.invert_momenta(base_wgt) 1107 #orig_wgt_check, partial_check = self.combine_wgt(scales2_i, pdg_i, bjx_i, base_wgt_i, gs, qcdpower, 1., 1.) 1108 1109 if '_nlo' in type_nlo: 1110 #wgt = self.invert_momenta(wgt_virt) 1111 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1112 new_out, partial = self.combine_wgt_local(scales2, pdg, bjx, wgt_virt, gs, qcdpower, self.pdf) 1113 # try to correct for precision issue 1114 avg = [partial_check[i]/ref_wgts[i] for i in range(len(ref_wgts))] 1115 out = sum(partial[i]/avg[i] if 0.85<avg[i]<1.15 else 0 \ 1116 for i in range(len(avg))) 1117 final_weight['_nlo'] = out/orig_wgt*event.wgt 1118 1119 1120 if '_tree' in type_nlo: 1121 #wgt = self.invert_momenta(wgt_tree) 1122 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1123 out, partial = self.combine_wgt_local(scales2, pdg, bjx, wgt_tree, gs, qcdpower, self.pdf) 1124 # try to correct for precision issue 1125 avg = [partial_check[i]/ref_wgts[i] for i in range(len(ref_wgts))] 1126 new_out = sum(partial[i]/avg[i] if 0.85<avg[i]<1.15 else partial[i] \ 1127 for i in range(len(avg))) 1128 final_weight['_tree'] = new_out/orig_wgt*event.wgt 1129 1130 1131 if '_lo' in type_nlo: 1132 w_orig = self.calculate_matrix_element(event, 0) 1133 w_new = self.calculate_matrix_element(event, 1) 1134 final_weight['_lo'] = w_new/w_orig*event.wgt 1135 1136 1137 if self.output_type != 'default' and len(type_nlo)==1 and '_lo' not in type_nlo: 1138 to_write = [partial[i]/ref_wgts[i]*partial_check[i] 1139 if 0.85<avg[i]<1.15 else 0 1140 for i in range(len(ref_wgts))] 1141 for cevent in event.nloweight.cevents: 1142 for c_wgt in cevent.wgts: 1143 c_wgt.ref_wgt = to_write.pop(0) 1144 if '_tree' in type_nlo: 1145 c_wgt.pwgt = wgt_tree.pop(0) 1146 else: 1147 c_wgt.pwgt = wgt_virt.pop(0) 1148 assert not to_write 1149 assert not wgt_tree 1150 return final_weight
1151 1152
1153 - def combine_wgt_local(self, scale2s, pdgs, bjxs, base_wgts, gss, qcdpowers, pdf):
1154 1155 wgt = 0. 1156 wgts = [] 1157 for (scale2, pdg, bjx, base_wgt, gs, qcdpower) in zip(scale2s, pdgs, bjxs, base_wgts, gss, qcdpowers): 1158 Q2, mur2, muf2 = scale2 #Q2 is Ellis-Sexton scale 1159 #misc.sprint(Q2, mur2, muf2, base_wgt, gs, qcdpower) 1160 pdf1 = pdf.xfxQ2(pdg[0], bjx[0], muf2)/bjx[0] 1161 pdf2 = pdf.xfxQ2(pdg[1], bjx[1], muf2)/bjx[1] 1162 alphas = pdf.alphasQ2(mur2) 1163 tmp = base_wgt[0] + base_wgt[1] * math.log(mur2/Q2) + base_wgt[2] * math.log(muf2/Q2) 1164 tmp *= gs**qcdpower*pdf1*pdf2 1165 wgt += tmp 1166 wgts.append(tmp) 1167 return wgt, wgts
1168 1169 1170 1171 @staticmethod
1172 - def invert_momenta(p):
1173 """ fortran/C-python do not order table in the same order""" 1174 new_p = [] 1175 for i in range(len(p[0])): new_p.append([0]*len(p)) 1176 for i, onep in enumerate(p): 1177 for j, x in enumerate(onep): 1178 new_p[j][i] = x 1179 return new_p
1180 1181 @staticmethod
1182 - def rename_f2py_lib(Pdir, tag):
1183 if tag == 2: 1184 return 1185 if os.path.exists(pjoin(Pdir, 'matrix%spy.so' % tag)): 1186 return 1187 else: 1188 open(pjoin(Pdir, 'matrix%spy.so' % tag),'w').write(open(pjoin(Pdir, 'matrix2py.so') 1189 ).read().replace('matrix2py', 'matrix%spy' % tag))
1190
1191 - def calculate_matrix_element(self, event, hypp_id, scale2=0):
1192 """routine to return the matrix element""" 1193 1194 if self.has_nlo: 1195 nb_retry, sleep = 10, 60 1196 else: 1197 nb_retry, sleep = 5, 20 1198 1199 tag, order = event.get_tag_and_order() 1200 if self.keep_ordering: 1201 old_tag = tuple(tag) 1202 tag = (tag[0], tuple(order[1])) 1203 if isinstance(hypp_id, str) and hypp_id.startswith('V'): 1204 tag = (tag,'V') 1205 hypp_id = int(hypp_id[1:]) 1206 # base = "rw_mevirt" 1207 #else: 1208 # base = "rw_me" 1209 1210 if (not self.second_model and not self.second_process and not self.dedicated_path) or hypp_id==0: 1211 orig_order, Pdir, hel_dict = self.id_to_path[tag] 1212 else: 1213 try: 1214 orig_order, Pdir, hel_dict = self.id_to_path_second[tag] 1215 except KeyError: 1216 if self.options['allow_missing_finalstate']: 1217 return 0.0 1218 else: 1219 logger.critical('The following initial/final state %s can not be found in the new model/process. If you want to set the weights of such events to zero use "change allow_missing_finalstate False"', tag) 1220 raise Exception 1221 1222 base = os.path.basename(os.path.dirname(Pdir)) 1223 if '_second' in base: 1224 moduletag = (base, 2) 1225 else: 1226 moduletag = (base, 2+hypp_id) 1227 1228 module = self.f2pylib[moduletag] 1229 1230 p = event.get_momenta(orig_order) 1231 # add helicity information 1232 1233 hel_order = event.get_helicity(orig_order) 1234 if self.helicity_reweighting and 9 not in hel_order: 1235 nhel = hel_dict[tuple(hel_order)] 1236 else: 1237 nhel = -1 1238 1239 # For 2>N pass in the center of mass frame 1240 # - required for helicity by helicity re-weighitng 1241 # - Speed-up loop computation 1242 if (hypp_id == 0 and ('frame_id' in self.banner.run_card and self.banner.run_card['frame_id'] !=6)): 1243 import copy 1244 new_event = copy.deepcopy(event) 1245 pboost = FourMomenta() 1246 to_inc = bin(self.banner.run_card['frame_id'])[2:] 1247 to_inc.reverse() 1248 nb_ext = 0 1249 for p in new_event: 1250 if p.status in [-1,1]: 1251 nb_ext += 1 1252 if to_inc[nb_ext]: 1253 pboost += p 1254 new_event.boost(pboost) 1255 p = new_event.get_momenta(orig_order) 1256 elif (hypp_id == 1 and self.boost_event): 1257 if self.boost_event is not True: 1258 import copy 1259 new_event = copy.deepcopy(event) 1260 new_event.boost(self.boost_event) 1261 p = new_event.get_momenta(orig_order) 1262 elif (hasattr(event[1], 'status') and event[1].status == -1) or \ 1263 (event[1].px == event[1].py == 0.): 1264 pboost = lhe_parser.FourMomentum(p[0]) + lhe_parser.FourMomentum(p[1]) 1265 for i,thisp in enumerate(p): 1266 p[i] = lhe_parser.FourMomentum(thisp).zboost(pboost).get_tuple() 1267 assert p[0][1] == p[0][2] == 0 == p[1][2] == p[1][2] == 0 1268 1269 pold = list(p) 1270 p = self.invert_momenta(p) 1271 pdg = list(orig_order[0])+list(orig_order[1]) 1272 1273 with misc.chdir(Pdir): 1274 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1275 me_value = module.smatrixhel(pdg,p, event.aqcd, scale2, nhel) 1276 1277 # for loop we have also the stability status code 1278 if isinstance(me_value, tuple): 1279 me_value, code = me_value 1280 #if code points unstability -> returns 0 1281 hundred_value = (code % 1000) //100 1282 if hundred_value in [4]: 1283 me_value = 0. 1284 1285 return me_value
1286
1287 - def terminate_fortran_executables(self, new_card_only=False):
1288 """routine to terminate all fortran executables""" 1289 1290 for (mode, production) in dict(self.calculator): 1291 1292 if new_card_only and production == 0: 1293 continue 1294 del self.calculator[(mode, production)]
1295
1296 - def do_quit(self, line):
1297 if self.exitted: 1298 return 1299 self.exitted = True 1300 1301 if 'init' in self.banner: 1302 cross = 0 1303 error = 0 1304 for line in self.banner['init'].split('\n'): 1305 split = line.split() 1306 if len(split) == 4: 1307 cross, error = float(split[0]), float(split[1]) 1308 1309 if not self.multicore == 'create': 1310 # No print of results for the multicore mode for the one printed on screen 1311 if 'orig' not in self.all_cross_section: 1312 logger.info('Original cross-section: %s +- %s pb' % (cross, error)) 1313 else: 1314 logger.info('Original cross-section: %s +- %s pb (cross-section from sum of weights: %s)' % (cross, error, self.all_cross_section['orig'][0])) 1315 logger.info('Computed cross-section:') 1316 keys = self.all_cross_section.keys() 1317 keys.sort() 1318 for key in keys: 1319 if key == 'orig': 1320 continue 1321 logger.info('%s : %s +- %s pb' % (key[0] if not key[1] else '%s%s' % key, 1322 self.all_cross_section[key][0],self.all_cross_section[key][1] )) 1323 self.terminate_fortran_executables() 1324 1325 if self.rwgt_dir and self.multicore == False: 1326 self.save_to_pickle() 1327 1328 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1329 for run_id in self.calculator: 1330 del self.calculator[run_id] 1331 del self.calculator
1332 1333
1334 - def __del__(self):
1335 self.do_quit('')
1336 1337
1338 - def adding_me(self, matrix_elements, path):
1339 """Adding one element to the list based on the matrix element"""
1340 1341 1342 @misc.mute_logger()
1343 - def create_standalone_tree_directory(self, data ,second=False):
1344 """generate the various directory for the weight evaluation""" 1345 1346 mgcmd = self.mg5cmd 1347 path_me = data['path'] 1348 # 2. compute the production matrix element ----------------------------- 1349 has_nlo = False 1350 mgcmd.exec_cmd("set group_subprocesses False") 1351 1352 if not second: 1353 logger.info('generating the square matrix element for reweighting') 1354 else: 1355 logger.info('generating the square matrix element for reweighting (second model and/or processes)') 1356 start = time.time() 1357 commandline='' 1358 for i,proc in enumerate(data['processes']): 1359 if '[' not in proc: 1360 commandline += "add process %s ;" % proc 1361 else: 1362 has_nlo = True 1363 if self.banner.get('run_card','ickkw') == 3: 1364 if len(proc) == min([len(p.strip()) for p in data['processes']]): 1365 commandline += self.get_LO_definition_from_NLO(proc, self.model) 1366 else: 1367 commandline += self.get_LO_definition_from_NLO(proc, 1368 self.model, real_only=True) 1369 else: 1370 commandline += self.get_LO_definition_from_NLO(proc, self.model) 1371 1372 commandline = commandline.replace('add process', 'generate',1) 1373 logger.info(commandline) 1374 try: 1375 mgcmd.exec_cmd(commandline, precmd=True, errorhandling=False) 1376 except diagram_generation.NoDiagramException: 1377 commandline='' 1378 for proc in data['processes']: 1379 if '[' not in proc: 1380 raise 1381 # pass to virtsq= 1382 base, post = proc.split('[',1) 1383 nlo_order, post = post.split(']',1) 1384 if '=' not in nlo_order: 1385 nlo_order = 'virt=%s' % nlo_order 1386 elif 'noborn' in nlo_order: 1387 nlo_order = nlo_order.replace('noborn', 'virt') 1388 commandline += "add process %s [%s] %s;" % (base,nlo_order,post) 1389 commandline = commandline.replace('add process', 'generate',1) 1390 logger.info("RETRY with %s", commandline) 1391 mgcmd.exec_cmd(commandline, precmd=True) 1392 has_nlo = False 1393 except Exception, error: 1394 raise 1395 1396 commandline = 'output standalone_rw %s --prefix=int' % pjoin(path_me,data['paths'][0]) 1397 mgcmd.exec_cmd(commandline, precmd=True) 1398 logger.info('Done %.4g' % (time.time()-start)) 1399 self.has_standalone_dir = True 1400 1401 1402 # 3. Store id to directory information --------------------------------- 1403 if False: 1404 # keep this for debugging 1405 matrix_elements = mgcmd._curr_matrix_elements.get_matrix_elements() 1406 1407 to_check = [] # list of tag that do not have a Pdir at creation time. 1408 for me in matrix_elements: 1409 for proc in me.get('processes'): 1410 initial = [] #filled in the next line 1411 final = [l.get('id') for l in proc.get('legs')\ 1412 if l.get('state') or initial.append(l.get('id'))] 1413 order = (initial, final) 1414 tag = proc.get_initial_final_ids() 1415 decay_finals = proc.get_final_ids_after_decay() 1416 1417 if tag[1] != decay_finals: 1418 order = (initial, list(decay_finals)) 1419 decay_finals.sort() 1420 tag = (tag[0], tuple(decay_finals)) 1421 Pdir = pjoin(path_me, data['paths'][0], 'SubProcesses', 1422 'P%s' % me.get('processes')[0].shell_string()) 1423 1424 if not os.path.exists(Pdir): 1425 to_check.append(tag) 1426 continue 1427 if tag in data['id2path']: 1428 if not Pdir == data['id2path'][tag][1]: 1429 misc.sprint(tag, Pdir, data['id2path'][tag][1]) 1430 raise self.InvalidCmd, '2 different process have the same final states. This module can not handle such situation' 1431 else: 1432 continue 1433 # build the helicity dictionary 1434 hel_nb = 0 1435 hel_dict = {9:0} # unknown helicity -> use full ME 1436 for helicities in me.get_helicity_matrix(): 1437 hel_nb +=1 #fortran starts at 1 1438 hel_dict[tuple(helicities)] = hel_nb 1439 1440 data['id2path'][tag] = [order, Pdir, hel_dict] 1441 1442 for tag in to_check: 1443 if tag not in self.id_to_path: 1444 logger.warning("no valid path for %s" % (tag,)) 1445 #raise self.InvalidCmd, "no valid path for %s" % (tag,) 1446 1447 # 4. Check MadLoopParam for Loop induced 1448 if os.path.exists(pjoin(path_me, data['paths'][0], 'Cards', 'MadLoopParams.dat')): 1449 MLCard = banner.MadLoopParam(pjoin(path_me, data['paths'][0], 'Cards', 'MadLoopParams.dat')) 1450 MLCard.set('WriteOutFilters', False) 1451 MLCard.set('UseLoopFilter', False) 1452 MLCard.set("DoubleCheckHelicityFilter", False) 1453 MLCard.set("HelicityFilterLevel", 0) 1454 MLCard.write(pjoin(path_me, data['paths'][0], 'SubProcesses', 'MadLoopParams.dat'), 1455 pjoin(path_me, data['paths'][0], 'Cards', 'MadLoopParams.dat'), 1456 commentdefault=False) 1457 1458 #if self.multicore == 'create': 1459 # print "compile OLP", data['paths'][0] 1460 # misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][0],'SubProcesses'), 1461 # nb_core=self.mother.options['nb_core']) 1462 1463 if os.path.exists(pjoin(path_me, data['paths'][1], 'Cards', 'MadLoopParams.dat')): 1464 if self.multicore == 'create': 1465 print "compile OLP", data['paths'][1] 1466 # It is potentially unsafe to use several cores, We limit ourself to one for now 1467 # n_cores = self.mother.options['nb_core'] 1468 n_cores = 1 1469 misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][1],'SubProcesses'), 1470 nb_core=self.mother.options['nb_core']) 1471 1472 return has_nlo
1473 1474 1475 @misc.mute_logger()
1476 - def create_standalone_virt_directory(self, data ,second=False):
1477 """generate the various directory for the weight evaluation""" 1478 1479 mgcmd = self.mg5cmd 1480 path_me = data['path'] 1481 # Do not pass here for LO/NLO_tree 1482 start = time.time() 1483 commandline='' 1484 for proc in data['processes']: 1485 if '[' not in proc: 1486 pass 1487 else: 1488 proc = proc.replace('[', '[ virt=') 1489 commandline += "add process %s ;" % proc 1490 commandline = re.sub('@\s*\d+', '', commandline) 1491 # deactivate golem since it creates troubles 1492 old_options = dict(mgcmd.options) 1493 if mgcmd.options['golem']: 1494 logger.info(" When doing NLO reweighting, MG5aMC cannot use the loop reduction algorithms Golem") 1495 mgcmd.options['golem'] = None 1496 commandline = commandline.replace('add process', 'generate',1) 1497 logger.info(commandline) 1498 mgcmd.exec_cmd(commandline, precmd=True) 1499 commandline = 'output standalone_rw %s --prefix=int -f' % pjoin(path_me, data['paths'][1]) 1500 mgcmd.exec_cmd(commandline, precmd=True) 1501 1502 #put back golem to original value 1503 mgcmd.options['golem'] = old_options['golem'] 1504 # update make_opts 1505 if not mgcmd.options['lhapdf']: 1506 raise Exception, "NLO reweighting requires LHAPDF to work correctly" 1507 1508 1509 1510 # Download LHAPDF SET 1511 common_run_interface.CommonRunCmd.install_lhapdf_pdfset_static(\ 1512 mgcmd.options['lhapdf'], None, self.banner.run_card.get_lhapdf_id()) 1513 1514 # now store the id information 1515 if False: 1516 # keep it for debugging purposes 1517 matrix_elements = mgcmd._curr_matrix_elements.get_matrix_elements() 1518 for me in matrix_elements: 1519 for proc in me.get('processes'): 1520 initial = [] #filled in the next line 1521 final = [l.get('id') for l in proc.get('legs')\ 1522 if l.get('state') or initial.append(l.get('id'))] 1523 order = (initial, final) 1524 tag = proc.get_initial_final_ids() 1525 decay_finals = proc.get_final_ids_after_decay() 1526 1527 if tag[1] != decay_finals: 1528 order = (initial, list(decay_finals)) 1529 decay_finals.sort() 1530 tag = (tag[0], tuple(decay_finals)) 1531 Pdir = pjoin(path_me, data['paths'][1], 'SubProcesses', 1532 'P%s' % me.get('processes')[0].shell_string()) 1533 assert os.path.exists(Pdir), "Pdir %s do not exists" % Pdir 1534 if (tag,'V') in data['id2path']: 1535 if not Pdir == data['id2path'][(tag,'V')][1]: 1536 misc.sprint(tag, Pdir, self.id_to_path[(tag,'V')][1]) 1537 raise self.InvalidCmd, '2 different process have the same final states. This module can not handle such situation' 1538 else: 1539 continue 1540 # build the helicity dictionary 1541 hel_nb = 0 1542 hel_dict = {9:0} # unknown helicity -> use full ME 1543 for helicities in me.get_helicity_matrix(): 1544 hel_nb +=1 #fortran starts at 1 1545 hel_dict[tuple(helicities)] = hel_nb 1546 1547 data['id2path'][(tag,'V')] = [order, Pdir, hel_dict]
1548 1549 1550 @misc.mute_logger()
1551 - def create_standalone_directory(self, second=False):
1552 """generate the various directory for the weight evaluation""" 1553 1554 data={} 1555 if not second: 1556 data['paths'] = ['rw_me', 'rw_mevirt'] 1557 # model 1558 info = self.banner.get('proc_card', 'full_model_line') 1559 if '-modelname' in info: 1560 data['mg_names'] = False 1561 else: 1562 data['mg_names'] = True 1563 data['model_name'] = self.banner.get('proc_card', 'model') 1564 #processes 1565 data['processes'] = [line[9:].strip() for line in self.banner.proc_card 1566 if line.startswith('generate')] 1567 data['processes'] += [' '.join(line.split()[2:]) for line in self.banner.proc_card 1568 if re.search('^\s*add\s+process', line)] 1569 #object_collector 1570 #self.id_to_path = {} 1571 #data['id2path'] = self.id_to_path 1572 else: 1573 data['paths'] = ['rw_me_second', 'rw_mevirt_second'] 1574 # model 1575 if self.second_model: 1576 data['mg_names'] = True 1577 if ' ' in self.second_model: 1578 args = self.second_model.split() 1579 if '--modelname' in args: 1580 data['mg_names'] = False 1581 data['model_name'] = args[0] 1582 else: 1583 data['model_name'] = self.second_model 1584 else: 1585 data['model_name'] = None 1586 #processes 1587 if self.second_process: 1588 data['processes'] = self.second_process 1589 else: 1590 data['processes'] = [line[9:].strip() for line in self.banner.proc_card 1591 if line.startswith('generate')] 1592 data['processes'] += [' '.join(line.split()[2:]) 1593 for line in self.banner.proc_card 1594 if re.search('^\s*add\s+process', line)] 1595 #object_collector 1596 #self.id_to_path_second = {} 1597 #data['id2path'] = self.id_to_path_second 1598 1599 # 0. clean previous run ------------------------------------------------ 1600 if not self.rwgt_dir: 1601 path_me = self.me_dir 1602 else: 1603 path_me = self.rwgt_dir 1604 data['path'] = path_me 1605 try: 1606 shutil.rmtree(pjoin(path_me,data['paths'][0])) 1607 except Exception: 1608 pass 1609 try: 1610 shutil.rmtree(pjoin(path_me, data['paths'][1])) 1611 except Exception: 1612 pass 1613 1614 # 1. prepare the interface---------------------------------------------- 1615 mgcmd = self.mg5cmd 1616 complex_mass = False 1617 has_cms = re.compile(r'''set\s+complex_mass_scheme\s*(True|T|1|true|$|;)''') 1618 for line in self.banner.proc_card: 1619 if line.startswith('set'): 1620 mgcmd.exec_cmd(line, printcmd=False, precmd=False, postcmd=False) 1621 if has_cms.search(line): 1622 complex_mass = True 1623 elif line.startswith('define'): 1624 try: 1625 mgcmd.exec_cmd(line, printcmd=False, precmd=False, postcmd=False) 1626 except Exception: 1627 pass 1628 1629 # 1. Load model--------------------------------------------------------- 1630 if not data['model_name'] and not second: 1631 raise self.InvalidCmd('Only UFO model can be loaded in this module.') 1632 elif data['model_name']: 1633 self.load_model(data['model_name'], data['mg_names'], complex_mass) 1634 modelpath = self.model.get('modelpath') 1635 if os.path.basename(modelpath) != mgcmd._curr_model['name']: 1636 name, restrict = mgcmd._curr_model['name'].rsplit('-',1) 1637 if os.path.exists(pjoin(os.path.dirname(modelpath),name, 'restrict_%s.dat' % restrict)): 1638 modelpath = pjoin(os.path.dirname(modelpath), mgcmd._curr_model['name']) 1639 1640 commandline="import model %s " % modelpath 1641 if not data['mg_names']: 1642 commandline += ' -modelname ' 1643 mgcmd.exec_cmd(commandline) 1644 1645 #multiparticles 1646 for name, content in self.banner.get('proc_card', 'multiparticles'): 1647 mgcmd.exec_cmd("define %s = %s" % (name, content)) 1648 1649 if second and 'tree_path' in self.dedicated_path: 1650 files.ln(self.dedicated_path['tree_path'], path_me,name=data['paths'][0]) 1651 if 'virtual_path' in self.dedicated_path: 1652 has_nlo=True 1653 else: 1654 has_nlo=False 1655 else: 1656 has_nlo = self.create_standalone_tree_directory(data, second) 1657 1658 1659 # 5. create the virtual for NLO reweighting --------------------------- 1660 if second and 'virtual_path' in self.dedicated_path: 1661 files.ln(self.dedicated_path['virtual_path'], path_me, name=data['paths'][1]) 1662 elif has_nlo and 'NLO' in self.rwgt_mode: 1663 self.create_standalone_virt_directory(data, second) 1664 1665 if False:#not second: 1666 #compile the module to combine the weight 1667 misc.compile(cwd=pjoin(path_me, data['paths'][1], 'Source')) 1668 #link it 1669 if path_me not in sys.path: 1670 sys.path.insert(0, os.path.realpath(path_me)) 1671 with misc.chdir(pjoin(path_me)): 1672 mymod = __import__('%s.Source.rwgt2py' % data['paths'][1], globals(), locals(), [],-1) 1673 mymod = mymod.Source.rwgt2py 1674 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1675 mymod.initialise([self.banner.run_card['lpp1'], 1676 self.banner.run_card['lpp2']], 1677 self.banner.run_card.get_lhapdf_id()) 1678 self.combine_wgt = mymod.get_wgt 1679 1680 if self.multicore == 'create': 1681 print "compile OLP", data['paths'][1] 1682 try: 1683 misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][1],'SubProcesses'), 1684 nb_core=self.mother.options['nb_core']) 1685 except: 1686 misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][1],'SubProcesses'), 1687 nb_core=1) 1688 elif has_nlo and not second and self.rwgt_mode == ['NLO_tree']: 1689 # We do not have any virtual reweighting to do but we still have to 1690 #combine the weights. 1691 #Idea:create a fake directory. 1692 start = time.time() 1693 commandline='import model loop_sm;generate g g > e+ ve [virt=QCD]' 1694 # deactivate golem since it creates troubles 1695 old_options = dict(mgcmd.options) 1696 mgcmd.options['golem'] = None 1697 commandline = commandline.replace('add process', 'generate',1) 1698 logger.info(commandline) 1699 mgcmd.exec_cmd(commandline, precmd=True) 1700 commandline = 'output standalone_rw %s --prefix=int -f' % pjoin(path_me, data['paths'][1]) 1701 mgcmd.exec_cmd(commandline, precmd=True) 1702 #put back golem to original value 1703 mgcmd.options['golem'] = old_options['golem'] 1704 # update make_opts 1705 if not mgcmd.options['lhapdf']: 1706 raise Exception, "NLO_tree reweighting requires LHAPDF to work correctly" 1707 1708 # Download LHAPDF SET 1709 common_run_interface.CommonRunCmd.install_lhapdf_pdfset_static(\ 1710 mgcmd.options['lhapdf'], None, self.banner.run_card.get_lhapdf_id()) 1711 1712 #compile the module to combine the weight 1713 if False: 1714 #use python module instead 1715 misc.compile(cwd=pjoin(path_me, data['paths'][1], 'Source')) 1716 #link it 1717 with misc.chdir(pjoin(path_me)): 1718 if path_me not in sys.path: 1719 sys.path.insert(0, path_me) 1720 mymod = __import__('%s.Source.rwgt2py' % data['paths'][1], globals(), locals(), [],-1) 1721 mymod = mymod.Source.rwgt2py 1722 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1723 mymod.initialise([self.banner.run_card['lpp1'], 1724 self.banner.run_card['lpp2']], 1725 self.banner.run_card.get_lhapdf_id()) 1726 self.combine_wgt = mymod.get_wgt 1727 1728 1729 # 6. If we need a new model/process------------------------------------- 1730 if (self.second_model or self.second_process or self.dedicated_path) and not second : 1731 self.create_standalone_directory(second=True) 1732 1733 if not second: 1734 self.has_nlo = has_nlo
1735 1736 1737
1738 - def compile(self):
1739 """compile the code""" 1740 1741 if self.multicore=='wait': 1742 return 1743 1744 if not self.rwgt_dir: 1745 path_me = self.me_dir 1746 else: 1747 path_me = self.rwgt_dir 1748 for onedir in self.rwgt_dir_possibility: 1749 if not os.path.isdir(pjoin(path_me,onedir)): 1750 continue 1751 pdir = pjoin(path_me, onedir, 'SubProcesses') 1752 if self.mother: 1753 nb_core = self.mother.options['nb_core'] if self.mother.options['run_mode'] !=0 else 1 1754 else: 1755 nb_core = 1 1756 os.environ['MENUM'] = '2' 1757 misc.compile(['allmatrix2py.so'], cwd=pdir, nb_core=nb_core) 1758 if not (self.second_model or self.second_process or self.dedicated_path): 1759 os.environ['MENUM'] = '3' 1760 misc.compile(['allmatrix3py.so'], cwd=pdir, nb_core=nb_core)
1761
1762 - def load_module(self, metag=1):
1763 """load the various module and load the associate information""" 1764 1765 if not self.rwgt_dir: 1766 path_me = self.me_dir 1767 else: 1768 path_me = self.rwgt_dir 1769 1770 self.id_to_path = {} 1771 self.id_to_path_second = {} 1772 for onedir in self.rwgt_dir_possibility: 1773 if not os.path.exists(pjoin(path_me,onedir)): 1774 continue 1775 pdir = pjoin(path_me, onedir, 'SubProcesses') 1776 for tag in [2*metag,2*metag+1]: 1777 with misc.TMP_variable(sys, 'path', [pjoin(path_me)]+sys.path): 1778 mod_name = '%s.SubProcesses.allmatrix%spy' % (onedir, tag) 1779 #mymod = __import__('%s.SubProcesses.allmatrix%spy' % (onedir, tag), globals(), locals(), [],-1) 1780 if mod_name in sys.modules.keys(): 1781 del sys.modules[mod_name] 1782 tmp_mod_name = mod_name 1783 while '.' in tmp_mod_name: 1784 tmp_mod_name = tmp_mod_name.rsplit('.',1)[0] 1785 del sys.modules[tmp_mod_name] 1786 mymod = __import__(mod_name, globals(), locals(), [],-1) 1787 else: 1788 mymod = __import__(mod_name, globals(), locals(), [],-1) 1789 1790 S = mymod.SubProcesses 1791 mymod = getattr(S, 'allmatrix%spy' % tag) 1792 1793 # Param card not available -> no initialisation 1794 self.f2pylib[(onedir,tag)] = mymod 1795 if hasattr(mymod, 'set_madloop_path'): 1796 mymod.set_madloop_path(pjoin(path_me,onedir,'SubProcesses','MadLoop5_resources')) 1797 if (self.second_model or self.second_process or self.dedicated_path): 1798 break 1799 1800 data = self.id_to_path 1801 if '_second' in onedir: 1802 data = self.id_to_path_second 1803 1804 # get all the information 1805 all_pdgs = mymod.get_pdg_order() 1806 all_pdgs = [[pdg for pdg in pdgs if pdg!=0] for pdgs in mymod.get_pdg_order()] 1807 all_prefix = [''.join(j).strip().lower() for j in mymod.get_prefix()] 1808 prefix_set = set(all_prefix) 1809 1810 1811 hel_dict={} 1812 for prefix in prefix_set: 1813 if hasattr(mymod,'%sprocess_nhel' % prefix): 1814 nhel = getattr(mymod, '%sprocess_nhel' % prefix).nhel 1815 hel_dict[prefix] = {} 1816 for i, onehel in enumerate(zip(*nhel)): 1817 hel_dict[prefix][tuple(onehel)] = i+1 1818 elif hasattr(mymod, 'set_madloop_path') and \ 1819 os.path.exists(pjoin(path_me,onedir,'SubProcesses','MadLoop5_resources', '%sHelConfigs.dat' % prefix.upper())): 1820 hel_dict[prefix] = {} 1821 for i,line in enumerate(open(pjoin(path_me,onedir,'SubProcesses','MadLoop5_resources', '%sHelConfigs.dat' % prefix.upper()))): 1822 onehel = [int(h) for h in line.split()] 1823 hel_dict[prefix][tuple(onehel)] = i+1 1824 else: 1825 misc.sprint(pjoin(path_me,onedir,'SubProcesses','MadLoop5_resources', '%sHelConfigs.dat' % prefix.upper() )) 1826 misc.sprint(os.path.exists(pjoin(path_me,onedir,'SubProcesses','MadLoop5_resources', '%sHelConfigs.dat' % prefix.upper()))) 1827 continue 1828 1829 for i,pdg in enumerate(all_pdgs): 1830 if self.is_decay: 1831 incoming = [pdg[0]] 1832 outgoing = pdg[1:] 1833 else: 1834 incoming = pdg[0:2] 1835 outgoing = pdg[2:] 1836 order = (list(incoming), list(outgoing)) 1837 incoming.sort() 1838 if not self.keep_ordering: 1839 outgoing.sort() 1840 tag = (tuple(incoming), tuple(outgoing)) 1841 if 'virt' in onedir: 1842 tag = (tag, 'V') 1843 prefix = all_prefix[i] 1844 if prefix in hel_dict: 1845 hel = hel_dict[prefix] 1846 else: 1847 hel = {} 1848 if tag in data: 1849 oldpdg = data[tag][0][0]+data[tag][0][1] 1850 if all_prefix[all_pdgs.index(pdg)] == all_prefix[all_pdgs.index(oldpdg)]: 1851 for i in range(len(pdg)): 1852 if pdg[i] == oldpdg[i]: 1853 continue 1854 if not self.model or not hasattr(self.model, 'get_mass'): 1855 continue 1856 if self.model.get_mass(int(pdg[i])) == self.model.get_mass(int(oldpdg[i])): 1857 continue 1858 misc.sprint(tag, onedir) 1859 misc.sprint(data[tag][:-1]) 1860 misc.sprint(order, pdir,) 1861 raise Exception 1862 else: 1863 misc.sprint(all_prefix[all_pdgs.index(pdg)]) 1864 misc.sprint(all_prefix[all_pdgs.index(oldpdg)]) 1865 misc.sprint(tag, onedir) 1866 misc.sprint(data[tag][:-1]) 1867 misc.sprint(order, pdir,) 1868 raise Exception, "two different matrix-element have the same initial/final state. Leading to an ambiguity. If your events are ALWAYS written in the correct-order (look at the numbering in the Feynman Diagram). Then you can add inside your reweight_card the line 'change keep_ordering True'." 1869 1870 data[tag] = order, pdir, hel
1871 1872
1873 - def load_model(self, name, use_mg_default, complex_mass=False):
1874 """load the model""" 1875 1876 loop = False 1877 1878 logger.info('detected model: %s. Loading...' % name) 1879 model_path = name 1880 1881 # Import model 1882 base_model = import_ufo.import_model(name, decay=False, 1883 complex_mass_scheme=complex_mass) 1884 1885 if use_mg_default: 1886 base_model.pass_particles_name_in_mg_default() 1887 1888 self.model = base_model 1889 self.mg5cmd._curr_model = self.model 1890 self.mg5cmd.process_model()
1891 1892
1893 - def save_to_pickle(self):
1894 import madgraph.iolibs.save_load_object as save_load_object 1895 1896 to_save = {} 1897 to_save['id_to_path'] = self.id_to_path 1898 if hasattr(self, 'id_to_path_second'): 1899 to_save['id_to_path_second'] = self.id_to_path_second 1900 else: 1901 to_save['id_to_path_second'] = {} 1902 to_save['all_cross_section'] = self.all_cross_section 1903 to_save['processes'] = self.processes 1904 to_save['second_process'] = self.second_process 1905 if self.second_model: 1906 to_save['second_model'] =True 1907 else: 1908 to_save['second_model'] = None 1909 to_save['rwgt_dir'] = self.rwgt_dir 1910 to_save['has_nlo'] = self.has_nlo 1911 to_save['rwgt_mode'] = self.rwgt_mode 1912 to_save['rwgt_name'] = self.options['rwgt_name'] 1913 to_save['allow_missing_finalstate'] = self.options['allow_missing_finalstate'] 1914 1915 name = pjoin(self.rwgt_dir, 'rw_me', 'rwgt.pkl') 1916 save_load_object.save_to_file(name, to_save)
1917 1918
1919 - def load_from_pickle(self, keep_name=False):
1920 import madgraph.iolibs.save_load_object as save_load_object 1921 1922 obj = save_load_object.load_from_file( pjoin(self.rwgt_dir, 'rw_me', 'rwgt.pkl')) 1923 1924 self.has_standalone_dir = True 1925 self.options = {'curr_dir': os.path.realpath(os.getcwd()), 1926 'rwgt_name': None} 1927 if keep_name: 1928 self.options['rwgt_name'] = obj['rwgt_name'] 1929 self.options['allow_missing_finalstate'] = obj['allow_missing_finalstate'] 1930 old_rwgt = obj['rwgt_dir'] 1931 1932 # path to fortran executable 1933 self.id_to_path = {} 1934 for key , (order, Pdir, hel_dict) in obj['id_to_path'].items(): 1935 new_P = Pdir.replace(old_rwgt, self.rwgt_dir) 1936 self.id_to_path[key] = [order, new_P, hel_dict] 1937 1938 # path to fortran executable (for second directory) 1939 self.id_to_path_second = {} 1940 for key , (order, Pdir, hel_dict) in obj['id_to_path_second'].items(): 1941 new_P = Pdir.replace(old_rwgt, self.rwgt_dir) 1942 self.id_to_path_second[key] = [order, new_P, hel_dict] 1943 1944 self.all_cross_section = obj['all_cross_section'] 1945 self.processes = obj['processes'] 1946 self.second_process = obj['second_process'] 1947 self.second_model = obj['second_model'] 1948 self.has_nlo = obj['has_nlo'] 1949 if not self.rwgt_mode: 1950 self.rwgt_mode = obj['rwgt_mode'] 1951 logger.info("mode set to %s" % self.rwgt_mode) 1952 if False:#self.has_nlo and 'NLO' in self.rwgt_mode: 1953 #use python version 1954 path = pjoin(obj['rwgt_dir'], 'rw_mevirt','Source') 1955 sys.path.insert(0, path) 1956 try: 1957 mymod = __import__('rwgt2py', globals(), locals()) 1958 except ImportError: 1959 misc.compile(['rwgt2py.so'], cwd=path) 1960 mymod = __import__('rwgt2py', globals(), locals()) 1961 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1962 mymod.initialise([self.banner.run_card['lpp1'], 1963 self.banner.run_card['lpp2']], 1964 self.banner.run_card.get_lhapdf_id()) 1965 self.combine_wgt = mymod.get_wgt
1966