1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """ Command interface for MadSpin """
16 from __future__ import division
17 import difflib
18 import logging
19 import math
20 import os
21 import re
22 import shutil
23 import sys
24 import tempfile
25 import time
26 import subprocess
27 from subprocess import Popen, PIPE, STDOUT
28
29
30 pjoin = os.path.join
31
32 import madgraph.interface.extended_cmd as extended_cmd
33 import madgraph.interface.madgraph_interface as mg_interface
34 import madgraph.interface.master_interface as master_interface
35 import madgraph.interface.common_run_interface as common_run_interface
36 import madgraph.interface.madevent_interface as madevent_interface
37 import madgraph.iolibs.files as files
38 import MadSpin.interface_madspin as madspin_interface
39 import madgraph.various.misc as misc
40 import madgraph.various.banner as banner
41 import madgraph.various.lhe_parser as lhe_parser
42 import madgraph.various.combine_plots as combine_plots
43 import madgraph.various.cluster as cluster
44 import madgraph.fks.fks_common as fks_common
45 import madgraph.core.diagram_generation as diagram_generation
46
47 import models.import_ufo as import_ufo
48 import models.check_param_card as check_param_card
49 import MadSpin.decay as madspin
50
51
52 logger = logging.getLogger('decay.stdout')
53 logger_stderr = logging.getLogger('decay.stderr')
54 cmd_logger = logging.getLogger('cmdprint2')
55
56
57 dir_to_f2py_free_mod = {}
58 nb_f2py_module = 0
65 """Basic interface for reweighting operation"""
66
67 prompt = 'Reweight>'
68 debug_output = 'Reweight_debug'
69
70 @misc.mute_logger()
71 - def __init__(self, event_path=None, allow_madspin=False, mother=None, *completekey, **stdin):
72 """initialize the interface with potentially an event_path"""
73
74 if not event_path:
75 cmd_logger.info('************************************************************')
76 cmd_logger.info('* *')
77 cmd_logger.info('* Welcome to Reweight Module *')
78 cmd_logger.info('* *')
79 cmd_logger.info('************************************************************')
80 extended_cmd.Cmd.__init__(self, *completekey, **stdin)
81
82 self.model = None
83 self.has_standalone_dir = False
84 self.mother= mother
85 self.multicore=False
86
87 self.options = {'curr_dir': os.path.realpath(os.getcwd()),
88 'rwgt_name':None}
89
90 self.events_file = None
91 self.processes = {}
92 self.second_model = None
93 self.second_process = None
94 self.mg5cmd = master_interface.MasterCmd()
95 if mother:
96 self.mg5cmd.options.update(mother.options)
97 self.seed = None
98 self.output_type = "default"
99 self.helicity_reweighting = True
100 self.rwgt_mode = ''
101 self.has_nlo = False
102 self.rwgt_dir = None
103 self.exitted = False
104
105 if event_path:
106 logger.info("Extracting the banner ...")
107 self.do_import(event_path, allow_madspin=allow_madspin)
108
109
110 self.calculator = {}
111 self.calculator_nbcall = {}
112
113
114 self.all_cross_section = {}
115
116 - def do_import(self, inputfile, allow_madspin=False):
117 """import the event file"""
118
119 args = self.split_arg(inputfile)
120 if not args:
121 return self.InvalidCmd, 'import requires arguments'
122
123
124 self.options['curr_dir'] = os.path.realpath(os.path.dirname(inputfile))
125 if os.path.basename(os.path.dirname(os.path.dirname(inputfile))) == 'Events':
126 self.options['curr_dir'] = pjoin(self.options['curr_dir'],
127 os.path.pardir, os.pardir)
128
129
130 if not os.path.exists(inputfile):
131 if inputfile.endswith('.gz'):
132 if not os.path.exists(inputfile[:-3]):
133 raise self.InvalidCmd('No such file or directory : %s' % inputfile)
134 else:
135 inputfile = inputfile[:-3]
136 elif os.path.exists(inputfile + '.gz'):
137 inputfile = inputfile + '.gz'
138 else:
139 raise self.InvalidCmd('No such file or directory : %s' % inputfile)
140
141 if inputfile.endswith('.gz'):
142 misc.gunzip(inputfile)
143 inputfile = inputfile[:-3]
144
145
146 self.lhe_input = lhe_parser.EventFile(os.path.realpath(inputfile))
147 if not self.lhe_input.banner:
148 value = self.ask("What is the path to banner", 0, [0], "please enter a path", timeout=0)
149 self.lhe_input.banner = open(value).read()
150 self.banner = self.lhe_input.get_banner()
151
152
153 if 'init' not in self.banner:
154 self.orig_cross = (0,0)
155
156 else:
157 for line in self.banner['init'].split('\n'):
158 split = line.split()
159 if len(split) == 4:
160 cross, error = float(split[0]), float(split[1])
161 self.orig_cross = (cross, error)
162
163
164
165
166 if 'slha' not in self.banner:
167 self.events_file = None
168 raise self.InvalidCmd('Event file does not contain model information')
169 elif 'mg5proccard' not in self.banner:
170 self.events_file = None
171 raise self.InvalidCmd('Event file does not contain generation information')
172
173 if 'madspin' in self.banner and not allow_madspin:
174 raise self.InvalidCmd('Reweight should be done before running MadSpin')
175
176
177
178 process = self.banner.get_detail('proc_card', 'generate')
179 if '[' in process and isinstance(self.banner.get('run_card'), banner.RunCardNLO):
180 if not self.banner.get_detail('run_card', 'store_rwgt_info'):
181 logger.warning("The information to perform a proper NLO reweighting is not present in the event file.")
182 logger.warning(" We will perform a LO reweighting instead. This does not guarantee NLO precision.")
183 self.rwgt_mode = 'LO'
184
185 if 'OLP' in self.mother.options:
186 if self.mother.options['OLP'].lower() != 'madloop':
187 logger.warning("Accurate NLO mode only works for OLP=MadLoop not for OLP=%s. An approximate (LO) reweighting will be performed instead")
188 self.rwgt_mode = 'LO'
189
190 if 'lhapdf' in self.mother.options and not self.mother.options['lhapdf']:
191 logger.warning('NLO accurate reweighting requires lhapdf to be installed. Pass in approximate LO mode.')
192 self.rwgt_mode = 'LO'
193 else:
194 self.rwgt_mode = 'LO'
195
196 if not process:
197 msg = 'Invalid proc_card information in the file (no generate line):\n %s' % self.banner['mg5proccard']
198 raise Exception, msg
199 process, option = mg_interface.MadGraphCmd.split_process_line(process)
200 self.proc_option = option
201
202 logger.info("process: %s" % process)
203 logger.info("options: %s" % option)
204
205
207 """return the LO definitions of the process corresponding to the born/real"""
208
209
210 process, order, final = re.split('\[\s*(.*)\s*\]', proc)
211
212 commandline="add process %s %s --no_warning=duplicate;" % (process, final)
213 if not order:
214
215 return proc
216 elif not order.startswith(('virt','loonly','noborn')):
217
218 if real_only:
219 commandline= ''
220
221 if '=' in order:
222
223 order = order.split('=',1)[1]
224
225
226 pert = fks_common.find_pert_particles_interactions(self.model,
227 pert_order = order)['soft_particles']
228 commandline += "define pert_%s = %s;" % (order.replace(' ',''), ' '.join(map(str,pert)) )
229
230
231 if '%s=' % order in process:
232 result=re.split(' ',process)
233 process=''
234 for r in result:
235 if '%s=' % order in r:
236 ior=re.split('=',r)
237 r='QCD=%i' % (int(ior[1])+1)
238 process=process+r+' '
239
240 result = re.split('([/$@]|\w+(?:^2)?(?:=|<=|>)?\w+)', process, 1)
241 if len(result) ==3:
242 process, split, rest = result
243 commandline+="add process %s pert_%s %s%s %s --no_warning=duplicate;" % (process, order.replace(' ','') ,split, rest, final)
244 else:
245 commandline +='add process %s pert_%s %s --no_warning=duplicate;' % (process,order.replace(' ',''), final)
246 elif order.startswith(('noborn=')):
247
248 return "add process %s ;" % proc.replace('noborn=', 'sqrvirt=')
249
250 else:
251
252 return "add process %s ;" % proc
253 return commandline
254
255
257 """Check some basic property of the events file"""
258
259 sum_of_weight = 0
260 sum_of_abs_weight = 0
261 negative_event = 0
262 positive_event = 0
263
264 start = time.time()
265 for event_nb,event in enumerate(self.lhe_input):
266
267 if (event_nb % max(int(10**int(math.log10(float(event_nb)+1))),10)==0):
268 running_time = misc.format_timer(time.time()-start)
269 logger.info('Event nb %s %s' % (event_nb, running_time))
270 if (event_nb==10001): logger.info('reducing number of print status. Next status update in 10000 events')
271
272 try:
273 event.check()
274 except Exception, error:
275 print event
276 raise error
277 sum_of_weight += event.wgt
278 sum_of_abs_weight += abs(event.wgt)
279 if event.wgt < 0 :
280 negative_event +=1
281 else:
282 positive_event +=1
283
284 logger.info("total cross-section: %s" % sum_of_weight)
285 logger.info("total abs cross-section: %s" % sum_of_abs_weight)
286 logger.info("fraction of negative event %s", negative_event/(negative_event+positive_event))
287 logger.info("total number of events %s", (negative_event+positive_event))
288 logger.info("negative event %s", negative_event)
289
290
291
292
293 @extended_cmd.debug()
295 "Complete the import command"
296
297 args=self.split_arg(line[0:begidx])
298
299 if len(args) == 1:
300 base_dir = '.'
301 else:
302 base_dir = args[1]
303
304 return self.path_completion(text, base_dir)
305
306
307 if os.path.sep in args[-1] + text:
308 return self.path_completion(text,
309 pjoin(*[a for a in args if \
310 a.endswith(os.path.sep)]))
311
313 """help for change command"""
314
315 print "change model X :use model X for the reweighting"
316 print "change process p p > e+ e-: use a new process for the reweighting"
317 print "change process p p > mu+ mu- --add : add one new process to existing ones"
318
320 """allow to define a second model/processes"""
321
322 global nb_f2py_module
323
324 args = self.split_arg(line)
325 if len(args)<2:
326 logger.critical("not enough argument (need at least two). Discard line")
327 if args[0] == "model":
328 nb_f2py_module += 1
329 self.second_model = " ".join(args[1:])
330 if self.has_standalone_dir:
331 self.terminate_fortran_executables()
332 self.has_standalone_dir = False
333 elif args[0] == "process":
334 nb_f2py_module += 1
335 if self.has_standalone_dir:
336 self.terminate_fortran_executables()
337 self.has_standalone_dir = False
338 if args[-1] == "--add":
339 self.second_process.append(" ".join(args[1:-1]))
340 else:
341 self.second_process = [" ".join(args[1:])]
342 elif args[0] == "output":
343 if args[1] in ['default', '2.0', 'unweight']:
344 self.output_type = args[1]
345 elif args[0] == "helicity":
346 self.helicity_reweighting = banner.ConfigFile.format_variable(args[1], bool, "helicity")
347 elif args[0] == "mode":
348 if args[1] != 'LO':
349 if 'OLP' in self.mother.options and self.mother.options['OLP'].lower() != 'madloop':
350 logger.warning("Only LO reweighting is allowed for OLP!=MadLoop. Keeping the mode to LO.")
351 self.rwgt_mode = 'LO'
352 elif not self.banner.get_detail('run_card','store_rwgt_info', default=False):
353 logger.warning("Missing information for NLO type of reweighting. Keeping the mode to LO.")
354 self.rwgt_mode = 'LO'
355 elif 'lhapdf' in self.mother.options and not self.mother.options['lhapdf']:
356 logger.warning('NLO accurate reweighting requires lhapdf to be installed. Pass in approximate LO mode.')
357 self.rwgt_mode = 'LO'
358 else:
359 self.rwgt_mode = args[1]
360 else:
361 self.rwgt_mode = args[1]
362 elif args[0] == "rwgt_dir":
363 self.rwgt_dir = args[1]
364 if not os.path.exists(self.rwgt_dir):
365 os.mkdir(self.rwgt_dir)
366 elif args[0] == 'multicore':
367 pass
368
369
370 else:
371 logger.critical("unknown option! %s. Discard line." % args[0])
372
373
375 """check the validity of the launch command"""
376
377 if not self.lhe_input:
378 if isinstance(self.lhe_input, lhe_parser.EventFile):
379 self.lhe_input = lhe_parser.EventFile(self.lhe_input.name)
380 else:
381 raise self.InvalidCmd("No events files defined.")
382
383 opts = {'rwgt_name':None}
384 if any(a.startswith('--') for a in args):
385 for a in args[:]:
386 if a.startswith('--') and '=' in a:
387 key,value = a[2:].split('=')
388 opts[key] = value .replace("'","") .replace('"','')
389 return opts
390
392 """help for the launch command"""
393
394 logger.info('''Add to the loaded events a weight associated to a
395 new param_card (to be define). The weight returned is the ratio of the
396 square matrix element by the squared matrix element of production.
397 All scale are kept fix for this re-weighting.''')
398
399
401 """ return the various name for the computed weights """
402
403 if self.rwgt_mode == 'LO':
404 return ['']
405 elif self.rwgt_mode == 'NLO':
406 return ['_nlo']
407 elif self.rwgt_mode == 'LO+NLO':
408 return ['_lo', '_nlo']
409 elif self.rwgt_mode == 'NLO_tree':
410 return ['_tree']
411 elif not self.rwgt_mode and self.has_nlo :
412 return ['_nlo']
413 else:
414 return ['']
415
416 @misc.mute_logger()
418 """end of the configuration launched the code"""
419
420 args = self.split_arg(line)
421 opts = self.check_launch(args)
422 if opts['rwgt_name']:
423 self.options['rwgt_name'] = opts['rwgt_name']
424
425 model_line = self.banner.get('proc_card', 'full_model_line')
426
427 if not self.has_standalone_dir:
428 if self.rwgt_dir and os.path.exists(pjoin(self.rwgt_dir,'rw_me','rwgt.pkl')):
429 self.load_from_pickle()
430 if not self.rwgt_dir:
431 self.me_dir = self.rwgt_dir
432 elif self.multicore == 'wait':
433 while not os.path.exists(pjoin(self.me_dir,'rw_me','rwgt.pkl')):
434 time.sleep(60)
435 print 'wait for pickle'
436 print "loading from pickle"
437 if not self.rwgt_dir:
438 self.rwgt_dir = self.me_dir
439 self.load_from_pickle(keep_name=True)
440 else:
441 self.create_standalone_directory()
442 if self.multicore == 'create':
443 if not self.rwgt_dir:
444 self.rwgt_dir = self.me_dir
445 self.save_to_pickle()
446
447 if self.rwgt_dir:
448 path_me =self.rwgt_dir
449 else:
450 path_me = self.me_dir
451
452 if self.second_model or self.second_process:
453 rw_dir = pjoin(path_me, 'rw_me_second')
454 else:
455 rw_dir = pjoin(path_me, 'rw_me')
456
457 if not '--keep_card' in args:
458 ff = open(pjoin(rw_dir,'Cards', 'param_card.dat'), 'w')
459 ff.write(self.banner['slha'])
460 ff.close()
461 if self.has_nlo and self.rwgt_mode != "LO":
462 rwdir_virt = rw_dir.replace('rw_me', 'rw_mevirt')
463 files.ln(ff.name, starting_dir=pjoin(rwdir_virt, 'Cards'))
464 ff = open(pjoin(path_me, 'rw_me','Cards', 'param_card_orig.dat'), 'w')
465 ff.write(self.banner['slha'])
466 ff.close()
467 if self.has_nlo and self.rwgt_mode != "LO":
468 files.ln(ff.name, starting_dir=pjoin(path_me, 'rw_mevirt', 'Cards'))
469 cmd = common_run_interface.CommonRunCmd.ask_edit_card_static(cards=['param_card.dat'],
470 ask=self.ask, pwd=rw_dir, first_cmd=self.stored_line)
471 self.stored_line = None
472
473
474 type_rwgt = self.get_weight_names()
475
476
477 new_card = open(pjoin(rw_dir, 'Cards', 'param_card.dat')).read()
478 pattern_scan = re.compile(r'''^[\s\d]*scan''', re.I+re.M)
479 param_card_iterator = []
480 if pattern_scan.search(new_card):
481 try:
482 import internal.extended_cmd as extended_internal
483 Shell_internal = extended_internal.CmdShell
484 except:
485 Shell_internal = None
486 import madgraph.interface.extended_cmd as extended_cmd
487 if not isinstance(self.mother, (extended_cmd.CmdShell, Shell_internal)):
488 raise Exception, "scan are not allowed on the Web"
489
490 main_card = check_param_card.ParamCardIterator(new_card)
491 if self.options['rwgt_name']:
492 self.options['rwgt_name'] = '%s_0' % self.options['rwgt_name']
493
494 param_card_iterator = main_card
495 first_card = param_card_iterator.next(autostart=True)
496 new_card = first_card.write()
497 first_card.write(pjoin(rw_dir, 'Cards', 'param_card.dat'))
498
499 if "auto" in new_card.lower():
500 self.mother.check_param_card(pjoin(rw_dir, 'Cards', 'param_card.dat'))
501 new_card = open(pjoin(rw_dir, 'Cards', 'param_card.dat')).read()
502
503
504
505 if 'initrwgt' in self.banner:
506 if 'name=\'mg_reweighting\'' in self.banner['initrwgt']:
507 blockpat = re.compile(r'''<weightgroup name=\'mg_reweighting\'\s*>(?P<text>.*?)</weightgroup>''', re.I+re.M+re.S)
508 before, content, after = blockpat.split(self.banner['initrwgt'])
509 header_rwgt_other = before + after
510 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)
511 mg_rwgt_info = pattern.findall(content)
512
513 maxid = 0
514 for k,(i, fulltag, nlotype, diff) in enumerate(mg_rwgt_info):
515 if i:
516 if int(i) > maxid:
517 maxid = int(i)
518 mg_rwgt_info[k] = (i, nlotype, diff)
519 else:
520 mg_rwgt_info[k] = (fulltag, nlotype, diff)
521
522 maxid += 1
523 rewgtid = maxid
524 if self.options['rwgt_name']:
525
526 for (i, nlotype, diff) in mg_rwgt_info[:]:
527 for flag in type_rwgt:
528 if 'rwgt_%s' % i == '%s%s' %(self.options['rwgt_name'],flag) or \
529 i == '%s%s' % (self.options['rwgt_name'], flag):
530 logger.warning("tag %s%s already defines, will replace it", self.options['rwgt_name'],flag)
531 mg_rwgt_info.remove((i, nlotype, diff))
532
533 else:
534 header_rwgt_other = self.banner['initrwgt']
535 mg_rwgt_info = []
536 rewgtid = 1
537 else:
538 self.banner['initrwgt'] = ''
539 header_rwgt_other = ''
540 mg_rwgt_info = []
541 rewgtid = 1
542
543
544
545 s_orig = self.banner['slha']
546 s_new = new_card
547
548
549 if self.options['rwgt_name']:
550 tag = self.options['rwgt_name']
551 else:
552 tag = str(rewgtid)
553
554 if not self.second_model:
555 old_param = check_param_card.ParamCard(s_orig.splitlines())
556 new_param = check_param_card.ParamCard(s_new.splitlines())
557 card_diff = old_param.create_diff(new_param)
558 if card_diff == '' and not self.second_process:
559 if not __debug__:
560 logger.warning(' REWEIGHTING: original card and new card are identical. Bypass this run')
561 return
562 else:
563 logger.warning(' REWEIGHTING: original card and new card are identical. Run it due to debug mode')
564
565 try:
566 if old_param['sminputs'].get(3)- new_param['sminputs'].get(3) > 1e-3 * new_param['sminputs'].get(3):
567 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.")
568 except Exception, error:
569 logger.debug("error in check of alphas: %s" % str(error))
570 pass
571 if not self.second_process:
572 for name in type_rwgt:
573 mg_rwgt_info.append((tag, name, card_diff))
574 else:
575 str_proc = "\n change process ".join([""]+self.second_process)
576 for name in type_rwgt:
577 mg_rwgt_info.append((tag, name, str_proc + '\n'+ card_diff))
578 else:
579 str_info = "change model %s" % self.second_model
580 if self.second_process:
581 str_info += "\n change process ".join([""]+self.second_process)
582 card_diff = str_info
583 str_info += '\n' + s_new
584 for name in type_rwgt:
585 mg_rwgt_info.append((tag, name, str_info))
586
587 self.banner['initrwgt'] = header_rwgt_other
588 self.banner['initrwgt'] += '\n<weightgroup name=\'mg_reweighting\'>\n'
589 for tag, rwgttype, diff in mg_rwgt_info:
590 if tag.isdigit():
591 self.banner['initrwgt'] += '<weight id=\'rwgt_%s%s\'>%s</weight>\n' % \
592 (tag, rwgttype, diff)
593 else:
594 self.banner['initrwgt'] += '<weight id=\'%s%s\'>%s</weight>\n' % \
595 (tag, rwgttype, diff)
596 self.banner['initrwgt'] += '\n</weightgroup>\n'
597 self.banner['initrwgt'] = self.banner['initrwgt'].replace('\n\n', '\n')
598
599
600 start = time.time()
601 cross, ratio, ratio_square,error = {},{},{}, {}
602 for name in type_rwgt + ['orig']:
603 cross[name], error[name] = 0.,0.
604 ratio[name],ratio_square[name] = 0., 0.
605
606 if self.output_type == "default":
607 output = open( self.lhe_input.name +'rw', 'w')
608
609 self.banner.write(output, close_tag=False)
610 else:
611 output = {}
612 for name in type_rwgt:
613 output[name] = open( self.lhe_input.name +'rw'+name, 'w')
614
615 self.banner.write(output[name], close_tag=False)
616
617 logger.info('starts to compute weight for events with the following modification to the param_card:')
618 logger.info(card_diff.replace('\n','\nKEEP:'))
619
620 if self.mother:
621 out_path = pjoin(self.mother.me_dir, 'Events', 'reweight.lhe')
622 output2 = open(out_path, 'w')
623 lha_strategy = self.banner.get_lha_strategy()
624 self.banner.set_lha_strategy(4*lha_strategy/abs(lha_strategy))
625 self.banner.write(output2, close_tag=False)
626 self.banner.set_lha_strategy(lha_strategy)
627 new_banner = banner.Banner(self.banner)
628 if not hasattr(self, 'run_card'):
629 self.run_card = new_banner.charge_card('run_card')
630 self.run_card['run_tag'] = 'reweight_%s' % rewgtid
631 new_banner['slha'] = s_new
632 del new_banner['initrwgt']
633 assert 'initrwgt' in self.banner
634 ff = open(pjoin(self.mother.me_dir,'Events',self.mother.run_name, '%s_%s_banner.txt' % \
635 (self.mother.run_name, self.run_card['run_tag'])),'w')
636 new_banner.write(ff)
637 ff.close()
638
639
640 if self.options['rwgt_name']:
641 tag_name = self.options['rwgt_name']
642 else:
643 tag_name = 'rwgt_%s' % rewgtid
644
645 os.environ['GFORTRAN_UNBUFFERED_ALL'] = 'y'
646 if self.lhe_input.closed:
647 self.lhe_input = lhe_parser.EventFile(self.lhe_input.name)
648
649
650 nb_core = 1
651
652
653
654 self.lhe_input.seek(0)
655 for event_nb,event in enumerate(self.lhe_input):
656
657 if (event_nb % max(int(10**int(math.log10(float(event_nb)+1))),10)==0):
658 running_time = misc.format_timer(time.time()-start)
659 logger.info('Event nb %s %s' % (event_nb, running_time))
660 if (event_nb==10001): logger.info('reducing number of print status. Next status update in 10000 events')
661
662 if nb_core > 1:
663
664 while 1:
665 if multicore.queue.qsize() < 100 * nb_core:
666 multicore.submit(self.write_reweighted_event, argument=[event, tag_name])
667 break
668
669
670 continue
671 else:
672 weight = self.calculate_weight(event)
673 if not isinstance(weight, dict):
674 weight = {'':weight}
675
676 for name in weight:
677 cross[name] += weight[name]
678 ratio[name] += weight[name]/event.wgt
679 ratio_square[name] += (weight[name]/event.wgt)**2
680
681
682
683 for tag in type_rwgt:
684 try:
685 event.reweight_order.remove('%s%s' % (tag_name,tag))
686 except ValueError:
687 continue
688
689 event.reweight_order += ['%s%s' % (tag_name,name) for name in type_rwgt]
690 if self.output_type == "default":
691 for name in weight:
692 if 'orig' in name:
693 continue
694 event.reweight_data['%s%s' % (tag_name,name)] = weight[name]
695
696 output.write(str(event))
697 if self.mother:
698 event.wgt = weight[type_rwgt[0]]
699 event.reweight_data = {}
700 output2.write(str(event))
701 else:
702 for i,name in enumerate(weight):
703 event.wgt = weight[name]
704 event.reweight_data = {}
705 if self.mother and len(weight)==1:
706 output2.write(str(event))
707 elif self.mother and i == 0:
708 output[name].write(str(event))
709 output2.write(str(event))
710 else:
711 output[name].write(str(event))
712
713
714 if 'event_norm' in self.run_card:
715 if self.run_card['event_norm'] == 'average':
716 for key, value in cross.items():
717 cross[key] = value / (event_nb+1)
718
719 running_time = misc.format_timer(time.time()-start)
720 logger.info('All event done (nb_event: %s) %s' % (event_nb+1, running_time))
721
722
723 if self.output_type == "default":
724 output.write('</LesHouchesEvents>\n')
725 output.close()
726 else:
727 for key in output:
728 output[key].write('</LesHouchesEvents>\n')
729 output.close()
730
731 os.environ['GFORTRAN_UNBUFFERED_ALL'] = 'n'
732
733 if self.mother:
734 output2.write('</LesHouchesEvents>\n')
735 output2.close()
736
737 if hasattr(self.mother, 'results'):
738 run_name = self.mother.run_name
739 results = self.mother.results
740 results.add_run(run_name, self.run_card, current=True)
741 results.add_detail('nb_event', event_nb+1)
742 name = type_rwgt[0]
743 results.add_detail('cross', cross[name])
744 event_nb +=1
745 for name in type_rwgt:
746 variance = ratio_square[name]/event_nb - (ratio[name]/event_nb)**2
747 orig_cross, orig_error = self.orig_cross
748 error[name] = variance/math.sqrt(event_nb) * orig_cross + ratio[name]/event_nb * orig_error
749 results.add_detail('error', error[type_rwgt[0]])
750 import madgraph.interface.madevent_interface as ME_interface
751 if isinstance(self.mother, ME_interface.MadEventCmd):
752 self.mother.create_plot(mode='reweight', event_path=output2.name,
753 tag=self.run_card['run_tag'])
754
755 if 'plot' in results.current.reweight:
756 html_dir = pjoin(self.mother.me_dir, 'HTML', run_name)
757 td = pjoin(self.mother.options['td_path'], 'td')
758 MA = pjoin(self.mother.options['madanalysis_path'])
759 path1 = pjoin(html_dir, 'plots_parton')
760 path2 = pjoin(html_dir, 'plots_%s' % self.run_card['run_tag'])
761 outputplot = path2
762 combine_plots.merge_all_plots(path2, path1, outputplot, td, MA)
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777 self.lhe_input.close()
778 if not self.mother or self.output_type != "default" :
779 target = pjoin(self.mother.me_dir, 'Events', run_name, 'events.lhe')
780 else:
781 target = self.lhe_input.name
782
783 if self.output_type == "default":
784 files.mv(output.name, target)
785 logger.info('Event %s have now the additional weight' % self.lhe_input.name)
786 elif self.output_type == "unweight":
787 output2.close()
788 lhe = lhe_parser.EventFile(output2.name)
789 nb_event = lhe.unweight(target)
790 if self.mother and hasattr(self.mother, 'results'):
791 results = self.mother.results
792 results.add_detail('nb_event', nb_event)
793 results.current.parton.append('lhe')
794 logger.info('Event %s is now unweighted under the new theory' % output2.name)
795 else:
796 files.mv(output2.name, self.lhe_input.name)
797 if self.mother and hasattr(self.mother, 'results'):
798 results = self.mother.results
799 results.current.parton.append('lhe')
800 logger.info('Event %s is now created with new central weight' % output2.name)
801
802 if self.multicore != 'create':
803 for name in cross:
804 if name == 'orig':
805 continue
806 logger.info('new cross-section is %s: %g pb (indicative error: %g pb)' %\
807 ('(%s)' %name if name else '',cross[name], error[name]))
808
809 self.terminate_fortran_executables(new_card_only=True)
810
811 for name in cross:
812 if name == 'orig':
813 self.all_cross_section[name] = (cross[name], error[name])
814 else:
815 self.all_cross_section[(tag_name,name)] = (cross[name], error[name])
816
817
818 if param_card_iterator:
819 for i,card in enumerate(param_card_iterator):
820 if self.options['rwgt_name']:
821 self.options['rwgt_name'] = '%s_%s' % (self.options['rwgt_name'].rsplit('_',1)[0], i+1)
822 card.write(pjoin(rw_dir, 'Cards', 'param_card.dat'))
823 self.exec_cmd("launch --keep_card", printcmd=False, precmd=True)
824
825 self.options['rwgt_name'] = None
826
828 "Not in help"
829
830 logger.warning("Invalid Syntax. The command 'set' should be placed after the 'launch' one. Continuing by adding automatically 'launch'")
831 self.stored_line = "set %s" % line
832 return self.exec_cmd("launch")
833
834 - def default(self, line, log=True):
835 """Default action if line is not recognized"""
836
837 if os.path.isfile(line):
838 if log:
839 logger.warning("Invalid Syntax. The path to a param_card' should be placed after the 'launch' command. Continuing by adding automatically 'launch'")
840 self.stored_line = line
841 return self.exec_cmd("launch")
842 else:
843 return super(ReweightInterface,self).default(line, log=log)
844
846 """a function for running in multicore"""
847
848 if not hasattr(opt['thread_space'], "calculator"):
849 opt['thread_space'].calculator = {}
850 opt['thread_space'].calculator_nbcall = {}
851 opt['thread_space'].cross = 0
852 opt['thread_space'].output = open( self.lhe_input.name +'rw.%s' % opt['thread_id'], 'w')
853 if self.mother:
854 out_path = pjoin(self.mother.me_dir, 'Events', 'reweight.lhe.%s' % opt['thread_id'])
855 opt['thread_space'].output2 = open(out_path, 'w')
856
857 weight = self.calculate_weight(event, space=opt['thread_space'])
858 opt['thread_space'].cross += weight
859 if self.output_type == "default":
860 event.reweight_data[tag_name] = weight
861
862 opt['thread_space'].output.write(str(event))
863 if self.mother:
864 event.wgt = weight
865 event.reweight_data = {}
866 opt['thread_space'].output2.write(str(event))
867 else:
868 event.wgt = weight
869 event.reweight_data = {}
870 if self.mother:
871 opt['thread_space'].output2.write(str(event))
872 else:
873 opt['thread_space'].output.write(str(event))
874
875 return 0
876
879
881 """space defines where to find the calculator (in multicore)"""
882
883 if self.has_nlo and self.rwgt_mode != "LO":
884 return self.calculate_nlo_weight(event, space)
885
886 if not space:
887 space = self
888 event.parse_reweight()
889
890
891 w_orig = self.calculate_matrix_element(event, 0, space)
892 w_new = self.calculate_matrix_element(event, 1, space)
893
894 if w_orig == 0:
895 tag, order = event.get_tag_and_order()
896 orig_order, Pdir, hel_dict = self.id_to_path[tag]
897 misc.sprint(w_orig, w_new)
898 misc.sprint(event)
899 misc.sprint(self.invert_momenta(event.get_momenta(orig_order)))
900 misc.sprint(event.get_momenta(orig_order))
901 misc.sprint(event.aqcd)
902 hel_order = event.get_helicity(orig_order)
903 if self.helicity_reweighting and 9 not in hel_order:
904 nhel = hel_dict[tuple(hel_order)]
905 else:
906 nhel = 0
907 misc.sprint(nhel, Pdir, hel_dict)
908 raise Exception, "Invalid matrix element for original computation (weight=0)"
909
910 return {'orig': event.wgt, '': w_new/w_orig*event.wgt}
911
913
914
915 type_nlo = self.get_weight_names()
916 final_weight = {'orig': event.wgt}
917
918 if not space:
919 space = self
920
921 event.parse_reweight()
922 event.parse_nlo_weight()
923
924
925 scales2 = []
926 pdg = []
927 bjx = []
928 wgt_tree = []
929 wgt_virt = []
930 base_wgt = []
931 gs=[]
932 qcdpower = []
933 ref_wgts = []
934
935 orig_wgt = 0
936 for cevent in event.nloweight.cevents:
937
938 need_V = False
939 all_ctype = [w.type for w in cevent.wgts]
940 if '_nlo' in type_nlo and any(c in all_ctype for c in [2,14,15]):
941 need_V =True
942
943 w_orig = self.calculate_matrix_element(cevent, 0, space)
944 w_new = self.calculate_matrix_element(cevent, 1, space)
945 ratio_T = w_new/w_orig
946 if need_V:
947 scale2 = cevent.wgts[0].scales2[0]
948
949 w_origV = self.calculate_matrix_element(cevent, 'V0', space, scale2=scale2)
950 w_newV = self.calculate_matrix_element(cevent, 'V1', space, scale2=scale2)
951 ratio_BV = (w_newV + w_new) / (w_origV + w_orig)
952 ratio_V = w_newV/w_origV
953 else:
954 ratio_V = "should not be used"
955 ratio_BV = "should not be used"
956
957 for c_wgt in cevent.wgts:
958 orig_wgt += c_wgt.ref_wgt
959
960 scales2.append(c_wgt.scales2)
961 pdg.append(c_wgt.pdgs[:2])
962
963 bjx.append(c_wgt.bjks)
964 qcdpower.append(c_wgt.qcdpower)
965 gs.append(c_wgt.gs)
966 ref_wgts.append(c_wgt.ref_wgt)
967
968 if '_nlo' in type_nlo:
969 if c_wgt.type in [2,14,15]:
970 R = ratio_BV
971 else:
972 R = ratio_T
973
974 new_wgt = [c_wgt.pwgt[0] * R,
975 c_wgt.pwgt[1] * ratio_T,
976 c_wgt.pwgt[2] * ratio_T]
977 wgt_virt.append(new_wgt)
978
979 if '_tree' in type_nlo:
980 new_wgt = [c_wgt.pwgt[0] * ratio_T,
981 c_wgt.pwgt[1] * ratio_T,
982 c_wgt.pwgt[2] * ratio_T]
983 wgt_tree.append(new_wgt)
984 base_wgt.append(c_wgt.pwgt[:3])
985
986
987 scales2 = self.invert_momenta(scales2)
988 pdg = self.invert_momenta(pdg)
989 bjx = self.invert_momenta(bjx)
990
991 base_wgt = self.invert_momenta(base_wgt)
992
993 orig_wgt_check, partial_check = self.combine_wgt(scales2, pdg, bjx, base_wgt, gs, qcdpower, 1., 1.)
994
995 if '_nlo' in type_nlo:
996 wgt = self.invert_momenta(wgt_virt)
997 with misc.stdchannel_redirected(sys.stdout, os.devnull):
998 new_out, partial = self.combine_wgt(scales2, pdg, bjx, wgt, gs, qcdpower, 1., 1.)
999
1000 avg = [partial_check[i]/ref_wgts[i] for i in range(len(ref_wgts))]
1001 out = sum(partial[i]/avg[i] if 0.85<avg[i]<1.15 else 0 \
1002 for i in range(len(avg)))
1003 final_weight['_nlo'] = out/orig_wgt*event.wgt
1004
1005
1006 if '_tree' in type_nlo:
1007 wgt = self.invert_momenta(wgt_tree)
1008 with misc.stdchannel_redirected(sys.stdout, os.devnull):
1009 out, partial = self.combine_wgt(scales2, pdg, bjx, wgt, gs, qcdpower, 1., 1.)
1010
1011 avg = [partial_check[i]/ref_wgts[i] for i in range(len(ref_wgts))]
1012 new_out = sum(partial[i]/avg[i] if 0.85<avg[i]<1.15 else partial[i] \
1013 for i in range(len(avg)))
1014 final_weight['_tree'] = new_out/orig_wgt*event.wgt
1015
1016 if '_lo' in type_nlo:
1017 w_orig = self.calculate_matrix_element(event, 0, space)
1018 w_new = self.calculate_matrix_element(event, 1, space)
1019 final_weight['_lo'] = w_new/w_orig*event.wgt
1020
1021 return final_weight
1022
1023
1024 @staticmethod
1026 """ fortran/C-python do not order table in the same order"""
1027 new_p = []
1028 for i in range(len(p[0])): new_p.append([0]*len(p))
1029 for i, onep in enumerate(p):
1030 for j, x in enumerate(onep):
1031 new_p[j][i] = x
1032 return new_p
1033
1034 @staticmethod
1036 if tag == 2:
1037 return
1038 if os.path.exists(pjoin(Pdir, 'matrix%spy.so' % tag)):
1039 return
1040 else:
1041 open(pjoin(Pdir, 'matrix%spy.so' % tag),'w').write(open(pjoin(Pdir, 'matrix2py.so')
1042 ).read().replace('matrix2py', 'matrix%spy' % tag))
1043
1045 """routine to return the matrix element"""
1046
1047 if self.has_nlo:
1048 nb_retry, sleep = 10, 60
1049 else:
1050 nb_retry, sleep = 5, 20
1051
1052 tag, order = event.get_tag_and_order()
1053 if isinstance(hypp_id, str) and hypp_id.startswith('V'):
1054 tag = (tag,'V')
1055 hypp_id = int(hypp_id[1:])
1056 base = "rw_mevirt"
1057 else:
1058 base = "rw_me"
1059
1060 if (not self.second_model and not self.second_process) or hypp_id==0:
1061 orig_order, Pdir, hel_dict = self.id_to_path[tag]
1062 else:
1063 orig_order, Pdir, hel_dict = self.id_to_path_second[tag]
1064
1065
1066 run_id = (tag, hypp_id)
1067
1068 assert space == self
1069 start = False
1070 if run_id in space.calculator:
1071 external = space.calculator[run_id]
1072
1073
1074
1075
1076
1077
1078 elif (not self.second_model and not self.second_process) or hypp_id==0:
1079
1080 subdir = pjoin(self.me_dir, base, 'SubProcesses')
1081 if self.me_dir not in sys.path:
1082 sys.path.insert(0,self.me_dir)
1083 if self.rwgt_dir and self.rwgt_dir not in sys.path:
1084 sys.path.insert(0,self.rwgt_dir)
1085 Pname = os.path.basename(Pdir)
1086 if hypp_id == 0:
1087 if (Pdir, 0) not in dir_to_f2py_free_mod:
1088 metag = 1
1089 dir_to_f2py_free_mod[(Pdir,0)] = (metag, nb_f2py_module)
1090 else:
1091 metag, old_module = dir_to_f2py_free_mod[(Pdir,0)]
1092 if old_module != nb_f2py_module:
1093 metag += 1
1094 dir_to_f2py_free_mod[(Pdir,0)] = (metag, nb_f2py_module)
1095 os.environ['MENUM'] = '2'
1096 if not self.rwgt_dir or not os.path.exists(pjoin(Pdir, 'matrix2py.so')):
1097 misc.multiple_try(nb_retry,sleep)(misc.compile)(['matrix2py.so'], cwd=Pdir)
1098 self.rename_f2py_lib(Pdir, 2*metag)
1099 try:
1100 mymod = __import__('%s.SubProcesses.%s.matrix%spy' % (base, Pname, 2*metag), globals(), locals(), [],-1)
1101 except:
1102 import platform
1103 if platform.system() == 'Darwin':
1104 os.system('install_name_tool -change libMadLoop.dylib %s/libMadLoop.dylib matrix%spy.so' % (Pdir,2*metag))
1105 mymod = __import__('%s.SubProcesses.%s.matrix%spy' % (base, Pname, 2*metag), globals(), locals(), [],-1)
1106 else:
1107 misc.sprint("fail compilation")
1108 raise
1109 S = mymod.SubProcesses
1110 P = getattr(S, Pname)
1111 mymod = getattr(P, 'matrix%spy' % (2*metag))
1112 with misc.chdir(Pdir):
1113 with misc.stdchannel_redirected(sys.stdout, os.devnull):
1114 mymod.initialise('param_card_orig.dat')
1115
1116
1117 if hypp_id == 1:
1118
1119 metag = dir_to_f2py_free_mod[(Pdir,0)][0]
1120 newtag = 2*metag+1
1121 self.rename_f2py_lib(Pdir, newtag)
1122 try:
1123 mymod = __import__('%s.SubProcesses.%s.matrix%spy' % (base, Pname, newtag), globals(), locals(), [],-1)
1124 except Exception, error:
1125 newtag = "L%s" % newtag
1126 os.environ['MENUM'] = newtag
1127 misc.multiple_try(nb_retry,sleep)(misc.compile)(['matrix%spy.so' % newtag], cwd=Pdir)
1128 mymod = __import__('%s.SubProcesses.%s.matrix%spy' % (base, Pname, newtag), globals(), locals(), [],-1)
1129
1130 S = mymod.SubProcesses
1131 P = getattr(S, Pname)
1132 mymod = getattr(P, 'matrix%spy' % newtag)
1133 with misc.chdir(Pdir):
1134 with misc.stdchannel_redirected(sys.stdout, os.devnull):
1135 mymod.initialise('param_card.dat')
1136
1137 space.calculator[run_id] = mymod.get_me
1138 space.calculator[(run_id,'module')] = mymod
1139 external = space.calculator[run_id]
1140 else:
1141 subdir = pjoin(self.me_dir,'%s_second' % base, 'SubProcesses')
1142 if self.me_dir not in sys.path:
1143 sys.path.append(self.me_dir)
1144
1145 assert hypp_id == 1
1146 Pname = os.path.basename(Pdir)
1147 os.environ['MENUM'] = '2'
1148 if not self.rwgt_dir or not os.path.exists(pjoin(Pdir, 'matrix2py.so')):
1149 misc.multiple_try(nb_retry,sleep)(misc.compile)(['matrix2py.so'], cwd=pjoin(subdir, Pdir))
1150 if (Pdir, 1) not in dir_to_f2py_free_mod:
1151 metag = 1
1152 dir_to_f2py_free_mod[(Pdir,1)] = (metag, nb_f2py_module)
1153 else:
1154 metag, old_module = dir_to_f2py_free_mod[(Pdir,1)]
1155 if old_module != nb_f2py_module:
1156 metag += 1
1157 dir_to_f2py_free_mod[(Pdir,1)] = (metag, nb_f2py_module)
1158 self.rename_f2py_lib(Pdir, metag)
1159 try:
1160 mymod = __import__("%s_second.SubProcesses.%s.matrix%spy" % (base, Pname, metag))
1161 except ImportError:
1162 metag = "L%s" % metag
1163 os.environ['MENUM'] = str(metag)
1164 misc.multiple_try(nb_retry,sleep)(misc.compile)(['matrix%spy.so' % metag], cwd=pjoin(subdir, Pdir))
1165 mymod = __import__("%s_second.SubProcesses.%s.matrix%spy" % (base, Pname, metag))
1166
1167 reload(mymod)
1168 S = mymod.SubProcesses
1169 P = getattr(S, Pname)
1170 mymod = getattr(P, 'matrix%spy' % metag)
1171 with misc.chdir(Pdir):
1172 with misc.stdchannel_redirected(sys.stdout, os.devnull):
1173 mymod.initialise('param_card.dat')
1174 space.calculator[run_id] = mymod.get_me
1175 space.calculator[(run_id,'module')] = mymod
1176 external = space.calculator[run_id]
1177
1178
1179
1180 p = event.get_momenta(orig_order)
1181
1182
1183 hel_order = event.get_helicity(orig_order)
1184 if self.helicity_reweighting and 9 not in hel_order:
1185 nhel = hel_dict[tuple(hel_order)]
1186 if event[1].status == -1:
1187
1188 pboost = lhe_parser.FourMomentum(p[0]) + lhe_parser.FourMomentum(p[1])
1189 for i,thisp in enumerate(p):
1190 p[i] = lhe_parser.FourMomentum(thisp).zboost(pboost).get_tuple()
1191 assert p[0][1] == p[0][2] == 0 == p[1][2] == p[1][2] == 0
1192
1193
1194 else:
1195 nhel = 0
1196
1197 p = self.invert_momenta(p)
1198
1199 with misc.chdir(Pdir):
1200 with misc.stdchannel_redirected(sys.stdout, os.devnull):
1201 if 'V' in tag or \
1202 (hypp_id ==1 and self.second_process and any('sqrvirt' in l for l in self.second_process)):
1203 me_value = external(p,event.aqcd, math.sqrt(scale2), nhel)
1204 else:
1205 try:
1206 me_value = external(p,event.aqcd, nhel)
1207 except TypeError:
1208 me_value = external(p,event.aqcd, math.sqrt(scale2), nhel)
1209
1210
1211 if isinstance(me_value, tuple):
1212 me_value, code = me_value
1213
1214 hundred_value = (code % 1000) //100
1215 if hundred_value in [4]:
1216 me_value = 0.
1217
1218 return me_value
1219
1221 """routine to terminate all fortran executables"""
1222
1223 for (mode, production) in dict(self.calculator):
1224
1225 if new_card_only and production == 0:
1226 continue
1227 del self.calculator[(mode, production)]
1228
1230 if self.exitted:
1231 return
1232 self.exitted = True
1233
1234 if 'init' in self.banner:
1235 cross = 0
1236 error = 0
1237 for line in self.banner['init'].split('\n'):
1238 split = line.split()
1239 if len(split) == 4:
1240 cross, error = float(split[0]), float(split[1])
1241
1242 if not self.multicore == 'create':
1243
1244 if 'orig' not in self.all_cross_section:
1245 logger.info('Original cross-section: %s +- %s pb' % (cross, error))
1246 else:
1247 logger.info('Original cross-section: %s +- %s pb (cross-section from sum of weights: %s)' % (cross, error, self.all_cross_section['orig'][0]))
1248 logger.info('Computed cross-section:')
1249 keys = self.all_cross_section.keys()
1250 keys.sort()
1251 for key in keys:
1252 if key == 'orig':
1253 continue
1254 logger.info('%s : %s +- %s pb' % (key[0] if not key[1] else '%s%s' % key,
1255 self.all_cross_section[key][0],self.all_cross_section[key][1] ))
1256 self.terminate_fortran_executables()
1257
1258 if self.rwgt_dir and self.multicore == False:
1259 self.save_to_pickle()
1260
1261 with misc.stdchannel_redirected(sys.stdout, os.devnull):
1262 for run_id in self.calculator:
1263 del self.calculator[run_id]
1264 del self.calculator
1265
1266
1269
1270
1271 - def adding_me(self, matrix_elements, path):
1272 """Adding one element to the list based on the matrix element"""
1273
1274
1275 @misc.mute_logger()
1277 """generate the various directory for the weight evaluation"""
1278
1279 data={}
1280 if not second:
1281 data['paths'] = ['rw_me', 'rw_mevirt']
1282
1283 info = self.banner.get('proc_card', 'full_model_line')
1284 if '-modelname' in info:
1285 data['mg_names'] = False
1286 else:
1287 data['mg_names'] = True
1288 data['model_name'] = self.banner.get('proc_card', 'model')
1289
1290 data['processes'] = [line[9:].strip() for line in self.banner.proc_card
1291 if line.startswith('generate')]
1292 data['processes'] += [' '.join(line.split()[2:]) for line in self.banner.proc_card
1293 if re.search('^\s*add\s+process', line)]
1294
1295 self.id_to_path = {}
1296 data['id2path'] = self.id_to_path
1297 else:
1298 data['paths'] = ['rw_me_second', 'rw_mevirt_second']
1299
1300 if self.second_model:
1301 data['mg_names'] = True
1302 if ' ' in self.second_model:
1303 args = self.second_model.split()
1304 if '--modelname' in args:
1305 data['mg_names'] = False
1306 data['model_name'] = args[0]
1307 else:
1308 data['model_name'] = self.second_model
1309 else:
1310 data['model_name'] = None
1311
1312 if self.second_process:
1313 data['processes'] = self.second_process
1314 else:
1315 data['processes'] = [line[9:].strip() for line in self.banner.proc_card
1316 if line.startswith('generate')]
1317 data['processes'] += [' '.join(line.split()[2:])
1318 for line in self.banner.proc_card
1319 if re.search('^\s*add\s+process', line)]
1320
1321 self.id_to_path_second = {}
1322 data['id2path'] = self.id_to_path_second
1323
1324
1325 if not self.rwgt_dir:
1326 path_me = self.me_dir
1327 else:
1328 path_me = self.rwgt_dir
1329 try:
1330 shutil.rmtree(pjoin(path_me,data['paths'][0]))
1331 except Exception:
1332 pass
1333 try:
1334 shutil.rmtree(pjoin(path_me, data['paths'][1]))
1335 except Exception:
1336 pass
1337
1338
1339 mgcmd = self.mg5cmd
1340 complex_mass = False
1341 has_cms = re.compile(r'''set\s+complex_mass_scheme\s*(True|T|1|true|$|;)''')
1342 for line in self.banner.proc_card:
1343 if line.startswith('set'):
1344 mgcmd.exec_cmd(line, printcmd=False, precmd=False, postcmd=False)
1345 if has_cms.search(line):
1346 complex_mass = True
1347 elif line.startswith('define'):
1348 try:
1349 mgcmd.exec_cmd(line, printcmd=False, precmd=False, postcmd=False)
1350 except Exception:
1351 pass
1352
1353
1354 if not data['model_name'] and not second:
1355 raise self.InvalidCmd('Only UFO model can be loaded in this module.')
1356 elif data['model_name']:
1357 self.load_model(data['model_name'], data['mg_names'], complex_mass)
1358 modelpath = self.model.get('modelpath')
1359 if os.path.basename(modelpath) != mgcmd._curr_model['name']:
1360 name, restrict = mgcmd._curr_model['name'].rsplit('-',1)
1361 if os.path.exists(pjoin(os.path.dirname(modelpath),name, 'restrict_%s.dat' % restrict)):
1362 modelpath = pjoin(os.path.dirname(modelpath), mgcmd._curr_model['name'])
1363
1364 commandline="import model %s " % modelpath
1365 if not data['mg_names']:
1366 commandline += ' -modelname '
1367 mgcmd.exec_cmd(commandline)
1368
1369
1370 for name, content in self.banner.get('proc_card', 'multiparticles'):
1371 mgcmd.exec_cmd("define %s = %s" % (name, content))
1372
1373
1374 has_nlo = False
1375 mgcmd.exec_cmd("set group_subprocesses False")
1376
1377 if not second:
1378 logger.info('generating the square matrix element for reweighting')
1379 else:
1380 logger.info('generating the square matrix element for reweighting (second model and/or processes)')
1381 start = time.time()
1382 commandline=''
1383 for i,proc in enumerate(data['processes']):
1384 if '[' not in proc:
1385 commandline += "add process %s ;" % proc
1386 else:
1387 has_nlo = True
1388 if self.banner.get('run_card','ickkw') == 3:
1389 if len(proc) == min([len(p.strip()) for p in data['processes']]):
1390 commandline += self.get_LO_definition_from_NLO(proc)
1391 else:
1392 commandline += self.get_LO_definition_from_NLO(proc, real_only=True)
1393 else:
1394 commandline += self.get_LO_definition_from_NLO(proc)
1395
1396 commandline = commandline.replace('add process', 'generate',1)
1397 logger.info(commandline)
1398 try:
1399 mgcmd.exec_cmd(commandline, precmd=True, errorhandling=False)
1400 except diagram_generation.NoDiagramException:
1401 commandline=''
1402 for proc in data['processes']:
1403 if '[' not in proc:
1404 raise
1405
1406 base, post = proc.split('[',1)
1407 nlo_order, post = post.split(']',1)
1408 if '=' not in nlo_order:
1409 nlo_order = 'virt=%s' % nlo_order
1410 elif 'noborn' in nlo_order:
1411 nlo_order = nlo_order.replace('noborn', 'virt')
1412 commandline += "add process %s [%s] %s;" % (base,nlo_order,post)
1413 commandline = commandline.replace('add process', 'generate',1)
1414 logger.info("RETRY with %s", commandline)
1415 mgcmd.exec_cmd(commandline, precmd=True)
1416 has_nlo = False
1417 except Exception, error:
1418 raise
1419
1420 commandline = 'output standalone_rw %s' % pjoin(path_me,data['paths'][0])
1421 mgcmd.exec_cmd(commandline, precmd=True)
1422 logger.info('Done %.4g' % (time.time()-start))
1423 self.has_standalone_dir = True
1424
1425
1426
1427 matrix_elements = mgcmd._curr_matrix_elements.get_matrix_elements()
1428
1429 to_check = []
1430 for me in matrix_elements:
1431 for proc in me.get('processes'):
1432 initial = []
1433 final = [l.get('id') for l in proc.get('legs')\
1434 if l.get('state') or initial.append(l.get('id'))]
1435 order = (initial, final)
1436 tag = proc.get_initial_final_ids()
1437 decay_finals = proc.get_final_ids_after_decay()
1438
1439 if tag[1] != decay_finals:
1440 order = (initial, list(decay_finals))
1441 decay_finals.sort()
1442 tag = (tag[0], tuple(decay_finals))
1443 Pdir = pjoin(path_me, data['paths'][0], 'SubProcesses',
1444 'P%s' % me.get('processes')[0].shell_string())
1445
1446 if not os.path.exists(Pdir):
1447 to_check.append(tag)
1448 continue
1449 if tag in data['id2path']:
1450 if not Pdir == data['id2path'][tag][1]:
1451 misc.sprint(tag, Pdir, data['id2path'][tag][1])
1452 raise self.InvalidCmd, '2 different process have the same final states. This module can not handle such situation'
1453 else:
1454 continue
1455
1456 hel_nb = 0
1457 hel_dict = {9:0}
1458 for helicities in me.get_helicity_matrix():
1459 hel_nb +=1
1460 hel_dict[tuple(helicities)] = hel_nb
1461
1462 data['id2path'][tag] = [order, Pdir, hel_dict]
1463
1464 for tag in to_check:
1465 if tag not in self.id_to_path:
1466 logger.warning("no valid path for %s" % (tag,))
1467
1468
1469
1470 if os.path.exists(pjoin(path_me, data['paths'][0], 'Cards', 'MadLoopParams.dat')):
1471 MLCard = banner.MadLoopParam(pjoin(path_me, data['paths'][0], 'Cards', 'MadLoopParams.dat'))
1472 MLCard.set('WriteOutFilters', False)
1473 MLCard.set('UseLoopFilter', False)
1474 MLCard.set("DoubleCheckHelicityFilter", False)
1475 MLCard.set("HelicityFilterLevel", 0)
1476 MLCard.write(pjoin(path_me, data['paths'][0], 'SubProcesses', 'MadLoopParams.dat'),
1477 pjoin(path_me, data['paths'][0], 'Cards', 'MadLoopParams.dat'),
1478 commentdefault=False)
1479
1480 if self.multicore == 'create':
1481 print "compile OLP", data['paths'][0]
1482 misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][0],'SubProcesses'),
1483 nb_core=self.mother.options['nb_core'])
1484
1485 if os.path.exists(pjoin(path_me, data['paths'][1], 'Cards', 'MadLoopParams.dat')):
1486 if self.multicore == 'create':
1487 print "compile OLP", data['paths'][1]
1488 misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][1],'SubProcesses'),
1489 nb_core=self.mother.options['nb_core'])
1490
1491
1492
1493 if has_nlo and 'NLO' in self.rwgt_mode:
1494
1495 start = time.time()
1496 commandline=''
1497 for proc in data['processes']:
1498 if '[' not in proc:
1499 pass
1500 else:
1501 proc = proc.replace('[', '[ virt=')
1502 commandline += "add process %s ;" % proc
1503
1504 old_options = dict(mgcmd.options)
1505 if mgcmd.options['golem'] or mgcmd.options['pjfry']:
1506 logger.info(" When doing NLO reweighting, MG5aMC cannot use the loop reduction algorithms Golem and/or PJFry++")
1507 mgcmd.options['golem'] = None
1508 mgcmd.options['pjfry'] = None
1509 commandline = commandline.replace('add process', 'generate',1)
1510 logger.info(commandline)
1511 mgcmd.exec_cmd(commandline, precmd=True)
1512 commandline = 'output standalone_rw %s -f' % pjoin(path_me, data['paths'][1])
1513 mgcmd.exec_cmd(commandline, precmd=True)
1514
1515
1516 mgcmd.options['golem'] = old_options['golem']
1517 mgcmd.options['pjfry'] = old_options['pjfry']
1518
1519 m_opts = {}
1520 if mgcmd.options['lhapdf']:
1521
1522
1523 m_opts['lhapdf'] = True
1524 m_opts['f2pymode'] = True
1525 m_opts['lhapdfversion'] = 5
1526 m_opts['llhapdf'] = self.mother.get_lhapdf_libdir()
1527 else:
1528 raise Exception, "NLO reweighting requires LHAPDF to work correctly"
1529
1530 path = pjoin(path_me,data['paths'][1], 'Source', 'make_opts')
1531 common_run_interface.CommonRunCmd.update_make_opts_full(path, m_opts)
1532 logger.info('Done %.4g' % (time.time()-start))
1533
1534
1535
1536 common_run_interface.CommonRunCmd.install_lhapdf_pdfset_static(\
1537 mgcmd.options['lhapdf'], None, self.banner.run_card.get_lhapdf_id())
1538
1539
1540 matrix_elements = mgcmd._curr_matrix_elements.get_matrix_elements()
1541 for me in matrix_elements:
1542 for proc in me.get('processes'):
1543 initial = []
1544 final = [l.get('id') for l in proc.get('legs')\
1545 if l.get('state') or initial.append(l.get('id'))]
1546 order = (initial, final)
1547 tag = proc.get_initial_final_ids()
1548 decay_finals = proc.get_final_ids_after_decay()
1549
1550 if tag[1] != decay_finals:
1551 order = (initial, list(decay_finals))
1552 decay_finals.sort()
1553 tag = (tag[0], tuple(decay_finals))
1554 Pdir = pjoin(path_me, data['paths'][1], 'SubProcesses',
1555 'P%s' % me.get('processes')[0].shell_string())
1556 assert os.path.exists(Pdir), "Pdir %s do not exists" % Pdir
1557 if (tag,'V') in data['id2path']:
1558 if not Pdir == data['id2path'][(tag,'V')][1]:
1559 misc.sprint(tag, Pdir, self.id_to_path[(tag,'V')][1])
1560 raise self.InvalidCmd, '2 different process have the same final states. This module can not handle such situation'
1561 else:
1562 continue
1563
1564 hel_nb = 0
1565 hel_dict = {9:0}
1566 for helicities in me.get_helicity_matrix():
1567 hel_nb +=1
1568 hel_dict[tuple(helicities)] = hel_nb
1569
1570 data['id2path'][(tag,'V')] = [order, Pdir, hel_dict]
1571
1572
1573 misc.compile(cwd=pjoin(path_me, data['paths'][1], 'Source'))
1574
1575 if path_me not in sys.path:
1576 sys.path.insert(0, os.path.realpath(path_me))
1577 with misc.chdir(pjoin(path_me)):
1578 mymod = __import__('%s.Source.rwgt2py' % data['paths'][1], globals(), locals(), [],-1)
1579 mymod = mymod.Source.rwgt2py
1580 with misc.stdchannel_redirected(sys.stdout, os.devnull):
1581 mymod.initialise([self.banner.run_card['lpp1'],
1582 self.banner.run_card['lpp2']],
1583 self.banner.run_card.get_lhapdf_id())
1584 self.combine_wgt = mymod.get_wgt
1585
1586 if self.multicore == 'create':
1587 print "compile OLP", data['paths'][1]
1588 misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][1],'SubProcesses'),
1589 nb_core=self.mother.options['nb_core'])
1590
1591 elif has_nlo and not second and self.rwgt_mode == ['NLO_tree']:
1592
1593
1594
1595 start = time.time()
1596 commandline='import model loop_sm;generate g g > e+ ve [virt=QCD]'
1597
1598 old_options = dict(mgcmd.options)
1599 mgcmd.options['golem'] = None
1600 mgcmd.options['pjfry'] = None
1601 commandline = commandline.replace('add process', 'generate',1)
1602 logger.info(commandline)
1603 mgcmd.exec_cmd(commandline, precmd=True)
1604 commandline = 'output standalone_rw %s -f' % pjoin(path_me, data['paths'][1])
1605 mgcmd.exec_cmd(commandline, precmd=True)
1606
1607 mgcmd.options['golem'] = old_options['golem']
1608 mgcmd.options['pjfry'] = old_options['pjfry']
1609
1610 m_opts = {}
1611 if mgcmd.options['lhapdf']:
1612
1613
1614 m_opts['lhapdf'] = True
1615 m_opts['f2pymode'] = True
1616 m_opts['lhapdfversion'] = 5
1617 m_opts['llhapdf'] = self.mother.get_lhapdf_libdir()
1618 else:
1619 raise Exception, "NLO_tree reweighting requires LHAPDF to work correctly"
1620
1621 path = pjoin(path_me,data['paths'][1], 'Source', 'make_opts')
1622 common_run_interface.CommonRunCmd.update_make_opts_full(path, m_opts)
1623 logger.info('Done %.4g' % (time.time()-start))
1624
1625
1626 common_run_interface.CommonRunCmd.install_lhapdf_pdfset_static(\
1627 mgcmd.options['lhapdf'], None, self.banner.run_card.get_lhapdf_id())
1628
1629
1630 misc.compile(cwd=pjoin(path_me, data['paths'][1], 'Source'))
1631
1632 with misc.chdir(pjoin(path_me)):
1633 if path_me not in sys.path:
1634 sys.path.insert(0, path_me)
1635 mymod = __import__('%s.Source.rwgt2py' % data['paths'][1], globals(), locals(), [],-1)
1636 mymod = mymod.Source.rwgt2py
1637 with misc.stdchannel_redirected(sys.stdout, os.devnull):
1638 mymod.initialise([self.banner.run_card['lpp1'],
1639 self.banner.run_card['lpp2']],
1640 self.banner.run_card.get_lhapdf_id())
1641 self.combine_wgt = mymod.get_wgt
1642
1643
1644
1645 if (self.second_model or self.second_process) and not second:
1646 self.create_standalone_directory(second=True)
1647
1648 if not second:
1649 self.has_nlo = has_nlo
1650
1651
1652
1653
1654 - def load_model(self, name, use_mg_default, complex_mass=False):
1672
1673
1675 import madgraph.iolibs.save_load_object as save_load_object
1676
1677 to_save = {}
1678 to_save['id_to_path'] = self.id_to_path
1679 if hasattr(self, 'id_to_path_second'):
1680 to_save['id_to_path_second'] = self.id_to_path_second
1681 else:
1682 to_save['id_to_path_second'] = {}
1683 to_save['all_cross_section'] = self.all_cross_section
1684 to_save['processes'] = self.processes
1685 to_save['second_process'] = self.second_process
1686 if self.second_model:
1687 to_save['second_model'] =True
1688 else:
1689 to_save['second_model'] = None
1690 to_save['rwgt_dir'] = self.rwgt_dir
1691 to_save['has_nlo'] = self.has_nlo
1692 to_save['rwgt_mode'] = self.rwgt_mode
1693 to_save['rwgt_name'] = self.options['rwgt_name']
1694
1695 name = pjoin(self.rwgt_dir, 'rw_me', 'rwgt.pkl')
1696 save_load_object.save_to_file(name, to_save)
1697
1698
1700 import madgraph.iolibs.save_load_object as save_load_object
1701
1702 obj = save_load_object.load_from_file( pjoin(self.rwgt_dir, 'rw_me', 'rwgt.pkl'))
1703
1704 self.has_standalone_dir = True
1705 self.options = {'curr_dir': os.path.realpath(os.getcwd()),
1706 'rwgt_name': None}
1707 if keep_name:
1708 self.options['rwgt_name'] = obj['rwgt_name']
1709
1710 old_rwgt = obj['rwgt_dir']
1711
1712
1713 self.id_to_path = {}
1714 for key , (order, Pdir, hel_dict) in obj['id_to_path'].items():
1715 new_P = Pdir.replace(old_rwgt, self.rwgt_dir)
1716 self.id_to_path[key] = [order, new_P, hel_dict]
1717
1718
1719 self.id_to_path_second = {}
1720 for key , (order, Pdir, hel_dict) in obj['id_to_path_second'].items():
1721 new_P = Pdir.replace(old_rwgt, self.rwgt_dir)
1722 self.id_to_path_second[key] = [order, new_P, hel_dict]
1723
1724 self.all_cross_section = obj['all_cross_section']
1725 self.processes = obj['processes']
1726 self.second_process = obj['second_process']
1727 self.second_model = obj['second_model']
1728 self.has_nlo = obj['has_nlo']
1729 if not self.rwgt_mode:
1730 self.rwgt_mode = obj['rwgt_mode']
1731 logger.info("mode set to %s" % self.rwgt_mode)
1732 if self.has_nlo and 'NLO' in self.rwgt_mode:
1733 path = pjoin(obj['rwgt_dir'], 'rw_mevirt','Source')
1734 sys.path.insert(0, path)
1735 try:
1736 mymod = __import__('rwgt2py', globals(), locals())
1737 except ImportError:
1738 misc.compile(['rwgt2py.so'], cwd=path)
1739 mymod = __import__('rwgt2py', globals(), locals())
1740 with misc.stdchannel_redirected(sys.stdout, os.devnull):
1741 mymod.initialise([self.banner.run_card['lpp1'],
1742 self.banner.run_card['lpp2']],
1743 self.banner.run_card.get_lhapdf_id())
1744 self.combine_wgt = mymod.get_wgt
1745