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