1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """A user friendly command line interface to access MadGraph5_aMC@NLO features.
16 Uses the cmd package for command interpretation and tab completion.
17 """
18 from __future__ import division
19
20 import collections
21 import glob
22 import logging
23 import math
24 import os
25 import random
26 import re
27
28 import stat
29 import subprocess
30 import sys
31 import time
32 import tarfile
33 import StringIO
34 import shutil
35 import copy
36
37 try:
38 import readline
39 GNU_SPLITTING = ('GNU' in readline.__doc__)
40 except:
41 GNU_SPLITTING = True
42
43 root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
44 root_path = os.path.split(root_path)[0]
45 sys.path.insert(0, os.path.join(root_path,'bin'))
46
47
48 pjoin = os.path.join
49
50 logger = logging.getLogger('madevent.stdout')
51 logger_stderr = logging.getLogger('madevent.stderr')
52
53 try:
54 import madgraph
55 except ImportError:
56
57 MADEVENT = True
58 import internal.extended_cmd as cmd
59 import internal.common_run_interface as common_run
60 import internal.banner as banner_mod
61 import internal.misc as misc
62 from internal import InvalidCmd, MadGraph5Error, ReadWrite
63 import internal.files as files
64 import internal.gen_crossxhtml as gen_crossxhtml
65 import internal.gen_ximprove as gen_ximprove
66 import internal.save_load_object as save_load_object
67 import internal.cluster as cluster
68 import internal.check_param_card as check_param_card
69 import internal.sum_html as sum_html
70 import internal.combine_runs as combine_runs
71 import internal.lhe_parser as lhe_parser
72
73 from internal.files import ln
74 else:
75
76 MADEVENT = False
77 import madgraph.interface.extended_cmd as cmd
78 import madgraph.interface.common_run_interface as common_run
79 import madgraph.iolibs.files as files
80 import madgraph.iolibs.save_load_object as save_load_object
81 import madgraph.madevent.gen_crossxhtml as gen_crossxhtml
82 import madgraph.madevent.gen_ximprove as gen_ximprove
83 import madgraph.madevent.sum_html as sum_html
84 import madgraph.various.banner as banner_mod
85 import madgraph.various.cluster as cluster
86 import madgraph.various.misc as misc
87 import madgraph.madevent.combine_runs as combine_runs
88 import madgraph.various.lhe_parser as lhe_parser
89
90 import models.check_param_card as check_param_card
91 from madgraph.iolibs.files import ln
92 from madgraph import InvalidCmd, MadGraph5Error, MG5DIR, ReadWrite
98
101
103
104 MadEventAlreadyRunning = common_run.MadEventAlreadyRunning
105
106
107
108
109 -class CmdExtended(common_run.CommonRunCmd):
110 """Particularisation of the cmd command for MadEvent"""
111
112
113 next_possibility = {
114 'start': [],
115 }
116
117 debug_output = 'ME5_debug'
118 error_debug = 'Please report this bug on https://bugs.launchpad.net/mg5amcnlo\n'
119 error_debug += 'More information is found in \'%(debug)s\'.\n'
120 error_debug += 'Please attach this file to your report.'
121
122 config_debug = 'If you need help with this issue please contact us on https://answers.launchpad.net/mg5amcnlo\n'
123
124
125 keyboard_stop_msg = """stopping all operation
126 in order to quit MadGraph5_aMC@NLO please enter exit"""
127
128
129 InvalidCmd = InvalidCmd
130 ConfigurationError = MadGraph5Error
131
132 - def __init__(self, me_dir, options, *arg, **opt):
133 """Init history and line continuation"""
134
135
136 self.force = False
137
138
139
140 info = misc.get_pkg_info()
141 info_line = ""
142 if info and info.has_key('version') and info.has_key('date'):
143 len_version = len(info['version'])
144 len_date = len(info['date'])
145 if len_version + len_date < 30:
146 info_line = "#* VERSION %s %s %s *\n" % \
147 (info['version'],
148 (30 - len_version - len_date) * ' ',
149 info['date'])
150 else:
151 version = open(pjoin(root_path,'MGMEVersion.txt')).readline().strip()
152 info_line = "#* VERSION %s %s *\n" % \
153 (version, (24 - len(version)) * ' ')
154
155
156
157 self.history_header = \
158 '#************************************************************\n' + \
159 '#* MadGraph5_aMC@NLO/MadEvent *\n' + \
160 '#* *\n' + \
161 "#* * * *\n" + \
162 "#* * * * * *\n" + \
163 "#* * * * * 5 * * * * *\n" + \
164 "#* * * * * *\n" + \
165 "#* * * *\n" + \
166 "#* *\n" + \
167 "#* *\n" + \
168 info_line + \
169 "#* *\n" + \
170 "#* The MadGraph5_aMC@NLO Development Team - Find us at *\n" + \
171 "#* https://server06.fynu.ucl.ac.be/projects/madgraph *\n" + \
172 '#* *\n' + \
173 '#************************************************************\n' + \
174 '#* *\n' + \
175 '#* Command File for MadEvent *\n' + \
176 '#* *\n' + \
177 '#* run as ./bin/madevent.py filename *\n' + \
178 '#* *\n' + \
179 '#************************************************************\n'
180
181 if info_line:
182 info_line = info_line[1:]
183
184 logger.info(\
185 "************************************************************\n" + \
186 "* *\n" + \
187 "* W E L C O M E to *\n" + \
188 "* M A D G R A P H 5 _ a M C @ N L O *\n" + \
189 "* M A D E V E N T *\n" + \
190 "* *\n" + \
191 "* * * *\n" + \
192 "* * * * * *\n" + \
193 "* * * * * 5 * * * * *\n" + \
194 "* * * * * *\n" + \
195 "* * * *\n" + \
196 "* *\n" + \
197 info_line + \
198 "* *\n" + \
199 "* The MadGraph5_aMC@NLO Development Team - Find us at *\n" + \
200 "* https://server06.fynu.ucl.ac.be/projects/madgraph *\n" + \
201 "* *\n" + \
202 "* Type 'help' for in-line help. *\n" + \
203 "* *\n" + \
204 "************************************************************")
205 super(CmdExtended, self).__init__(me_dir, options, *arg, **opt)
206
208 """return the history header"""
209 return self.history_header % misc.get_time_info()
210
212 """action to perform to close nicely on a keyboard interupt"""
213 try:
214 if hasattr(self, 'cluster'):
215 logger.info('rm jobs on queue')
216 self.cluster.remove()
217 if hasattr(self, 'results'):
218 self.update_status('Stop by the user', level=None, makehtml=False, error=True)
219 self.add_error_log_in_html(KeyboardInterrupt)
220 except:
221 pass
222
223 - def postcmd(self, stop, line):
224 """ Update the status of the run for finishing interactive command """
225
226 stop = super(CmdExtended, self).postcmd(stop, line)
227
228 self.force = False
229
230 if not self.use_rawinput:
231 return stop
232
233 if self.results and not self.results.current:
234 return stop
235
236 arg = line.split()
237 if len(arg) == 0:
238 return stop
239 if isinstance(self.results.status, str) and self.results.status.startswith('Error'):
240 return stop
241 if isinstance(self.results.status, str) and self.results.status == 'Stop by the user':
242 self.update_status('%s Stop by the user' % arg[0], level=None, error=True)
243 return stop
244 elif not self.results.status:
245 return stop
246 elif str(arg[0]) in ['exit','quit','EOF']:
247 return stop
248
249 try:
250 self.update_status('Command \'%s\' done.<br> Waiting for instruction.' % arg[0],
251 level=None, error=True)
252 except Exception:
253 misc.sprint('update_status fails')
254 pass
255
256
262
276
277
279 """If a ME run is currently running add a link in the html output"""
280
281 if isinstance(error, ZeroResult):
282 self.add_error_log_in_html(error)
283 logger.warning('Zero result detected: %s' % error)
284
285 try:
286 if not self.banner:
287 self.banner = banner_mod.Banner()
288 if 'slha' not in self.banner:
289 self.banner.add(pjoin(self.me_dir,'Cards','param_card.dat'))
290 if 'mgruncard' not in self.banner:
291 self.banner.add(pjoin(self.me_dir,'Cards','run_card.dat'))
292 if 'mg5proccard' not in self.banner:
293 proc_card = pjoin(self.me_dir,'Cards','proc_card_mg5.dat')
294 if os.path.exists(proc_card):
295 self.banner.add(proc_card)
296
297 out_dir = pjoin(self.me_dir, 'Events', self.run_name)
298 if not os.path.isdir(out_dir):
299 os.mkdir(out_dir)
300 output_path = pjoin(out_dir, '%s_%s_banner.txt' % \
301 (self.run_name, self.run_tag))
302 self.banner.write(output_path)
303 except Exception:
304 if __debug__:
305 raise
306 else:
307 pass
308 else:
309 self.add_error_log_in_html()
310 cmd.Cmd.nice_error_handling(self, error, line)
311 try:
312 debug_file = open(self.debug_output, 'a')
313 debug_file.write(open(pjoin(self.me_dir,'Cards','proc_card_mg5.dat')))
314 debug_file.close()
315 except:
316 pass
317
323 """ The Series of help routine for the MadEventCmd"""
324
326 logger.info("syntax: pythia [RUN] [--run_options]")
327 logger.info("-- run pythia on RUN (current one by default)")
328 self.run_options_help([('-f','answer all question by default'),
329 ('--tag=', 'define the tag for the pythia run'),
330 ('--no_default', 'not run if pythia_card not present')])
331
333 logger.info("syntax: pythia8 [RUN] [--run_options]")
334 logger.info("-- run pythia8 on RUN (current one by default)")
335 self.run_options_help([('-f','answer all question by default'),
336 ('--tag=', 'define the tag for the pythia8 run'),
337 ('--no_default', 'not run if pythia8_card not present')])
338
340 logger.info("syntax: banner_run Path|RUN [--run_options]")
341 logger.info("-- Reproduce a run following a given banner")
342 logger.info(" One of the following argument is require:")
343 logger.info(" Path should be the path of a valid banner.")
344 logger.info(" RUN should be the name of a run of the current directory")
345 self.run_options_help([('-f','answer all question by default'),
346 ('--name=X', 'Define the name associated with the new run')])
347
349 logger.info("syntax: open FILE ")
350 logger.info("-- open a file with the appropriate editor.")
351 logger.info(' If FILE belongs to index.html, param_card.dat, run_card.dat')
352 logger.info(' the path to the last created/used directory is used')
353 logger.info(' The program used to open those files can be chosen in the')
354 logger.info(' configuration file ./input/mg5_configuration.txt')
355
356
358 if data:
359 logger.info('-- local options:')
360 for name, info in data:
361 logger.info(' %s : %s' % (name, info))
362
363 logger.info("-- session options:")
364 logger.info(" Note that those options will be kept for the current session")
365 logger.info(" --cluster : Submit to the cluster. Current cluster: %s" % self.options['cluster_type'])
366 logger.info(" --multicore : Run in multi-core configuration")
367 logger.info(" --nb_core=X : limit the number of core to use to X.")
368
369
371 logger.info("syntax: generate_events [run_name] [options]",)
372 logger.info("-- Launch the full chain of script for the generation of events")
373 logger.info(" Including possible plotting, shower and detector resolution.")
374 logger.info(" Those steps are performed if the related program are installed")
375 logger.info(" and if the related card are present in the Cards directory.")
376 self.run_options_help([('-f', 'Use default for all questions.'),
377 ('--laststep=', 'argument might be parton/pythia/pgs/delphes and indicate the last level to be run.'),
378 ('-M', 'in order to add MadSpin'),
379 ('-R', 'in order to add the reweighting module')])
380
382 logger.info("syntax: initMadLoop [options]",'$MG:color:GREEN')
383 logger.info(
384 """-- Command only useful when MadEvent simulates loop-induced processes. This command compiles and run
385 the MadLoop output for the matrix element computation so as to initialize the filter for analytically
386 zero helicity configurations and loop topologies. If you suspect that a change you made in the model
387 parameters can have affected these filters, this command allows you to automatically refresh them. """)
388 logger.info(" The available options are:",'$MG:color:BLUE')
389 logger.info(" -f : Bypass the edition of MadLoopParams.dat.",'$MG:color:BLUE')
390 logger.info(" -r : Refresh of the existing filters (erasing them if already present).",'$MG:color:BLUE')
391 logger.info(" --nPS=<int> : Specify how many phase-space points should be tried to set up the filters.",'$MG:color:BLUE')
392
394 logger.info("syntax: add_time_of_flight [run_name|path_to_file] [--threshold=]")
395 logger.info('-- Add in the lhe files the information')
396 logger.info(' of how long it takes to a particle to decay.')
397 logger.info(' threshold option allows to change the minimal value required to')
398 logger.info(' a non zero value for the particle (default:1e-12s)')
399
401
402 if self.ninitial != 1:
403 logger.warning("This command is only valid for processes of type A > B C.")
404 logger.warning("This command can not be run in current context.")
405 logger.warning("")
406
407 logger.info("syntax: calculate_decay_widths [run_name] [options])")
408 logger.info("-- Calculate decay widths and enter widths and BRs in param_card")
409 logger.info(" for a series of processes of type A > B C ...")
410 self.run_options_help([('-f', 'Use default for all questions.'),
411 ('--accuracy=', 'accuracy (for each partial decay width).'\
412 + ' Default is 0.01.')])
413
415 logger.info("syntax: multi_run NB_RUN [run_name] [--run_options])")
416 logger.info("-- Launch the full chain of script for the generation of events")
417 logger.info(" NB_RUN times. This chains includes possible plotting, shower")
418 logger.info(" and detector resolution.")
419 self.run_options_help([('-f', 'Use default for all questions.'),
420 ('--laststep=', 'argument might be parton/pythia/pgs/delphes and indicate the last level to be run.')])
421
427
429 """exec generate_events for 2>N and calculate_width for 1>N"""
430 logger.info("syntax: launch [run_name] [options])")
431 logger.info(" --alias for either generate_events/calculate_decay_widths")
432 logger.info(" depending of the number of particles in the initial state.")
433
434 if self.ninitial == 1:
435 logger.info("For this directory this is equivalent to calculate_decay_widths")
436 self.help_calculate_decay_widths()
437 else:
438 logger.info("For this directory this is equivalent to $generate_events")
439 self.help_generate_events()
440
442 logger.info("syntax: refine require_precision [max_channel] [--run_options]")
443 logger.info("-- refine the LAST run to achieve a given precision.")
444 logger.info(" require_precision: can be either the targeted number of events")
445 logger.info(' or the required relative error')
446 logger.info(' max_channel:[5] maximal number of channel per job')
447 self.run_options_help([])
448
450 """ """
451 logger.info("syntax: combine_events [run_name] [--tag=tag_name] [--run_options]")
452 logger.info("-- Combine the last run in order to write the number of events")
453 logger.info(" asked in the run_card.")
454 self.run_options_help([])
455
462
469
475
477 logger.info("syntax: syscalc [RUN] [%s] [-f | --tag=]" % '|'.join(self._plot_mode))
478 logger.info("-- calculate systematics information for the RUN (current run by default)")
479 logger.info(" at different stages of the event generation for scale/pdf/...")
480
482 logger.info("syntax: remove RUN [all|parton|pythia|pgs|delphes|banner] [-f] [--tag=]")
483 logger.info("-- Remove all the files linked to previous run RUN")
484 logger.info(" if RUN is 'all', then all run will be cleaned.")
485 logger.info(" The optional argument precise which part should be cleaned.")
486 logger.info(" By default we clean all the related files but the banners.")
487 logger.info(" the optional '-f' allows to by-pass all security question")
488 logger.info(" The banner can be remove only if all files are removed first.")
489
496 """ The Series of check routine for the MadEventCmd"""
497
499 """check the validity of line"""
500
501 if len(args) == 0:
502 self.help_banner_run()
503 raise self.InvalidCmd('banner_run requires at least one argument.')
504
505 tag = [a[6:] for a in args if a.startswith('--tag=')]
506
507
508 if os.path.exists(args[0]):
509 type ='banner'
510 format = self.detect_card_type(args[0])
511 if format != 'banner':
512 raise self.InvalidCmd('The file is not a valid banner.')
513 elif tag:
514 args[0] = pjoin(self.me_dir,'Events', args[0], '%s_%s_banner.txt' % \
515 (args[0], tag))
516 if not os.path.exists(args[0]):
517 raise self.InvalidCmd('No banner associates to this name and tag.')
518 else:
519 name = args[0]
520 type = 'run'
521 banners = misc.glob('*_banner.txt', pjoin(self.me_dir,'Events', args[0]))
522 if not banners:
523 raise self.InvalidCmd('No banner associates to this name.')
524 elif len(banners) == 1:
525 args[0] = banners[0]
526 else:
527
528 tags = [os.path.basename(p)[len(args[0])+1:-11] for p in banners]
529 tag = self.ask('which tag do you want to use?', tags[0], tags)
530 args[0] = pjoin(self.me_dir,'Events', args[0], '%s_%s_banner.txt' % \
531 (args[0], tag))
532
533 run_name = [arg[7:] for arg in args if arg.startswith('--name=')]
534 if run_name:
535 try:
536 self.exec_cmd('remove %s all banner -f' % run_name)
537 except Exception:
538 pass
539 self.set_run_name(args[0], tag=None, level='parton', reload_card=True)
540 elif type == 'banner':
541 self.set_run_name(self.find_available_run_name(self.me_dir))
542 elif type == 'run':
543 if not self.results[name].is_empty():
544 run_name = self.find_available_run_name(self.me_dir)
545 logger.info('Run %s is not empty so will use run_name: %s' % \
546 (name, run_name))
547 self.set_run_name(run_name)
548 else:
549 try:
550 self.exec_cmd('remove %s all banner -f' % run_name)
551 except Exception:
552 pass
553 self.set_run_name(name)
554
555 - def check_history(self, args):
556 """check the validity of line"""
557
558 if len(args) > 1:
559 self.help_history()
560 raise self.InvalidCmd('\"history\" command takes at most one argument')
561
562 if not len(args):
563 return
564 elif args[0] != 'clean':
565 dirpath = os.path.dirname(args[0])
566 if dirpath and not os.path.exists(dirpath) or \
567 os.path.isdir(args[0]):
568 raise self.InvalidCmd("invalid path %s " % dirpath)
569
571 """ check the validity of the line"""
572
573 if len(args) == 0:
574 args.append('options')
575
576 if args[0] not in self._save_opts:
577 raise self.InvalidCmd('wrong \"save\" format')
578
579 if args[0] != 'options' and len(args) != 2:
580 self.help_save()
581 raise self.InvalidCmd('wrong \"save\" format')
582 elif args[0] != 'options' and len(args) == 2:
583 basename = os.path.dirname(args[1])
584 if not os.path.exists(basename):
585 raise self.InvalidCmd('%s is not a valid path, please retry' % \
586 args[1])
587
588 if args[0] == 'options':
589 has_path = None
590 for arg in args[1:]:
591 if arg in ['--auto', '--all']:
592 continue
593 elif arg.startswith('--'):
594 raise self.InvalidCmd('unknow command for \'save options\'')
595 else:
596 basename = os.path.dirname(arg)
597 if not os.path.exists(basename):
598 raise self.InvalidCmd('%s is not a valid path, please retry' % \
599 arg)
600 elif has_path:
601 raise self.InvalidCmd('only one path is allowed')
602 else:
603 args.remove(arg)
604 args.insert(1, arg)
605 has_path = True
606 if not has_path:
607 if '--auto' in arg and self.options['mg5_path']:
608 args.insert(1, pjoin(self.options['mg5_path'],'input','mg5_configuration.txt'))
609 else:
610 args.insert(1, pjoin(self.me_dir,'Cards','me5_configuration.txt'))
611
613 """ check the validity of the line"""
614
615 if len(args) < 2:
616 self.help_set()
617 raise self.InvalidCmd('set needs an option and an argument')
618
619 if args[0] not in self._set_options + self.options.keys():
620 self.help_set()
621 raise self.InvalidCmd('Possible options for set are %s' % \
622 self._set_options)
623
624 if args[0] in ['stdout_level']:
625 if args[1] not in ['DEBUG','INFO','WARNING','ERROR','CRITICAL'] \
626 and not args[1].isdigit():
627 raise self.InvalidCmd('output_level needs ' + \
628 'a valid level')
629
630 if args[0] in ['timeout']:
631 if not args[1].isdigit():
632 raise self.InvalidCmd('timeout values should be a integer')
633
635 """ check the validity of the line """
636
637 if len(args) != 1:
638 self.help_open()
639 raise self.InvalidCmd('OPEN command requires exactly one argument')
640
641 if args[0].startswith('./'):
642 if not os.path.isfile(args[0]):
643 raise self.InvalidCmd('%s: not such file' % args[0])
644 return True
645
646
647 if not self.me_dir:
648 if not os.path.isfile(args[0]):
649 self.help_open()
650 raise self.InvalidCmd('No MadEvent path defined. Unable to associate this name to a file')
651 else:
652 return True
653
654 path = self.me_dir
655 if os.path.isfile(os.path.join(path,args[0])):
656 args[0] = os.path.join(path,args[0])
657 elif os.path.isfile(os.path.join(path,'Cards',args[0])):
658 args[0] = os.path.join(path,'Cards',args[0])
659 elif os.path.isfile(os.path.join(path,'HTML',args[0])):
660 args[0] = os.path.join(path,'HTML',args[0])
661
662 elif '_card.dat' in args[0]:
663 name = args[0].replace('_card.dat','_card_default.dat')
664 if os.path.isfile(os.path.join(path,'Cards', name)):
665 files.cp(os.path.join(path,'Cards', name), os.path.join(path,'Cards', args[0]))
666 args[0] = os.path.join(path,'Cards', args[0])
667 else:
668 raise self.InvalidCmd('No default path for this file')
669 elif not os.path.isfile(args[0]):
670 raise self.InvalidCmd('No default path for this file')
671
673 """ check initMadLoop command arguments are valid."""
674
675 opt = {'refresh': False, 'nPS': None, 'force': False}
676
677 for arg in args:
678 if arg in ['-r','--refresh']:
679 opt['refresh'] = True
680 if arg in ['-f','--force']:
681 opt['force'] = True
682 elif arg.startswith('--nPS='):
683 n_attempts = arg.split('=')[1]
684 try:
685 opt['nPS'] = int(n_attempts)
686 except ValueError:
687 raise InvalidCmd("The number of attempts specified "+
688 "'%s' is not a valid integer."%n_attempts)
689
690 return opt
691
693 """check that treatcards arguments are valid
694 [param|run|all] [--output_dir=] [--param_card=] [--run_card=]
695 """
696
697 opt = {'output_dir':pjoin(self.me_dir,'Source'),
698 'param_card':pjoin(self.me_dir,'Cards','param_card.dat'),
699 'run_card':pjoin(self.me_dir,'Cards','run_card.dat'),
700 'forbid_MadLoopInit': False}
701 mode = 'all'
702 for arg in args:
703 if arg.startswith('--') and '=' in arg:
704 key,value =arg[2:].split('=',1)
705 if not key in opt:
706 self.help_treatcards()
707 raise self.InvalidCmd('Invalid option for treatcards command:%s ' \
708 % key)
709 if key in ['param_card', 'run_card']:
710 if os.path.isfile(value):
711 card_name = self.detect_card_type(value)
712 if card_name != key:
713 raise self.InvalidCmd('Format for input file detected as %s while expecting %s'
714 % (card_name, key))
715 opt[key] = value
716 elif os.path.isfile(pjoin(self.me_dir,value)):
717 card_name = self.detect_card_type(pjoin(self.me_dir,value))
718 if card_name != key:
719 raise self.InvalidCmd('Format for input file detected as %s while expecting %s'
720 % (card_name, key))
721 opt[key] = value
722 else:
723 raise self.InvalidCmd('No such file: %s ' % value)
724 elif key in ['output_dir']:
725 if os.path.isdir(value):
726 opt[key] = value
727 elif os.path.isdir(pjoin(self.me_dir,value)):
728 opt[key] = pjoin(self.me_dir, value)
729 else:
730 raise self.InvalidCmd('No such directory: %s' % value)
731 elif arg in ['loop','param','run','all']:
732 mode = arg
733 elif arg == '--no_MadLoopInit':
734 opt['forbid_MadLoopInit'] = True
735 else:
736 self.help_treatcards()
737 raise self.InvalidCmd('Unvalid argument %s' % arg)
738
739 return mode, opt
740
741
743 """check that the argument for survey are valid"""
744
745
746 self.opts = dict([(key,value[1]) for (key,value) in \
747 self._survey_options.items()])
748
749
750 while args and args[-1].startswith('--'):
751 arg = args.pop(-1)
752 try:
753 for opt,value in self._survey_options.items():
754 if arg.startswith('--%s=' % opt):
755 exec('self.opts[\'%s\'] = %s(arg.split(\'=\')[-1])' % \
756 (opt, value[0]))
757 arg = ""
758 if arg != "": raise Exception
759 except Exception:
760 self.help_survey()
761 raise self.InvalidCmd('invalid %s argument'% arg)
762
763 if len(args) > 1:
764 self.help_survey()
765 raise self.InvalidCmd('Too many argument for %s command' % cmd)
766 elif not args:
767
768 self.set_run_name(self.find_available_run_name(self.me_dir))
769 else:
770 self.set_run_name(args[0], None,'parton', True)
771 args.pop(0)
772
773 return True
774
776 """check that the argument for generate_events are valid"""
777
778 run = None
779 if args and args[-1].startswith('--laststep='):
780 run = args[-1].split('=')[-1]
781 if run not in ['auto','parton', 'pythia', 'pgs', 'delphes']:
782 self.help_generate_events()
783 raise self.InvalidCmd('invalid %s argument'% args[-1])
784 if run != 'parton' and not self.options['pythia-pgs_path']:
785 raise self.InvalidCmd('''pythia-pgs not install. Please install this package first.
786 To do so type: \'install pythia-pgs\' in the mg5 interface''')
787 if run == 'delphes' and not self.options['delphes_path']:
788 raise self.InvalidCmd('''delphes not install. Please install this package first.
789 To do so type: \'install Delphes\' in the mg5 interface''')
790 del args[-1]
791
792
793
794
795
796
797 return run
798
800 """check that the argument are correct"""
801
802
803 if len(args) >2:
804 self.help_time_of_flight()
805 raise self.InvalidCmd('Too many arguments')
806
807
808 if args and args[-1].startswith('--threshold='):
809 try:
810 threshold = float(args[-1].split('=')[1])
811 except ValueError:
812 raise self.InvalidCmd('threshold options require a number.')
813 args.remove(args[-1])
814 else:
815 threshold = 1e-12
816
817 if len(args) == 1 and os.path.exists(args[0]):
818 event_path = args[0]
819 else:
820 if len(args) and self.run_name != args[0]:
821 self.set_run_name(args.pop(0))
822 elif not self.run_name:
823 self.help_add_time_of_flight()
824 raise self.InvalidCmd('Need a run_name to process')
825 event_path = pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe.gz')
826 if not os.path.exists(event_path):
827 event_path = event_path[:-3]
828 if not os.path.exists(event_path):
829 raise self.InvalidCmd('No unweighted events associate to this run.')
830
831
832
833
834 args[:] = [event_path, threshold]
835
837 """check that the argument for calculate_decay_widths are valid"""
838
839 if self.ninitial != 1:
840 raise self.InvalidCmd('Can only calculate decay widths for decay processes A > B C ...')
841
842 accuracy = 0.01
843 run = None
844 if args and args[-1].startswith('--accuracy='):
845 try:
846 accuracy = float(args[-1].split('=')[-1])
847 except Exception:
848 raise self.InvalidCmd('Argument error in calculate_decay_widths command')
849 del args[-1]
850 if len(args) > 1:
851 self.help_calculate_decay_widths()
852 raise self.InvalidCmd('Too many argument for calculate_decay_widths command: %s' % cmd)
853
854 return accuracy
855
856
857
859 """check that the argument for survey are valid"""
860
861 run = None
862
863 if not len(args):
864 self.help_multi_run()
865 raise self.InvalidCmd("""multi_run command requires at least one argument for
866 the number of times that it call generate_events command""")
867
868 if args[-1].startswith('--laststep='):
869 run = args[-1].split('=')[-1]
870 if run not in ['parton', 'pythia', 'pgs', 'delphes']:
871 self.help_multi_run()
872 raise self.InvalidCmd('invalid %s argument'% args[-1])
873 if run != 'parton' and not self.options['pythia-pgs_path']:
874 raise self.InvalidCmd('''pythia-pgs not install. Please install this package first.
875 To do so type: \'install pythia-pgs\' in the mg5 interface''')
876 if run == 'delphes' and not self.options['delphes_path']:
877 raise self.InvalidCmd('''delphes not install. Please install this package first.
878 To do so type: \'install Delphes\' in the mg5 interface''')
879 del args[-1]
880
881
882 elif not args[0].isdigit():
883 self.help_multi_run()
884 raise self.InvalidCmd("The first argument of multi_run should be a integer.")
885
886 nb_run = args.pop(0)
887 args.insert(0, int(nb_run))
888
889
890 return run
891
893 """check that the argument for survey are valid"""
894
895
896 try:
897 float(args[-1])
898 except ValueError:
899 self.help_refine()
900 raise self.InvalidCmd('Not valid arguments')
901 except IndexError:
902 self.help_refine()
903 raise self.InvalidCmd('require_precision argument is require for refine cmd')
904
905
906 if not self.run_name:
907 if self.results.lastrun:
908 self.set_run_name(self.results.lastrun)
909 else:
910 raise self.InvalidCmd('No run_name currently define. Unable to run refine')
911
912 if len(args) > 2:
913 self.help_refine()
914 raise self.InvalidCmd('Too many argument for refine command')
915 else:
916 try:
917 [float(arg) for arg in args]
918 except ValueError:
919 self.help_refine()
920 raise self.InvalidCmd('refine arguments are suppose to be number')
921
922 return True
923
925 """ Check the argument for the combine events command """
926
927 tag = [a for a in arg if a.startswith('--tag=')]
928 if tag:
929 arg.remove(tag[0])
930 tag = tag[0][6:]
931 elif not self.run_tag:
932 tag = 'tag_1'
933 else:
934 tag = self.run_tag
935 self.run_tag = tag
936
937 if len(arg) > 1:
938 self.help_combine_events()
939 raise self.InvalidCmd('Too many argument for combine_events command')
940
941 if len(arg) == 1:
942 self.set_run_name(arg[0], self.run_tag, 'parton', True)
943
944 if not self.run_name:
945 if not self.results.lastrun:
946 raise self.InvalidCmd('No run_name currently define. Unable to run combine')
947 else:
948 self.set_run_name(self.results.lastrun)
949
950 return True
951
953 """Check the argument for pythia command
954 syntax: pythia [NAME]
955 Note that other option are already removed at this point
956 """
957
958 mode = None
959 laststep = [arg for arg in args if arg.startswith('--laststep=')]
960 if laststep and len(laststep)==1:
961 mode = laststep[0].split('=')[-1]
962 if mode not in ['auto', 'pythia', 'pgs', 'delphes']:
963 self.help_pythia()
964 raise self.InvalidCmd('invalid %s argument'% args[-1])
965 elif laststep:
966 raise self.InvalidCmd('only one laststep argument is allowed')
967
968 if not self.options['pythia-pgs_path']:
969 logger.info('Retry to read configuration file to find pythia-pgs path')
970 self.set_configuration()
971
972 if not self.options['pythia-pgs_path'] or not \
973 os.path.exists(pjoin(self.options['pythia-pgs_path'],'src')):
974 error_msg = 'No valid pythia-pgs path set.\n'
975 error_msg += 'Please use the set command to define the path and retry.\n'
976 error_msg += 'You can also define it in the configuration file.\n'
977 raise self.InvalidCmd(error_msg)
978
979
980
981 tag = [a for a in args if a.startswith('--tag=')]
982 if tag:
983 args.remove(tag[0])
984 tag = tag[0][6:]
985
986 if len(args) == 0 and not self.run_name:
987 if self.results.lastrun:
988 args.insert(0, self.results.lastrun)
989 else:
990 raise self.InvalidCmd('No run name currently define. Please add this information.')
991
992 if len(args) >= 1:
993 if args[0] != self.run_name and\
994 not os.path.exists(pjoin(self.me_dir,'Events',args[0], 'unweighted_events.lhe.gz')):
995 raise self.InvalidCmd('No events file corresponding to %s run. '% args[0])
996 self.set_run_name(args[0], tag, 'pythia')
997 else:
998 if tag:
999 self.run_card['run_tag'] = tag
1000 self.set_run_name(self.run_name, tag, 'pythia')
1001
1002 input_file = pjoin(self.me_dir,'Events',self.run_name, 'unweighted_events.lhe')
1003 output_file = pjoin(self.me_dir, 'Events', 'unweighted_events.lhe')
1004 if not os.path.exists('%s.gz' % input_file):
1005 if not os.path.exists(input_file):
1006 raise self.InvalidCmd('No events file corresponding to %s run. '% self.run_name)
1007 files.ln(input_file, os.path.dirname(output_file))
1008 else:
1009 misc.gunzip(input_file, keep=True, stdout=output_file)
1010
1011 args.append(mode)
1012
1014 """Check the argument for pythia command
1015 syntax: pythia8 [NAME]
1016 Note that other option are already removed at this point
1017 """
1018 mode = None
1019 laststep = [arg for arg in args if arg.startswith('--laststep=')]
1020 if laststep and len(laststep)==1:
1021 mode = laststep[0].split('=')[-1]
1022 if mode not in ['auto', 'pythia','pythia8','delphes']:
1023 self.help_pythia8()
1024 raise self.InvalidCmd('invalid %s argument'% args[-1])
1025 elif laststep:
1026 raise self.InvalidCmd('only one laststep argument is allowed')
1027
1028
1029 if not self.options['pythia8_path']:
1030 logger.info('Retry reading configuration file to find pythia8 path')
1031 self.set_configuration()
1032
1033 if not self.options['pythia8_path'] or not \
1034 os.path.exists(pjoin(self.options['pythia8_path'],'bin','pythia8-config')):
1035 error_msg = 'No valid pythia8 path set.\n'
1036 error_msg += 'Please use the set command to define the path and retry.\n'
1037 error_msg += 'You can also define it in the configuration file.\n'
1038 error_msg += 'Finally, it can be installed automatically using the'
1039 error_msg += ' install command.\n'
1040 raise self.InvalidCmd(error_msg)
1041
1042 tag = [a for a in args if a.startswith('--tag=')]
1043 if tag:
1044 args.remove(tag[0])
1045 tag = tag[0][6:]
1046
1047 if len(args) == 0 and not self.run_name:
1048 if self.results.lastrun:
1049 args.insert(0, self.results.lastrun)
1050 else:
1051 raise self.InvalidCmd('No run name currently define. '+
1052 'Please add this information.')
1053
1054 if len(args) >= 1:
1055 if args[0] != self.run_name and\
1056 not os.path.exists(pjoin(self.me_dir,'Events',args[0],
1057 'unweighted_events.lhe.gz')):
1058 raise self.InvalidCmd('No events file corresponding to %s run. '
1059 % args[0])
1060 self.set_run_name(args[0], tag, 'pythia8')
1061 else:
1062 if tag:
1063 self.run_card['run_tag'] = tag
1064 self.set_run_name(self.run_name, tag, 'pythia8')
1065
1066 input_file = pjoin(self.me_dir,'Events',self.run_name, 'unweighted_events.lhe')
1067 if not os.path.exists('%s.gz'%input_file):
1068 if os.path.exists(input_file):
1069 misc.gzip(input_file, stdout='%s.gz'%input_file)
1070 else:
1071 raise self.InvalidCmd('No event file corresponding to %s run. '
1072 % self.run_name)
1073
1074 args.append(mode)
1075
1077 """Check that the remove command is valid"""
1078
1079 tmp_args = args[:]
1080
1081 tag = [a[6:] for a in tmp_args if a.startswith('--tag=')]
1082 if tag:
1083 tag = tag[0]
1084 tmp_args.remove('--tag=%s' % tag)
1085
1086
1087 if len(tmp_args) == 0:
1088 self.help_remove()
1089 raise self.InvalidCmd('clean command require the name of the run to clean')
1090 elif len(tmp_args) == 1:
1091 return tmp_args[0], tag, ['all']
1092 else:
1093 for arg in tmp_args[1:]:
1094 if arg not in self._clean_mode:
1095 self.help_remove()
1096 raise self.InvalidCmd('%s is not a valid options for clean command'\
1097 % arg)
1098 return tmp_args[0], tag, tmp_args[1:]
1099
1101 """Check the argument for the plot command
1102 plot run_name modes"""
1103
1104 madir = self.options['madanalysis_path']
1105 td = self.options['td_path']
1106
1107 if not madir or not td:
1108 logger.info('Retry to read configuration file to find madanalysis/td')
1109 self.set_configuration()
1110
1111 madir = self.options['madanalysis_path']
1112 td = self.options['td_path']
1113
1114 if not madir:
1115 error_msg = 'No valid MadAnalysis path set.\n'
1116 error_msg += 'Please use the set command to define the path and retry.\n'
1117 error_msg += 'You can also define it in the configuration file.\n'
1118 raise self.InvalidCmd(error_msg)
1119 if not td:
1120 error_msg = 'No valid td path set.\n'
1121 error_msg += 'Please use the set command to define the path and retry.\n'
1122 error_msg += 'You can also define it in the configuration file.\n'
1123 raise self.InvalidCmd(error_msg)
1124
1125 if len(args) == 0:
1126 if not hasattr(self, 'run_name') or not self.run_name:
1127 self.help_plot()
1128 raise self.InvalidCmd('No run name currently define. Please add this information.')
1129 args.append('all')
1130 return
1131
1132
1133 if args[0] not in self._plot_mode:
1134 self.set_run_name(args[0], level='plot')
1135 del args[0]
1136 if len(args) == 0:
1137 args.append('all')
1138 elif not self.run_name:
1139 self.help_plot()
1140 raise self.InvalidCmd('No run name currently define. Please add this information.')
1141
1142 for arg in args:
1143 if arg not in self._plot_mode and arg != self.run_name:
1144 self.help_plot()
1145 raise self.InvalidCmd('unknown options %s' % arg)
1146
1148 """Check the argument for the syscalc command
1149 syscalc run_name modes"""
1150
1151 scdir = self.options['syscalc_path']
1152
1153 if not scdir:
1154 logger.info('Retry to read configuration file to find SysCalc')
1155 self.set_configuration()
1156
1157 scdir = self.options['syscalc_path']
1158
1159 if not scdir:
1160 error_msg = 'No valid SysCalc path set.\n'
1161 error_msg += 'Please use the set command to define the path and retry.\n'
1162 error_msg += 'You can also define it in the configuration file.\n'
1163 error_msg += 'Please note that you need to compile SysCalc first.'
1164 raise self.InvalidCmd(error_msg)
1165
1166 if len(args) == 0:
1167 if not hasattr(self, 'run_name') or not self.run_name:
1168 self.help_syscalc()
1169 raise self.InvalidCmd('No run name currently defined. Please add this information.')
1170 args.append('all')
1171 return
1172
1173
1174 tag = [a for a in args if a.startswith('--tag=')]
1175 if tag:
1176 args.remove(tag[0])
1177 tag = tag[0][6:]
1178
1179 if args[0] not in self._syscalc_mode:
1180 self.set_run_name(args[0], tag=tag, level='syscalc')
1181 del args[0]
1182 if len(args) == 0:
1183 args.append('all')
1184 elif not self.run_name:
1185 self.help_syscalc()
1186 raise self.InvalidCmd('No run name currently defined. Please add this information.')
1187 elif tag and tag != self.run_tag:
1188 self.set_run_name(self.run_name, tag=tag, level='syscalc')
1189
1190 for arg in args:
1191 if arg not in self._syscalc_mode and arg != self.run_name:
1192 self.help_syscalc()
1193 raise self.InvalidCmd('unknown options %s' % arg)
1194
1195 if self.run_card['use_syst'] not in self.true:
1196 raise self.InvalidCmd('Run %s does not include ' % self.run_name + \
1197 'systematics information needed for syscalc.')
1198
1199
1200 - def check_pgs(self, arg, no_default=False):
1201 """Check the argument for pythia command
1202 syntax is "pgs [NAME]"
1203 Note that other option are already remove at this point
1204 """
1205
1206
1207 if not self.options['pythia-pgs_path']:
1208 logger.info('Retry to read configuration file to find pythia-pgs path')
1209 self.set_configuration()
1210
1211 if not self.options['pythia-pgs_path'] or not \
1212 os.path.exists(pjoin(self.options['pythia-pgs_path'],'src')):
1213 error_msg = 'No valid pythia-pgs path set.\n'
1214 error_msg += 'Please use the set command to define the path and retry.\n'
1215 error_msg += 'You can also define it in the configuration file.\n'
1216 raise self.InvalidCmd(error_msg)
1217
1218 tag = [a for a in arg if a.startswith('--tag=')]
1219 if tag:
1220 arg.remove(tag[0])
1221 tag = tag[0][6:]
1222
1223
1224 if len(arg) == 0 and not self.run_name:
1225 if self.results.lastrun:
1226 arg.insert(0, self.results.lastrun)
1227 else:
1228 raise self.InvalidCmd('No run name currently define. Please add this information.')
1229
1230 if len(arg) == 1 and self.run_name == arg[0]:
1231 arg.pop(0)
1232
1233 if not len(arg) and \
1234 not os.path.exists(pjoin(self.me_dir,'Events','pythia_events.hep')):
1235 if not no_default:
1236 self.help_pgs()
1237 raise self.InvalidCmd('''No file file pythia_events.hep currently available
1238 Please specify a valid run_name''')
1239
1240 lock = None
1241 if len(arg) == 1:
1242 prev_tag = self.set_run_name(arg[0], tag, 'pgs')
1243 if not os.path.exists(pjoin(self.me_dir,'Events',self.run_name,'%s_pythia_events.hep.gz' % prev_tag)):
1244 raise self.InvalidCmd('No events file corresponding to %s run with tag %s. '% (self.run_name, prev_tag))
1245 else:
1246 input_file = pjoin(self.me_dir,'Events', self.run_name, '%s_pythia_events.hep.gz' % prev_tag)
1247 output_file = pjoin(self.me_dir, 'Events', 'pythia_events.hep')
1248 lock = cluster.asyncrone_launch('gunzip',stdout=open(output_file,'w'),
1249 argument=['-c', input_file])
1250
1251 else:
1252 if tag:
1253 self.run_card['run_tag'] = tag
1254 self.set_run_name(self.run_name, tag, 'pgs')
1255
1256 return lock
1257
1259 """check the validity of line
1260 syntax is "display XXXXX"
1261 """
1262
1263 if len(args) < 1 or args[0] not in self._display_opts:
1264 self.help_display()
1265 raise self.InvalidCmd
1266
1267 if args[0] == 'variable' and len(args) !=2:
1268 raise self.InvalidCmd('variable need a variable name')
1269
1270
1271
1272
1273
1275 """check the validity of line"""
1276
1277 if not args:
1278 self.help_import()
1279 raise self.InvalidCmd('wrong \"import\" format')
1280
1281 if args[0] != 'command':
1282 args.insert(0,'command')
1283
1284
1285 if not len(args) == 2 or not os.path.exists(args[1]):
1286 raise self.InvalidCmd('PATH is mandatory for import command\n')
1287
1293 """ The Series of help routine for the MadGraphCmd"""
1294
1295
1297 "Complete command"
1298
1299 args = self.split_arg(line[0:begidx], error=False)
1300
1301 if len(args) == 1:
1302
1303 data = misc.glob(pjoin('*','unweighted_events.lhe.gz'), pjoin(self.me_dir, 'Events'))
1304 data = [n.rsplit('/',2)[1] for n in data]
1305 return self.list_completion(text, data + ['--threshold='], line)
1306 elif args[-1].endswith(os.path.sep):
1307 return self.path_completion(text,
1308 os.path.join('.',*[a for a in args \
1309 if a.endswith(os.path.sep)]))
1310 else:
1311 return self.list_completion(text, ['--threshold='], line)
1312
1314 "Complete the banner run command"
1315 try:
1316
1317
1318 args = self.split_arg(line[0:begidx], error=False)
1319
1320 if args[-1].endswith(os.path.sep):
1321 return self.path_completion(text,
1322 os.path.join('.',*[a for a in args \
1323 if a.endswith(os.path.sep)]))
1324
1325
1326 if len(args) > 1:
1327
1328 tags = misc.glob('%s_*_banner.txt' % args[1], pjoin(self.me_dir, 'Events' , args[1]))
1329 tags = ['%s' % os.path.basename(t)[len(args[1])+1:-11] for t in tags]
1330
1331 if args[-1] != '--tag=':
1332 tags = ['--tag=%s' % t for t in tags]
1333 else:
1334 return self.list_completion(text, tags)
1335 return self.list_completion(text, tags +['--name=','-f'], line)
1336
1337
1338 possibilites = {}
1339
1340 comp = self.path_completion(text, os.path.join('.',*[a for a in args \
1341 if a.endswith(os.path.sep)]))
1342 if os.path.sep in line:
1343 return comp
1344 else:
1345 possibilites['Path from ./'] = comp
1346
1347 run_list = misc.glob(pjoin('*','*_banner.txt'), pjoin(self.me_dir, 'Events'))
1348 run_list = [n.rsplit('/',2)[1] for n in run_list]
1349 possibilites['RUN Name'] = self.list_completion(text, run_list)
1350
1351 return self.deal_multiple_categories(possibilites, formatting)
1352
1353
1354 except Exception, error:
1355 print error
1356
1357
1358 - def complete_history(self, text, line, begidx, endidx):
1359 "Complete the history command"
1360
1361 args = self.split_arg(line[0:begidx], error=False)
1362
1363
1364 if args[-1].endswith(os.path.sep):
1365 return self.path_completion(text,
1366 os.path.join('.',*[a for a in args \
1367 if a.endswith(os.path.sep)]))
1368
1369 if len(args) == 1:
1370 return self.path_completion(text)
1371
1373 """ complete the open command """
1374
1375 args = self.split_arg(line[0:begidx])
1376
1377
1378 if os.path.sep in args[-1] + text:
1379 return self.path_completion(text,
1380 os.path.join('.',*[a for a in args if \
1381 a.endswith(os.path.sep)]))
1382
1383 possibility = []
1384 if self.me_dir:
1385 path = self.me_dir
1386 possibility = ['index.html']
1387 if os.path.isfile(os.path.join(path,'README')):
1388 possibility.append('README')
1389 if os.path.isdir(os.path.join(path,'Cards')):
1390 possibility += [f for f in os.listdir(os.path.join(path,'Cards'))
1391 if f.endswith('.dat')]
1392 if os.path.isdir(os.path.join(path,'HTML')):
1393 possibility += [f for f in os.listdir(os.path.join(path,'HTML'))
1394 if f.endswith('.html') and 'default' not in f]
1395 else:
1396 possibility.extend(['./','../'])
1397 if os.path.exists('ME5_debug'):
1398 possibility.append('ME5_debug')
1399 if os.path.exists('MG5_debug'):
1400 possibility.append('MG5_debug')
1401 return self.list_completion(text, possibility)
1402
1404 "Complete the set command"
1405
1406 args = self.split_arg(line[0:begidx])
1407
1408
1409 if len(args) == 1:
1410 return self.list_completion(text, self._set_options + self.options.keys() )
1411
1412 if len(args) == 2:
1413 if args[1] == 'stdout_level':
1414 return self.list_completion(text, ['DEBUG','INFO','WARNING','ERROR','CRITICAL'])
1415 else:
1416 first_set = ['None','True','False']
1417
1418 second_set = [name for name in self.path_completion(text, '.', only_dirs = True)]
1419 return self.list_completion(text, first_set + second_set)
1420 elif len(args) >2 and args[-1].endswith(os.path.sep):
1421 return self.path_completion(text,
1422 os.path.join('.',*[a for a in args if a.endswith(os.path.sep)]),
1423 only_dirs = True)
1424
1426 """ Complete the survey command """
1427
1428 if line.endswith('nb_core=') and not text:
1429 import multiprocessing
1430 max = multiprocessing.cpu_count()
1431 return [str(i) for i in range(2,max+1)]
1432
1433 return self.list_completion(text, self._run_options, line)
1434
1435 complete_refine = complete_survey
1436 complete_combine_events = complete_survey
1437 complite_store = complete_survey
1438 complete_generate_events = complete_survey
1439 complete_create_gridpack = complete_survey
1440
1442 """ Complete the generate events"""
1443
1444 if line.endswith('nb_core=') and not text:
1445 import multiprocessing
1446 max = multiprocessing.cpu_count()
1447 return [str(i) for i in range(2,max+1)]
1448 if line.endswith('laststep=') and not text:
1449 return ['parton','pythia','pgs','delphes']
1450 elif '--laststep=' in line.split()[-1] and line and line[-1] != ' ':
1451 return self.list_completion(text,['parton','pythia','pgs','delphes'],line)
1452
1453 opts = self._run_options + self._generate_options
1454 return self.list_completion(text, opts, line)
1455
1456
1458 "Complete the initMadLoop command"
1459
1460 numbers = [str(i) for i in range(10)]
1461 opts = ['-f','-r','--nPS=']
1462
1463 args = self.split_arg(line[0:begidx], error=False)
1464 if len(line) >=6 and line[begidx-6:begidx]=='--nPS=':
1465 return self.list_completion(text, numbers, line)
1466 else:
1467 return self.list_completion(text, [opt for opt in opts if not opt in
1468 line], line)
1469
1476
1478 """ Complete the calculate_decay_widths command"""
1479
1480 if line.endswith('nb_core=') and not text:
1481 import multiprocessing
1482 max = multiprocessing.cpu_count()
1483 return [str(i) for i in range(2,max+1)]
1484
1485 opts = self._run_options + self._calculate_decay_options
1486 return self.list_completion(text, opts, line)
1487
1496
1498 """complete multi run command"""
1499
1500 args = self.split_arg(line[0:begidx], error=False)
1501 if len(args) == 1:
1502 data = [str(i) for i in range(0,20)]
1503 return self.list_completion(text, data, line)
1504
1505 if line.endswith('run=') and not text:
1506 return ['parton','pythia','pgs','delphes']
1507 elif '--laststep=' in line.split()[-1] and line and line[-1] != ' ':
1508 return self.list_completion(text,['parton','pythia','pgs','delphes'],line)
1509
1510 opts = self._run_options + self._generate_options
1511 return self.list_completion(text, opts, line)
1512
1513
1514
1515 if line.endswith('nb_core=') and not text:
1516 import multiprocessing
1517 max = multiprocessing.cpu_count()
1518 return [str(i) for i in range(2,max+1)]
1519 opts = self._run_options + self._generate_options
1520 return self.list_completion(text, opts, line)
1521
1530
1548
1550 """Complete the remove command """
1551
1552 args = self.split_arg(line[0:begidx], error=False)
1553 if len(args) > 1 and (text.startswith('--t')):
1554 run = args[1]
1555 tags = ['--tag=%s' % tag['tag'] for tag in self.results[run]]
1556 return self.list_completion(text, tags)
1557 elif len(args) > 1 and '--' == args[-1]:
1558 run = args[1]
1559 tags = ['tag=%s' % tag['tag'] for tag in self.results[run]]
1560 return self.list_completion(text, tags)
1561 elif len(args) > 1 and '--tag=' == args[-1]:
1562 run = args[1]
1563 tags = [tag['tag'] for tag in self.results[run]]
1564 return self.list_completion(text, tags)
1565 elif len(args) > 1:
1566 return self.list_completion(text, self._clean_mode + ['-f','--tag='])
1567 else:
1568 data = misc.glob(pjoin('*','*_banner.txt'), pjoin(self.me_dir, 'Events'))
1569 data = [n.rsplit('/',2)[1] for n in data]
1570 return self.list_completion(text, ['all'] + data)
1571
1572
1582
1584 "Complete the pythia8 command"
1585 args = self.split_arg(line[0:begidx], error=False)
1586 if len(args) == 1:
1587
1588 data = misc.glob(pjoin('*','unweighted_events.lhe.gz'),pjoin(self.me_dir, 'Events'))
1589 data = [n.rsplit('/',2)[1] for n in data]
1590 tmp1 = self.list_completion(text, data)
1591 if not self.run_name:
1592 return tmp1
1593 else:
1594 tmp2 = self.list_completion(text, self._run_options + ['-f',
1595 '--no_default', '--tag='], line)
1596 return tmp1 + tmp2
1597 elif line[-1] != '=':
1598 return self.list_completion(text, self._run_options + ['-f',
1599 '--no_default','--tag='], line)
1600
1602 "Complete the madanalysis5 command"
1603 args = self.split_arg(line[0:begidx], error=False)
1604 if len(args) == 1:
1605
1606 data = []
1607 for name in ['unweighted_events.lhe']:
1608 data += misc.glob(pjoin('*','%s'%name), pjoin(self.me_dir, 'Events'))
1609 data += misc.glob(pjoin('*','%s.gz'%name), pjoin(self.me_dir, 'Events'))
1610 data = [n.rsplit('/',2)[1] for n in data]
1611 tmp1 = self.list_completion(text, data)
1612 if not self.run_name:
1613 return tmp1
1614 else:
1615 tmp2 = self.list_completion(text, ['-f',
1616 '--MA5_stdout_lvl=','--no_default','--tag='], line)
1617 return tmp1 + tmp2
1618 elif '--MA5_stdout_lvl=' in line and not any(arg.startswith(
1619 '--MA5_stdout_lvl=') for arg in args):
1620 return self.list_completion(text,
1621 ['--MA5_stdout_lvl=%s'%opt for opt in
1622 ['logging.INFO','logging.DEBUG','logging.WARNING',
1623 'logging.CRITICAL','90']], line)
1624 else:
1625 return self.list_completion(text, ['-f',
1626 '--MA5_stdout_lvl=','--no_default','--tag='], line)
1627
1629 "Complete the pythia command"
1630 args = self.split_arg(line[0:begidx], error=False)
1631
1632 if len(args) == 1:
1633
1634 data = misc.glob(pjoin('*','unweighted_events.lhe.gz'), pjoin(self.me_dir, 'Events'))
1635 data = [n.rsplit('/',2)[1] for n in data]
1636 tmp1 = self.list_completion(text, data)
1637 if not self.run_name:
1638 return tmp1
1639 else:
1640 tmp2 = self.list_completion(text, self._run_options + ['-f',
1641 '--no_default', '--tag='], line)
1642 return tmp1 + tmp2
1643 elif line[-1] != '=':
1644 return self.list_completion(text, self._run_options + ['-f',
1645 '--no_default','--tag='], line)
1646
1648 "Complete the pythia command"
1649 args = self.split_arg(line[0:begidx], error=False)
1650 if len(args) == 1:
1651
1652 data = misc.glob(pjoin('*', '*_pythia_events.hep.gz'), pjoin(self.me_dir, 'Events'))
1653 data = [n.rsplit('/',2)[1] for n in data]
1654 tmp1 = self.list_completion(text, data)
1655 if not self.run_name:
1656 return tmp1
1657 else:
1658 tmp2 = self.list_completion(text, self._run_options + ['-f',
1659 '--tag=' ,'--no_default'], line)
1660 return tmp1 + tmp2
1661 else:
1662 return self.list_completion(text, self._run_options + ['-f',
1663 '--tag=','--no_default'], line)
1664
1665 complete_delphes = complete_pgs
1666
1667
1668
1669
1670
1671
1672
1673
1674 -class MadEventCmd(CompleteForCmd, CmdExtended, HelpToCmd, common_run.CommonRunCmd):
1675
1676 """The command line processor of Mad Graph"""
1677
1678
1679 true = ['T','.true.',True,'true']
1680
1681 _run_options = ['--cluster','--multicore','--nb_core=','--nb_core=2', '-c', '-m']
1682 _generate_options = ['-f', '--laststep=parton', '--laststep=pythia', '--laststep=pgs', '--laststep=delphes']
1683 _calculate_decay_options = ['-f', '--accuracy=0.']
1684 _interfaced_showers = ['pythia','pythia8']
1685 _set_options = ['stdout_level','fortran_compiler','timeout']
1686 _plot_mode = ['all', 'parton','pythia','pgs','delphes','channel', 'banner']
1687 _syscalc_mode = ['all', 'parton','pythia']
1688 _clean_mode = _plot_mode
1689 _display_opts = ['run_name', 'options', 'variable', 'results']
1690 _save_opts = ['options']
1691 _initMadLoop_opts = ['-f','-r','--nPS=']
1692
1693 _survey_options = {'points':('int', 1000,'Number of points for first iteration'),
1694 'iterations':('int', 5, 'Number of iterations'),
1695 'accuracy':('float', 0.1, 'Required accuracy'),
1696 'gridpack':('str', '.false.', 'Gridpack generation')}
1697
1698 true = ['T','.true.',True,'true', 1, '1']
1699 web = False
1700 cluster_mode = 0
1701 queue = 'madgraph'
1702 nb_core = None
1703
1704 next_possibility = {
1705 'start': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]',
1706 'calculate_decay_widths [OPTIONS]',
1707 'help generate_events'],
1708 'generate_events': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]', 'pythia', 'pgs','delphes'],
1709 'calculate_decay_widths': ['calculate_decay_widths [OPTIONS]',
1710 'generate_events [OPTIONS]'],
1711 'multi_run': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]'],
1712 'survey': ['refine'],
1713 'refine': ['combine_events'],
1714 'combine_events': ['store'],
1715 'store': ['pythia'],
1716 'pythia': ['pgs', 'delphes'],
1717 'pgs': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]'],
1718 'delphes' : ['generate_events [OPTIONS]', 'multi_run [OPTIONS]']
1719 }
1720
1721
1722 - def __init__(self, me_dir = None, options={}, *completekey, **stdin):
1723 """ add information to the cmd """
1724
1725 CmdExtended.__init__(self, me_dir, options, *completekey, **stdin)
1726
1727
1728 self.mode = 'madevent'
1729 self.nb_refine=0
1730 if self.web:
1731 os.system('touch %s' % pjoin(self.me_dir,'Online'))
1732
1733 self.load_results_db()
1734 self.results.def_web_mode(self.web)
1735
1736 self.prompt = "%s>"%os.path.basename(pjoin(self.me_dir))
1737 self.configured = 0
1738 self._options = {}
1739
1740
1742 """configure web data"""
1743 self.web = True
1744 self.results.def_web_mode(True)
1745 self.force = True
1746 if os.environ['MADGRAPH_BASE']:
1747 self.options['mg5_path'] = pjoin(os.environ['MADGRAPH_BASE'],'MG5')
1748
1749
1751 """ Check that the output path is a valid madevent directory """
1752
1753 bin_path = os.path.join(path,'bin')
1754 if os.path.isfile(os.path.join(bin_path,'generate_events')):
1755 return True
1756 else:
1757 return False
1758
1759
1761 """assign all configuration variable from file
1762 loop over the different config file if config_file not define """
1763
1764 super(MadEventCmd,self).set_configuration(amcatnlo=amcatnlo,
1765 final=final, **opt)
1766
1767 if not final:
1768 return self.options
1769
1770
1771
1772
1773
1774 for key in (k for k in self.options if k.endswith('path')):
1775 path = self.options[key]
1776 if path is None or key.startswith("cluster"):
1777 continue
1778 if not os.path.isdir(path):
1779 path = pjoin(self.me_dir, self.options[key])
1780 if os.path.isdir(path):
1781 self.options[key] = None
1782 if key == "pythia-pgs_path":
1783 if not os.path.exists(pjoin(path, 'src','pythia')):
1784 logger.info("No valid pythia-pgs path found")
1785 continue
1786 elif key == "delphes_path":
1787 if not os.path.exists(pjoin(path, 'Delphes')) and not\
1788 os.path.exists(pjoin(path, 'DelphesSTDHEP')):
1789 logger.info("No valid Delphes path found")
1790 continue
1791 elif key == "madanalysis_path":
1792 if not os.path.exists(pjoin(path, 'plot_events')):
1793 logger.info("No valid MadAnalysis path found")
1794 continue
1795 elif key == "td_path":
1796 if not os.path.exists(pjoin(path, 'td')):
1797 logger.info("No valid td path found")
1798 continue
1799 elif key == "syscalc_path":
1800 if not os.path.exists(pjoin(path, 'sys_calc')):
1801 logger.info("No valid SysCalc path found")
1802 continue
1803
1804
1805 self.options[key] = os.path.realpath(path)
1806 continue
1807 else:
1808 self.options[key] = None
1809
1810
1811 return self.options
1812
1813
1867
1868
1870 """Make a run from the banner file"""
1871
1872 args = self.split_arg(line)
1873
1874 self.check_banner_run(args)
1875
1876
1877 for name in ['delphes_trigger.dat', 'delphes_card.dat',
1878 'pgs_card.dat', 'pythia_card.dat', 'madspin_card.dat',
1879 'reweight_card.dat']:
1880 try:
1881 os.remove(pjoin(self.me_dir, 'Cards', name))
1882 except Exception:
1883 pass
1884
1885 banner_mod.split_banner(args[0], self.me_dir, proc_card=False)
1886
1887
1888 if not self.force:
1889 ans = self.ask('Do you want to modify the Cards?', 'n', ['y','n'])
1890 if ans == 'n':
1891 self.force = True
1892
1893
1894 self.exec_cmd('generate_events %s %s' % (self.run_name, self.force and '-f' or ''))
1895
1896
1897
1898
1900 """Display current internal status"""
1901
1902 args = self.split_arg(line)
1903
1904 self.check_display(args)
1905
1906 if args[0] == 'run_name':
1907
1908 data = misc.glob(pjoin('*','*_banner.txt'), pjoin(self.me_dir, 'Events'))
1909 data = [n.rsplit('/',2)[1:] for n in data]
1910
1911 if data:
1912 out = {}
1913 for name, tag in data:
1914 tag = tag[len(name)+1:-11]
1915 if name in out:
1916 out[name].append(tag)
1917 else:
1918 out[name] = [tag]
1919 print 'the runs available are:'
1920 for run_name, tags in out.items():
1921 print ' run: %s' % run_name
1922 print ' tags: ',
1923 print ', '.join(tags)
1924 else:
1925 print 'No run detected.'
1926
1927 elif args[0] == 'options':
1928 outstr = " Run Options \n"
1929 outstr += " ----------- \n"
1930 for key, default in self.options_madgraph.items():
1931 value = self.options[key]
1932 if value == default:
1933 outstr += " %25s \t:\t%s\n" % (key,value)
1934 else:
1935 outstr += " %25s \t:\t%s (user set)\n" % (key,value)
1936 outstr += "\n"
1937 outstr += " MadEvent Options \n"
1938 outstr += " ---------------- \n"
1939 for key, default in self.options_madevent.items():
1940 if key in self.options:
1941 value = self.options[key]
1942 else:
1943 default = ''
1944 if value == default:
1945 outstr += " %25s \t:\t%s\n" % (key,value)
1946 else:
1947 outstr += " %25s \t:\t%s (user set)\n" % (key,value)
1948 outstr += "\n"
1949 outstr += " Configuration Options \n"
1950 outstr += " --------------------- \n"
1951 for key, default in self.options_configuration.items():
1952 value = self.options[key]
1953 if value == default:
1954 outstr += " %25s \t:\t%s\n" % (key,value)
1955 else:
1956 outstr += " %25s \t:\t%s (user set)\n" % (key,value)
1957 output.write(outstr)
1958 elif args[0] == 'results':
1959 self.do_print_results(' '.join(args[1:]))
1960 else:
1961 super(MadEventCmd, self).do_display(line, output)
1962
1963 - def do_save(self, line, check=True, to_keep={}):
1964 """Not in help: Save information to file"""
1965
1966 args = self.split_arg(line)
1967
1968 if check:
1969 self.check_save(args)
1970
1971 if args[0] == 'options':
1972
1973 to_define = {}
1974 for key, default in self.options_configuration.items():
1975 if self.options[key] != self.options_configuration[key]:
1976 to_define[key] = self.options[key]
1977
1978 if not '--auto' in args:
1979 for key, default in self.options_madevent.items():
1980 if self.options[key] != self.options_madevent[key]:
1981 to_define[key] = self.options[key]
1982
1983 if '--all' in args:
1984 for key, default in self.options_madgraph.items():
1985 if self.options[key] != self.options_madgraph[key]:
1986 to_define[key] = self.options[key]
1987 elif not '--auto' in args:
1988 for key, default in self.options_madgraph.items():
1989 if self.options[key] != self.options_madgraph[key]:
1990 logger.info('The option %s is modified [%s] but will not be written in the configuration files.' \
1991 % (key,self.options_madgraph[key]) )
1992 logger.info('If you want to make this value the default for future session, you can run \'save options --all\'')
1993 if len(args) >1 and not args[1].startswith('--'):
1994 filepath = args[1]
1995 else:
1996 filepath = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
1997 basefile = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
1998 basedir = self.me_dir
1999
2000 if to_keep:
2001 to_define = to_keep
2002 self.write_configuration(filepath, basefile, basedir, to_define)
2003
2004
2005
2006
2015
2016
2017
2018
2020 """Main Commands: launch the full chain """
2021
2022 self.banner = None
2023 args = self.split_arg(line)
2024
2025 mode = self.check_generate_events(args)
2026 switch_mode = self.ask_run_configuration(mode, args)
2027 if not args:
2028
2029 self.set_run_name(self.find_available_run_name(self.me_dir), None, 'parton')
2030 else:
2031 self.set_run_name(args[0], None, 'parton', True)
2032 args.pop(0)
2033
2034 if self.proc_characteristics['loop_induced'] and self.options['run_mode']==0:
2035
2036
2037 logger.warning(
2038 """Single-core mode not supported for loop-induced processes.
2039 Beware that MG5aMC now changes your runtime options to a multi-core mode with only one active core.""")
2040 self.do_set('run_mode 2')
2041 self.do_set('nb_core 1')
2042
2043 if self.run_card['gridpack'] in self.true:
2044
2045 gridpack_opts=[('accuracy', 0.01),
2046 ('points', 2000),
2047 ('iterations',8),
2048 ('gridpack','.true.')]
2049 logger.info('Generating gridpack with run name %s' % self.run_name)
2050 self.exec_cmd('survey %s %s' % \
2051 (self.run_name,
2052 " ".join(['--' + opt + '=' + str(val) for (opt,val) \
2053 in gridpack_opts])),
2054 postcmd=False)
2055 self.exec_cmd('combine_events', postcmd=False)
2056 self.exec_cmd('store_events', postcmd=False)
2057 self.exec_cmd('decay_events -from_cards', postcmd=False)
2058 self.exec_cmd('create_gridpack', postcmd=False)
2059 else:
2060
2061 logger.info('Generating %s events with run name %s' %
2062 (self.run_card['nevents'], self.run_name))
2063
2064 self.exec_cmd('survey %s %s' % (self.run_name,' '.join(args)),
2065 postcmd=False)
2066 nb_event = self.run_card['nevents']
2067 bypass_run=False
2068 self.exec_cmd('refine %s' % nb_event, postcmd=False)
2069 if not float(self.results.current['cross']):
2070
2071 text = '''Survey return zero cross section.
2072 Typical reasons are the following:
2073 1) A massive s-channel particle has a width set to zero.
2074 2) The pdf are zero for at least one of the initial state particles
2075 or you are using maxjetflavor=4 for initial state b:s.
2076 3) The cuts are too strong.
2077 Please check/correct your param_card and/or your run_card.'''
2078 logger_stderr.critical(text)
2079 if not self.param_card_iterator:
2080 raise ZeroResult('See https://cp3.irmp.ucl.ac.be/projects/madgraph/wiki/FAQ-General-14')
2081 else:
2082 bypass_run = True
2083
2084
2085 if not bypass_run:
2086 self.exec_cmd('refine %s' % nb_event, postcmd=False)
2087
2088 self.exec_cmd('combine_events', postcmd=False,printcmd=False)
2089 self.print_results_in_shell(self.results.current)
2090
2091 if self.run_card['use_syst']:
2092 if self.run_card['systematics_program'] == 'auto':
2093 scdir = self.options['syscalc_path']
2094 if not scdir or not os.path.exists(scdir):
2095 to_use = 'systematics'
2096 else:
2097 to_use = 'syscalc'
2098 elif self.run_card['systematics_program'].lower() in ['systematics','syscalc', 'none']:
2099 to_use = self.run_card['systematics_program']
2100 else:
2101 logger.critical('Unvalid options for systematics_program: bypass computation of systematics variations.')
2102 to_use = 'none'
2103
2104 if to_use == 'systematics':
2105 if self.run_card['systematics_arguments'] != ['']:
2106 self.exec_cmd('systematics %s %s ' % (self.run_name,
2107 ' '.join(self.run_card['systematics_arguments'])),
2108 postcmd=False, printcmd=False)
2109 else:
2110 self.exec_cmd('systematics %s --from_card' % self.run_name,
2111 postcmd=False,printcmd=False)
2112 elif to_use == 'syscalc':
2113 self.run_syscalc('parton')
2114
2115
2116 self.create_plot('parton')
2117 self.exec_cmd('store_events', postcmd=False)
2118 self.exec_cmd('reweight -from_cards', postcmd=False)
2119 self.exec_cmd('decay_events -from_cards', postcmd=False)
2120 if self.run_card['time_of_flight']>=0:
2121 self.exec_cmd("add_time_of_flight --threshold=%s" % self.run_card['time_of_flight'] ,postcmd=False)
2122
2123 if switch_mode['analysis'] == 'EXROOTANALYSIS':
2124 input = pjoin(self.me_dir, 'Events', self.run_name,'unweighted_events.lhe.gz')
2125 output = pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.root')
2126 self.create_root_file(input , output)
2127
2128 self.exec_cmd('madanalysis5_parton --no_default', postcmd=False, printcmd=False)
2129
2130 self.exec_cmd('shower --no_default', postcmd=False, printcmd=False)
2131 self.exec_cmd('madanalysis5_hadron --no_default', postcmd=False, printcmd=False)
2132 self.store_result()
2133
2134 if self.param_card_iterator:
2135 param_card_iterator = self.param_card_iterator
2136 self.param_card_iterator = []
2137 with misc.TMP_variable(self, 'allow_notification_center', False):
2138 param_card_iterator.store_entry(self.run_name, self.results.current['cross'])
2139
2140 orig_name = self.run_name
2141 for card in param_card_iterator:
2142 path = pjoin(self.me_dir,'Cards','param_card.dat')
2143 card.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2144 self.check_param_card(path, dependent=True)
2145 next_name = param_card_iterator.get_next_name(self.run_name)
2146 try:
2147 self.exec_cmd("generate_events -f %s" % next_name,
2148 precmd=True, postcmd=True,errorhandling=False)
2149 except ZeroResult:
2150 param_card_iterator.store_entry(self.run_name, 0)
2151 else:
2152 param_card_iterator.store_entry(self.run_name, self.results.current['cross'])
2153 param_card_iterator.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2154 name = misc.get_scan_name(orig_name, self.run_name)
2155 path = pjoin(self.me_dir, 'Events','scan_%s.txt' % name)
2156 logger.info("write all cross-section results in %s" % path ,'$MG:color:BLACK')
2157 param_card_iterator.write_summary(path)
2158
2159
2160 if self.allow_notification_center:
2161 misc.apple_notify('Run %s finished' % os.path.basename(self.me_dir),
2162 '%s: %s +- %s ' % (self.results.current['run_name'],
2163 self.results.current['cross'],
2164 self.results.current['error']))
2165
2167 """Compile and run MadLoop for a certain number of PS point so as to
2168 initialize MadLoop (setup the zero helicity and loop filter.)"""
2169
2170 args = line.split()
2171
2172 options = self.check_initMadLoop(args)
2173
2174 if not options['force']:
2175 self.ask_edit_cards(['MadLoopParams.dat'], mode='fixed', plot=False)
2176 self.exec_cmd('treatcards loop --no_MadLoopInit')
2177
2178 if options['refresh']:
2179 for filter in misc.glob('*Filter*',
2180 pjoin(self.me_dir,'SubProcesses','MadLoop5_resources')):
2181 logger.debug("Resetting filter '%s'."%os.path.basename(filter))
2182 os.remove(filter)
2183
2184 MLCard = banner_mod.MadLoopParam(pjoin(self.me_dir,
2185 'Cards','MadLoopParams.dat'))
2186 if options['nPS'] is None:
2187 options['nPS'] = MLCard['CheckCycle']+2
2188 elif options['nPS'] < MLCard['CheckCycle']+2:
2189 new_n_PS = MLCard['CheckCycle']+2
2190 logger.debug('Hard-setting user-defined n_PS (%d) to %d, because '\
2191 %(options['nPS'],new_n_PS)+"of the 'CheckCycle' value (%d) "%MLCard['CheckCycle']+\
2192 "specified in the ML param card.")
2193 options['nPS'] = new_n_PS
2194
2195 MadLoopInitializer.init_MadLoop(self.me_dir,n_PS=options['nPS'],
2196 subproc_prefix='PV', MG_options=self.options, interface=self)
2197
2199 """Main Commands: exec generate_events for 2>N and calculate_width for 1>N"""
2200
2201 if self.ninitial == 1:
2202 logger.info("Note that since 2.3. The launch for 1>N pass in event generation\n"+
2203 " To have the previous behavior use the calculate_decay_widths function")
2204
2205
2206 self.do_generate_events(line, *args, **opt)
2207
2209 """Have a nice results prints in the shell,
2210 data should be of type: gen_crossxhtml.OneTagResults"""
2211
2212 if not data:
2213 return
2214
2215 if data['run_statistics']:
2216 globalstat = sum_html.RunStatistics()
2217
2218 logger.info(" " )
2219 logger.debug(" === Run statistics summary ===")
2220 for key, value in data['run_statistics'].items():
2221 globalstat.aggregate_statistics(value)
2222 level = 5
2223 if value.has_warning():
2224 level = 10
2225 logger.log(level, value.nice_output(str('/'.join([key[0],'G%s'%key[1]]))).\
2226 replace(' statistics',''))
2227 logger.info(" " )
2228 logger.debug(globalstat.nice_output('combined', no_warning=True))
2229 if globalstat.has_warning():
2230 logger.warning(globalstat.get_warning_text())
2231 logger.info(" ")
2232
2233
2234 logger.info(" === Results Summary for run: %s tag: %s ===\n" % (data['run_name'],data['tag']))
2235
2236 total_time = int(sum(_['cumulative_timing'] for _ in data['run_statistics'].values()))
2237 if total_time > 0:
2238 logger.info(" Cumulative sequential time for this run: %s"%misc.format_time(total_time))
2239
2240 if self.ninitial == 1:
2241 logger.info(" Width : %.4g +- %.4g GeV" % (data['cross'], data['error']))
2242 else:
2243 logger.info(" Cross-section : %.4g +- %.4g pb" % (data['cross'], data['error']))
2244 logger.info(" Nb of events : %s" % data['nb_event'] )
2245
2246 if data['run_mode']=='madevent':
2247 if data['cross_pythia'] and data['nb_event_pythia']:
2248 if data['cross_pythia'] == -1:
2249 path = pjoin(self.me_dir, 'Events', self.run_name, '%s_merged_xsecs.txt' % self.run_tag)
2250 cross_sections = {}
2251 if os.path.exists(path):
2252 for line in open(path):
2253 split = line.split()
2254 if len(split)!=3:
2255 continue
2256 scale, cross, error = split
2257 cross_sections[float(scale)] = (float(cross), float(error))
2258 if len(cross_sections)>0:
2259 logger.info(' Pythia8 merged cross-sections are:')
2260 for scale in sorted(cross_sections.keys()):
2261 logger.info(' > Merging scale = %-6.4g : %-11.5g +/- %-7.2g [pb]'%\
2262 (scale,cross_sections[scale][0],cross_sections[scale][1]))
2263
2264 else:
2265 if self.ninitial == 1:
2266 logger.info(" Matched width : %.4g +- %.4g GeV" % (data['cross_pythia'], data['error_pythia']))
2267 else:
2268 logger.info(" Matched cross-section : %.4g +- %.4g pb" % (data['cross_pythia'], data['error_pythia']))
2269 logger.info(" Nb of events after matching/merging : %d" % int(data['nb_event_pythia']))
2270 if self.run_card['use_syst'] in self.true and \
2271 (int(self.run_card['ickkw'])==1 or self.run_card['ktdurham']>0.0
2272 or self.run_card['ptlund']>0.0):
2273 logger.info(" Notice that because Systematics computation is turned on, the merging did not veto events but modified their weights instead.\n"+\
2274 " The resulting hepmc/stdhep file should therefore be use with those weights.")
2275 else:
2276 logger.info(" Nb of events after merging : %s" % data['nb_event_pythia'])
2277
2278 logger.info(" " )
2279
2281 """Have a nice results prints in the shell,
2282 data should be of type: gen_crossxhtml.OneTagResults"""
2283 if not data:
2284 return
2285
2286 fsock = open(path, mode)
2287
2288 if data['run_statistics']:
2289 logger.debug(" === Run statistics summary ===")
2290 for key, value in data['run_statistics'].items():
2291 logger.debug(value.nice_output(str('/'.join([key[0],'G%s'%key[1]]))).\
2292 replace(' statistics',''))
2293 logger.info(" " )
2294
2295 if format == "full":
2296 fsock.write(" === Results Summary for run: %s tag: %s process: %s ===\n" % \
2297 (data['run_name'],data['tag'], os.path.basename(self.me_dir)))
2298
2299 if self.ninitial == 1:
2300 fsock.write(" Width : %.4g +- %.4g GeV\n" % (data['cross'], data['error']))
2301 else:
2302 fsock.write(" Cross-section : %.4g +- %.4g pb\n" % (data['cross'], data['error']))
2303 fsock.write(" Nb of events : %s\n" % data['nb_event'] )
2304 if data['cross_pythia'] and data['nb_event_pythia']:
2305 if self.ninitial == 1:
2306 fsock.write(" Matched Width : %.4g +- %.4g GeV\n" % (data['cross_pythia'], data['error_pythia']))
2307 else:
2308 fsock.write(" Matched Cross-section : %.4g +- %.4g pb\n" % (data['cross_pythia'], data['error_pythia']))
2309 fsock.write(" Nb of events after Matching : %s\n" % data['nb_event_pythia'])
2310 fsock.write(" \n" )
2311 elif format == "short":
2312 if mode == "w":
2313 fsock.write("# run_name tag cross error Nb_event cross_after_matching nb_event_after matching\n")
2314
2315 if data['cross_pythia'] and data['nb_event_pythia']:
2316 text = "%(run_name)s %(tag)s %(cross)s %(error)s %(nb_event)s %(cross_pythia)s %(nb_event_pythia)s\n"
2317 else:
2318 text = "%(run_name)s %(tag)s %(cross)s %(error)s %(nb_event)s\n"
2319 fsock.write(text % data)
2320
2321
2323 """Main Commands: launch decay width calculation and automatic inclusion of
2324 calculated widths and BRs in the param_card."""
2325
2326 args = self.split_arg(line)
2327
2328 accuracy = self.check_calculate_decay_widths(args)
2329 self.ask_run_configuration('parton')
2330 self.banner = None
2331 if not args:
2332
2333 self.set_run_name(self.find_available_run_name(self.me_dir))
2334 else:
2335 self.set_run_name(args[0], reload_card=True)
2336 args.pop(0)
2337
2338 self.configure_directory()
2339
2340
2341 opts=[('accuracy', accuracy),
2342 ('points', 1000),
2343 ('iterations',9)]
2344
2345 logger.info('Calculating decay widths with run name %s' % self.run_name)
2346
2347 self.exec_cmd('survey %s %s' % \
2348 (self.run_name,
2349 " ".join(['--' + opt + '=' + str(val) for (opt,val) \
2350 in opts])),
2351 postcmd=False)
2352 self.refine_mode = "old"
2353 self.exec_cmd('combine_events', postcmd=False)
2354 self.exec_cmd('store_events', postcmd=False)
2355
2356 self.collect_decay_widths()
2357 self.print_results_in_shell(self.results.current)
2358 self.update_status('calculate_decay_widths done',
2359 level='parton', makehtml=False)
2360
2361
2362
2364 """ Collect the decay widths and calculate BRs for all particles, and put
2365 in param_card form.
2366 """
2367
2368 particle_dict = {}
2369 run_name = self.run_name
2370
2371
2372 for P_path in SubProcesses.get_subP(self.me_dir):
2373 ids = SubProcesses.get_subP_ids(P_path)
2374
2375
2376
2377 nb_output = len(ids) / (len(set([p[0] for p in ids])))
2378 results = open(pjoin(P_path, run_name + '_results.dat')).read().split('\n')[0]
2379 result = float(results.strip().split(' ')[0])
2380 for particles in ids:
2381 try:
2382 particle_dict[particles[0]].append([particles[1:], result/nb_output])
2383 except KeyError:
2384 particle_dict[particles[0]] = [[particles[1:], result/nb_output]]
2385
2386 self.update_width_in_param_card(particle_dict,
2387 initial = pjoin(self.me_dir, 'Cards', 'param_card.dat'),
2388 output=pjoin(self.me_dir, 'Events', run_name, "param_card.dat"))
2389
2390 @staticmethod
2392
2393
2394 if not output:
2395 output = initial
2396
2397 param_card_file = open(initial)
2398 param_card = param_card_file.read().split('\n')
2399 param_card_file.close()
2400
2401 decay_lines = []
2402 line_number = 0
2403
2404 while line_number < len(param_card):
2405 line = param_card[line_number]
2406 if line.lower().startswith('decay'):
2407
2408
2409 line = param_card.pop(line_number)
2410 line = line.split()
2411 particle = 0
2412 if int(line[1]) not in decay_info:
2413 try:
2414 particle = int(line[1])
2415 width = float(line[2])
2416 except Exception:
2417 particle = 0
2418
2419 line = param_card[line_number]
2420 while line.startswith('#') or line.startswith(' '):
2421 line = param_card.pop(line_number)
2422 if not particle or line.startswith('#'):
2423 line=param_card[line_number]
2424 continue
2425
2426 line = line.split()
2427 try:
2428 partial_width = float(line[0])*width
2429 decay_products = [int(p) for p in line[2:2+int(line[1])]]
2430 except Exception:
2431 line=param_card[line_number]
2432 continue
2433 try:
2434 decay_info[particle].append([decay_products, partial_width])
2435 except KeyError:
2436 decay_info[particle] = [[decay_products, partial_width]]
2437 if line_number == len(param_card):
2438 break
2439 line=param_card[line_number]
2440 if particle and particle not in decay_info:
2441
2442 decay_info[particle] = [[[], width]]
2443 else:
2444 line_number += 1
2445
2446 while not param_card[-1] or param_card[-1].startswith('#'):
2447 param_card.pop(-1)
2448
2449
2450 param_card.append("#\n#*************************")
2451 param_card.append("# Decay widths *")
2452 param_card.append("#*************************")
2453 for key in sorted(decay_info.keys()):
2454 width = sum([r for p,r in decay_info[key]])
2455 param_card.append("#\n# PDG Width")
2456 param_card.append("DECAY %i %e" % (key, width.real))
2457 if not width:
2458 continue
2459 if decay_info[key][0][0]:
2460 param_card.append("# BR NDA ID1 ID2 ...")
2461 brs = [[(val[1]/width).real, val[0]] for val in decay_info[key] if val[1]]
2462 for val in sorted(brs, reverse=True):
2463 param_card.append(" %e %i %s # %s" %
2464 (val[0].real, len(val[1]),
2465 " ".join([str(v) for v in val[1]]),
2466 val[0] * width
2467 ))
2468 decay_table = open(output, 'w')
2469 decay_table.write("\n".join(param_card) + "\n")
2470 decay_table.close()
2471 logger.info("Results written to %s" % output)
2472
2473
2474
2476
2477 args = self.split_arg(line)
2478
2479 mode = self.check_multi_run(args)
2480 nb_run = args.pop(0)
2481 if nb_run == 1:
2482 logger.warn("'multi_run 1' command is not optimal. Think of using generate_events instead")
2483 self.ask_run_configuration(mode)
2484
2485 self.check_survey(args, cmd='multi_run')
2486 main_name = self.run_name
2487
2488 path=pjoin(self.me_dir, 'Cards', 'param_card.dat')
2489 self.check_param_card(path, run=False)
2490
2491 param_card_iterator, self.param_card_iterator = self.param_card_iterator, []
2492
2493 crossoversig = 0
2494 inv_sq_err = 0
2495 nb_event = 0
2496 for i in range(nb_run):
2497 self.nb_refine = 0
2498 self.exec_cmd('generate_events %s_%s -f' % (main_name, i), postcmd=False)
2499
2500 nb_event += int(self.results[self.run_name][-1]['nb_event'])
2501 self.results.add_detail('nb_event', nb_event , run=main_name)
2502 cross = self.results[self.run_name][-1]['cross']
2503 error = self.results[self.run_name][-1]['error'] + 1e-99
2504 crossoversig+=cross/error**2
2505 inv_sq_err+=1.0/error**2
2506 self.results[main_name][-1]['cross'] = crossoversig/inv_sq_err
2507 self.results[main_name][-1]['error'] = math.sqrt(1.0/inv_sq_err)
2508 self.results.def_current(main_name)
2509 self.run_name = main_name
2510 self.update_status("Merging LHE files", level='parton')
2511 try:
2512 os.mkdir(pjoin(self.me_dir,'Events', self.run_name))
2513 except Exception:
2514 pass
2515 os.system('%(bin)s/merge.pl %(event)s/%(name)s_*/unweighted_events.lhe.gz %(event)s/%(name)s/unweighted_events.lhe.gz %(event)s/%(name)s_banner.txt'
2516 % {'bin': self.dirbin, 'event': pjoin(self.me_dir,'Events'),
2517 'name': self.run_name})
2518
2519 eradir = self.options['exrootanalysis_path']
2520 if eradir and misc.is_executable(pjoin(eradir,'ExRootLHEFConverter')):
2521 self.update_status("Create Root file", level='parton')
2522 misc.gunzip('%s/%s/unweighted_events.lhe.gz' %
2523 (pjoin(self.me_dir,'Events'), self.run_name))
2524
2525 self.create_root_file('%s/unweighted_events.lhe' % self.run_name,
2526 '%s/unweighted_events.root' % self.run_name)
2527
2528 path = pjoin(self.me_dir, "Events", self.run_name, "unweighted_events.lhe")
2529 self.create_plot('parton', path,
2530 pjoin(self.me_dir, 'HTML',self.run_name, 'plots_parton.html')
2531 )
2532
2533
2534 if not os.path.exists('%s.gz' % path):
2535 misc.gzip(path)
2536
2537 self.update_status('', level='parton')
2538 self.print_results_in_shell(self.results.current)
2539
2540 if param_card_iterator:
2541
2542 param_card_iterator.store_entry(self.run_name, self.results.current['cross'])
2543
2544 orig_name=self.run_name
2545 for card in param_card_iterator:
2546 card.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2547 self.exec_cmd("multi_run %s -f " % nb_run ,precmd=True, postcmd=True,errorhandling=False)
2548 param_card_iterator.store_entry(self.run_name, self.results.current['cross'])
2549 param_card_iterator.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2550 scan_name = misc.get_scan_name(orig_name, self.run_name)
2551 path = pjoin(self.me_dir, 'Events','scan_%s.txt' % scan_name)
2552 logger.info("write all cross-section results in %s" % path, '$MG:color:BLACK')
2553 param_card_iterator.write_summary(path)
2554
2555
2556
2558 """Advanced commands: create .inc files from param_card.dat/run_card.dat"""
2559
2560 if not mode and not opt:
2561 args = self.split_arg(line)
2562 mode, opt = self.check_treatcards(args)
2563
2564
2565
2566
2567 need_MadLoopFilterUpdate = False
2568
2569
2570 type_of_change = ''
2571 if not opt['forbid_MadLoopInit'] and self.proc_characteristics['loop_induced'] \
2572 and mode in ['loop', 'all']:
2573 paramDat = pjoin(self.me_dir, 'Cards','param_card.dat')
2574 paramInc = pjoin(opt['output_dir'], 'param_card.inc')
2575 if (not os.path.isfile(paramDat)) or (not os.path.isfile(paramInc)) or \
2576 (os.path.getmtime(paramDat)-os.path.getmtime(paramInc)) > 0.0:
2577 need_MadLoopFilterUpdate = True
2578 type_of_change = 'model'
2579
2580 ML_in = pjoin(self.me_dir, 'Cards', 'MadLoopParams.dat')
2581 ML_out = pjoin(self.me_dir,"SubProcesses",
2582 "MadLoop5_resources", "MadLoopParams.dat")
2583 if (not os.path.isfile(ML_in)) or (not os.path.isfile(ML_out)) or \
2584 (os.path.getmtime(ML_in)-os.path.getmtime(ML_out)) > 0.0:
2585 need_MadLoopFilterUpdate = True
2586 type_of_change = 'MadLoop'
2587
2588
2589 self.check_param_card(pjoin(self.me_dir, 'Cards','param_card.dat'))
2590
2591 if mode in ['param', 'all']:
2592 model = self.find_model_name()
2593 tmp_model = os.path.basename(model)
2594 if tmp_model == 'mssm' or tmp_model.startswith('mssm-'):
2595 if not '--param_card=' in line:
2596 param_card = pjoin(self.me_dir, 'Cards','param_card.dat')
2597 mg5_param = pjoin(self.me_dir, 'Source', 'MODEL', 'MG5_param.dat')
2598 check_param_card.convert_to_mg5card(param_card, mg5_param)
2599 check_param_card.check_valid_param_card(mg5_param)
2600 opt['param_card'] = pjoin(self.me_dir, 'Source', 'MODEL', 'MG5_param.dat')
2601 else:
2602 check_param_card.check_valid_param_card(opt['param_card'])
2603
2604 logger.debug('write compile file for card: %s' % opt['param_card'])
2605 param_card = check_param_card.ParamCard(opt['param_card'])
2606 outfile = pjoin(opt['output_dir'], 'param_card.inc')
2607 ident_card = pjoin(self.me_dir,'Cards','ident_card.dat')
2608 if os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')):
2609 default = pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')
2610 elif os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')):
2611 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
2612 elif not os.path.exists(pjoin(self.me_dir,'bin','internal','ufomodel')):
2613 fsock = open(pjoin(self.me_dir,'Source','param_card.inc'),'w')
2614 fsock.write(' ')
2615 fsock.close()
2616 if mode == 'all':
2617 self.do_treatcards('', 'run', opt)
2618 return
2619 else:
2620 devnull = open(os.devnull,'w')
2621 subprocess.call([sys.executable, 'write_param_card.py'],
2622 cwd=pjoin(self.me_dir,'bin','internal','ufomodel'),
2623 stdout=devnull)
2624 devnull.close()
2625 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
2626
2627 need_mp = self.proc_characteristics['loop_induced']
2628 param_card.write_inc_file(outfile, ident_card, default, need_mp=need_mp)
2629
2630
2631 if mode in ['run', 'all']:
2632 if not hasattr(self, 'run_card'):
2633 run_card = banner_mod.RunCard(opt['run_card'])
2634 else:
2635 run_card = self.run_card
2636 if self.ninitial == 1:
2637 run_card['lpp1'] = 0
2638 run_card['lpp2'] = 0
2639 run_card['ebeam1'] = 0
2640 run_card['ebeam2'] = 0
2641
2642
2643
2644 if run_card['bias_module'].lower() not in ['dummy','none']:
2645
2646 bias_module_path = pjoin(self.me_dir,'Source','BIAS',
2647 os.path.basename(run_card['bias_module']))
2648 if not os.path.isdir(bias_module_path):
2649 if not os.path.isdir(run_card['bias_module']):
2650 raise InvalidCmd("The bias module at '%s' cannot be found."%run_card['bias_module'])
2651 else:
2652 for mandatory_file in ['makefile','%s.f'%os.path.basename(run_card['bias_module'])]:
2653 if not os.path.isfile(pjoin(run_card['bias_module'],mandatory_file)):
2654 raise InvalidCmd("Could not find the mandatory file '%s' in bias module '%s'."%(
2655 mandatory_file,run_card['bias_module']))
2656 shutil.copytree(run_card['bias_module'], pjoin(self.me_dir,'Source','BIAS',
2657 os.path.basename(run_card['bias_module'])))
2658
2659
2660 default_bias_parameters = {}
2661 start, last = False,False
2662 for line in open(pjoin(bias_module_path,'%s.f'%os.path.basename(bias_module_path))):
2663 if start and last:
2664 break
2665 if not start and not re.search('c\s*parameters\s*=\s*{',line, re.I):
2666 continue
2667 start = True
2668 if not line.startswith('C'):
2669 continue
2670 line = line[1:]
2671 if '{' in line:
2672 line = line.split('{')[-1]
2673
2674 split_result = re.split('(\}|!|\#)', line,1, re.M)
2675 line = split_result[0]
2676 sep = split_result[1] if len(split_result)>1 else None
2677 if sep == '}':
2678 last = True
2679 if ',' in line:
2680 for pair in line.split(','):
2681 if not pair.strip():
2682 continue
2683 x,y =pair.split(':')
2684 x=x.strip()
2685 if x.startswith(('"',"'")) and x.endswith(x[0]):
2686 x = x[1:-1]
2687 default_bias_parameters[x] = y
2688 elif ':' in line:
2689 x,y = line.split(':')
2690 x = x.strip()
2691 if x.startswith(('"',"'")) and x.endswith(x[0]):
2692 x = x[1:-1]
2693 default_bias_parameters[x] = y
2694 for key,value in run_card['bias_parameters'].items():
2695 if key not in default_bias_parameters:
2696 logger.warning('%s not supported by the bias module. We discard this entry.', key)
2697 else:
2698 default_bias_parameters[key] = value
2699 run_card['bias_parameters'] = default_bias_parameters
2700
2701
2702
2703 run_card.write_include_file(opt['output_dir'])
2704
2705
2706 if self.proc_characteristics['loop_induced'] and mode in ['loop', 'all']:
2707 self.MadLoopparam = banner_mod.MadLoopParam(pjoin(self.me_dir,
2708 'Cards', 'MadLoopParams.dat'))
2709
2710
2711
2712
2713 if 'WriteOutFilters' in self.MadLoopparam.user_set and \
2714 self.MadLoopparam.get('WriteOutFilters'):
2715 logger.info(
2716 """You chose to have MadLoop writing out filters.
2717 Beware that this can be dangerous for local multicore runs.""")
2718 self.MadLoopparam.set('WriteOutFilters',False, changeifuserset=False)
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739 self.MadLoopparam.set('HelicityFilterLevel',1, changeifuserset=False)
2740
2741
2742
2743 self.MadLoopparam.set('CheckCycle',4, changeifuserset=False)
2744
2745
2746
2747
2748
2749 self.MadLoopparam.set('DoubleCheckHelicityFilter',False,
2750 changeifuserset=False)
2751
2752
2753
2754 if not hasattr(self, 'run_card'):
2755 run_card = banner_mod.RunCard(opt['run_card'])
2756 else:
2757 run_card = self.run_card
2758 if run_card['nhel'] == 0:
2759 if 'MLReductionLib' in self.MadLoopparam.user_set and \
2760 (self.MadLoopparam.get('MLReductionLib').startswith('1') or
2761 self.MadLoopparam.get('MLReductionLib').startswith('6')):
2762 logger.warning(
2763 """You chose to set the preferred reduction technique in MadLoop to be OPP (see parameter MLReductionLib).
2764 Beware that this can bring significant slowdown; the optimal choice --when not MC over helicity-- being to first start with TIR reduction.""")
2765
2766 self.MadLoopparam.set('MLReductionLib','7|6|1', changeifuserset=False)
2767 else:
2768 if 'MLReductionLib' in self.MadLoopparam.user_set and \
2769 not (self.MadLoopparam.get('MLReductionLib').startswith('1') or
2770 self.MadLoopparam.get('MLReductionLib').startswith('6')):
2771 logger.warning(
2772 """You chose to set the preferred reduction technique in MadLoop to be different than OPP (see parameter MLReductionLib).
2773 Beware that this can bring significant slowdown; the optimal choice --when MC over helicity-- being to first start with OPP reduction.""")
2774 self.MadLoopparam.set('MLReductionLib','6|7|1', changeifuserset=False)
2775
2776
2777
2778
2779
2780 if run_card['nhel'] == 0:
2781 if ('NRotations_DP' in self.MadLoopparam.user_set and \
2782 self.MadLoopparam.get('NRotations_DP')!=0) or \
2783 ('NRotations_QP' in self.MadLoopparam.user_set and \
2784 self.MadLoopparam.get('NRotations_QP')!=0):
2785 logger.warning(
2786 """You chose to also use a lorentz rotation for stability tests (see parameter NRotations_[DP|QP]).
2787 Beware that, for optimization purposes, MadEvent uses manual TIR cache clearing which is not compatible
2788 with the lorentz rotation stability test. The number of these rotations to be used will be reset to
2789 zero by MadLoop. You can avoid this by changing the parameter 'FORCE_ML_HELICITY_SUM' int he matrix<i>.f
2790 files to be .TRUE. so that the sum over helicity configurations is performed within MadLoop (in which case
2791 the helicity of final state particles cannot be speicfied in the LHE file.""")
2792 self.MadLoopparam.set('NRotations_DP',0,changeifuserset=False)
2793 self.MadLoopparam.set('NRotations_QP',0,changeifuserset=False)
2794 else:
2795
2796
2797
2798
2799
2800
2801 self.MadLoopparam.set('NRotations_DP',1,changeifuserset=False)
2802 self.MadLoopparam.set('NRotations_QP',0,changeifuserset=False)
2803
2804
2805
2806
2807
2808
2809
2810
2811 if self.proc_characteristics['nexternal']<=4:
2812 if ('MLStabThres' in self.MadLoopparam.user_set and \
2813 self.MadLoopparam.get('MLStabThres')>1.0e-7):
2814 logger.warning(
2815 """You chose to increase the default value of the MadLoop parameter 'MLStabThres' above 1.0e-7.
2816 Stability tests can be less reliable on the limited kinematic of processes with less or equal
2817 than four external legs, so this is not recommended (especially not for g g > z z).""")
2818 self.MadLoopparam.set('MLStabThres',1.0e-7,changeifuserset=False)
2819 else:
2820 self.MadLoopparam.set('MLStabThres',1.0e-4,changeifuserset=False)
2821
2822
2823 self.MadLoopparam.write(pjoin(self.me_dir,"SubProcesses","MadLoop5_resources",
2824 "MadLoopParams.dat"))
2825
2826 if self.proc_characteristics['loop_induced'] and mode in ['loop', 'all']:
2827
2828
2829 if need_MadLoopFilterUpdate:
2830 logger.debug('Changes to the %s parameters'%type_of_change+\
2831 ' have been detected. Madevent will then now reinitialize'+\
2832 ' MadLoop filters.')
2833 self.exec_cmd('initMadLoop -r -f')
2834
2835
2836
2837
2838
2839 elif not opt['forbid_MadLoopInit'] and \
2840 MadLoopInitializer.need_MadLoopInit(self.me_dir):
2841 self.exec_cmd('initMadLoop -f')
2842
2843
2845 """Advanced commands: launch survey for the current process """
2846
2847
2848 args = self.split_arg(line)
2849
2850 self.check_survey(args)
2851
2852
2853 if os.path.exists(pjoin(self.me_dir,'error')):
2854 os.remove(pjoin(self.me_dir,'error'))
2855
2856 self.configure_directory()
2857
2858 self.random_orig = self.random
2859 logger.info("Using random number seed offset = %s" % self.random)
2860
2861 self.update_random()
2862 self.save_random()
2863 self.update_status('Running Survey', level=None)
2864 if self.cluster_mode:
2865 logger.info('Creating Jobs')
2866
2867 self.total_jobs = 0
2868 subproc = [l.strip() for l in open(pjoin(self.me_dir,
2869 'SubProcesses', 'subproc.mg'))]
2870
2871 P_zero_result = []
2872
2873
2874 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
2875 'MadLoop5_resources')) and cluster.need_transfer(self.options):
2876 tf=tarfile.open(pjoin(self.me_dir, 'SubProcesses',
2877 'MadLoop5_resources.tar.gz'), 'w:gz', dereference=True)
2878 tf.add(pjoin(self.me_dir,'SubProcesses','MadLoop5_resources'),
2879 arcname='MadLoop5_resources')
2880 tf.close()
2881
2882 logger.info('Working on SubProcesses')
2883 ajobcreator = gen_ximprove.gensym(self)
2884
2885
2886 if float(self.run_card['mmjj']) > 0.01 * (float(self.run_card['ebeam1'])+float(self.run_card['ebeam2'])):
2887 self.pass_in_difficult_integration_mode()
2888
2889 jobs, P_zero_result = ajobcreator.launch()
2890
2891
2892 if P_zero_result:
2893 if len(P_zero_result) == len(subproc):
2894 Pdir = pjoin(self.me_dir, 'SubProcesses',subproc[0].strip())
2895 raise ZeroResult, '%s' % \
2896 open(pjoin(Pdir,'ajob.no_ps.log')).read()
2897 else:
2898 logger.warning(''' %s SubProcesses doesn\'t have available phase-space.
2899 Please check mass spectrum.''' % ','.join(P_zero_result))
2900
2901
2902 self.monitor(run_type='All jobs submitted for survey', html=True)
2903 if not self.history or 'survey' in self.history[-1] or self.ninitial ==1 or \
2904 self.run_card['gridpack']:
2905
2906 cross, error = sum_html.make_all_html_results(self)
2907 self.results.add_detail('cross', cross)
2908 self.results.add_detail('error', error)
2909 self.exec_cmd("print_results %s" % self.run_name,
2910 errorhandling=False, printcmd=False, precmd=False, postcmd=False)
2911
2912 self.results.add_detail('run_statistics', dict(ajobcreator.run_statistics))
2913 self.update_status('End survey', 'parton', makehtml=False)
2914
2915
2917 """be more secure for the integration to not miss it due to strong cut"""
2918
2919
2920 if self.opts['points'] == self._survey_options['points'][1]:
2921 self.opts['points'] = 2 * self._survey_options['points'][1]
2922 if self.opts['iterations'] == self._survey_options['iterations'][1]:
2923 self.opts['iterations'] = 1 + self._survey_options['iterations'][1]
2924 if self.opts['accuracy'] == self._survey_options['accuracy'][1]:
2925 self.opts['accuracy'] = self._survey_options['accuracy'][1]/2
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939 for name in ['../bin/internal/gen_ximprove', 'all',
2940 '../bin/internal/combine_events']:
2941 self.compile(arg=[name], cwd=os.path.join(self.me_dir, 'Source'))
2942
2943
2944
2946 """Advanced commands: launch survey for the current process """
2947 devnull = open(os.devnull, 'w')
2948 self.nb_refine += 1
2949 args = self.split_arg(line)
2950
2951 self.check_refine(args)
2952
2953 refine_opt = {'err_goal': args[0], 'split_channels': True}
2954 precision = args[0]
2955 if len(args) == 2:
2956 refine_opt['max_process']= args[1]
2957
2958
2959
2960 self.configure_directory()
2961
2962
2963 self.update_random()
2964 self.save_random()
2965
2966 if self.cluster_mode:
2967 logger.info('Creating Jobs')
2968 self.update_status('Refine results to %s' % precision, level=None)
2969
2970 self.total_jobs = 0
2971 subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses',
2972 'subproc.mg'))]
2973
2974
2975 for nb_proc,subdir in enumerate(subproc):
2976 subdir = subdir.strip()
2977 Pdir = pjoin(self.me_dir, 'SubProcesses', subdir)
2978 for match in misc.glob('*ajob*', Pdir):
2979 if os.path.basename(match)[:4] in ['ajob', 'wait', 'run.', 'done']:
2980 os.remove(match)
2981
2982 x_improve = gen_ximprove.gen_ximprove(self, refine_opt)
2983
2984 survey_statistics = dict(self.results.get_detail('run_statistics'))
2985
2986 if __debug__ and survey_statistics:
2987 globalstat = sum_html.RunStatistics()
2988 logger.debug(" === Survey statistics summary ===")
2989 for key, value in survey_statistics.items():
2990 globalstat.aggregate_statistics(value)
2991 level = 5
2992 if value.has_warning():
2993 level = 10
2994 logger.log(level,
2995 value.nice_output(str('/'.join([key[0],'G%s'%key[1]]))).
2996 replace(' statistics',''))
2997 logger.debug(globalstat.nice_output('combined', no_warning=True))
2998
2999 if survey_statistics:
3000 x_improve.run_statistics = survey_statistics
3001
3002 x_improve.launch()
3003 if not self.history or 'refine' not in self.history[-1]:
3004 cross, error = x_improve.update_html()
3005 if cross == 0:
3006 return
3007 logger.info("Current estimate of cross-section: %s +- %s" % (cross, error))
3008
3009 if isinstance(x_improve, gen_ximprove.gen_ximprove_v4):
3010
3011
3012 for nb_proc,subdir in enumerate(subproc):
3013 subdir = subdir.strip()
3014 Pdir = pjoin(self.me_dir, 'SubProcesses',subdir)
3015 bindir = pjoin(os.path.relpath(self.dirbin, Pdir))
3016
3017 logger.info(' %s ' % subdir)
3018
3019 if os.path.exists(pjoin(Pdir, 'ajob1')):
3020 self.compile(['madevent'], cwd=Pdir)
3021
3022 alljobs = misc.glob('ajob*', Pdir)
3023
3024
3025 Gre = re.compile("\s*j=(G[\d\.\w]+)")
3026 for job in alljobs:
3027 Gdirs = Gre.findall(open(job).read())
3028 for Gdir in Gdirs:
3029 if os.path.exists(pjoin(Pdir, Gdir, 'results.dat')):
3030 os.remove(pjoin(Pdir, Gdir,'results.dat'))
3031
3032 nb_tot = len(alljobs)
3033 self.total_jobs += nb_tot
3034 for i, job in enumerate(alljobs):
3035 job = os.path.basename(job)
3036 self.launch_job('%s' % job, cwd=Pdir, remaining=(nb_tot-i-1),
3037 run_type='Refine number %s on %s (%s/%s)' %
3038 (self.nb_refine, subdir, nb_proc+1, len(subproc)))
3039
3040 self.monitor(run_type='All job submitted for refine number %s' % self.nb_refine,
3041 html=True)
3042
3043 self.update_status("Combining runs", level='parton')
3044 try:
3045 os.remove(pjoin(Pdir, 'combine_runs.log'))
3046 except Exception:
3047 pass
3048
3049 if isinstance(x_improve, gen_ximprove.gen_ximprove_v4):
3050
3051
3052 combine_runs.CombineRuns(self.me_dir)
3053 self.refine_mode = "old"
3054 else:
3055 self.refine_mode = "new"
3056
3057 cross, error = sum_html.make_all_html_results(self)
3058 self.results.add_detail('cross', cross)
3059 self.results.add_detail('error', error)
3060
3061 self.results.add_detail('run_statistics',
3062 dict(self.results.get_detail('run_statistics')))
3063
3064 self.update_status('finish refine', 'parton', makehtml=False)
3065 devnull.close()
3066
3067
3069 """Not in help: Combine a given iteration combine_iteration Pdir Gdir S|R step
3070 S is for survey
3071 R is for refine
3072 step is the iteration number (not very critical)"""
3073
3074 self.set_run_name("tmp")
3075 self.configure_directory(html_opening=False)
3076 Pdir, Gdir, mode, step = self.split_arg(line)
3077 if Gdir.startswith("G"):
3078 Gdir = Gdir[1:]
3079 if "SubProcesses" not in Pdir:
3080 Pdir = pjoin(self.me_dir, "SubProcesses", Pdir)
3081 if mode == "S":
3082 self.opts = dict([(key,value[1]) for (key,value) in \
3083 self._survey_options.items()])
3084 gensym = gen_ximprove.gensym(self)
3085 gensym.combine_iteration(Pdir, Gdir, int(step))
3086 elif mode == "R":
3087 refine = gen_ximprove.gen_ximprove_share(self)
3088 refine.combine_iteration(Pdir, Gdir, int(step))
3089
3090
3091
3092
3093
3095 """Advanced commands: Launch combine events"""
3096
3097 args = self.split_arg(line)
3098
3099 self.check_combine_events(args)
3100
3101 self.update_status('Combining Events', level='parton')
3102
3103
3104
3105 if self.run_card['gridpack']:
3106 try:
3107 os.remove(pjoin(self.me_dir,'SubProcesses', 'combine.log'))
3108 except Exception:
3109 pass
3110
3111 cluster.onecore.launch_and_wait('../bin/internal/run_combine',
3112 args=[self.run_name],
3113 cwd=pjoin(self.me_dir,'SubProcesses'),
3114 stdout=pjoin(self.me_dir,'SubProcesses', 'combine.log'),
3115 required_output=[pjoin(self.me_dir,'SubProcesses', 'combine.log')])
3116
3117
3118
3119
3120
3121
3122 output = misc.mult_try_open(pjoin(self.me_dir,'SubProcesses','combine.log')).read()
3123
3124 pat = re.compile(r'''\s*Unweighting\s*selected\s*(\d+)\s*events''')
3125 try:
3126 nb_event = pat.search(output).groups()[0]
3127 except AttributeError:
3128 time.sleep(10)
3129 output = misc.mult_try_open(pjoin(self.me_dir,'SubProcesses','combine.log')).read()
3130 try:
3131 nb_event = pat.search(output).groups()[0]
3132 except AttributeError:
3133 logger.warning('Fail to read the number of unweighted events in the combine.log file')
3134 nb_event = 0
3135
3136 self.results.add_detail('nb_event', nb_event)
3137
3138
3139
3140 tag = self.run_card['run_tag']
3141
3142
3143 if not self.banner:
3144 self.banner = banner_mod.recover_banner(self.results, 'parton')
3145 self.banner.load_basic(self.me_dir)
3146
3147 self.banner.add_generation_info(self.results.current['cross'], nb_event)
3148 if not hasattr(self, 'random_orig'): self.random_orig = 0
3149 self.banner.change_seed(self.random_orig)
3150 if not os.path.exists(pjoin(self.me_dir, 'Events', self.run_name)):
3151 os.mkdir(pjoin(self.me_dir, 'Events', self.run_name))
3152 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name,
3153 '%s_%s_banner.txt' % (self.run_name, tag)))
3154
3155
3156 self.banner.add_to_file(pjoin(self.me_dir,'Events', 'events.lhe'),
3157 out=pjoin(self.me_dir,'Events', self.run_name, 'events.lhe'))
3158 self.banner.add_to_file(pjoin(self.me_dir,'Events', 'unweighted_events.lhe'),
3159 out=pjoin(self.me_dir,'Events', self.run_name, 'unweighted_events.lhe'))
3160
3161 else:
3162
3163 tag = self.run_card['run_tag']
3164
3165 if not self.banner:
3166 self.banner = banner_mod.recover_banner(self.results, 'parton')
3167 self.banner.load_basic(self.me_dir)
3168
3169 self.banner.add_generation_info(self.results.current['cross'], self.run_card['nevents'])
3170 if not hasattr(self, 'random_orig'): self.random_orig = 0
3171 self.banner.change_seed(self.random_orig)
3172 if not os.path.exists(pjoin(self.me_dir, 'Events', self.run_name)):
3173 os.mkdir(pjoin(self.me_dir, 'Events', self.run_name))
3174 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name,
3175 '%s_%s_banner.txt' % (self.run_name, tag)))
3176
3177
3178 get_wgt = lambda event: event.wgt
3179 AllEvent = lhe_parser.MultiEventFile()
3180 AllEvent.banner = self.banner
3181
3182 partials = 0
3183 sum_xsec, sum_xerru, sum_axsec = 0,[],0
3184 for Gdir,mfactor in self.get_Gdir():
3185 if os.path.exists(pjoin(Gdir, 'events.lhe')):
3186 result = sum_html.OneResult('')
3187 result.read_results(pjoin(Gdir, 'results.dat'))
3188 AllEvent.add(pjoin(Gdir, 'events.lhe'),
3189 result.get('xsec'),
3190 result.get('xerru'),
3191 result.get('axsec')
3192 )
3193
3194 sum_xsec += result.get('xsec')
3195 sum_xerru.append(result.get('xerru'))
3196 sum_axsec += result.get('axsec')
3197
3198 if len(AllEvent) >= 80:
3199 AllEvent.unweight(pjoin(self.me_dir, "Events", self.run_name, "partials%s.lhe.gz" % partials),
3200 get_wgt, log_level=5, trunc_error=1e-2, event_target=self.run_card['nevents'])
3201 AllEvent = lhe_parser.MultiEventFile()
3202 AllEvent.banner = self.banner
3203 AllEvent.add(pjoin(self.me_dir, "Events", self.run_name, "partials%s.lhe.gz" % partials),
3204 sum_xsec,
3205 math.sqrt(sum(x**2 for x in sum_xerru)),
3206 sum_axsec)
3207 partials +=1
3208
3209 if not hasattr(self,'proc_characteristic'):
3210 self.proc_characteristic = self.get_characteristics()
3211
3212 nb_event = AllEvent.unweight(pjoin(self.me_dir, "Events", self.run_name, "unweighted_events.lhe.gz"),
3213 get_wgt, trunc_error=1e-2, event_target=self.run_card['nevents'],
3214 log_level=logging.DEBUG, normalization=self.run_card['event_norm'],
3215 proc_charac=self.proc_characteristic)
3216
3217 if partials:
3218 for i in range(partials):
3219 try:
3220 os.remove(pjoin(self.me_dir, "Events", self.run_name, "partials%s.lhe.gz" % i))
3221 except Exception:
3222 os.remove(pjoin(self.me_dir, "Events", self.run_name, "partials%s.lhe" % i))
3223
3224 self.results.add_detail('nb_event', nb_event)
3225
3226 if self.run_card['bias_module'].lower() not in ['dummy', 'none']:
3227 self.correct_bias()
3228
3229
3230
3231 self.to_store.append('event')
3232
3233
3235 """check the first event and correct the weight by the bias
3236 and correct the cross-section.
3237 If the event do not have the bias tag it means that the bias is
3238 one modifying the cross-section/shape so we have nothing to do
3239 """
3240
3241 lhe = lhe_parser.EventFile(pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe.gz'))
3242 init = False
3243 cross = collections.defaultdict(float)
3244 nb_event = 0
3245 for event in lhe:
3246 rwgt_info = event.parse_reweight()
3247 if not init:
3248 if 'bias' in rwgt_info:
3249 output = lhe_parser.EventFile(pjoin(self.me_dir, 'Events', self.run_name, '.unweighted_events.lhe.tmp.gz'),'w')
3250
3251 init = True
3252 else:
3253 return
3254
3255 event.wgt /= rwgt_info['bias']
3256
3257 del event.reweight_data['bias']
3258
3259 cross[event.ievent] += event.wgt
3260 nb_event +=1
3261 output.write(str(event))
3262 output.write('</LesHouchesEvents>')
3263 output.close()
3264 lhe.close()
3265
3266
3267
3268 total_cross = sum(cross[key] for key in cross)
3269 if 'event_norm' in self.run_card:
3270 if self.run_card['event_norm'] == 'average':
3271 total_cross = total_cross / nb_event
3272 for key in cross:
3273 cross[key] /= nb_event
3274 elif self.run_card['event_norm'] == 'unity':
3275 total_cross = self.results.current['cross'] * total_cross / nb_event
3276 for key in cross:
3277 cross[key] *= total_cross / nb_event
3278
3279 bannerfile = lhe_parser.EventFile(pjoin(self.me_dir, 'Events', self.run_name, '.banner.tmp.gz'),'w')
3280 banner = banner_mod.Banner(lhe.banner)
3281 banner.modify_init_cross(cross)
3282 banner.write(bannerfile, close_tag=False)
3283 bannerfile.close()
3284
3285 os.system('cat %s %s > %s' %(bannerfile.name, output.name, lhe.name))
3286 os.remove(bannerfile.name)
3287 os.remove(output.name)
3288
3289
3290 self.results.current['cross'] = total_cross
3291 self.results.current['error'] = 0
3292
3293
3295 """Advanced commands: Launch store events"""
3296
3297 args = self.split_arg(line)
3298
3299 self.check_combine_events(args)
3300 self.update_status('Storing parton level results', level='parton')
3301
3302 run = self.run_name
3303 tag = self.run_card['run_tag']
3304 devnull = open(os.devnull, 'w')
3305
3306 if not os.path.exists(pjoin(self.me_dir, 'Events', run)):
3307 os.mkdir(pjoin(self.me_dir, 'Events', run))
3308 if not os.path.exists(pjoin(self.me_dir, 'HTML', run)):
3309 os.mkdir(pjoin(self.me_dir, 'HTML', run))
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319 if self.results.current['nb_event'] == 0:
3320 logger.warning("No event detected. No cleaning performed! This should allow to run:\n" +
3321 " cd Subprocesses; ../bin/internal/combine_events\n"+
3322 " to have your events if those one are missing.")
3323 else:
3324 for P_path in SubProcesses.get_subP(self.me_dir):
3325 G_dir = [G for G in os.listdir(P_path) if G.startswith('G') and
3326 os.path.isdir(pjoin(P_path,G))]
3327 for G in G_dir:
3328 G_path = pjoin(P_path,G)
3329 try:
3330
3331 if os.path.exists(pjoin(G_path, 'events.lhe')):
3332 os.remove(pjoin(G_path, 'events.lhe'))
3333 except Exception:
3334 continue
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344 try:
3345 if os.path.exists(pjoin(G_path, 'log.txt')):
3346 input = pjoin(G_path, 'log.txt')
3347 output = pjoin(G_path, '%s_log.txt' % run)
3348 files.mv(input, output)
3349 except Exception:
3350 continue
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364 if os.path.exists(pjoin(G_path, 'ftn25')):
3365 os.remove(pjoin(G_path, 'ftn25'))
3366
3367
3368 misc.call(['%s/gen_cardhtml-pl' % self.dirbin],
3369 cwd=pjoin(self.me_dir))
3370
3371
3372
3373 E_path = pjoin(self.me_dir, 'Events')
3374 O_path = pjoin(self.me_dir, 'Events', run)
3375
3376
3377 for name in ['events.lhe', 'unweighted_events.lhe']:
3378 finput = pjoin(E_path, name)
3379 foutput = pjoin(O_path, name)
3380 if os.path.exists(finput):
3381 logger.debug("File %s exists BAAAAD. Not move anymore!" % pjoin(E_path, name))
3382 if os.path.exists(foutput):
3383 misc.gzip(foutput, stdout="%s.gz" % foutput, error=False)
3384
3385
3386
3387
3388
3389
3390 self.update_status('End Parton', level='parton', makehtml=False)
3391 devnull.close()
3392
3393
3394
3396 """Advanced commands: Create gridpack from present run"""
3397
3398 self.update_status('Creating gridpack', level='parton')
3399
3400 misc.compile(['../bin/internal/gen_ximprove'], cwd=pjoin(self.me_dir, "Source"))
3401 args = self.split_arg(line)
3402 self.check_combine_events(args)
3403 if not self.run_tag: self.run_tag = 'tag_1'
3404 os.system("sed -i.bak \"s/ *.false.*=.*GridRun/ .true. = GridRun/g\" %s/Cards/grid_card.dat" \
3405 % self.me_dir)
3406 misc.call(['./bin/internal/restore_data', self.run_name],
3407 cwd=self.me_dir)
3408 misc.call(['./bin/internal/store4grid',
3409 self.run_name, self.run_tag],
3410 cwd=self.me_dir)
3411 misc.call(['./bin/internal/clean'], cwd=self.me_dir)
3412 misc.call(['./bin/internal/make_gridpack'], cwd=self.me_dir)
3413 files.mv(pjoin(self.me_dir, 'gridpack.tar.gz'),
3414 pjoin(self.me_dir, '%s_gridpack.tar.gz' % self.run_name))
3415 os.system("sed -i.bak \"s/\s*.true.*=.*GridRun/ .false. = GridRun/g\" %s/Cards/grid_card.dat" \
3416 % self.me_dir)
3417 self.update_status('gridpack created', level='gridpack')
3418
3419
3421 """launch the shower"""
3422
3423 args = self.split_arg(line)
3424 if len(args)>1 and args[0] in self._interfaced_showers:
3425 chosen_showers = [args.pop(0)]
3426 elif '--no_default' in line:
3427
3428
3429
3430 chosen_showers = list(self._interfaced_showers)
3431 else:
3432 chosen_showers = list(self._interfaced_showers)
3433
3434
3435 shower_priority = ['pythia8','pythia']
3436 chosen_showers = [sorted(chosen_showers,key=lambda sh:
3437 shower_priority.index(sh) if sh in shower_priority else len(shower_priority)+1)[0]]
3438
3439 for shower in chosen_showers:
3440 self.exec_cmd('%s %s'%(shower,' '.join(args)),
3441 postcmd=False, printcmd=False)
3442
3444 """launch MadAnalysis5 at the parton level."""
3445 return self.run_madanalysis5(line,mode='parton')
3446
3447
3448
3449
3450
3451
3452 @staticmethod
3454 """ Check the consistency of the mg5amc_py8_interface installed with
3455 the current MG5 and Pythia8 versions. """
3456
3457
3458 if not options['pythia8_path']:
3459 return None
3460
3461 if not options['mg5amc_py8_interface_path']:
3462 return \
3463 """
3464 A Pythia8 path is specified via the option 'pythia8_path' but no path for option
3465 'mg5amc_py8_interface_path' is specified. This means that Pythia8 cannot be used
3466 leading order simulations with MadEvent.
3467 Consider installing the MG5_aMC-PY8 interface with the following command:
3468 MG5_aMC>install mg5amc_py8_interface
3469 """
3470
3471 mg5amc_py8_interface_path = options['mg5amc_py8_interface_path']
3472 py8_path = options['pythia8_path']
3473
3474
3475 if not MADEVENT:
3476 mg5amc_py8_interface_path = pjoin(MG5DIR,mg5amc_py8_interface_path)
3477 py8_path = pjoin(MG5DIR,py8_path)
3478
3479
3480 fsock = open(pjoin(mg5amc_py8_interface_path, 'MG5AMC_VERSION_ON_INSTALL'))
3481 MG5_version_on_install = fsock.read().replace('\n','')
3482 fsock.close()
3483 if MG5_version_on_install == 'UNSPECIFIED':
3484 MG5_version_on_install = None
3485 fsock = open(pjoin(mg5amc_py8_interface_path, 'PYTHIA8_VERSION_ON_INSTALL'))
3486 PY8_version_on_install = fsock.read().replace('\n','')
3487 fsock.close()
3488 MG5_curr_version =misc.get_pkg_info()['version']
3489 try:
3490 p = subprocess.Popen(['./get_pythia8_version.py',py8_path],
3491 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
3492 cwd=mg5amc_py8_interface_path)
3493 (out, err) = p.communicate()
3494 out = out.replace('\n','')
3495 PY8_curr_version = out
3496
3497
3498 float(out)
3499 except:
3500 PY8_curr_version = None
3501
3502 if not MG5_version_on_install is None and not MG5_curr_version is None:
3503 if MG5_version_on_install != MG5_curr_version:
3504 return \
3505 """
3506 The current version of MG5_aMC (v%s) is different than the one active when
3507 installing the 'mg5amc_py8_interface_path' (which was MG5aMC v%s).
3508 Please consider refreshing the installation of this interface with the command:
3509 MG5_aMC>install mg5amc_py8_interface
3510 """%(MG5_curr_version, MG5_version_on_install)
3511
3512 if not PY8_version_on_install is None and not PY8_curr_version is None:
3513 if PY8_version_on_install != PY8_curr_version:
3514 return \
3515 """
3516 The current version of Pythia8 (v%s) is different than the one active when
3517 installing the 'mg5amc_py8_interface' tool (which was Pythia8 v%s).
3518 Please consider refreshing the installation of this interface with the command:
3519 MG5_aMC>install mg5amc_py8_interface
3520 """%(PY8_curr_version,PY8_version_on_install)
3521
3522 return None
3523
3525 """ Setup the Pythia8 Run environment and card. In particular all the process and run specific parameters
3526 of the card are automatically set here. This function returns the path where HEPMC events will be output,
3527 if any."""
3528
3529 HepMC_event_output = None
3530 tag = self.run_tag
3531
3532 PY8_Card.subruns[0].systemSet('Beams:LHEF',"unweighted_events.lhe.gz")
3533
3534 if PY8_Card['HEPMCoutput:file']=='auto':
3535 HepMC_event_output = pjoin(self.me_dir,'Events', self.run_name,
3536 '%s_pythia8_events.hepmc'%tag)
3537 PY8_Card.MadGraphSet('HEPMCoutput:file','%s_pythia8_events.hepmc'%tag, force=True)
3538 elif PY8_Card['HEPMCoutput:file'].startswith('fifo'):
3539 fifo_specs = PY8_Card['HEPMCoutput:file'].split('@')
3540 fifo_path = None
3541 if len(fifo_specs)<=1:
3542 fifo_path = pjoin(self.me_dir,'Events', self.run_name,'PY8.hepmc.fifo')
3543 if os.path.exists(fifo_path):
3544 os.remove(fifo_path)
3545 misc.mkfifo(fifo_path)
3546
3547 PY8_Card.defaultSet('HEPMCoutput:file','PY8.hepmc.fifo')
3548 else:
3549 fifo_path = fifo_specs[1]
3550 if os.path.exists(fifo_path):
3551 if stat.S_ISFIFO(os.stat(fifo_path).st_mode):
3552 logger.warning('PY8 will be reusing already existing '+
3553 'custom fifo file at:\n %s'%fifo_path)
3554 else:
3555 raise InvalidCmd(
3556 """The fifo path speficied for the PY8 parameter 'HEPMCoutput:file':
3557 %s
3558 already exists and is not a fifo file."""%fifo_path)
3559 else:
3560 misc.mkfifo(fifo_path)
3561
3562 PY8_Card.defaultSet('HEPMCoutput:file',fifo_path)
3563 HepMC_event_output=fifo_path
3564 elif PY8_Card['HEPMCoutput:file'] in ['','/dev/null','None']:
3565 logger.warning('User disabled the HepMC output of Pythia8.')
3566 HepMC_event_output = None
3567 else:
3568
3569 HepMC_event_output = pjoin(self.me_dir,'Events', self.run_name,
3570 PY8_Card['HEPMCoutput:file'])
3571
3572
3573
3574 PY8_Card.MadGraphSet('JetMatching:setMad', False)
3575 if run_type=='MLM':
3576
3577
3578
3579 PY8_Card.vetoParamWriteOut('Merging:TMS')
3580 PY8_Card.vetoParamWriteOut('Merging:Process')
3581 PY8_Card.vetoParamWriteOut('Merging:nJetMax')
3582
3583
3584 if PY8_Card['JetMatching:qCut']==-1.0:
3585 PY8_Card.MadGraphSet('JetMatching:qCut',1.5*self.run_card['xqcut'], force=True)
3586
3587 if PY8_Card['JetMatching:qCut']<(1.5*self.run_card['xqcut']):
3588 logger.error(
3589 'The MLM merging qCut parameter you chose (%f) is less than '%PY8_Card['JetMatching:qCut']+
3590 '1.5*xqcut, with xqcut your run_card parameter (=%f).\n'%self.run_card['xqcut']+
3591 'It would be better/safer to use a larger qCut or a smaller xqcut.')
3592
3593
3594
3595 PY8_Card.systemSet('Beams:setProductionScalesFromLHEF',True)
3596
3597
3598 if PY8_Card['SysCalc:qWeed']==-1.0:
3599 PY8_Card.MadGraphSet('SysCalc:qWeed',self.run_card['xqcut'], force=True)
3600
3601 if PY8_Card['SysCalc:qCutList']=='auto':
3602 if self.run_card['use_syst']:
3603 if self.run_card['sys_matchscale']=='auto':
3604 qcut = PY8_Card['JetMatching:qCut']
3605 value = [factor*qcut for factor in [0.5,0.75,1.0,1.5,2.0] if\
3606 factor*qcut> 1.5*self.run_card['xqcut'] ]
3607 PY8_Card.MadGraphSet('SysCalc:qCutList', value, force=True)
3608 else:
3609 qCutList = [float(qc) for qc in self.run_card['sys_matchscale'].split()]
3610 if PY8_Card['JetMatching:qCut'] not in qCutList:
3611 qCutList.append(PY8_Card['JetMatching:qCut'])
3612 PY8_Card.MadGraphSet('SysCalc:qCutList', qCutList, force=True)
3613
3614 for scale in PY8_Card['SysCalc:qCutList']:
3615 if scale<(1.5*self.run_card['xqcut']):
3616 logger.error(
3617 'One of the MLM merging qCut parameter you chose (%f) in the variation list'%scale+\
3618 " (either via 'SysCalc:qCutList' in the PY8 shower card or "+\
3619 "'sys_matchscale' in the run_card) is less than 1.5*xqcut, where xqcut is"+
3620 ' the run_card parameter (=%f)\n'%self.run_card['xqcut']+
3621 'It would be better/safer to use a larger qCut or a smaller xqcut.')
3622
3623
3624
3625
3626 if self.run_card['use_syst']:
3627
3628
3629 PY8_Card.MadGraphSet('JetMatching:doVeto',False)
3630 PY8_Card.MadGraphSet('JetMatching:merge',True)
3631 PY8_Card.MadGraphSet('JetMatching:scheme',1)
3632
3633
3634 PY8_Card.MadGraphSet('JetMatching:nQmatch',self.run_card['maxjetflavor'])
3635
3636 PY8_Card.MadGraphSet('JetMatching:coneRadius',1.0)
3637
3638
3639 if not hasattr(self,'proc_characteristic'):
3640 self.proc_characteristic = self.get_characteristics()
3641 nJetMax = self.proc_characteristic['max_n_matched_jets']
3642 if PY8_Card['JetMatching:nJetMax'.lower()] == -1:
3643 logger.info("No user-defined value for Pythia8 parameter "+
3644 "'JetMatching:nJetMax'. Setting it automatically to %d."%nJetMax)
3645 PY8_Card.MadGraphSet('JetMatching:nJetMax',nJetMax, force=True)
3646
3647 elif run_type=='CKKW':
3648
3649
3650 if PY8_Card['Merging:Process']=='<set_by_user>':
3651 raise self.InvalidCmd('When running CKKWl merging, the user must'+
3652 " specifiy the option 'Merging:Process' in pythia8_card.dat.\n"+
3653 "Read section 'Defining the hard process' of "+\
3654 "http://home.thep.lu.se/~torbjorn/pythia81html/CKKWLMerging.html for more information.")
3655
3656
3657
3658
3659 PY8_Card.vetoParamWriteOut('JetMatching:qCut')
3660 PY8_Card.vetoParamWriteOut('JetMatching:doShowerKt')
3661 PY8_Card.vetoParamWriteOut('JetMatching:nJetMax')
3662
3663 CKKW_cut = None
3664
3665 if self.run_card['ptlund']<=0.0 and self.run_card['ktdurham']>0.0:
3666 PY8_Card.subruns[0].MadGraphSet('Merging:doKTMerging',True)
3667 PY8_Card.subruns[0].MadGraphSet('Merging:Dparameter',
3668 self.run_card['dparameter'])
3669 CKKW_cut = 'ktdurham'
3670 elif self.run_card['ptlund']>0.0 and self.run_card['ktdurham']<=0.0:
3671 PY8_Card.subruns[0].MadGraphSet('Merging:doPTLundMerging',True)
3672 CKKW_cut = 'ptlund'
3673 else:
3674 raise InvalidCmd("*Either* the 'ptlund' or 'ktdurham' cut in "+\
3675 " the run_card must be turned on to activate CKKW(L) merging"+
3676 " with Pythia8, but *both* cuts cannot be turned on at the same time."+
3677 "\n ptlund=%f, ktdurham=%f."%(self.run_card['ptlund'],self.run_card['ktdurham']))
3678
3679
3680
3681 if PY8_Card['SysCalc:qWeed']==-1.0:
3682 PY8_Card.MadGraphSet('SysCalc:qWeed',self.run_card[CKKW_cut], force=True)
3683
3684
3685
3686 if PY8_Card['Merging:TMS']==-1.0:
3687 if self.run_card[CKKW_cut]>0.0:
3688 PY8_Card.MadGraphSet('Merging:TMS',self.run_card[CKKW_cut], force=True)
3689 else:
3690 raise self.InvalidCmd('When running CKKWl merging, the user'+\
3691 " select a '%s' cut larger than 0.0 in the run_card."%CKKW_cut)
3692 if PY8_Card['Merging:TMS']<self.run_card[CKKW_cut]:
3693 logger.error(
3694 'The CKKWl merging scale you chose (%f) is less than '%PY8_Card['Merging:TMS']+
3695 'the %s cut specified in the run_card parameter (=%f).\n'%(CKKW_cut,self.run_card[CKKW_cut])+
3696 'It is incorrect to use a smaller CKKWl scale than the generation-level %s cut!'%CKKW_cut)
3697
3698 PY8_Card.MadGraphSet('TimeShower:pTmaxMatch',1)
3699 PY8_Card.MadGraphSet('SpaceShower:pTmaxMatch',1)
3700 PY8_Card.MadGraphSet('SpaceShower:rapidityOrder',False)
3701
3702 if self.run_card['use_syst']:
3703
3704
3705 PY8_Card.MadGraphSet('Merging:applyVeto',False)
3706 PY8_Card.MadGraphSet('Merging:includeWeightInXsection',False)
3707
3708
3709 PY8_Card.MadGraphSet('Merging:nQuarksMerge',self.run_card['maxjetflavor'])
3710 if not hasattr(self,'proc_characteristic'):
3711 self.proc_characteristic = self.get_characteristics()
3712 nJetMax = self.proc_characteristic['max_n_matched_jets']
3713 if PY8_Card['Merging:nJetMax'.lower()] == -1:
3714 logger.info("No user-defined value for Pythia8 parameter "+
3715 "'Merging:nJetMax'. Setting it automatically to %d."%nJetMax)
3716 PY8_Card.MadGraphSet('Merging:nJetMax',nJetMax, force=True)
3717 if PY8_Card['SysCalc:tmsList']=='auto':
3718 if self.run_card['use_syst']:
3719 if self.run_card['sys_matchscale']=='auto':
3720 tms = PY8_Card["Merging:TMS"]
3721 value = [factor*tms for factor in [0.5,0.75,1.0,1.5,2.0]
3722 if factor*tms > self.run_card[CKKW_cut]]
3723 PY8_Card.MadGraphSet('SysCalc:tmsList', value, force=True)
3724 else:
3725 tmsList = [float(tms) for tms in self.run_card['sys_matchscale'].split()]
3726 if PY8_Card['Merging:TMS'] not in tmsList:
3727 tmsList.append(PY8_Card['Merging:TMS'])
3728 PY8_Card.MadGraphSet('SysCalc:tmsList', tmsList, force=True)
3729
3730 for scale in PY8_Card['SysCalc:tmsList']:
3731 if scale<self.run_card[CKKW_cut]:
3732 logger.error(
3733 'One of the CKKWl merging scale you chose (%f) in the variation list'%scale+\
3734 " (either via 'SysCalc:tmsList' in the PY8 shower card or "+\
3735 "'sys_matchscale' in the run_card) is less than %f, "%self.run_card[CKKW_cut]+
3736 'the %s cut specified in the run_card parameter.\n'%CKKW_cut+
3737 'It is incorrect to use a smaller CKKWl scale than the generation-level %s cut!'%CKKW_cut)
3738 else:
3739
3740
3741
3742 PY8_Card.vetoParamWriteOut('Merging:TMS')
3743 PY8_Card.vetoParamWriteOut('Merging:Process')
3744 PY8_Card.vetoParamWriteOut('Merging:nJetMax')
3745 PY8_Card.vetoParamWriteOut('JetMatching:qCut')
3746 PY8_Card.vetoParamWriteOut('JetMatching:doShowerKt')
3747 PY8_Card.vetoParamWriteOut('JetMatching:nJetMax')
3748
3749 return HepMC_event_output
3750
3752 """launch pythia8"""
3753
3754
3755 try:
3756 import madgraph
3757 except ImportError:
3758 import internal.histograms as histograms
3759 else:
3760 import madgraph.various.histograms as histograms
3761
3762
3763 args = self.split_arg(line)
3764 if '--no_default' in args:
3765 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pythia8_card.dat')):
3766 return
3767 no_default = True
3768 args.remove('--no_default')
3769 else:
3770 no_default = False
3771
3772 if not self.run_name:
3773 self.check_pythia8(args)
3774 self.configure_directory(html_opening =False)
3775 else:
3776
3777 self.configure_directory(html_opening =False)
3778 self.check_pythia8(args)
3779
3780
3781 if not no_default:
3782 self.ask_pythia_run_configuration(args[-1], pythia_version=8)
3783
3784 if self.options['automatic_html_opening']:
3785 misc.open_file(os.path.join(self.me_dir, 'crossx.html'))
3786 self.options['automatic_html_opening'] = False
3787
3788 if self.run_card['event_norm'] not in ['unit','average']:
3789 logger.critical("Pythia8 does not support normalization to the sum. Not running Pythia8")
3790 return
3791
3792
3793
3794
3795
3796 if not self.banner or len(self.banner) <=1:
3797
3798 self.banner = banner_mod.recover_banner(self.results, 'pythia')
3799
3800 if not self.options['mg5amc_py8_interface_path'] or not \
3801 os.path.exists(pjoin(self.options['mg5amc_py8_interface_path'],
3802 'MG5aMC_PY8_interface')):
3803 raise self.InvalidCmd(
3804 """The MG5aMC_PY8_interface tool cannot be found, so that MadEvent cannot steer Pythia8 shower.
3805 Please install this tool with the following MG5_aMC command:
3806 MG5_aMC> install mg5amc_py8_interface_path""")
3807 else:
3808 pythia_main = pjoin(self.options['mg5amc_py8_interface_path'],
3809 'MG5aMC_PY8_interface')
3810 warnings = MadEventCmd.mg5amc_py8_interface_consistency_warning(self.options)
3811 if warnings:
3812 logger.warning(warnings)
3813
3814 self.results.add_detail('run_mode', 'madevent')
3815
3816
3817 self.update_status('\033[92mRunning Pythia8 [arXiv:1410.3012]\033[0m', 'pythia8')
3818
3819 tag = self.run_tag
3820
3821
3822
3823 PY8_Card = banner_mod.PY8Card(pjoin(self.me_dir, 'Cards',
3824 'pythia8_card_default.dat'))
3825 PY8_Card.read(pjoin(self.me_dir, 'Cards', 'pythia8_card.dat'),
3826 setter='user')
3827
3828 run_type = 'default'
3829 merged_run_types = ['MLM','CKKW']
3830 if int(self.run_card['ickkw'])==1:
3831 run_type = 'MLM'
3832 elif int(self.run_card['ickkw'])==2 or \
3833 self.run_card['ktdurham']>0.0 or self.run_card['ptlund']>0.0:
3834 run_type = 'CKKW'
3835
3836
3837 HepMC_event_output = self.setup_Pythia8RunAndCard(PY8_Card, run_type)
3838
3839
3840 pythia_cmd_card = pjoin(self.me_dir, 'Events', self.run_name ,
3841 '%s_pythia8.cmd' % tag)
3842 cmd_card = StringIO.StringIO()
3843 PY8_Card.write(cmd_card,pjoin(self.me_dir,'Cards','pythia8_card_default.dat'),
3844 direct_pythia_input=True)
3845
3846
3847
3848
3849 if 'heptools_install_dir' in self.options:
3850 preamble = misc.get_HEPTools_location_setter(
3851 self.options['heptools_install_dir'],'lib')
3852 else:
3853 if MADEVENT:
3854 preamble = misc.get_HEPTools_location_setter(
3855 pjoin(self.options['mg5amc_py8_interface_path'],os.pardir),'lib')
3856 else:
3857 preamble = misc.get_HEPTools_location_setter(
3858 pjoin(MG5DIR,'HEPTools'),'lib')
3859
3860 open(pythia_cmd_card,'w').write("""!
3861 ! It is possible to run this card manually with:
3862 ! %s %s
3863 !
3864 """%(preamble+pythia_main,os.path.basename(pythia_cmd_card))+cmd_card.getvalue())
3865
3866
3867 pythia_log = pjoin(self.me_dir , 'Events', self.run_name ,
3868 '%s_pythia8.log' % tag)
3869
3870
3871 wrapper_path = pjoin(self.me_dir,'Events',self.run_name,'run_shower.sh')
3872 wrapper = open(wrapper_path,'w')
3873 shell = 'bash' if misc.get_shell_type() in ['bash',None] else 'tcsh'
3874 shell_exe = None
3875 if os.path.exists('/usr/bin/env'):
3876 shell_exe = '/usr/bin/env %s'%shell
3877 else:
3878 shell_exe = misc.which(shell)
3879 if not shell_exe:
3880 self.InvalidCmd('No s hell could be found in your environment.\n'+
3881 "Make sure that either '%s' is in your path or that the"%shell+\
3882 " command '/usr/bin/env %s' exists and returns a valid path."%shell)
3883
3884 exe_cmd = "#!%s\n%s"%(shell_exe,' '.join(
3885 [preamble+pythia_main,
3886 os.path.basename(pythia_cmd_card)]))
3887
3888 wrapper.write(exe_cmd)
3889 wrapper.close()
3890
3891
3892 st = os.stat(wrapper_path)
3893 os.chmod(wrapper_path, st.st_mode | stat.S_IEXEC)
3894
3895
3896
3897 is_HepMC_output_fifo = False if not HepMC_event_output else \
3898 ( os.path.exists(HepMC_event_output) and \
3899 stat.S_ISFIFO(os.stat(HepMC_event_output).st_mode))
3900 startPY8timer = time.time()
3901
3902
3903 PY8_extracted_information={ 'sigma_m':None, 'Nacc':None, 'Ntry':None,
3904 'cross_sections':{} }
3905
3906 if is_HepMC_output_fifo:
3907 logger.info(
3908 """Pythia8 is set to output HEPMC events to to a fifo file.
3909 You can follow PY8 run with the following command (in a separate terminal):
3910 tail -f %s"""%pythia_log )
3911 py8_log = open( pythia_log,'w')
3912 py8_bkgrd_proc = misc.Popen([wrapper_path],
3913 stdout=py8_log,stderr=py8_log,
3914 cwd=pjoin(self.me_dir,'Events',self.run_name))
3915
3916 if not no_default:
3917 logger.info('You can now run a tool that reads the following fifo file:'+\
3918 '\n %s\nwhere PY8 outputs HEPMC events (e.g. MadAnalysis5).'
3919 %HepMC_event_output,'$MG:color:GREEN')
3920 return
3921 else:
3922 if self.options ['run_mode']!=0:
3923
3924 self.configure_run_mode(self.options['run_mode'])
3925 if self.options['run_mode']==1:
3926 n_cores = max(self.options['cluster_size'],1)
3927 elif self.options['run_mode']==2:
3928 n_cores = max(self.cluster.nb_core,1)
3929
3930 lhe_file_name = os.path.basename(PY8_Card.subruns[0]['Beams:LHEF'])
3931 lhe_file = lhe_parser.EventFile(pjoin(self.me_dir,'Events',
3932 self.run_name,PY8_Card.subruns[0]['Beams:LHEF']))
3933 n_available_events = len(lhe_file)
3934 if PY8_Card['Main:numberOfEvents']==-1:
3935 n_events = n_available_events
3936 else:
3937 n_events = PY8_Card['Main:numberOfEvents']
3938 if n_events > n_available_events:
3939 raise self.InvalidCmd, 'You specified more events (%d) in the PY8 parameter'%n_events+\
3940 "'Main:numberOfEvents' than the total number of events available (%d)"%n_available_events+\
3941 ' in the event file:\n %s'%pjoin(self.me_dir,'Events',self.run_name,PY8_Card.subruns[0]['Beams:LHEF'])
3942
3943
3944 if self.options['run_mode']==2:
3945 min_n_events_per_job = 100
3946 elif self.options['run_mode']==1:
3947 min_n_events_per_job = 1000
3948 min_n_core = n_events//min_n_events_per_job
3949 n_cores = max(min(min_n_core,n_cores),1)
3950
3951 if self.options['run_mode']==0 or (self.options['run_mode']==2 and self.options['nb_core']==1):
3952
3953 self.cluster = None
3954 logger.info('Follow Pythia8 shower by running the '+
3955 'following command (in a separate terminal):\n tail -f %s'%pythia_log)
3956
3957 if self.options['run_mode']==2 and self.options['nb_core']>1:
3958 ret_code = self.cluster.launch_and_wait(wrapper_path,
3959 argument= [], stdout= pythia_log, stderr=subprocess.STDOUT,
3960 cwd=pjoin(self.me_dir,'Events',self.run_name))
3961 else:
3962 ret_code = misc.call(wrapper_path, stdout=open(pythia_log,'w'), stderr=subprocess.STDOUT,
3963 cwd=pjoin(self.me_dir,'Events',self.run_name))
3964 if ret_code != 0:
3965 raise self.InvalidCmd, 'Pythia8 shower interrupted with return'+\
3966 ' code %d.\n'%ret_code+\
3967 'You can find more information in this log file:\n%s'%pythia_log
3968 else:
3969 if self.run_card['event_norm']=='sum':
3970 logger.error("")
3971 logger.error("Either run in single core or change event_norm to 'average'.")
3972 raise InvalidCmd("Pythia8 parallelization with event_norm set to 'sum' is not supported."
3973 "Either run in single core or change event_norm to 'average'.")
3974
3975
3976 parallelization_dir = pjoin(self.me_dir,'Events',self.run_name,'PY8_parallelization')
3977 if os.path.isdir(parallelization_dir):
3978 shutil.rmtree(parallelization_dir)
3979 os.mkdir(parallelization_dir)
3980
3981 shutil.copy(pythia_main,parallelization_dir)
3982
3983 ParallelPY8Card = copy.copy(PY8_Card)
3984
3985 if HepMC_event_output:
3986 ParallelPY8Card['HEPMCoutput:file']='events.hepmc'
3987 else:
3988 ParallelPY8Card['HEPMCoutput:file']='/dev/null'
3989
3990 ParallelPY8Card.subruns[0].systemSet('Beams:LHEF','events.lhe.gz')
3991 ParallelPY8Card.write(pjoin(parallelization_dir,'PY8Card.dat'),
3992 pjoin(self.me_dir,'Cards','pythia8_card_default.dat'),
3993 direct_pythia_input=True)
3994
3995 wrapper_path = pjoin(parallelization_dir,'run_PY8.sh')
3996 wrapper = open(wrapper_path,'w')
3997 if self.options['cluster_temp_path'] is None:
3998 exe_cmd = \
3999 """#!%s
4000 ./%s PY8Card.dat >& PY8_log.txt
4001 """
4002 else:
4003 exe_cmd = \
4004 """#!%s
4005 ln -s ./events_$1.lhe.gz ./events.lhe.gz
4006 ./%s PY8Card_$1.dat >& PY8_log.txt
4007 mkdir split_$1
4008 if [ -f ./events.hepmc ];
4009 then
4010 mv ./events.hepmc ./split_$1/
4011 fi
4012 if [ -f ./pts.dat ];
4013 then
4014 mv ./pts.dat ./split_$1/
4015 fi
4016 if [ -f ./djrs.dat ];
4017 then
4018 mv ./djrs.dat ./split_$1/
4019 fi
4020 if [ -f ./PY8_log.txt ];
4021 then
4022 mv ./PY8_log.txt ./split_$1/
4023 fi
4024 tar -czf split_$1.tar.gz split_$1
4025 """
4026 exe_cmd = exe_cmd%(shell_exe,os.path.basename(pythia_main))
4027 wrapper.write(exe_cmd)
4028 wrapper.close()
4029
4030 st = os.stat(wrapper_path)
4031 os.chmod(wrapper_path, st.st_mode | stat.S_IEXEC)
4032
4033
4034 partition=[n_available_events//n_cores]*n_cores
4035 for i in range(n_available_events%n_cores):
4036 partition[i] += 1
4037
4038
4039
4040 partition_for_PY8=[n_events//n_cores]*n_cores
4041 for i in range(n_events%n_cores):
4042 partition_for_PY8[i] += 1
4043
4044 logger.info('Splitting .lhe event file for PY8 parallelization...')
4045 n_splits = lhe_file.split(partition=partition, cwd=parallelization_dir, zip=True)
4046
4047 if n_splits!=len(partition):
4048 raise MadGraph5Error('Error during lhe file splitting. Expected %d files but obtained %d.'
4049 %(len(partition),n_splits))
4050
4051 split_files = []
4052 split_dirs = []
4053 for split_id in range(n_splits):
4054 split_files.append('events_%s.lhe.gz'%split_id)
4055 split_dirs.append(pjoin(parallelization_dir,'split_%d'%split_id))
4056
4057 shutil.move(pjoin(parallelization_dir,lhe_file.name+'_%d.lhe.gz'%split_id),
4058 pjoin(parallelization_dir,split_files[-1]))
4059
4060 logger.info('Submitting Pythia8 jobs...')
4061 for i, split_file in enumerate(split_files):
4062
4063
4064
4065 split_PY8_Card = banner_mod.PY8Card(pjoin(parallelization_dir,'PY8Card.dat'))
4066
4067 split_PY8_Card.systemSet('Main:numberOfEvents',partition_for_PY8[i])
4068 split_PY8_Card.systemSet('HEPMCoutput:scaling',split_PY8_Card['HEPMCoutput:scaling']*
4069 (float(partition_for_PY8[i])/float(n_events)))
4070
4071
4072 split_PY8_Card.write(pjoin(parallelization_dir,'PY8Card_%d.dat'%i),
4073 pjoin(parallelization_dir,'PY8Card.dat'), add_missing=False)
4074 in_files = [pjoin(parallelization_dir,os.path.basename(pythia_main)),
4075 pjoin(parallelization_dir,'PY8Card_%d.dat'%i),
4076 pjoin(parallelization_dir,split_file)]
4077 if self.options['cluster_temp_path'] is None:
4078 out_files = []
4079 os.mkdir(pjoin(parallelization_dir,'split_%d'%i))
4080 selected_cwd = pjoin(parallelization_dir,'split_%d'%i)
4081 for in_file in in_files+[pjoin(parallelization_dir,'run_PY8.sh')]:
4082
4083
4084 if os.path.basename(in_file)==split_file:
4085 ln(in_file,selected_cwd,name='events.lhe.gz')
4086 elif os.path.basename(in_file).startswith('PY8Card'):
4087 ln(in_file,selected_cwd,name='PY8Card.dat')
4088 else:
4089 ln(in_file,selected_cwd)
4090 in_files = []
4091 else:
4092 out_files = ['split_%d.tar.gz'%i]
4093 selected_cwd = parallelization_dir
4094 self.cluster.submit2(wrapper_path,
4095 argument=[str(i)], cwd=selected_cwd,
4096 input_files=in_files,
4097 output_files=out_files,
4098 required_output=out_files)
4099
4100 def wait_monitoring(Idle, Running, Done):
4101 if Idle+Running+Done == 0:
4102 return
4103 logger.info('Pythia8 shower jobs: %d Idle, %d Running, %d Done [%s]'\
4104 %(Idle, Running, Done, misc.format_time(time.time() - startPY8timer)))
4105 self.cluster.wait(parallelization_dir,wait_monitoring)
4106
4107 logger.info('Merging results from the split PY8 runs...')
4108 if self.options['cluster_temp_path']:
4109
4110 for i, split_file in enumerate(split_files):
4111 misc.call(['tar','-xzf','split_%d.tar.gz'%i],cwd=parallelization_dir)
4112 os.remove(pjoin(parallelization_dir,'split_%d.tar.gz'%i))
4113
4114
4115 pythia_log_file = open(pythia_log,'w')
4116 n_added = 0
4117 for split_dir in split_dirs:
4118 log_file = pjoin(split_dir,'PY8_log.txt')
4119 pythia_log_file.write('='*35+'\n')
4120 pythia_log_file.write(' -> Pythia8 log file for run %d <-'%i+'\n')
4121 pythia_log_file.write('='*35+'\n')
4122 pythia_log_file.write(open(log_file,'r').read()+'\n')
4123 if run_type in merged_run_types:
4124 sigma_m, Nacc, Ntry = self.parse_PY8_log_file(log_file)
4125 if any(elem is None for elem in [sigma_m, Nacc, Ntry]):
4126 continue
4127 n_added += 1
4128 if PY8_extracted_information['sigma_m'] is None:
4129 PY8_extracted_information['sigma_m'] = sigma_m
4130 else:
4131 PY8_extracted_information['sigma_m'] += sigma_m
4132 if PY8_extracted_information['Nacc'] is None:
4133 PY8_extracted_information['Nacc'] = Nacc
4134 else:
4135 PY8_extracted_information['Nacc'] += Nacc
4136 if PY8_extracted_information['Ntry'] is None:
4137 PY8_extracted_information['Ntry'] = Ntry
4138 else:
4139 PY8_extracted_information['Ntry'] += Ntry
4140
4141
4142 if n_added>0:
4143 PY8_extracted_information['sigma_m'] /= float(n_added)
4144 pythia_log_file.close()
4145
4146
4147 djr_HwU = None
4148 n_added = 0
4149 for split_dir in split_dirs:
4150 djr_file = pjoin(split_dir,'djrs.dat')
4151 if not os.path.isfile(djr_file):
4152 continue
4153 xsecs = self.extract_cross_sections_from_DJR(djr_file)
4154 if len(xsecs)>0:
4155 n_added += 1
4156 if len(PY8_extracted_information['cross_sections'])==0:
4157 PY8_extracted_information['cross_sections'] = xsecs
4158
4159 for key in PY8_extracted_information['cross_sections']:
4160 PY8_extracted_information['cross_sections'][key][1] = \
4161 PY8_extracted_information['cross_sections'][key][1]**2
4162 else:
4163 for key, value in xsecs.items():
4164 PY8_extracted_information['cross_sections'][key][0] += value[0]
4165
4166 PY8_extracted_information['cross_sections'][key][1] += value[1]**2
4167 new_djr_HwU = histograms.HwUList(djr_file,run_id=0)
4168 if djr_HwU is None:
4169 djr_HwU = new_djr_HwU
4170 else:
4171 for i, hist in enumerate(djr_HwU):
4172 djr_HwU[i] = hist + new_djr_HwU[i]
4173
4174
4175 if not djr_HwU is None:
4176 djr_HwU.output(pjoin(self.me_dir,'Events',self.run_name,'djrs'),format='HwU')
4177 shutil.move(pjoin(self.me_dir,'Events',self.run_name,'djrs.HwU'),
4178 pjoin(self.me_dir,'Events',self.run_name,'%s_djrs.dat'%tag))
4179
4180 if n_added>0:
4181 for key in PY8_extracted_information['cross_sections']:
4182
4183
4184
4185 PY8_extracted_information['cross_sections'][key][1] = \
4186 math.sqrt(PY8_extracted_information['cross_sections'][key][1]) / float(n_added)
4187
4188
4189 pts_HwU = None
4190 for split_dir in split_dirs:
4191 pts_file = pjoin(split_dir,'pts.dat')
4192 if not os.path.isfile(pts_file):
4193 continue
4194 new_pts_HwU = histograms.HwUList(pts_file,run_id=0)
4195 if pts_HwU is None:
4196 pts_HwU = new_pts_HwU
4197 else:
4198 for i, hist in enumerate(pts_HwU):
4199 pts_HwU[i] = hist + new_pts_HwU[i]
4200 if not pts_HwU is None:
4201 pts_HwU.output(pjoin(self.me_dir,'Events',self.run_name,'pts'),format='HwU')
4202 shutil.move(pjoin(self.me_dir,'Events',self.run_name,'pts.HwU'),
4203 pjoin(self.me_dir,'Events',self.run_name,'%s_pts.dat'%tag))
4204
4205
4206 all_hepmc_files = []
4207 for split_dir in split_dirs:
4208 hepmc_file = pjoin(split_dir,'events.hepmc')
4209 if not os.path.isfile(hepmc_file):
4210 continue
4211 all_hepmc_files.append(hepmc_file)
4212
4213 if len(all_hepmc_files)>0:
4214 hepmc_output = pjoin(self.me_dir,'Events',self.run_name,HepMC_event_output)
4215 with misc.TMP_directory() as tmp_dir:
4216
4217 header = open(pjoin(tmp_dir,'header.hepmc'),'w')
4218 n_head = 0
4219 for line in open(all_hepmc_files[0],'r'):
4220 if not line.startswith('E'):
4221 n_head += 1
4222 header.write(line)
4223 else:
4224 break
4225 header.close()
4226 tail = open(pjoin(tmp_dir,'tail.hepmc'),'w')
4227 n_tail = 0
4228 for line in misc.BackRead(all_hepmc_files[-1]):
4229 if line.startswith('HepMC::'):
4230 n_tail += 1
4231 tail.write(line)
4232 else:
4233 break
4234 tail.close()
4235 if n_tail>1:
4236 raise MadGraph5Error,'HEPMC files should only have one trailing command.'
4237
4238
4239
4240
4241 for hepmc_file in all_hepmc_files:
4242
4243 if sys.platform == 'darwin':
4244
4245 os.system(' '.join(['sed','-i',"''","'%s;$d'"%
4246 (';'.join('%id'%(i+1) for i in range(n_head))),hepmc_file]))
4247 else:
4248
4249 os.system(' '.join(['sed','-i']+["-e '%id'"%(i+1) for i in range(n_head)]+
4250 ["-e '$d'",hepmc_file]))
4251
4252 os.system(' '.join(['cat',pjoin(tmp_dir,'header.hepmc')]+all_hepmc_files+
4253 [pjoin(tmp_dir,'tail.hepmc'),'>',hepmc_output]))
4254
4255
4256 if os.path.isdir(parallelization_dir):
4257 shutil.rmtree(parallelization_dir)
4258
4259
4260 djr_output = pjoin(self.me_dir,'Events', self.run_name, 'djrs.dat')
4261 if os.path.isfile(djr_output):
4262 shutil.move(djr_output, pjoin(self.me_dir,'Events',
4263 self.run_name, '%s_djrs.dat' % tag))
4264 pt_output = pjoin(self.me_dir,'Events', self.run_name, 'pts.dat')
4265 if os.path.isfile(pt_output):
4266 shutil.move(pt_output, pjoin(self.me_dir,'Events',
4267 self.run_name, '%s_pts.dat' % tag))
4268
4269 if not os.path.isfile(pythia_log) or \
4270 'Inclusive cross section:' not in '\n'.join(open(pythia_log,'r').readlines()[-20:]):
4271 logger.warning('Fail to produce a pythia8 output. More info in \n %s'%pythia_log)
4272 return
4273
4274
4275 successful = self.create_plot('Pythia8')
4276 if not successful:
4277 logger.warning('Failed to produce Pythia8 merging plots.')
4278
4279 self.to_store.append('pythia8')
4280
4281
4282 if run_type in merged_run_types:
4283
4284 if all(PY8_extracted_information[_] is None for _ in ['sigma_m','Nacc','Ntry']):
4285
4286 if self.options ['run_mode']!=0:
4287 logger.warning('Pythia8 cross-section could not be retreived.\n'+
4288 'Try turning parallelization off by setting the option nb_core to 1.')
4289 else:
4290 PY8_extracted_information['sigma_m'],PY8_extracted_information['Nacc'],\
4291 PY8_extracted_information['Ntry'] = self.parse_PY8_log_file(
4292 pjoin(self.me_dir,'Events', self.run_name,'%s_pythia8.log' % tag))
4293
4294 if not any(PY8_extracted_information[_] is None for _ in ['sigma_m','Nacc','Ntry']):
4295 self.results.add_detail('cross_pythia', PY8_extracted_information['sigma_m'])
4296 self.results.add_detail('nb_event_pythia', PY8_extracted_information['Nacc'])
4297
4298 Nacc = PY8_extracted_information['Nacc']
4299 Ntry = PY8_extracted_information['Ntry']
4300 sigma_m = PY8_extracted_information['sigma_m']
4301
4302 error = self.results[self.run_name].return_tag(self.run_tag)['error']
4303 try:
4304 error_m = math.sqrt((error * Nacc/Ntry)**2 + sigma_m**2 *(1-Nacc/Ntry)/Nacc)
4305 except ZeroDivisionError:
4306
4307 error_m = -1.0
4308
4309 self.results.add_detail('error_pythia', error_m)
4310
4311 if self.run_card['use_syst']:
4312 self.results.add_detail('cross_pythia', -1)
4313 self.results.add_detail('error_pythia', 0)
4314
4315
4316 djr_output = pjoin(self.me_dir,'Events',self.run_name,'%s_djrs.dat'%tag)
4317 if os.path.isfile(djr_output) and len(PY8_extracted_information['cross_sections'])==0:
4318
4319 if self.options ['run_mode']!=0:
4320 logger.warning('Pythia8 merged cross-sections could not be retreived.\n'+
4321 'Try turning parallelization off by setting the option nb_core to 1.')
4322 PY8_extracted_information['cross_sections'] = {}
4323 else:
4324 PY8_extracted_information['cross_sections'] = self.extract_cross_sections_from_DJR(djr_output)
4325 cross_sections = PY8_extracted_information['cross_sections']
4326 if cross_sections:
4327
4328
4329 a_float_re = '[\+|-]?\d+(\.\d*)?([EeDd][\+|-]?\d+)?'
4330 central_merging_re = re.compile(
4331 '^\s*Weight_MERGING\s*=\s*(?P<merging>%s)\s*$'%a_float_re,
4332 re.IGNORECASE)
4333 cross_sections = dict(
4334 (float(central_merging_re.match(xsec).group('merging')),value)
4335 for xsec, value in cross_sections.items() if not
4336 central_merging_re.match(xsec) is None)
4337 central_scale = PY8_Card['JetMatching:qCut'] if \
4338 int(self.run_card['ickkw'])==1 else PY8_Card['Merging:TMS']
4339 if central_scale in cross_sections:
4340 self.results.add_detail('cross_pythia8', cross_sections[central_scale][0])
4341 self.results.add_detail('error_pythia8', cross_sections[central_scale][1])
4342
4343
4344
4345
4346
4347
4348 xsecs_file = open(pjoin(self.me_dir,'Events',self.run_name,
4349 '%s_merged_xsecs.txt'%tag),'w')
4350 if cross_sections:
4351 xsecs_file.write('%-20s%-20s%-20s\n'%('Merging scale',
4352 'Cross-section [pb]','MC uncertainty [pb]'))
4353 for scale in sorted(cross_sections.keys()):
4354 xsecs_file.write('%-20.4g%-20.6e%-20.2e\n'%
4355 (scale,cross_sections[scale][0],cross_sections[scale][1]))
4356 else:
4357 xsecs_file.write('Cross-sections could not be read from the'+\
4358 "XML node 'xsection' of the .dat file produced by Pythia8.")
4359 xsecs_file.close()
4360
4361
4362
4363
4364 self.banner.add(pythia_cmd_card)
4365
4366 if int(self.run_card['ickkw']):
4367
4368 if 'MGGenerationInfo' in self.banner:
4369 self.banner['MGGenerationInfo'] += '# Matched Integrated weight (pb) : %s\n' % self.results.current['cross_pythia']
4370 else:
4371 self.banner['MGGenerationInfo'] = '# Matched Integrated weight (pb) : %s\n' % self.results.current['cross_pythia']
4372 banner_path = pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, tag))
4373 self.banner.write(banner_path)
4374
4375 self.update_status('Pythia8 shower finished after %s.'%misc.format_time(time.time() - startPY8timer), level='pythia8')
4376 if self.options['delphes_path']:
4377 self.exec_cmd('delphes --no_default', postcmd=False, printcmd=False)
4378 self.print_results_in_shell(self.results.current)
4379
4381 """ Parse a log file to extract number of event and cross-section. """
4382 pythiare = re.compile("Les Houches User Process\(es\)\s*\d+\s*\|\s*(?P<tried>\d+)\s*(?P<selected>\d+)\s*(?P<generated>\d+)\s*\|\s*(?P<xsec>[\d\.e\-\+]+)\s*(?P<xsec_error>[\d\.e\-\+]+)")
4383 pythia_xsec_re = re.compile("Inclusive cross section\s*:\s*(?P<xsec>[\d\.e\-\+]+)\s*(?P<xsec_error>[\d\.e\-\+]+)")
4384 sigma_m, Nacc, Ntry = None, None, None
4385 for line in misc.BackRead(log_file_path):
4386 info = pythiare.search(line)
4387 if not info:
4388
4389
4390
4391 final_PY8_xsec = pythia_xsec_re.search(line)
4392 if not final_PY8_xsec:
4393 continue
4394 else:
4395 sigma_m = float(final_PY8_xsec.group('xsec')) *1e9
4396 continue
4397 else:
4398 try:
4399
4400 if sigma_m is None:
4401 sigma_m = float(info.group('xsec')) *1e9
4402 if Nacc is None:
4403 Nacc = int(info.group('generated'))
4404 if Ntry is None:
4405 Ntry = int(info.group('tried'))
4406 if Nacc==0:
4407 raise self.InvalidCmd, 'Pythia8 shower failed since it'+\
4408 ' did not accept any event from the MG5aMC event file.'
4409 return sigma_m, Nacc, Ntry
4410 except ValueError:
4411 return None,None,None
4412
4413 raise self.InvalidCmd, "Could not find cross-section and event number information "+\
4414 "in Pythia8 log\n '%s'."%log_file_path
4415
4417 """Extract cross-sections from a djr XML output."""
4418 import xml.dom.minidom as minidom
4419 run_nodes = minidom.parse(djr_output).getElementsByTagName("run")
4420 all_nodes = dict((int(node.getAttribute('id')),node) for
4421 node in run_nodes)
4422 try:
4423 selected_run_node = all_nodes[0]
4424 except:
4425 return {}
4426 xsections = selected_run_node.getElementsByTagName("xsection")
4427
4428 return dict((xsec.getAttribute('name'),
4429 [float(xsec.childNodes[0].data.split()[0]),
4430 float(xsec.childNodes[0].data.split()[1])])
4431 for xsec in xsections)
4432
4434 """launch pythia"""
4435
4436
4437
4438 args = self.split_arg(line)
4439 if '--no_default' in args:
4440 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pythia_card.dat')):
4441 return
4442 no_default = True
4443 args.remove('--no_default')
4444 else:
4445 no_default = False
4446
4447 if not self.run_name:
4448 self.check_pythia(args)
4449 self.configure_directory(html_opening =False)
4450 else:
4451
4452 self.configure_directory(html_opening =False)
4453 self.check_pythia(args)
4454
4455 if self.run_card['event_norm'] != 'sum':
4456 logger.error('pythia-pgs require event_norm to be on sum. Do not run pythia6')
4457 return
4458
4459
4460 if not no_default:
4461 self.ask_pythia_run_configuration(args[-1])
4462 if self.options['automatic_html_opening']:
4463 misc.open_file(os.path.join(self.me_dir, 'crossx.html'))
4464 self.options['automatic_html_opening'] = False
4465
4466
4467 if not self.banner or len(self.banner) <=1:
4468 self.banner = banner_mod.recover_banner(self.results, 'pythia')
4469
4470 pythia_src = pjoin(self.options['pythia-pgs_path'],'src')
4471
4472 self.results.add_detail('run_mode', 'madevent')
4473
4474 self.update_status('Running Pythia', 'pythia')
4475 try:
4476 os.remove(pjoin(self.me_dir,'Events','pythia.done'))
4477 except Exception:
4478 pass
4479
4480
4481
4482 if not re.search(r'^\s*LHAPATH=%s/PDFsets' % pythia_src,
4483 open(pjoin(self.me_dir,'Cards','pythia_card.dat')).read(),
4484 re.M):
4485 f = open(pjoin(self.me_dir,'Cards','pythia_card.dat'),'a')
4486 f.write('\n LHAPATH=%s/PDFsets' % pythia_src)
4487 f.close()
4488 tag = self.run_tag
4489 pythia_log = pjoin(self.me_dir, 'Events', self.run_name , '%s_pythia.log' % tag)
4490
4491
4492
4493
4494 output_files = ['pythia_events.hep']
4495 if self.run_card['use_syst']:
4496 output_files.append('syst.dat')
4497 if self.run_card['ickkw'] == 1:
4498 output_files += ['beforeveto.tree', 'xsecs.tree', 'events.tree']
4499
4500 os.environ['PDG_MASS_TBL'] = pjoin(pythia_src,'mass_width_2004.mc')
4501 self.cluster.launch_and_wait(pjoin(pythia_src, 'pythia'),
4502 input_files=[pjoin(self.me_dir, "Events", "unweighted_events.lhe"),
4503 pjoin(self.me_dir,'Cards','pythia_card.dat'),
4504 pjoin(pythia_src,'mass_width_2004.mc')],
4505 output_files=output_files,
4506 stdout= pythia_log,
4507 stderr=subprocess.STDOUT,
4508 cwd=pjoin(self.me_dir,'Events'))
4509
4510
4511 os.remove(pjoin(self.me_dir, "Events", "unweighted_events.lhe"))
4512
4513 if not os.path.exists(pjoin(self.me_dir,'Events','pythia_events.hep')):
4514 logger.warning('Fail to produce pythia output. More info in \n %s' % pythia_log)
4515 return
4516
4517 self.to_store.append('pythia')
4518
4519
4520 if int(self.run_card['ickkw']):
4521
4522 pythia_log = misc.BackRead(pjoin(self.me_dir,'Events', self.run_name,
4523 '%s_pythia.log' % tag))
4524 pythiare = re.compile("\s*I\s+0 All included subprocesses\s+I\s+(?P<generated>\d+)\s+(?P<tried>\d+)\s+I\s+(?P<xsec>[\d\.D\-+]+)\s+I")
4525 for line in pythia_log:
4526 info = pythiare.search(line)
4527 if not info:
4528 continue
4529 try:
4530
4531 sigma_m = float(info.group('xsec').replace('D','E')) *1e9
4532 Nacc = int(info.group('generated'))
4533 Ntry = int(info.group('tried'))
4534 except ValueError:
4535
4536 self.results.add_detail('cross_pythia', 0)
4537 self.results.add_detail('nb_event_pythia', 0)
4538 self.results.add_detail('error_pythia', 0)
4539 else:
4540 self.results.add_detail('cross_pythia', sigma_m)
4541 self.results.add_detail('nb_event_pythia', Nacc)
4542
4543 error = self.results[self.run_name].return_tag(self.run_tag)['error']
4544 if Nacc:
4545 error_m = math.sqrt((error * Nacc/Ntry)**2 + sigma_m**2 *(1-Nacc/Ntry)/Nacc)
4546 else:
4547 error_m = 10000 * sigma_m
4548
4549 self.results.add_detail('error_pythia', error_m)
4550 break
4551
4552 pythia_log.close()
4553
4554 pydir = pjoin(self.options['pythia-pgs_path'], 'src')
4555 eradir = self.options['exrootanalysis_path']
4556 madir = self.options['madanalysis_path']
4557 td = self.options['td_path']
4558
4559
4560 self.banner.add(pjoin(self.me_dir, 'Cards','pythia_card.dat'))
4561 if int(self.run_card['ickkw']):
4562
4563 if 'MGGenerationInfo' in self.banner:
4564 self.banner['MGGenerationInfo'] += '# Matched Integrated weight (pb) : %s\n' % self.results.current['cross_pythia']
4565 else:
4566 self.banner['MGGenerationInfo'] = '# Matched Integrated weight (pb) : %s\n' % self.results.current['cross_pythia']
4567 banner_path = pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, tag))
4568 self.banner.write(banner_path)
4569
4570
4571 self.run_hep2lhe(banner_path)
4572
4573 if int(self.run_card['ickkw']):
4574 misc.gzip(pjoin(self.me_dir,'Events','beforeveto.tree'),
4575 stdout=pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_beforeveto.tree.gz'))
4576
4577
4578 if self.run_card['use_syst'] in self.true:
4579
4580 try:
4581 self.run_syscalc('Pythia')
4582 except SysCalcError, error:
4583 logger.error(str(error))
4584 else:
4585 if os.path.exists(pjoin(self.me_dir,'Events', 'syst.dat')):
4586
4587 misc.gzip(pjoin(self.me_dir,'Events', 'syst.dat'),
4588 stdout=pjoin(self.me_dir,'Events',self.run_name, tag + '_pythia_syst.dat.gz'))
4589
4590
4591 if os.path.exists(pjoin(self.me_dir, 'Events', 'syscalc.dat')):
4592 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
4593 '%s_syscalc.dat' % self.run_tag)
4594 misc.gzip(pjoin(self.me_dir, 'Events','syscalc.dat'),
4595 stdout = "%s.gz" % filename)
4596
4597
4598 self.create_plot('Pythia')
4599
4600 if os.path.exists(pjoin(self.me_dir,'Events','pythia_events.lhe')):
4601 misc.gzip(pjoin(self.me_dir,'Events','pythia_events.lhe'),
4602 stdout=pjoin(self.me_dir,'Events', self.run_name,'%s_pythia_events.lhe.gz' % tag))
4603
4604 self.update_status('finish', level='pythia', makehtml=False)
4605 self.exec_cmd('pgs --no_default', postcmd=False, printcmd=False)
4606 if self.options['delphes_path']:
4607 self.exec_cmd('delphes --no_default', postcmd=False, printcmd=False)
4608 self.print_results_in_shell(self.results.current)
4609
4610
4611
4613 """Remove one/all run or only part of it"""
4614
4615 args = self.split_arg(line)
4616 run, tag, mode = self.check_remove(args)
4617 if 'banner' in mode:
4618 mode.append('all')
4619
4620
4621 if run == 'all':
4622
4623 if os.path.exists(pjoin(self.me_dir, 'Events', 'all')):
4624 logger.warning('A run with name all exists. So we will not supress all processes.')
4625 else:
4626 for match in misc.glob(pjoin('*','*_banner.txt'), pjoin(self.me_dir, 'Events')):
4627 run = match.rsplit(os.path.sep,2)[1]
4628 if self.force:
4629 args.append('-f')
4630 try:
4631 self.exec_cmd('remove %s %s' % (run, ' '.join(args[1:]) ) )
4632 except self.InvalidCmd, error:
4633 logger.info(error)
4634 pass
4635 return
4636
4637
4638 if not os.path.exists(pjoin(self.me_dir, 'Events', run)):
4639 raise self.InvalidCmd('No run \'%s\' detected' % run)
4640
4641 try:
4642 self.resuls.def_current(run)
4643 self.update_status(' Cleaning %s' % run, level=None)
4644 except Exception:
4645 misc.sprint('fail to update results or html status')
4646 pass
4647
4648
4649
4650
4651 to_delete = misc.glob('*', pjoin(self.me_dir, 'Events', run))
4652 to_delete += misc.glob('*', pjoin(self.me_dir, 'HTML', run))
4653
4654 to_delete = [os.path.basename(f) for f in to_delete if 'banner' not in f]
4655 if tag:
4656 to_delete = [f for f in to_delete if tag in f]
4657 if 'parton' in mode or 'all' in mode:
4658 try:
4659 if self.results[run][0]['tag'] != tag:
4660 raise Exception, 'dummy'
4661 except Exception:
4662 pass
4663 else:
4664 nb_rm = len(to_delete)
4665 if os.path.exists(pjoin(self.me_dir, 'Events', run, 'events.lhe.gz')):
4666 to_delete.append('events.lhe.gz')
4667 if os.path.exists(pjoin(self.me_dir, 'Events', run, 'unweighted_events.lhe.gz')):
4668 to_delete.append('unweighted_events.lhe.gz')
4669 if os.path.exists(pjoin(self.me_dir, 'HTML', run,'plots_parton.html')):
4670 to_delete.append(pjoin(self.me_dir, 'HTML', run,'plots_parton.html'))
4671 if nb_rm != len(to_delete):
4672 logger.warning('Be carefull that partonic information are on the point to be removed.')
4673 if 'all' in mode:
4674 pass
4675 else:
4676 if 'pythia' not in mode:
4677 to_delete = [f for f in to_delete if 'pythia' not in f]
4678 if 'pgs' not in mode:
4679 to_delete = [f for f in to_delete if 'pgs' not in f]
4680 if 'delphes' not in mode:
4681 to_delete = [f for f in to_delete if 'delphes' not in f]
4682 if 'parton' not in mode:
4683 to_delete = [f for f in to_delete if 'delphes' in f
4684 or 'pgs' in f
4685 or 'pythia' in f]
4686 if not self.force and len(to_delete):
4687 question = 'Do you want to delete the following files?\n %s' % \
4688 '\n '.join(to_delete)
4689 ans = self.ask(question, 'y', choices=['y','n'])
4690 else:
4691 ans = 'y'
4692
4693 if ans == 'y':
4694 for file2rm in to_delete:
4695 if os.path.exists(pjoin(self.me_dir, 'Events', run, file2rm)):
4696 try:
4697 os.remove(pjoin(self.me_dir, 'Events', run, file2rm))
4698 except Exception:
4699 shutil.rmtree(pjoin(self.me_dir, 'Events', run, file2rm))
4700 else:
4701 try:
4702 os.remove(pjoin(self.me_dir, 'HTML', run, file2rm))
4703 except Exception:
4704 shutil.rmtree(pjoin(self.me_dir, 'HTML', run, file2rm))
4705
4706
4707
4708
4709 if 'all' in mode or 'channel' in mode:
4710 try:
4711 if tag and self.results[run][0]['tag'] != tag:
4712 raise Exception, 'dummy'
4713 except Exception:
4714 pass
4715 else:
4716 to_delete = misc.glob('%s*' % run, pjoin(self.me_dir, 'SubProcesses'))
4717 to_delete += misc.glob(pjoin('*','%s*' % run), pjoin(self.me_dir, 'SubProcesses'))
4718 to_delete += misc.glob(pjoin('*','*','%s*' % run), pjoin(self.me_dir, 'SubProcesses'))
4719
4720 if self.force or len(to_delete) == 0:
4721 ans = 'y'
4722 else:
4723 question = 'Do you want to delete the following files?\n %s' % \
4724 '\n '.join(to_delete)
4725 ans = self.ask(question, 'y', choices=['y','n'])
4726
4727 if ans == 'y':
4728 for file2rm in to_delete:
4729 os.remove(file2rm)
4730
4731 if 'banner' in mode:
4732 to_delete = misc.glob('*', pjoin(self.me_dir, 'Events', run))
4733 if tag:
4734
4735 try:
4736 os.remove(pjoin(self.me_dir, 'Events',run,'%s_%s_banner.txt' % (run,tag)))
4737 except Exception:
4738 logger.warning('fail to remove the banner')
4739
4740 if run in self.results:
4741 self.results.delete_run(run, tag)
4742 return
4743 elif any(['banner' not in os.path.basename(p) for p in to_delete]):
4744 if to_delete:
4745 raise MadGraph5Error, '''Some output still exists for this run.
4746 Please remove those output first. Do for example:
4747 remove %s all banner
4748 ''' % run
4749 else:
4750 shutil.rmtree(pjoin(self.me_dir, 'Events',run))
4751 if run in self.results:
4752 self.results.delete_run(run)
4753 return
4754 else:
4755 logger.info('''The banner is not removed. In order to remove it run:
4756 remove %s all banner %s''' % (run, tag and '--tag=%s ' % tag or ''))
4757
4758
4759 self.results.clean(mode, run, tag)
4760 self.update_status('', level='all')
4761
4762
4763
4764
4766 """Create the plot for a given run"""
4767
4768
4769 self.store_result()
4770 args = self.split_arg(line)
4771
4772 self.check_plot(args)
4773 logger.info('plot for run %s' % self.run_name)
4774 if not self.force:
4775 self.ask_edit_cards([], args, plot=True)
4776
4777 if any([arg in ['all','parton'] for arg in args]):
4778 filename = pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe')
4779 if os.path.exists(filename+'.gz'):
4780 misc.gunzip('%s.gz' % filename, keep=True)
4781 if os.path.exists(filename):
4782 files.ln(filename, pjoin(self.me_dir, 'Events'))
4783 self.create_plot('parton')
4784 if not os.path.exists(filename+'.gz'):
4785 misc.gzip(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'),
4786 stdout= "%s.gz" % filename)
4787 else:
4788 try:
4789 os.remove(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'))
4790 os.remove(filename)
4791 except Exception:
4792 pass
4793 else:
4794 logger.info('No valid files for partonic plot')
4795
4796 if any([arg in ['all','pythia'] for arg in args]):
4797 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
4798 '%s_pythia_events.lhe' % self.run_tag)
4799 if os.path.exists(filename+'.gz'):
4800 misc.gunzip("%s.gz" % filename)
4801 if os.path.exists(filename):
4802 shutil.move(filename, pjoin(self.me_dir, 'Events','pythia_events.lhe'))
4803 self.create_plot('Pythia')
4804 misc.gzip(pjoin(self.me_dir, 'Events','pythia_events.lhe'),
4805 stdout= "%s.gz" % filename)
4806 else:
4807 logger.info('No valid files for pythia plot')
4808
4809
4810 if any([arg in ['all','pgs'] for arg in args]):
4811 filename = pjoin(self.me_dir, 'Events', self.run_name,
4812 '%s_pgs_events.lhco' % self.run_tag)
4813 if os.path.exists(filename+'.gz'):
4814 misc.gunzip("%s.gz" % filename)
4815 if os.path.exists(filename):
4816 self.create_plot('PGS')
4817 misc.gzip(filename)
4818 else:
4819 logger.info('No valid files for pgs plot')
4820
4821 if any([arg in ['all','delphes'] for arg in args]):
4822 filename = pjoin(self.me_dir, 'Events', self.run_name,
4823 '%s_delphes_events.lhco' % self.run_tag)
4824 if os.path.exists(filename+'.gz'):
4825 misc.gunzip("%s.gz" % filename)
4826 if os.path.exists(filename):
4827 self.create_plot('Delphes')
4828 misc.gzip(filename)
4829 else:
4830 logger.info('No valid files for delphes plot')
4831
4832
4834 """Evaluate systematics variation weights for a given run"""
4835
4836
4837 self.store_result()
4838 args = self.split_arg(line)
4839
4840 self.check_syscalc(args)
4841 if self.ninitial == 1:
4842 logger.error('SysCalc can\'t be run for decay processes')
4843 return
4844
4845 logger.info('Calculating systematics for run %s' % self.run_name)
4846
4847 self.ask_edit_cards(['run_card'], args)
4848 self.run_card = banner_mod.RunCard(pjoin(self.me_dir, 'Cards', 'run_card.dat'))
4849 if any([arg in ['all','parton'] for arg in args]):
4850 filename = pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe')
4851 if os.path.exists(filename+'.gz'):
4852 misc.gunzip("%s.gz" % filename)
4853 if os.path.exists(filename):
4854 shutil.move(filename, pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'))
4855 self.run_syscalc('parton')
4856 misc.gzip(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'),
4857 stdout="%s.gz" % filename)
4858 else:
4859 logger.info('No valid files for parton level systematics run.')
4860
4861 if any([arg in ['all','pythia'] for arg in args]):
4862 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
4863 '%s_pythia_syst.dat' % self.run_tag)
4864 if os.path.exists(filename+'.gz'):
4865 misc.gunzip("%s.gz" % filename)
4866 if os.path.exists(filename):
4867 shutil.move(filename, pjoin(self.me_dir, 'Events','syst.dat'))
4868 try:
4869 self.run_syscalc('Pythia')
4870 except SysCalcError, error:
4871 logger.warning(str(error))
4872 return
4873 misc.gzip(pjoin(self.me_dir, 'Events','syst.dat'), "%s.gz" % filename)
4874 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
4875 '%s_syscalc.dat' % self.run_tag)
4876 misc.gzip(pjoin(self.me_dir, 'Events','syscalc.dat'),
4877 stdout=filename)
4878 else:
4879 logger.info('No valid files for pythia level')
4880
4881
4883 """ tar the pythia results. This is done when we are quite sure that
4884 the pythia output will not be use anymore """
4885
4886 if not self.run_name:
4887 return
4888
4889 self.results.save()
4890
4891
4892 if not self.to_store:
4893 return
4894
4895 tag = self.run_card['run_tag']
4896 self.update_status('storing files of previous run', level=None,\
4897 error=True)
4898 if 'event' in self.to_store:
4899 if not os.path.exists(pjoin(self.me_dir, 'Events',self.run_name, 'unweighted_events.lhe.gz')) and\
4900 os.path.exists(pjoin(self.me_dir, 'Events',self.run_name, 'unweighted_events.lhe')):
4901 logger.info("gzipping output file: unweighted_events.lhe")
4902 misc.gzip(pjoin(self.me_dir,'Events',self.run_name,"unweighted_events.lhe"))
4903 if os.path.exists(pjoin(self.me_dir,'Events','reweight.lhe')):
4904 os.remove(pjoin(self.me_dir,'Events', 'reweight.lhe'))
4905
4906 if 'pythia' in self.to_store:
4907 self.update_status('Storing Pythia files of previous run', level='pythia', error=True)
4908
4909 p = pjoin(self.me_dir,'Events')
4910 n = self.run_name
4911 t = tag
4912 self.to_store.remove('pythia')
4913 misc.gzip(pjoin(p,'pythia_events.hep'),
4914 stdout=pjoin(p, str(n),'%s_pythia_events.hep' % t))
4915
4916 if 'pythia8' in self.to_store:
4917 p = pjoin(self.me_dir,'Events')
4918 n = self.run_name
4919 t = tag
4920 file_path = pjoin(p, n ,'%s_pythia8_events.hepmc'%t)
4921 self.to_store.remove('pythia8')
4922 if os.path.isfile(file_path):
4923 self.update_status('Storing Pythia8 files of previous run',
4924 level='pythia', error=True)
4925 misc.gzip(file_path,stdout=file_path)
4926
4927 self.update_status('Done', level='pythia',makehtml=False,error=True)
4928
4929 self.to_store = []
4930
4931 - def launch_job(self,exe, cwd=None, stdout=None, argument = [], remaining=0,
4932 run_type='', mode=None, **opt):
4933 """ """
4934 argument = [str(arg) for arg in argument]
4935 if mode is None:
4936 mode = self.cluster_mode
4937
4938
4939 if os.path.exists(exe) and not os.access(exe, os.X_OK):
4940 os.system('chmod +x %s ' % exe)
4941 elif (cwd and os.path.exists(pjoin(cwd, exe))) and not \
4942 os.access(pjoin(cwd, exe), os.X_OK):
4943 os.system('chmod +x %s ' % pjoin(cwd, exe))
4944
4945 if mode == 0:
4946 self.update_status((remaining, 1,
4947 self.total_jobs - remaining -1, run_type), level=None, force=False)
4948 start = time.time()
4949
4950 status = misc.call([exe] + argument, cwd=cwd, stdout=stdout, **opt)
4951 logger.info('%s run in %f s' % (exe, time.time() -start))
4952 if status:
4953 raise MadGraph5Error, '%s didn\'t stop properly. Stop all computation' % exe
4954
4955
4956 elif mode in [1,2]:
4957 exename = os.path.basename(exe)
4958
4959 if 'ajob' in exename:
4960 input_files = ['madevent','input_app.txt','symfact.dat','iproc.dat','dname.mg',
4961 pjoin(self.me_dir, 'SubProcesses','randinit')]
4962 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
4963 'MadLoop5_resources.tar.gz')) and cluster.need_transfer(self.options):
4964 input_files.append(pjoin(self.me_dir,'SubProcesses', 'MadLoop5_resources.tar.gz'))
4965
4966 output_files = []
4967 required_output = []
4968
4969
4970
4971 input_files.append(self.get_pdf_input_filename())
4972
4973
4974 Gre = re.compile("\s*j=(G[\d\.\w]+)")
4975 origre = re.compile("grid_directory=(G[\d\.\w]+)")
4976 try :
4977 fsock = open(exe)
4978 except Exception:
4979 fsock = open(pjoin(cwd,exe))
4980 text = fsock.read()
4981 output_files = Gre.findall(text)
4982 if not output_files:
4983 Ire = re.compile("for i in ([\d\.\s]*) ; do")
4984 data = Ire.findall(text)
4985 data = ' '.join(data).split()
4986 for nb in data:
4987 output_files.append('G%s' % nb)
4988 required_output.append('G%s/results.dat' % nb)
4989 else:
4990 for G in output_files:
4991 if os.path.isdir(pjoin(cwd,G)):
4992 input_files.append(G)
4993 required_output.append('%s/results.dat' % G)
4994
4995 if origre.search(text):
4996 G_grid = origre.search(text).groups()[0]
4997 input_files.append(pjoin(G_grid, 'ftn26'))
4998
4999
5000 self.cluster.submit2(exe, stdout=stdout, cwd=cwd,
5001 input_files=input_files, output_files=output_files,
5002 required_output=required_output)
5003 elif 'survey' in exename:
5004 input_files = ['madevent','input_app.txt','symfact.dat','iproc.dat', 'dname.mg',
5005 pjoin(self.me_dir, 'SubProcesses','randinit')]
5006 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
5007 'MadLoop5_resources.tar.gz')) and cluster.need_transfer(self.options):
5008 input_files.append(pjoin(self.me_dir,'SubProcesses',
5009 'MadLoop5_resources.tar.gz'))
5010
5011
5012 input_files.append(self.get_pdf_input_filename())
5013
5014
5015 output_files = []
5016 required_output = []
5017
5018
5019 suffix = "_%s" % int(float(argument[0]))
5020 if suffix == '_0':
5021 suffix = ''
5022 output_files = ['G%s%s' % (i, suffix) for i in argument[1:]]
5023 for G in output_files:
5024 required_output.append('%s/results.dat' % G)
5025
5026
5027 for G in output_files:
5028 if '.' in argument[0]:
5029 offset = int(str(argument[0]).split('.')[1])
5030 else:
5031 offset = 0
5032
5033 if offset ==0 or offset == int(float(argument[0])):
5034 if os.path.exists(pjoin(cwd, G, 'input_app.txt')):
5035 os.remove(pjoin(cwd, G, 'input_app.txt'))
5036
5037 if os.path.exists(os.path.realpath(pjoin(cwd, G, 'ftn25'))):
5038 if offset == 0 or offset == int(float(argument[0])):
5039 os.remove(pjoin(cwd, G, 'ftn25'))
5040 continue
5041 else:
5042 input_files.append(pjoin(cwd, G, 'ftn25'))
5043 input_files.remove('input_app.txt')
5044 input_files.append(pjoin(cwd, G, 'input_app.txt'))
5045 elif os.path.lexists(pjoin(cwd, G, 'ftn25')):
5046 try:
5047 os.remove(pjoin(cwd,G,'ftn25'))
5048 except:
5049 pass
5050
5051
5052 self.cluster.cluster_submit(exe, stdout=stdout, cwd=cwd, argument=argument,
5053 input_files=input_files, output_files=output_files,
5054 required_output=required_output, **opt)
5055 elif "refine_splitted.sh" in exename:
5056 input_files = ['madevent','symfact.dat','iproc.dat', 'dname.mg',
5057 pjoin(self.me_dir, 'SubProcesses','randinit')]
5058
5059 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
5060 'MadLoop5_resources.tar.gz')) and cluster.need_transfer(self.options):
5061 input_files.append(pjoin(self.me_dir,'SubProcesses',
5062 'MadLoop5_resources.tar.gz'))
5063
5064
5065 input_files.append(self.get_pdf_input_filename())
5066
5067
5068 output_files = [argument[0]]
5069 required_output = []
5070 for G in output_files:
5071 required_output.append('%s/results.dat' % G)
5072 input_files.append(pjoin(argument[1], "input_app.txt"))
5073 input_files.append(pjoin(argument[1], "ftn26"))
5074
5075
5076 self.cluster.cluster_submit(exe, stdout=stdout, cwd=cwd, argument=argument,
5077 input_files=input_files, output_files=output_files,
5078 required_output=required_output, **opt)
5079
5080
5081
5082 else:
5083 self.cluster.submit(exe, argument=argument, stdout=stdout, cwd=cwd, **opt)
5084
5085
5086
5088 """Find if Madevent is in Group mode or not"""
5089
5090
5091
5092 file_path = pjoin(self.me_dir, 'Source', 'run_config.inc')
5093 text = open(file_path).read()
5094 if re.search(r'''s*parameter\s+\(ChanPerJob=2\)''', text, re.I+re.M):
5095 return 'group'
5096 else:
5097 return 'v4'
5098
5099
5100 - def monitor(self, run_type='monitor', mode=None, html=False):
5101 """ monitor the progress of running job """
5102
5103
5104 starttime = time.time()
5105 if mode is None:
5106 mode = self.cluster_mode
5107 if mode > 0:
5108 if html:
5109 update_status = lambda idle, run, finish: \
5110 self.update_status((idle, run, finish, run_type), level=None,
5111 force=False, starttime=starttime)
5112 update_first = lambda idle, run, finish: \
5113 self.update_status((idle, run, finish, run_type), level=None,
5114 force=True, starttime=starttime)
5115 else:
5116 update_status = lambda idle, run, finish: None
5117 update_first = None
5118 try:
5119 self.cluster.wait(self.me_dir, update_status, update_first=update_first)
5120 except Exception, error:
5121 logger.info(error)
5122 if not self.force:
5123 ans = self.ask('Cluster Error detected. Do you want to clean the queue? ("c"=continue the run anyway)',
5124 default = 'y', choices=['y','n', 'c'])
5125 else:
5126 ans = 'y'
5127 if ans == 'y':
5128 self.cluster.remove()
5129 elif ans == 'c':
5130 return self.monitor(run_type=run_type, mode=mode, html=html)
5131 raise
5132 except KeyboardInterrupt, error:
5133 self.cluster.remove()
5134 raise
5135
5136
5137
5138
5260
5261
5262
5263
5264 @staticmethod
5266 """check if the directory exists. if so return the path otherwise the
5267 default"""
5268
5269 if os.path.isdir(path):
5270 return path
5271 else:
5272 return default
5273
5274
5276 """get the list of Pdirectory if not yet saved."""
5277
5278 if hasattr(self, "Pdirs"):
5279 if self.me_dir in self.Pdirs[0]:
5280 return self.Pdirs
5281 self.Pdirs = [pjoin(self.me_dir, 'SubProcesses', l.strip())
5282 for l in open(pjoin(self.me_dir,'SubProcesses', 'subproc.mg'))]
5283 return self.Pdirs
5284
5285
5287 """get the list of Gdirectory if not yet saved."""
5288
5289 if hasattr(self, "Gdirs"):
5290 if self.me_dir in self.Gdirs[0]:
5291 return self.Gdirs
5292
5293 Pdirs = self.get_Pdir()
5294 Gdirs = []
5295 for P in Pdirs:
5296 for line in open(pjoin(P, "symfact.dat")):
5297 tag, mfactor = line.split()
5298 Gdirs.append( (pjoin(P, "G%s" % tag), int(mfactor)) )
5299
5300
5301 self.Gdirs = Gdirs
5302 return self.Gdirs
5303
5304
5305 - def set_run_name(self, name, tag=None, level='parton', reload_card=False,
5306 allow_new_tag=True):
5307 """define the run name, the run_tag, the banner and the results."""
5308
5309 def get_last_tag(self, level):
5310
5311
5312 if level == 'parton':
5313 return
5314 elif level in ['pythia','pythia8','madanalysis5_parton','madanalysis5_hadron']:
5315 return self.results[self.run_name][0]['tag']
5316 else:
5317 for i in range(-1,-len(self.results[self.run_name])-1,-1):
5318 tagRun = self.results[self.run_name][i]
5319 if tagRun.pythia or tagRun.shower or tagRun.pythia8 :
5320 return tagRun['tag']
5321
5322
5323
5324 upgrade_tag = {'parton': ['parton','pythia','pgs','delphes','madanalysis5_hadron','madanalysis5_parton'],
5325 'pythia': ['pythia','pgs','delphes','madanalysis5_hadron'],
5326 'pythia8': ['pythia8','pgs','delphes','madanalysis5_hadron'],
5327 'pgs': ['pgs'],
5328 'delphes':['delphes'],
5329 'madanalysis5_hadron':['madanalysis5_hadron'],
5330 'madanalysis5_parton':['madanalysis5_parton'],
5331 'plot':[],
5332 'syscalc':[]}
5333
5334 if name == self.run_name:
5335 if reload_card:
5336 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
5337 self.run_card = banner_mod.RunCard(run_card)
5338
5339
5340 if tag:
5341 self.run_card['run_tag'] = tag
5342 self.run_tag = tag
5343 self.results.add_run(self.run_name, self.run_card)
5344 else:
5345 for tag in upgrade_tag[level]:
5346 if getattr(self.results[self.run_name][-1], tag):
5347 tag = self.get_available_tag()
5348 self.run_card['run_tag'] = tag
5349 self.run_tag = tag
5350 self.results.add_run(self.run_name, self.run_card)
5351 break
5352 return get_last_tag(self, level)
5353
5354
5355
5356 if self.run_name:
5357 self.store_result()
5358
5359 self.run_name = name
5360
5361 new_tag = False
5362
5363 self.banner = banner_mod.recover_banner(self.results, level, name)
5364 if 'mgruncard' in self.banner:
5365 self.run_card = self.banner.charge_card('run_card')
5366 else:
5367
5368 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
5369 self.run_card = banner_mod.RunCard(run_card)
5370
5371 if tag:
5372 self.run_card['run_tag'] = tag
5373 new_tag = True
5374 elif not self.run_name in self.results and level =='parton':
5375 pass
5376 elif not self.run_name in self.results:
5377
5378 logger.warning('Trying to run data on unknown run.')
5379 self.results.add_run(name, self.run_card)
5380 self.results.update('add run %s' % name, 'all', makehtml=False)
5381 else:
5382 for tag in upgrade_tag[level]:
5383
5384 if getattr(self.results[self.run_name][-1], tag):
5385
5386 tag = self.get_available_tag()
5387 self.run_card['run_tag'] = tag
5388 new_tag = True
5389 break
5390 if not new_tag:
5391
5392 tag = self.results[self.run_name][-1]['tag']
5393 self.run_card['run_tag'] = tag
5394
5395 if allow_new_tag and (name in self.results and not new_tag):
5396 self.results.def_current(self.run_name)
5397 else:
5398 self.results.add_run(self.run_name, self.run_card)
5399
5400 self.run_tag = self.run_card['run_tag']
5401
5402 return get_last_tag(self, level)
5403
5404
5405
5407 """ return the model name """
5408 if hasattr(self, 'model_name'):
5409 return self.model_name
5410
5411 model = 'sm'
5412 proc = []
5413 for line in open(os.path.join(self.me_dir,'Cards','proc_card_mg5.dat')):
5414 line = line.split('#')[0]
5415
5416 if line.startswith('import') and 'model' in line:
5417 model = line.split()[2]
5418 proc = []
5419 elif line.startswith('generate'):
5420 proc.append(line.split(None,1)[1])
5421 elif line.startswith('add process'):
5422 proc.append(line.split(None,2)[2])
5423
5424 self.model = model
5425 self.process = proc
5426 return model
5427
5428
5429
5431 """Find the number of event in the run_card, and check that this is not
5432 too large"""
5433
5434
5435 nb_event = int(self.run_card['nevents'])
5436 if nb_event > 1000000:
5437 logger.warning("Attempting to generate more than 1M events")
5438 logger.warning("Limiting number to 1M. Use multi_run for larger statistics.")
5439 path = pjoin(self.me_dir, 'Cards', 'run_card.dat')
5440 os.system(r"""perl -p -i.bak -e "s/\d+\s*=\s*nevents/1000000 = nevents/" %s""" \
5441 % path)
5442 self.run_card['nevents'] = 1000000
5443
5444 return
5445
5446
5447
5449 """ change random number"""
5450
5451 self.random += 3
5452 if self.random > 30081*30081:
5453 raise MadGraph5Error,\
5454 'Random seed too large ' + str(self.random) + ' > 30081*30081'
5455
5456
5458 """save random number in appropirate file"""
5459
5460 fsock = open(pjoin(self.me_dir, 'SubProcesses','randinit'),'w')
5461 fsock.writelines('r=%s\n' % self.random)
5462
5463 - def do_quit(self, *args, **opts):
5467
5468
5470 """check for ckkw"""
5471
5472 lpp1 = self.run_card['lpp1']
5473 lpp2 = self.run_card['lpp2']
5474 e1 = self.run_card['ebeam1']
5475 e2 = self.run_card['ebeam2']
5476 pd = self.run_card['pdlabel']
5477 lha = self.run_card['lhaid']
5478 xq = self.run_card['xqcut']
5479 translation = {'e1': e1, 'e2':e2, 'pd':pd,
5480 'lha':lha, 'xq':xq}
5481
5482 if lpp1 or lpp2:
5483
5484 if pd.startswith("'"):
5485 pd = pd[1:]
5486 if pd.endswith("'"):
5487 pd = pd[:-1]
5488
5489 if xq >2 or xq ==2:
5490 xq = 2
5491
5492
5493 if pd == "lhapdf":
5494 issudfile = 'lib/issudgrid-%(e1)s-%(e2)s-%(pd)s-%(lha)s-%(xq)s.dat.gz'
5495 else:
5496 issudfile = 'lib/issudgrid-%(e1)s-%(e2)s-%(pd)s-%(xq)s.dat.gz'
5497 if self.web:
5498 issudfile = pjoin(self.webbin, issudfile % translation)
5499 else:
5500 issudfile = pjoin(self.me_dir, issudfile % translation)
5501
5502 logger.info('Sudakov grid file: %s' % issudfile)
5503
5504
5505 if os.path.exists(issudfile):
5506 path = pjoin(self.me_dir, 'lib', 'issudgrid.dat')
5507 misc.gunzip(issudfile, keep=True, stdout=path)
5508 else:
5509 msg = 'No sudakov grid file for parameter choice. Start to generate it. This might take a while'
5510 logger.info(msg)
5511 self.update_status('GENERATE SUDAKOV GRID', level='parton')
5512
5513 for i in range(-2,6):
5514 self.cluster.submit('%s/gensudgrid ' % self.dirbin,
5515 argument = ['%d'%i],
5516 cwd=self.me_dir,
5517 stdout=open(pjoin(self.me_dir, 'gensudgrid%s.log' % i),'w'))
5518 self.monitor()
5519 for i in range(-2,6):
5520 path = pjoin(self.me_dir, 'lib', 'issudgrid.dat')
5521 os.system('cat %s/gensudgrid%s.log >> %s' % (self.me_dir, path))
5522 misc.gzip(path, stdout=issudfile)
5523
5524
5525 - def create_root_file(self, input='unweighted_events.lhe',
5526 output='unweighted_events.root' ):
5527 """create the LHE root file """
5528 self.update_status('Creating root files', level='parton')
5529
5530 eradir = self.options['exrootanalysis_path']
5531 totar = False
5532 if input.endswith('.gz'):
5533 misc.gunzip(input, keep=True)
5534 totar = True
5535 input = input[:-3]
5536
5537 try:
5538 misc.call(['%s/ExRootLHEFConverter' % eradir,
5539 input, output],
5540 cwd=pjoin(self.me_dir, 'Events'))
5541 except Exception:
5542 logger.warning('fail to produce Root output [problem with ExRootAnalysis]')
5543
5544 if totar:
5545 if os.path.exists('%s.gz' % input):
5546 try:
5547 os.remove(input)
5548 except:
5549 pass
5550 else:
5551 misc.gzip(input,keep=False)
5552
5553
5554 - def run_syscalc(self, mode='parton', event_path=None, output=None):
5555 """create the syscalc output"""
5556
5557 if self.run_card['use_syst'] not in self.true:
5558 return
5559
5560 scdir = self.options['syscalc_path']
5561 if not scdir or not os.path.exists(scdir):
5562 return
5563
5564 if self.run_card['event_norm'] != 'sum':
5565 logger.critical('SysCalc works only when event_norm is on \'sum\'.')
5566 return
5567 logger.info('running SysCalc on mode %s' % mode)
5568
5569
5570 if self.run_card['sys_matchscale']=='auto':
5571 self.run_card['sys_matchscale'] = "30 50"
5572
5573
5574 lhaid = [self.run_card.get_lhapdf_id()]
5575 if '&&' in self.run_card['sys_pdf']:
5576 line = ' '.join(self.run_card['sys_pdf'])
5577 sys_pdf = line.split('&&')
5578 lhaid += [l.split()[0] for l in sys_pdf]
5579 else:
5580 lhaid += [l for l in self.run_card['sys_pdf'].split() if not l.isdigit() or int(l) > 500]
5581 try:
5582 pdfsets_dir = self.get_lhapdf_pdfsetsdir()
5583 except Exception, error:
5584 logger.debug(str(error))
5585 logger.warning('Systematic computation requires lhapdf to run. Bypass SysCalc')
5586 return
5587
5588
5589 [self.copy_lhapdf_set([onelha], pdfsets_dir) for onelha in lhaid]
5590
5591 to_syscalc={'sys_scalefact': self.run_card['sys_scalefact'],
5592 'sys_alpsfact': self.run_card['sys_alpsfact'],
5593 'sys_matchscale': self.run_card['sys_matchscale'],
5594 'sys_scalecorrelation': self.run_card['sys_scalecorrelation'],
5595 'sys_pdf': self.run_card['sys_pdf']}
5596
5597 tag = self.run_card['run_tag']
5598 card = pjoin(self.me_dir, 'bin','internal', 'syscalc_card.dat')
5599 template = open(pjoin(self.me_dir, 'bin','internal', 'syscalc_template.dat')).read()
5600
5601 if '&&' in to_syscalc['sys_pdf']:
5602 to_syscalc['sys_pdf'] = to_syscalc['sys_pdf'].split('#',1)[0].replace('&&',' \n ')
5603 else:
5604 data = to_syscalc['sys_pdf'].split()
5605 new = []
5606 for d in data:
5607 if not d.isdigit():
5608 new.append(d)
5609 elif int(d) > 500:
5610 new.append(d)
5611 else:
5612 new[-1] += ' %s' % d
5613 to_syscalc['sys_pdf'] = '\n'.join(new)
5614
5615 if to_syscalc['sys_pdf'].lower() in ['', 'f', 'false', 'none', '.false.']:
5616 to_syscalc['sys_pdf'] = ''
5617 if to_syscalc['sys_alpsfact'].lower() in ['', 'f', 'false', 'none','.false.']:
5618 to_syscalc['sys_alpsfact'] = ''
5619
5620
5621
5622
5623
5624 if not 'sys_scalecorrelation' in self.run_card:
5625 self.run_card['sys_scalecorrelation'] = -1
5626 open(card,'w').write(template % self.run_card)
5627
5628 if not os.path.exists(card):
5629 return False
5630
5631
5632
5633 event_dir = pjoin(self.me_dir, 'Events')
5634
5635 if not event_path:
5636 if mode == 'parton':
5637 event_path = pjoin(event_dir,self.run_name, 'unweighted_events.lhe')
5638 if not (os.path.exists(event_path) or os.path.exists(event_path+".gz")):
5639 event_path = pjoin(event_dir, 'unweighted_events.lhe')
5640 output = pjoin(event_dir, 'syscalc.lhe')
5641 stdout = open(pjoin(event_dir, self.run_name, '%s_systematics.log' % (mode)),'w')
5642 elif mode == 'Pythia':
5643 stdout = open(pjoin(event_dir, self.run_name, '%s_%s_syscalc.log' % (tag,mode)),'w')
5644 if 'mgpythiacard' in self.banner:
5645 pat = re.compile('''^\s*qcut\s*=\s*([\+\-\d.e]*)''', re.M+re.I)
5646 data = pat.search(self.banner['mgpythiacard'])
5647 if data:
5648 qcut = float(data.group(1))
5649 xqcut = abs(self.run_card['xqcut'])
5650 for value in self.run_card['sys_matchscale'].split():
5651 if float(value) < qcut:
5652 raise SysCalcError, 'qcut value for sys_matchscale lower than qcut in pythia_card. Bypass syscalc'
5653 if float(value) < xqcut:
5654 raise SysCalcError, 'qcut value for sys_matchscale lower than xqcut in run_card. Bypass syscalc'
5655
5656
5657 event_path = pjoin(event_dir,'syst.dat')
5658 output = pjoin(event_dir, 'syscalc.dat')
5659 else:
5660 raise self.InvalidCmd, 'Invalid mode %s' % mode
5661
5662 if not os.path.exists(event_path):
5663 if os.path.exists(event_path+'.gz'):
5664 misc.gunzip(event_path+'.gz')
5665 else:
5666 raise SysCalcError, 'Events file %s does not exits' % event_path
5667
5668 self.update_status('Calculating systematics for %s level' % mode, level = mode.lower())
5669 try:
5670 proc = misc.call([os.path.join(scdir, 'sys_calc'),
5671 event_path, card, output],
5672 stdout = stdout,
5673 stderr = subprocess.STDOUT,
5674 cwd=event_dir)
5675
5676 time.sleep(5)
5677 except OSError, error:
5678 logger.error('fail to run syscalc: %s. Please check that SysCalc is correctly installed.' % error)
5679 else:
5680 if not os.path.exists(output):
5681 logger.warning('SysCalc Failed. Please read the associate log to see the reason. Did you install the associate PDF set?')
5682 elif mode == 'parton':
5683 files.mv(output, event_path)
5684
5685 self.update_status('End syscalc for %s level' % mode, level = mode.lower(),
5686 makehtml=False)
5687
5688 return True
5689
5690
5691
5692
5694 """Ask the question when launching generate_events/multi_run"""
5695
5696 available_mode = ['0']
5697 void = 'Not installed'
5698 switch_order = ['shower', 'detector', 'analysis', 'madspin', 'reweight']
5699
5700 switch = dict((k, void) for k in switch_order)
5701
5702 description = {'shower': 'Choose the shower/hadronization program:',
5703 'detector': 'Choose the detector simulation program:',
5704 'madspin': 'Decay particles with the MadSpin module:',
5705 'reweight':'Add weights to events for different model hypothesis:',
5706 'analysis':'Run an analysis package on the events generated:'
5707 }
5708
5709 force_switch = {('shower', 'OFF'): {'detector': 'OFF'},
5710 ('detector', 'PGS'): {'shower':'PYTHIA6'},
5711 ('detector', 'DELPHES'): {'shower': ['PYTHIA8', 'PYTHIA6']}}
5712
5713 switch_assign = lambda key, value: switch.__setitem__(key, value if value \
5714 in valid_options[key] else switch[key])
5715
5716 valid_options = dict((k, ['OFF']) for k in switch_order)
5717 options = ['auto', 'done']
5718 options_legacy = []
5719
5720
5721 if self.options['pythia-pgs_path']:
5722 available_mode.append('1')
5723 available_mode.append('2')
5724 valid_options['shower'].append('PYTHIA6')
5725 valid_options['detector'].append('PGS')
5726 options_legacy += ['pythia', 'pgs', 'pythia=ON', 'pythia=OFF', 'pgs=ON', 'pgs=OFF']
5727 if os.path.exists(pjoin(self.me_dir,'Cards','pythia_card.dat')):
5728 switch['shower'] = 'PYTHIA6'
5729 else:
5730 switch['shower'] = 'OFF'
5731 if os.path.exists(pjoin(self.me_dir,'Cards','pgs_card.dat')):
5732 switch['detector'] = 'PGS'
5733 else:
5734 switch['detector'] = 'OFF'
5735
5736 if self.options['pythia8_path']:
5737 available_mode.append('1')
5738 valid_options['shower'].append('PYTHIA8')
5739 if os.path.exists(pjoin(self.me_dir,'Cards','pythia8_card.dat')):
5740 switch['shower'] = 'PYTHIA8'
5741 elif switch['shower'] == void:
5742 switch['shower'] = 'OFF'
5743
5744
5745 if self.options['madanalysis_path']:
5746 if os.path.exists(pjoin(self.me_dir,'Cards','plot_card_default.dat')):
5747 valid_options['analysis'].insert(0,'MADANALYSIS_4')
5748
5749 if os.path.exists(pjoin(self.me_dir,'Cards','plot_card.dat')):
5750 switch['analysis'] = 'MADANALYSIS_4'
5751
5752
5753 if self.options['madanalysis5_path']:
5754 if os.path.exists(pjoin(self.me_dir,'Cards','madanalysis5_parton_card_default.dat')) or \
5755 os.path.exists(pjoin(self.me_dir,'Cards','madanalysis5_hadron_card_default.dat')):
5756 valid_options['analysis'].append('MADANALYSIS_5')
5757
5758 parton_card_present = os.path.exists(pjoin(self.me_dir,'Cards',
5759 'madanalysis5_parton_card.dat'))
5760 hadron_card_present = os.path.exists(pjoin(self.me_dir,'Cards',
5761 'madanalysis5_hadron_card.dat'))
5762 if hadron_card_present or parton_card_present:
5763 switch['analysis'] = 'MADANALYSIS_5'
5764
5765
5766 eradir = self.options['exrootanalysis_path']
5767 if eradir and misc.is_executable(pjoin(eradir,'ExRootLHEFConverter')):
5768 valid_options['analysis'].insert(0,'EXROOTANALYSIS')
5769 if switch['analysis'] in ['OFF', void]:
5770 switch['analysis'] = 'EXROOTANALYSIS'
5771
5772
5773
5774 if len(valid_options['analysis'])>1:
5775 available_mode.append('3')
5776 if switch['analysis'] == void:
5777 switch['analysis'] = 'OFF'
5778 else:
5779 switch['analysis'] = 'No analysis tool interfaced to MG5aMC.'
5780
5781
5782 if self.options['delphes_path']:
5783 if valid_options['shower'] != ['OFF']:
5784 available_mode.append('2')
5785 valid_options['detector'].append('DELPHES')
5786 options += ['delphes', 'delphes=ON', 'delphes=OFF']
5787 if os.path.exists(pjoin(self.me_dir,'Cards','delphes_card.dat')):
5788 switch['detector'] = 'DELPHES'
5789 elif switch['detector'] not in ['PGS']:
5790 switch['detector'] = 'OFF'
5791 elif valid_options['detector'] == ['OFF']:
5792 switch['detector'] = "Requires a shower"
5793
5794
5795 if not MADEVENT or ('mg5_path' in self.options and self.options['mg5_path']):
5796 available_mode.append('4')
5797 valid_options['madspin'] = ['ON', 'OFF']
5798 if os.path.exists(pjoin(self.me_dir,'Cards','madspin_card.dat')):
5799 switch['madspin'] = 'ON'
5800 else:
5801 switch['madspin'] = 'OFF'
5802 if misc.has_f2py() or self.options['f2py_compiler']:
5803 available_mode.append('5')
5804 valid_options['reweight'] = ['ON', 'OFF']
5805 if os.path.exists(pjoin(self.me_dir,'Cards','reweight_card.dat')):
5806 switch['reweight'] = 'ON'
5807 else:
5808 switch['reweight'] = 'OFF'
5809 else:
5810 switch['reweight'] = 'Not available (requires NumPy/f2py)'
5811
5812 if '-R' in args or '--reweight' in args:
5813 if switch['reweight'] == 'OFF':
5814 switch['reweight'] = 'ON'
5815 elif switch['reweight'] != 'ON':
5816 logger.critical("Cannot run reweight: %s", switch['reweight'])
5817 if '-M' in args or '--madspin' in args:
5818 if switch['madspin'] == 'OFF':
5819 switch['madspin'] = 'ON'
5820 elif switch['madspin'] != 'ON':
5821 logger.critical("Cannot run madspin: %s", switch['reweight'])
5822
5823 for id, key in enumerate(switch_order):
5824 if len(valid_options[key]) >1:
5825 options += ['%s=%s' % (key, s) for s in valid_options[key]]
5826 options.append(key)
5827 else:
5828 options.append('%s=OFF' % (key))
5829
5830 options += ['parton'] + sorted(list(set(available_mode)))
5831 options += options_legacy
5832
5833
5834
5835 def color(switch_value):
5836 green = '\x1b[32m%s\x1b[0m'
5837 bold = '\x1b[33m%s\x1b[0m'
5838 red = '\x1b[31m%s\x1b[0m'
5839 if switch_value in ['OFF',void,'Requires a shower',
5840 'Not available (requires NumPy)',
5841 'Not available yet for this output/process']:
5842 return red%switch_value
5843 elif switch_value in ['ON','MADANALYSIS_4','MADANALYSIS_5',
5844 'PYTHIA8','PYTHIA6','PGS','DELPHES-ATLAS',
5845 'DELPHES-CMS','DELPHES', 'EXROOTANALYSIS']:
5846 return green%switch_value
5847 else:
5848 return bold%switch_value
5849
5850 if mode or not self.force:
5851 answer = ''
5852 while answer not in ['0', 'done', 'auto']:
5853 if mode:
5854 answer = mode
5855 else:
5856 switch_format = " \x1b[31m%i\x1b[0m. %-60s %12s = %s"
5857 question = "The following switches determine which programs are run:\n"
5858 question += '/'+'-'*98+'\\\n'
5859 for id, key in enumerate(switch_order):
5860 question += '| %-115s|\n'%(switch_format%(id+1, description[key], key, color(switch[key])))
5861 question += '\\'+'-'*98+'/\n'
5862 question += ' Either type the switch number (1 to %s) to change its setting,\n' % (id+1)
5863 question += ' Set any switch explicitly (e.g. type \'madspin=ON\' at the prompt)\n'
5864 question += ' Type \'help\' for the list of all valid option\n'
5865 question += ' Type \'0\', \'auto\', \'done\' or just press enter when you are done.\n'
5866 answer = self.ask(question, '0', options, casesensitive=False)
5867 if (answer.isdigit() and answer != '0') or answer in ['shower', 'detector']:
5868 if answer.isdigit():
5869 key = switch_order[int(answer) - 1]
5870 else:
5871 key = answer
5872 for i, opt in enumerate(valid_options[key]):
5873 if opt == switch[key]:
5874 break
5875 i +=1
5876 if i == len(valid_options[key]):
5877 i=0
5878 answer = '%s=%s' % (key, valid_options[key][i])
5879
5880 if '=' in answer:
5881 key, status = answer.split('=')
5882 key, status = key.lower().strip(), status.upper().strip()
5883
5884 if key not in switch:
5885
5886 logger.warning("Using old syntax. Please check that we run what you expect.")
5887 if key == "pythia" and status == "ON":
5888 key, status = "shower", "PYTHIA6"
5889 elif key == "pythia" and status == "OFF":
5890 key, status = "shower", "OFF"
5891 elif key == "pgs" and status == "ON":
5892 if switch["detector"] in ["OFF", "PGS"] :
5893 key, status = "detector", "PGS"
5894 else:
5895 key, status = "detector", "DELPHES+PGS"
5896 elif key == "delphes" and status == "ON":
5897 if switch["detector"] in ["OFF", "DELPHES"] :
5898 key, status = "detector", "DELPHES"
5899 else:
5900 key, status = "detector", "DELPHES+PGS"
5901 elif key == "pgs" and status == "OFF":
5902 if switch["detector"] in ["OFF", "PGS"] :
5903 key, status = "detector", "OFF"
5904 elif switch["detector"] == "DELPHES+PGS":
5905 key, status = "detector", "DELPHES"
5906 else:
5907 key, status = "detector", switch['detector']
5908 elif key == "delphes" and status == "OFF":
5909 if switch["detector"] in ["OFF", "DELPHES"] :
5910 key, status = "detector", "OFF"
5911 elif switch["detector"] == "DELPHES+PGS":
5912 key, status = "detector", "PGS"
5913 else:
5914 key, status = "detector", switch['detector']
5915
5916
5917 switch[key] = status
5918 if (key, status) in force_switch:
5919 for key2, status2 in force_switch[(key, status)].items():
5920 if isinstance(status2, str):
5921 if switch[key2] not in [status2, void]:
5922 logger.info('For coherence \'%s\' is set to \'%s\''
5923 % (key2, status2), '$MG:color:BLACK')
5924 switch[key2] = status2
5925 else:
5926 if switch[key2] not in status2 + [void]:
5927 logger.info('For coherence \'%s\' is set to \'%s\''
5928 % (key2, status2[0]), '$MG:color:BLACK')
5929 switch[key2] = status2[0]
5930 elif answer in ['0', 'auto', 'done']:
5931 continue
5932 elif answer in ['parton', 'pythia','pgs','madspin','reweight', 'delphes']:
5933 logger.info('pass in %s only mode' % answer, '$MG:color:BLACK')
5934 switch_assign('madspin', 'OFF')
5935 switch_assign('reweight', 'OFF')
5936 if answer == 'parton':
5937 switch_assign('shower', 'OFF')
5938 switch_assign('detector', 'OFF')
5939 elif answer == 'pythia':
5940 switch_assign('shower', 'PYTHIA6')
5941 switch_assign('detector', 'OFF')
5942 elif answer == 'pgs':
5943 switch_assign('shower', 'PYTHIA6')
5944 switch_assign('detector', 'PGS')
5945 elif answer == 'delphes':
5946 switch_assign('shower', 'PYTHIA6')
5947 if switch['shower'] == 'OFF':
5948 switch_assign('shower', 'PYTHIA8')
5949 switch_assign('detector', 'DELPHES')
5950 elif answer == 'madspin':
5951 switch_assign('madspin', 'ON')
5952 switch_assign('shower', 'OFF')
5953 switch_assign('detector', 'OFF')
5954 elif answer == 'reweight':
5955 switch_assign('reweight', 'ON')
5956 switch_assign('shower', 'OFF')
5957 switch_assign('detector', 'OFF')
5958
5959 if mode:
5960 answer = '0'
5961 else:
5962 answer = 'auto'
5963
5964
5965
5966
5967 cards = ['param_card.dat', 'run_card.dat']
5968 if switch['shower'] in ['PY6', 'PYTHIA6']:
5969 cards.append('pythia_card.dat')
5970 if switch['shower'] in ['PY8', 'PYTHIA8']:
5971 cards.append('pythia8_card.dat')
5972 if switch['detector'] in ['PGS','DELPHES+PGS']:
5973 cards.append('pgs_card.dat')
5974 if switch['detector'] in ['DELPHES', 'DELPHES+PGS']:
5975 cards.append('delphes_card.dat')
5976 delphes3 = True
5977 if os.path.exists(pjoin(self.options['delphes_path'], 'data')):
5978 delphes3 = False
5979 cards.append('delphes_trigger.dat')
5980 if switch['madspin'] == 'ON':
5981 cards.append('madspin_card.dat')
5982 if switch['reweight'] == 'ON':
5983 cards.append('reweight_card.dat')
5984 if switch['analysis'] in ['MADANALYSIS_5']:
5985 cards.append('madanalysis5_parton_card.dat')
5986 if switch['analysis'] in ['MADANALYSIS_5'] and not switch['shower']=='OFF':
5987 cards.append('madanalysis5_hadron_card.dat')
5988 if switch['analysis'] in ['MADANALYSIS_4']:
5989 cards.append('plot_card.dat')
5990
5991 self.keep_cards(cards)
5992
5993 if os.path.isfile(pjoin(self.me_dir,'Cards','MadLoopParams.dat')):
5994 cards.append('MadLoopParams.dat')
5995
5996 if self.force:
5997 self.check_param_card(pjoin(self.me_dir,'Cards','param_card.dat' ))
5998 return switch
5999
6000 if answer == 'auto':
6001 self.ask_edit_cards(cards, plot=False, mode='auto')
6002 else:
6003 self.ask_edit_cards(cards, plot=False)
6004 return switch
6005
6006
6008 """Ask the question when launching pythia"""
6009
6010 pythia_suffix = '' if pythia_version==6 else '%d'%pythia_version
6011
6012 available_mode = ['0', '1']
6013 if pythia_version==6:
6014 available_mode.append('2')
6015 if self.options['delphes_path']:
6016 available_mode.append('3')
6017 name = {'0': 'auto', '2':'pgs', '3':'delphes'}
6018 name['1'] = 'pythia%s'%pythia_suffix
6019 options = available_mode + [name[val] for val in available_mode]
6020 question = """Which programs do you want to run?
6021 0 / auto : running existing cards\n"""
6022 if pythia_version==6:
6023 question += """ 1. pythia : Pythia\n"""
6024 question += """ 2. pgs : Pythia + PGS\n"""
6025 else:
6026 question += """ 1. pythia8 : Pythia8\n"""
6027
6028 if '3' in available_mode:
6029 question += """ 3. delphes : Pythia%s + Delphes.\n"""%pythia_suffix
6030
6031 if not self.force:
6032 if not mode:
6033 mode = self.ask(question, '0', options)
6034 elif not mode:
6035 mode = 'auto'
6036
6037 if mode.isdigit():
6038 mode = name[mode]
6039
6040 auto = False
6041 if mode == 'auto':
6042 auto = True
6043 if pythia_version==6 and os.path.exists(pjoin(self.me_dir,
6044 'Cards', 'pgs_card.dat')):
6045 mode = 'pgs'
6046 elif os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
6047 mode = 'delphes'
6048 else:
6049 mode = 'pythia%s'%pythia_suffix
6050 logger.info('Will run in mode %s' % mode)
6051
6052
6053 cards = ['pythia%s_card.dat'%pythia_suffix]
6054 if mode == 'pgs' and pythia_version==6:
6055 cards.append('pgs_card.dat')
6056 if mode == 'delphes':
6057 cards.append('delphes_card.dat')
6058 delphes3 = True
6059 if os.path.exists(pjoin(self.options['delphes_path'], 'data')):
6060 delphes3 = False
6061 cards.append('delphes_trigger.dat')
6062 self.keep_cards(cards, ignore=['madanalysis5_parton_card.dat','madanalysis5_hadron_card.dat',
6063 'plot_card.dat'])
6064
6065 if self.force:
6066 return mode
6067
6068 if auto:
6069 self.ask_edit_cards(cards, mode='auto', plot=(pythia_version==6))
6070 else:
6071 self.ask_edit_cards(cards, plot=(pythia_version==6))
6072
6073 return mode
6074
6079 """The command line processor of MadGraph"""
6080
6087
6088 name_to_pdg = {}
6089
6090 @classmethod
6093
6094 @staticmethod
6096 """return the list of Subprocesses"""
6097
6098 out = []
6099 for line in open(pjoin(me_dir,'SubProcesses', 'subproc.mg')):
6100 if not line:
6101 continue
6102 name = line.strip()
6103 if os.path.exists(pjoin(me_dir, 'SubProcesses', name)):
6104 out.append(pjoin(me_dir, 'SubProcesses', name))
6105
6106 return out
6107
6108
6109
6110 @staticmethod
6112 """ return the list of processes with their name"""
6113
6114 nb_sub = 0
6115 names = {}
6116 old_main = ''
6117
6118 if not os.path.exists(os.path.join(path,'processes.dat')):
6119 return SubProcesses.get_subP_info_v4(path)
6120
6121 for line in open(os.path.join(path,'processes.dat')):
6122 main = line[:8].strip()
6123 if main == 'mirror':
6124 main = old_main
6125 if line[8:].strip() == 'none':
6126 continue
6127 else:
6128 main = int(main)
6129 old_main = main
6130
6131 sub_proccess = line[8:]
6132 nb_sub += sub_proccess.count(',') + 1
6133 if main in names:
6134 names[main] += [sub_proccess.split(',')]
6135 else:
6136 names[main]= [sub_proccess.split(',')]
6137
6138 return names
6139
6140 @staticmethod
6142 """ return the list of processes with their name in case without grouping """
6143
6144 nb_sub = 0
6145 names = {'':[[]]}
6146 path = os.path.join(path, 'auto_dsig.f')
6147 found = 0
6148 for line in open(path):
6149 if line.startswith('C Process:'):
6150 found += 1
6151 names[''][0].append(line[15:])
6152 elif found >1:
6153 break
6154 return names
6155
6156
6157 @staticmethod
6159 """return the pdg codes of the particles present in the Subprocesses"""
6160
6161 all_ids = []
6162 for line in open(pjoin(path, 'leshouche.inc')):
6163 if not 'IDUP' in line:
6164 continue
6165 particles = re.search("/([\d,-]+)/", line)
6166 all_ids.append([int(p) for p in particles.group(1).split(',')])
6167 return all_ids
6168
6172 """The command for the gridpack --Those are not suppose to be use interactively--"""
6173
6174 - def __init__(self, me_dir = None, nb_event=0, seed=0, *completekey, **stdin):
6175 """Initialize the command and directly run"""
6176
6177
6178
6179 MadEventCmd.__init__(self, me_dir, *completekey, **stdin)
6180 self.run_mode = 0
6181 self.random = seed
6182 self.random_orig = self.random
6183 self.options['automatic_html_opening'] = False
6184
6185 if me_dir and nb_event and seed:
6186 self.launch(nb_event, seed)
6187 else:
6188 raise MadGraph5Error,\
6189 'Gridpack run failed: ' + str(me_dir) + str(nb_event) + \
6190 str(seed)
6191
6192 - def launch(self, nb_event, seed):
6215
6217 """Special refine for gridpack run."""
6218 self.nb_refine += 1
6219
6220 precision = nb_event
6221
6222
6223
6224 self.cluster_mode = 0
6225
6226
6227 self.save_random()
6228
6229 self.update_status('Refine results to %s' % precision, level=None)
6230 logger.info("Using random number seed offset = %s" % self.random)
6231
6232 self.total_jobs = 0
6233 subproc = [P for P in os.listdir(pjoin(self.me_dir,'SubProcesses')) if
6234 P.startswith('P') and os.path.isdir(pjoin(self.me_dir,'SubProcesses', P))]
6235 devnull = open(os.devnull, 'w')
6236 for nb_proc,subdir in enumerate(subproc):
6237 subdir = subdir.strip()
6238 Pdir = pjoin(self.me_dir, 'SubProcesses',subdir)
6239 bindir = pjoin(os.path.relpath(self.dirbin, Pdir))
6240
6241 logger.info(' %s ' % subdir)
6242
6243 for match in misc.glob('*ajob*', Pdir):
6244 if os.path.basename(match)[:4] in ['ajob', 'wait', 'run.', 'done']:
6245 os.remove(pjoin(Pdir, match))
6246
6247
6248 logfile = pjoin(Pdir, 'gen_ximprove.log')
6249 misc.call([pjoin(bindir, 'gen_ximprove')],
6250 stdin=subprocess.PIPE,
6251 stdout=open(logfile,'w'),
6252 cwd=Pdir)
6253
6254 if os.path.exists(pjoin(Pdir, 'ajob1')):
6255 alljobs = misc.glob('ajob*', Pdir)
6256 nb_tot = len(alljobs)
6257 self.total_jobs += nb_tot
6258 for i, job in enumerate(alljobs):
6259 job = os.path.basename(job)
6260 self.launch_job('%s' % job, cwd=Pdir, remaining=(nb_tot-i-1),
6261 run_type='Refine number %s on %s (%s/%s)' %
6262 (self.nb_refine, subdir, nb_proc+1, len(subproc)))
6263 if os.path.exists(pjoin(self.me_dir,'error')):
6264 self.monitor(html=True)
6265 raise MadEventError, \
6266 'Error detected in dir %s: %s' % \
6267 (Pdir, open(pjoin(self.me_dir,'error')).read())
6268 self.monitor(run_type='All job submitted for refine number %s' %
6269 self.nb_refine)
6270
6271 self.update_status("Combining runs", level='parton')
6272 try:
6273 os.remove(pjoin(Pdir, 'combine_runs.log'))
6274 except Exception:
6275 pass
6276
6277 bindir = pjoin(os.path.relpath(self.dirbin, pjoin(self.me_dir,'SubProcesses')))
6278 combine_runs.CombineRuns(self.me_dir)
6279
6280
6281 cross, error = sum_html.make_all_html_results(self)
6282 self.results.add_detail('cross', cross)
6283 self.results.add_detail('error', error)
6284
6285
6286 self.update_status('finish refine', 'parton', makehtml=False)
6287 devnull.close()
6288
6291 """ A container class for the various methods for initializing MadLoop. It is
6292 placed in MadEventInterface because it is used by Madevent for loop-induced
6293 simulations. """
6294
6295 @staticmethod
6297 """ Compile the check program in the directory dir_name.
6298 Return the compilation and running time. """
6299
6300
6301
6302 if os.path.isfile(pjoin(dir_name,'check')):
6303 os.remove(pjoin(dir_name,'check'))
6304 os.remove(pjoin(dir_name,'check_sa.o'))
6305 os.remove(pjoin(dir_name,'loop_matrix.o'))
6306
6307 devnull = open(os.devnull, 'w')
6308 start=time.time()
6309 retcode = misc.compile(arg=['-j1','check'], cwd=dir_name, nb_core=1)
6310 compilation_time = time.time()-start
6311 if retcode != 0:
6312 logging.info("Error while executing make in %s" % dir_name)
6313 return None, None, None
6314
6315 if not checkRam:
6316 start=time.time()
6317 retcode = subprocess.call('./check',
6318 cwd=dir_name, stdout=devnull, stderr=devnull)
6319
6320 run_time = time.time()-start
6321 ram_usage = None
6322 else:
6323 ptimer = misc.ProcessTimer(['./check'], cwd=dir_name, shell=False, \
6324 stdout=devnull, stderr=devnull, close_fds=True)
6325 try:
6326 ptimer.execute()
6327
6328
6329
6330 while ptimer.poll():
6331 time.sleep(.2)
6332 finally:
6333
6334 ptimer.close()
6335
6336 ram_usage = ptimer.max_rss_memory
6337
6338
6339 run_time = (ptimer.t1 - ptimer.t0)
6340 retcode = ptimer.p.returncode
6341
6342 devnull.close()
6343
6344 if retcode != 0:
6345 logging.warning("Error while executing ./check in %s" % dir_name)
6346 return None, None, None
6347
6348 return compilation_time, run_time, ram_usage
6349
6350 @staticmethod
6351 - def fix_PSPoint_in_check(dir_path, read_ps = True, npoints = 1,
6352 hel_config = -1, mu_r=0.0, split_orders=-1):
6353 """Set check_sa.f to be reading PS.input assuming a working dir dir_name.
6354 if hel_config is different than -1 then check_sa.f is configured so to
6355 evaluate only the specified helicity.
6356 If mu_r > 0.0, then the renormalization constant value will be hardcoded
6357 directly in check_sa.f, if is is 0 it will be set to Sqrt(s) and if it
6358 is < 0.0 the value in the param_card.dat is used.
6359 If the split_orders target (i.e. the target squared coupling orders for
6360 the computation) is != -1, it will be changed in check_sa.f via the
6361 subroutine CALL SET_COUPLINGORDERS_TARGET(split_orders)."""
6362
6363 file_path = dir_path
6364 if not os.path.isfile(dir_path) or \
6365 not os.path.basename(dir_path)=='check_sa.f':
6366 file_path = pjoin(dir_path,'check_sa.f')
6367 if not os.path.isfile(file_path):
6368 directories = [d for d in misc.glob('P*_*', dir_path) \
6369 if (re.search(r'.*P\d+_\w*$', d) and os.path.isdir(d))]
6370 if len(directories)>0:
6371 file_path = pjoin(directories[0],'check_sa.f')
6372 if not os.path.isfile(file_path):
6373 raise MadGraph5Error('Could not find the location of check_sa.f'+\
6374 ' from the specified path %s.'%str(file_path))
6375
6376 file = open(file_path, 'r')
6377 check_sa = file.read()
6378 file.close()
6379
6380 file = open(file_path, 'w')
6381 check_sa = re.sub(r"READPS = \S+\)","READPS = %s)"%('.TRUE.' if read_ps \
6382 else '.FALSE.'), check_sa)
6383 check_sa = re.sub(r"NPSPOINTS = \d+","NPSPOINTS = %d"%npoints, check_sa)
6384 if hel_config != -1:
6385 check_sa = re.sub(r"SLOOPMATRIX\S+\(\S+,MATELEM,",
6386 "SLOOPMATRIXHEL_THRES(P,%d,MATELEM,"%hel_config, check_sa)
6387 else:
6388 check_sa = re.sub(r"SLOOPMATRIX\S+\(\S+,MATELEM,",
6389 "SLOOPMATRIX_THRES(P,MATELEM,",check_sa)
6390 if mu_r > 0.0:
6391 check_sa = re.sub(r"MU_R=SQRTS","MU_R=%s"%\
6392 (("%.17e"%mu_r).replace('e','d')),check_sa)
6393 elif mu_r < 0.0:
6394 check_sa = re.sub(r"MU_R=SQRTS","",check_sa)
6395
6396 if split_orders > 0:
6397 check_sa = re.sub(r"SET_COUPLINGORDERS_TARGET\(-?\d+\)",
6398 "SET_COUPLINGORDERS_TARGET(%d)"%split_orders,check_sa)
6399
6400 file.write(check_sa)
6401 file.close()
6402
6403 @staticmethod
6404 - def run_initialization(run_dir=None, SubProc_dir=None, infos=None,\
6405 req_files = ['HelFilter.dat','LoopFilter.dat'],
6406 attempts = [4,15]):
6407 """ Run the initialization of the process in 'run_dir' with success
6408 characterized by the creation of the files req_files in this directory.
6409 The directory containing the driving source code 'check_sa.f'.
6410 The list attempt gives the successive number of PS points the
6411 initialization should be tried with before calling it failed.
6412 Returns the number of PS points which were necessary for the init.
6413 Notice at least run_dir or SubProc_dir must be provided.
6414 A negative attempt number given in input means that quadprec will be
6415 forced for initialization."""
6416
6417
6418
6419 if infos is None:
6420 infos={}
6421
6422 if SubProc_dir is None and run_dir is None:
6423 raise MadGraph5Error, 'At least one of [SubProc_dir,run_dir] must'+\
6424 ' be provided in run_initialization.'
6425
6426
6427
6428 if SubProc_dir is None:
6429 SubProc_dir = os.path.abspath(pjoin(run_dir,os.pardir))
6430
6431 if run_dir is None:
6432 directories =[ dir for dir in misc.glob('P[0-9]*', SubProc_dir)
6433 if os.path.isdir(dir) ]
6434 if directories:
6435 run_dir = directories[0]
6436 else:
6437 raise MadGraph5Error, 'Could not find a valid running directory'+\
6438 ' in %s.'%str(SubProc_dir)
6439
6440
6441
6442
6443
6444 if not os.path.isfile(pjoin(run_dir,'born_matrix.f')):
6445 if len(attempts)>=1 and attempts[0]<8:
6446 attempts[0]=8
6447 if len(attempts)>=2 and attempts[1]<25:
6448 attempts[1]=25
6449
6450 to_attempt = list(attempts)
6451 to_attempt.reverse()
6452 my_req_files = list(req_files)
6453
6454 MLCardPath = pjoin(SubProc_dir,'MadLoopParams.dat')
6455 if not os.path.isfile(MLCardPath):
6456 raise MadGraph5Error, 'Could not find MadLoopParams.dat at %s.'\
6457 %MLCardPath
6458 else:
6459 MLCard = banner_mod.MadLoopParam(MLCardPath)
6460 MLCard_orig = banner_mod.MadLoopParam(MLCard)
6461
6462
6463 if not MLCard['UseLoopFilter']:
6464 try:
6465 my_req_files.remove('LoopFilter.dat')
6466 except ValueError:
6467 pass
6468
6469 if MLCard['HelicityFilterLevel']==0:
6470 try:
6471 my_req_files.remove('HelFilter.dat')
6472 except ValueError:
6473 pass
6474
6475 def need_init():
6476 """ True if init not done yet."""
6477 proc_prefix_file = open(pjoin(run_dir,'proc_prefix.txt'),'r')
6478 proc_prefix = proc_prefix_file.read()
6479 proc_prefix_file.close()
6480 return any([not os.path.exists(pjoin(run_dir,'MadLoop5_resources',
6481 proc_prefix+fname)) for fname in my_req_files]) or \
6482 not os.path.isfile(pjoin(run_dir,'check')) or \
6483 not os.access(pjoin(run_dir,'check'), os.X_OK)
6484
6485
6486
6487 is_loop_induced = os.path.exists(pjoin(run_dir,'born_matrix.f'))
6488
6489
6490
6491
6492 if not any(attempt<0 for attempt in to_attempt):
6493 to_attempt = [-attempt for attempt in to_attempt] + to_attempt
6494 use_quad_prec = 1
6495 curr_attempt = 1
6496
6497 MLCard.set('WriteOutFilters',True)
6498
6499 while to_attempt!=[] and need_init():
6500 curr_attempt = to_attempt.pop()
6501
6502
6503 if curr_attempt < 0:
6504 use_quad_prec = -1
6505
6506 MLCard.set('CTModeInit',4)
6507 MLCard.set('ZeroThres',1e-11)
6508 else:
6509
6510 MLCard.set('CTModeInit',1)
6511 MLCard.set('ZeroThres',1e-9)
6512
6513 curr_attempt = abs(curr_attempt+1)
6514 MLCard.set('MaxAttempts',curr_attempt)
6515 MLCard.write(pjoin(SubProc_dir,'MadLoopParams.dat'))
6516
6517
6518 MadLoopInitializer.fix_PSPoint_in_check(run_dir, read_ps = False,
6519 npoints = curr_attempt)
6520 compile_time, run_time, ram_usage = \
6521 MadLoopInitializer.make_and_run(run_dir)
6522 if compile_time==None:
6523 logging.error("Failed at running the process in %s."%run_dir)
6524 attempts = None
6525 return None
6526
6527 if 'Process_compilation' not in infos.keys() or \
6528 infos['Process_compilation']==None:
6529 infos['Process_compilation'] = compile_time
6530 infos['Initialization'] = run_time
6531
6532 MLCard_orig.write(pjoin(SubProc_dir,'MadLoopParams.dat'))
6533 if need_init():
6534 return None
6535 else:
6536 return use_quad_prec*(curr_attempt-1)
6537
6538 @staticmethod
6540 """Checks whether the necessary filters are present or not."""
6541
6542 def need_init(ML_resources_path, proc_prefix, r_files):
6543 """ Returns true if not all required files are present. """
6544 return any([not os.path.exists(pjoin(ML_resources_path,
6545 proc_prefix+fname)) for fname in r_files])
6546
6547 MLCardPath = pjoin(proc_dir,'SubProcesses','MadLoopParams.dat')
6548 if not os.path.isfile(MLCardPath):
6549 raise MadGraph5Error, 'Could not find MadLoopParams.dat at %s.'\
6550 %MLCardPath
6551 MLCard = banner_mod.MadLoopParam(MLCardPath)
6552
6553 req_files = ['HelFilter.dat','LoopFilter.dat']
6554
6555 if not MLCard['UseLoopFilter']:
6556 try:
6557 req_files.remove('LoopFilter.dat')
6558 except ValueError:
6559 pass
6560 if MLCard['HelicityFilterLevel']==0:
6561 try:
6562 req_files.remove('HelFilter.dat')
6563 except ValueError:
6564 pass
6565
6566 for v_folder in glob.iglob(pjoin(proc_dir,'SubProcesses',
6567 '%s*'%subproc_prefix)):
6568
6569 if not os.path.isdir(v_folder) or not os.path.isfile(\
6570 pjoin(v_folder,'loop_matrix.f')):
6571 continue
6572 proc_prefix_file = open(pjoin(v_folder,'proc_prefix.txt'),'r')
6573 proc_prefix = proc_prefix_file.read()
6574 proc_prefix_file.close()
6575 if need_init(pjoin(proc_dir,'SubProcesses','MadLoop5_resources'),
6576 proc_prefix, req_files):
6577 return True
6578
6579 return False
6580
6581 @staticmethod
6582 - def init_MadLoop(proc_dir, n_PS=None, subproc_prefix='PV', MG_options=None,
6583 interface = None):
6584 """Advanced commands: Compiles and run MadLoop on RAMBO random PS points to initilize the
6585 filters."""
6586
6587 logger.debug('Compiling Source materials necessary for MadLoop '+
6588 'initialization.')
6589
6590
6591
6592 if interface is None:
6593 misc.compile(arg=['treatCardsLoopNoInit'], cwd=pjoin(proc_dir,'Source'))
6594 else:
6595 interface.do_treatcards('all --no_MadLoopInit')
6596
6597
6598 if os.path.exists(pjoin(proc_dir,'Source','CutTools')):
6599 misc.compile(arg=['libcuttools'],cwd=pjoin(proc_dir,'Source'))
6600 if os.path.exists(pjoin(proc_dir,'Source','IREGI')):
6601 misc.compile(arg=['libiregi'],cwd=pjoin(proc_dir,'Source'))
6602
6603 misc.compile(arg=['libmodel'],cwd=pjoin(proc_dir,'Source'))
6604 misc.compile(arg=['libdhelas'],cwd=pjoin(proc_dir,'Source'))
6605
6606
6607 logger.info('Initializing MadLoop loop-induced matrix elements '+\
6608 '(this can take some time)...')
6609
6610
6611 if MG_options:
6612 mcore = cluster.MultiCore(**MG_options)
6613 else:
6614 mcore = cluster.onecore
6615 def run_initialization_wrapper(run_dir, infos, attempts):
6616 if attempts is None:
6617 n_PS = MadLoopInitializer.run_initialization(
6618 run_dir=run_dir, infos=infos)
6619 else:
6620 n_PS = MadLoopInitializer.run_initialization(
6621 run_dir=run_dir, infos=infos, attempts=attempts)
6622 infos['nPS'] = n_PS
6623 return 0
6624
6625 def wait_monitoring(Idle, Running, Done):
6626 if Idle+Running+Done == 0:
6627 return
6628 logger.debug('MadLoop initialization jobs: %d Idle, %d Running, %d Done'\
6629 %(Idle, Running, Done))
6630
6631 init_info = {}
6632
6633 VirtualFolders = [f for f in glob.iglob(pjoin(proc_dir,'SubProcesses',
6634 '%s*'%subproc_prefix)) if (os.path.isdir(f) or
6635 os.path.isfile(pjoin(f,'loop_matrix.f')))]
6636 logger.debug("Now Initializing MadLoop matrix element in %d folder%s:"%\
6637 (len(VirtualFolders),'s' if len(VirtualFolders)>1 else ''))
6638 logger.debug(', '.join("'%s'"%os.path.basename(v_folder) for v_folder in
6639 VirtualFolders))
6640 for v_folder in VirtualFolders:
6641 init_info[v_folder] = {}
6642
6643
6644
6645 max_mult = 3
6646 if n_PS is None:
6647
6648 mcore.submit(run_initialization_wrapper,
6649 [pjoin(v_folder), init_info[v_folder], None])
6650 else:
6651
6652 mcore.submit(run_initialization_wrapper, [pjoin(v_folder),
6653 init_info[v_folder],
6654 [n_PS*multiplier for multiplier in range(1,max_mult+1)]])
6655
6656
6657 mcore.wait('',wait_monitoring,update_first=wait_monitoring)
6658 for v_folder in VirtualFolders:
6659 init = init_info[v_folder]
6660 if init['nPS'] is None:
6661 raise MadGraph5Error, 'Failed the initialization of'+\
6662 " loop-induced matrix element '%s'%s."%\
6663 (os.path.basename(v_folder),' (using default n_PS points)' if\
6664 n_PS is None else ' (trying with a maximum of %d PS points)'\
6665 %(max_mult*n_PS))
6666 if init['nPS']==0:
6667 logger.debug("Nothing to be done in '%s', all filters already "%\
6668 os.path.basename(v_folder)+\
6669 "present (use the '-r' option to force their recomputation)")
6670 else:
6671 logger.debug("'%s' finished using "%os.path.basename(v_folder)+
6672 '%d PS points (%s), in %.3g(compil.) + %.3g(init.) secs.'%(
6673 abs(init['nPS']),'DP' if init['nPS']>0 else 'QP',
6674 init['Process_compilation'],init['Initialization']))
6675
6676 logger.info('MadLoop initialization finished.')
6677
6678 AskforEditCard = common_run.AskforEditCard
6679
6680
6681 if '__main__' == __name__:
6682
6683
6684 import sys
6685 if not sys.version_info[0] == 2 or sys.version_info[1] < 6:
6686 sys.exit('MadGraph/MadEvent 5 works only with python 2.6 or later (but not python 3.X).\n'+\
6687 'Please upgrate your version of python.')
6688
6689 import os
6690 import optparse
6691
6692
6693 root_path = os.path.dirname(os.path.dirname(os.path.realpath( __file__ )))
6694 sys.path.insert(0, root_path)
6698 - def error(self, msg=''):
6700
6701 usage = "usage: %prog [options] [FILE] "
6702 parser = MyOptParser(usage=usage)
6703 parser.add_option("-l", "--logging", default='INFO',
6704 help="logging level (DEBUG|INFO|WARNING|ERROR|CRITICAL) [%default]")
6705 parser.add_option("","--web", action="store_true", default=False, dest='web', \
6706 help='force toce to be in secure mode')
6707 parser.add_option("","--debug", action="store_true", default=False, dest='debug', \
6708 help='force to launch debug mode')
6709 parser_error = ''
6710 done = False
6711
6712 for i in range(len(sys.argv)-1):
6713 try:
6714 (options, args) = parser.parse_args(sys.argv[1:len(sys.argv)-i])
6715 done = True
6716 except MyOptParser.InvalidOption, error:
6717 pass
6718 else:
6719 args += sys.argv[len(sys.argv)-i:]
6720 if not done:
6721
6722 try:
6723 (options, args) = parser.parse_args()
6724 except MyOptParser.InvalidOption, error:
6725 print error
6726 sys.exit(2)
6727
6728 if len(args) == 0:
6729 args = ''
6730
6731 import subprocess
6732 import logging
6733 import logging.config
6734
6735
6736 import internal.coloring_logging
6737 try:
6738 if __debug__ and options.logging == 'INFO':
6739 options.logging = 'DEBUG'
6740 if options.logging.isdigit():
6741 level = int(options.logging)
6742 else:
6743 level = eval('logging.' + options.logging)
6744 print os.path.join(root_path, 'internal', 'me5_logging.conf')
6745 logging.config.fileConfig(os.path.join(root_path, 'internal', 'me5_logging.conf'))
6746 logging.root.setLevel(level)
6747 logging.getLogger('madgraph').setLevel(level)
6748 except:
6749 raise
6750 pass
6751
6752
6753 try:
6754 if args:
6755
6756 if '--web' in args:
6757 i = args.index('--web')
6758 args.pop(i)
6759 cmd_line = MadEventCmd(force_run=True)
6760 else:
6761 cmd_line = MadEventCmdShell(force_run=True)
6762 if not hasattr(cmd_line, 'do_%s' % args[0]):
6763 if parser_error:
6764 print parser_error
6765 print 'and %s can not be interpreted as a valid command.' % args[0]
6766 else:
6767 print 'ERROR: %s not a valid command. Please retry' % args[0]
6768 else:
6769 cmd_line.use_rawinput = False
6770 cmd_line.run_cmd(' '.join(args))
6771 cmd_line.run_cmd('quit')
6772
6773 except KeyboardInterrupt:
6774 print 'quit on KeyboardInterrupt'
6775 pass
6776