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