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