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