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