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