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