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