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