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