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 atexit
21 import cmath
22 import glob
23 import logging
24 import math
25 import optparse
26 import os
27 import pydoc
28 import random
29 import re
30 import signal
31 import shutil
32 import stat
33 import subprocess
34 import sys
35 import traceback
36 import time
37 import tarfile
38
39 try:
40 import readline
41 GNU_SPLITTING = ('GNU' in readline.__doc__)
42 except:
43 GNU_SPLITTING = True
44
45 root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
46 root_path = os.path.split(root_path)[0]
47 sys.path.insert(0, os.path.join(root_path,'bin'))
48
49
50 pjoin = os.path.join
51
52 logger = logging.getLogger('madevent.stdout')
53 logger_stderr = logging.getLogger('madevent.stderr')
54
55 try:
56 import madgraph
57
58
59 except ImportError:
60
61 MADEVENT = True
62 import internal.extended_cmd as cmd
63 import internal.common_run_interface as common_run
64 import internal.banner as banner_mod
65 import internal.misc as misc
66 from internal import InvalidCmd, MadGraph5Error, ReadWrite
67 import internal.files as files
68 import internal.gen_crossxhtml as gen_crossxhtml
69 import internal.gen_ximprove as gen_ximprove
70 import internal.save_load_object as save_load_object
71 import internal.cluster as cluster
72 import internal.check_param_card as check_param_card
73 import internal.sum_html as sum_html
74 import internal.combine_runs as combine_runs
75 import internal.lhe_parser as lhe_parser
76 else:
77
78 MADEVENT = False
79 import madgraph.interface.extended_cmd as cmd
80 import madgraph.interface.common_run_interface as common_run
81 import madgraph.iolibs.files as files
82 import madgraph.iolibs.save_load_object as save_load_object
83 import madgraph.madevent.gen_crossxhtml as gen_crossxhtml
84 import madgraph.madevent.gen_ximprove as gen_ximprove
85 import madgraph.madevent.sum_html as sum_html
86 import madgraph.various.banner as banner_mod
87 import madgraph.various.cluster as cluster
88 import madgraph.various.misc as misc
89 import madgraph.madevent.combine_runs as combine_runs
90 import madgraph.various.lhe_parser as lhe_parser
91
92 import models.check_param_card as check_param_card
93 from madgraph import InvalidCmd, MadGraph5Error, MG5DIR, ReadWrite
100
103
105
106 MadEventAlreadyRunning = common_run.MadEventAlreadyRunning
107
108
109
110
111 -class CmdExtended(common_run.CommonRunCmd):
112 """Particularisation of the cmd command for MadEvent"""
113
114
115 next_possibility = {
116 'start': [],
117 }
118
119 debug_output = 'ME5_debug'
120 error_debug = 'Please report this bug on https://bugs.launchpad.net/mg5amcnlo\n'
121 error_debug += 'More information is found in \'%(debug)s\'.\n'
122 error_debug += 'Please attach this file to your report.'
123
124 config_debug = 'If you need help with this issue please contact us on https://answers.launchpad.net/mg5amcnlo\n'
125
126
127 keyboard_stop_msg = """stopping all operation
128 in order to quit MadGraph5_aMC@NLO please enter exit"""
129
130
131 InvalidCmd = InvalidCmd
132 ConfigurationError = MadGraph5Error
133
134 - def __init__(self, me_dir, options, *arg, **opt):
135 """Init history and line continuation"""
136
137
138 self.force = False
139
140
141
142 info = misc.get_pkg_info()
143 info_line = ""
144 if info and info.has_key('version') and info.has_key('date'):
145 len_version = len(info['version'])
146 len_date = len(info['date'])
147 if len_version + len_date < 30:
148 info_line = "#* VERSION %s %s %s *\n" % \
149 (info['version'],
150 (30 - len_version - len_date) * ' ',
151 info['date'])
152 else:
153 version = open(pjoin(root_path,'MGMEVersion.txt')).readline().strip()
154 info_line = "#* VERSION %s %s *\n" % \
155 (version, (24 - len(version)) * ' ')
156
157
158
159 self.history_header = \
160 '#************************************************************\n' + \
161 '#* MadGraph5_aMC@NLO/MadEvent *\n' + \
162 '#* *\n' + \
163 "#* * * *\n" + \
164 "#* * * * * *\n" + \
165 "#* * * * * 5 * * * * *\n" + \
166 "#* * * * * *\n" + \
167 "#* * * *\n" + \
168 "#* *\n" + \
169 "#* *\n" + \
170 info_line + \
171 "#* *\n" + \
172 "#* The MadGraph5_aMC@NLO Development Team - Find us at *\n" + \
173 "#* https://server06.fynu.ucl.ac.be/projects/madgraph *\n" + \
174 '#* *\n' + \
175 '#************************************************************\n' + \
176 '#* *\n' + \
177 '#* Command File for MadEvent *\n' + \
178 '#* *\n' + \
179 '#* run as ./bin/madevent.py filename *\n' + \
180 '#* *\n' + \
181 '#************************************************************\n'
182
183 if info_line:
184 info_line = info_line[1:]
185
186 logger.info(\
187 "************************************************************\n" + \
188 "* *\n" + \
189 "* W E L C O M E to *\n" + \
190 "* M A D G R A P H 5 _ a M C @ N L O *\n" + \
191 "* M A D E V E N T *\n" + \
192 "* *\n" + \
193 "* * * *\n" + \
194 "* * * * * *\n" + \
195 "* * * * * 5 * * * * *\n" + \
196 "* * * * * *\n" + \
197 "* * * *\n" + \
198 "* *\n" + \
199 info_line + \
200 "* *\n" + \
201 "* The MadGraph5_aMC@NLO Development Team - Find us at *\n" + \
202 "* https://server06.fynu.ucl.ac.be/projects/madgraph *\n" + \
203 "* *\n" + \
204 "* Type 'help' for in-line help. *\n" + \
205 "* *\n" + \
206 "************************************************************")
207 super(CmdExtended, self).__init__(me_dir, options, *arg, **opt)
208
210 """return the history header"""
211 return self.history_header % misc.get_time_info()
212
214 """action to perform to close nicely on a keyboard interupt"""
215 try:
216 if hasattr(self, 'cluster'):
217 logger.info('rm jobs on queue')
218 self.cluster.remove()
219 if hasattr(self, 'results'):
220 self.update_status('Stop by the user', level=None, makehtml=False, error=True)
221 self.add_error_log_in_html(KeyboardInterrupt)
222 except:
223 pass
224
225 - def postcmd(self, stop, line):
226 """ Update the status of the run for finishing interactive command """
227
228 stop = super(CmdExtended, self).postcmd(stop, line)
229
230 self.force = False
231
232 if not self.use_rawinput:
233 return stop
234
235 if self.results and not self.results.current:
236 return stop
237
238 arg = line.split()
239 if len(arg) == 0:
240 return stop
241 if isinstance(self.results.status, str) and self.results.status.startswith('Error'):
242 return stop
243 if isinstance(self.results.status, str) and self.results.status == 'Stop by the user':
244 self.update_status('%s Stop by the user' % arg[0], level=None, error=True)
245 return stop
246 elif not self.results.status:
247 return stop
248 elif str(arg[0]) in ['exit','quit','EOF']:
249 return stop
250
251 try:
252 self.update_status('Command \'%s\' done.<br> Waiting for instruction.' % arg[0],
253 level=None, error=True)
254 except Exception:
255 misc.sprint('update_status fails')
256 pass
257
258
264
278
279
281 """If a ME run is currently running add a link in the html output"""
282
283 if isinstance(error, ZeroResult):
284 self.add_error_log_in_html(error)
285 logger.warning('Zero result detected: %s' % error)
286
287 try:
288 if not self.banner:
289 self.banner = banner_mod.Banner()
290 if 'slha' not in self.banner:
291 self.banner.add(pjoin(self.me_dir,'Cards','param_card.dat'))
292 if 'mgruncard' not in self.banner:
293 self.banner.add(pjoin(self.me_dir,'Cards','run_card.dat'))
294 if 'mg5proccard' not in self.banner:
295 proc_card = pjoin(self.me_dir,'Cards','proc_card_mg5.dat')
296 if os.path.exists(proc_card):
297 self.banner.add(proc_card)
298
299 out_dir = pjoin(self.me_dir, 'Events', self.run_name)
300 if not os.path.isdir(out_dir):
301 os.mkdir(out_dir)
302 output_path = pjoin(out_dir, '%s_%s_banner.txt' % \
303 (self.run_name, self.run_tag))
304 self.banner.write(output_path)
305 except Exception:
306 if __debug__:
307 raise
308 else:
309 pass
310 else:
311 self.add_error_log_in_html()
312 cmd.Cmd.nice_error_handling(self, error, line)
313 try:
314 debug_file = open(self.debug_output, 'a')
315 debug_file.write(open(pjoin(self.me_dir,'Cards','proc_card_mg5.dat')))
316 debug_file.close()
317 except:
318 pass
319
325 """ The Series of help routine for the MadEventCmd"""
326
328 logger.info("syntax: banner_run Path|RUN [--run_options]")
329 logger.info("-- Reproduce a run following a given banner")
330 logger.info(" One of the following argument is require:")
331 logger.info(" Path should be the path of a valid banner.")
332 logger.info(" RUN should be the name of a run of the current directory")
333 self.run_options_help([('-f','answer all question by default'),
334 ('--name=X', 'Define the name associated with the new run')])
335
337 logger.info("syntax: open FILE ")
338 logger.info("-- open a file with the appropriate editor.")
339 logger.info(' If FILE belongs to index.html, param_card.dat, run_card.dat')
340 logger.info(' the path to the last created/used directory is used')
341 logger.info(' The program used to open those files can be chosen in the')
342 logger.info(' configuration file ./input/mg5_configuration.txt')
343
344
346 if data:
347 logger.info('-- local options:')
348 for name, info in data:
349 logger.info(' %s : %s' % (name, info))
350
351 logger.info("-- session options:")
352 logger.info(" Note that those options will be kept for the current session")
353 logger.info(" --cluster : Submit to the cluster. Current cluster: %s" % self.options['cluster_type'])
354 logger.info(" --multicore : Run in multi-core configuration")
355 logger.info(" --nb_core=X : limit the number of core to use to X.")
356
357
359 logger.info("syntax: generate_events [run_name] [options]",)
360 logger.info("-- Launch the full chain of script for the generation of events")
361 logger.info(" Including possible plotting, shower and detector resolution.")
362 logger.info(" Those steps are performed if the related program are installed")
363 logger.info(" and if the related card are present in the Cards directory.")
364 self.run_options_help([('-f', 'Use default for all questions.'),
365 ('--laststep=', 'argument might be parton/pythia/pgs/delphes and indicate the last level to be run.'),
366 ('-M', 'in order to add MadSpin'),
367 ('-R', 'in order to add the reweighting module')])
368
370 logger.info("syntax: initMadLoop [options]",'$MG:color:GREEN')
371 logger.info(
372 """-- Command only useful when MadEvent simulates loop-induced processes. This command compiles and run
373 the MadLoop output for the matrix element computation so as to initialize the filter for analytically
374 zero helicity configurations and loop topologies. If you suspect that a change you made in the model
375 parameters can have affected these filters, this command allows you to automatically refresh them. """)
376 logger.info(" The available options are:",'$MG:color:BLUE')
377 logger.info(" -f : Bypass the edition of MadLoopParams.dat.",'$MG:color:BLUE')
378 logger.info(" -r : Refresh of the existing filters (erasing them if already present).",'$MG:color:BLUE')
379 logger.info(" --nPS=<int> : Specify how many phase-space points should be tried to set up the filters.",'$MG:color:BLUE')
380
382 logger.info("syntax: add_time_of_flight [run_name|path_to_file] [--threshold=]")
383 logger.info('-- Add in the lhe files the information')
384 logger.info(' of how long it takes to a particle to decay.')
385 logger.info(' threshold option allows to change the minimal value required to')
386 logger.info(' a non zero value for the particle (default:1e-12s)')
387
389
390 if self.ninitial != 1:
391 logger.warning("This command is only valid for processes of type A > B C.")
392 logger.warning("This command can not be run in current context.")
393 logger.warning("")
394
395 logger.info("syntax: calculate_decay_widths [run_name] [options])")
396 logger.info("-- Calculate decay widths and enter widths and BRs in param_card")
397 logger.info(" for a series of processes of type A > B C ...")
398 self.run_options_help([('-f', 'Use default for all questions.'),
399 ('--accuracy=', 'accuracy (for each partial decay width).'\
400 + ' Default is 0.01.')])
401
403 logger.info("syntax: multi_run NB_RUN [run_name] [--run_options])")
404 logger.info("-- Launch the full chain of script for the generation of events")
405 logger.info(" NB_RUN times. This chains includes possible plotting, shower")
406 logger.info(" and detector resolution.")
407 self.run_options_help([('-f', 'Use default for all questions.'),
408 ('--laststep=', 'argument might be parton/pythia/pgs/delphes and indicate the last level to be run.')])
409
415
417 """exec generate_events for 2>N and calculate_width for 1>N"""
418 logger.info("syntax: launch [run_name] [options])")
419 logger.info(" --alias for either generate_events/calculate_decay_widths")
420 logger.info(" depending of the number of particles in the initial state.")
421
422 if self.ninitial == 1:
423 logger.info("For this directory this is equivalent to calculate_decay_widths")
424 self.help_calculate_decay_widths()
425 else:
426 logger.info("For this directory this is equivalent to $generate_events")
427 self.help_generate_events()
428
430 logger.info("syntax: refine require_precision [max_channel] [--run_options]")
431 logger.info("-- refine the LAST run to achieve a given precision.")
432 logger.info(" require_precision: can be either the targeted number of events")
433 logger.info(' or the required relative error')
434 logger.info(' max_channel:[5] maximal number of channel per job')
435 self.run_options_help([])
436
438 """ """
439 logger.info("syntax: combine_events [run_name] [--tag=tag_name] [--run_options]")
440 logger.info("-- Combine the last run in order to write the number of events")
441 logger.info(" asked in the run_card.")
442 self.run_options_help([])
443
450
457
463
465 logger.info("syntax: syscalc [RUN] [%s] [-f | --tag=]" % '|'.join(self._plot_mode))
466 logger.info("-- calculate systematics information for the RUN (current run by default)")
467 logger.info(" at different stages of the event generation for scale/pdf/...")
468
470 logger.info("syntax: remove RUN [all|parton|pythia|pgs|delphes|banner] [-f] [--tag=]")
471 logger.info("-- Remove all the files linked to previous run RUN")
472 logger.info(" if RUN is 'all', then all run will be cleaned.")
473 logger.info(" The optional argument precise which part should be cleaned.")
474 logger.info(" By default we clean all the related files but the banners.")
475 logger.info(" the optional '-f' allows to by-pass all security question")
476 logger.info(" The banner can be remove only if all files are removed first.")
477
484 """ The Series of check routine for the MadEventCmd"""
485
487 """check the validity of line"""
488
489 if len(args) == 0:
490 self.help_banner_run()
491 raise self.InvalidCmd('banner_run requires at least one argument.')
492
493 tag = [a[6:] for a in args if a.startswith('--tag=')]
494
495
496 if os.path.exists(args[0]):
497 type ='banner'
498 format = self.detect_card_type(args[0])
499 if format != 'banner':
500 raise self.InvalidCmd('The file is not a valid banner.')
501 elif tag:
502 args[0] = pjoin(self.me_dir,'Events', args[0], '%s_%s_banner.txt' % \
503 (args[0], tag))
504 if not os.path.exists(args[0]):
505 raise self.InvalidCmd('No banner associates to this name and tag.')
506 else:
507 name = args[0]
508 type = 'run'
509 banners = misc.glob('*_banner.txt', pjoin(self.me_dir,'Events', args[0]))
510 if not banners:
511 raise self.InvalidCmd('No banner associates to this name.')
512 elif len(banners) == 1:
513 args[0] = banners[0]
514 else:
515
516 tags = [os.path.basename(p)[len(args[0])+1:-11] for p in banners]
517 tag = self.ask('which tag do you want to use?', tags[0], tags)
518 args[0] = pjoin(self.me_dir,'Events', args[0], '%s_%s_banner.txt' % \
519 (args[0], tag))
520
521 run_name = [arg[7:] for arg in args if arg.startswith('--name=')]
522 if run_name:
523 try:
524 self.exec_cmd('remove %s all banner -f' % run_name)
525 except Exception:
526 pass
527 self.set_run_name(args[0], tag=None, level='parton', reload_card=True)
528 elif type == 'banner':
529 self.set_run_name(self.find_available_run_name(self.me_dir))
530 elif type == 'run':
531 if not self.results[name].is_empty():
532 run_name = self.find_available_run_name(self.me_dir)
533 logger.info('Run %s is not empty so will use run_name: %s' % \
534 (name, run_name))
535 self.set_run_name(run_name)
536 else:
537 try:
538 self.exec_cmd('remove %s all banner -f' % run_name)
539 except Exception:
540 pass
541 self.set_run_name(name)
542
543 - def check_history(self, args):
544 """check the validity of line"""
545
546 if len(args) > 1:
547 self.help_history()
548 raise self.InvalidCmd('\"history\" command takes at most one argument')
549
550 if not len(args):
551 return
552 elif args[0] != 'clean':
553 dirpath = os.path.dirname(args[0])
554 if dirpath and not os.path.exists(dirpath) or \
555 os.path.isdir(args[0]):
556 raise self.InvalidCmd("invalid path %s " % dirpath)
557
559 """ check the validity of the line"""
560
561 if len(args) == 0:
562 args.append('options')
563
564 if args[0] not in self._save_opts:
565 raise self.InvalidCmd('wrong \"save\" format')
566
567 if args[0] != 'options' and len(args) != 2:
568 self.help_save()
569 raise self.InvalidCmd('wrong \"save\" format')
570 elif args[0] != 'options' and len(args) == 2:
571 basename = os.path.dirname(args[1])
572 if not os.path.exists(basename):
573 raise self.InvalidCmd('%s is not a valid path, please retry' % \
574 args[1])
575
576 if args[0] == 'options':
577 has_path = None
578 for arg in args[1:]:
579 if arg in ['--auto', '--all']:
580 continue
581 elif arg.startswith('--'):
582 raise self.InvalidCmd('unknow command for \'save options\'')
583 else:
584 basename = os.path.dirname(arg)
585 if not os.path.exists(basename):
586 raise self.InvalidCmd('%s is not a valid path, please retry' % \
587 arg)
588 elif has_path:
589 raise self.InvalidCmd('only one path is allowed')
590 else:
591 args.remove(arg)
592 args.insert(1, arg)
593 has_path = True
594 if not has_path:
595 if '--auto' in arg and self.options['mg5_path']:
596 args.insert(1, pjoin(self.options['mg5_path'],'input','mg5_configuration.txt'))
597 else:
598 args.insert(1, pjoin(self.me_dir,'Cards','me5_configuration.txt'))
599
601 """ check the validity of the line"""
602
603 if len(args) < 2:
604 self.help_set()
605 raise self.InvalidCmd('set needs an option and an argument')
606
607 if args[0] not in self._set_options + self.options.keys():
608 self.help_set()
609 raise self.InvalidCmd('Possible options for set are %s' % \
610 self._set_options)
611
612 if args[0] in ['stdout_level']:
613 if args[1] not in ['DEBUG','INFO','WARNING','ERROR','CRITICAL'] \
614 and not args[1].isdigit():
615 raise self.InvalidCmd('output_level needs ' + \
616 'a valid level')
617
618 if args[0] in ['timeout']:
619 if not args[1].isdigit():
620 raise self.InvalidCmd('timeout values should be a integer')
621
623 """ check the validity of the line """
624
625 if len(args) != 1:
626 self.help_open()
627 raise self.InvalidCmd('OPEN command requires exactly one argument')
628
629 if args[0].startswith('./'):
630 if not os.path.isfile(args[0]):
631 raise self.InvalidCmd('%s: not such file' % args[0])
632 return True
633
634
635 if not self.me_dir:
636 if not os.path.isfile(args[0]):
637 self.help_open()
638 raise self.InvalidCmd('No MadEvent path defined. Unable to associate this name to a file')
639 else:
640 return True
641
642 path = self.me_dir
643 if os.path.isfile(os.path.join(path,args[0])):
644 args[0] = os.path.join(path,args[0])
645 elif os.path.isfile(os.path.join(path,'Cards',args[0])):
646 args[0] = os.path.join(path,'Cards',args[0])
647 elif os.path.isfile(os.path.join(path,'HTML',args[0])):
648 args[0] = os.path.join(path,'HTML',args[0])
649
650 elif '_card.dat' in args[0]:
651 name = args[0].replace('_card.dat','_card_default.dat')
652 if os.path.isfile(os.path.join(path,'Cards', name)):
653 files.cp(os.path.join(path,'Cards', name), os.path.join(path,'Cards', args[0]))
654 args[0] = os.path.join(path,'Cards', args[0])
655 else:
656 raise self.InvalidCmd('No default path for this file')
657 elif not os.path.isfile(args[0]):
658 raise self.InvalidCmd('No default path for this file')
659
661 """ check initMadLoop command arguments are valid."""
662
663 opt = {'refresh': False, 'nPS': None, 'force': False}
664
665 for arg in args:
666 if arg in ['-r','--refresh']:
667 opt['refresh'] = True
668 if arg in ['-f','--force']:
669 opt['force'] = True
670 elif arg.startswith('--nPS='):
671 n_attempts = arg.split('=')[1]
672 try:
673 opt['nPS'] = int(n_attempts)
674 except ValueError:
675 raise InvalidCmd("The number of attempts specified "+
676 "'%s' is not a valid integer."%n_attempts)
677
678 return opt
679
681 """check that treatcards arguments are valid
682 [param|run|all] [--output_dir=] [--param_card=] [--run_card=]
683 """
684
685 opt = {'output_dir':pjoin(self.me_dir,'Source'),
686 'param_card':pjoin(self.me_dir,'Cards','param_card.dat'),
687 'run_card':pjoin(self.me_dir,'Cards','run_card.dat'),
688 'forbid_MadLoopInit': False}
689 mode = 'all'
690 for arg in args:
691 if arg.startswith('--') and '=' in arg:
692 key,value =arg[2:].split('=',1)
693 if not key in opt:
694 self.help_treatcards()
695 raise self.InvalidCmd('Invalid option for treatcards command:%s ' \
696 % key)
697 if key in ['param_card', 'run_card']:
698 if os.path.isfile(value):
699 card_name = self.detect_card_type(value)
700 if card_name != key:
701 raise self.InvalidCmd('Format for input file detected as %s while expecting %s'
702 % (card_name, key))
703 opt[key] = value
704 elif os.path.isfile(pjoin(self.me_dir,value)):
705 card_name = self.detect_card_type(pjoin(self.me_dir,value))
706 if card_name != key:
707 raise self.InvalidCmd('Format for input file detected as %s while expecting %s'
708 % (card_name, key))
709 opt[key] = value
710 else:
711 raise self.InvalidCmd('No such file: %s ' % value)
712 elif key in ['output_dir']:
713 if os.path.isdir(value):
714 opt[key] = value
715 elif os.path.isdir(pjoin(self.me_dir,value)):
716 opt[key] = pjoin(self.me_dir, value)
717 else:
718 raise self.InvalidCmd('No such directory: %s' % value)
719 elif arg in ['loop','param','run','all']:
720 mode = arg
721 elif arg == '--no_MadLoopInit':
722 opt['forbid_MadLoopInit'] = True
723 else:
724 self.help_treatcards()
725 raise self.InvalidCmd('Unvalid argument %s' % arg)
726
727 return mode, opt
728
729
731 """check that the argument for survey are valid"""
732
733
734 self.opts = dict([(key,value[1]) for (key,value) in \
735 self._survey_options.items()])
736
737
738 while args and args[-1].startswith('--'):
739 arg = args.pop(-1)
740 try:
741 for opt,value in self._survey_options.items():
742 if arg.startswith('--%s=' % opt):
743 exec('self.opts[\'%s\'] = %s(arg.split(\'=\')[-1])' % \
744 (opt, value[0]))
745 arg = ""
746 if arg != "": raise Exception
747 except Exception:
748 self.help_survey()
749 raise self.InvalidCmd('invalid %s argument'% arg)
750
751 if len(args) > 1:
752 self.help_survey()
753 raise self.InvalidCmd('Too many argument for %s command' % cmd)
754 elif not args:
755
756 self.set_run_name(self.find_available_run_name(self.me_dir))
757 else:
758 self.set_run_name(args[0], None,'parton', True)
759 args.pop(0)
760
761 return True
762
764 """check that the argument for generate_events are valid"""
765
766 run = None
767 if args and args[-1].startswith('--laststep='):
768 run = args[-1].split('=')[-1]
769 if run not in ['auto','parton', 'pythia', 'pgs', 'delphes']:
770 self.help_generate_events()
771 raise self.InvalidCmd('invalid %s argument'% args[-1])
772 if run != 'parton' and not self.options['pythia-pgs_path']:
773 raise self.InvalidCmd('''pythia-pgs not install. Please install this package first.
774 To do so type: \'install pythia-pgs\' in the mg5 interface''')
775 if run == 'delphes' and not self.options['delphes_path']:
776 raise self.InvalidCmd('''delphes not install. Please install this package first.
777 To do so type: \'install Delphes\' in the mg5 interface''')
778 del args[-1]
779
780
781
782
783
784
785 return run
786
788 """check that the argument are correct"""
789
790
791 if len(args) >2:
792 self.help_time_of_flight()
793 raise self.InvalidCmd('Too many arguments')
794
795
796 if args and args[-1].startswith('--threshold='):
797 try:
798 threshold = float(args[-1].split('=')[1])
799 except ValueError:
800 raise self.InvalidCmd('threshold options require a number.')
801 args.remove(args[-1])
802 else:
803 threshold = 1e-12
804
805 if len(args) == 1 and os.path.exists(args[0]):
806 event_path = args[0]
807 else:
808 if len(args) and self.run_name != args[0]:
809 self.set_run_name(args.pop(0))
810 elif not self.run_name:
811 self.help_add_time_of_flight()
812 raise self.InvalidCmd('Need a run_name to process')
813 event_path = pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe.gz')
814 if not os.path.exists(event_path):
815 event_path = event_path[:-3]
816 if not os.path.exists(event_path):
817 raise self.InvalidCmd('No unweighted events associate to this run.')
818
819
820
821
822 args[:] = [event_path, threshold]
823
825 """check that the argument for calculate_decay_widths are valid"""
826
827 if self.ninitial != 1:
828 raise self.InvalidCmd('Can only calculate decay widths for decay processes A > B C ...')
829
830 accuracy = 0.01
831 run = None
832 if args and args[-1].startswith('--accuracy='):
833 try:
834 accuracy = float(args[-1].split('=')[-1])
835 except Exception:
836 raise self.InvalidCmd('Argument error in calculate_decay_widths command')
837 del args[-1]
838 if len(args) > 1:
839 self.help_calculate_decay_widths()
840 raise self.InvalidCmd('Too many argument for calculate_decay_widths command: %s' % cmd)
841
842 return accuracy
843
844
845
847 """check that the argument for survey are valid"""
848
849 run = None
850
851 if not len(args):
852 self.help_multi_run()
853 raise self.InvalidCmd("""multi_run command requires at least one argument for
854 the number of times that it call generate_events command""")
855
856 if args[-1].startswith('--laststep='):
857 run = args[-1].split('=')[-1]
858 if run not in ['parton', 'pythia', 'pgs', 'delphes']:
859 self.help_multi_run()
860 raise self.InvalidCmd('invalid %s argument'% args[-1])
861 if run != 'parton' and not self.options['pythia-pgs_path']:
862 raise self.InvalidCmd('''pythia-pgs not install. Please install this package first.
863 To do so type: \'install pythia-pgs\' in the mg5 interface''')
864 if run == 'delphes' and not self.options['delphes_path']:
865 raise self.InvalidCmd('''delphes not install. Please install this package first.
866 To do so type: \'install Delphes\' in the mg5 interface''')
867 del args[-1]
868
869
870 elif not args[0].isdigit():
871 self.help_multi_run()
872 raise self.InvalidCmd("The first argument of multi_run should be a integer.")
873
874 nb_run = args.pop(0)
875 args.insert(0, int(nb_run))
876
877
878 return run
879
881 """check that the argument for survey are valid"""
882
883
884 try:
885 float(args[-1])
886 except ValueError:
887 self.help_refine()
888 raise self.InvalidCmd('Not valid arguments')
889 except IndexError:
890 self.help_refine()
891 raise self.InvalidCmd('require_precision argument is require for refine cmd')
892
893
894 if not self.run_name:
895 if self.results.lastrun:
896 self.set_run_name(self.results.lastrun)
897 else:
898 raise self.InvalidCmd('No run_name currently define. Unable to run refine')
899
900 if len(args) > 2:
901 self.help_refine()
902 raise self.InvalidCmd('Too many argument for refine command')
903 else:
904 try:
905 [float(arg) for arg in args]
906 except ValueError:
907 self.help_refine()
908 raise self.InvalidCmd('refine arguments are suppose to be number')
909
910 return True
911
913 """ Check the argument for the combine events command """
914
915 tag = [a for a in arg if a.startswith('--tag=')]
916 if tag:
917 arg.remove(tag[0])
918 tag = tag[0][6:]
919 elif not self.run_tag:
920 tag = 'tag_1'
921 else:
922 tag = self.run_tag
923 self.run_tag = tag
924
925 if len(arg) > 1:
926 self.help_combine_events()
927 raise self.InvalidCmd('Too many argument for combine_events command')
928
929 if len(arg) == 1:
930 self.set_run_name(arg[0], self.run_tag, 'parton', True)
931
932 if not self.run_name:
933 if not self.results.lastrun:
934 raise self.InvalidCmd('No run_name currently define. Unable to run combine')
935 else:
936 self.set_run_name(self.results.lastrun)
937
938 return True
939
941 """Check the argument for pythia command
942 syntax is "pythia [NAME]"
943 Note that other option are already remove at this point
944 """
945
946 mode = None
947 laststep = [arg for arg in args if arg.startswith('--laststep=')]
948 if laststep and len(laststep)==1:
949 mode = laststep[0].split('=')[-1]
950 if mode not in ['auto', 'pythia', 'pgs', 'delphes']:
951 self.help_pythia()
952 raise self.InvalidCmd('invalid %s argument'% args[-1])
953 elif laststep:
954 raise self.InvalidCmd('only one laststep argument is allowed')
955
956
957 if not self.options['pythia-pgs_path']:
958 logger.info('Retry to read configuration file to find pythia-pgs path')
959 self.set_configuration()
960
961 if not self.options['pythia-pgs_path'] or not \
962 os.path.exists(pjoin(self.options['pythia-pgs_path'],'src')):
963 error_msg = 'No valid pythia-pgs path set.\n'
964 error_msg += 'Please use the set command to define the path and retry.\n'
965 error_msg += 'You can also define it in the configuration file.\n'
966 raise self.InvalidCmd(error_msg)
967
968
969
970 tag = [a for a in args if a.startswith('--tag=')]
971 if tag:
972 args.remove(tag[0])
973 tag = tag[0][6:]
974
975 if len(args) == 0 and not self.run_name:
976 if self.results.lastrun:
977 args.insert(0, self.results.lastrun)
978 else:
979 raise self.InvalidCmd('No run name currently define. Please add this information.')
980
981 if len(args) >= 1:
982 if args[0] != self.run_name and\
983 not os.path.exists(pjoin(self.me_dir,'Events',args[0], 'unweighted_events.lhe.gz')):
984 raise self.InvalidCmd('No events file corresponding to %s run. '% args[0])
985 self.set_run_name(args[0], tag, 'pythia')
986 else:
987 if tag:
988 self.run_card['run_tag'] = tag
989 self.set_run_name(self.run_name, tag, 'pythia')
990
991 input_file = pjoin(self.me_dir,'Events',self.run_name, 'unweighted_events.lhe')
992 output_file = pjoin(self.me_dir, 'Events', 'unweighted_events.lhe')
993 if not os.path.exists('%s.gz' % input_file):
994 if not os.path.exists(input_file):
995 raise self.InvalidCmd('No events file corresponding to %s run. '% self.run_name)
996 files.ln(input_file, os.path.dirname(output_file))
997 else:
998 misc.gunzip(input_file, keep=True, stdout=output_file)
999
1000 args.append(mode)
1001
1003 """Check that the remove command is valid"""
1004
1005 tmp_args = args[:]
1006
1007 tag = [a[6:] for a in tmp_args if a.startswith('--tag=')]
1008 if tag:
1009 tag = tag[0]
1010 tmp_args.remove('--tag=%s' % tag)
1011
1012
1013 if len(tmp_args) == 0:
1014 self.help_remove()
1015 raise self.InvalidCmd('clean command require the name of the run to clean')
1016 elif len(tmp_args) == 1:
1017 return tmp_args[0], tag, ['all']
1018 else:
1019 for arg in tmp_args[1:]:
1020 if arg not in self._clean_mode:
1021 self.help_remove()
1022 raise self.InvalidCmd('%s is not a valid options for clean command'\
1023 % arg)
1024 return tmp_args[0], tag, tmp_args[1:]
1025
1027 """Check the argument for the plot command
1028 plot run_name modes"""
1029
1030 madir = self.options['madanalysis_path']
1031 td = self.options['td_path']
1032
1033 if not madir or not td:
1034 logger.info('Retry to read configuration file to find madanalysis/td')
1035 self.set_configuration()
1036
1037 madir = self.options['madanalysis_path']
1038 td = self.options['td_path']
1039
1040 if not madir:
1041 error_msg = 'No valid MadAnalysis path set.\n'
1042 error_msg += 'Please use the set command to define the path and retry.\n'
1043 error_msg += 'You can also define it in the configuration file.\n'
1044 raise self.InvalidCmd(error_msg)
1045 if not td:
1046 error_msg = 'No valid td path set.\n'
1047 error_msg += 'Please use the set command to define the path and retry.\n'
1048 error_msg += 'You can also define it in the configuration file.\n'
1049 raise self.InvalidCmd(error_msg)
1050
1051 if len(args) == 0:
1052 if not hasattr(self, 'run_name') or not self.run_name:
1053 self.help_plot()
1054 raise self.InvalidCmd('No run name currently define. Please add this information.')
1055 args.append('all')
1056 return
1057
1058
1059 if args[0] not in self._plot_mode:
1060 self.set_run_name(args[0], level='plot')
1061 del args[0]
1062 if len(args) == 0:
1063 args.append('all')
1064 elif not self.run_name:
1065 self.help_plot()
1066 raise self.InvalidCmd('No run name currently define. Please add this information.')
1067
1068 for arg in args:
1069 if arg not in self._plot_mode and arg != self.run_name:
1070 self.help_plot()
1071 raise self.InvalidCmd('unknown options %s' % arg)
1072
1074 """Check the argument for the syscalc command
1075 syscalc run_name modes"""
1076
1077 scdir = self.options['syscalc_path']
1078
1079 if not scdir:
1080 logger.info('Retry to read configuration file to find SysCalc')
1081 self.set_configuration()
1082
1083 scdir = self.options['syscalc_path']
1084
1085 if not scdir:
1086 error_msg = 'No valid SysCalc path set.\n'
1087 error_msg += 'Please use the set command to define the path and retry.\n'
1088 error_msg += 'You can also define it in the configuration file.\n'
1089 error_msg += 'Please note that you need to compile SysCalc first.'
1090 raise self.InvalidCmd(error_msg)
1091
1092 if len(args) == 0:
1093 if not hasattr(self, 'run_name') or not self.run_name:
1094 self.help_syscalc()
1095 raise self.InvalidCmd('No run name currently defined. Please add this information.')
1096 args.append('all')
1097 return
1098
1099
1100 tag = [a for a in args if a.startswith('--tag=')]
1101 if tag:
1102 args.remove(tag[0])
1103 tag = tag[0][6:]
1104
1105 if args[0] not in self._syscalc_mode:
1106 self.set_run_name(args[0], tag=tag, level='syscalc')
1107 del args[0]
1108 if len(args) == 0:
1109 args.append('all')
1110 elif not self.run_name:
1111 self.help_syscalc()
1112 raise self.InvalidCmd('No run name currently defined. Please add this information.')
1113 elif tag and tag != self.run_tag:
1114 self.set_run_name(self.run_name, tag=tag, level='syscalc')
1115
1116 for arg in args:
1117 if arg not in self._syscalc_mode and arg != self.run_name:
1118 self.help_syscalc()
1119 raise self.InvalidCmd('unknown options %s' % arg)
1120
1121 if self.run_card['use_syst'] not in self.true:
1122 raise self.InvalidCmd('Run %s does not include ' % self.run_name + \
1123 'systematics information needed for syscalc.')
1124
1125
1126 - def check_pgs(self, arg, no_default=False):
1127 """Check the argument for pythia command
1128 syntax is "pgs [NAME]"
1129 Note that other option are already remove at this point
1130 """
1131
1132
1133 if not self.options['pythia-pgs_path']:
1134 logger.info('Retry to read configuration file to find pythia-pgs path')
1135 self.set_configuration()
1136
1137 if not self.options['pythia-pgs_path'] or not \
1138 os.path.exists(pjoin(self.options['pythia-pgs_path'],'src')):
1139 error_msg = 'No valid pythia-pgs path set.\n'
1140 error_msg += 'Please use the set command to define the path and retry.\n'
1141 error_msg += 'You can also define it in the configuration file.\n'
1142 raise self.InvalidCmd(error_msg)
1143
1144 tag = [a for a in arg if a.startswith('--tag=')]
1145 if tag:
1146 arg.remove(tag[0])
1147 tag = tag[0][6:]
1148
1149
1150 if len(arg) == 0 and not self.run_name:
1151 if self.results.lastrun:
1152 arg.insert(0, self.results.lastrun)
1153 else:
1154 raise self.InvalidCmd('No run name currently define. Please add this information.')
1155
1156 if len(arg) == 1 and self.run_name == arg[0]:
1157 arg.pop(0)
1158
1159 if not len(arg) and \
1160 not os.path.exists(pjoin(self.me_dir,'Events','pythia_events.hep')):
1161 if not no_default:
1162 self.help_pgs()
1163 raise self.InvalidCmd('''No file file pythia_events.hep currently available
1164 Please specify a valid run_name''')
1165
1166 lock = None
1167 if len(arg) == 1:
1168 prev_tag = self.set_run_name(arg[0], tag, 'pgs')
1169 if not os.path.exists(pjoin(self.me_dir,'Events',self.run_name,'%s_pythia_events.hep.gz' % prev_tag)):
1170 raise self.InvalidCmd('No events file corresponding to %s run with tag %s. '% (self.run_name, prev_tag))
1171 else:
1172 input_file = pjoin(self.me_dir,'Events', self.run_name, '%s_pythia_events.hep.gz' % prev_tag)
1173 output_file = pjoin(self.me_dir, 'Events', 'pythia_events.hep')
1174 lock = cluster.asyncrone_launch('gunzip',stdout=open(output_file,'w'),
1175 argument=['-c', input_file])
1176
1177 else:
1178 if tag:
1179 self.run_card['run_tag'] = tag
1180 self.set_run_name(self.run_name, tag, 'pgs')
1181
1182 return lock
1183
1185 """Check the argument for pythia command
1186 syntax is "delphes [NAME]"
1187 Note that other option are already remove at this point
1188 """
1189
1190
1191 if not self.options['delphes_path']:
1192 logger.info('Retry to read configuration file to find delphes path')
1193 self.set_configuration()
1194
1195 if not self.options['delphes_path']:
1196 error_msg = 'No valid Delphes path set.\n'
1197 error_msg += 'Please use the set command to define the path and retry.\n'
1198 error_msg += 'You can also define it in the configuration file.\n'
1199 raise self.InvalidCmd(error_msg)
1200
1201 tag = [a for a in arg if a.startswith('--tag=')]
1202 if tag:
1203 arg.remove(tag[0])
1204 tag = tag[0][6:]
1205
1206
1207 if len(arg) == 0 and not self.run_name:
1208 if self.results.lastrun:
1209 arg.insert(0, self.results.lastrun)
1210 else:
1211 raise self.InvalidCmd('No run name currently define. Please add this information.')
1212
1213 if len(arg) == 1 and self.run_name == arg[0]:
1214 arg.pop(0)
1215
1216 if not len(arg) and \
1217 not os.path.exists(pjoin(self.me_dir,'Events','pythia_events.hep')):
1218 self.help_pgs()
1219 raise self.InvalidCmd('''No file file pythia_events.hep currently available
1220 Please specify a valid run_name''')
1221
1222 lock = None
1223 if len(arg) == 1:
1224 prev_tag = self.set_run_name(arg[0], tag, 'delphes')
1225 if not os.path.exists(pjoin(self.me_dir,'Events',self.run_name, '%s_pythia_events.hep.gz' % prev_tag)):
1226 raise self.InvalidCmd('No events file corresponding to %s run with tag %s.:%s '\
1227 % (self.run_name, prev_tag,
1228 pjoin(self.me_dir,'Events',self.run_name, '%s_pythia_events.hep.gz' % prev_tag)))
1229 else:
1230 input_file = pjoin(self.me_dir,'Events', self.run_name, '%s_pythia_events.hep.gz' % prev_tag)
1231 output_file = pjoin(self.me_dir, 'Events', 'pythia_events.hep')
1232 lock = cluster.asyncrone_launch('gunzip',stdout=open(output_file,'w'),
1233 argument=['-c', input_file])
1234 else:
1235 if tag:
1236 self.run_card['run_tag'] = tag
1237 self.set_run_name(self.run_name, tag, 'delphes')
1238
1239 return lock
1240
1242 """check the validity of line
1243 syntax is "display XXXXX"
1244 """
1245
1246 if len(args) < 1 or args[0] not in self._display_opts:
1247 self.help_display()
1248 raise self.InvalidCmd
1249
1250 if args[0] == 'variable' and len(args) !=2:
1251 raise self.InvalidCmd('variable need a variable name')
1252
1253
1254
1255
1256
1258 """check the validity of line"""
1259
1260 if not args:
1261 self.help_import()
1262 raise self.InvalidCmd('wrong \"import\" format')
1263
1264 if args[0] != 'command':
1265 args.insert(0,'command')
1266
1267
1268 if not len(args) == 2 or not os.path.exists(args[1]):
1269 raise self.InvalidCmd('PATH is mandatory for import command\n')
1270
1276 """ The Series of help routine for the MadGraphCmd"""
1277
1278
1280 "Complete command"
1281
1282 args = self.split_arg(line[0:begidx], error=False)
1283
1284 if len(args) == 1:
1285
1286 data = misc.glob(pjoin('*','unweighted_events.lhe.gz'), pjoin(self.me_dir, 'Events'))
1287 data = [n.rsplit('/',2)[1] for n in data]
1288 return self.list_completion(text, data + ['--threshold='], line)
1289 elif args[-1].endswith(os.path.sep):
1290 return self.path_completion(text,
1291 os.path.join('.',*[a for a in args \
1292 if a.endswith(os.path.sep)]))
1293 else:
1294 return self.list_completion(text, ['--threshold='], line)
1295
1297 "Complete the banner run command"
1298 try:
1299
1300
1301 args = self.split_arg(line[0:begidx], error=False)
1302
1303 if args[-1].endswith(os.path.sep):
1304 return self.path_completion(text,
1305 os.path.join('.',*[a for a in args \
1306 if a.endswith(os.path.sep)]))
1307
1308
1309 if len(args) > 1:
1310
1311 tags = misc.glob('%s_*_banner.txt' % args[1], pjoin(self.me_dir, 'Events' , args[1]))
1312 tags = ['%s' % os.path.basename(t)[len(args[1])+1:-11] for t in tags]
1313
1314 if args[-1] != '--tag=':
1315 tags = ['--tag=%s' % t for t in tags]
1316 else:
1317 return self.list_completion(text, tags)
1318 return self.list_completion(text, tags +['--name=','-f'], line)
1319
1320
1321 possibilites = {}
1322
1323 comp = self.path_completion(text, os.path.join('.',*[a for a in args \
1324 if a.endswith(os.path.sep)]))
1325 if os.path.sep in line:
1326 return comp
1327 else:
1328 possibilites['Path from ./'] = comp
1329
1330 run_list = misc.glob(pjoin('*','*_banner.txt'), pjoin(self.me_dir, 'Events'))
1331 run_list = [n.rsplit('/',2)[1] for n in run_list]
1332 possibilites['RUN Name'] = self.list_completion(text, run_list)
1333
1334 return self.deal_multiple_categories(possibilites)
1335
1336
1337 except Exception, error:
1338 print error
1339
1340
1341 - def complete_history(self, text, line, begidx, endidx):
1342 "Complete the history command"
1343
1344 args = self.split_arg(line[0:begidx], error=False)
1345
1346
1347 if args[-1].endswith(os.path.sep):
1348 return self.path_completion(text,
1349 os.path.join('.',*[a for a in args \
1350 if a.endswith(os.path.sep)]))
1351
1352 if len(args) == 1:
1353 return self.path_completion(text)
1354
1356 """ complete the open command """
1357
1358 args = self.split_arg(line[0:begidx])
1359
1360
1361 if os.path.sep in args[-1] + text:
1362 return self.path_completion(text,
1363 os.path.join('.',*[a for a in args if \
1364 a.endswith(os.path.sep)]))
1365
1366 possibility = []
1367 if self.me_dir:
1368 path = self.me_dir
1369 possibility = ['index.html']
1370 if os.path.isfile(os.path.join(path,'README')):
1371 possibility.append('README')
1372 if os.path.isdir(os.path.join(path,'Cards')):
1373 possibility += [f for f in os.listdir(os.path.join(path,'Cards'))
1374 if f.endswith('.dat')]
1375 if os.path.isdir(os.path.join(path,'HTML')):
1376 possibility += [f for f in os.listdir(os.path.join(path,'HTML'))
1377 if f.endswith('.html') and 'default' not in f]
1378 else:
1379 possibility.extend(['./','../'])
1380 if os.path.exists('ME5_debug'):
1381 possibility.append('ME5_debug')
1382 if os.path.exists('MG5_debug'):
1383 possibility.append('MG5_debug')
1384 return self.list_completion(text, possibility)
1385
1387 "Complete the set command"
1388
1389 args = self.split_arg(line[0:begidx])
1390
1391
1392 if len(args) == 1:
1393 return self.list_completion(text, self._set_options + self.options.keys() )
1394
1395 if len(args) == 2:
1396 if args[1] == 'stdout_level':
1397 return self.list_completion(text, ['DEBUG','INFO','WARNING','ERROR','CRITICAL'])
1398 else:
1399 first_set = ['None','True','False']
1400
1401 second_set = [name for name in self.path_completion(text, '.', only_dirs = True)]
1402 return self.list_completion(text, first_set + second_set)
1403 elif len(args) >2 and args[-1].endswith(os.path.sep):
1404 return self.path_completion(text,
1405 os.path.join('.',*[a for a in args if a.endswith(os.path.sep)]),
1406 only_dirs = True)
1407
1409 """ Complete the survey command """
1410
1411 if line.endswith('nb_core=') and not text:
1412 import multiprocessing
1413 max = multiprocessing.cpu_count()
1414 return [str(i) for i in range(2,max+1)]
1415
1416 return self.list_completion(text, self._run_options, line)
1417
1418 complete_refine = complete_survey
1419 complete_combine_events = complete_survey
1420 complite_store = complete_survey
1421 complete_generate_events = complete_survey
1422 complete_create_gridpack = complete_survey
1423
1425 """ Complete the generate events"""
1426
1427 if line.endswith('nb_core=') and not text:
1428 import multiprocessing
1429 max = multiprocessing.cpu_count()
1430 return [str(i) for i in range(2,max+1)]
1431 if line.endswith('laststep=') and not text:
1432 return ['parton','pythia','pgs','delphes']
1433 elif '--laststep=' in line.split()[-1] and line and line[-1] != ' ':
1434 return self.list_completion(text,['parton','pythia','pgs','delphes'],line)
1435
1436 opts = self._run_options + self._generate_options
1437 return self.list_completion(text, opts, line)
1438
1439
1441 "Complete the initMadLoop command"
1442
1443 numbers = [str(i) for i in range(10)]
1444 opts = ['-f','-r','--nPS=']
1445
1446 args = self.split_arg(line[0:begidx], error=False)
1447 if len(line) >=6 and line[begidx-6:begidx]=='--nPS=':
1448 return self.list_completion(text, numbers, line)
1449 else:
1450 return self.list_completion(text, [opt for opt in opts if not opt in
1451 line], line)
1452
1459
1461 """ Complete the calculate_decay_widths command"""
1462
1463 if line.endswith('nb_core=') and not text:
1464 import multiprocessing
1465 max = multiprocessing.cpu_count()
1466 return [str(i) for i in range(2,max+1)]
1467
1468 opts = self._run_options + self._calculate_decay_options
1469 return self.list_completion(text, opts, line)
1470
1479
1481 """complete multi run command"""
1482
1483 args = self.split_arg(line[0:begidx], error=False)
1484 if len(args) == 1:
1485 data = [str(i) for i in range(0,20)]
1486 return self.list_completion(text, data, line)
1487
1488 if line.endswith('run=') and not text:
1489 return ['parton','pythia','pgs','delphes']
1490 elif '--laststep=' in line.split()[-1] and line and line[-1] != ' ':
1491 return self.list_completion(text,['parton','pythia','pgs','delphes'],line)
1492
1493 opts = self._run_options + self._generate_options
1494 return self.list_completion(text, opts, line)
1495
1496
1497
1498 if line.endswith('nb_core=') and not text:
1499 import multiprocessing
1500 max = multiprocessing.cpu_count()
1501 return [str(i) for i in range(2,max+1)]
1502 opts = self._run_options + self._generate_options
1503 return self.list_completion(text, opts, line)
1504
1513
1531
1533 """Complete the remove command """
1534
1535 args = self.split_arg(line[0:begidx], error=False)
1536 if len(args) > 1 and (text.startswith('--t')):
1537 run = args[1]
1538 tags = ['--tag=%s' % tag['tag'] for tag in self.results[run]]
1539 return self.list_completion(text, tags)
1540 elif len(args) > 1 and '--' == args[-1]:
1541 run = args[1]
1542 tags = ['tag=%s' % tag['tag'] for tag in self.results[run]]
1543 return self.list_completion(text, tags)
1544 elif len(args) > 1 and '--tag=' == args[-1]:
1545 run = args[1]
1546 tags = [tag['tag'] for tag in self.results[run]]
1547 return self.list_completion(text, tags)
1548 elif len(args) > 1:
1549 return self.list_completion(text, self._clean_mode + ['-f','--tag='])
1550 else:
1551 data = misc.glob(pjoin('*','*_banner.txt'), pjoin(self.me_dir, 'Events'))
1552 data = [n.rsplit('/',2)[1] for n in data]
1553 return self.list_completion(text, ['all'] + data)
1554
1555
1557 "Complete the pythia command"
1558 args = self.split_arg(line[0:begidx], error=False)
1559
1560 if len(args) == 1:
1561
1562 data = misc.glob(pjoin('*','unweighted_events.lhe.gz'), pjoin(self.me_dir, 'Events'))
1563 data = [n.rsplit('/',2)[1] for n in data]
1564 tmp1 = self.list_completion(text, data)
1565 if not self.run_name:
1566 return tmp1
1567 else:
1568 tmp2 = self.list_completion(text, self._run_options + ['-f',
1569 '--no_default', '--tag='], line)
1570 return tmp1 + tmp2
1571 elif line[-1] != '=':
1572 return self.list_completion(text, self._run_options + ['-f',
1573 '--no_default','--tag='], line)
1574
1576 "Complete the pythia command"
1577 args = self.split_arg(line[0:begidx], error=False)
1578 if len(args) == 1:
1579
1580 data = misc.glob(pjoin('*', '*_pythia_events.hep.gz'), pjoin(self.me_dir, 'Events'))
1581 data = [n.rsplit('/',2)[1] for n in data]
1582 tmp1 = self.list_completion(text, data)
1583 if not self.run_name:
1584 return tmp1
1585 else:
1586 tmp2 = self.list_completion(text, self._run_options + ['-f',
1587 '--tag=' ,'--no_default'], line)
1588 return tmp1 + tmp2
1589 else:
1590 return self.list_completion(text, self._run_options + ['-f',
1591 '--tag=','--no_default'], line)
1592
1593 complete_delphes = complete_pgs
1594
1595
1596
1597
1598
1599
1600
1601
1602 -class MadEventCmd(CompleteForCmd, CmdExtended, HelpToCmd, common_run.CommonRunCmd):
1603
1604 """The command line processor of MadGraph"""
1605
1606
1607 true = ['T','.true.',True,'true']
1608
1609 _run_options = ['--cluster','--multicore','--nb_core=','--nb_core=2', '-c', '-m']
1610 _generate_options = ['-f', '--laststep=parton', '--laststep=pythia', '--laststep=pgs', '--laststep=delphes']
1611 _calculate_decay_options = ['-f', '--accuracy=0.']
1612 _set_options = ['stdout_level','fortran_compiler','timeout']
1613 _plot_mode = ['all', 'parton','pythia','pgs','delphes','channel', 'banner']
1614 _syscalc_mode = ['all', 'parton','pythia']
1615 _clean_mode = _plot_mode
1616 _display_opts = ['run_name', 'options', 'variable', 'results']
1617 _save_opts = ['options']
1618 _initMadLoop_opts = ['-f','-r','--nPS=']
1619
1620 _survey_options = {'points':('int', 1000,'Number of points for first iteration'),
1621 'iterations':('int', 5, 'Number of iterations'),
1622 'accuracy':('float', 0.1, 'Required accuracy'),
1623 'gridpack':('str', '.false.', 'Gridpack generation')}
1624
1625 true = ['T','.true.',True,'true', 1, '1']
1626 web = False
1627 cluster_mode = 0
1628 queue = 'madgraph'
1629 nb_core = None
1630
1631 next_possibility = {
1632 'start': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]',
1633 'calculate_decay_widths [OPTIONS]',
1634 'help generate_events'],
1635 'generate_events': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]', 'pythia', 'pgs','delphes'],
1636 'calculate_decay_widths': ['calculate_decay_widths [OPTIONS]',
1637 'generate_events [OPTIONS]'],
1638 'multi_run': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]'],
1639 'survey': ['refine'],
1640 'refine': ['combine_events'],
1641 'combine_events': ['store'],
1642 'store': ['pythia'],
1643 'pythia': ['pgs', 'delphes'],
1644 'pgs': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]'],
1645 'delphes' : ['generate_events [OPTIONS]', 'multi_run [OPTIONS]']
1646 }
1647
1648
1649 - def __init__(self, me_dir = None, options={}, *completekey, **stdin):
1650 """ add information to the cmd """
1651
1652 CmdExtended.__init__(self, me_dir, options, *completekey, **stdin)
1653
1654
1655 self.mode = 'madevent'
1656 self.nb_refine=0
1657 if self.web:
1658 os.system('touch %s' % pjoin(self.me_dir,'Online'))
1659
1660 self.load_results_db()
1661 self.results.def_web_mode(self.web)
1662
1663 self.prompt = "%s>"%os.path.basename(pjoin(self.me_dir))
1664 self.configured = 0
1665 self._options = {}
1666
1667
1669 """configure web data"""
1670 self.web = True
1671 self.results.def_web_mode(True)
1672 self.force = True
1673 if os.environ['MADGRAPH_BASE']:
1674 self.options['mg5_path'] = pjoin(os.environ['MADGRAPH_BASE'],'MG5')
1675
1676
1678 """ Check that the output path is a valid madevent directory """
1679
1680 bin_path = os.path.join(path,'bin')
1681 if os.path.isfile(os.path.join(bin_path,'generate_events')):
1682 return True
1683 else:
1684 return False
1685
1686
1688 """assign all configuration variable from file
1689 loop over the different config file if config_file not define """
1690
1691 super(MadEventCmd,self).set_configuration(amcatnlo=amcatnlo,
1692 final=final, **opt)
1693
1694 if not final:
1695 return self.options
1696
1697
1698
1699
1700
1701 for key in (k for k in self.options if k.endswith('path')):
1702 path = self.options[key]
1703 if path is None or key.startswith("cluster"):
1704 continue
1705 if not os.path.isdir(path):
1706 path = pjoin(self.me_dir, self.options[key])
1707 if os.path.isdir(path):
1708 self.options[key] = None
1709 if key == "pythia-pgs_path":
1710 if not os.path.exists(pjoin(path, 'src','pythia')):
1711 logger.info("No valid pythia-pgs path found")
1712 continue
1713 elif key == "delphes_path":
1714 if not os.path.exists(pjoin(path, 'Delphes')) and not\
1715 os.path.exists(pjoin(path, 'DelphesSTDHEP')):
1716 logger.info("No valid Delphes path found")
1717 continue
1718 elif key == "madanalysis_path":
1719 if not os.path.exists(pjoin(path, 'plot_events')):
1720 logger.info("No valid MadAnalysis path found")
1721 continue
1722 elif key == "td_path":
1723 if not os.path.exists(pjoin(path, 'td')):
1724 logger.info("No valid td path found")
1725 continue
1726 elif key == "syscalc_path":
1727 if not os.path.exists(pjoin(path, 'sys_calc')):
1728 logger.info("No valid SysCalc path found")
1729 continue
1730
1731
1732 self.options[key] = os.path.realpath(path)
1733 continue
1734 else:
1735 self.options[key] = None
1736
1737
1738 return self.options
1739
1740
1794
1795
1797 """Make a run from the banner file"""
1798
1799 args = self.split_arg(line)
1800
1801 self.check_banner_run(args)
1802
1803
1804 for name in ['delphes_trigger.dat', 'delphes_card.dat',
1805 'pgs_card.dat', 'pythia_card.dat', 'madspin_card.dat',
1806 'reweight_card.dat']:
1807 try:
1808 os.remove(pjoin(self.me_dir, 'Cards', name))
1809 except Exception:
1810 pass
1811
1812 banner_mod.split_banner(args[0], self.me_dir, proc_card=False)
1813
1814
1815 if not self.force:
1816 ans = self.ask('Do you want to modify the Cards?', 'n', ['y','n'])
1817 if ans == 'n':
1818 self.force = True
1819
1820
1821 self.exec_cmd('generate_events %s %s' % (self.run_name, self.force and '-f' or ''))
1822
1823
1824
1825
1827 """Display current internal status"""
1828
1829 args = self.split_arg(line)
1830
1831 self.check_display(args)
1832
1833 if args[0] == 'run_name':
1834
1835 data = misc.glob(pjoin('*','*_banner.txt'), pjoin(self.me_dir, 'Events'))
1836 data = [n.rsplit('/',2)[1:] for n in data]
1837
1838 if data:
1839 out = {}
1840 for name, tag in data:
1841 tag = tag[len(name)+1:-11]
1842 if name in out:
1843 out[name].append(tag)
1844 else:
1845 out[name] = [tag]
1846 print 'the runs available are:'
1847 for run_name, tags in out.items():
1848 print ' run: %s' % run_name
1849 print ' tags: ',
1850 print ', '.join(tags)
1851 else:
1852 print 'No run detected.'
1853
1854 elif args[0] == 'options':
1855 outstr = " Run Options \n"
1856 outstr += " ----------- \n"
1857 for key, default in self.options_madgraph.items():
1858 value = self.options[key]
1859 if value == default:
1860 outstr += " %25s \t:\t%s\n" % (key,value)
1861 else:
1862 outstr += " %25s \t:\t%s (user set)\n" % (key,value)
1863 outstr += "\n"
1864 outstr += " MadEvent Options \n"
1865 outstr += " ---------------- \n"
1866 for key, default in self.options_madevent.items():
1867 if key in self.options:
1868 value = self.options[key]
1869 else:
1870 default = ''
1871 if value == default:
1872 outstr += " %25s \t:\t%s\n" % (key,value)
1873 else:
1874 outstr += " %25s \t:\t%s (user set)\n" % (key,value)
1875 outstr += "\n"
1876 outstr += " Configuration Options \n"
1877 outstr += " --------------------- \n"
1878 for key, default in self.options_configuration.items():
1879 value = self.options[key]
1880 if value == default:
1881 outstr += " %25s \t:\t%s\n" % (key,value)
1882 else:
1883 outstr += " %25s \t:\t%s (user set)\n" % (key,value)
1884 output.write(outstr)
1885 elif args[0] == 'results':
1886 self.do_print_results(' '.join(args[1:]))
1887 else:
1888 super(MadEventCmd, self).do_display(line, output)
1889
1890 - def do_save(self, line, check=True, to_keep={}):
1891 """Not in help: Save information to file"""
1892
1893 args = self.split_arg(line)
1894
1895 if check:
1896 self.check_save(args)
1897
1898 if args[0] == 'options':
1899
1900 to_define = {}
1901 for key, default in self.options_configuration.items():
1902 if self.options[key] != self.options_configuration[key]:
1903 to_define[key] = self.options[key]
1904
1905 if not '--auto' in args:
1906 for key, default in self.options_madevent.items():
1907 if self.options[key] != self.options_madevent[key]:
1908 to_define[key] = self.options[key]
1909
1910 if '--all' in args:
1911 for key, default in self.options_madgraph.items():
1912 if self.options[key] != self.options_madgraph[key]:
1913 to_define[key] = self.options[key]
1914 elif not '--auto' in args:
1915 for key, default in self.options_madgraph.items():
1916 if self.options[key] != self.options_madgraph[key]:
1917 logger.info('The option %s is modified [%s] but will not be written in the configuration files.' \
1918 % (key,self.options_madgraph[key]) )
1919 logger.info('If you want to make this value the default for future session, you can run \'save options --all\'')
1920 if len(args) >1 and not args[1].startswith('--'):
1921 filepath = args[1]
1922 else:
1923 filepath = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
1924 basefile = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
1925 basedir = self.me_dir
1926
1927 if to_keep:
1928 to_define = to_keep
1929 self.write_configuration(filepath, basefile, basedir, to_define)
1930
1931
1932
1933
1942
1943
1944
1945
1947 """Main Commands: launch the full chain """
1948
1949 self.banner = None
1950 args = self.split_arg(line)
1951
1952 mode = self.check_generate_events(args)
1953 self.ask_run_configuration(mode, args)
1954 if not args:
1955
1956 self.set_run_name(self.find_available_run_name(self.me_dir), None, 'parton')
1957 else:
1958 self.set_run_name(args[0], None, 'parton', True)
1959 args.pop(0)
1960
1961 if self.proc_characteristics['loop_induced'] and self.options['run_mode']==0:
1962
1963
1964 logger.warning(
1965 """Single-core mode not supported for loop-induced processes.
1966 Beware that MG5aMC now changes your runtime options to a multi-core mode with only one active core.""")
1967 self.do_set('run_mode 2')
1968 self.do_set('nb_core 1')
1969
1970 if self.run_card['gridpack'] in self.true:
1971
1972 gridpack_opts=[('accuracy', 0.01),
1973 ('points', 2000),
1974 ('iterations',8),
1975 ('gridpack','.true.')]
1976 logger.info('Generating gridpack with run name %s' % self.run_name)
1977 self.exec_cmd('survey %s %s' % \
1978 (self.run_name,
1979 " ".join(['--' + opt + '=' + str(val) for (opt,val) \
1980 in gridpack_opts])),
1981 postcmd=False)
1982 self.exec_cmd('combine_events', postcmd=False)
1983 self.exec_cmd('store_events', postcmd=False)
1984 self.exec_cmd('decay_events -from_cards', postcmd=False)
1985 self.exec_cmd('create_gridpack', postcmd=False)
1986 else:
1987
1988 logger.info('Generating %s events with run name %s' %
1989 (self.run_card['nevents'], self.run_name))
1990
1991 self.exec_cmd('survey %s %s' % (self.run_name,' '.join(args)),
1992 postcmd=False)
1993 nb_event = self.run_card['nevents']
1994 bypass_run=False
1995 self.exec_cmd('refine %s' % nb_event, postcmd=False)
1996 if not float(self.results.current['cross']):
1997
1998 text = '''Survey return zero cross section.
1999 Typical reasons are the following:
2000 1) A massive s-channel particle has a width set to zero.
2001 2) The pdf are zero for at least one of the initial state particles
2002 or you are using maxjetflavor=4 for initial state b:s.
2003 3) The cuts are too strong.
2004 Please check/correct your param_card and/or your run_card.'''
2005 logger_stderr.critical(text)
2006 if not self.param_card_iterator:
2007 raise ZeroResult('See https://cp3.irmp.ucl.ac.be/projects/madgraph/wiki/FAQ-General-14')
2008 else:
2009 bypass_run = True
2010
2011
2012 if not bypass_run:
2013 self.exec_cmd('refine %s' % nb_event, postcmd=False)
2014
2015 self.exec_cmd('combine_events', postcmd=False)
2016 self.print_results_in_shell(self.results.current)
2017
2018
2019 self.run_syscalc('parton')
2020 self.create_plot('parton')
2021 self.exec_cmd('store_events', postcmd=False)
2022 self.exec_cmd('reweight -from_cards', postcmd=False)
2023 self.exec_cmd('decay_events -from_cards', postcmd=False)
2024 if self.run_card['time_of_flight']>=0:
2025 self.exec_cmd("add_time_of_flight --threshold=%s" % self.run_card['time_of_flight'] ,postcmd=False)
2026 self.exec_cmd('pythia --no_default', postcmd=False, printcmd=False)
2027
2028 self.store_result()
2029
2030 if self.param_card_iterator:
2031 param_card_iterator = self.param_card_iterator
2032 self.param_card_iterator = []
2033 with misc.TMP_variable(self, 'allow_notification_center', False):
2034 param_card_iterator.store_entry(self.run_name, self.results.current['cross'])
2035
2036 orig_name = self.run_name
2037 for card in param_card_iterator:
2038 card.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2039 next_name = param_card_iterator.get_next_name(self.run_name)
2040 try:
2041 self.exec_cmd("generate_events -f %s" % next_name,
2042 precmd=True, postcmd=True,errorhandling=False)
2043 except ZeroResult:
2044 param_card_iterator.store_entry(self.run_name, 0)
2045 else:
2046 param_card_iterator.store_entry(self.run_name, self.results.current['cross'])
2047 param_card_iterator.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2048 name = misc.get_scan_name(orig_name, self.run_name)
2049 path = pjoin(self.me_dir, 'Events','scan_%s.txt' % name)
2050 logger.info("write all cross-section results in %s" % path ,'$MG:color:BLACK')
2051 param_card_iterator.write_summary(path)
2052
2053
2054 if self.allow_notification_center:
2055 misc.apple_notify('Run %s finished' % os.path.basename(self.me_dir),
2056 '%s: %s +- %s ' % (self.results.current['run_name'],
2057 self.results.current['cross'],
2058 self.results.current['error']))
2059
2061 """Compile and run MadLoop for a certain number of PS point so as to
2062 initialize MadLoop (setup the zero helicity and loop filter.)"""
2063
2064 args = line.split()
2065
2066 options = self.check_initMadLoop(args)
2067
2068 if not options['force']:
2069 self.ask_edit_cards(['MadLoopParams.dat'], mode='fixed', plot=False)
2070 self.exec_cmd('treatcards loop --no_MadLoopInit')
2071
2072 if options['refresh']:
2073 for filter in misc.glob('*Filter*',
2074 pjoin(self.me_dir,'SubProcesses','MadLoop5_resources')):
2075 logger.debug("Resetting filter '%s'."%os.path.basename(filter))
2076 os.remove(filter)
2077
2078 MLCard = banner_mod.MadLoopParam(pjoin(self.me_dir,
2079 'Cards','MadLoopParams.dat'))
2080 if options['nPS'] is None:
2081 options['nPS'] = MLCard['CheckCycle']+2
2082 elif options['nPS'] < MLCard['CheckCycle']+2:
2083 new_n_PS = MLCard['CheckCycle']+2
2084 logger.debug('Hard-setting user-defined n_PS (%d) to %d, because '\
2085 %(options['nPS'],new_n_PS)+"of the 'CheckCycle' value (%d) "%MLCard['CheckCycle']+\
2086 "specified in the ML param card.")
2087 options['nPS'] = new_n_PS
2088
2089 MadLoopInitializer.init_MadLoop(self.me_dir,n_PS=options['nPS'],
2090 subproc_prefix='PV', MG_options=self.options, interface=self)
2091
2093 """Main Commands: exec generate_events for 2>N and calculate_width for 1>N"""
2094 if self.ninitial == 1:
2095 logger.info("Note that since 2.3. The launch for 1>N pass in event generation\n"+
2096 " To have the previous behavior use the calculate_decay_widths function")
2097 self.do_calculate_decay_widths(line, *args, **opt)
2098 else:
2099 self.do_generate_events(line, *args, **opt)
2100
2102 """Have a nice results prints in the shell,
2103 data should be of type: gen_crossxhtml.OneTagResults"""
2104
2105 if not data:
2106 return
2107
2108 if data['run_statistics']:
2109 globalstat = sum_html.RunStatistics()
2110
2111 logger.info(" " )
2112 logger.debug(" === Run statistics summary ===")
2113 for key, value in data['run_statistics'].items():
2114 globalstat.aggregate_statistics(value)
2115 level = 5
2116 if value.has_warning():
2117 level = 10
2118 logger.log(level, value.nice_output(str('/'.join([key[0],'G%s'%key[1]]))).\
2119 replace(' statistics',''))
2120 logger.info(" " )
2121 logger.debug(globalstat.nice_output('combined', no_warning=True))
2122 if globalstat.has_warning():
2123 logger.warning(globalstat.get_warning_text())
2124 logger.info(" ")
2125
2126
2127 logger.info(" === Results Summary for run: %s tag: %s ===\n" % (data['run_name'],data['tag']))
2128
2129 total_time = int(sum(_['cumulative_timing'] for _ in data['run_statistics'].values()))
2130 if total_time > 0:
2131 logger.info(" Cumulative sequential time for this run: %s"%misc.format_time(total_time))
2132
2133 if self.ninitial == 1:
2134 logger.info(" Width : %.4g +- %.4g GeV" % (data['cross'], data['error']))
2135 else:
2136 logger.info(" Cross-section : %.4g +- %.4g pb" % (data['cross'], data['error']))
2137 logger.info(" Nb of events : %s" % data['nb_event'] )
2138 if data['cross_pythia'] and data['nb_event_pythia']:
2139 if self.ninitial == 1:
2140 logger.info(" Matched Width : %.4g +- %.4g GeV" % (data['cross_pythia'], data['error_pythia']))
2141 else:
2142 logger.info(" Matched Cross-section : %.4g +- %.4g pb" % (data['cross_pythia'], data['error_pythia']))
2143 logger.info(" Nb of events after Matching : %s" % data['nb_event_pythia'])
2144 if self.run_card['use_syst'] in self.true:
2145 logger.info(" Be carefull that matched information are here NOT for the central value. Refer to SysCalc output for it")
2146
2147 logger.info(" " )
2148
2150 """Have a nice results prints in the shell,
2151 data should be of type: gen_crossxhtml.OneTagResults"""
2152 if not data:
2153 return
2154
2155 fsock = open(path, mode)
2156
2157 if data['run_statistics']:
2158 logger.debug(" === Run statistics summary ===")
2159 for key, value in data['run_statistics'].items():
2160 logger.debug(value.nice_output(str('/'.join([key[0],'G%s'%key[1]]))).\
2161 replace(' statistics',''))
2162 logger.info(" " )
2163
2164 if format == "full":
2165 fsock.write(" === Results Summary for run: %s tag: %s process: %s ===\n" % \
2166 (data['run_name'],data['tag'], os.path.basename(self.me_dir)))
2167
2168 if self.ninitial == 1:
2169 fsock.write(" Width : %.4g +- %.4g GeV\n" % (data['cross'], data['error']))
2170 else:
2171 fsock.write(" Cross-section : %.4g +- %.4g pb\n" % (data['cross'], data['error']))
2172 fsock.write(" Nb of events : %s\n" % data['nb_event'] )
2173 if data['cross_pythia'] and data['nb_event_pythia']:
2174 if self.ninitial == 1:
2175 fsock.write(" Matched Width : %.4g +- %.4g GeV\n" % (data['cross_pythia'], data['error_pythia']))
2176 else:
2177 fsock.write(" Matched Cross-section : %.4g +- %.4g pb\n" % (data['cross_pythia'], data['error_pythia']))
2178 fsock.write(" Nb of events after Matching : %s\n" % data['nb_event_pythia'])
2179 fsock.write(" \n" )
2180 elif format == "short":
2181 if mode == "w":
2182 fsock.write("# run_name tag cross error Nb_event cross_after_matching nb_event_after matching\n")
2183
2184 if data['cross_pythia'] and data['nb_event_pythia']:
2185 text = "%(run_name)s %(tag)s %(cross)s %(error)s %(nb_event)s %(cross_pythia)s %(nb_event_pythia)s\n"
2186 else:
2187 text = "%(run_name)s %(tag)s %(cross)s %(error)s %(nb_event)s\n"
2188 fsock.write(text % data)
2189
2190
2192 """Main Commands: launch decay width calculation and automatic inclusion of
2193 calculated widths and BRs in the param_card."""
2194
2195 args = self.split_arg(line)
2196
2197 accuracy = self.check_calculate_decay_widths(args)
2198 self.ask_run_configuration('parton')
2199 self.banner = None
2200 if not args:
2201
2202 self.set_run_name(self.find_available_run_name(self.me_dir))
2203 else:
2204 self.set_run_name(args[0], reload_card=True)
2205 args.pop(0)
2206
2207 self.configure_directory()
2208
2209
2210 opts=[('accuracy', accuracy),
2211 ('points', 1000),
2212 ('iterations',9)]
2213
2214 logger.info('Calculating decay widths with run name %s' % self.run_name)
2215
2216 self.exec_cmd('survey %s %s' % \
2217 (self.run_name,
2218 " ".join(['--' + opt + '=' + str(val) for (opt,val) \
2219 in opts])),
2220 postcmd=False)
2221 self.refine_mode = "old"
2222 self.exec_cmd('combine_events', postcmd=False)
2223 self.exec_cmd('store_events', postcmd=False)
2224
2225 self.collect_decay_widths()
2226 self.print_results_in_shell(self.results.current)
2227 self.update_status('calculate_decay_widths done',
2228 level='parton', makehtml=False)
2229
2230
2231
2233 """ Collect the decay widths and calculate BRs for all particles, and put
2234 in param_card form.
2235 """
2236
2237 particle_dict = {}
2238 run_name = self.run_name
2239
2240
2241 for P_path in SubProcesses.get_subP(self.me_dir):
2242 ids = SubProcesses.get_subP_ids(P_path)
2243
2244
2245
2246 nb_output = len(ids) / (len(set([p[0] for p in ids])))
2247 results = open(pjoin(P_path, run_name + '_results.dat')).read().split('\n')[0]
2248 result = float(results.strip().split(' ')[0])
2249 for particles in ids:
2250 try:
2251 particle_dict[particles[0]].append([particles[1:], result/nb_output])
2252 except KeyError:
2253 particle_dict[particles[0]] = [[particles[1:], result/nb_output]]
2254
2255 self.update_width_in_param_card(particle_dict,
2256 initial = pjoin(self.me_dir, 'Cards', 'param_card.dat'),
2257 output=pjoin(self.me_dir, 'Events', run_name, "param_card.dat"))
2258
2259 @staticmethod
2261
2262
2263 if not output:
2264 output = initial
2265
2266 param_card_file = open(initial)
2267 param_card = param_card_file.read().split('\n')
2268 param_card_file.close()
2269
2270 decay_lines = []
2271 line_number = 0
2272
2273 while line_number < len(param_card):
2274 line = param_card[line_number]
2275 if line.lower().startswith('decay'):
2276
2277
2278 line = param_card.pop(line_number)
2279 line = line.split()
2280 particle = 0
2281 if int(line[1]) not in decay_info:
2282 try:
2283 particle = int(line[1])
2284 width = float(line[2])
2285 except Exception:
2286 particle = 0
2287
2288 line = param_card[line_number]
2289 while line.startswith('#') or line.startswith(' '):
2290 line = param_card.pop(line_number)
2291 if not particle or line.startswith('#'):
2292 line=param_card[line_number]
2293 continue
2294
2295 line = line.split()
2296 try:
2297 partial_width = float(line[0])*width
2298 decay_products = [int(p) for p in line[2:2+int(line[1])]]
2299 except Exception:
2300 line=param_card[line_number]
2301 continue
2302 try:
2303 decay_info[particle].append([decay_products, partial_width])
2304 except KeyError:
2305 decay_info[particle] = [[decay_products, partial_width]]
2306 if line_number == len(param_card):
2307 break
2308 line=param_card[line_number]
2309 if particle and particle not in decay_info:
2310
2311 decay_info[particle] = [[[], width]]
2312 else:
2313 line_number += 1
2314
2315 while not param_card[-1] or param_card[-1].startswith('#'):
2316 param_card.pop(-1)
2317
2318
2319 param_card.append("#\n#*************************")
2320 param_card.append("# Decay widths *")
2321 param_card.append("#*************************")
2322 for key in sorted(decay_info.keys()):
2323 width = sum([r for p,r in decay_info[key]])
2324 param_card.append("#\n# PDG Width")
2325 param_card.append("DECAY %i %e" % (key, width.real))
2326 if not width:
2327 continue
2328 if decay_info[key][0][0]:
2329 param_card.append("# BR NDA ID1 ID2 ...")
2330 brs = [[(val[1]/width).real, val[0]] for val in decay_info[key] if val[1]]
2331 for val in sorted(brs, reverse=True):
2332 param_card.append(" %e %i %s # %s" %
2333 (val[0].real, len(val[1]),
2334 " ".join([str(v) for v in val[1]]),
2335 val[0] * width
2336 ))
2337 decay_table = open(output, 'w')
2338 decay_table.write("\n".join(param_card) + "\n")
2339 decay_table.close()
2340 logger.info("Results written to %s" % output)
2341
2342
2343
2345
2346 args = self.split_arg(line)
2347
2348 mode = self.check_multi_run(args)
2349 nb_run = args.pop(0)
2350 if nb_run == 1:
2351 logger.warn("'multi_run 1' command is not optimal. Think of using generate_events instead")
2352 self.ask_run_configuration(mode)
2353
2354 self.check_survey(args, cmd='multi_run')
2355 main_name = self.run_name
2356
2357 path=pjoin(self.me_dir, 'Cards', 'param_card.dat')
2358 self.check_param_card(path, run=False)
2359
2360 param_card_iterator, self.param_card_iterator = self.param_card_iterator, []
2361
2362 crossoversig = 0
2363 inv_sq_err = 0
2364 nb_event = 0
2365 for i in range(nb_run):
2366 self.nb_refine = 0
2367 self.exec_cmd('generate_events %s_%s -f' % (main_name, i), postcmd=False)
2368
2369 nb_event += int(self.results[self.run_name][-1]['nb_event'])
2370 self.results.add_detail('nb_event', nb_event , run=main_name)
2371 cross = self.results[self.run_name][-1]['cross']
2372 error = self.results[self.run_name][-1]['error'] + 1e-99
2373 crossoversig+=cross/error**2
2374 inv_sq_err+=1.0/error**2
2375 self.results[main_name][-1]['cross'] = crossoversig/inv_sq_err
2376 self.results[main_name][-1]['error'] = math.sqrt(1.0/inv_sq_err)
2377 self.results.def_current(main_name)
2378 self.run_name = main_name
2379 self.update_status("Merging LHE files", level='parton')
2380 try:
2381 os.mkdir(pjoin(self.me_dir,'Events', self.run_name))
2382 except Exception:
2383 pass
2384 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'
2385 % {'bin': self.dirbin, 'event': pjoin(self.me_dir,'Events'),
2386 'name': self.run_name})
2387
2388 eradir = self.options['exrootanalysis_path']
2389 if eradir and misc.is_executable(pjoin(eradir,'ExRootLHEFConverter')):
2390 self.update_status("Create Root file", level='parton')
2391 misc.gunzip('%s/%s/unweighted_events.lhe.gz' %
2392 (pjoin(self.me_dir,'Events'), self.run_name))
2393
2394 self.create_root_file('%s/unweighted_events.lhe' % self.run_name,
2395 '%s/unweighted_events.root' % self.run_name)
2396
2397 path = pjoin(self.me_dir, "Events", self.run_name, "unweighted_events.lhe")
2398 self.create_plot('parton', path,
2399 pjoin(self.me_dir, 'HTML',self.run_name, 'plots_parton.html')
2400 )
2401
2402
2403 if not os.path.exists('%s.gz' % path):
2404 misc.gzip(path)
2405
2406 self.update_status('', level='parton')
2407 self.print_results_in_shell(self.results.current)
2408
2409 if param_card_iterator:
2410
2411 param_card_iterator.store_entry(self.run_name, self.results.current['cross'])
2412
2413 orig_name=self.run_name
2414 for card in param_card_iterator:
2415 card.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2416 self.exec_cmd("multi_run %s -f " % nb_run ,precmd=True, postcmd=True,errorhandling=False)
2417 param_card_iterator.store_entry(self.run_name, self.results.current['cross'])
2418 param_card_iterator.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2419 scan_name = misc.get_scan_name(orig_name, self.run_name)
2420 path = pjoin(self.me_dir, 'Events','scan_%s.txt' % scan_name)
2421 logger.info("write all cross-section results in %s" % path, '$MG:color:BLACK')
2422 param_card_iterator.write_summary(path)
2423
2424
2425
2427 """Advanced commands: create .inc files from param_card.dat/run_card.dat"""
2428
2429 if not mode and not opt:
2430 args = self.split_arg(line)
2431 mode, opt = self.check_treatcards(args)
2432
2433
2434
2435
2436 need_MadLoopFilterUpdate = False
2437
2438
2439 type_of_change = ''
2440 if not opt['forbid_MadLoopInit'] and self.proc_characteristics['loop_induced'] \
2441 and mode in ['loop', 'all']:
2442 paramDat = pjoin(self.me_dir, 'Cards','param_card.dat')
2443 paramInc = pjoin(opt['output_dir'], 'param_card.inc')
2444 if (not os.path.isfile(paramDat)) or (not os.path.isfile(paramInc)) or \
2445 (os.path.getmtime(paramDat)-os.path.getmtime(paramInc)) > 0.0:
2446 need_MadLoopFilterUpdate = True
2447 type_of_change = 'model'
2448
2449 ML_in = pjoin(self.me_dir, 'Cards', 'MadLoopParams.dat')
2450 ML_out = pjoin(self.me_dir,"SubProcesses",
2451 "MadLoop5_resources", "MadLoopParams.dat")
2452 if (not os.path.isfile(ML_in)) or (not os.path.isfile(ML_out)) or \
2453 (os.path.getmtime(ML_in)-os.path.getmtime(ML_out)) > 0.0:
2454 need_MadLoopFilterUpdate = True
2455 type_of_change = 'MadLoop'
2456
2457
2458 self.check_param_card(pjoin(self.me_dir, 'Cards','param_card.dat'))
2459
2460 if mode in ['param', 'all']:
2461 model = self.find_model_name()
2462 tmp_model = os.path.basename(model)
2463 if tmp_model == 'mssm' or tmp_model.startswith('mssm-'):
2464 if not '--param_card=' in line:
2465 param_card = pjoin(self.me_dir, 'Cards','param_card.dat')
2466 mg5_param = pjoin(self.me_dir, 'Source', 'MODEL', 'MG5_param.dat')
2467 check_param_card.convert_to_mg5card(param_card, mg5_param)
2468 check_param_card.check_valid_param_card(mg5_param)
2469 opt['param_card'] = pjoin(self.me_dir, 'Source', 'MODEL', 'MG5_param.dat')
2470 else:
2471 check_param_card.check_valid_param_card(opt['param_card'])
2472
2473 logger.debug('write compile file for card: %s' % opt['param_card'])
2474 param_card = check_param_card.ParamCard(opt['param_card'])
2475 outfile = pjoin(opt['output_dir'], 'param_card.inc')
2476 ident_card = pjoin(self.me_dir,'Cards','ident_card.dat')
2477 if os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')):
2478 default = pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')
2479 elif os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')):
2480 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
2481 elif not os.path.exists(pjoin(self.me_dir,'bin','internal','ufomodel')):
2482 fsock = open(pjoin(self.me_dir,'Source','param_card.inc'),'w')
2483 fsock.write(' ')
2484 fsock.close()
2485 if mode == 'all':
2486 self.do_treatcards('', 'run', opt)
2487 return
2488 else:
2489 devnull = open(os.devnull,'w')
2490 subprocess.call([sys.executable, 'write_param_card.py'],
2491 cwd=pjoin(self.me_dir,'bin','internal','ufomodel'),
2492 stdout=devnull)
2493 devnull.close()
2494 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
2495
2496 need_mp = self.proc_characteristics['loop_induced']
2497 param_card.write_inc_file(outfile, ident_card, default, need_mp=need_mp)
2498
2499
2500 if mode in ['run', 'all']:
2501 if not hasattr(self, 'run_card'):
2502 run_card = banner_mod.RunCard(opt['run_card'])
2503 else:
2504 run_card = self.run_card
2505 if self.ninitial == 1:
2506 run_card['lpp1'] = 0
2507 run_card['lpp2'] = 0
2508 run_card['ebeam1'] = 0
2509 run_card['ebeam2'] = 0
2510
2511 run_card.write_include_file(pjoin(opt['output_dir'],'run_card.inc'))
2512
2513
2514 if self.proc_characteristics['loop_induced'] and mode in ['loop', 'all']:
2515 self.MadLoopparam = banner_mod.MadLoopParam(pjoin(self.me_dir,
2516 'Cards', 'MadLoopParams.dat'))
2517
2518
2519
2520
2521 if 'WriteOutFilters' in self.MadLoopparam.user_set and \
2522 self.MadLoopparam.get('WriteOutFilters'):
2523 logger.info(
2524 """You chose to have MadLoop writing out filters.
2525 Beware that this can be dangerous for local multicore runs.""")
2526 self.MadLoopparam.set('WriteOutFilters',False, ifnotdefault=False)
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547 self.MadLoopparam.set('HelicityFilterLevel',1, ifnotdefault=False)
2548
2549
2550
2551 self.MadLoopparam.set('CheckCycle',4, ifnotdefault=False)
2552
2553
2554
2555
2556
2557 self.MadLoopparam.set('DoubleCheckHelicityFilter',False,
2558 ifnotdefault=False)
2559
2560
2561
2562 if not hasattr(self, 'run_card'):
2563 run_card = banner_mod.RunCard(opt['run_card'])
2564 else:
2565 run_card = self.run_card
2566 if run_card['nhel'] == 0:
2567 if 'MLReductionLib' in self.MadLoopparam.user_set and \
2568 (self.MadLoopparam.get('MLReductionLib').startswith('1') or
2569 self.MadLoopparam.get('MLReductionLib').startswith('6')):
2570 logger.warning(
2571 """You chose to set the preferred reduction technique in MadLoop to be OPP (see parameter MLReductionLib).
2572 Beware that this can bring significant slowdown; the optimal choice --when not MC over helicity-- being to first start with TIR reduction.""")
2573
2574 self.MadLoopparam.set('MLReductionLib','2|6|1', ifnotdefault=False)
2575 else:
2576 if 'MLReductionLib' in self.MadLoopparam.user_set and \
2577 not (self.MadLoopparam.get('MLReductionLib').startswith('1') or
2578 self.MadLoopparam.get('MLReductionLib').startswith('6')):
2579 logger.warning(
2580 """You chose to set the preferred reduction technique in MadLoop to be different than OPP (see parameter MLReductionLib).
2581 Beware that this can bring significant slowdown; the optimal choice --when MC over helicity-- being to first start with OPP reduction.""")
2582 self.MadLoopparam.set('MLReductionLib','6|1|2', ifnotdefault=False)
2583
2584
2585
2586
2587
2588 if run_card['nhel'] == 0:
2589 if ('NRotations_DP' in self.MadLoopparam.user_set and \
2590 self.MadLoopparam.get('NRotations_DP')!=0) or \
2591 ('NRotations_QP' in self.MadLoopparam.user_set and \
2592 self.MadLoopparam.get('NRotations_QP')!=0):
2593 logger.warning(
2594 """You chose to also use a lorentz rotation for stability tests (see parameter NRotations_[DP|QP]).
2595 Beware that, for optimization purposes, MadEvent uses manual TIR cache clearing which is not compatible
2596 with the lorentz rotation stability test. The number of these rotations to be used will be reset to
2597 zero by MadLoop. You can avoid this by changing the parameter 'FORCE_ML_HELICITY_SUM' int he matrix<i>.f
2598 files to be .TRUE. so that the sum over helicity configurations is performed within MadLoop (in which case
2599 the helicity of final state particles cannot be speicfied in the LHE file.""")
2600 self.MadLoopparam.set('NRotations_DP',0,ifnotdefault=False)
2601 self.MadLoopparam.set('NRotations_QP',0,ifnotdefault=False)
2602 else:
2603
2604
2605
2606
2607
2608
2609 self.MadLoopparam.set('NRotations_DP',1,ifnotdefault=False)
2610 self.MadLoopparam.set('NRotations_QP',0,ifnotdefault=False)
2611
2612
2613
2614
2615
2616
2617
2618
2619 if self.proc_characteristics['nexternal']<=4:
2620 if ('MLStabThres' in self.MadLoopparam.user_set and \
2621 self.MadLoopparam.get('MLStabThres')>1.0e-7):
2622 logger.warning(
2623 """You chose to increase the default value of the MadLoop parameter 'MLStabThres' above 1.0e-7.
2624 Stability tests can be less reliable on the limited kinematic of processes with less or equal
2625 than four external legs, so this is not recommended (especially not for g g > z z).""")
2626 self.MadLoopparam.set('MLStabThres',1.0e-7,ifnotdefault=False)
2627 else:
2628 self.MadLoopparam.set('MLStabThres',1.0e-4,ifnotdefault=False)
2629
2630
2631 self.MadLoopparam.write(pjoin(self.me_dir,"SubProcesses","MadLoop5_resources",
2632 "MadLoopParams.dat"))
2633
2634 if self.proc_characteristics['loop_induced'] and mode in ['loop', 'all']:
2635
2636
2637 if need_MadLoopFilterUpdate:
2638 logger.debug('Changes to the %s parameters'%type_of_change+\
2639 ' have been detected. Madevent will then now reinitialize'+\
2640 ' MadLoop filters.')
2641 self.exec_cmd('initMadLoop -r -f')
2642
2643
2644
2645
2646
2647 elif not opt['forbid_MadLoopInit'] and \
2648 MadLoopInitializer.need_MadLoopInit(self.me_dir):
2649 self.exec_cmd('initMadLoop -f')
2650
2651
2653 """Advanced commands: launch survey for the current process """
2654
2655
2656 args = self.split_arg(line)
2657
2658 self.check_survey(args)
2659
2660
2661 if os.path.exists(pjoin(self.me_dir,'error')):
2662 os.remove(pjoin(self.me_dir,'error'))
2663
2664 self.configure_directory()
2665
2666 self.random_orig = self.random
2667 logger.info("Using random number seed offset = %s" % self.random)
2668
2669 self.update_random()
2670 self.save_random()
2671 self.update_status('Running Survey', level=None)
2672 if self.cluster_mode:
2673 logger.info('Creating Jobs')
2674
2675 self.total_jobs = 0
2676 subproc = [l.strip() for l in open(pjoin(self.me_dir,
2677 'SubProcesses', 'subproc.mg'))]
2678
2679 P_zero_result = []
2680
2681
2682 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
2683 'MadLoop5_resources')) and cluster.need_transfer(self.options):
2684 tf=tarfile.open(pjoin(self.me_dir, 'SubProcesses',
2685 'MadLoop5_resources.tar.gz'), 'w:gz', dereference=True)
2686 tf.add(pjoin(self.me_dir,'SubProcesses','MadLoop5_resources'),
2687 arcname='MadLoop5_resources')
2688 tf.close()
2689
2690 logger.info('Working on SubProcesses')
2691 ajobcreator = gen_ximprove.gensym(self)
2692
2693
2694 if float(self.run_card['mmjj']) > 0.01 * (float(self.run_card['ebeam1'])+float(self.run_card['ebeam2'])):
2695 self.pass_in_difficult_integration_mode()
2696
2697 jobs, P_zero_result = ajobcreator.launch()
2698
2699
2700 if P_zero_result:
2701 if len(P_zero_result) == len(subproc):
2702 Pdir = pjoin(self.me_dir, 'SubProcesses',subproc[0].strip())
2703 raise ZeroResult, '%s' % \
2704 open(pjoin(Pdir,'ajob.no_ps.log')).read()
2705 else:
2706 logger.warning(''' %s SubProcesses doesn\'t have available phase-space.
2707 Please check mass spectrum.''' % ','.join(P_zero_result))
2708
2709
2710 self.monitor(run_type='All jobs submitted for survey', html=True)
2711 if not self.history or 'survey' in self.history[-1] or self.ninitial ==1 or \
2712 self.run_card['gridpack']:
2713
2714 cross, error = sum_html.make_all_html_results(self)
2715 self.results.add_detail('cross', cross)
2716 self.results.add_detail('error', error)
2717 self.exec_cmd("print_results %s" % self.run_name,
2718 errorhandling=False, printcmd=False, precmd=False, postcmd=False)
2719
2720 self.results.add_detail('run_statistics', dict(ajobcreator.run_statistics))
2721 self.update_status('End survey', 'parton', makehtml=False)
2722
2723
2725 """be more secure for the integration to not miss it due to strong cut"""
2726
2727
2728 if self.opts['points'] == self._survey_options['points'][1]:
2729 self.opts['points'] = 2 * self._survey_options['points'][1]
2730 if self.opts['iterations'] == self._survey_options['iterations'][1]:
2731 self.opts['iterations'] = 1 + self._survey_options['iterations'][1]
2732 if self.opts['accuracy'] == self._survey_options['accuracy'][1]:
2733 self.opts['accuracy'] = self._survey_options['accuracy'][1]/2
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747 for name in ['../bin/internal/gen_ximprove', 'all',
2748 '../bin/internal/combine_events']:
2749 self.compile(arg=[name], cwd=os.path.join(self.me_dir, 'Source'))
2750
2751
2752
2754 """Advanced commands: launch survey for the current process """
2755 devnull = open(os.devnull, 'w')
2756 self.nb_refine += 1
2757 args = self.split_arg(line)
2758
2759 self.check_refine(args)
2760
2761 refine_opt = {'err_goal': args[0], 'split_channels': True}
2762 precision = args[0]
2763 if len(args) == 2:
2764 refine_opt['max_process']= args[1]
2765
2766
2767
2768 self.configure_directory()
2769
2770
2771 self.update_random()
2772 self.save_random()
2773
2774 if self.cluster_mode:
2775 logger.info('Creating Jobs')
2776 self.update_status('Refine results to %s' % precision, level=None)
2777
2778 self.total_jobs = 0
2779 subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses',
2780 'subproc.mg'))]
2781
2782
2783 for nb_proc,subdir in enumerate(subproc):
2784 subdir = subdir.strip()
2785 Pdir = pjoin(self.me_dir, 'SubProcesses', subdir)
2786 for match in misc.glob('*ajob*', Pdir):
2787 if os.path.basename(match)[:4] in ['ajob', 'wait', 'run.', 'done']:
2788 os.remove(match)
2789
2790 x_improve = gen_ximprove.gen_ximprove(self, refine_opt)
2791
2792 survey_statistics = dict(self.results.get_detail('run_statistics'))
2793
2794 if __debug__ and survey_statistics:
2795 globalstat = sum_html.RunStatistics()
2796 logger.debug(" === Survey statistics summary ===")
2797 for key, value in survey_statistics.items():
2798 globalstat.aggregate_statistics(value)
2799 level = 5
2800 if value.has_warning():
2801 level = 10
2802 logger.log(level,
2803 value.nice_output(str('/'.join([key[0],'G%s'%key[1]]))).
2804 replace(' statistics',''))
2805 logger.debug(globalstat.nice_output('combined', no_warning=True))
2806
2807 if survey_statistics:
2808 x_improve.run_statistics = survey_statistics
2809
2810 x_improve.launch()
2811 if not self.history or 'refine' not in self.history[-1]:
2812 cross, error = x_improve.update_html()
2813 if cross == 0:
2814 return
2815 logger.info("Current estimate of cross-section: %s +- %s" % (cross, error))
2816
2817
2818 if isinstance(x_improve, gen_ximprove.gen_ximprove_v4):
2819
2820
2821 for nb_proc,subdir in enumerate(subproc):
2822 subdir = subdir.strip()
2823 Pdir = pjoin(self.me_dir, 'SubProcesses',subdir)
2824 bindir = pjoin(os.path.relpath(self.dirbin, Pdir))
2825
2826 logger.info(' %s ' % subdir)
2827
2828 if os.path.exists(pjoin(Pdir, 'ajob1')):
2829 self.compile(['madevent'], cwd=Pdir)
2830
2831 alljobs = misc.glob('ajob*', Pdir)
2832
2833
2834 Gre = re.compile("\s*j=(G[\d\.\w]+)")
2835 for job in alljobs:
2836 Gdirs = Gre.findall(open(job).read())
2837 for Gdir in Gdirs:
2838 if os.path.exists(pjoin(Pdir, Gdir, 'results.dat')):
2839 os.remove(pjoin(Pdir, Gdir,'results.dat'))
2840
2841 nb_tot = len(alljobs)
2842 self.total_jobs += nb_tot
2843 for i, job in enumerate(alljobs):
2844 job = os.path.basename(job)
2845 self.launch_job('%s' % job, cwd=Pdir, remaining=(nb_tot-i-1),
2846 run_type='Refine number %s on %s (%s/%s)' %
2847 (self.nb_refine, subdir, nb_proc+1, len(subproc)))
2848
2849 self.monitor(run_type='All job submitted for refine number %s' % self.nb_refine,
2850 html=True)
2851
2852 self.update_status("Combining runs", level='parton')
2853 try:
2854 os.remove(pjoin(Pdir, 'combine_runs.log'))
2855 except Exception:
2856 pass
2857
2858 if isinstance(x_improve, gen_ximprove.gen_ximprove_v4):
2859
2860
2861 combine_runs.CombineRuns(self.me_dir)
2862 self.refine_mode = "old"
2863 else:
2864 self.refine_mode = "new"
2865
2866 cross, error = sum_html.make_all_html_results(self)
2867 self.results.add_detail('cross', cross)
2868 self.results.add_detail('error', error)
2869
2870 self.results.add_detail('run_statistics',
2871 dict(self.results.get_detail('run_statistics')))
2872
2873 self.update_status('finish refine', 'parton', makehtml=False)
2874 devnull.close()
2875
2876
2878 """Not in help: Combine a given iteration combine_iteration Pdir Gdir S|R step
2879 S is for survey
2880 R is for refine
2881 step is the iteration number (not very critical)"""
2882
2883 self.set_run_name("tmp")
2884 self.configure_directory(html_opening=False)
2885 Pdir, Gdir, mode, step = self.split_arg(line)
2886 if Gdir.startswith("G"):
2887 Gdir = Gdir[1:]
2888 if "SubProcesses" not in Pdir:
2889 Pdir = pjoin(self.me_dir, "SubProcesses", Pdir)
2890 if mode == "S":
2891 self.opts = dict([(key,value[1]) for (key,value) in \
2892 self._survey_options.items()])
2893 gensym = gen_ximprove.gensym(self)
2894 gensym.combine_iteration(Pdir, Gdir, int(step))
2895 elif mode == "R":
2896 refine = gen_ximprove.gen_ximprove_share(self)
2897 refine.combine_iteration(Pdir, Gdir, int(step))
2898
2899
2900
2901
2902
2904 """Advanced commands: Launch combine events"""
2905
2906 args = self.split_arg(line)
2907
2908 self.check_combine_events(args)
2909
2910 self.update_status('Combining Events', level='parton')
2911
2912
2913 if False:
2914 try:
2915 os.remove(pjoin(self.me_dir,'SubProcesses', 'combine.log'))
2916 except Exception:
2917 pass
2918
2919 cluster.onecore.launch_and_wait('../bin/internal/run_combine',
2920 args=[self.run_name],
2921 cwd=pjoin(self.me_dir,'SubProcesses'),
2922 stdout=pjoin(self.me_dir,'SubProcesses', 'combine.log'),
2923 required_output=[pjoin(self.me_dir,'SubProcesses', 'combine.log')])
2924
2925
2926
2927
2928
2929
2930 output = misc.mult_try_open(pjoin(self.me_dir,'SubProcesses','combine.log')).read()
2931
2932 pat = re.compile(r'''\s*Unweighting\s*selected\s*(\d+)\s*events''')
2933 try:
2934 nb_event = pat.search(output).groups()[0]
2935 except AttributeError:
2936 time.sleep(10)
2937 output = misc.mult_try_open(pjoin(self.me_dir,'SubProcesses','combine.log')).read()
2938 try:
2939 nb_event = pat.search(output).groups()[0]
2940 except AttributeError:
2941 logger.warning('Fail to read the number of unweighted events in the combine.log file')
2942 nb_event = 0
2943
2944 self.results.add_detail('nb_event', nb_event)
2945
2946
2947
2948 tag = self.run_card['run_tag']
2949
2950
2951 if not self.banner:
2952 self.banner = banner_mod.recover_banner(self.results, 'parton')
2953 self.banner.load_basic(self.me_dir)
2954
2955 self.banner.add_generation_info(self.results.current['cross'], nb_event)
2956 if not hasattr(self, 'random_orig'): self.random_orig = 0
2957 self.banner.change_seed(self.random_orig)
2958 if not os.path.exists(pjoin(self.me_dir, 'Events', self.run_name)):
2959 os.mkdir(pjoin(self.me_dir, 'Events', self.run_name))
2960 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name,
2961 '%s_%s_banner.txt' % (self.run_name, tag)))
2962
2963
2964 self.banner.add_to_file(pjoin(self.me_dir,'Events', 'events.lhe'),
2965 out=pjoin(self.me_dir,'Events', self.run_name, 'events.lhe'))
2966 self.banner.add_to_file(pjoin(self.me_dir,'Events', 'unweighted_events.lhe'),
2967 out=pjoin(self.me_dir,'Events', self.run_name, 'unweighted_events.lhe'))
2968
2969
2970 elif True:
2971
2972 tag = self.run_card['run_tag']
2973
2974 if not self.banner:
2975 self.banner = banner_mod.recover_banner(self.results, 'parton')
2976 self.banner.load_basic(self.me_dir)
2977
2978 self.banner.add_generation_info(self.results.current['cross'], self.run_card['nevents'])
2979 if not hasattr(self, 'random_orig'): self.random_orig = 0
2980 self.banner.change_seed(self.random_orig)
2981 if not os.path.exists(pjoin(self.me_dir, 'Events', self.run_name)):
2982 os.mkdir(pjoin(self.me_dir, 'Events', self.run_name))
2983 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name,
2984 '%s_%s_banner.txt' % (self.run_name, tag)))
2985
2986
2987 get_wgt = lambda event: event.wgt
2988 AllEvent = lhe_parser.MultiEventFile()
2989 AllEvent.banner = self.banner
2990
2991 partials = 0
2992 sum_xsec, sum_xerru, sum_axsec = 0,[],0
2993 for Gdir,mfactor in self.get_Gdir():
2994 if os.path.exists(pjoin(Gdir, 'events.lhe')):
2995 result = sum_html.OneResult('')
2996 result.read_results(pjoin(Gdir, 'results.dat'))
2997 AllEvent.add(pjoin(Gdir, 'events.lhe'),
2998 result.get('xsec'),
2999 result.get('xerru'),
3000 result.get('axsec')
3001 )
3002 sum_xsec += result.get('xsec')
3003 sum_xerru.append(result.get('xerru'))
3004 sum_axsec += result.get('axsec')
3005
3006 if len(AllEvent) >= 80:
3007 AllEvent.unweight(pjoin(self.me_dir, "Events", self.run_name, "partials%s.lhe.gz" % partials),
3008 get_wgt, log_level=logging.DEBUG, write_init=True)
3009 AllEvent = lhe_parser.MultiEventFile()
3010 AllEvent.banner = self.banner
3011 AllEvent.add(pjoin(self.me_dir, "Events", self.run_name, "partials%s.lhe.gz" % partials),
3012 sum_xsec,
3013 math.sqrt(sum(x**2 for x in sum_xerru)),
3014 sum_axsec)
3015 partials +=1
3016
3017 nb_event = AllEvent.unweight(pjoin(self.me_dir, "Events", self.run_name, "unweighted_events.lhe.gz"),
3018 get_wgt, trunc_error=1e-2, event_target=self.run_card['nevents'],
3019 log_level=logging.DEBUG)
3020
3021 if partials:
3022 misc.sprint("used partials")
3023 for i in range(partials):
3024 os.remove(pjoin(self.me_dir, "Events", self.run_name, "partials%s.lhe.gz" % i))
3025
3026 self.results.add_detail('nb_event', nb_event)
3027
3028 self.to_store.append('event')
3029 eradir = self.options['exrootanalysis_path']
3030 madir = self.options['madanalysis_path']
3031 td = self.options['td_path']
3032 if eradir and misc.is_executable(pjoin(eradir,'ExRootLHEFConverter')) and\
3033 os.path.exists(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe')):
3034 if not os.path.exists(pjoin(self.me_dir, 'Events', self.run_name)):
3035 os.mkdir(pjoin(self.me_dir, 'Events', self.run_name))
3036 self.create_root_file(output='%s/unweighted_events.root' % \
3037 self.run_name)
3038
3039
3041 """Advanced commands: Launch store events"""
3042
3043 args = self.split_arg(line)
3044
3045 self.check_combine_events(args)
3046 self.update_status('Storing parton level results', level='parton')
3047
3048 run = self.run_name
3049 tag = self.run_card['run_tag']
3050 devnull = open(os.devnull, 'w')
3051
3052 if not os.path.exists(pjoin(self.me_dir, 'Events', run)):
3053 os.mkdir(pjoin(self.me_dir, 'Events', run))
3054 if not os.path.exists(pjoin(self.me_dir, 'HTML', run)):
3055 os.mkdir(pjoin(self.me_dir, 'HTML', run))
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065 if self.results.current['nb_event'] == 0:
3066 logger.warning("No event detected. No cleaning performed! This should allow to run:\n" +
3067 " cd Subprocesses; ../bin/internal/combine_events\n"+
3068 " to have your events if those one are missing.")
3069 else:
3070 for P_path in SubProcesses.get_subP(self.me_dir):
3071 G_dir = [G for G in os.listdir(P_path) if G.startswith('G') and
3072 os.path.isdir(pjoin(P_path,G))]
3073 for G in G_dir:
3074 G_path = pjoin(P_path,G)
3075 try:
3076
3077 if os.path.exists(pjoin(G_path, 'events.lhe')):
3078 os.remove(pjoin(G_path, 'events.lhe'))
3079 except Exception:
3080 continue
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090 try:
3091 if os.path.exists(pjoin(G_path, 'log.txt')):
3092 input = pjoin(G_path, 'log.txt')
3093 output = pjoin(G_path, '%s_log.txt' % run)
3094 files.mv(input, output)
3095 except Exception:
3096 continue
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110 if os.path.exists(pjoin(G_path, 'ftn25')):
3111 os.remove(pjoin(G_path, 'ftn25'))
3112
3113
3114 misc.call(['%s/gen_cardhtml-pl' % self.dirbin],
3115 cwd=pjoin(self.me_dir))
3116
3117
3118
3119 E_path = pjoin(self.me_dir, 'Events')
3120 O_path = pjoin(self.me_dir, 'Events', run)
3121
3122
3123 for name in ['events.lhe', 'unweighted_events.lhe']:
3124 finput = pjoin(E_path, name)
3125 foutput = pjoin(O_path, name)
3126 if os.path.exists(finput):
3127 logger.debug("File %s exists BAAAAD. Not move anymore!" % pjoin(E_path, name))
3128 if os.path.exists(foutput):
3129 misc.gzip(foutput, stdout="%s.gz" % foutput, error=False)
3130
3131
3132
3133
3134
3135
3136 self.update_status('End Parton', level='parton', makehtml=False)
3137 devnull.close()
3138
3139
3140
3142 """Advanced commands: Create gridpack from present run"""
3143
3144 self.update_status('Creating gridpack', level='parton')
3145
3146 misc.compile(['../bin/internal/gen_ximprove'], cwd=pjoin(self.me_dir, "Source"))
3147 args = self.split_arg(line)
3148 self.check_combine_events(args)
3149 if not self.run_tag: self.run_tag = 'tag_1'
3150 os.system("sed -i.bak \"s/ *.false.*=.*GridRun/ .true. = GridRun/g\" %s/Cards/grid_card.dat" \
3151 % self.me_dir)
3152 misc.call(['./bin/internal/restore_data', self.run_name],
3153 cwd=self.me_dir)
3154 misc.call(['./bin/internal/store4grid',
3155 self.run_name, self.run_tag],
3156 cwd=self.me_dir)
3157 misc.call(['./bin/internal/clean'], cwd=self.me_dir)
3158 misc.call(['./bin/internal/make_gridpack'], cwd=self.me_dir)
3159 files.mv(pjoin(self.me_dir, 'gridpack.tar.gz'),
3160 pjoin(self.me_dir, '%s_gridpack.tar.gz' % self.run_name))
3161 os.system("sed -i.bak \"s/\s*.true.*=.*GridRun/ .false. = GridRun/g\" %s/Cards/grid_card.dat" \
3162 % self.me_dir)
3163 self.update_status('gridpack created', level='gridpack')
3164
3165
3167 """launch pythia"""
3168
3169
3170 args = self.split_arg(line)
3171 if '--no_default' in args:
3172 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pythia_card.dat')):
3173 return
3174 no_default = True
3175 args.remove('--no_default')
3176 else:
3177 no_default = False
3178
3179 if not self.run_name:
3180 self.check_pythia(args)
3181 self.configure_directory(html_opening =False)
3182 else:
3183
3184 self.configure_directory(html_opening =False)
3185 self.check_pythia(args)
3186
3187
3188
3189 if not no_default:
3190 self.ask_pythia_run_configuration(args[-1])
3191
3192 if self.options['automatic_html_opening']:
3193 misc.open_file(os.path.join(self.me_dir, 'crossx.html'))
3194 self.options['automatic_html_opening'] = False
3195
3196
3197 if not self.banner or len(self.banner) <=1:
3198 self.banner = banner_mod.recover_banner(self.results, 'pythia')
3199
3200
3201
3202 pythia_src = pjoin(self.options['pythia-pgs_path'],'src')
3203
3204 self.update_status('Running Pythia', 'pythia')
3205 try:
3206 os.remove(pjoin(self.me_dir,'Events','pythia.done'))
3207 except Exception:
3208 pass
3209
3210
3211
3212 if not re.search(r'^\s*LHAPATH=%s/PDFsets' % pythia_src,
3213 open(pjoin(self.me_dir,'Cards','pythia_card.dat')).read(),
3214 re.M):
3215 f = open(pjoin(self.me_dir,'Cards','pythia_card.dat'),'a')
3216 f.write('\n LHAPATH=%s/PDFsets' % pythia_src)
3217 f.close()
3218 tag = self.run_tag
3219 pythia_log = pjoin(self.me_dir, 'Events', self.run_name , '%s_pythia.log' % tag)
3220 self.cluster.launch_and_wait('../bin/internal/run_pythia',
3221 argument= [pythia_src], stdout= pythia_log,
3222 stderr=subprocess.STDOUT,
3223 cwd=pjoin(self.me_dir,'Events'))
3224
3225 os.remove(pjoin(self.me_dir, "Events", "unweighted_events.lhe"))
3226
3227
3228
3229 if not os.path.exists(pjoin(self.me_dir,'Events','pythia.done')):
3230 logger.warning('Fail to produce pythia output. More info in \n %s' % pythia_log)
3231 return
3232 else:
3233 os.remove(pjoin(self.me_dir,'Events','pythia.done'))
3234
3235 self.to_store.append('pythia')
3236
3237
3238 if int(self.run_card['ickkw']):
3239
3240 pythia_log = misc.BackRead(pjoin(self.me_dir,'Events', self.run_name,
3241 '%s_pythia.log' % tag))
3242 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")
3243 for line in pythia_log:
3244 info = pythiare.search(line)
3245 if not info:
3246 continue
3247 try:
3248
3249 sigma_m = float(info.group('xsec').replace('D','E')) *1e9
3250 Nacc = int(info.group('generated'))
3251 Ntry = int(info.group('tried'))
3252 except ValueError:
3253
3254 self.results.add_detail('cross_pythia', 0)
3255 self.results.add_detail('nb_event_pythia', 0)
3256 self.results.add_detail('error_pythia', 0)
3257 else:
3258 self.results.add_detail('cross_pythia', sigma_m)
3259 self.results.add_detail('nb_event_pythia', Nacc)
3260
3261 error = self.results[self.run_name].return_tag(self.run_tag)['error']
3262 if Nacc:
3263 error_m = math.sqrt((error * Nacc/Ntry)**2 + sigma_m**2 *(1-Nacc/Ntry)/Nacc)
3264 else:
3265 error_m = 10000 * sigma_m
3266
3267 self.results.add_detail('error_pythia', error_m)
3268 break
3269
3270 pythia_log.close()
3271
3272 pydir = pjoin(self.options['pythia-pgs_path'], 'src')
3273 eradir = self.options['exrootanalysis_path']
3274 madir = self.options['madanalysis_path']
3275 td = self.options['td_path']
3276
3277
3278
3279
3280
3281 self.banner.add(pjoin(self.me_dir, 'Cards','pythia_card.dat'))
3282 if int(self.run_card['ickkw']):
3283
3284 if 'MGGenerationInfo' in self.banner:
3285 self.banner['MGGenerationInfo'] += '# Matched Integrated weight (pb) : %s\n' % self.results.current['cross_pythia']
3286 else:
3287 self.banner['MGGenerationInfo'] = '# Matched Integrated weight (pb) : %s\n' % self.results.current['cross_pythia']
3288 banner_path = pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, tag))
3289 self.banner.write(banner_path)
3290
3291
3292 self.run_hep2lhe(banner_path)
3293 if int(self.run_card['ickkw']):
3294 misc.gzip(pjoin(self.me_dir,'Events','beforeveto.tree'),
3295 stdout=pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_beforeveto.tree.gz'))
3296 if self.run_card['use_syst'] in self.true:
3297
3298 try:
3299 self.run_syscalc('Pythia')
3300 except SysCalcError, error:
3301 logger.error(str(error))
3302 else:
3303 if os.path.exists(pjoin(self.me_dir,'Events', 'syst.dat')):
3304
3305 misc.gzip(pjoin(self.me_dir,'Events', 'syst.dat'),
3306 stdout=pjoin(self.me_dir,'Events',self.run_name, tag + '_pythia_syst.dat.gz'))
3307
3308
3309 if os.path.exists(pjoin(self.me_dir, 'Events', 'syscalc.dat')):
3310 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
3311 '%s_syscalc.dat' % self.run_tag)
3312 misc.gzip(pjoin(self.me_dir, 'Events','syscalc.dat'),
3313 stdout = "%s.gz" % filename)
3314
3315
3316 self.create_plot('Pythia')
3317
3318 if os.path.exists(pjoin(self.me_dir,'Events','pythia_events.lhe')):
3319 misc.gzip(pjoin(self.me_dir,'Events','pythia_events.lhe'),
3320 stdout=pjoin(self.me_dir,'Events', self.run_name,'%s_pythia_events.lhe.gz' % tag))
3321
3322 self.update_status('finish', level='pythia', makehtml=False)
3323 self.exec_cmd('pgs --no_default', postcmd=False, printcmd=False)
3324 if self.options['delphes_path']:
3325 self.exec_cmd('delphes --no_default', postcmd=False, printcmd=False)
3326 self.print_results_in_shell(self.results.current)
3327
3328
3329
3331 """Remove one/all run or only part of it"""
3332
3333 args = self.split_arg(line)
3334 run, tag, mode = self.check_remove(args)
3335 if 'banner' in mode:
3336 mode.append('all')
3337
3338
3339 if run == 'all':
3340
3341 if os.path.exists(pjoin(self.me_dir, 'Events', 'all')):
3342 logger.warning('A run with name all exists. So we will not supress all processes.')
3343 else:
3344 for match in misc.glob(pjoin('*','*_banner.txt'), pjoin(self.me_dir, 'Events')):
3345 run = match.rsplit(os.path.sep,2)[1]
3346 if self.force:
3347 args.append('-f')
3348 try:
3349 self.exec_cmd('remove %s %s' % (run, ' '.join(args[1:]) ) )
3350 except self.InvalidCmd, error:
3351 logger.info(error)
3352 pass
3353 return
3354
3355
3356 if not os.path.exists(pjoin(self.me_dir, 'Events', run)):
3357 raise self.InvalidCmd('No run \'%s\' detected' % run)
3358
3359 try:
3360 self.resuls.def_current(run)
3361 self.update_status(' Cleaning %s' % run, level=None)
3362 except Exception:
3363 misc.sprint('fail to update results or html status')
3364 pass
3365
3366
3367
3368
3369 to_delete = misc.glob('*', pjoin(self.me_dir, 'Events', run))
3370 to_delete += misc.glob('*', pjoin(self.me_dir, 'HTML', run))
3371
3372 to_delete = [os.path.basename(f) for f in to_delete if 'banner' not in f]
3373 if tag:
3374 to_delete = [f for f in to_delete if tag in f]
3375 if 'parton' in mode or 'all' in mode:
3376 try:
3377 if self.results[run][0]['tag'] != tag:
3378 raise Exception, 'dummy'
3379 except Exception:
3380 pass
3381 else:
3382 nb_rm = len(to_delete)
3383 if os.path.exists(pjoin(self.me_dir, 'Events', run, 'events.lhe.gz')):
3384 to_delete.append('events.lhe.gz')
3385 if os.path.exists(pjoin(self.me_dir, 'Events', run, 'unweighted_events.lhe.gz')):
3386 to_delete.append('unweighted_events.lhe.gz')
3387 if os.path.exists(pjoin(self.me_dir, 'HTML', run,'plots_parton.html')):
3388 to_delete.append(pjoin(self.me_dir, 'HTML', run,'plots_parton.html'))
3389 if nb_rm != len(to_delete):
3390 logger.warning('Be carefull that partonic information are on the point to be removed.')
3391 if 'all' in mode:
3392 pass
3393 else:
3394 if 'pythia' not in mode:
3395 to_delete = [f for f in to_delete if 'pythia' not in f]
3396 if 'pgs' not in mode:
3397 to_delete = [f for f in to_delete if 'pgs' not in f]
3398 if 'delphes' not in mode:
3399 to_delete = [f for f in to_delete if 'delphes' not in f]
3400 if 'parton' not in mode:
3401 to_delete = [f for f in to_delete if 'delphes' in f
3402 or 'pgs' in f
3403 or 'pythia' in f]
3404 if not self.force and len(to_delete):
3405 question = 'Do you want to delete the following files?\n %s' % \
3406 '\n '.join(to_delete)
3407 ans = self.ask(question, 'y', choices=['y','n'])
3408 else:
3409 ans = 'y'
3410
3411 if ans == 'y':
3412 for file2rm in to_delete:
3413 if os.path.exists(pjoin(self.me_dir, 'Events', run, file2rm)):
3414 try:
3415 os.remove(pjoin(self.me_dir, 'Events', run, file2rm))
3416 except Exception:
3417 shutil.rmtree(pjoin(self.me_dir, 'Events', run, file2rm))
3418 else:
3419 try:
3420 os.remove(pjoin(self.me_dir, 'HTML', run, file2rm))
3421 except Exception:
3422 shutil.rmtree(pjoin(self.me_dir, 'HTML', run, file2rm))
3423
3424
3425
3426
3427 if 'all' in mode or 'channel' in mode:
3428 try:
3429 if tag and self.results[run][0]['tag'] != tag:
3430 raise Exception, 'dummy'
3431 except Exception:
3432 pass
3433 else:
3434 to_delete = misc.glob('%s*' % run, pjoin(self.me_dir, 'SubProcesses'))
3435 to_delete += misc.glob(pjoin('*','%s*' % run), pjoin(self.me_dir, 'SubProcesses'))
3436 to_delete += misc.glob(pjoin('*','*','%s*' % run), pjoin(self.me_dir, 'SubProcesses'))
3437
3438 if self.force or len(to_delete) == 0:
3439 ans = 'y'
3440 else:
3441 question = 'Do you want to delete the following files?\n %s' % \
3442 '\n '.join(to_delete)
3443 ans = self.ask(question, 'y', choices=['y','n'])
3444
3445 if ans == 'y':
3446 for file2rm in to_delete:
3447 os.remove(file2rm)
3448
3449 if 'banner' in mode:
3450 to_delete = misc.glob('*', pjoin(self.me_dir, 'Events', run))
3451 if tag:
3452
3453 try:
3454 os.remove(pjoin(self.me_dir, 'Events',run,'%s_%s_banner.txt' % (run,tag)))
3455 except Exception:
3456 logger.warning('fail to remove the banner')
3457
3458 if run in self.results:
3459 self.results.delete_run(run, tag)
3460 return
3461 elif any(['banner' not in os.path.basename(p) for p in to_delete]):
3462 if to_delete:
3463 raise MadGraph5Error, '''Some output still exists for this run.
3464 Please remove those output first. Do for example:
3465 remove %s all banner
3466 ''' % run
3467 else:
3468 shutil.rmtree(pjoin(self.me_dir, 'Events',run))
3469 if run in self.results:
3470 self.results.delete_run(run)
3471 return
3472 else:
3473 logger.info('''The banner is not removed. In order to remove it run:
3474 remove %s all banner %s''' % (run, tag and '--tag=%s ' % tag or ''))
3475
3476
3477 self.results.clean(mode, run, tag)
3478 self.update_status('', level='all')
3479
3480
3481
3482
3484 """Create the plot for a given run"""
3485
3486
3487 self.store_result()
3488 args = self.split_arg(line)
3489
3490 self.check_plot(args)
3491 logger.info('plot for run %s' % self.run_name)
3492 if not self.force:
3493 self.ask_edit_cards([], args, plot=True)
3494
3495 if any([arg in ['all','parton'] for arg in args]):
3496 filename = pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe')
3497 if os.path.exists(filename+'.gz'):
3498 misc.gunzip('%s.gz' % filename, keep=True)
3499 if os.path.exists(filename):
3500 files.ln(filename, pjoin(self.me_dir, 'Events'))
3501 self.create_plot('parton')
3502 if not os.path.exists(filename+'.gz'):
3503 misc.gzip(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'),
3504 stdout= "%s.gz" % filename)
3505 else:
3506 try:
3507 os.remove(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'))
3508 os.remove(filename)
3509 except Exception:
3510 pass
3511 else:
3512 logger.info('No valid files for partonic plot')
3513
3514 if any([arg in ['all','pythia'] for arg in args]):
3515 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
3516 '%s_pythia_events.lhe' % self.run_tag)
3517 if os.path.exists(filename+'.gz'):
3518 misc.gunzip("%s.gz" % filename)
3519 if os.path.exists(filename):
3520 shutil.move(filename, pjoin(self.me_dir, 'Events','pythia_events.lhe'))
3521 self.create_plot('Pythia')
3522 misc.gzip(pjoin(self.me_dir, 'Events','pythia_events.lhe'),
3523 stdout= "%s.gz" % filename)
3524 else:
3525 logger.info('No valid files for pythia plot')
3526
3527
3528 if any([arg in ['all','pgs'] for arg in args]):
3529 filename = pjoin(self.me_dir, 'Events', self.run_name,
3530 '%s_pgs_events.lhco' % self.run_tag)
3531 if os.path.exists(filename+'.gz'):
3532 misc.gunzip("%s.gz" % filename)
3533 if os.path.exists(filename):
3534 self.create_plot('PGS')
3535 misc.gzip(filename)
3536 else:
3537 logger.info('No valid files for pgs plot')
3538
3539 if any([arg in ['all','delphes'] for arg in args]):
3540 filename = pjoin(self.me_dir, 'Events', self.run_name,
3541 '%s_delphes_events.lhco' % self.run_tag)
3542 if os.path.exists(filename+'.gz'):
3543 misc.gunzip("%s.gz" % filename)
3544 if os.path.exists(filename):
3545 self.create_plot('Delphes')
3546 misc.gzip(filename)
3547 else:
3548 logger.info('No valid files for delphes plot')
3549
3550
3552 """Evaluate systematics variation weights for a given run"""
3553
3554
3555 self.store_result()
3556 args = self.split_arg(line)
3557
3558 self.check_syscalc(args)
3559 if self.ninitial == 1:
3560 logger.error('SysCalc can\'t be run for decay processes')
3561 return
3562
3563 logger.info('Calculating systematics for run %s' % self.run_name)
3564
3565 self.ask_edit_cards(['run_card'], args)
3566 self.run_card = banner_mod.RunCard(pjoin(self.me_dir, 'Cards', 'run_card.dat'))
3567
3568 if any([arg in ['all','parton'] for arg in args]):
3569 filename = pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe')
3570 if os.path.exists(filename+'.gz'):
3571 misc.gunzip("%s.gz" % filename)
3572 if os.path.exists(filename):
3573 shutil.move(filename, pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'))
3574 self.run_syscalc('parton')
3575 misc.gzip(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'),
3576 stdout="%s.gz" % filename)
3577 else:
3578 logger.info('No valid files for parton level systematics run.')
3579
3580 if any([arg in ['all','pythia'] for arg in args]):
3581 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
3582 '%s_pythia_syst.dat' % self.run_tag)
3583 if os.path.exists(filename+'.gz'):
3584 misc.gunzip("%s.gz" % filename)
3585 if os.path.exists(filename):
3586 shutil.move(filename, pjoin(self.me_dir, 'Events','syst.dat'))
3587 try:
3588 self.run_syscalc('Pythia')
3589 except SysCalcError, error:
3590 logger.warning(str(error))
3591 return
3592 misc.gzip(pjoin(self.me_dir, 'Events','syst.dat'), "%s.gz" % filename)
3593 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
3594 '%s_syscalc.dat' % self.run_tag)
3595 misc.gzip(pjoin(self.me_dir, 'Events','syscalc.dat'),
3596 stdout=filename)
3597 else:
3598 logger.info('No valid files for pythia level')
3599
3600
3602 """ tar the pythia results. This is done when we are quite sure that
3603 the pythia output will not be use anymore """
3604
3605 if not self.run_name:
3606 return
3607
3608 self.results.save()
3609
3610
3611 if not self.to_store:
3612 return
3613
3614 tag = self.run_card['run_tag']
3615 self.update_status('storring files of previous run', level=None,\
3616 error=True)
3617 if 'event' in self.to_store:
3618 if not os.path.exists(pjoin(self.me_dir, 'Events',self.run_name, 'unweighted_events.lhe.gz')) and\
3619 os.path.exists(pjoin(self.me_dir, 'Events',self.run_name, 'unweighted_events.lhe')):
3620 logger.info("gzipping output file: unweighted_events.lhe")
3621 misc.gzip(pjoin(self.me_dir,'Events',self.run_name,"unweighted_events.lhe"))
3622 if os.path.exists(pjoin(self.me_dir,'Events','reweight.lhe')):
3623 os.remove(pjoin(self.me_dir,'Events', 'reweight.lhe'))
3624
3625 if 'pythia' in self.to_store:
3626 self.update_status('Storing Pythia files of previous run', level='pythia', error=True)
3627
3628 p = pjoin(self.me_dir,'Events')
3629 n = self.run_name
3630 t = tag
3631 misc.gzip(pjoin(p,'pythia_events.hep'),
3632 stdout=pjoin(p,'%s/%s_pythia_events.hep' % (n,t)))
3633
3634 self.to_store.remove('pythia')
3635 self.update_status('Done', level='pythia',makehtml=False,error=True)
3636
3637 self.to_store = []
3638
3639 - def launch_job(self,exe, cwd=None, stdout=None, argument = [], remaining=0,
3640 run_type='', mode=None, **opt):
3641 """ """
3642 argument = [str(arg) for arg in argument]
3643 if mode is None:
3644 mode = self.cluster_mode
3645
3646
3647 if os.path.exists(exe) and not os.access(exe, os.X_OK):
3648 os.system('chmod +x %s ' % exe)
3649 elif (cwd and os.path.exists(pjoin(cwd, exe))) and not \
3650 os.access(pjoin(cwd, exe), os.X_OK):
3651 os.system('chmod +x %s ' % pjoin(cwd, exe))
3652
3653 if mode == 0:
3654 self.update_status((remaining, 1,
3655 self.total_jobs - remaining -1, run_type), level=None, force=False)
3656 start = time.time()
3657
3658 status = misc.call([exe] + argument, cwd=cwd, stdout=stdout, **opt)
3659 logger.info('%s run in %f s' % (exe, time.time() -start))
3660 if status:
3661 raise MadGraph5Error, '%s didn\'t stop properly. Stop all computation' % exe
3662
3663
3664 elif mode in [1,2]:
3665 exename = os.path.basename(exe)
3666
3667 if 'ajob' in exename:
3668 input_files = ['madevent','input_app.txt','symfact.dat','iproc.dat',
3669 pjoin(self.me_dir, 'SubProcesses','randinit')]
3670 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
3671 'MadLoop5_resources.tar.gz')) and cluster.need_transfer(self.options):
3672 input_files.append(pjoin(self.me_dir,'SubProcesses', 'MadLoop5_resources.tar.gz'))
3673
3674 output_files = []
3675 required_output = []
3676
3677
3678
3679 input_files.append(self.get_pdf_input_filename())
3680
3681
3682 Gre = re.compile("\s*j=(G[\d\.\w]+)")
3683 origre = re.compile("grid_directory=(G[\d\.\w]+)")
3684 try :
3685 fsock = open(exe)
3686 except Exception:
3687 fsock = open(pjoin(cwd,exe))
3688 text = fsock.read()
3689 output_files = Gre.findall(text)
3690 if not output_files:
3691 Ire = re.compile("for i in ([\d\.\s]*) ; do")
3692 data = Ire.findall(text)
3693 data = ' '.join(data).split()
3694 for nb in data:
3695 output_files.append('G%s' % nb)
3696 required_output.append('G%s/results.dat' % nb)
3697 else:
3698 for G in output_files:
3699 if os.path.isdir(pjoin(cwd,G)):
3700 input_files.append(G)
3701 required_output.append('%s/results.dat' % G)
3702
3703 if origre.search(text):
3704 G_grid = origre.search(text).groups()[0]
3705 input_files.append(pjoin(G_grid, 'ftn26'))
3706
3707
3708 self.cluster.submit2(exe, stdout=stdout, cwd=cwd,
3709 input_files=input_files, output_files=output_files,
3710 required_output=required_output)
3711 elif 'survey' in exename:
3712 input_files = ['madevent','input_app.txt','symfact.dat','iproc.dat',
3713 pjoin(self.me_dir, 'SubProcesses','randinit')]
3714 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
3715 'MadLoop5_resources.tar.gz')) and cluster.need_transfer(self.options):
3716 input_files.append(pjoin(self.me_dir,'SubProcesses',
3717 'MadLoop5_resources.tar.gz'))
3718
3719
3720 input_files.append(self.get_pdf_input_filename())
3721
3722
3723 output_files = []
3724 required_output = []
3725
3726
3727 suffix = "_%s" % int(float(argument[0]))
3728 if suffix == '_0':
3729 suffix = ''
3730 output_files = ['G%s%s' % (i, suffix) for i in argument[1:]]
3731 for G in output_files:
3732 required_output.append('%s/results.dat' % G)
3733
3734
3735 for G in output_files:
3736 if '.' in argument[0]:
3737 offset = int(str(argument[0]).split('.')[1])
3738 else:
3739 offset = 0
3740
3741 if offset ==0 or offset == int(float(argument[0])):
3742 if os.path.exists(pjoin(cwd, G, 'input_app.txt')):
3743 os.remove(pjoin(cwd, G, 'input_app.txt'))
3744
3745 if os.path.exists(os.path.realpath(pjoin(cwd, G, 'ftn25'))):
3746 if offset == 0 or offset == int(float(argument[0])):
3747 os.remove(pjoin(cwd, G, 'ftn25'))
3748 continue
3749 else:
3750 input_files.append(pjoin(cwd, G, 'ftn25'))
3751 input_files.remove('input_app.txt')
3752 input_files.append(pjoin(cwd, G, 'input_app.txt'))
3753 elif os.path.lexists(pjoin(cwd, G, 'ftn25')):
3754 try:
3755 os.remove(pjoin(cwd,G,'ftn25'))
3756 except:
3757 pass
3758
3759
3760 self.cluster.cluster_submit(exe, stdout=stdout, cwd=cwd, argument=argument,
3761 input_files=input_files, output_files=output_files,
3762 required_output=required_output, **opt)
3763 elif "refine_splitted.sh" in exename:
3764 input_files = ['madevent','symfact.dat','iproc.dat',
3765 pjoin(self.me_dir, 'SubProcesses','randinit')]
3766
3767 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
3768 'MadLoop5_resources.tar.gz')) and cluster.need_transfer(self.options):
3769 input_files.append(pjoin(self.me_dir,'SubProcesses',
3770 'MadLoop5_resources.tar.gz'))
3771
3772
3773 input_files.append(self.get_pdf_input_filename())
3774
3775
3776 output_files = [argument[0]]
3777 required_output = []
3778 for G in output_files:
3779 required_output.append('%s/results.dat' % G)
3780 input_files.append(pjoin(argument[1], "input_app.txt"))
3781 input_files.append(pjoin(argument[1], "ftn26"))
3782
3783
3784 self.cluster.cluster_submit(exe, stdout=stdout, cwd=cwd, argument=argument,
3785 input_files=input_files, output_files=output_files,
3786 required_output=required_output, **opt)
3787
3788
3789
3790 else:
3791 self.cluster.submit(exe, argument=argument, stdout=stdout, cwd=cwd, **opt)
3792
3793
3794
3796 """Find if Madevent is in Group mode or not"""
3797
3798
3799
3800 file_path = pjoin(self.me_dir, 'Source', 'run_config.inc')
3801 text = open(file_path).read()
3802 if re.search(r'''s*parameter\s+\(ChanPerJob=2\)''', text, re.I+re.M):
3803 return 'group'
3804 else:
3805 return 'v4'
3806
3807
3808 - def monitor(self, run_type='monitor', mode=None, html=False):
3809 """ monitor the progress of running job """
3810
3811
3812 starttime = time.time()
3813 if mode is None:
3814 mode = self.cluster_mode
3815 if mode > 0:
3816 if html:
3817 update_status = lambda idle, run, finish: \
3818 self.update_status((idle, run, finish, run_type), level=None,
3819 force=False, starttime=starttime)
3820 update_first = lambda idle, run, finish: \
3821 self.update_status((idle, run, finish, run_type), level=None,
3822 force=True, starttime=starttime)
3823 else:
3824 update_status = lambda idle, run, finish: None
3825 update_first = None
3826 try:
3827 self.cluster.wait(self.me_dir, update_status, update_first=update_first)
3828 except Exception, error:
3829 logger.info(error)
3830 if not self.force:
3831 ans = self.ask('Cluster Error detected. Do you want to clean the queue? ("c"=continue the run anyway)',
3832 default = 'y', choices=['y','n', 'c'])
3833 else:
3834 ans = 'y'
3835 if ans == 'y':
3836 self.cluster.remove()
3837 elif ans == 'c':
3838 return self.monitor(run_type=run_type, mode=mode, html=html)
3839 raise
3840 except KeyboardInterrupt, error:
3841 self.cluster.remove()
3842 raise
3843
3844
3845
3846
3928
3929
3930
3931
3932
3933 @staticmethod
3935 """check if the directory exists. if so return the path otherwise the
3936 default"""
3937
3938 if os.path.isdir(path):
3939 return path
3940 else:
3941 return default
3942
3943
3945 """get the list of Pdirectory if not yet saved."""
3946
3947 if hasattr(self, "Pdirs"):
3948 if self.me_dir in self.Pdirs[0]:
3949 return self.Pdirs
3950 self.Pdirs = [pjoin(self.me_dir, 'SubProcesses', l.strip())
3951 for l in open(pjoin(self.me_dir,'SubProcesses', 'subproc.mg'))]
3952 return self.Pdirs
3953
3954
3956 """get the list of Gdirectory if not yet saved."""
3957
3958 if hasattr(self, "Gdirs"):
3959 if self.me_dir in self.Gdirs[0]:
3960 return self.Gdirs
3961
3962 Pdirs = self.get_Pdir()
3963 Gdirs = []
3964 for P in Pdirs:
3965 for line in open(pjoin(P, "symfact.dat")):
3966 tag, mfactor = line.split()
3967 Gdirs.append( (pjoin(P, "G%s" % tag), int(mfactor)) )
3968
3969
3970 self.Gdirs = Gdirs
3971 return self.Gdirs
3972
3973
3974 - def set_run_name(self, name, tag=None, level='parton', reload_card=False,
3975 allow_new_tag=True):
3976 """define the run name, the run_tag, the banner and the results."""
3977
3978
3979 upgrade_tag = {'parton': ['parton','pythia','pgs','delphes'],
3980 'pythia': ['pythia','pgs','delphes'],
3981 'pgs': ['pgs'],
3982 'delphes':['delphes'],
3983 'plot':[],
3984 'syscalc':[]}
3985
3986
3987
3988 if name == self.run_name:
3989 if reload_card:
3990 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
3991 self.run_card = banner_mod.RunCard(run_card)
3992
3993
3994 if tag:
3995 self.run_card['run_tag'] = tag
3996 self.run_tag = tag
3997 self.results.add_run(self.run_name, self.run_card)
3998 else:
3999 for tag in upgrade_tag[level]:
4000 if getattr(self.results[self.run_name][-1], tag):
4001 tag = self.get_available_tag()
4002 self.run_card['run_tag'] = tag
4003 self.run_tag = tag
4004 self.results.add_run(self.run_name, self.run_card)
4005 break
4006 return
4007
4008
4009 if self.run_name:
4010 self.store_result()
4011
4012 self.run_name = name
4013
4014 new_tag = False
4015
4016 self.banner = banner_mod.recover_banner(self.results, level, name)
4017 if 'mgruncard' in self.banner:
4018 self.run_card = self.banner.charge_card('run_card')
4019 else:
4020
4021 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
4022 self.run_card = banner_mod.RunCard(run_card)
4023
4024 if tag:
4025 self.run_card['run_tag'] = tag
4026 new_tag = True
4027 elif not self.run_name in self.results and level =='parton':
4028 pass
4029 elif not self.run_name in self.results:
4030
4031 logger.warning('Trying to run data on unknown run.')
4032 self.results.add_run(name, self.run_card)
4033 self.results.update('add run %s' % name, 'all', makehtml=False)
4034 else:
4035 for tag in upgrade_tag[level]:
4036
4037 if getattr(self.results[self.run_name][-1], tag):
4038
4039 tag = self.get_available_tag()
4040 self.run_card['run_tag'] = tag
4041 new_tag = True
4042 break
4043 if not new_tag:
4044
4045 tag = self.results[self.run_name][-1]['tag']
4046 self.run_card['run_tag'] = tag
4047
4048 if allow_new_tag and (name in self.results and not new_tag):
4049 self.results.def_current(self.run_name)
4050 else:
4051 self.results.add_run(self.run_name, self.run_card)
4052
4053 self.run_tag = self.run_card['run_tag']
4054
4055
4056
4057 if level == 'parton':
4058 return
4059 elif level == 'pythia':
4060 return self.results[self.run_name][0]['tag']
4061 else:
4062 for i in range(-1,-len(self.results[self.run_name])-1,-1):
4063 tagRun = self.results[self.run_name][i]
4064 if tagRun.pythia:
4065 return tagRun['tag']
4066
4067
4068
4069
4070
4071
4072
4073
4074
4076 """ return the model name """
4077 if hasattr(self, 'model_name'):
4078 return self.model_name
4079
4080 model = 'sm'
4081 proc = []
4082 for line in open(os.path.join(self.me_dir,'Cards','proc_card_mg5.dat')):
4083 line = line.split('#')[0]
4084
4085 if line.startswith('import') and 'model' in line:
4086 model = line.split()[2]
4087 proc = []
4088 elif line.startswith('generate'):
4089 proc.append(line.split(None,1)[1])
4090 elif line.startswith('add process'):
4091 proc.append(line.split(None,2)[2])
4092
4093 self.model = model
4094 self.process = proc
4095 return model
4096
4097
4098
4100 """Find the number of event in the run_card, and check that this is not
4101 too large"""
4102
4103
4104 nb_event = int(self.run_card['nevents'])
4105 if nb_event > 1000000:
4106 logger.warning("Attempting to generate more than 1M events")
4107 logger.warning("Limiting number to 1M. Use multi_run for larger statistics.")
4108 path = pjoin(self.me_dir, 'Cards', 'run_card.dat')
4109 os.system(r"""perl -p -i.bak -e "s/\d+\s*=\s*nevents/1000000 = nevents/" %s""" \
4110 % path)
4111 self.run_card['nevents'] = 1000000
4112
4113 return
4114
4115
4116
4118 """ change random number"""
4119
4120 self.random += 3
4121 if self.random > 30081*30081:
4122 raise MadGraph5Error,\
4123 'Random seed too large ' + str(self.random) + ' > 30081*30081'
4124
4125
4127 """save random number in appropirate file"""
4128
4129 fsock = open(pjoin(self.me_dir, 'SubProcesses','randinit'),'w')
4130 fsock.writelines('r=%s\n' % self.random)
4131
4132 - def do_quit(self, *args, **opts):
4136
4137
4139 """check for ckkw"""
4140
4141 lpp1 = self.run_card['lpp1']
4142 lpp2 = self.run_card['lpp2']
4143 e1 = self.run_card['ebeam1']
4144 e2 = self.run_card['ebeam2']
4145 pd = self.run_card['pdlabel']
4146 lha = self.run_card['lhaid']
4147 xq = self.run_card['xqcut']
4148 translation = {'e1': e1, 'e2':e2, 'pd':pd,
4149 'lha':lha, 'xq':xq}
4150
4151 if lpp1 or lpp2:
4152
4153 if pd.startswith("'"):
4154 pd = pd[1:]
4155 if pd.endswith("'"):
4156 pd = pd[:-1]
4157
4158 if xq >2 or xq ==2:
4159 xq = 2
4160
4161
4162 if pd == "lhapdf":
4163 issudfile = 'lib/issudgrid-%(e1)s-%(e2)s-%(pd)s-%(lha)s-%(xq)s.dat.gz'
4164 else:
4165 issudfile = 'lib/issudgrid-%(e1)s-%(e2)s-%(pd)s-%(xq)s.dat.gz'
4166 if self.web:
4167 issudfile = pjoin(self.webbin, issudfile % translation)
4168 else:
4169 issudfile = pjoin(self.me_dir, issudfile % translation)
4170
4171 logger.info('Sudakov grid file: %s' % issudfile)
4172
4173
4174 if os.path.exists(issudfile):
4175 path = pjoin(self.me_dir, 'lib', 'issudgrid.dat')
4176 misc.gunzip(issudfile, keep=True, stdout=path)
4177 else:
4178 msg = 'No sudakov grid file for parameter choice. Start to generate it. This might take a while'
4179 logger.info(msg)
4180 self.update_status('GENERATE SUDAKOF GRID', level='parton')
4181
4182 for i in range(-2,6):
4183 self.cluster.submit('%s/gensudgrid ' % self.dirbin,
4184 arguments = [i],
4185 cwd=self.me_dir,
4186 stdout=open(pjoin(self.me_dir, 'gensudgrid%s.log' % i,'w')))
4187 self.monitor()
4188 for i in range(-2,6):
4189 path = pjoin(self.me_dir, 'lib', 'issudgrid.dat')
4190 os.system('cat %s/gensudgrid%s.log >> %s' % (self.me_dir, path))
4191 misc.gzip(path, stdout=issudfile)
4192
4193
4194 - def create_root_file(self, input='unweighted_events.lhe',
4195 output='unweighted_events.root' ):
4196 """create the LHE root file """
4197 self.update_status('Creating root files', level='parton')
4198
4199 eradir = self.options['exrootanalysis_path']
4200 try:
4201 misc.call(['%s/ExRootLHEFConverter' % eradir,
4202 input, output],
4203 cwd=pjoin(self.me_dir, 'Events'))
4204 except Exception:
4205 logger.warning('fail to produce Root output [problem with ExRootAnalysis]')
4206
4207 - def run_syscalc(self, mode='parton', event_path=None, output=None):
4208 """create the syscalc output"""
4209
4210 if self.run_card['use_syst'] not in self.true:
4211 return
4212
4213 scdir = self.options['syscalc_path']
4214 if not scdir or not os.path.exists(scdir):
4215 return
4216 logger.info('running syscalc on mode %s' % mode)
4217
4218
4219
4220 lhaid = [self.run_card.get_lhapdf_id()]
4221 sys_pdf = self.run_card['sys_pdf'].split('&&')
4222 lhaid += [l.split()[0] for l in sys_pdf]
4223 try:
4224 pdfsets_dir = self.get_lhapdf_pdfsetsdir()
4225 except Exception, error:
4226 logger.debug(str(error))
4227 logger.warning('Systematic computation requires lhapdf to run. Bypass SysCalc')
4228 return
4229
4230
4231 [self.copy_lhapdf_set([onelha], pdfsets_dir) for onelha in lhaid]
4232
4233
4234
4235 tag = self.run_card['run_tag']
4236 card = pjoin(self.me_dir, 'bin','internal', 'syscalc_card.dat')
4237 template = open(pjoin(self.me_dir, 'bin','internal', 'syscalc_template.dat')).read()
4238 self.run_card['sys_pdf'] = self.run_card['sys_pdf'].split('#',1)[0].replace('&&',' \n ')
4239
4240 if self.run_card['sys_pdf'].lower() in ['', 'f', 'false', 'none', '.false.']:
4241 self.run_card['sys_pdf'] = ''
4242 if self.run_card['sys_alpsfact'].lower() in ['', 'f', 'false', 'none','.false.']:
4243 self.run_card['sys_alpsfact'] = ''
4244
4245
4246
4247
4248
4249 if not 'sys_scalecorrelation' in self.run_card:
4250 self.run_card['sys_scalecorrelation'] = -1
4251 open(card,'w').write(template % self.run_card)
4252
4253 if not os.path.exists(card):
4254 return False
4255
4256
4257
4258 event_dir = pjoin(self.me_dir, 'Events')
4259
4260 if not event_path:
4261 if mode == 'parton':
4262 event_path = pjoin(event_dir,self.run_name, 'unweighted_events.lhe')
4263 if not (os.path.exists(event_path) or os.path.exists(event_path+".gz")):
4264 event_path = pjoin(event_dir, 'unweighted_events.lhe')
4265 output = pjoin(event_dir, 'syscalc.lhe')
4266 elif mode == 'Pythia':
4267 if 'mgpythiacard' in self.banner:
4268 pat = re.compile('''^\s*qcut\s*=\s*([\+\-\d.e]*)''', re.M+re.I)
4269 data = pat.search(self.banner['mgpythiacard'])
4270 if data:
4271 qcut = float(data.group(1))
4272 xqcut = abs(self.run_card['xqcut'])
4273 for value in self.run_card['sys_matchscale'].split():
4274 if float(value) < qcut:
4275 raise SysCalcError, 'qcut value for sys_matchscale lower than qcut in pythia_card. Bypass syscalc'
4276 if float(value) < xqcut:
4277 raise SysCalcError, 'qcut value for sys_matchscale lower than xqcut in run_card. Bypass syscalc'
4278
4279
4280 event_path = pjoin(event_dir,'syst.dat')
4281 output = pjoin(event_dir, 'syscalc.dat')
4282 else:
4283 raise self.InvalidCmd, 'Invalid mode %s' % mode
4284
4285 if not os.path.exists(event_path):
4286 if os.path.exists(event_path+'.gz'):
4287 misc.gunzip(event_path+'.gz')
4288 else:
4289 raise SysCalcError, 'Events file %s does not exits' % event_path
4290
4291 self.update_status('Calculating systematics for %s level' % mode, level = mode.lower())
4292 try:
4293 proc = misc.call([os.path.join(scdir, 'sys_calc'),
4294 event_path, card, output],
4295 stdout = open(pjoin(event_dir, self.run_name, '%s_%s_syscalc.log' % (tag,mode)),'w'),
4296 stderr = subprocess.STDOUT,
4297 cwd=event_dir)
4298
4299 time.sleep(5)
4300 except OSError, error:
4301 logger.error('fail to run syscalc: %s. Please check that SysCalc is correctly installed.' % error)
4302 else:
4303 if not os.path.exists(output):
4304 logger.warning('SysCalc Failed. Please read the associate log to see the reason. Did you install the associate PDF set?')
4305 elif mode == 'parton':
4306 files.mv(output, event_path)
4307
4308 self.update_status('End syscalc for %s level' % mode, level = mode.lower(),
4309 makehtml=False)
4310
4311 return True
4312
4313
4314
4315
4317 """Ask the question when launching generate_events/multi_run"""
4318
4319 available_mode = ['0']
4320 void = 'NOT INSTALLED'
4321 switch_order = ['pythia', 'pgs', 'delphes', 'madspin', 'reweight']
4322 switch = {'pythia': void, 'pgs': void, 'delphes': void,
4323 'madspin': void, 'reweight': void}
4324 description = {'pythia': 'Run the pythia shower/hadronization:',
4325 'pgs': 'Run PGS as detector simulator:',
4326 'delphes':'Run Delphes as detector simulator:',
4327 'madspin':'Decay particles with the MadSpin module:',
4328 'reweight':'Add weights to the events based on changing model parameters:',
4329 }
4330 force_switch = {('pythia', 'OFF'): {'pgs': 'OFF', 'delphes': 'OFF'},
4331 ('pgs', 'ON'): {'pythia':'ON'},
4332 ('delphes', 'ON'): {'pythia': 'ON'}}
4333 switch_assign = lambda key, value: switch.__setitem__(key, value if switch[key] != void else void )
4334
4335
4336
4337 if self.options['pythia-pgs_path']:
4338 available_mode.append('1')
4339 available_mode.append('2')
4340 if os.path.exists(pjoin(self.me_dir,'Cards','pythia_card.dat')):
4341 switch['pythia'] = 'ON'
4342 else:
4343 switch['pythia'] = 'OFF'
4344 if os.path.exists(pjoin(self.me_dir,'Cards','pgs_card.dat')):
4345 switch['pgs'] = 'ON'
4346 else:
4347 switch['pgs'] = 'OFF'
4348 if self.options['delphes_path']:
4349 available_mode.append('3')
4350 if os.path.exists(pjoin(self.me_dir,'Cards','delphes_card.dat')):
4351 switch['delphes'] = 'ON'
4352 else:
4353 switch['delphes'] = 'OFF'
4354
4355
4356 if not MADEVENT or ('mg5_path' in self.options and self.options['mg5_path']):
4357 available_mode.append('4')
4358 available_mode.append('5')
4359 if os.path.exists(pjoin(self.me_dir,'Cards','madspin_card.dat')):
4360 switch['madspin'] = 'ON'
4361 else:
4362 switch['madspin'] = 'OFF'
4363 if misc.has_f2py() or self.options['f2py_compiler']:
4364 if os.path.exists(pjoin(self.me_dir,'Cards','reweight_card.dat')):
4365 switch['reweight'] = 'ON'
4366 else:
4367 switch['reweight'] = 'OFF'
4368 else:
4369 switch['reweight'] = 'Not available (requires NumPy)'
4370
4371 if '-R' in args or '--reweight' in args:
4372 if switch['reweight'] == 'OFF':
4373 switch['reweight'] = 'ON'
4374 elif switch['reweight'] != 'ON':
4375 logger.critical("Cannot run reweight: %s", switch['reweight'])
4376 if '-M' in args or '--madspin' in args:
4377 switch['madspin'] = 'ON'
4378
4379 options = list(available_mode) + ['auto', 'done']
4380 for id, key in enumerate(switch_order):
4381 if switch[key] not in [void, 'Not available (requires NumPy)']:
4382 options += ['%s=%s' % (key, s) for s in ['ON','OFF']]
4383 options.append(key)
4384 options.append('parton')
4385
4386
4387 if mode or not self.force:
4388 answer = ''
4389 while answer not in ['0', 'done', 'auto']:
4390 if mode:
4391 answer = mode
4392 else:
4393 switch_format = " %i %-61s %10s=%s\n"
4394 question = "The following switches determine which programs are run:\n"
4395 for id, key in enumerate(switch_order):
4396 question += switch_format % (id+1, description[key], key, switch[key])
4397 question += ' Either type the switch number (1 to %s) to change its default setting,\n' % (id+1)
4398 question += ' or set any switch explicitly (e.g. type \'madspin=ON\' at the prompt)\n'
4399 question += ' Type \'0\', \'auto\', \'done\' or just press enter when you are done.\n'
4400 answer = self.ask(question, '0', options)
4401 if answer.isdigit() and answer != '0':
4402 key = switch_order[int(answer) - 1]
4403 answer = '%s=%s' % (key, 'ON' if switch[key] == 'OFF' else 'OFF')
4404
4405 if '=' in answer:
4406 key, status = answer.split('=')
4407 switch[key] = status
4408 if (key, status) in force_switch:
4409 for key2, status2 in force_switch[(key, status)].items():
4410 if switch[key2] not in [status2, void]:
4411 logger.info('For coherence \'%s\' is set to \'%s\''
4412 % (key2, status2), '$MG:color:BLACK')
4413 switch[key2] = status2
4414 elif answer in ['0', 'auto', 'done']:
4415 continue
4416 else:
4417 logger.info('pass in %s only mode' % answer, '$MG:color:BLACK')
4418 switch_assign('madspin', 'OFF')
4419 switch_assign('reweight', 'OFF')
4420 if answer == 'parton':
4421 switch_assign('pythia', 'OFF')
4422 switch_assign('pgs', 'OFF')
4423 switch_assign('delphes', 'OFF')
4424 elif answer == 'pythia':
4425 switch_assign('pythia', 'ON')
4426 switch_assign('pgs', 'OFF')
4427 switch_assign('delphes', 'OFF')
4428 elif answer == 'pgs':
4429 switch_assign('pythia', 'ON')
4430 switch_assign('pgs', 'ON')
4431 switch_assign('delphes', 'OFF')
4432 elif answer == 'delphes':
4433 switch_assign('pythia', 'ON')
4434 switch_assign('pgs', 'OFF')
4435 switch_assign('delphes', 'ON')
4436 elif answer == 'madspin':
4437 switch_assign('madspin', 'ON')
4438 switch_assign('pythia', 'OFF')
4439 switch_assign('pgs', 'OFF')
4440 switch_assign('delphes', 'OF')
4441 elif answer == 'reweight':
4442 switch_assign('reweight', 'ON')
4443 switch_assign('pythia', 'OFF')
4444 switch_assign('pgs', 'OFF')
4445 switch_assign('delphes', 'OFF')
4446
4447
4448 if mode:
4449 answer = '0'
4450 else:
4451 answer = 'auto'
4452
4453
4454
4455
4456 cards = ['param_card.dat', 'run_card.dat']
4457 if switch['pythia'] == 'ON':
4458 cards.append('pythia_card.dat')
4459 if switch['pgs'] == 'ON':
4460 cards.append('pgs_card.dat')
4461 if switch['delphes'] == 'ON':
4462 cards.append('delphes_card.dat')
4463 delphes3 = True
4464 if os.path.exists(pjoin(self.options['delphes_path'], 'data')):
4465 delphes3 = False
4466 cards.append('delphes_trigger.dat')
4467 if switch['madspin'] == 'ON':
4468 cards.append('madspin_card.dat')
4469 if switch['reweight'] == 'ON':
4470 cards.append('reweight_card.dat')
4471 self.keep_cards(cards)
4472
4473 if os.path.isfile(pjoin(self.me_dir,'Cards','MadLoopParams.dat')):
4474 cards.append('MadLoopParams.dat')
4475
4476 if self.force:
4477 self.check_param_card(pjoin(self.me_dir,'Cards','param_card.dat' ))
4478 return
4479
4480 if answer == 'auto':
4481 self.ask_edit_cards(cards, mode='auto')
4482 else:
4483 self.ask_edit_cards(cards)
4484 return
4485
4486
4488 """Ask the question when launching pythia"""
4489
4490 available_mode = ['0', '1', '2']
4491 if self.options['delphes_path']:
4492 available_mode.append('3')
4493 name = {'0': 'auto', '1': 'pythia', '2':'pgs', '3':'delphes'}
4494 options = available_mode + [name[val] for val in available_mode]
4495 question = """Which programs do you want to run?
4496 0 / auto : running existing card
4497 1 / pythia : Pythia
4498 2 / pgs : Pythia + PGS\n"""
4499 if '3' in available_mode:
4500 question += """ 3 / delphes : Pythia + Delphes.\n"""
4501
4502 if not self.force:
4503 if not mode:
4504 mode = self.ask(question, '0', options)
4505 elif not mode:
4506 mode = 'auto'
4507
4508 if mode.isdigit():
4509 mode = name[mode]
4510
4511 auto = False
4512 if mode == 'auto':
4513 auto = True
4514 if os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')):
4515 mode = 'pgs'
4516 elif os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
4517 mode = 'delphes'
4518 else:
4519 mode = 'pythia'
4520 logger.info('Will run in mode %s' % mode)
4521
4522
4523
4524 cards = ['pythia_card.dat']
4525 if mode == 'pgs':
4526 cards.append('pgs_card.dat')
4527 if mode == 'delphes':
4528 cards.append('delphes_card.dat')
4529 delphes3 = True
4530 if os.path.exists(pjoin(self.options['delphes_path'], 'data')):
4531 delphes3 = False
4532 cards.append('delphes_trigger.dat')
4533 self.keep_cards(cards)
4534
4535 if self.force:
4536 return mode
4537
4538 if auto:
4539 self.ask_edit_cards(cards, mode='auto')
4540 else:
4541 self.ask_edit_cards(cards)
4542
4543 return mode
4544
4545
4546
4547
4548
4549
4550
4551
4552 -class MadEventCmdShell(MadEventCmd, cmd.CmdShell):
4553 """The command line processor of MadGraph"""
4554
4561
4562 name_to_pdg = {}
4563
4564 @classmethod
4567
4568 @staticmethod
4570 """return the list of Subprocesses"""
4571
4572 out = []
4573 for line in open(pjoin(me_dir,'SubProcesses', 'subproc.mg')):
4574 if not line:
4575 continue
4576 name = line.strip()
4577 if os.path.exists(pjoin(me_dir, 'SubProcesses', name)):
4578 out.append(pjoin(me_dir, 'SubProcesses', name))
4579
4580 return out
4581
4582
4583
4584 @staticmethod
4586 """ return the list of processes with their name"""
4587
4588 nb_sub = 0
4589 names = {}
4590 old_main = ''
4591
4592 if not os.path.exists(os.path.join(path,'processes.dat')):
4593 return SubProcesses.get_subP_info_v4(path)
4594
4595 for line in open(os.path.join(path,'processes.dat')):
4596 main = line[:8].strip()
4597 if main == 'mirror':
4598 main = old_main
4599 if line[8:].strip() == 'none':
4600 continue
4601 else:
4602 main = int(main)
4603 old_main = main
4604
4605 sub_proccess = line[8:]
4606 nb_sub += sub_proccess.count(',') + 1
4607 if main in names:
4608 names[main] += [sub_proccess.split(',')]
4609 else:
4610 names[main]= [sub_proccess.split(',')]
4611
4612 return names
4613
4614 @staticmethod
4616 """ return the list of processes with their name in case without grouping """
4617
4618 nb_sub = 0
4619 names = {'':[[]]}
4620 path = os.path.join(path, 'auto_dsig.f')
4621 found = 0
4622 for line in open(path):
4623 if line.startswith('C Process:'):
4624 found += 1
4625 names[''][0].append(line[15:])
4626 elif found >1:
4627 break
4628 return names
4629
4630
4631 @staticmethod
4633 """return the pdg codes of the particles present in the Subprocesses"""
4634
4635 all_ids = []
4636 for line in open(pjoin(path, 'leshouche.inc')):
4637 if not 'IDUP' in line:
4638 continue
4639 particles = re.search("/([\d,-]+)/", line)
4640 all_ids.append([int(p) for p in particles.group(1).split(',')])
4641 return all_ids
4642
4646 """The command for the gridpack --Those are not suppose to be use interactively--"""
4647
4648 - def __init__(self, me_dir = None, nb_event=0, seed=0, *completekey, **stdin):
4649 """Initialize the command and directly run"""
4650
4651
4652
4653 MadEventCmd.__init__(self, me_dir, *completekey, **stdin)
4654 self.run_mode = 0
4655 self.random = seed
4656 self.random_orig = self.random
4657 self.options['automatic_html_opening'] = False
4658
4659 if me_dir and nb_event and seed:
4660 self.launch(nb_event, seed)
4661 else:
4662 raise MadGraph5Error,\
4663 'Gridpack run failed: ' + str(me_dir) + str(nb_event) + \
4664 str(seed)
4665
4666 - def launch(self, nb_event, seed):
4689
4691 """Special refine for gridpack run."""
4692 self.nb_refine += 1
4693
4694 precision = nb_event
4695
4696
4697
4698 self.cluster_mode = 0
4699
4700
4701 self.save_random()
4702
4703 self.update_status('Refine results to %s' % precision, level=None)
4704 logger.info("Using random number seed offset = %s" % self.random)
4705
4706 self.total_jobs = 0
4707 subproc = [P for P in os.listdir(pjoin(self.me_dir,'SubProcesses')) if
4708 P.startswith('P') and os.path.isdir(pjoin(self.me_dir,'SubProcesses', P))]
4709 devnull = open(os.devnull, 'w')
4710 for nb_proc,subdir in enumerate(subproc):
4711 subdir = subdir.strip()
4712 Pdir = pjoin(self.me_dir, 'SubProcesses',subdir)
4713 bindir = pjoin(os.path.relpath(self.dirbin, Pdir))
4714
4715 logger.info(' %s ' % subdir)
4716
4717 for match in misc.glob('*ajob*', Pdir):
4718 if os.path.basename(match)[:4] in ['ajob', 'wait', 'run.', 'done']:
4719 os.remove(pjoin(Pdir, match))
4720
4721
4722 logfile = pjoin(Pdir, 'gen_ximprove.log')
4723 misc.call([pjoin(bindir, 'gen_ximprove')],
4724 stdin=subprocess.PIPE,
4725 stdout=open(logfile,'w'),
4726 cwd=Pdir)
4727
4728 if os.path.exists(pjoin(Pdir, 'ajob1')):
4729 alljobs = misc.glob('ajob*', Pdir)
4730 nb_tot = len(alljobs)
4731 self.total_jobs += nb_tot
4732 for i, job in enumerate(alljobs):
4733 job = os.path.basename(job)
4734 self.launch_job('%s' % job, cwd=Pdir, remaining=(nb_tot-i-1),
4735 run_type='Refine number %s on %s (%s/%s)' %
4736 (self.nb_refine, subdir, nb_proc+1, len(subproc)))
4737 if os.path.exists(pjoin(self.me_dir,'error')):
4738 self.monitor(html=True)
4739 raise MadEventError, \
4740 'Error detected in dir %s: %s' % \
4741 (Pdir, open(pjoin(self.me_dir,'error')).read())
4742 self.monitor(run_type='All job submitted for refine number %s' %
4743 self.nb_refine)
4744
4745 self.update_status("Combining runs", level='parton')
4746 try:
4747 os.remove(pjoin(Pdir, 'combine_runs.log'))
4748 except Exception:
4749 pass
4750
4751 bindir = pjoin(os.path.relpath(self.dirbin, pjoin(self.me_dir,'SubProcesses')))
4752 combine_runs.CombineRuns(self.me_dir)
4753
4754
4755 cross, error = sum_html.make_all_html_results(self)
4756 self.results.add_detail('cross', cross)
4757 self.results.add_detail('error', error)
4758
4759
4760 self.update_status('finish refine', 'parton', makehtml=False)
4761 devnull.close()
4762
4765 """ A container class for the various methods for initializing MadLoop. It is
4766 placed in MadEventInterface because it is used by Madevent for loop-induced
4767 simulations. """
4768
4769 @staticmethod
4771 """ Compile the check program in the directory dir_name.
4772 Return the compilation and running time. """
4773
4774
4775
4776 if os.path.isfile(pjoin(dir_name,'check')):
4777 os.remove(pjoin(dir_name,'check'))
4778 os.remove(pjoin(dir_name,'check_sa.o'))
4779 os.remove(pjoin(dir_name,'loop_matrix.o'))
4780
4781 devnull = open(os.devnull, 'w')
4782 start=time.time()
4783 retcode = subprocess.call(['make','check'],
4784 cwd=dir_name, stdout=devnull, stderr=devnull)
4785 compilation_time = time.time()-start
4786 if retcode != 0:
4787 logging.info("Error while executing make in %s" % dir_name)
4788 return None, None, None
4789
4790 if not checkRam:
4791 start=time.time()
4792 retcode = subprocess.call('./check',
4793 cwd=dir_name, stdout=devnull, stderr=devnull)
4794
4795 run_time = time.time()-start
4796 ram_usage = None
4797 else:
4798 ptimer = misc.ProcessTimer(['./check'], cwd=dir_name, shell=False, \
4799 stdout=devnull, stderr=devnull, close_fds=True)
4800 try:
4801 ptimer.execute()
4802
4803
4804
4805 while ptimer.poll():
4806 time.sleep(.2)
4807 finally:
4808
4809 ptimer.close()
4810
4811 ram_usage = ptimer.max_rss_memory
4812
4813
4814 run_time = (ptimer.t1 - ptimer.t0)
4815 retcode = ptimer.p.returncode
4816
4817 devnull.close()
4818
4819 if retcode != 0:
4820 logging.warning("Error while executing ./check in %s" % dir_name)
4821 return None, None, None
4822
4823 return compilation_time, run_time, ram_usage
4824
4825 @staticmethod
4826 - def fix_PSPoint_in_check(dir_path, read_ps = True, npoints = 1,
4827 hel_config = -1, mu_r=0.0, split_orders=-1):
4828 """Set check_sa.f to be reading PS.input assuming a working dir dir_name.
4829 if hel_config is different than -1 then check_sa.f is configured so to
4830 evaluate only the specified helicity.
4831 If mu_r > 0.0, then the renormalization constant value will be hardcoded
4832 directly in check_sa.f, if is is 0 it will be set to Sqrt(s) and if it
4833 is < 0.0 the value in the param_card.dat is used.
4834 If the split_orders target (i.e. the target squared coupling orders for
4835 the computation) is != -1, it will be changed in check_sa.f via the
4836 subroutine CALL SET_COUPLINGORDERS_TARGET(split_orders)."""
4837
4838 file_path = dir_path
4839 if not os.path.isfile(dir_path) or \
4840 not os.path.basename(dir_path)=='check_sa.f':
4841 file_path = pjoin(dir_path,'check_sa.f')
4842 if not os.path.isfile(file_path):
4843 directories = [d for d in misc.glob('P*_*', dir_path) \
4844 if (re.search(r'.*P\d+_\w*$', d) and os.path.isdir(d))]
4845 if len(directories)>0:
4846 file_path = pjoin(directories[0],'check_sa.f')
4847 if not os.path.isfile(file_path):
4848 raise MadGraph5Error('Could not find the location of check_sa.f'+\
4849 ' from the specified path %s.'%str(file_path))
4850
4851 file = open(file_path, 'r')
4852 check_sa = file.read()
4853 file.close()
4854
4855 file = open(file_path, 'w')
4856 check_sa = re.sub(r"READPS = \S+\)","READPS = %s)"%('.TRUE.' if read_ps \
4857 else '.FALSE.'), check_sa)
4858 check_sa = re.sub(r"NPSPOINTS = \d+","NPSPOINTS = %d"%npoints, check_sa)
4859 if hel_config != -1:
4860 check_sa = re.sub(r"SLOOPMATRIX\S+\(\S+,MATELEM,",
4861 "SLOOPMATRIXHEL_THRES(P,%d,MATELEM,"%hel_config, check_sa)
4862 else:
4863 check_sa = re.sub(r"SLOOPMATRIX\S+\(\S+,MATELEM,",
4864 "SLOOPMATRIX_THRES(P,MATELEM,",check_sa)
4865 if mu_r > 0.0:
4866 check_sa = re.sub(r"MU_R=SQRTS","MU_R=%s"%\
4867 (("%.17e"%mu_r).replace('e','d')),check_sa)
4868 elif mu_r < 0.0:
4869 check_sa = re.sub(r"MU_R=SQRTS","",check_sa)
4870
4871 if split_orders > 0:
4872 check_sa = re.sub(r"SET_COUPLINGORDERS_TARGET\(-?\d+\)",
4873 "SET_COUPLINGORDERS_TARGET(%d)"%split_orders,check_sa)
4874
4875 file.write(check_sa)
4876 file.close()
4877
4878 @staticmethod
4879 - def run_initialization(run_dir=None, SubProc_dir=None, infos=None,\
4880 req_files = ['HelFilter.dat','LoopFilter.dat'],
4881 attempts = [4,15]):
4882 """ Run the initialization of the process in 'run_dir' with success
4883 characterized by the creation of the files req_files in this directory.
4884 The directory containing the driving source code 'check_sa.f'.
4885 The list attempt gives the successive number of PS points the
4886 initialization should be tried with before calling it failed.
4887 Returns the number of PS points which were necessary for the init.
4888 Notice at least run_dir or SubProc_dir must be provided.
4889 A negative attempt number given in input means that quadprec will be
4890 forced for initialization."""
4891
4892
4893
4894 if infos is None:
4895 infos={}
4896
4897 if SubProc_dir is None and run_dir is None:
4898 raise MadGraph5Error, 'At least one of [SubProc_dir,run_dir] must'+\
4899 ' be provided in run_initialization.'
4900
4901
4902
4903 if SubProc_dir is None:
4904 SubProc_dir = os.path.abspath(pjoin(run_dir,os.pardir))
4905
4906 if run_dir is None:
4907 directories =[ dir for dir in misc.glob('P[0-9]*', SubProc_dir)
4908 if os.path.isdir(dir) ]
4909 if directories:
4910 run_dir = directories[0]
4911 else:
4912 raise MadGraph5Error, 'Could not find a valid running directory'+\
4913 ' in %s.'%str(SubProc_dir)
4914
4915
4916
4917
4918
4919 if not os.path.isfile(pjoin(run_dir,'born_matrix.f')):
4920 if len(attempts)>=1 and attempts[0]<8:
4921 attempts[0]=8
4922 if len(attempts)>=2 and attempts[1]<25:
4923 attempts[1]=25
4924
4925 to_attempt = list(attempts)
4926 to_attempt.reverse()
4927 my_req_files = list(req_files)
4928
4929 MLCardPath = pjoin(SubProc_dir,'MadLoopParams.dat')
4930 if not os.path.isfile(MLCardPath):
4931 raise MadGraph5Error, 'Could not find MadLoopParams.dat at %s.'\
4932 %MLCardPath
4933 else:
4934 MLCard = banner_mod.MadLoopParam(MLCardPath)
4935 MLCard_orig = banner_mod.MadLoopParam(MLCard)
4936
4937
4938 if not MLCard['UseLoopFilter']:
4939 try:
4940 my_req_files.remove('LoopFilter.dat')
4941 except ValueError:
4942 pass
4943
4944 if MLCard['HelicityFilterLevel']==0:
4945 try:
4946 my_req_files.remove('HelFilter.dat')
4947 except ValueError:
4948 pass
4949
4950 def need_init():
4951 """ True if init not done yet."""
4952 proc_prefix_file = open(pjoin(run_dir,'proc_prefix.txt'),'r')
4953 proc_prefix = proc_prefix_file.read()
4954 proc_prefix_file.close()
4955 return any([not os.path.exists(pjoin(run_dir,'MadLoop5_resources',
4956 proc_prefix+fname)) for fname in my_req_files]) or \
4957 not os.path.isfile(pjoin(run_dir,'check')) or \
4958 not os.access(pjoin(run_dir,'check'), os.X_OK)
4959
4960
4961
4962 is_loop_induced = os.path.exists(pjoin(run_dir,'born_matrix.f'))
4963
4964
4965
4966
4967 if not any(attempt<0 for attempt in to_attempt):
4968 to_attempt = [-attempt for attempt in to_attempt] + to_attempt
4969 use_quad_prec = 1
4970 curr_attempt = 1
4971
4972 MLCard.set('WriteOutFilters',True)
4973
4974 while to_attempt!=[] and need_init():
4975 curr_attempt = to_attempt.pop()
4976
4977
4978 if curr_attempt < 0:
4979 use_quad_prec = -1
4980
4981 MLCard.set('CTModeInit',4)
4982 MLCard.set('ZeroThres',1e-11)
4983 else:
4984
4985 MLCard.set('CTModeInit',1)
4986 MLCard.set('ZeroThres',1e-9)
4987
4988 curr_attempt = abs(curr_attempt+1)
4989 MLCard.set('MaxAttempts',curr_attempt)
4990 MLCard.write(pjoin(SubProc_dir,'MadLoopParams.dat'))
4991
4992
4993 MadLoopInitializer.fix_PSPoint_in_check(run_dir, read_ps = False,
4994 npoints = curr_attempt)
4995 compile_time, run_time, ram_usage = \
4996 MadLoopInitializer.make_and_run(run_dir)
4997 if compile_time==None:
4998 logging.error("Failed at running the process in %s."%run_dir)
4999 attempts = None
5000 return None
5001
5002 if 'Process_compilation' not in infos.keys() or \
5003 infos['Process_compilation']==None:
5004 infos['Process_compilation'] = compile_time
5005 infos['Initialization'] = run_time
5006
5007 MLCard_orig.write(pjoin(SubProc_dir,'MadLoopParams.dat'))
5008 if need_init():
5009 return None
5010 else:
5011 return use_quad_prec*(curr_attempt-1)
5012
5013 @staticmethod
5015 """Checks whether the necessary filters are present or not."""
5016
5017 def need_init(ML_resources_path, proc_prefix, r_files):
5018 """ Returns true if not all required files are present. """
5019 return any([not os.path.exists(pjoin(ML_resources_path,
5020 proc_prefix+fname)) for fname in r_files])
5021
5022 MLCardPath = pjoin(proc_dir,'SubProcesses','MadLoopParams.dat')
5023 if not os.path.isfile(MLCardPath):
5024 raise MadGraph5Error, 'Could not find MadLoopParams.dat at %s.'\
5025 %MLCardPath
5026 MLCard = banner_mod.MadLoopParam(MLCardPath)
5027
5028 req_files = ['HelFilter.dat','LoopFilter.dat']
5029
5030 if not MLCard['UseLoopFilter']:
5031 try:
5032 req_files.remove('LoopFilter.dat')
5033 except ValueError:
5034 pass
5035 if MLCard['HelicityFilterLevel']==0:
5036 try:
5037 req_files.remove('HelFilter.dat')
5038 except ValueError:
5039 pass
5040
5041 for v_folder in glob.iglob(pjoin(proc_dir,'SubProcesses',
5042 '%s*'%subproc_prefix)):
5043
5044 if not os.path.isdir(v_folder) or not os.path.isfile(\
5045 pjoin(v_folder,'loop_matrix.f')):
5046 continue
5047 proc_prefix_file = open(pjoin(v_folder,'proc_prefix.txt'),'r')
5048 proc_prefix = proc_prefix_file.read()
5049 proc_prefix_file.close()
5050 if need_init(pjoin(proc_dir,'SubProcesses','MadLoop5_resources'),
5051 proc_prefix, req_files):
5052 return True
5053
5054 return False
5055
5056 @staticmethod
5057 - def init_MadLoop(proc_dir, n_PS=None, subproc_prefix='PV', MG_options=None,
5058 interface = None):
5059 """Advanced commands: Compiles and run MadLoop on RAMBO random PS points to initilize the
5060 filters."""
5061
5062 logger.debug('Compiling Source materials necessary for MadLoop '+
5063 'initialization.')
5064
5065
5066
5067 if interface is None:
5068 misc.compile(arg=['treatCardsLoopNoInit'], cwd=pjoin(proc_dir,'Source'))
5069 else:
5070 interface.do_treatcards('all --no_MadLoopInit')
5071
5072
5073 if os.path.exists(pjoin(proc_dir,'Source','CUTTOOLS')):
5074 misc.compile(arg=['libcuttools'],cwd=pjoin(proc_dir,'Source'))
5075 if os.path.exists(pjoin(proc_dir,'Source','IREGI')):
5076 misc.compile(arg=['libiregi'],cwd=pjoin(proc_dir,'Source'))
5077
5078 misc.compile(arg=['libmodel'],cwd=pjoin(proc_dir,'Source'))
5079 misc.compile(arg=['libdhelas'],cwd=pjoin(proc_dir,'Source'))
5080
5081
5082 logger.info('Initializing MadLoop loop-induced matrix elements '+\
5083 '(this can take some time)...')
5084
5085
5086 if MG_options:
5087 mcore = cluster.MultiCore(**MG_options)
5088 else:
5089 mcore = cluster.onecore
5090 def run_initialization_wrapper(run_dir, infos, attempts):
5091 if attempts is None:
5092 n_PS = MadLoopInitializer.run_initialization(
5093 run_dir=run_dir, infos=infos)
5094 else:
5095 n_PS = MadLoopInitializer.run_initialization(
5096 run_dir=run_dir, infos=infos, attempts=attempts)
5097 infos['nPS'] = n_PS
5098 return 0
5099
5100 def wait_monitoring(Idle, Running, Done):
5101 if Idle+Running+Done == 0:
5102 return
5103 logger.debug('MadLoop initialization jobs: %d Idle, %d Running, %d Done'\
5104 %(Idle, Running, Done))
5105
5106 init_info = {}
5107
5108 VirtualFolders = [f for f in glob.iglob(pjoin(proc_dir,'SubProcesses',
5109 '%s*'%subproc_prefix)) if (os.path.isdir(f) or
5110 os.path.isfile(pjoin(f,'loop_matrix.f')))]
5111 logger.debug("Now Initializing MadLoop matrix element in %d folder%s:"%\
5112 (len(VirtualFolders),'s' if len(VirtualFolders)>1 else ''))
5113 logger.debug(', '.join("'%s'"%os.path.basename(v_folder) for v_folder in
5114 VirtualFolders))
5115 for v_folder in VirtualFolders:
5116 init_info[v_folder] = {}
5117
5118
5119
5120 max_mult = 3
5121 if n_PS is None:
5122
5123 mcore.submit(run_initialization_wrapper,
5124 [pjoin(v_folder), init_info[v_folder], None])
5125 else:
5126
5127 mcore.submit(run_initialization_wrapper, [pjoin(v_folder),
5128 init_info[v_folder],
5129 [n_PS*multiplier for multiplier in range(1,max_mult+1)]])
5130
5131
5132 mcore.wait('',wait_monitoring,update_first=wait_monitoring)
5133 for v_folder in VirtualFolders:
5134 init = init_info[v_folder]
5135 if init['nPS'] is None:
5136 raise MadGraph5Error, 'Failed the initialization of'+\
5137 " loop-induced matrix element '%s'%s."%\
5138 (os.path.basename(v_folder),' (using default n_PS points)' if\
5139 n_PS is None else ' (trying with a maximum of %d PS points)'\
5140 %(max_mult*n_PS))
5141 if init['nPS']==0:
5142 logger.debug("Nothing to be done in '%s', all filters already "%\
5143 os.path.basename(v_folder)+\
5144 "present (use the '-r' option to force their recomputation)")
5145 else:
5146 logger.debug("'%s' finished using "%os.path.basename(v_folder)+
5147 '%d PS points (%s), in %.3g(compil.) + %.3g(init.) secs.'%(
5148 abs(init['nPS']),'DP' if init['nPS']>0 else 'QP',
5149 init['Process_compilation'],init['Initialization']))
5150
5151 logger.info('MadLoop initialization finished.')
5152
5153 AskforEditCard = common_run.AskforEditCard
5154
5155
5156 if '__main__' == __name__:
5157
5158
5159 import sys
5160 if not sys.version_info[0] == 2 or sys.version_info[1] < 6:
5161 sys.exit('MadGraph/MadEvent 5 works only with python 2.6 or later (but not python 3.X).\n'+\
5162 'Please upgrate your version of python.')
5163
5164 import os
5165 import optparse
5166
5167
5168 root_path = os.path.dirname(os.path.dirname(os.path.realpath( __file__ )))
5169 sys.path.insert(0, root_path)
5173 - def error(self, msg=''):
5175
5176 usage = "usage: %prog [options] [FILE] "
5177 parser = MyOptParser(usage=usage)
5178 parser.add_option("-l", "--logging", default='INFO',
5179 help="logging level (DEBUG|INFO|WARNING|ERROR|CRITICAL) [%default]")
5180 parser.add_option("","--web", action="store_true", default=False, dest='web', \
5181 help='force toce to be in secure mode')
5182 parser.add_option("","--debug", action="store_true", default=False, dest='debug', \
5183 help='force to launch debug mode')
5184 parser_error = ''
5185 done = False
5186
5187 for i in range(len(sys.argv)-1):
5188 try:
5189 (options, args) = parser.parse_args(sys.argv[1:len(sys.argv)-i])
5190 done = True
5191 except MyOptParser.InvalidOption, error:
5192 pass
5193 else:
5194 args += sys.argv[len(sys.argv)-i:]
5195 if not done:
5196
5197 try:
5198 (options, args) = parser.parse_args()
5199 except MyOptParser.InvalidOption, error:
5200 print error
5201 sys.exit(2)
5202
5203 if len(args) == 0:
5204 args = ''
5205
5206 import subprocess
5207 import logging
5208 import logging.config
5209
5210
5211 import internal.coloring_logging
5212 try:
5213 if __debug__ and options.logging == 'INFO':
5214 options.logging = 'DEBUG'
5215 if options.logging.isdigit():
5216 level = int(options.logging)
5217 else:
5218 level = eval('logging.' + options.logging)
5219 print os.path.join(root_path, 'internal', 'me5_logging.conf')
5220 logging.config.fileConfig(os.path.join(root_path, 'internal', 'me5_logging.conf'))
5221 logging.root.setLevel(level)
5222 logging.getLogger('madgraph').setLevel(level)
5223 except:
5224 raise
5225 pass
5226
5227
5228 try:
5229 if args:
5230
5231 if '--web' in args:
5232 i = args.index('--web')
5233 args.pop(i)
5234 cmd_line = MadEventCmd(force_run=True)
5235 else:
5236 cmd_line = MadEventCmdShell(force_run=True)
5237 if not hasattr(cmd_line, 'do_%s' % args[0]):
5238 if parser_error:
5239 print parser_error
5240 print 'and %s can not be interpreted as a valid command.' % args[0]
5241 else:
5242 print 'ERROR: %s not a valid command. Please retry' % args[0]
5243 else:
5244 cmd_line.use_rawinput = False
5245 cmd_line.run_cmd(' '.join(args))
5246 cmd_line.run_cmd('quit')
5247
5248 except KeyboardInterrupt:
5249 print 'quit on KeyboardInterrupt'
5250 pass
5251