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