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 weight = self.calculate_weight(event) 563 if not isinstance(weight, dict): 564 weight = {'':weight} 565 566 for name in weight: 567 cross[name] += weight[name] 568 ratio[name] += weight[name]/event.wgt 569 ratio_square[name] += (weight[name]/event.wgt)**2 570 571 # ensure to have a consistent order of the weights. new one are put 572 # at the back, remove old position if already defines 573 for tag in type_rwgt: 574 try: 575 event.reweight_order.remove('%s%s' % (tag_name,tag)) 576 except ValueError: 577 continue 578 579 event.reweight_order += ['%s%s' % (tag_name,name) for name in type_rwgt] 580 if self.output_type == "default": 581 for name in weight: 582 if 'orig' in name: 583 continue 584 event.reweight_data['%s%s' % (tag_name,name)] = weight[name] 585 #write this event with weight 586 output.write(str(event)) 587 else: 588 for i,name in enumerate(weight): 589 if 'orig' in name: 590 continue 591 if weight[name] == 0: 592 continue 593 new_evt = lhe_parser.Event(str(event)) 594 new_evt.wgt = weight[name] 595 new_evt.parse_reweight() 596 new_evt.reweight_data = {} 597 output[(tag_name,name)].write(str(new_evt)) 598 599 # check normalisation of the events: 600 if 'event_norm' in self.run_card: 601 if self.run_card['event_norm'] in ['average','bias']: 602 for key, value in cross.items(): 603 cross[key] = value / (event_nb+1) 604 605 running_time = misc.format_timer(time.time()-start) 606 logger.info('All event done (nb_event: %s) %s' % (event_nb+1, running_time)) 607 608 609 if self.output_type == "default": 610 output.write('</LesHouchesEvents>\n') 611 output.close() 612 else: 613 for key in output: 614 output[key].write('</LesHouchesEvents>\n') 615 output[key].close() 616 if self.systematics and len(output) ==1: 617 try: 618 logger.info('running systematics computation') 619 import madgraph.various.systematics as syst 620 621 if not isinstance(self.systematics, bool): 622 args = [output[key].name, output[key].name] + self.systematics 623 else: 624 args = [output[key].name, output[key].name] 625 if self.mother and self.mother.options['lhapdf']: 626 args.append('--lhapdf_config=%s' % self.mother.options['lhapdf']) 627 syst.call_systematics(args, result=open('rwg_syst_%s.result' % key[0],'w'), 628 log=logger.info) 629 except Exception: 630 logger.error('fail to add systematics') 631 raise 632 # add output information 633 if self.mother and hasattr(self.mother, 'results'): 634 run_name = self.mother.run_name 635 results = self.mother.results 636 results.add_run(run_name, self.run_card, current=True) 637 results.add_detail('nb_event', event_nb+1) 638 name = type_rwgt[0] 639 results.add_detail('cross', cross[name]) 640 event_nb +=1 641 for name in type_rwgt: 642 variance = ratio_square[name]/event_nb - (ratio[name]/event_nb)**2 643 orig_cross, orig_error = self.orig_cross 644 error[name] = math.sqrt(max(0,variance/math.sqrt(event_nb))) * orig_cross + ratio[name]/event_nb * orig_error 645 results.add_detail('error', error[type_rwgt[0]]) 646 import madgraph.interface.madevent_interface as ME_interface 647 648 self.lhe_input.close() 649 if not self.mother: 650 name, ext = self.lhe_input.name.rsplit('.',1) 651 target = '%s_out.%s' % (name, ext) 652 elif self.output_type != "default" : 653 target = pjoin(self.mother.me_dir, 'Events', run_name, 'events.lhe') 654 else: 655 target = self.lhe_input.name 656 657 if self.output_type == "default": 658 files.mv(output.name, target) 659 logger.info('Event %s have now the additional weight' % self.lhe_input.name) 660 elif self.output_type == "unweight": 661 for key in output: 662 #output[key].write('</LesHouchesEvents>\n') 663 #output.close() 664 lhe = lhe_parser.EventFile(output[key].name) 665 nb_event = lhe.unweight(target) 666 if self.mother and hasattr(self.mother, 'results'): 667 results = self.mother.results 668 results.add_detail('nb_event', nb_event) 669 results.current.parton.append('lhe') 670 logger.info('Event %s is now unweighted under the new theory: %s(%s)' % (lhe.name, target, nb_event)) 671 else: 672 if self.mother and hasattr(self.mother, 'results'): 673 results = self.mother.results 674 results.current.parton.append('lhe') 675 logger.info('Eventfiles is/are now created with new central weight') 676 677 if self.multicore != 'create': 678 for name in cross: 679 if name == 'orig': 680 continue 681 logger.info('new cross-section is %s: %g pb (indicative error: %g pb)' %\ 682 ('(%s)' %name if name else '',cross[name], error[name])) 683 684 self.terminate_fortran_executables(new_card_only=True) 685 #store result 686 for name in cross: 687 if name == 'orig': 688 self.all_cross_section[name] = (cross[name], error[name]) 689 else: 690 self.all_cross_section[(tag_name,name)] = (cross[name], error[name]) 691 692 # perform the scanning 693 if param_card_iterator: 694 for i,card in enumerate(param_card_iterator): 695 if self.options['rwgt_name']: 696 self.options['rwgt_name'] = '%s_%s' % (self.options['rwgt_name'].rsplit('_',1)[0], i+1) 697 self.new_param_card = card 698 #card.write(pjoin(rw_dir, 'Cards', 'param_card.dat')) 699 self.exec_cmd("launch --keep_card", printcmd=False, precmd=True) 700 701 self.options['rwgt_name'] = None
702 703
704 - def handle_param_card(self, model_line, args, type_rwgt):
705 706 if self.rwgt_dir: 707 path_me =self.rwgt_dir 708 else: 709 path_me = self.me_dir 710 711 if self.second_model or self.second_process or self.dedicated_path: 712 rw_dir = pjoin(path_me, 'rw_me_second') 713 else: 714 rw_dir = pjoin(path_me, 'rw_me') 715 716 717 if not '--keep_card' in args: 718 if self.has_nlo and self.rwgt_mode != "LO": 719 rwdir_virt = rw_dir.replace('rw_me', 'rw_mevirt') 720 721 out, cmd = common_run_interface.CommonRunCmd.ask_edit_card_static(cards=['param_card.dat'], 722 ask=self.ask, pwd=rw_dir, first_cmd=self.stored_line, 723 write_file=False, return_instance=True 724 ) 725 self.stored_line = None 726 card = cmd.param_card 727 new_card = card.write() 728 elif self.new_param_card: 729 new_card = self.new_param_card.write() 730 else: 731 new_card = open(pjoin(rw_dir, 'Cards', 'param_card.dat')).read() 732 733 # check for potential scan in the new card 734 pattern_scan = re.compile(r'''^(decay)?[\s\d]*scan''', re.I+re.M) 735 param_card_iterator = [] 736 if pattern_scan.search(new_card): 737 try: 738 import internal.extended_cmd as extended_internal 739 Shell_internal = extended_internal.CmdShell 740 except: 741 Shell_internal = None 742 import madgraph.interface.extended_cmd as extended_cmd 743 if not isinstance(self.mother, (extended_cmd.CmdShell, Shell_internal)): 744 raise Exception("scan are not allowed on the Web") 745 # at least one scan parameter found. create an iterator to go trough the cards 746 main_card = check_param_card.ParamCardIterator(new_card) 747 if self.options['rwgt_name']: 748 self.options['rwgt_name'] = '%s_0' % self.options['rwgt_name'] 749 750 param_card_iterator = main_card 751 first_card = param_card_iterator.next(autostart=True) 752 new_card = first_card.write() 753 self.new_param_card = first_card 754 #first_card.write(pjoin(rw_dir, 'Cards', 'param_card.dat')) 755 756 # check if "Auto" is present for a width parameter) 757 tmp_card = new_card.lower().split('block',1)[1] 758 if "auto" in tmp_card: 759 if param_card_iterator: 760 first_card.write(pjoin(rw_dir, 'Cards', 'param_card.dat')) 761 else: 762 ff = open(pjoin(rw_dir, 'Cards', 'param_card.dat'),'w') 763 ff.write(new_card) 764 ff.close() 765 766 self.mother.check_param_card(pjoin(rw_dir, 'Cards', 'param_card.dat')) 767 new_card = open(pjoin(rw_dir, 'Cards', 'param_card.dat')).read() 768 769 770 # Find new tag in the banner and add information if needed 771 if 'initrwgt' in self.banner and self.output_type == 'default': 772 if 'name=\'mg_reweighting\'' in self.banner['initrwgt']: 773 blockpat = re.compile(r'''<weightgroup name=\'mg_reweighting\'\s*weight_name_strategy=\'includeIdInWeightName\'>(?P<text>.*?)</weightgroup>''', re.I+re.M+re.S) 774 before, content, after = blockpat.split(self.banner['initrwgt']) 775 header_rwgt_other = before + after 776 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) 777 mg_rwgt_info = pattern.findall(content) 778 779 maxid = 0 780 for k,(i, fulltag, nlotype, diff) in enumerate(mg_rwgt_info): 781 if i: 782 if int(i) > maxid: 783 maxid = int(i) 784 mg_rwgt_info[k] = (i, nlotype, diff) # remove the pointless fulltag tag 785 else: 786 mg_rwgt_info[k] = (fulltag, nlotype, diff) # remove the pointless id tag 787 788 maxid += 1 789 rewgtid = maxid 790 if self.options['rwgt_name']: 791 #ensure that the entry is not already define if so overwrites it 792 for (i, nlotype, diff) in mg_rwgt_info[:]: 793 for flag in type_rwgt: 794 if 'rwgt_%s' % i == '%s%s' %(self.options['rwgt_name'],flag) or \ 795 i == '%s%s' % (self.options['rwgt_name'], flag): 796 logger.warning("tag %s%s already defines, will replace it", self.options['rwgt_name'],flag) 797 mg_rwgt_info.remove((i, nlotype, diff)) 798 799 else: 800 header_rwgt_other = self.banner['initrwgt'] 801 mg_rwgt_info = [] 802 rewgtid = 1 803 else: 804 self.banner['initrwgt'] = '' 805 header_rwgt_other = '' 806 mg_rwgt_info = [] 807 rewgtid = 1 808 809 # add the reweighting in the banner information: 810 #starts by computing the difference in the cards. 811 s_orig = self.banner['slha'] 812 self.orig_param_card_text = s_orig 813 s_new = new_card 814 self.new_param_card = check_param_card.ParamCard(s_new.splitlines()) 815 816 #define tag for the run 817 if self.options['rwgt_name']: 818 tag = self.options['rwgt_name'] 819 else: 820 tag = str(rewgtid) 821 822 if 'rwgt_info' in self.options and self.options['rwgt_info']: 823 card_diff = self.options['rwgt_info'] 824 for name in type_rwgt: 825 mg_rwgt_info.append((tag, name, self.options['rwgt_info'])) 826 elif not self.second_model and not self.dedicated_path: 827 old_param = check_param_card.ParamCard(s_orig.splitlines()) 828 new_param = self.new_param_card 829 card_diff = old_param.create_diff(new_param) 830 if card_diff == '' and not self.second_process: 831 logger.warning(' REWEIGHTING: original card and new card are identical.') 832 try: 833 if old_param['sminputs'].get(3)- new_param['sminputs'].get(3) > 1e-3 * new_param['sminputs'].get(3): 834 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.") 835 except Exception as error: 836 logger.debug("error in check of alphas: %s" % str(error)) 837 pass #this is a security 838 if not self.second_process: 839 for name in type_rwgt: 840 mg_rwgt_info.append((tag, name, card_diff)) 841 else: 842 str_proc = "\n change process ".join([""]+self.second_process) 843 for name in type_rwgt: 844 mg_rwgt_info.append((tag, name, str_proc + '\n'+ card_diff)) 845 else: 846 if self.second_model: 847 str_info = "change model %s" % self.second_model 848 else: 849 str_info ='' 850 if self.second_process: 851 str_info += "\n change process ".join([""]+self.second_process) 852 if self.dedicated_path: 853 for k,v in self.dedicated_path.items(): 854 str_info += "\n change %s %s" % (k,v) 855 card_diff = str_info 856 str_info += '\n' + s_new 857 for name in type_rwgt: 858 mg_rwgt_info.append((tag, name, str_info)) 859 # re-create the banner. 860 self.banner['initrwgt'] = header_rwgt_other 861 if self.output_type == 'default': 862 self.banner['initrwgt'] += '\n<weightgroup name=\'mg_reweighting\' weight_name_strategy=\'includeIdInWeightName\'>\n' 863 else: 864 self.banner['initrwgt'] += '\n<weightgroup name=\'main\'>\n' 865 for tag, rwgttype, diff in mg_rwgt_info: 866 if tag.isdigit(): 867 self.banner['initrwgt'] += '<weight id=\'rwgt_%s%s\'>%s</weight>\n' % \ 868 (tag, rwgttype, diff) 869 else: 870 self.banner['initrwgt'] += '<weight id=\'%s%s\'>%s</weight>\n' % \ 871 (tag, rwgttype, diff) 872 self.banner['initrwgt'] += '\n</weightgroup>\n' 873 self.banner['initrwgt'] = self.banner['initrwgt'].replace('\n\n', '\n') 874 875 logger.info('starts to compute weight for events with the following modification to the param_card:') 876 logger.info(card_diff.replace('\n','\nKEEP:')) 877 self.run_card = banner.Banner(self.banner).charge_card('run_card') 878 879 if self.options['rwgt_name']: 880 tag_name = self.options['rwgt_name'] 881 else: 882 tag_name = 'rwgt_%s' % rewgtid 883 884 885 #initialise module. 886 for (path,tag), module in self.f2pylib.items(): 887 with misc.chdir(pjoin(os.path.dirname(rw_dir), path)): 888 with misc.stdchannel_redirected(sys.stdout, os.devnull): 889 if 'second' in path or tag == 3: 890 param_card = self.new_param_card 891 else: 892 param_card = check_param_card.ParamCard(self.orig_param_card_text) 893 894 for block in param_card: 895 896 for param in param_card[block]: 897 lhacode = param.lhacode 898 value = param.value 899 name = '%s_%s' % (block.upper(), '_'.join([str(i) for i in lhacode])) 900 module.change_para(name, value) 901 module.update_all_coup() 902 903 return param_card_iterator, tag_name
904 905
906 - def do_set(self, line):
907 "Not in help" 908 909 logger.warning("Invalid Syntax. The command 'set' should be placed after the 'launch' one. Continuing by adding automatically 'launch'") 910 self.stored_line = "set %s" % line 911 return self.exec_cmd("launch")
912
913 - def default(self, line, log=True):
914 """Default action if line is not recognized""" 915 916 if os.path.isfile(line): 917 if log: 918 logger.warning("Invalid Syntax. The path to a param_card' should be placed after the 'launch' command. Continuing by adding automatically 'launch'") 919 self.stored_line = line 920 return self.exec_cmd("launch") 921 else: 922 return super(ReweightInterface,self).default(line, log=log)
923
924 - def write_reweighted_event(self, event, tag_name, **opt):
925 """a function for running in multicore""" 926 927 if not hasattr(opt['thread_space'], "calculator"): 928 opt['thread_space'].calculator = {} 929 opt['thread_space'].calculator_nbcall = {} 930 opt['thread_space'].cross = 0 931 opt['thread_space'].output = open( self.lhe_input.name +'rw.%s' % opt['thread_id'], 'w') 932 if self.mother: 933 out_path = pjoin(self.mother.me_dir, 'Events', 'reweight.lhe.%s' % opt['thread_id']) 934 opt['thread_space'].output2 = open(out_path, 'w') 935 936 weight = self.calculate_weight(event, space=opt['thread_space']) 937 opt['thread_space'].cross += weight 938 if self.output_type == "default": 939 event.reweight_data[tag_name] = weight 940 #write this event with weight 941 opt['thread_space'].output.write(str(event)) 942 if self.mother: 943 event.wgt = weight 944 event.reweight_data = {} 945 opt['thread_space'].output2.write(str(event)) 946 else: 947 event.wgt = weight 948 event.reweight_data = {} 949 if self.mother: 950 opt['thread_space'].output2.write(str(event)) 951 else: 952 opt['thread_space'].output.write(str(event)) 953 954 return 0
955
956 - def do_compute_widths(self, line):
957 return self.mother.do_compute_widths(line)
958 959 960 dynamical_scale_warning=True
961 - def change_kinematics(self, event):
962 963 964 if isinstance(self.run_card, banner.RunCardLO): 965 jac = event.change_ext_mass(self.new_param_card) 966 new_event = event 967 else: 968 jac =1 969 new_event = event 970 971 if jac != 1: 972 if self.output_type == 'default': 973 logger.critical('mass reweighting requires dedicated lhe output!. Please include "change output 2.0" in your reweight_card') 974 raise Exception 975 mode = self.run_card['dynamical_scale_choice'] 976 if mode == -1: 977 if self.dynamical_scale_warning: 978 logger.warning('dynamical_scale is set to -1. New sample will be with HT/2 dynamical scale for renormalisation scale') 979 mode = 3 980 new_event.scale = event.get_scale(mode) 981 new_event.aqcd = self.lhe_input.get_alphas(new_event.scale, lhapdf_config=self.mother.options['lhapdf']) 982 983 return jac, new_event
984 985
986 - def calculate_weight(self, event):
987 """space defines where to find the calculator (in multicore)""" 988 989 990 if self.has_nlo and self.rwgt_mode != "LO": 991 if not hasattr(self,'pdf'): 992 lhapdf = misc.import_python_lhapdf(self.mg5cmd.options['lhapdf']) 993 self.pdf = lhapdf.mkPDF(self.banner.run_card.get_lhapdf_id()) 994 995 return self.calculate_nlo_weight(event) 996 997 event.parse_reweight() 998 orig_wgt = event.wgt 999 # LO reweighting 1000 w_orig = self.calculate_matrix_element(event, 0) 1001 1002 # reshuffle event for mass effect # external mass only 1003 # carefull that new_event can sometimes be = to event 1004 # (i.e. change can be in place) 1005 jac, new_event = self.change_kinematics(event) 1006 1007 1008 if event.wgt != 0: # impossible reshuffling 1009 w_new = self.calculate_matrix_element(new_event, 1) 1010 else: 1011 w_new = 0 1012 1013 if w_orig == 0: 1014 tag, order = event.get_tag_and_order() 1015 orig_order, Pdir, hel_dict = self.id_to_path[tag] 1016 misc.sprint(w_orig, w_new) 1017 misc.sprint(event) 1018 misc.sprint(self.invert_momenta(event.get_momenta(orig_order))) 1019 misc.sprint(event.get_momenta(orig_order)) 1020 misc.sprint(event.aqcd) 1021 hel_order = event.get_helicity(orig_order) 1022 if self.helicity_reweighting and 9 not in hel_order: 1023 nhel = hel_dict[tuple(hel_order)] 1024 else: 1025 nhel = 0 1026 misc.sprint(nhel, Pdir, hel_dict) 1027 raise Exception("Invalid matrix element for original computation (weight=0)") 1028 1029 return {'orig': orig_wgt, '': w_new/w_orig*orig_wgt*jac}
1030
1031 - def calculate_nlo_weight(self, event):
1032 1033 1034 type_nlo = self.get_weight_names() 1035 final_weight = {'orig': event.wgt} 1036 1037 event.parse_reweight() 1038 event.parse_nlo_weight(threshold=self.soft_threshold) 1039 if self.output_type != 'default': 1040 event.nloweight.modified = True # the internal info will be changed 1041 # so set this flage to True to change 1042 # the writting of those data 1043 1044 #initialise the input to the function which recompute the weight 1045 scales2 = [] 1046 pdg = [] 1047 bjx = [] 1048 wgt_tree = [] # reweight for loop-improved type 1049 wgt_virt = [] #reweight b+v together 1050 base_wgt = [] 1051 gs=[] 1052 qcdpower = [] 1053 ref_wgts = [] #for debugging 1054 1055 orig_wgt = 0 1056 for cevent in event.nloweight.cevents: 1057 #check if we need to compute the virtual for that cevent 1058 need_V = False # the real is nothing else than the born for a N+1 config 1059 all_ctype = [w.type for w in cevent.wgts] 1060 if '_nlo' in type_nlo and any(c in all_ctype for c in [2,14,15]): 1061 need_V =True 1062 1063 w_orig = self.calculate_matrix_element(cevent, 0) 1064 w_new = self.calculate_matrix_element(cevent, 1) 1065 ratio_T = w_new/w_orig 1066 if need_V: 1067 scale2 = cevent.wgts[0].scales2[0] 1068 #for scale2 in set(c.scales2[1] for c in cevent.wgts): 1069 w_origV = self.calculate_matrix_element(cevent, 'V0', scale2=scale2) 1070 w_newV = self.calculate_matrix_element(cevent, 'V1', scale2=scale2) 1071 ratio_BV = (w_newV + w_new) / (w_origV + w_orig) 1072 ratio_V = w_newV/w_origV 1073 else: 1074 ratio_V = "should not be used" 1075 ratio_BV = "should not be used" 1076 for c_wgt in cevent.wgts: 1077 orig_wgt += c_wgt.ref_wgt 1078 #add the information to the input 1079 scales2.append(c_wgt.scales2) 1080 pdg.append(c_wgt.pdgs[:2]) 1081 1082 bjx.append(c_wgt.bjks) 1083 qcdpower.append(c_wgt.qcdpower) 1084 gs.append(c_wgt.gs) 1085 ref_wgts.append(c_wgt.ref_wgt) 1086 1087 if '_nlo' in type_nlo: 1088 if c_wgt.type in [2,14,15]: 1089 R = ratio_BV 1090 else: 1091 R = ratio_T 1092 1093 new_wgt = [c_wgt.pwgt[0] * R, 1094 c_wgt.pwgt[1] * ratio_T, 1095 c_wgt.pwgt[2] * ratio_T] 1096 wgt_virt.append(new_wgt) 1097 1098 if '_tree' in type_nlo: 1099 new_wgt = [c_wgt.pwgt[0] * ratio_T, 1100 c_wgt.pwgt[1] * ratio_T, 1101 c_wgt.pwgt[2] * ratio_T] 1102 wgt_tree.append(new_wgt) 1103 1104 base_wgt.append(c_wgt.pwgt[:3]) 1105 1106 1107 orig_wgt_check, partial_check = self.combine_wgt_local(scales2, pdg, bjx, base_wgt, gs, qcdpower, self.pdf) 1108 #change the ordering to the fortran one: 1109 #scales2_i = self.invert_momenta(scales2) 1110 #pdg_i = self.invert_momenta(pdg) 1111 #bjx_i = self.invert_momenta(bjx) 1112 # re-compute original weight to reduce numerical inacurracy 1113 #base_wgt_i = self.invert_momenta(base_wgt) 1114 #orig_wgt_check, partial_check = self.combine_wgt(scales2_i, pdg_i, bjx_i, base_wgt_i, gs, qcdpower, 1., 1.) 1115 1116 if '_nlo' in type_nlo: 1117 #wgt = self.invert_momenta(wgt_virt) 1118 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1119 new_out, partial = self.combine_wgt_local(scales2, pdg, bjx, wgt_virt, gs, qcdpower, self.pdf) 1120 # try to correct for precision issue 1121 avg = [partial_check[i]/ref_wgts[i] for i in range(len(ref_wgts))] 1122 out = sum(partial[i]/avg[i] if 0.85<avg[i]<1.15 else 0 \ 1123 for i in range(len(avg))) 1124 final_weight['_nlo'] = out/orig_wgt*event.wgt 1125 1126 1127 if '_tree' in type_nlo: 1128 #wgt = self.invert_momenta(wgt_tree) 1129 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1130 out, partial = self.combine_wgt_local(scales2, pdg, bjx, wgt_tree, gs, qcdpower, self.pdf) 1131 # try to correct for precision issue 1132 avg = [partial_check[i]/ref_wgts[i] for i in range(len(ref_wgts))] 1133 new_out = sum(partial[i]/avg[i] if 0.85<avg[i]<1.15 else partial[i] \ 1134 for i in range(len(avg))) 1135 final_weight['_tree'] = new_out/orig_wgt*event.wgt 1136 1137 1138 if '_lo' in type_nlo: 1139 w_orig = self.calculate_matrix_element(event, 0) 1140 w_new = self.calculate_matrix_element(event, 1) 1141 final_weight['_lo'] = w_new/w_orig*event.wgt 1142 1143 1144 if self.output_type != 'default' and len(type_nlo)==1 and '_lo' not in type_nlo: 1145 to_write = [partial[i]/ref_wgts[i]*partial_check[i] 1146 if 0.85<avg[i]<1.15 else 0 1147 for i in range(len(ref_wgts))] 1148 for cevent in event.nloweight.cevents: 1149 for c_wgt in cevent.wgts: 1150 c_wgt.ref_wgt = to_write.pop(0) 1151 if '_tree' in type_nlo: 1152 c_wgt.pwgt = wgt_tree.pop(0) 1153 else: 1154 c_wgt.pwgt = wgt_virt.pop(0) 1155 assert not to_write 1156 assert not wgt_tree 1157 return final_weight
1158 1159
1160 - def combine_wgt_local(self, scale2s, pdgs, bjxs, base_wgts, gss, qcdpowers, pdf):
1161 1162 wgt = 0. 1163 wgts = [] 1164 for (scale2, pdg, bjx, base_wgt, gs, qcdpower) in zip(scale2s, pdgs, bjxs, base_wgts, gss, qcdpowers): 1165 Q2, mur2, muf2 = scale2 #Q2 is Ellis-Sexton scale 1166 #misc.sprint(Q2, mur2, muf2, base_wgt, gs, qcdpower) 1167 pdf1 = pdf.xfxQ2(pdg[0], bjx[0], muf2)/bjx[0] 1168 pdf2 = pdf.xfxQ2(pdg[1], bjx[1], muf2)/bjx[1] 1169 alphas = pdf.alphasQ2(mur2) 1170 tmp = base_wgt[0] + base_wgt[1] * math.log(mur2/Q2) + base_wgt[2] * math.log(muf2/Q2) 1171 tmp *= gs**qcdpower*pdf1*pdf2 1172 wgt += tmp 1173 wgts.append(tmp) 1174 return wgt, wgts
1175 1176 1177 1178 @staticmethod
1179 - def invert_momenta(p):
1180 """ fortran/C-python do not order table in the same order""" 1181 new_p = [] 1182 for i in range(len(p[0])): new_p.append([0]*len(p)) 1183 for i, onep in enumerate(p): 1184 for j, x in enumerate(onep): 1185 new_p[j][i] = x 1186 return new_p
1187 1188 @staticmethod
1189 - def rename_f2py_lib(Pdir, tag):
1190 if tag == 2: 1191 return 1192 if os.path.exists(pjoin(Pdir, 'matrix%spy.so' % tag)): 1193 return 1194 else: 1195 open(pjoin(Pdir, 'matrix%spy.so' % tag),'w').write(open(pjoin(Pdir, 'matrix2py.so') 1196 ).read().replace('matrix2py', 'matrix%spy' % tag))
1197
1198 - def calculate_matrix_element(self, event, hypp_id, scale2=0):
1199 """routine to return the matrix element""" 1200 1201 if self.has_nlo: 1202 nb_retry, sleep = 10, 60 1203 else: 1204 nb_retry, sleep = 5, 20 1205 1206 tag, order = event.get_tag_and_order() 1207 if self.keep_ordering: 1208 old_tag = tuple(tag) 1209 tag = (tag[0], tuple(order[1])) 1210 if isinstance(hypp_id, str) and hypp_id.startswith('V'): 1211 tag = (tag,'V') 1212 hypp_id = int(hypp_id[1:]) 1213 # base = "rw_mevirt" 1214 #else: 1215 # base = "rw_me" 1216 1217 if (not self.second_model and not self.second_process and not self.dedicated_path) or hypp_id==0: 1218 orig_order, Pdir, hel_dict = self.id_to_path[tag] 1219 else: 1220 try: 1221 orig_order, Pdir, hel_dict = self.id_to_path_second[tag] 1222 except KeyError: 1223 if self.options['allow_missing_finalstate']: 1224 return 0.0 1225 else: 1226 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) 1227 raise Exception 1228 1229 base = os.path.basename(os.path.dirname(Pdir)) 1230 if '_second' in base: 1231 moduletag = (base, 2) 1232 else: 1233 moduletag = (base, 2+hypp_id) 1234 1235 module = self.f2pylib[moduletag] 1236 1237 p = event.get_momenta(orig_order) 1238 # add helicity information 1239 1240 hel_order = event.get_helicity(orig_order) 1241 if self.helicity_reweighting and 9 not in hel_order: 1242 nhel = hel_dict[tuple(hel_order)] 1243 else: 1244 nhel = -1 1245 1246 # For 2>N pass in the center of mass frame 1247 # - required for helicity by helicity re-weighitng 1248 # - Speed-up loop computation 1249 if (hypp_id == 0 and ('frame_id' in self.banner.run_card and self.banner.run_card['frame_id'] !=6)): 1250 import copy 1251 new_event = copy.deepcopy(event) 1252 pboost = FourMomenta() 1253 to_inc = bin(self.banner.run_card['frame_id'])[2:] 1254 to_inc.reverse() 1255 nb_ext = 0 1256 for p in new_event: 1257 if p.status in [-1,1]: 1258 nb_ext += 1 1259 if to_inc[nb_ext]: 1260 pboost += p 1261 new_event.boost(pboost) 1262 p = new_event.get_momenta(orig_order) 1263 elif (hypp_id == 1 and self.boost_event): 1264 if self.boost_event is not True: 1265 import copy 1266 new_event = copy.deepcopy(event) 1267 new_event.boost(self.boost_event) 1268 p = new_event.get_momenta(orig_order) 1269 elif (hasattr(event[1], 'status') and event[1].status == -1) or \ 1270 (event[1].px == event[1].py == 0.): 1271 pboost = lhe_parser.FourMomentum(p[0]) + lhe_parser.FourMomentum(p[1]) 1272 for i,thisp in enumerate(p): 1273 p[i] = lhe_parser.FourMomentum(thisp).zboost(pboost).get_tuple() 1274 assert p[0][1] == p[0][2] == 0 == p[1][2] == p[1][2] == 0 1275 1276 pold = list(p) 1277 p = self.invert_momenta(p) 1278 pdg = list(orig_order[0])+list(orig_order[1]) 1279 try: 1280 pid = event.ievent 1281 except AttributeError: 1282 pid = -1 1283 if not self.use_eventid: 1284 pid = -1 1285 1286 with misc.chdir(Pdir): 1287 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1288 me_value = module.smatrixhel(pdg, pid, p, event.aqcd, scale2, nhel) 1289 1290 # for loop we have also the stability status code 1291 if isinstance(me_value, tuple): 1292 me_value, code = me_value 1293 #if code points unstability -> returns 0 1294 hundred_value = (code % 1000) //100 1295 if hundred_value in [4]: 1296 me_value = 0. 1297 1298 return me_value
1299
1300 - def terminate_fortran_executables(self, new_card_only=False):
1301 """routine to terminate all fortran executables""" 1302 1303 for (mode, production) in dict(self.calculator): 1304 1305 if new_card_only and production == 0: 1306 continue 1307 del self.calculator[(mode, production)]
1308
1309 - def do_quit(self, line):
1310 if self.exitted: 1311 return 1312 self.exitted = True 1313 1314 if 'init' in self.banner: 1315 cross = 0 1316 error = 0 1317 for line in self.banner['init'].split('\n'): 1318 split = line.split() 1319 if len(split) == 4: 1320 cross, error = float(split[0]), float(split[1]) 1321 1322 if not self.multicore == 'create': 1323 # No print of results for the multicore mode for the one printed on screen 1324 if 'orig' not in self.all_cross_section: 1325 logger.info('Original cross-section: %s +- %s pb' % (cross, error)) 1326 else: 1327 logger.info('Original cross-section: %s +- %s pb (cross-section from sum of weights: %s)' % (cross, error, self.all_cross_section['orig'][0])) 1328 logger.info('Computed cross-section:') 1329 keys = list(self.all_cross_section.keys()) 1330 keys.sort(key=lambda x: str(x)) 1331 for key in keys: 1332 if key == 'orig': 1333 continue 1334 logger.info('%s : %s +- %s pb' % (key[0] if not key[1] else '%s%s' % key, 1335 self.all_cross_section[key][0],self.all_cross_section[key][1] )) 1336 self.terminate_fortran_executables() 1337 1338 if self.rwgt_dir and self.multicore == False: 1339 self.save_to_pickle() 1340 1341 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1342 for run_id in self.calculator: 1343 del self.calculator[run_id] 1344 del self.calculator
1345 1346
1347 - def __del__(self):
1348 self.do_quit('')
1349 1350
1351 - def adding_me(self, matrix_elements, path):
1352 """Adding one element to the list based on the matrix element"""
1353 1354 1355 @misc.mute_logger()
1356 - def create_standalone_tree_directory(self, data ,second=False):
1357 """generate the various directory for the weight evaluation""" 1358 1359 mgcmd = self.mg5cmd 1360 path_me = data['path'] 1361 # 2. compute the production matrix element ----------------------------- 1362 has_nlo = False 1363 mgcmd.exec_cmd("set group_subprocesses False") 1364 1365 if not second: 1366 logger.info('generating the square matrix element for reweighting') 1367 else: 1368 logger.info('generating the square matrix element for reweighting (second model and/or processes)') 1369 start = time.time() 1370 commandline='' 1371 for i,proc in enumerate(data['processes']): 1372 if '[' not in proc: 1373 commandline += "add process %s ;" % proc 1374 else: 1375 has_nlo = True 1376 if self.banner.get('run_card','ickkw') == 3: 1377 if len(proc) == min([len(p.strip()) for p in data['processes']]): 1378 commandline += self.get_LO_definition_from_NLO(proc, self.model) 1379 else: 1380 commandline += self.get_LO_definition_from_NLO(proc, 1381 self.model, real_only=True) 1382 else: 1383 commandline += self.get_LO_definition_from_NLO(proc, self.model) 1384 1385 commandline = commandline.replace('add process', 'generate',1) 1386 logger.info(commandline) 1387 try: 1388 mgcmd.exec_cmd(commandline, precmd=True, errorhandling=False) 1389 except diagram_generation.NoDiagramException: 1390 commandline='' 1391 for proc in data['processes']: 1392 if '[' not in proc: 1393 raise 1394 # pass to virtsq= 1395 base, post = proc.split('[',1) 1396 nlo_order, post = post.split(']',1) 1397 if '=' not in nlo_order: 1398 nlo_order = 'virt=%s' % nlo_order 1399 elif 'noborn' in nlo_order: 1400 nlo_order = nlo_order.replace('noborn', 'virt') 1401 commandline += "add process %s [%s] %s;" % (base,nlo_order,post) 1402 commandline = commandline.replace('add process', 'generate',1) 1403 if commandline: 1404 logger.info("RETRY with %s", commandline) 1405 mgcmd.exec_cmd(commandline, precmd=True) 1406 has_nlo = False 1407 except Exception as error: 1408 misc.sprint(type(error)) 1409 raise 1410 1411 commandline = 'output standalone_rw %s --prefix=int' % pjoin(path_me,data['paths'][0]) 1412 mgcmd.exec_cmd(commandline, precmd=True) 1413 logger.info('Done %.4g' % (time.time()-start)) 1414 self.has_standalone_dir = True 1415 1416 1417 # 3. Store id to directory information --------------------------------- 1418 if False: 1419 # keep this for debugging 1420 matrix_elements = mgcmd._curr_matrix_elements.get_matrix_elements() 1421 1422 to_check = [] # list of tag that do not have a Pdir at creation time. 1423 for me in matrix_elements: 1424 for proc in me.get('processes'): 1425 initial = [] #filled in the next line 1426 final = [l.get('id') for l in proc.get('legs')\ 1427 if l.get('state') or initial.append(l.get('id'))] 1428 order = (initial, final) 1429 tag = proc.get_initial_final_ids() 1430 decay_finals = proc.get_final_ids_after_decay() 1431 1432 if tag[1] != decay_finals: 1433 order = (initial, list(decay_finals)) 1434 decay_finals.sort() 1435 tag = (tag[0], tuple(decay_finals)) 1436 Pdir = pjoin(path_me, data['paths'][0], 'SubProcesses', 1437 'P%s' % me.get('processes')[0].shell_string()) 1438 1439 if not os.path.exists(Pdir): 1440 to_check.append(tag) 1441 continue 1442 if tag in data['id2path']: 1443 if not Pdir == data['id2path'][tag][1]: 1444 misc.sprint(tag, Pdir, data['id2path'][tag][1]) 1445 raise self.InvalidCmd('2 different process have the same final states. This module can not handle such situation') 1446 else: 1447 continue 1448 # build the helicity dictionary 1449 hel_nb = 0 1450 hel_dict = {9:0} # unknown helicity -> use full ME 1451 for helicities in me.get_helicity_matrix(): 1452 hel_nb +=1 #fortran starts at 1 1453 hel_dict[tuple(helicities)] = hel_nb 1454 1455 data['id2path'][tag] = [order, Pdir, hel_dict] 1456 1457 for tag in to_check: 1458 if tag not in self.id_to_path: 1459 logger.warning("no valid path for %s" % (tag,)) 1460 #raise self.InvalidCmd, "no valid path for %s" % (tag,) 1461 1462 # 4. Check MadLoopParam for Loop induced 1463 if os.path.exists(pjoin(path_me, data['paths'][0], 'Cards', 'MadLoopParams.dat')): 1464 MLCard = banner.MadLoopParam(pjoin(path_me, data['paths'][0], 'Cards', 'MadLoopParams.dat')) 1465 MLCard.set('WriteOutFilters', False) 1466 MLCard.set('UseLoopFilter', False) 1467 MLCard.set("DoubleCheckHelicityFilter", False) 1468 MLCard.set("HelicityFilterLevel", 0) 1469 MLCard.write(pjoin(path_me, data['paths'][0], 'SubProcesses', 'MadLoopParams.dat'), 1470 pjoin(path_me, data['paths'][0], 'Cards', 'MadLoopParams.dat'), 1471 commentdefault=False) 1472 1473 #if self.multicore == 'create': 1474 # print "compile OLP", data['paths'][0] 1475 # misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][0],'SubProcesses'), 1476 # nb_core=self.mother.options['nb_core']) 1477 1478 if os.path.exists(pjoin(path_me, data['paths'][1], 'Cards', 'MadLoopParams.dat')): 1479 if self.multicore == 'create': 1480 print("compile OLP", data['paths'][1]) 1481 # It is potentially unsafe to use several cores, We limit ourself to one for now 1482 # n_cores = self.mother.options['nb_core'] 1483 n_cores = 1 1484 misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][1],'SubProcesses'), 1485 nb_core=self.mother.options['nb_core']) 1486 1487 return has_nlo
1488 1489 1490 @misc.mute_logger()
1491 - def create_standalone_virt_directory(self, data ,second=False):
1492 """generate the various directory for the weight evaluation""" 1493 1494 mgcmd = self.mg5cmd 1495 path_me = data['path'] 1496 # Do not pass here for LO/NLO_tree 1497 start = time.time() 1498 commandline='' 1499 for proc in data['processes']: 1500 if '[' not in proc: 1501 pass 1502 else: 1503 proc = proc.replace('[', '[ virt=') 1504 commandline += "add process %s ;" % proc 1505 commandline = re.sub('@\s*\d+', '', commandline) 1506 # deactivate golem since it creates troubles 1507 old_options = dict(mgcmd.options) 1508 if mgcmd.options['golem']: 1509 logger.info(" When doing NLO reweighting, MG5aMC cannot use the loop reduction algorithms Golem") 1510 mgcmd.options['golem'] = None 1511 commandline = commandline.replace('add process', 'generate',1) 1512 logger.info(commandline) 1513 mgcmd.exec_cmd(commandline, precmd=True) 1514 commandline = 'output standalone_rw %s --prefix=int -f' % pjoin(path_me, data['paths'][1]) 1515 mgcmd.exec_cmd(commandline, precmd=True) 1516 1517 #put back golem to original value 1518 mgcmd.options['golem'] = old_options['golem'] 1519 # update make_opts 1520 1521 if not mgcmd.options['lhapdf']: 1522 raise Exception("NLO reweighting requires LHAPDF to work correctly") 1523 1524 # Download LHAPDF SET 1525 common_run_interface.CommonRunCmd.install_lhapdf_pdfset_static(\ 1526 mgcmd.options['lhapdf'], None, self.banner.run_card.get_lhapdf_id()) 1527 1528 # now store the id information 1529 if False: 1530 # keep it for debugging purposes 1531 matrix_elements = mgcmd._curr_matrix_elements.get_matrix_elements() 1532 for me in matrix_elements: 1533 for proc in me.get('processes'): 1534 initial = [] #filled in the next line 1535 final = [l.get('id') for l in proc.get('legs')\ 1536 if l.get('state') or initial.append(l.get('id'))] 1537 order = (initial, final) 1538 tag = proc.get_initial_final_ids() 1539 decay_finals = proc.get_final_ids_after_decay() 1540 1541 if tag[1] != decay_finals: 1542 order = (initial, list(decay_finals)) 1543 decay_finals.sort() 1544 tag = (tag[0], tuple(decay_finals)) 1545 Pdir = pjoin(path_me, data['paths'][1], 'SubProcesses', 1546 'P%s' % me.get('processes')[0].shell_string()) 1547 assert os.path.exists(Pdir), "Pdir %s do not exists" % Pdir 1548 if (tag,'V') in data['id2path']: 1549 if not Pdir == data['id2path'][(tag,'V')][1]: 1550 misc.sprint(tag, Pdir, self.id_to_path[(tag,'V')][1]) 1551 raise self.InvalidCmd('2 different process have the same final states. This module can not handle such situation') 1552 else: 1553 continue 1554 # build the helicity dictionary 1555 hel_nb = 0 1556 hel_dict = {9:0} # unknown helicity -> use full ME 1557 for helicities in me.get_helicity_matrix(): 1558 hel_nb +=1 #fortran starts at 1 1559 hel_dict[tuple(helicities)] = hel_nb 1560 1561 data['id2path'][(tag,'V')] = [order, Pdir, hel_dict]
1562 1563 1564 @misc.mute_logger()
1565 - def create_standalone_directory(self, second=False):
1566 """generate the various directory for the weight evaluation""" 1567 1568 data={} 1569 if not second: 1570 data['paths'] = ['rw_me', 'rw_mevirt'] 1571 # model 1572 info = self.banner.get('proc_card', 'full_model_line') 1573 if '-modelname' in info: 1574 data['mg_names'] = False 1575 else: 1576 data['mg_names'] = True 1577 data['model_name'] = self.banner.get('proc_card', 'model') 1578 #processes 1579 data['processes'] = [line[9:].strip() for line in self.banner.proc_card 1580 if line.startswith('generate')] 1581 data['processes'] += [' '.join(line.split()[2:]) for line in self.banner.proc_card 1582 if re.search('^\s*add\s+process', line)] 1583 #object_collector 1584 #self.id_to_path = {} 1585 #data['id2path'] = self.id_to_path 1586 else: 1587 data['paths'] = ['rw_me_second', 'rw_mevirt_second'] 1588 # model 1589 if self.second_model: 1590 data['mg_names'] = True 1591 if ' ' in self.second_model: 1592 args = self.second_model.split() 1593 if '--modelname' in args: 1594 data['mg_names'] = False 1595 data['model_name'] = args[0] 1596 else: 1597 data['model_name'] = self.second_model 1598 else: 1599 data['model_name'] = None 1600 #processes 1601 if self.second_process: 1602 data['processes'] = self.second_process 1603 else: 1604 data['processes'] = [line[9:].strip() for line in self.banner.proc_card 1605 if line.startswith('generate')] 1606 data['processes'] += [' '.join(line.split()[2:]) 1607 for line in self.banner.proc_card 1608 if re.search('^\s*add\s+process', line)] 1609 #object_collector 1610 #self.id_to_path_second = {} 1611 #data['id2path'] = self.id_to_path_second 1612 1613 # 0. clean previous run ------------------------------------------------ 1614 if not self.rwgt_dir: 1615 path_me = self.me_dir 1616 else: 1617 path_me = self.rwgt_dir 1618 data['path'] = path_me 1619 try: 1620 shutil.rmtree(pjoin(path_me,data['paths'][0])) 1621 except Exception: 1622 pass 1623 try: 1624 shutil.rmtree(pjoin(path_me, data['paths'][1])) 1625 except Exception: 1626 pass 1627 1628 # 1. prepare the interface---------------------------------------------- 1629 mgcmd = self.mg5cmd 1630 complex_mass = False 1631 has_cms = re.compile(r'''set\s+complex_mass_scheme\s*(True|T|1|true|$|;)''') 1632 for line in self.banner.proc_card: 1633 if line.startswith('set'): 1634 mgcmd.exec_cmd(line, printcmd=False, precmd=False, postcmd=False) 1635 if has_cms.search(line): 1636 complex_mass = True 1637 elif line.startswith('define'): 1638 try: 1639 mgcmd.exec_cmd(line, printcmd=False, precmd=False, postcmd=False) 1640 except Exception: 1641 pass 1642 1643 # 1. Load model--------------------------------------------------------- 1644 if not data['model_name'] and not second: 1645 raise self.InvalidCmd('Only UFO model can be loaded in this module.') 1646 elif data['model_name']: 1647 self.load_model(data['model_name'], data['mg_names'], complex_mass) 1648 modelpath = self.model.get('modelpath') 1649 if os.path.basename(modelpath) != mgcmd._curr_model['name']: 1650 name, restrict = mgcmd._curr_model['name'].rsplit('-',1) 1651 if os.path.exists(pjoin(os.path.dirname(modelpath),name, 'restrict_%s.dat' % restrict)): 1652 modelpath = pjoin(os.path.dirname(modelpath), mgcmd._curr_model['name']) 1653 1654 commandline="import model %s " % modelpath 1655 if not data['mg_names']: 1656 commandline += ' -modelname ' 1657 mgcmd.exec_cmd(commandline) 1658 1659 #multiparticles 1660 for name, content in self.banner.get('proc_card', 'multiparticles'): 1661 mgcmd.exec_cmd("define %s = %s" % (name, content)) 1662 1663 if second and 'tree_path' in self.dedicated_path: 1664 files.ln(self.dedicated_path['tree_path'], path_me,name=data['paths'][0]) 1665 if 'virtual_path' in self.dedicated_path: 1666 has_nlo=True 1667 else: 1668 has_nlo=False 1669 else: 1670 has_nlo = self.create_standalone_tree_directory(data, second) 1671 1672 1673 # 5. create the virtual for NLO reweighting --------------------------- 1674 if second and 'virtual_path' in self.dedicated_path: 1675 files.ln(self.dedicated_path['virtual_path'], path_me, name=data['paths'][1]) 1676 elif has_nlo and 'NLO' in self.rwgt_mode: 1677 self.create_standalone_virt_directory(data, second) 1678 1679 if False:#not second: 1680 #compile the module to combine the weight 1681 misc.compile(cwd=pjoin(path_me, data['paths'][1], 'Source')) 1682 #link it 1683 if path_me not in sys.path: 1684 sys.path.insert(0, os.path.realpath(path_me)) 1685 with misc.chdir(pjoin(path_me)): 1686 mymod = __import__('%s.Source.rwgt2py' % data['paths'][1], globals(), locals(), []) 1687 mymod = mymod.Source.rwgt2py 1688 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1689 mymod.initialise([self.banner.run_card['lpp1'], 1690 self.banner.run_card['lpp2']], 1691 self.banner.run_card.get_lhapdf_id()) 1692 self.combine_wgt = mymod.get_wgt 1693 1694 if self.multicore == 'create': 1695 print("compile OLP", data['paths'][1]) 1696 try: 1697 misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][1],'SubProcesses'), 1698 nb_core=self.mother.options['nb_core']) 1699 except: 1700 misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][1],'SubProcesses'), 1701 nb_core=1) 1702 elif has_nlo and not second and self.rwgt_mode == ['NLO_tree']: 1703 # We do not have any virtual reweighting to do but we still have to 1704 #combine the weights. 1705 #Idea:create a fake directory. 1706 start = time.time() 1707 commandline='import model loop_sm;generate g g > e+ ve [virt=QCD]' 1708 # deactivate golem since it creates troubles 1709 old_options = dict(mgcmd.options) 1710 mgcmd.options['golem'] = None 1711 commandline = commandline.replace('add process', 'generate',1) 1712 logger.info(commandline) 1713 mgcmd.exec_cmd(commandline, precmd=True) 1714 commandline = 'output standalone_rw %s --prefix=int -f' % pjoin(path_me, data['paths'][1]) 1715 mgcmd.exec_cmd(commandline, precmd=True) 1716 #put back golem to original value 1717 mgcmd.options['golem'] = old_options['golem'] 1718 # update make_opts 1719 if not mgcmd.options['lhapdf']: 1720 raise Exception("NLO_tree reweighting requires LHAPDF to work correctly") 1721 1722 # Download LHAPDF SET 1723 common_run_interface.CommonRunCmd.install_lhapdf_pdfset_static(\ 1724 mgcmd.options['lhapdf'], None, self.banner.run_card.get_lhapdf_id()) 1725 1726 #compile the module to combine the weight 1727 if False: 1728 #use python module instead 1729 misc.compile(cwd=pjoin(path_me, data['paths'][1], 'Source')) 1730 #link it 1731 with misc.chdir(pjoin(path_me)): 1732 if path_me not in sys.path: 1733 sys.path.insert(0, path_me) 1734 mymod = __import__('%s.Source.rwgt2py' % data['paths'][1], globals(), locals(), [],-1) 1735 mymod = mymod.Source.rwgt2py 1736 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1737 mymod.initialise([self.banner.run_card['lpp1'], 1738 self.banner.run_card['lpp2']], 1739 self.banner.run_card.get_lhapdf_id()) 1740 self.combine_wgt = mymod.get_wgt 1741 1742 1743 # 6. If we need a new model/process------------------------------------- 1744 if (self.second_model or self.second_process or self.dedicated_path) and not second : 1745 self.create_standalone_directory(second=True) 1746 1747 if not second: 1748 self.has_nlo = has_nlo
1749 1750 1751
1752 - def compile(self):
1753 """compile the code""" 1754 1755 if self.multicore=='wait': 1756 return 1757 1758 if not self.rwgt_dir: 1759 path_me = self.me_dir 1760 else: 1761 path_me = self.rwgt_dir 1762 for onedir in self.rwgt_dir_possibility: 1763 if not os.path.isdir(pjoin(path_me,onedir)): 1764 continue 1765 pdir = pjoin(path_me, onedir, 'SubProcesses') 1766 if self.mother: 1767 nb_core = self.mother.options['nb_core'] if self.mother.options['run_mode'] !=0 else 1 1768 else: 1769 nb_core = 1 1770 os.environ['MENUM'] = '2' 1771 misc.compile(['allmatrix2py.so'], cwd=pdir, nb_core=nb_core) 1772 if not (self.second_model or self.second_process or self.dedicated_path): 1773 os.environ['MENUM'] = '3' 1774 misc.compile(['allmatrix3py.so'], cwd=pdir, nb_core=nb_core)
1775
1776 - def load_module(self, metag=1):
1777 """load the various module and load the associate information""" 1778 1779 if not self.rwgt_dir: 1780 path_me = self.me_dir 1781 else: 1782 path_me = self.rwgt_dir 1783 1784 self.id_to_path = {} 1785 self.id_to_path_second = {} 1786 for onedir in self.rwgt_dir_possibility: 1787 if not os.path.exists(pjoin(path_me,onedir)): 1788 continue 1789 pdir = pjoin(path_me, onedir, 'SubProcesses') 1790 for tag in [2*metag,2*metag+1]: 1791 with misc.TMP_variable(sys, 'path', [pjoin(path_me)]+sys.path): 1792 mod_name = '%s.SubProcesses.allmatrix%spy' % (onedir, tag) 1793 #mymod = __import__('%s.SubProcesses.allmatrix%spy' % (onedir, tag), globals(), locals(), [],-1) 1794 if mod_name in list(sys.modules.keys()): 1795 del sys.modules[mod_name] 1796 tmp_mod_name = mod_name 1797 while '.' in tmp_mod_name: 1798 tmp_mod_name = tmp_mod_name.rsplit('.',1)[0] 1799 del sys.modules[tmp_mod_name] 1800 if True:#six.PY3: 1801 mymod = __import__(mod_name, globals(), locals(), []) 1802 else: 1803 mymod = __import__(mod_name, globals(), locals(), [],-1) 1804 else: 1805 if True:#six.PY3: 1806 mymod = __import__(mod_name, globals(), locals(), []) 1807 else: 1808 mymod = __import__(mod_name, globals(), locals(), [],-1) 1809 S = mymod.SubProcesses 1810 mymod = getattr(S, 'allmatrix%spy' % tag) 1811 1812 # Param card not available -> no initialisation 1813 self.f2pylib[(onedir,tag)] = mymod 1814 if hasattr(mymod, 'set_madloop_path'): 1815 mymod.set_madloop_path(pjoin(path_me,onedir,'SubProcesses','MadLoop5_resources')) 1816 if (self.second_model or self.second_process or self.dedicated_path): 1817 break 1818 1819 data = self.id_to_path 1820 if '_second' in onedir: 1821 data = self.id_to_path_second 1822 1823 # get all the information 1824 allids, all_pids = mymod.get_pdg_order() 1825 all_pdgs = [[pdg for pdg in pdgs if pdg!=0] for pdgs in allids] 1826 all_prefix = [''.join([i.decode() for i in j]).strip().lower() for j in mymod.get_prefix()] 1827 prefix_set = set(all_prefix) 1828 1829 1830 hel_dict={} 1831 for prefix in prefix_set: 1832 if hasattr(mymod,'%sprocess_nhel' % prefix): 1833 nhel = getattr(mymod, '%sprocess_nhel' % prefix).nhel 1834 hel_dict[prefix] = {} 1835 for i, onehel in enumerate(zip(*nhel)): 1836 hel_dict[prefix][tuple(onehel)] = i+1 1837 elif hasattr(mymod, 'set_madloop_path') and \ 1838 os.path.exists(pjoin(path_me,onedir,'SubProcesses','MadLoop5_resources', '%sHelConfigs.dat' % prefix.upper())): 1839 hel_dict[prefix] = {} 1840 for i,line in enumerate(open(pjoin(path_me,onedir,'SubProcesses','MadLoop5_resources', '%sHelConfigs.dat' % prefix.upper()))): 1841 onehel = [int(h) for h in line.split()] 1842 hel_dict[prefix][tuple(onehel)] = i+1 1843 else: 1844 misc.sprint(pjoin(path_me,onedir,'SubProcesses','MadLoop5_resources', '%sHelConfigs.dat' % prefix.upper() )) 1845 misc.sprint(os.path.exists(pjoin(path_me,onedir,'SubProcesses','MadLoop5_resources', '%sHelConfigs.dat' % prefix.upper()))) 1846 continue 1847 1848 for i,(pdg,pid) in enumerate(zip(all_pdgs,all_pids)): 1849 if self.is_decay: 1850 incoming = [pdg[0]] 1851 outgoing = pdg[1:] 1852 else: 1853 incoming = pdg[0:2] 1854 outgoing = pdg[2:] 1855 order = (list(incoming), list(outgoing)) 1856 incoming.sort() 1857 if not self.keep_ordering: 1858 outgoing.sort() 1859 tag = (tuple(incoming), tuple(outgoing)) 1860 if 'virt' in onedir: 1861 tag = (tag, 'V') 1862 prefix = all_prefix[i] 1863 if prefix in hel_dict: 1864 hel = hel_dict[prefix] 1865 else: 1866 hel = {} 1867 if tag in data: 1868 oldpdg = data[tag][0][0]+data[tag][0][1] 1869 if all_prefix[all_pdgs.index(pdg)] == all_prefix[all_pdgs.index(oldpdg)]: 1870 for i in range(len(pdg)): 1871 if pdg[i] == oldpdg[i]: 1872 continue 1873 if not self.model or not hasattr(self.model, 'get_mass'): 1874 continue 1875 if self.model.get_mass(int(pdg[i])) == self.model.get_mass(int(oldpdg[i])): 1876 continue 1877 misc.sprint(tag, onedir) 1878 misc.sprint(data[tag][:-1]) 1879 misc.sprint(order, pdir,) 1880 raise Exception 1881 else: 1882 misc.sprint(all_prefix[all_pdgs.index(pdg)]) 1883 misc.sprint(all_prefix[all_pdgs.index(oldpdg)]) 1884 misc.sprint(tag, onedir) 1885 misc.sprint(data[tag][:-1]) 1886 misc.sprint(order, pdir,) 1887 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'." ) 1888 1889 data[tag] = order, pdir, hel
1890 1891
1892 - def load_model(self, name, use_mg_default, complex_mass=False):
1893 """load the model""" 1894 1895 loop = False 1896 1897 logger.info('detected model: %s. Loading...' % name) 1898 model_path = name 1899 1900 # Import model 1901 base_model = import_ufo.import_model(name, decay=False, 1902 complex_mass_scheme=complex_mass) 1903 1904 if use_mg_default: 1905 base_model.pass_particles_name_in_mg_default() 1906 1907 self.model = base_model 1908 self.mg5cmd._curr_model = self.model 1909 self.mg5cmd.process_model()
1910 1911
1912 - def save_to_pickle(self):
1913 import madgraph.iolibs.save_load_object as save_load_object 1914 1915 to_save = {} 1916 to_save['id_to_path'] = self.id_to_path 1917 if hasattr(self, 'id_to_path_second'): 1918 to_save['id_to_path_second'] = self.id_to_path_second 1919 else: 1920 to_save['id_to_path_second'] = {} 1921 to_save['all_cross_section'] = self.all_cross_section 1922 to_save['processes'] = self.processes 1923 to_save['second_process'] = self.second_process 1924 if self.second_model: 1925 to_save['second_model'] =True 1926 else: 1927 to_save['second_model'] = None 1928 to_save['rwgt_dir'] = self.rwgt_dir 1929 to_save['has_nlo'] = self.has_nlo 1930 to_save['rwgt_mode'] = self.rwgt_mode 1931 to_save['rwgt_name'] = self.options['rwgt_name'] 1932 to_save['allow_missing_finalstate'] = self.options['allow_missing_finalstate'] 1933 1934 name = pjoin(self.rwgt_dir, 'rw_me', 'rwgt.pkl') 1935 save_load_object.save_to_file(name, to_save)
1936 1937
1938 - def load_from_pickle(self, keep_name=False):
1939 import madgraph.iolibs.save_load_object as save_load_object 1940 1941 obj = save_load_object.load_from_file( pjoin(self.rwgt_dir, 'rw_me', 'rwgt.pkl')) 1942 1943 self.has_standalone_dir = True 1944 self.options = {'curr_dir': os.path.realpath(os.getcwd()), 1945 'rwgt_name': None} 1946 if keep_name: 1947 self.options['rwgt_name'] = obj['rwgt_name'] 1948 self.options['allow_missing_finalstate'] = obj['allow_missing_finalstate'] 1949 old_rwgt = obj['rwgt_dir'] 1950 1951 # path to fortran executable 1952 self.id_to_path = {} 1953 for key , (order, Pdir, hel_dict) in obj['id_to_path'].items(): 1954 new_P = Pdir.replace(old_rwgt, self.rwgt_dir) 1955 self.id_to_path[key] = [order, new_P, hel_dict] 1956 1957 # path to fortran executable (for second directory) 1958 self.id_to_path_second = {} 1959 for key , (order, Pdir, hel_dict) in obj['id_to_path_second'].items(): 1960 new_P = Pdir.replace(old_rwgt, self.rwgt_dir) 1961 self.id_to_path_second[key] = [order, new_P, hel_dict] 1962 1963 self.all_cross_section = obj['all_cross_section'] 1964 self.processes = obj['processes'] 1965 self.second_process = obj['second_process'] 1966 self.second_model = obj['second_model'] 1967 self.has_nlo = obj['has_nlo'] 1968 if not self.rwgt_mode: 1969 self.rwgt_mode = obj['rwgt_mode'] 1970 logger.info("mode set to %s" % self.rwgt_mode) 1971 if False:#self.has_nlo and 'NLO' in self.rwgt_mode: 1972 #use python version 1973 path = pjoin(obj['rwgt_dir'], 'rw_mevirt','Source') 1974 sys.path.insert(0, path) 1975 try: 1976 mymod = __import__('rwgt2py', globals(), locals()) 1977 except ImportError: 1978 misc.compile(['rwgt2py.so'], cwd=path) 1979 mymod = __import__('rwgt2py', globals(), locals()) 1980 with misc.stdchannel_redirected(sys.stdout, os.devnull): 1981 mymod.initialise([self.banner.run_card['lpp1'], 1982 self.banner.run_card['lpp2']], 1983 self.banner.run_card.get_lhapdf_id()) 1984 self.combine_wgt = mymod.get_wgt
1985