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 self.exec_cmd('refine %s' % nb_event, postcmd=False)
1995 if not float(self.results.current['cross']):
1996
1997 text = '''Survey return zero cross section.
1998 Typical reasons are the following:
1999 1) A massive s-channel particle has a width set to zero.
2000 2) The pdf are zero for at least one of the initial state particles
2001 or you are using maxjetflavor=4 for initial state b:s.
2002 3) The cuts are too strong.
2003 Please check/correct your param_card and/or your run_card.'''
2004 logger_stderr.critical(text)
2005 raise ZeroResult('See https://cp3.irmp.ucl.ac.be/projects/madgraph/wiki/FAQ-General-14')
2006
2007 self.exec_cmd('refine %s' % nb_event, postcmd=False)
2008
2009 self.exec_cmd('combine_events', postcmd=False)
2010 self.print_results_in_shell(self.results.current)
2011
2012
2013 self.run_syscalc('parton')
2014 self.create_plot('parton')
2015 self.exec_cmd('store_events', postcmd=False)
2016 self.exec_cmd('reweight -from_cards', postcmd=False)
2017 self.exec_cmd('decay_events -from_cards', postcmd=False)
2018 if self.run_card['time_of_flight']>=0:
2019 self.exec_cmd("add_time_of_flight --threshold=%s" % self.run_card['time_of_flight'] ,postcmd=False)
2020 self.exec_cmd('pythia --no_default', postcmd=False, printcmd=False)
2021
2022 self.store_result()
2023
2024 if self.param_card_iterator:
2025 param_card_iterator = self.param_card_iterator
2026 self.param_card_iterator = []
2027 with misc.TMP_variable(self, 'allow_notification_center', False):
2028 param_card_iterator.store_entry(self.run_name, self.results.current['cross'])
2029
2030 orig_name = self.run_name
2031 for card in param_card_iterator:
2032 card.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2033 next_name = param_card_iterator.get_next_name(self.run_name)
2034 self.exec_cmd("generate_events -f %s" % next_name,
2035 precmd=True, postcmd=True,errorhandling=False)
2036 param_card_iterator.store_entry(self.run_name, self.results.current['cross'])
2037 param_card_iterator.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2038 name = misc.get_scan_name(orig_name, self.run_name)
2039 path = pjoin(self.me_dir, 'Events','scan_%s.txt' % name)
2040 logger.info("write all cross-section results in %s" % path ,'$MG:color:BLACK')
2041 param_card_iterator.write_summary(path)
2042
2043
2044 if self.allow_notification_center:
2045 misc.apple_notify('Run %s finished' % os.path.basename(self.me_dir),
2046 '%s: %s +- %s ' % (self.results.current['run_name'],
2047 self.results.current['cross'],
2048 self.results.current['error']))
2049
2051 """Compile and run MadLoop for a certain number of PS point so as to
2052 initialize MadLoop (setup the zero helicity and loop filter.)"""
2053
2054 args = line.split()
2055
2056 options = self.check_initMadLoop(args)
2057
2058 if not options['force']:
2059 self.ask_edit_cards(['MadLoopParams.dat'], mode='fixed', plot=False)
2060 self.exec_cmd('treatcards loop --no_MadLoopInit')
2061
2062 if options['refresh']:
2063 for filter in misc.glob('*Filter*',
2064 pjoin(self.me_dir,'SubProcesses','MadLoop5_resources')):
2065 logger.debug("Resetting filter '%s'."%os.path.basename(filter))
2066 os.remove(filter)
2067
2068 MLCard = banner_mod.MadLoopParam(pjoin(self.me_dir,
2069 'Cards','MadLoopParams.dat'))
2070 if options['nPS'] is None:
2071 options['nPS'] = MLCard['CheckCycle']+2
2072 elif options['nPS'] < MLCard['CheckCycle']+2:
2073 new_n_PS = MLCard['CheckCycle']+2
2074 logger.debug('Hard-setting user-defined n_PS (%d) to %d, because '\
2075 %(options['nPS'],new_n_PS)+"of the 'CheckCycle' value (%d) "%MLCard['CheckCycle']+\
2076 "specified in the ML param card.")
2077 options['nPS'] = new_n_PS
2078
2079 MadLoopInitializer.init_MadLoop(self.me_dir,n_PS=options['nPS'],
2080 subproc_prefix='PV', MG_options=self.options, interface=self)
2081
2083 """Main Commands: exec generate_events for 2>N and calculate_width for 1>N"""
2084 if self.ninitial == 1:
2085 logger.info("Note that since 2.3. The launch for 1>N pass in event generation\n"+
2086 " To have the previous behavior use the calculate_decay_widths function")
2087 self.do_calculate_decay_widths(line, *args, **opt)
2088 else:
2089 self.do_generate_events(line, *args, **opt)
2090
2092 """Have a nice results prints in the shell,
2093 data should be of type: gen_crossxhtml.OneTagResults"""
2094
2095 if not data:
2096 return
2097
2098 if data['run_statistics']:
2099 globalstat = sum_html.RunStatistics()
2100
2101 logger.info(" " )
2102 logger.debug(" === Run statistics summary ===")
2103 for key, value in data['run_statistics'].items():
2104 globalstat.aggregate_statistics(value)
2105 level = 5
2106 if value.has_warning():
2107 level = 10
2108 logger.log(level, value.nice_output(str('/'.join([key[0],'G%s'%key[1]]))).\
2109 replace(' statistics',''))
2110 logger.info(" " )
2111 logger.debug(globalstat.nice_output('combined', no_warning=True))
2112 if globalstat.has_warning():
2113 logger.warning(globalstat.get_warning_text())
2114 logger.info(" ")
2115
2116
2117 logger.info(" === Results Summary for run: %s tag: %s ===\n" % (data['run_name'],data['tag']))
2118
2119 total_time = int(sum(_['cumulative_timing'] for _ in data['run_statistics'].values()))
2120 if total_time > 0:
2121 logger.info(" Cumulative sequential time for this run: %s"%misc.format_time(total_time))
2122
2123 if self.ninitial == 1:
2124 logger.info(" Width : %.4g +- %.4g GeV" % (data['cross'], data['error']))
2125 else:
2126 logger.info(" Cross-section : %.4g +- %.4g pb" % (data['cross'], data['error']))
2127 logger.info(" Nb of events : %s" % data['nb_event'] )
2128 if data['cross_pythia'] and data['nb_event_pythia']:
2129 if self.ninitial == 1:
2130 logger.info(" Matched Width : %.4g +- %.4g GeV" % (data['cross_pythia'], data['error_pythia']))
2131 else:
2132 logger.info(" Matched Cross-section : %.4g +- %.4g pb" % (data['cross_pythia'], data['error_pythia']))
2133 logger.info(" Nb of events after Matching : %s" % data['nb_event_pythia'])
2134 if self.run_card['use_syst'] in self.true:
2135 logger.info(" Be carefull that matched information are here NOT for the central value. Refer to SysCalc output for it")
2136
2137 logger.info(" " )
2138
2140 """Have a nice results prints in the shell,
2141 data should be of type: gen_crossxhtml.OneTagResults"""
2142 if not data:
2143 return
2144
2145 fsock = open(path, mode)
2146
2147 if data['run_statistics']:
2148 logger.debug(" === Run statistics summary ===")
2149 for key, value in data['run_statistics'].items():
2150 logger.debug(value.nice_output(str('/'.join([key[0],'G%s'%key[1]]))).\
2151 replace(' statistics',''))
2152 logger.info(" " )
2153
2154 if format == "full":
2155 fsock.write(" === Results Summary for run: %s tag: %s process: %s ===\n" % \
2156 (data['run_name'],data['tag'], os.path.basename(self.me_dir)))
2157
2158 if self.ninitial == 1:
2159 fsock.write(" Width : %.4g +- %.4g GeV\n" % (data['cross'], data['error']))
2160 else:
2161 fsock.write(" Cross-section : %.4g +- %.4g pb\n" % (data['cross'], data['error']))
2162 fsock.write(" Nb of events : %s\n" % data['nb_event'] )
2163 if data['cross_pythia'] and data['nb_event_pythia']:
2164 if self.ninitial == 1:
2165 fsock.write(" Matched Width : %.4g +- %.4g GeV\n" % (data['cross_pythia'], data['error_pythia']))
2166 else:
2167 fsock.write(" Matched Cross-section : %.4g +- %.4g pb\n" % (data['cross_pythia'], data['error_pythia']))
2168 fsock.write(" Nb of events after Matching : %s\n" % data['nb_event_pythia'])
2169 fsock.write(" \n" )
2170 elif format == "short":
2171 if mode == "w":
2172 fsock.write("# run_name tag cross error Nb_event cross_after_matching nb_event_after matching\n")
2173
2174 if data['cross_pythia'] and data['nb_event_pythia']:
2175 text = "%(run_name)s %(tag)s %(cross)s %(error)s %(nb_event)s %(cross_pythia)s %(nb_event_pythia)s\n"
2176 else:
2177 text = "%(run_name)s %(tag)s %(cross)s %(error)s %(nb_event)s\n"
2178 fsock.write(text % data)
2179
2180
2182 """Main Commands: launch decay width calculation and automatic inclusion of
2183 calculated widths and BRs in the param_card."""
2184
2185 args = self.split_arg(line)
2186
2187 accuracy = self.check_calculate_decay_widths(args)
2188 self.ask_run_configuration('parton')
2189 self.banner = None
2190 if not args:
2191
2192 self.set_run_name(self.find_available_run_name(self.me_dir))
2193 else:
2194 self.set_run_name(args[0], reload_card=True)
2195 args.pop(0)
2196
2197 self.configure_directory()
2198
2199
2200 opts=[('accuracy', accuracy),
2201 ('points', 1000),
2202 ('iterations',9)]
2203
2204 logger.info('Calculating decay widths with run name %s' % self.run_name)
2205
2206 self.exec_cmd('survey %s %s' % \
2207 (self.run_name,
2208 " ".join(['--' + opt + '=' + str(val) for (opt,val) \
2209 in opts])),
2210 postcmd=False)
2211 self.refine_mode = "old"
2212 self.exec_cmd('combine_events', postcmd=False)
2213 self.exec_cmd('store_events', postcmd=False)
2214
2215 self.collect_decay_widths()
2216 self.print_results_in_shell(self.results.current)
2217 self.update_status('calculate_decay_widths done',
2218 level='parton', makehtml=False)
2219
2220
2221
2223 """ Collect the decay widths and calculate BRs for all particles, and put
2224 in param_card form.
2225 """
2226
2227 particle_dict = {}
2228 run_name = self.run_name
2229
2230
2231 for P_path in SubProcesses.get_subP(self.me_dir):
2232 ids = SubProcesses.get_subP_ids(P_path)
2233
2234
2235
2236 nb_output = len(ids) / (len(set([p[0] for p in ids])))
2237 results = open(pjoin(P_path, run_name + '_results.dat')).read().split('\n')[0]
2238 result = float(results.strip().split(' ')[0])
2239 for particles in ids:
2240 try:
2241 particle_dict[particles[0]].append([particles[1:], result/nb_output])
2242 except KeyError:
2243 particle_dict[particles[0]] = [[particles[1:], result/nb_output]]
2244
2245 self.update_width_in_param_card(particle_dict,
2246 initial = pjoin(self.me_dir, 'Cards', 'param_card.dat'),
2247 output=pjoin(self.me_dir, 'Events', run_name, "param_card.dat"))
2248
2249 @staticmethod
2251
2252
2253 if not output:
2254 output = initial
2255
2256 param_card_file = open(initial)
2257 param_card = param_card_file.read().split('\n')
2258 param_card_file.close()
2259
2260 decay_lines = []
2261 line_number = 0
2262
2263 while line_number < len(param_card):
2264 line = param_card[line_number]
2265 if line.lower().startswith('decay'):
2266
2267
2268 line = param_card.pop(line_number)
2269 line = line.split()
2270 particle = 0
2271 if int(line[1]) not in decay_info:
2272 try:
2273 particle = int(line[1])
2274 width = float(line[2])
2275 except Exception:
2276 particle = 0
2277
2278 line = param_card[line_number]
2279 while line.startswith('#') or line.startswith(' '):
2280 line = param_card.pop(line_number)
2281 if not particle or line.startswith('#'):
2282 line=param_card[line_number]
2283 continue
2284
2285 line = line.split()
2286 try:
2287 partial_width = float(line[0])*width
2288 decay_products = [int(p) for p in line[2:2+int(line[1])]]
2289 except Exception:
2290 line=param_card[line_number]
2291 continue
2292 try:
2293 decay_info[particle].append([decay_products, partial_width])
2294 except KeyError:
2295 decay_info[particle] = [[decay_products, partial_width]]
2296 if line_number == len(param_card):
2297 break
2298 line=param_card[line_number]
2299 if particle and particle not in decay_info:
2300
2301 decay_info[particle] = [[[], width]]
2302 else:
2303 line_number += 1
2304
2305 while not param_card[-1] or param_card[-1].startswith('#'):
2306 param_card.pop(-1)
2307
2308
2309 param_card.append("#\n#*************************")
2310 param_card.append("# Decay widths *")
2311 param_card.append("#*************************")
2312 for key in sorted(decay_info.keys()):
2313 width = sum([r for p,r in decay_info[key]])
2314 param_card.append("#\n# PDG Width")
2315 param_card.append("DECAY %i %e" % (key, width.real))
2316 if not width:
2317 continue
2318 if decay_info[key][0][0]:
2319 param_card.append("# BR NDA ID1 ID2 ...")
2320 brs = [[(val[1]/width).real, val[0]] for val in decay_info[key] if val[1]]
2321 for val in sorted(brs, reverse=True):
2322 param_card.append(" %e %i %s # %s" %
2323 (val[0].real, len(val[1]),
2324 " ".join([str(v) for v in val[1]]),
2325 val[0] * width
2326 ))
2327 decay_table = open(output, 'w')
2328 decay_table.write("\n".join(param_card) + "\n")
2329 decay_table.close()
2330 logger.info("Results written to %s" % output)
2331
2332
2333
2335
2336 args = self.split_arg(line)
2337
2338 mode = self.check_multi_run(args)
2339 nb_run = args.pop(0)
2340 if nb_run == 1:
2341 logger.warn("'multi_run 1' command is not optimal. Think of using generate_events instead")
2342 self.ask_run_configuration(mode)
2343
2344 self.check_survey(args, cmd='multi_run')
2345 main_name = self.run_name
2346
2347 path=pjoin(self.me_dir, 'Cards', 'param_card.dat')
2348 self.check_param_card(path, run=False)
2349
2350 param_card_iterator, self.param_card_iterator = self.param_card_iterator, []
2351
2352 crossoversig = 0
2353 inv_sq_err = 0
2354 nb_event = 0
2355 for i in range(nb_run):
2356 self.nb_refine = 0
2357 self.exec_cmd('generate_events %s_%s -f' % (main_name, i), postcmd=False)
2358
2359 nb_event += int(self.results[self.run_name][-1]['nb_event'])
2360 self.results.add_detail('nb_event', nb_event , run=main_name)
2361 cross = self.results[self.run_name][-1]['cross']
2362 error = self.results[self.run_name][-1]['error'] + 1e-99
2363 crossoversig+=cross/error**2
2364 inv_sq_err+=1.0/error**2
2365 self.results[main_name][-1]['cross'] = crossoversig/inv_sq_err
2366 self.results[main_name][-1]['error'] = math.sqrt(1.0/inv_sq_err)
2367 self.results.def_current(main_name)
2368 self.run_name = main_name
2369 self.update_status("Merging LHE files", level='parton')
2370 try:
2371 os.mkdir(pjoin(self.me_dir,'Events', self.run_name))
2372 except Exception:
2373 pass
2374 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'
2375 % {'bin': self.dirbin, 'event': pjoin(self.me_dir,'Events'),
2376 'name': self.run_name})
2377
2378 eradir = self.options['exrootanalysis_path']
2379 if eradir and misc.is_executable(pjoin(eradir,'ExRootLHEFConverter')):
2380 self.update_status("Create Root file", level='parton')
2381 misc.gunzip('%s/%s/unweighted_events.lhe.gz' %
2382 (pjoin(self.me_dir,'Events'), self.run_name))
2383
2384 self.create_root_file('%s/unweighted_events.lhe' % self.run_name,
2385 '%s/unweighted_events.root' % self.run_name)
2386
2387 path = pjoin(self.me_dir, "Events", self.run_name, "unweighted_events.lhe")
2388 self.create_plot('parton', path,
2389 pjoin(self.me_dir, 'HTML',self.run_name, 'plots_parton.html')
2390 )
2391
2392
2393 if not os.path.exists('%s.gz' % path):
2394 misc.gzip(path)
2395
2396 self.update_status('', level='parton')
2397 self.print_results_in_shell(self.results.current)
2398
2399 if param_card_iterator:
2400
2401 param_card_iterator.store_entry(self.run_name, self.results.current['cross'])
2402
2403 orig_name=self.run_name
2404 for card in param_card_iterator:
2405 card.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2406 self.exec_cmd("multi_run %s -f " % nb_run ,precmd=True, postcmd=True,errorhandling=False)
2407 param_card_iterator.store_entry(self.run_name, self.results.current['cross'])
2408 param_card_iterator.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2409 scan_name = misc.get_scan_name(orig_name, self.run_name)
2410 path = pjoin(self.me_dir, 'Events','scan_%s.txt' % scan_name)
2411 logger.info("write all cross-section results in %s" % path, '$MG:color:BLACK')
2412 param_card_iterator.write_summary(path)
2413
2414
2415
2417 """Advanced commands: create .inc files from param_card.dat/run_card.dat"""
2418
2419 if not mode and not opt:
2420 args = self.split_arg(line)
2421 mode, opt = self.check_treatcards(args)
2422
2423
2424
2425
2426 need_MadLoopFilterUpdate = False
2427
2428
2429 type_of_change = ''
2430 if not opt['forbid_MadLoopInit'] and self.proc_characteristics['loop_induced'] \
2431 and mode in ['loop', 'all']:
2432 paramDat = pjoin(self.me_dir, 'Cards','param_card.dat')
2433 paramInc = pjoin(opt['output_dir'], 'param_card.inc')
2434 if (not os.path.isfile(paramDat)) or (not os.path.isfile(paramInc)) or \
2435 (os.path.getmtime(paramDat)-os.path.getmtime(paramInc)) > 0.0:
2436 need_MadLoopFilterUpdate = True
2437 type_of_change = 'model'
2438
2439 ML_in = pjoin(self.me_dir, 'Cards', 'MadLoopParams.dat')
2440 ML_out = pjoin(self.me_dir,"SubProcesses",
2441 "MadLoop5_resources", "MadLoopParams.dat")
2442 if (not os.path.isfile(ML_in)) or (not os.path.isfile(ML_out)) or \
2443 (os.path.getmtime(ML_in)-os.path.getmtime(ML_out)) > 0.0:
2444 need_MadLoopFilterUpdate = True
2445 type_of_change = 'MadLoop'
2446
2447
2448 self.check_param_card(pjoin(self.me_dir, 'Cards','param_card.dat'))
2449
2450 if mode in ['param', 'all']:
2451 model = self.find_model_name()
2452 tmp_model = os.path.basename(model)
2453 if tmp_model == 'mssm' or tmp_model.startswith('mssm-'):
2454 if not '--param_card=' in line:
2455 param_card = pjoin(self.me_dir, 'Cards','param_card.dat')
2456 mg5_param = pjoin(self.me_dir, 'Source', 'MODEL', 'MG5_param.dat')
2457 check_param_card.convert_to_mg5card(param_card, mg5_param)
2458 check_param_card.check_valid_param_card(mg5_param)
2459 opt['param_card'] = pjoin(self.me_dir, 'Source', 'MODEL', 'MG5_param.dat')
2460 else:
2461 check_param_card.check_valid_param_card(opt['param_card'])
2462
2463 logger.debug('write compile file for card: %s' % opt['param_card'])
2464 param_card = check_param_card.ParamCard(opt['param_card'])
2465 outfile = pjoin(opt['output_dir'], 'param_card.inc')
2466 ident_card = pjoin(self.me_dir,'Cards','ident_card.dat')
2467 if os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')):
2468 default = pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')
2469 elif os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')):
2470 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
2471 elif not os.path.exists(pjoin(self.me_dir,'bin','internal','ufomodel')):
2472 fsock = open(pjoin(self.me_dir,'Source','param_card.inc'),'w')
2473 fsock.write(' ')
2474 fsock.close()
2475 if mode == 'all':
2476 self.do_treatcards('', 'run', opt)
2477 return
2478 else:
2479 devnull = open(os.devnull,'w')
2480 subprocess.call([sys.executable, 'write_param_card.py'],
2481 cwd=pjoin(self.me_dir,'bin','internal','ufomodel'),
2482 stdout=devnull)
2483 devnull.close()
2484 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
2485
2486 need_mp = self.proc_characteristics['loop_induced']
2487 param_card.write_inc_file(outfile, ident_card, default, need_mp=need_mp)
2488
2489
2490 if mode in ['run', 'all']:
2491 if not hasattr(self, 'run_card'):
2492 run_card = banner_mod.RunCard(opt['run_card'])
2493 else:
2494 run_card = self.run_card
2495 if self.ninitial == 1:
2496 run_card['lpp1'] = 0
2497 run_card['lpp2'] = 0
2498 run_card['ebeam1'] = 0
2499 run_card['ebeam2'] = 0
2500
2501 run_card.write_include_file(pjoin(opt['output_dir'],'run_card.inc'))
2502
2503
2504 if self.proc_characteristics['loop_induced'] and mode in ['loop', 'all']:
2505 self.MadLoopparam = banner_mod.MadLoopParam(pjoin(self.me_dir,
2506 'Cards', 'MadLoopParams.dat'))
2507
2508
2509
2510
2511 if 'WriteOutFilters' in self.MadLoopparam.user_set and \
2512 self.MadLoopparam.get('WriteOutFilters'):
2513 logger.info(
2514 """You chose to have MadLoop writing out filters.
2515 Beware that this can be dangerous for local multicore runs.""")
2516 self.MadLoopparam.set('WriteOutFilters',False, ifnotdefault=False)
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537 self.MadLoopparam.set('HelicityFilterLevel',1, ifnotdefault=False)
2538
2539
2540
2541 self.MadLoopparam.set('CheckCycle',4, ifnotdefault=False)
2542
2543
2544
2545
2546
2547 self.MadLoopparam.set('DoubleCheckHelicityFilter',False,
2548 ifnotdefault=False)
2549
2550
2551
2552 if not hasattr(self, 'run_card'):
2553 run_card = banner_mod.RunCard(opt['run_card'])
2554 else:
2555 run_card = self.run_card
2556 if run_card['nhel'] == 0:
2557 if 'MLReductionLib' in self.MadLoopparam.user_set and \
2558 (self.MadLoopparam.get('MLReductionLib').startswith('1') or
2559 self.MadLoopparam.get('MLReductionLib').startswith('6')):
2560 logger.warning(
2561 """You chose to set the preferred reduction technique in MadLoop to be OPP (see parameter MLReductionLib).
2562 Beware that this can bring significant slowdown; the optimal choice --when not MC over helicity-- being to first start with TIR reduction.""")
2563
2564 self.MadLoopparam.set('MLReductionLib','2|6|1', ifnotdefault=False)
2565 else:
2566 if 'MLReductionLib' in self.MadLoopparam.user_set and \
2567 not (self.MadLoopparam.get('MLReductionLib').startswith('1') or
2568 self.MadLoopparam.get('MLReductionLib').startswith('6')):
2569 logger.warning(
2570 """You chose to set the preferred reduction technique in MadLoop to be different than OPP (see parameter MLReductionLib).
2571 Beware that this can bring significant slowdown; the optimal choice --when MC over helicity-- being to first start with OPP reduction.""")
2572 self.MadLoopparam.set('MLReductionLib','6|1|2', ifnotdefault=False)
2573
2574
2575
2576
2577
2578 if run_card['nhel'] == 0:
2579 if ('NRotations_DP' in self.MadLoopparam.user_set and \
2580 self.MadLoopparam.get('NRotations_DP')!=0) or \
2581 ('NRotations_QP' in self.MadLoopparam.user_set and \
2582 self.MadLoopparam.get('NRotations_QP')!=0):
2583 logger.warning(
2584 """You chose to also use a lorentz rotation for stability tests (see parameter NRotations_[DP|QP]).
2585 Beware that, for optimization purposes, MadEvent uses manual TIR cache clearing which is not compatible
2586 with the lorentz rotation stability test. The number of these rotations to be used will be reset to
2587 zero by MadLoop. You can avoid this by changing the parameter 'FORCE_ML_HELICITY_SUM' int he matrix<i>.f
2588 files to be .TRUE. so that the sum over helicity configurations is performed within MadLoop (in which case
2589 the helicity of final state particles cannot be speicfied in the LHE file.""")
2590 self.MadLoopparam.set('NRotations_DP',0,ifnotdefault=False)
2591 self.MadLoopparam.set('NRotations_QP',0,ifnotdefault=False)
2592 else:
2593
2594
2595
2596
2597
2598
2599 self.MadLoopparam.set('NRotations_DP',1,ifnotdefault=False)
2600 self.MadLoopparam.set('NRotations_QP',0,ifnotdefault=False)
2601
2602
2603
2604
2605
2606
2607
2608
2609 if self.proc_characteristics['nexternal']<=4:
2610 if ('MLStabThres' in self.MadLoopparam.user_set and \
2611 self.MadLoopparam.get('MLStabThres')>1.0e-7):
2612 logger.warning(
2613 """You chose to increase the default value of the MadLoop parameter 'MLStabThres' above 1.0e-7.
2614 Stability tests can be less reliable on the limited kinematic of processes with less or equal
2615 than four external legs, so this is not recommended (especially not for g g > z z).""")
2616 self.MadLoopparam.set('MLStabThres',1.0e-7,ifnotdefault=False)
2617 else:
2618 self.MadLoopparam.set('MLStabThres',1.0e-4,ifnotdefault=False)
2619
2620
2621 self.MadLoopparam.write(pjoin(self.me_dir,"SubProcesses","MadLoop5_resources",
2622 "MadLoopParams.dat"))
2623
2624 if self.proc_characteristics['loop_induced'] and mode in ['loop', 'all']:
2625
2626
2627 if need_MadLoopFilterUpdate:
2628 logger.debug('Changes to the %s parameters'%type_of_change+\
2629 ' have been detected. Madevent will then now reinitialize'+\
2630 ' MadLoop filters.')
2631 self.exec_cmd('initMadLoop -r -f')
2632
2633
2634
2635
2636
2637 elif not opt['forbid_MadLoopInit'] and \
2638 MadLoopInitializer.need_MadLoopInit(self.me_dir):
2639 self.exec_cmd('initMadLoop -f')
2640
2641
2643 """Advanced commands: launch survey for the current process """
2644
2645
2646 args = self.split_arg(line)
2647
2648 self.check_survey(args)
2649
2650
2651 if os.path.exists(pjoin(self.me_dir,'error')):
2652 os.remove(pjoin(self.me_dir,'error'))
2653
2654 self.configure_directory()
2655
2656 self.random_orig = self.random
2657 logger.info("Using random number seed offset = %s" % self.random)
2658
2659 self.update_random()
2660 self.save_random()
2661 self.update_status('Running Survey', level=None)
2662 if self.cluster_mode:
2663 logger.info('Creating Jobs')
2664
2665 self.total_jobs = 0
2666 subproc = [l.strip() for l in open(pjoin(self.me_dir,
2667 'SubProcesses', 'subproc.mg'))]
2668
2669 P_zero_result = []
2670
2671
2672 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
2673 'MadLoop5_resources')) and cluster.need_transfer(self.options):
2674 tf=tarfile.open(pjoin(self.me_dir, 'SubProcesses',
2675 'MadLoop5_resources.tar.gz'), 'w:gz', dereference=True)
2676 tf.add(pjoin(self.me_dir,'SubProcesses','MadLoop5_resources'),
2677 arcname='MadLoop5_resources')
2678 tf.close()
2679
2680 logger.info('Working on SubProcesses')
2681 ajobcreator = gen_ximprove.gensym(self)
2682
2683
2684 if float(self.run_card['mmjj']) > 0.01 * (float(self.run_card['ebeam1'])+float(self.run_card['ebeam2'])):
2685 self.pass_in_difficult_integration_mode()
2686
2687 jobs, P_zero_result = ajobcreator.launch()
2688
2689
2690 if P_zero_result:
2691 if len(P_zero_result) == len(subproc):
2692 Pdir = pjoin(self.me_dir, 'SubProcesses',subproc[0].strip())
2693 raise ZeroResult, '%s' % \
2694 open(pjoin(Pdir,'ajob.no_ps.log')).read()
2695 else:
2696 logger.warning(''' %s SubProcesses doesn\'t have available phase-space.
2697 Please check mass spectrum.''' % ','.join(P_zero_result))
2698
2699
2700 self.monitor(run_type='All jobs submitted for survey', html=True)
2701 if not self.history or 'survey' in self.history[-1] or self.ninitial ==1 or \
2702 self.run_card['gridpack']:
2703
2704 cross, error = sum_html.make_all_html_results(self)
2705 self.results.add_detail('cross', cross)
2706 self.results.add_detail('error', error)
2707 self.exec_cmd("print_results %s" % self.run_name,
2708 errorhandling=False, printcmd=False, precmd=False, postcmd=False)
2709
2710 self.results.add_detail('run_statistics', dict(ajobcreator.run_statistics))
2711 self.update_status('End survey', 'parton', makehtml=False)
2712
2713
2715 """be more secure for the integration to not miss it due to strong cut"""
2716
2717
2718 if self.opts['points'] == self._survey_options['points'][1]:
2719 self.opts['points'] = 2 * self._survey_options['points'][1]
2720 if self.opts['iterations'] == self._survey_options['iterations'][1]:
2721 self.opts['iterations'] = 1 + self._survey_options['iterations'][1]
2722 if self.opts['accuracy'] == self._survey_options['accuracy'][1]:
2723 self.opts['accuracy'] = self._survey_options['accuracy'][1]/2
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737 for name in ['../bin/internal/gen_ximprove', 'all',
2738 '../bin/internal/combine_events']:
2739 self.compile(arg=[name], cwd=os.path.join(self.me_dir, 'Source'))
2740
2741
2742
2744 """Advanced commands: launch survey for the current process """
2745 devnull = open(os.devnull, 'w')
2746 self.nb_refine += 1
2747 args = self.split_arg(line)
2748
2749 self.check_refine(args)
2750
2751 refine_opt = {'err_goal': args[0], 'split_channels': True}
2752 precision = args[0]
2753 if len(args) == 2:
2754 refine_opt['max_process']= args[1]
2755
2756
2757
2758 self.configure_directory()
2759
2760
2761 self.update_random()
2762 self.save_random()
2763
2764 if self.cluster_mode:
2765 logger.info('Creating Jobs')
2766 self.update_status('Refine results to %s' % precision, level=None)
2767
2768 self.total_jobs = 0
2769 subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses',
2770 'subproc.mg'))]
2771
2772
2773 for nb_proc,subdir in enumerate(subproc):
2774 subdir = subdir.strip()
2775 Pdir = pjoin(self.me_dir, 'SubProcesses', subdir)
2776 for match in misc.glob('*ajob*', Pdir):
2777 if os.path.basename(match)[:4] in ['ajob', 'wait', 'run.', 'done']:
2778 os.remove(match)
2779
2780 x_improve = gen_ximprove.gen_ximprove(self, refine_opt)
2781
2782 survey_statistics = dict(self.results.get_detail('run_statistics'))
2783
2784 if __debug__ and survey_statistics:
2785 globalstat = sum_html.RunStatistics()
2786 logger.debug(" === Survey statistics summary ===")
2787 for key, value in survey_statistics.items():
2788 globalstat.aggregate_statistics(value)
2789 level = 5
2790 if value.has_warning():
2791 level = 10
2792 logger.log(level,
2793 value.nice_output(str('/'.join([key[0],'G%s'%key[1]]))).
2794 replace(' statistics',''))
2795 logger.debug(globalstat.nice_output('combined', no_warning=True))
2796
2797 if survey_statistics:
2798 x_improve.run_statistics = survey_statistics
2799
2800 x_improve.launch()
2801 if not self.history or 'refine' not in self.history[-1]:
2802 cross, error = x_improve.update_html()
2803 if cross == 0:
2804 return
2805 logger.info("Current estimate of cross-section: %s +- %s" % (cross, error))
2806
2807
2808 if isinstance(x_improve, gen_ximprove.gen_ximprove_v4):
2809
2810
2811 for nb_proc,subdir in enumerate(subproc):
2812 subdir = subdir.strip()
2813 Pdir = pjoin(self.me_dir, 'SubProcesses',subdir)
2814 bindir = pjoin(os.path.relpath(self.dirbin, Pdir))
2815
2816 logger.info(' %s ' % subdir)
2817
2818 if os.path.exists(pjoin(Pdir, 'ajob1')):
2819 self.compile(['madevent'], cwd=Pdir)
2820
2821 alljobs = misc.glob('ajob*', Pdir)
2822
2823
2824 Gre = re.compile("\s*j=(G[\d\.\w]+)")
2825 for job in alljobs:
2826 Gdirs = Gre.findall(open(job).read())
2827 for Gdir in Gdirs:
2828 if os.path.exists(pjoin(Pdir, Gdir, 'results.dat')):
2829 os.remove(pjoin(Pdir, Gdir,'results.dat'))
2830
2831 nb_tot = len(alljobs)
2832 self.total_jobs += nb_tot
2833 for i, job in enumerate(alljobs):
2834 job = os.path.basename(job)
2835 self.launch_job('%s' % job, cwd=Pdir, remaining=(nb_tot-i-1),
2836 run_type='Refine number %s on %s (%s/%s)' %
2837 (self.nb_refine, subdir, nb_proc+1, len(subproc)))
2838
2839 self.monitor(run_type='All job submitted for refine number %s' % self.nb_refine,
2840 html=True)
2841
2842 self.update_status("Combining runs", level='parton')
2843 try:
2844 os.remove(pjoin(Pdir, 'combine_runs.log'))
2845 except Exception:
2846 pass
2847
2848 if isinstance(x_improve, gen_ximprove.gen_ximprove_v4):
2849
2850
2851 combine_runs.CombineRuns(self.me_dir)
2852 self.refine_mode = "old"
2853 else:
2854 self.refine_mode = "new"
2855
2856 cross, error = sum_html.make_all_html_results(self)
2857 self.results.add_detail('cross', cross)
2858 self.results.add_detail('error', error)
2859
2860 self.results.add_detail('run_statistics',
2861 dict(self.results.get_detail('run_statistics')))
2862
2863 self.update_status('finish refine', 'parton', makehtml=False)
2864 devnull.close()
2865
2866
2868 """Not in help: Combine a given iteration combine_iteration Pdir Gdir S|R step
2869 S is for survey
2870 R is for refine
2871 step is the iteration number (not very critical)"""
2872
2873 self.set_run_name("tmp")
2874 self.configure_directory(html_opening=False)
2875 Pdir, Gdir, mode, step = self.split_arg(line)
2876 if Gdir.startswith("G"):
2877 Gdir = Gdir[1:]
2878 if "SubProcesses" not in Pdir:
2879 Pdir = pjoin(self.me_dir, "SubProcesses", Pdir)
2880 if mode == "S":
2881 self.opts = dict([(key,value[1]) for (key,value) in \
2882 self._survey_options.items()])
2883 gensym = gen_ximprove.gensym(self)
2884 gensym.combine_iteration(Pdir, Gdir, int(step))
2885 elif mode == "R":
2886 refine = gen_ximprove.gen_ximprove_share(self)
2887 refine.combine_iteration(Pdir, Gdir, int(step))
2888
2889
2890
2891
2892
2894 """Advanced commands: Launch combine events"""
2895
2896 args = self.split_arg(line)
2897
2898 self.check_combine_events(args)
2899
2900 self.update_status('Combining Events', level='parton')
2901
2902
2903 if not hasattr(self, "refine_mode") or self.refine_mode == "old":
2904 try:
2905 os.remove(pjoin(self.me_dir,'SubProcesses', 'combine.log'))
2906 except Exception:
2907 pass
2908
2909 tmpcluster = cluster.MultiCore(nb_core=1)
2910 tmpcluster.launch_and_wait('../bin/internal/run_combine',
2911 args=[self.run_name],
2912 cwd=pjoin(self.me_dir,'SubProcesses'),
2913 stdout=pjoin(self.me_dir,'SubProcesses', 'combine.log'),
2914 required_output=[pjoin(self.me_dir,'SubProcesses', 'combine.log')])
2915
2916
2917
2918
2919
2920
2921 output = misc.mult_try_open(pjoin(self.me_dir,'SubProcesses','combine.log')).read()
2922
2923 pat = re.compile(r'''\s*Unweighting\s*selected\s*(\d+)\s*events''')
2924 try:
2925 nb_event = pat.search(output).groups()[0]
2926 except AttributeError:
2927 time.sleep(10)
2928 output = misc.mult_try_open(pjoin(self.me_dir,'SubProcesses','combine.log')).read()
2929 try:
2930 nb_event = pat.search(output).groups()[0]
2931 except AttributeError:
2932 logger.warning('Fail to read the number of unweighted events in the combine.log file')
2933 nb_event = 0
2934
2935 self.results.add_detail('nb_event', nb_event)
2936
2937
2938
2939 tag = self.run_card['run_tag']
2940
2941
2942 if not self.banner:
2943 self.banner = banner_mod.recover_banner(self.results, 'parton')
2944 self.banner.load_basic(self.me_dir)
2945
2946 self.banner.add_generation_info(self.results.current['cross'], nb_event)
2947 if not hasattr(self, 'random_orig'): self.random_orig = 0
2948 self.banner.change_seed(self.random_orig)
2949 if not os.path.exists(pjoin(self.me_dir, 'Events', self.run_name)):
2950 os.mkdir(pjoin(self.me_dir, 'Events', self.run_name))
2951 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name,
2952 '%s_%s_banner.txt' % (self.run_name, tag)))
2953
2954
2955 self.banner.add_to_file(pjoin(self.me_dir,'Events', 'events.lhe'),
2956 out=pjoin(self.me_dir,'Events', self.run_name, 'events.lhe'))
2957 self.banner.add_to_file(pjoin(self.me_dir,'Events', 'unweighted_events.lhe'),
2958 out=pjoin(self.me_dir,'Events', self.run_name, 'unweighted_events.lhe'))
2959
2960
2961 elif self.refine_mode == "new":
2962
2963 tag = self.run_card['run_tag']
2964
2965 if not self.banner:
2966 self.banner = banner_mod.recover_banner(self.results, 'parton')
2967 self.banner.load_basic(self.me_dir)
2968
2969 self.banner.add_generation_info(self.results.current['cross'], self.run_card['nevents'])
2970 if not hasattr(self, 'random_orig'): self.random_orig = 0
2971 self.banner.change_seed(self.random_orig)
2972 if not os.path.exists(pjoin(self.me_dir, 'Events', self.run_name)):
2973 os.mkdir(pjoin(self.me_dir, 'Events', self.run_name))
2974 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name,
2975 '%s_%s_banner.txt' % (self.run_name, tag)))
2976
2977
2978 AllEvent = lhe_parser.MultiEventFile()
2979 AllEvent.banner = self.banner
2980
2981 for Gdir,mfactor in self.get_Gdir():
2982 if os.path.exists(pjoin(Gdir, 'events.lhe')):
2983 result = sum_html.OneResult('')
2984 result.read_results(pjoin(Gdir, 'results.dat'))
2985 AllEvent.add(pjoin(Gdir, 'events.lhe'),
2986 result.get('xsec'),
2987 result.get('xerru'),
2988 result.get('axsec')
2989 )
2990
2991 get_wgt = lambda event: event.wgt
2992 nb_event = AllEvent.unweight(pjoin(self.me_dir, "Events", self.run_name, "unweighted_events.lhe.gz"),
2993 get_wgt, trunc_error=1e-2, event_target=self.run_card['nevents'],
2994 log_level=logging.DEBUG)
2995
2996 self.results.add_detail('nb_event', nb_event)
2997
2998 self.to_store.append('event')
2999 eradir = self.options['exrootanalysis_path']
3000 madir = self.options['madanalysis_path']
3001 td = self.options['td_path']
3002 if eradir and misc.is_executable(pjoin(eradir,'ExRootLHEFConverter')) and\
3003 os.path.exists(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe')):
3004 if not os.path.exists(pjoin(self.me_dir, 'Events', self.run_name)):
3005 os.mkdir(pjoin(self.me_dir, 'Events', self.run_name))
3006 self.create_root_file(output='%s/unweighted_events.root' % \
3007 self.run_name)
3008
3009
3011 """Advanced commands: Launch store events"""
3012
3013 args = self.split_arg(line)
3014
3015 self.check_combine_events(args)
3016 self.update_status('Storing parton level results', level='parton')
3017
3018 run = self.run_name
3019 tag = self.run_card['run_tag']
3020 devnull = open(os.devnull, 'w')
3021
3022 if not os.path.exists(pjoin(self.me_dir, 'Events', run)):
3023 os.mkdir(pjoin(self.me_dir, 'Events', run))
3024 if not os.path.exists(pjoin(self.me_dir, 'HTML', run)):
3025 os.mkdir(pjoin(self.me_dir, 'HTML', run))
3026
3027
3028 input = pjoin(self.me_dir, 'SubProcesses', 'results.dat')
3029 output = pjoin(self.me_dir, 'SubProcesses', '%s_results.dat' % run)
3030 files.cp(input, output)
3031
3032
3033
3034
3035 if self.results.current['nb_event'] == 0:
3036 logger.warning("No event detected. No cleaning performed! This should allow to run:\n" +
3037 " cd Subprocesses; ../bin/internal/combine_events\n"+
3038 " to have your events if those one are missing.")
3039 else:
3040 for P_path in SubProcesses.get_subP(self.me_dir):
3041 G_dir = [G for G in os.listdir(P_path) if G.startswith('G') and
3042 os.path.isdir(pjoin(P_path,G))]
3043 for G in G_dir:
3044 G_path = pjoin(P_path,G)
3045 try:
3046
3047 if os.path.exists(pjoin(G_path, 'events.lhe')):
3048 os.remove(pjoin(G_path, 'events.lhe'))
3049 except Exception:
3050 continue
3051 try:
3052
3053 if os.path.exists(pjoin(G_path, 'results.dat')):
3054 input = pjoin(G_path, 'results.dat')
3055 output = pjoin(G_path, '%s_results.dat' % run)
3056 files.cp(input, output)
3057 except Exception:
3058 continue
3059
3060 try:
3061 if os.path.exists(pjoin(G_path, 'log.txt')):
3062 input = pjoin(G_path, 'log.txt')
3063 output = pjoin(G_path, '%s_log.txt' % run)
3064 files.mv(input, output)
3065 except Exception:
3066 continue
3067 try:
3068
3069 for name in ['ftn26']:
3070 if os.path.exists(pjoin(G_path, name)):
3071 if os.path.exists(pjoin(G_path, '%s_%s.gz'%(run,name))):
3072 os.remove(pjoin(G_path, '%s_%s.gz'%(run,name)))
3073 input = pjoin(G_path, name)
3074 output = pjoin(G_path, '%s_%s' % (run,name))
3075 files.mv(input, output)
3076 misc.gzip(pjoin(G_path, output), error=None)
3077 except Exception:
3078 continue
3079
3080 if os.path.exists(pjoin(G_path, 'ftn25')):
3081 os.remove(pjoin(G_path, 'ftn25'))
3082
3083
3084 misc.call(['%s/gen_cardhtml-pl' % self.dirbin],
3085 cwd=pjoin(self.me_dir))
3086
3087
3088
3089 E_path = pjoin(self.me_dir, 'Events')
3090 O_path = pjoin(self.me_dir, 'Events', run)
3091
3092
3093 for name in ['events.lhe', 'unweighted_events.lhe']:
3094 finput = pjoin(E_path, name)
3095 foutput = pjoin(O_path, name)
3096 if os.path.exists(finput):
3097 logger.debug("File %s exists BAAAAD. Not move anymore!" % pjoin(E_path, name))
3098 if os.path.exists(foutput):
3099 misc.gzip(foutput, stdout="%s.gz" % foutput, error=False)
3100
3101
3102
3103
3104
3105
3106 self.update_status('End Parton', level='parton', makehtml=False)
3107 devnull.close()
3108
3109
3110
3112 """Advanced commands: Create gridpack from present run"""
3113
3114 self.update_status('Creating gridpack', level='parton')
3115
3116 misc.compile(['../bin/internal/gen_ximprove'], cwd=pjoin(self.me_dir, "Source"))
3117 args = self.split_arg(line)
3118 self.check_combine_events(args)
3119 if not self.run_tag: self.run_tag = 'tag_1'
3120 os.system("sed -i.bak \"s/ *.false.*=.*GridRun/ .true. = GridRun/g\" %s/Cards/grid_card.dat" \
3121 % self.me_dir)
3122 misc.call(['./bin/internal/restore_data', self.run_name],
3123 cwd=self.me_dir)
3124 misc.call(['./bin/internal/store4grid',
3125 self.run_name, self.run_tag],
3126 cwd=self.me_dir)
3127 misc.call(['./bin/internal/clean'], cwd=self.me_dir)
3128 misc.call(['./bin/internal/make_gridpack'], cwd=self.me_dir)
3129 files.mv(pjoin(self.me_dir, 'gridpack.tar.gz'),
3130 pjoin(self.me_dir, '%s_gridpack.tar.gz' % self.run_name))
3131 os.system("sed -i.bak \"s/\s*.true.*=.*GridRun/ .false. = GridRun/g\" %s/Cards/grid_card.dat" \
3132 % self.me_dir)
3133 self.update_status('gridpack created', level='gridpack')
3134
3135
3137 """launch pythia"""
3138
3139
3140 args = self.split_arg(line)
3141 if '--no_default' in args:
3142 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pythia_card.dat')):
3143 return
3144 no_default = True
3145 args.remove('--no_default')
3146 else:
3147 no_default = False
3148
3149 if not self.run_name:
3150 self.check_pythia(args)
3151 self.configure_directory(html_opening =False)
3152 else:
3153
3154 self.configure_directory(html_opening =False)
3155 self.check_pythia(args)
3156
3157
3158
3159 if not no_default:
3160 self.ask_pythia_run_configuration(args[-1])
3161
3162 if self.options['automatic_html_opening']:
3163 misc.open_file(os.path.join(self.me_dir, 'crossx.html'))
3164 self.options['automatic_html_opening'] = False
3165
3166
3167 if not self.banner or len(self.banner) <=1:
3168 self.banner = banner_mod.recover_banner(self.results, 'pythia')
3169
3170
3171
3172 pythia_src = pjoin(self.options['pythia-pgs_path'],'src')
3173
3174 self.update_status('Running Pythia', 'pythia')
3175 try:
3176 os.remove(pjoin(self.me_dir,'Events','pythia.done'))
3177 except Exception:
3178 pass
3179
3180
3181
3182 if not re.search(r'^\s*LHAPATH=%s/PDFsets' % pythia_src,
3183 open(pjoin(self.me_dir,'Cards','pythia_card.dat')).read(),
3184 re.M):
3185 f = open(pjoin(self.me_dir,'Cards','pythia_card.dat'),'a')
3186 f.write('\n LHAPATH=%s/PDFsets' % pythia_src)
3187 f.close()
3188 tag = self.run_tag
3189 pythia_log = pjoin(self.me_dir, 'Events', self.run_name , '%s_pythia.log' % tag)
3190 self.cluster.launch_and_wait('../bin/internal/run_pythia',
3191 argument= [pythia_src], stdout= pythia_log,
3192 stderr=subprocess.STDOUT,
3193 cwd=pjoin(self.me_dir,'Events'))
3194
3195 os.remove(pjoin(self.me_dir, "Events", "unweighted_events.lhe"))
3196
3197
3198
3199 if not os.path.exists(pjoin(self.me_dir,'Events','pythia.done')):
3200 logger.warning('Fail to produce pythia output. More info in \n %s' % pythia_log)
3201 return
3202 else:
3203 os.remove(pjoin(self.me_dir,'Events','pythia.done'))
3204
3205 self.to_store.append('pythia')
3206
3207
3208 if int(self.run_card['ickkw']):
3209
3210 pythia_log = misc.BackRead(pjoin(self.me_dir,'Events', self.run_name,
3211 '%s_pythia.log' % tag))
3212 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")
3213 for line in pythia_log:
3214 info = pythiare.search(line)
3215 if not info:
3216 continue
3217 try:
3218
3219 sigma_m = float(info.group('xsec').replace('D','E')) *1e9
3220 Nacc = int(info.group('generated'))
3221 Ntry = int(info.group('tried'))
3222 except ValueError:
3223
3224 self.results.add_detail('cross_pythia', 0)
3225 self.results.add_detail('nb_event_pythia', 0)
3226 self.results.add_detail('error_pythia', 0)
3227 else:
3228 self.results.add_detail('cross_pythia', sigma_m)
3229 self.results.add_detail('nb_event_pythia', Nacc)
3230
3231 error = self.results[self.run_name].return_tag(self.run_tag)['error']
3232 if Nacc:
3233 error_m = math.sqrt((error * Nacc/Ntry)**2 + sigma_m**2 *(1-Nacc/Ntry)/Nacc)
3234 else:
3235 error_m = 10000 * sigma_m
3236
3237 self.results.add_detail('error_pythia', error_m)
3238 break
3239
3240 pythia_log.close()
3241
3242 pydir = pjoin(self.options['pythia-pgs_path'], 'src')
3243 eradir = self.options['exrootanalysis_path']
3244 madir = self.options['madanalysis_path']
3245 td = self.options['td_path']
3246
3247
3248
3249
3250
3251 self.banner.add(pjoin(self.me_dir, 'Cards','pythia_card.dat'))
3252 if int(self.run_card['ickkw']):
3253
3254 if 'MGGenerationInfo' in self.banner:
3255 self.banner['MGGenerationInfo'] += '# Matched Integrated weight (pb) : %s\n' % self.results.current['cross_pythia']
3256 else:
3257 self.banner['MGGenerationInfo'] = '# Matched Integrated weight (pb) : %s\n' % self.results.current['cross_pythia']
3258 banner_path = pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, tag))
3259 self.banner.write(banner_path)
3260
3261
3262 self.run_hep2lhe(banner_path)
3263 if int(self.run_card['ickkw']):
3264 misc.gzip(pjoin(self.me_dir,'Events','beforeveto.tree'),
3265 stdout=pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_beforeveto.tree.gz'))
3266 if self.run_card['use_syst'] in self.true:
3267
3268 try:
3269 self.run_syscalc('Pythia')
3270 except SysCalcError, error:
3271 logger.error(str(error))
3272 else:
3273 if os.path.exists(pjoin(self.me_dir,'Events', 'syst.dat')):
3274
3275 misc.gzip(pjoin(self.me_dir,'Events', 'syst.dat'),
3276 stdout=pjoin(self.me_dir,'Events',self.run_name, tag + '_pythia_syst.dat.gz'))
3277
3278
3279 if os.path.exists(pjoin(self.me_dir, 'Events', 'syscalc.dat')):
3280 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
3281 '%s_syscalc.dat' % self.run_tag)
3282 misc.gzip(pjoin(self.me_dir, 'Events','syscalc.dat'),
3283 stdout = "%s.gz" % filename)
3284
3285
3286 self.create_plot('Pythia')
3287
3288 if os.path.exists(pjoin(self.me_dir,'Events','pythia_events.lhe')):
3289 misc.gzip(pjoin(self.me_dir,'Events','pythia_events.lhe'),
3290 stdout=pjoin(self.me_dir,'Events', self.run_name,'%s_pythia_events.lhe.gz' % tag))
3291
3292 self.update_status('finish', level='pythia', makehtml=False)
3293 self.exec_cmd('pgs --no_default', postcmd=False, printcmd=False)
3294 if self.options['delphes_path']:
3295 self.exec_cmd('delphes --no_default', postcmd=False, printcmd=False)
3296 self.print_results_in_shell(self.results.current)
3297
3298
3299
3301 """Remove one/all run or only part of it"""
3302
3303 args = self.split_arg(line)
3304 run, tag, mode = self.check_remove(args)
3305 if 'banner' in mode:
3306 mode.append('all')
3307
3308
3309 if run == 'all':
3310
3311 if os.path.exists(pjoin(self.me_dir, 'Events', 'all')):
3312 logger.warning('A run with name all exists. So we will not supress all processes.')
3313 else:
3314 for match in misc.glob(pjoin('*','*_banner.txt'), pjoin(self.me_dir, 'Events')):
3315 run = match.rsplit(os.path.sep,2)[1]
3316 if self.force:
3317 args.append('-f')
3318 try:
3319 self.exec_cmd('remove %s %s' % (run, ' '.join(args[1:]) ) )
3320 except self.InvalidCmd, error:
3321 logger.info(error)
3322 pass
3323 return
3324
3325
3326 if not os.path.exists(pjoin(self.me_dir, 'Events', run)):
3327 raise self.InvalidCmd('No run \'%s\' detected' % run)
3328
3329 try:
3330 self.resuls.def_current(run)
3331 self.update_status(' Cleaning %s' % run, level=None)
3332 except Exception:
3333 misc.sprint('fail to update results or html status')
3334 pass
3335
3336
3337
3338
3339 to_delete = misc.glob('*', pjoin(self.me_dir, 'Events', run))
3340 to_delete += misc.glob('*', pjoin(self.me_dir, 'HTML', run))
3341
3342 to_delete = [os.path.basename(f) for f in to_delete if 'banner' not in f]
3343 if tag:
3344 to_delete = [f for f in to_delete if tag in f]
3345 if 'parton' in mode or 'all' in mode:
3346 try:
3347 if self.results[run][0]['tag'] != tag:
3348 raise Exception, 'dummy'
3349 except Exception:
3350 pass
3351 else:
3352 nb_rm = len(to_delete)
3353 if os.path.exists(pjoin(self.me_dir, 'Events', run, 'events.lhe.gz')):
3354 to_delete.append('events.lhe.gz')
3355 if os.path.exists(pjoin(self.me_dir, 'Events', run, 'unweighted_events.lhe.gz')):
3356 to_delete.append('unweighted_events.lhe.gz')
3357 if os.path.exists(pjoin(self.me_dir, 'HTML', run,'plots_parton.html')):
3358 to_delete.append(pjoin(self.me_dir, 'HTML', run,'plots_parton.html'))
3359 if nb_rm != len(to_delete):
3360 logger.warning('Be carefull that partonic information are on the point to be removed.')
3361 if 'all' in mode:
3362 pass
3363 else:
3364 if 'pythia' not in mode:
3365 to_delete = [f for f in to_delete if 'pythia' not in f]
3366 if 'pgs' not in mode:
3367 to_delete = [f for f in to_delete if 'pgs' not in f]
3368 if 'delphes' not in mode:
3369 to_delete = [f for f in to_delete if 'delphes' not in f]
3370 if 'parton' not in mode:
3371 to_delete = [f for f in to_delete if 'delphes' in f
3372 or 'pgs' in f
3373 or 'pythia' in f]
3374 if not self.force and len(to_delete):
3375 question = 'Do you want to delete the following files?\n %s' % \
3376 '\n '.join(to_delete)
3377 ans = self.ask(question, 'y', choices=['y','n'])
3378 else:
3379 ans = 'y'
3380
3381 if ans == 'y':
3382 for file2rm in to_delete:
3383 if os.path.exists(pjoin(self.me_dir, 'Events', run, file2rm)):
3384 try:
3385 os.remove(pjoin(self.me_dir, 'Events', run, file2rm))
3386 except Exception:
3387 shutil.rmtree(pjoin(self.me_dir, 'Events', run, file2rm))
3388 else:
3389 try:
3390 os.remove(pjoin(self.me_dir, 'HTML', run, file2rm))
3391 except Exception:
3392 shutil.rmtree(pjoin(self.me_dir, 'HTML', run, file2rm))
3393
3394
3395
3396
3397 if 'all' in mode or 'channel' in mode:
3398 try:
3399 if tag and self.results[run][0]['tag'] != tag:
3400 raise Exception, 'dummy'
3401 except Exception:
3402 pass
3403 else:
3404 to_delete = misc.glob('%s*' % run, pjoin(self.me_dir, 'SubProcesses'))
3405 to_delete += misc.glob(pjoin('*','%s*' % run), pjoin(self.me_dir, 'SubProcesses'))
3406 to_delete += misc.glob(pjoin('*','*','%s*' % run), pjoin(self.me_dir, 'SubProcesses'))
3407
3408 if self.force or len(to_delete) == 0:
3409 ans = 'y'
3410 else:
3411 question = 'Do you want to delete the following files?\n %s' % \
3412 '\n '.join(to_delete)
3413 ans = self.ask(question, 'y', choices=['y','n'])
3414
3415 if ans == 'y':
3416 for file2rm in to_delete:
3417 os.remove(file2rm)
3418
3419 if 'banner' in mode:
3420 to_delete = misc.glob('*', pjoin(self.me_dir, 'Events', run))
3421 if tag:
3422
3423 try:
3424 os.remove(pjoin(self.me_dir, 'Events',run,'%s_%s_banner.txt' % (run,tag)))
3425 except Exception:
3426 logger.warning('fail to remove the banner')
3427
3428 if run in self.results:
3429 self.results.delete_run(run, tag)
3430 return
3431 elif any(['banner' not in os.path.basename(p) for p in to_delete]):
3432 if to_delete:
3433 raise MadGraph5Error, '''Some output still exists for this run.
3434 Please remove those output first. Do for example:
3435 remove %s all banner
3436 ''' % run
3437 else:
3438 shutil.rmtree(pjoin(self.me_dir, 'Events',run))
3439 if run in self.results:
3440 self.results.delete_run(run)
3441 return
3442 else:
3443 logger.info('''The banner is not removed. In order to remove it run:
3444 remove %s all banner %s''' % (run, tag and '--tag=%s ' % tag or ''))
3445
3446
3447 self.results.clean(mode, run, tag)
3448 self.update_status('', level='all')
3449
3450
3451
3452
3454 """Create the plot for a given run"""
3455
3456
3457 self.store_result()
3458 args = self.split_arg(line)
3459
3460 self.check_plot(args)
3461 logger.info('plot for run %s' % self.run_name)
3462 if not self.force:
3463 self.ask_edit_cards([], args, plot=True)
3464
3465 if any([arg in ['all','parton'] for arg in args]):
3466 filename = pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe')
3467 if os.path.exists(filename+'.gz'):
3468 misc.gunzip('%s.gz' % filename, keep=True)
3469 if os.path.exists(filename):
3470 files.ln(filename, pjoin(self.me_dir, 'Events'))
3471 self.create_plot('parton')
3472 if not os.path.exists(filename+'.gz'):
3473 misc.gzip(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'),
3474 stdout= "%s.gz" % filename)
3475 else:
3476 try:
3477 os.remove(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'))
3478 os.remove(filename)
3479 except Exception:
3480 pass
3481 else:
3482 logger.info('No valid files for partonic plot')
3483
3484 if any([arg in ['all','pythia'] for arg in args]):
3485 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
3486 '%s_pythia_events.lhe' % self.run_tag)
3487 if os.path.exists(filename+'.gz'):
3488 misc.gunzip("%s.gz" % filename)
3489 if os.path.exists(filename):
3490 shutil.move(filename, pjoin(self.me_dir, 'Events','pythia_events.lhe'))
3491 self.create_plot('Pythia')
3492 misc.gzip(pjoin(self.me_dir, 'Events','pythia_events.lhe'),
3493 stdout= "%s.gz" % filename)
3494 else:
3495 logger.info('No valid files for pythia plot')
3496
3497
3498 if any([arg in ['all','pgs'] for arg in args]):
3499 filename = pjoin(self.me_dir, 'Events', self.run_name,
3500 '%s_pgs_events.lhco' % self.run_tag)
3501 if os.path.exists(filename+'.gz'):
3502 misc.gunzip("%s.gz" % filename)
3503 if os.path.exists(filename):
3504 self.create_plot('PGS')
3505 misc.gzip(filename)
3506 else:
3507 logger.info('No valid files for pgs plot')
3508
3509 if any([arg in ['all','delphes'] for arg in args]):
3510 filename = pjoin(self.me_dir, 'Events', self.run_name,
3511 '%s_delphes_events.lhco' % self.run_tag)
3512 if os.path.exists(filename+'.gz'):
3513 misc.gunzip("%s.gz" % filename)
3514 if os.path.exists(filename):
3515 self.create_plot('Delphes')
3516 misc.gzip(filename)
3517 else:
3518 logger.info('No valid files for delphes plot')
3519
3520
3522 """Evaluate systematics variation weights for a given run"""
3523
3524
3525 self.store_result()
3526 args = self.split_arg(line)
3527
3528 self.check_syscalc(args)
3529 if self.ninitial == 1:
3530 logger.error('SysCalc can\'t be run for decay processes')
3531 return
3532
3533 logger.info('Calculating systematics for run %s' % self.run_name)
3534
3535 self.ask_edit_cards(['run_card'], args)
3536 self.run_card = banner_mod.RunCard(pjoin(self.me_dir, 'Cards', 'run_card.dat'))
3537
3538 if any([arg in ['all','parton'] for arg in args]):
3539 filename = pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe')
3540 if os.path.exists(filename+'.gz'):
3541 misc.gunzip("%s.gz" % filename)
3542 if os.path.exists(filename):
3543 shutil.move(filename, pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'))
3544 self.run_syscalc('parton')
3545 misc.gzip(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'),
3546 stdout="%s.gz" % filename)
3547 else:
3548 logger.info('No valid files for parton level systematics run.')
3549
3550 if any([arg in ['all','pythia'] for arg in args]):
3551 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
3552 '%s_pythia_syst.dat' % self.run_tag)
3553 if os.path.exists(filename+'.gz'):
3554 misc.gunzip("%s.gz" % filename)
3555 if os.path.exists(filename):
3556 shutil.move(filename, pjoin(self.me_dir, 'Events','syst.dat'))
3557 try:
3558 self.run_syscalc('Pythia')
3559 except SysCalcError, error:
3560 logger.warning(str(error))
3561 return
3562 misc.gzip(pjoin(self.me_dir, 'Events','syst.dat'), "%s.gz" % filename)
3563 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
3564 '%s_syscalc.dat' % self.run_tag)
3565 misc.gzip(pjoin(self.me_dir, 'Events','syscalc.dat'),
3566 stdout=filename)
3567 else:
3568 logger.info('No valid files for pythia level')
3569
3570
3572 """ tar the pythia results. This is done when we are quite sure that
3573 the pythia output will not be use anymore """
3574
3575 if not self.run_name:
3576 return
3577
3578 self.results.save()
3579
3580
3581 if not self.to_store:
3582 return
3583
3584 tag = self.run_card['run_tag']
3585 self.update_status('storring files of previous run', level=None,\
3586 error=True)
3587 if 'event' in self.to_store:
3588 if not os.path.exists(pjoin(self.me_dir, 'Events',self.run_name, 'unweighted_events.lhe.gz')) and\
3589 os.path.exists(pjoin(self.me_dir, 'Events',self.run_name, 'unweighted_events.lhe')):
3590 logger.info("gzipping output file: unweighted_events.lhe")
3591 misc.gzip(pjoin(self.me_dir,'Events',self.run_name,"unweighted_events.lhe"))
3592 if os.path.exists(pjoin(self.me_dir,'Events','reweight.lhe')):
3593 os.remove(pjoin(self.me_dir,'Events', 'reweight.lhe'))
3594
3595 if 'pythia' in self.to_store:
3596 self.update_status('Storing Pythia files of previous run', level='pythia', error=True)
3597
3598 p = pjoin(self.me_dir,'Events')
3599 n = self.run_name
3600 t = tag
3601 misc.gzip(pjoin(p,'pythia_events.hep'),
3602 stdout=pjoin(p,'%s/%s_pythia_events.hep' % (n,t)))
3603
3604 self.to_store.remove('pythia')
3605 self.update_status('Done', level='pythia',makehtml=False,error=True)
3606
3607 self.to_store = []
3608
3609 - def launch_job(self,exe, cwd=None, stdout=None, argument = [], remaining=0,
3610 run_type='', mode=None, **opt):
3611 """ """
3612 argument = [str(arg) for arg in argument]
3613 if mode is None:
3614 mode = self.cluster_mode
3615
3616
3617 if os.path.exists(exe) and not os.access(exe, os.X_OK):
3618 os.system('chmod +x %s ' % exe)
3619 elif (cwd and os.path.exists(pjoin(cwd, exe))) and not \
3620 os.access(pjoin(cwd, exe), os.X_OK):
3621 os.system('chmod +x %s ' % pjoin(cwd, exe))
3622
3623 if mode == 0:
3624 self.update_status((remaining, 1,
3625 self.total_jobs - remaining -1, run_type), level=None, force=False)
3626 start = time.time()
3627
3628 status = misc.call([exe] + argument, cwd=cwd, stdout=stdout, **opt)
3629 logger.info('%s run in %f s' % (exe, time.time() -start))
3630 if status:
3631 raise MadGraph5Error, '%s didn\'t stop properly. Stop all computation' % exe
3632
3633
3634 elif mode in [1,2]:
3635 exename = os.path.basename(exe)
3636
3637 if 'ajob' in exename:
3638 input_files = ['madevent','input_app.txt','symfact.dat','iproc.dat',
3639 pjoin(self.me_dir, 'SubProcesses','randinit')]
3640 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
3641 'MadLoop5_resources.tar.gz')) and cluster.need_transfer(self.options):
3642 input_files.append(pjoin(self.me_dir,'SubProcesses', 'MadLoop5_resources.tar.gz'))
3643
3644 output_files = []
3645 required_output = []
3646
3647
3648
3649 input_files.append(self.get_pdf_input_filename())
3650
3651
3652 Gre = re.compile("\s*j=(G[\d\.\w]+)")
3653 origre = re.compile("grid_directory=(G[\d\.\w]+)")
3654 try :
3655 fsock = open(exe)
3656 except Exception:
3657 fsock = open(pjoin(cwd,exe))
3658 text = fsock.read()
3659 output_files = Gre.findall(text)
3660 if not output_files:
3661 Ire = re.compile("for i in ([\d\.\s]*) ; do")
3662 data = Ire.findall(text)
3663 data = ' '.join(data).split()
3664 for nb in data:
3665 output_files.append('G%s' % nb)
3666 required_output.append('G%s/results.dat' % nb)
3667 else:
3668 for G in output_files:
3669 if os.path.isdir(pjoin(cwd,G)):
3670 input_files.append(G)
3671 required_output.append('%s/results.dat' % G)
3672
3673 if origre.search(text):
3674 G_grid = origre.search(text).groups()[0]
3675 input_files.append(pjoin(G_grid, 'ftn26'))
3676
3677
3678 self.cluster.submit2(exe, stdout=stdout, cwd=cwd,
3679 input_files=input_files, output_files=output_files,
3680 required_output=required_output)
3681 elif 'survey' in exename:
3682 input_files = ['madevent','input_app.txt','symfact.dat','iproc.dat',
3683 pjoin(self.me_dir, 'SubProcesses','randinit')]
3684 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
3685 'MadLoop5_resources.tar.gz')) and cluster.need_transfer(self.options):
3686 input_files.append(pjoin(self.me_dir,'SubProcesses',
3687 'MadLoop5_resources.tar.gz'))
3688
3689
3690 input_files.append(self.get_pdf_input_filename())
3691
3692
3693 output_files = []
3694 required_output = []
3695
3696
3697 suffix = "_%s" % int(float(argument[0]))
3698 if suffix == '_0':
3699 suffix = ''
3700 output_files = ['G%s%s' % (i, suffix) for i in argument[1:]]
3701 for G in output_files:
3702 required_output.append('%s/results.dat' % G)
3703
3704
3705 for G in output_files:
3706 if '.' in argument[0]:
3707 offset = int(str(argument[0]).split('.')[1])
3708 else:
3709 offset = 0
3710
3711 if offset ==0 or offset == int(float(argument[0])):
3712 if os.path.exists(pjoin(cwd, G, 'input_app.txt')):
3713 os.remove(pjoin(cwd, G, 'input_app.txt'))
3714
3715 if os.path.exists(os.path.realpath(pjoin(cwd, G, 'ftn25'))):
3716 if offset == 0 or offset == int(float(argument[0])):
3717 os.remove(pjoin(cwd, G, 'ftn25'))
3718 continue
3719 else:
3720 input_files.append(pjoin(cwd, G, 'ftn25'))
3721 input_files.remove('input_app.txt')
3722 input_files.append(pjoin(cwd, G, 'input_app.txt'))
3723 elif os.path.lexists(pjoin(cwd, G, 'ftn25')):
3724 try:
3725 os.remove(pjoin(cwd,G,'ftn25'))
3726 except:
3727 pass
3728
3729
3730 self.cluster.cluster_submit(exe, stdout=stdout, cwd=cwd, argument=argument,
3731 input_files=input_files, output_files=output_files,
3732 required_output=required_output, **opt)
3733 elif "refine_splitted.sh" in exename:
3734 input_files = ['madevent','symfact.dat','iproc.dat',
3735 pjoin(self.me_dir, 'SubProcesses','randinit')]
3736
3737 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
3738 'MadLoop5_resources.tar.gz')) and cluster.need_transfer(self.options):
3739 input_files.append(pjoin(self.me_dir,'SubProcesses',
3740 'MadLoop5_resources.tar.gz'))
3741
3742
3743 input_files.append(self.get_pdf_input_filename())
3744
3745
3746 output_files = [argument[0]]
3747 required_output = []
3748 for G in output_files:
3749 required_output.append('%s/results.dat' % G)
3750 input_files.append(pjoin(argument[1], "input_app.txt"))
3751 input_files.append(pjoin(argument[1], "ftn26"))
3752
3753
3754 self.cluster.cluster_submit(exe, stdout=stdout, cwd=cwd, argument=argument,
3755 input_files=input_files, output_files=output_files,
3756 required_output=required_output, **opt)
3757
3758
3759
3760 else:
3761 self.cluster.submit(exe, argument=argument, stdout=stdout, cwd=cwd, **opt)
3762
3763
3764
3766 """Find if Madevent is in Group mode or not"""
3767
3768
3769
3770 file_path = pjoin(self.me_dir, 'Source', 'run_config.inc')
3771 text = open(file_path).read()
3772 if re.search(r'''s*parameter\s+\(ChanPerJob=2\)''', text, re.I+re.M):
3773 return 'group'
3774 else:
3775 return 'v4'
3776
3777
3778 - def monitor(self, run_type='monitor', mode=None, html=False):
3779 """ monitor the progress of running job """
3780
3781
3782 starttime = time.time()
3783 if mode is None:
3784 mode = self.cluster_mode
3785 if mode > 0:
3786 if html:
3787 update_status = lambda idle, run, finish: \
3788 self.update_status((idle, run, finish, run_type), level=None,
3789 force=False, starttime=starttime)
3790 update_first = lambda idle, run, finish: \
3791 self.update_status((idle, run, finish, run_type), level=None,
3792 force=True, starttime=starttime)
3793 else:
3794 update_status = lambda idle, run, finish: None
3795 update_first = None
3796 try:
3797 self.cluster.wait(self.me_dir, update_status, update_first=update_first)
3798 except Exception, error:
3799 logger.info(error)
3800 if not self.force:
3801 ans = self.ask('Cluster Error detected. Do you want to clean the queue? ("c"=continue the run anyway)',
3802 default = 'y', choices=['y','n', 'c'])
3803 else:
3804 ans = 'y'
3805 if ans == 'y':
3806 self.cluster.remove()
3807 elif ans == 'c':
3808 return self.monitor(run_type=run_type, mode=mode, html=html)
3809 raise
3810 except KeyboardInterrupt, error:
3811 self.cluster.remove()
3812 raise
3813
3814
3815
3816
3898
3899
3900
3901
3902
3903 @staticmethod
3905 """check if the directory exists. if so return the path otherwise the
3906 default"""
3907
3908 if os.path.isdir(path):
3909 return path
3910 else:
3911 return default
3912
3913
3915 """get the list of Pdirectory if not yet saved."""
3916
3917 if hasattr(self, "Pdirs"):
3918 if self.me_dir in self.Pdirs[0]:
3919 return self.Pdirs
3920 self.Pdirs = [pjoin(self.me_dir, 'SubProcesses', l.strip())
3921 for l in open(pjoin(self.me_dir,'SubProcesses', 'subproc.mg'))]
3922 return self.Pdirs
3923
3924
3926 """get the list of Gdirectory if not yet saved."""
3927
3928 if hasattr(self, "Gdirs"):
3929 if self.me_dir in self.Gdirs[0]:
3930 return self.Gdirs
3931
3932 Pdirs = self.get_Pdir()
3933 Gdirs = []
3934 for P in Pdirs:
3935 for line in open(pjoin(P, "symfact.dat")):
3936 tag, mfactor = line.split()
3937 Gdirs.append( (pjoin(P, "G%s" % tag), int(mfactor)) )
3938
3939
3940 self.Gdirs = Gdirs
3941 return self.Gdirs
3942
3943
3944 - def set_run_name(self, name, tag=None, level='parton', reload_card=False,
3945 allow_new_tag=True):
3946 """define the run name, the run_tag, the banner and the results."""
3947
3948
3949 upgrade_tag = {'parton': ['parton','pythia','pgs','delphes'],
3950 'pythia': ['pythia','pgs','delphes'],
3951 'pgs': ['pgs'],
3952 'delphes':['delphes'],
3953 'plot':[],
3954 'syscalc':[]}
3955
3956
3957
3958 if name == self.run_name:
3959 if reload_card:
3960 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
3961 self.run_card = banner_mod.RunCard(run_card)
3962
3963
3964 if tag:
3965 self.run_card['run_tag'] = tag
3966 self.run_tag = tag
3967 self.results.add_run(self.run_name, self.run_card)
3968 else:
3969 for tag in upgrade_tag[level]:
3970 if getattr(self.results[self.run_name][-1], tag):
3971 tag = self.get_available_tag()
3972 self.run_card['run_tag'] = tag
3973 self.run_tag = tag
3974 self.results.add_run(self.run_name, self.run_card)
3975 break
3976 return
3977
3978
3979 if self.run_name:
3980 self.store_result()
3981
3982 self.run_name = name
3983
3984 new_tag = False
3985
3986 self.banner = banner_mod.recover_banner(self.results, level, name)
3987 if 'mgruncard' in self.banner:
3988 self.run_card = self.banner.charge_card('run_card')
3989 else:
3990
3991 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
3992 self.run_card = banner_mod.RunCard(run_card)
3993
3994 if tag:
3995 self.run_card['run_tag'] = tag
3996 new_tag = True
3997 elif not self.run_name in self.results and level =='parton':
3998 pass
3999 elif not self.run_name in self.results:
4000
4001 logger.warning('Trying to run data on unknown run.')
4002 self.results.add_run(name, self.run_card)
4003 self.results.update('add run %s' % name, 'all', makehtml=False)
4004 else:
4005 for tag in upgrade_tag[level]:
4006
4007 if getattr(self.results[self.run_name][-1], tag):
4008
4009 tag = self.get_available_tag()
4010 self.run_card['run_tag'] = tag
4011 new_tag = True
4012 break
4013 if not new_tag:
4014
4015 tag = self.results[self.run_name][-1]['tag']
4016 self.run_card['run_tag'] = tag
4017
4018 if allow_new_tag and (name in self.results and not new_tag):
4019 self.results.def_current(self.run_name)
4020 else:
4021 self.results.add_run(self.run_name, self.run_card)
4022
4023 self.run_tag = self.run_card['run_tag']
4024
4025
4026
4027 if level == 'parton':
4028 return
4029 elif level == 'pythia':
4030 return self.results[self.run_name][0]['tag']
4031 else:
4032 for i in range(-1,-len(self.results[self.run_name])-1,-1):
4033 tagRun = self.results[self.run_name][i]
4034 if tagRun.pythia:
4035 return tagRun['tag']
4036
4037
4038
4039
4040
4041
4042
4043
4044
4046 """ return the model name """
4047 if hasattr(self, 'model_name'):
4048 return self.model_name
4049
4050 model = 'sm'
4051 proc = []
4052 for line in open(os.path.join(self.me_dir,'Cards','proc_card_mg5.dat')):
4053 line = line.split('#')[0]
4054
4055 if line.startswith('import') and 'model' in line:
4056 model = line.split()[2]
4057 proc = []
4058 elif line.startswith('generate'):
4059 proc.append(line.split(None,1)[1])
4060 elif line.startswith('add process'):
4061 proc.append(line.split(None,2)[2])
4062
4063 self.model = model
4064 self.process = proc
4065 return model
4066
4067
4068
4070 """Find the number of event in the run_card, and check that this is not
4071 too large"""
4072
4073
4074 nb_event = int(self.run_card['nevents'])
4075 if nb_event > 1000000:
4076 logger.warning("Attempting to generate more than 1M events")
4077 logger.warning("Limiting number to 1M. Use multi_run for larger statistics.")
4078 path = pjoin(self.me_dir, 'Cards', 'run_card.dat')
4079 os.system(r"""perl -p -i.bak -e "s/\d+\s*=\s*nevents/1000000 = nevents/" %s""" \
4080 % path)
4081 self.run_card['nevents'] = 1000000
4082
4083 return
4084
4085
4086
4088 """ change random number"""
4089
4090 self.random += 3
4091 if self.random > 30081*30081:
4092 raise MadGraph5Error,\
4093 'Random seed too large ' + str(self.random) + ' > 30081*30081'
4094
4095
4097 """save random number in appropirate file"""
4098
4099 fsock = open(pjoin(self.me_dir, 'SubProcesses','randinit'),'w')
4100 fsock.writelines('r=%s\n' % self.random)
4101
4102 - def do_quit(self, *args, **opts):
4106
4107
4109 """check for ckkw"""
4110
4111 lpp1 = self.run_card['lpp1']
4112 lpp2 = self.run_card['lpp2']
4113 e1 = self.run_card['ebeam1']
4114 e2 = self.run_card['ebeam2']
4115 pd = self.run_card['pdlabel']
4116 lha = self.run_card['lhaid']
4117 xq = self.run_card['xqcut']
4118 translation = {'e1': e1, 'e2':e2, 'pd':pd,
4119 'lha':lha, 'xq':xq}
4120
4121 if lpp1 or lpp2:
4122
4123 if pd.startswith("'"):
4124 pd = pd[1:]
4125 if pd.endswith("'"):
4126 pd = pd[:-1]
4127
4128 if xq >2 or xq ==2:
4129 xq = 2
4130
4131
4132 if pd == "lhapdf":
4133 issudfile = 'lib/issudgrid-%(e1)s-%(e2)s-%(pd)s-%(lha)s-%(xq)s.dat.gz'
4134 else:
4135 issudfile = 'lib/issudgrid-%(e1)s-%(e2)s-%(pd)s-%(xq)s.dat.gz'
4136 if self.web:
4137 issudfile = pjoin(self.webbin, issudfile % translation)
4138 else:
4139 issudfile = pjoin(self.me_dir, issudfile % translation)
4140
4141 logger.info('Sudakov grid file: %s' % issudfile)
4142
4143
4144 if os.path.exists(issudfile):
4145 path = pjoin(self.me_dir, 'lib', 'issudgrid.dat')
4146 misc.gunzip(issudfile, keep=True, stdout=path)
4147 else:
4148 msg = 'No sudakov grid file for parameter choice. Start to generate it. This might take a while'
4149 logger.info(msg)
4150 self.update_status('GENERATE SUDAKOF GRID', level='parton')
4151
4152 for i in range(-2,6):
4153 self.cluster.submit('%s/gensudgrid ' % self.dirbin,
4154 arguments = [i],
4155 cwd=self.me_dir,
4156 stdout=open(pjoin(self.me_dir, 'gensudgrid%s.log' % i,'w')))
4157 self.monitor()
4158 for i in range(-2,6):
4159 path = pjoin(self.me_dir, 'lib', 'issudgrid.dat')
4160 os.system('cat %s/gensudgrid%s.log >> %s' % (self.me_dir, path))
4161 misc.gzip(path, stdout=issudfile)
4162
4163
4164 - def create_root_file(self, input='unweighted_events.lhe',
4165 output='unweighted_events.root' ):
4166 """create the LHE root file """
4167 self.update_status('Creating root files', level='parton')
4168
4169 eradir = self.options['exrootanalysis_path']
4170 try:
4171 misc.call(['%s/ExRootLHEFConverter' % eradir,
4172 input, output],
4173 cwd=pjoin(self.me_dir, 'Events'))
4174 except Exception:
4175 logger.warning('fail to produce Root output [problem with ExRootAnalysis]')
4176
4177 - def run_syscalc(self, mode='parton', event_path=None, output=None):
4178 """create the syscalc output"""
4179
4180 if self.run_card['use_syst'] not in self.true:
4181 return
4182
4183 scdir = self.options['syscalc_path']
4184 if not scdir or not os.path.exists(scdir):
4185 return
4186 logger.info('running syscalc on mode %s' % mode)
4187
4188
4189
4190 lhaid = [self.run_card.get_lhapdf_id()]
4191 sys_pdf = self.run_card['sys_pdf'].split('&&')
4192 lhaid += [l.split()[0] for l in sys_pdf]
4193 try:
4194 pdfsets_dir = self.get_lhapdf_pdfsetsdir()
4195 except Exception, error:
4196 logger.debug(str(error))
4197 logger.warning('Systematic computation requires lhapdf to run. Bypass SysCalc')
4198 return
4199
4200
4201 [self.copy_lhapdf_set([onelha], pdfsets_dir) for onelha in lhaid]
4202
4203
4204
4205 tag = self.run_card['run_tag']
4206 card = pjoin(self.me_dir, 'bin','internal', 'syscalc_card.dat')
4207 template = open(pjoin(self.me_dir, 'bin','internal', 'syscalc_template.dat')).read()
4208 self.run_card['sys_pdf'] = self.run_card['sys_pdf'].split('#',1)[0].replace('&&',' \n ')
4209
4210 if self.run_card['sys_pdf'].lower() in ['', 'f', 'false', 'none', '.false.']:
4211 self.run_card['sys_pdf'] = ''
4212 if self.run_card['sys_alpsfact'].lower() in ['', 'f', 'false', 'none','.false.']:
4213 self.run_card['sys_alpsfact'] = ''
4214
4215
4216
4217
4218
4219 if not 'sys_scalecorrelation' in self.run_card:
4220 self.run_card['sys_scalecorrelation'] = -1
4221 open(card,'w').write(template % self.run_card)
4222
4223 if not os.path.exists(card):
4224 return False
4225
4226
4227
4228 event_dir = pjoin(self.me_dir, 'Events')
4229
4230 if not event_path:
4231 if mode == 'parton':
4232 event_path = pjoin(event_dir,self.run_name, 'unweighted_events.lhe')
4233 if not (os.path.exists(event_path) or os.path.exists(event_path+".gz")):
4234 event_path = pjoin(event_dir, 'unweighted_events.lhe')
4235 output = pjoin(event_dir, 'syscalc.lhe')
4236 elif mode == 'Pythia':
4237 if 'mgpythiacard' in self.banner:
4238 pat = re.compile('''^\s*qcut\s*=\s*([\+\-\d.e]*)''', re.M+re.I)
4239 data = pat.search(self.banner['mgpythiacard'])
4240 if data:
4241 qcut = float(data.group(1))
4242 xqcut = abs(self.run_card['xqcut'])
4243 for value in self.run_card['sys_matchscale'].split():
4244 if float(value) < qcut:
4245 raise SysCalcError, 'qcut value for sys_matchscale lower than qcut in pythia_card. Bypass syscalc'
4246 if float(value) < xqcut:
4247 raise SysCalcError, 'qcut value for sys_matchscale lower than xqcut in run_card. Bypass syscalc'
4248
4249
4250 event_path = pjoin(event_dir,'syst.dat')
4251 output = pjoin(event_dir, 'syscalc.dat')
4252 else:
4253 raise self.InvalidCmd, 'Invalid mode %s' % mode
4254
4255 if not os.path.exists(event_path):
4256 if os.path.exists(event_path+'.gz'):
4257 misc.gunzip(event_path+'.gz')
4258 else:
4259 raise SysCalcError, 'Events file %s does not exits' % event_path
4260
4261 self.update_status('Calculating systematics for %s level' % mode, level = mode.lower())
4262 try:
4263 proc = misc.call([os.path.join(scdir, 'sys_calc'),
4264 event_path, card, output],
4265 stdout = open(pjoin(event_dir, self.run_name, '%s_%s_syscalc.log' % (tag,mode)),'w'),
4266 stderr = subprocess.STDOUT,
4267 cwd=event_dir)
4268
4269 time.sleep(5)
4270 except OSError, error:
4271 logger.error('fail to run syscalc: %s. Please check that SysCalc is correctly installed.' % error)
4272 else:
4273 if not os.path.exists(output):
4274 logger.warning('SysCalc Failed. Please read the associate log to see the reason. Did you install the associate PDF set?')
4275 elif mode == 'parton':
4276 files.mv(output, event_path)
4277
4278 self.update_status('End syscalc for %s level' % mode, level = mode.lower(),
4279 makehtml=False)
4280
4281 return True
4282
4283
4284
4285
4287 """Ask the question when launching generate_events/multi_run"""
4288
4289 available_mode = ['0']
4290 void = 'NOT INSTALLED'
4291 switch_order = ['pythia', 'pgs', 'delphes', 'madspin', 'reweight']
4292 switch = {'pythia': void, 'pgs': void, 'delphes': void,
4293 'madspin': void, 'reweight': void}
4294 description = {'pythia': 'Run the pythia shower/hadronization:',
4295 'pgs': 'Run PGS as detector simulator:',
4296 'delphes':'Run Delphes as detector simulator:',
4297 'madspin':'Decay particles with the MadSpin module:',
4298 'reweight':'Add weights to the events based on changing model parameters:',
4299 }
4300 force_switch = {('pythia', 'OFF'): {'pgs': 'OFF', 'delphes': 'OFF'},
4301 ('pgs', 'ON'): {'pythia':'ON'},
4302 ('delphes', 'ON'): {'pythia': 'ON'}}
4303 switch_assign = lambda key, value: switch.__setitem__(key, value if switch[key] != void else void )
4304
4305
4306
4307 if self.options['pythia-pgs_path']:
4308 available_mode.append('1')
4309 available_mode.append('2')
4310 if os.path.exists(pjoin(self.me_dir,'Cards','pythia_card.dat')):
4311 switch['pythia'] = 'ON'
4312 else:
4313 switch['pythia'] = 'OFF'
4314 if os.path.exists(pjoin(self.me_dir,'Cards','pgs_card.dat')):
4315 switch['pgs'] = 'ON'
4316 else:
4317 switch['pgs'] = 'OFF'
4318 if self.options['delphes_path']:
4319 available_mode.append('3')
4320 if os.path.exists(pjoin(self.me_dir,'Cards','delphes_card.dat')):
4321 switch['delphes'] = 'ON'
4322 else:
4323 switch['delphes'] = 'OFF'
4324
4325
4326 if not MADEVENT or ('mg5_path' in self.options and self.options['mg5_path']):
4327 available_mode.append('4')
4328 available_mode.append('5')
4329 if os.path.exists(pjoin(self.me_dir,'Cards','madspin_card.dat')):
4330 switch['madspin'] = 'ON'
4331 else:
4332 switch['madspin'] = 'OFF'
4333 if misc.has_f2py() or self.options['f2py_compiler']:
4334 if os.path.exists(pjoin(self.me_dir,'Cards','reweight_card.dat')):
4335 switch['reweight'] = 'ON'
4336 else:
4337 switch['reweight'] = 'OFF'
4338 else:
4339 switch['reweight'] = 'Not available (requires NumPy)'
4340
4341 if '-R' in args or '--reweight' in args:
4342 if switch['reweight'] == 'OFF':
4343 switch['reweight'] = 'ON'
4344 elif switch['reweight'] != 'ON':
4345 logger.critical("Cannot run reweight: %s", switch['reweight'])
4346 if '-M' in args or '--madspin' in args:
4347 switch['madspin'] = 'ON'
4348
4349 options = list(available_mode) + ['auto', 'done']
4350 for id, key in enumerate(switch_order):
4351 if switch[key] not in [void, 'Not available (requires NumPy)']:
4352 options += ['%s=%s' % (key, s) for s in ['ON','OFF']]
4353 options.append(key)
4354 options.append('parton')
4355
4356
4357 if mode or not self.force:
4358 answer = ''
4359 while answer not in ['0', 'done', 'auto']:
4360 if mode:
4361 answer = mode
4362 else:
4363 switch_format = " %i %-61s %10s=%s\n"
4364 question = "The following switches determine which programs are run:\n"
4365 for id, key in enumerate(switch_order):
4366 question += switch_format % (id+1, description[key], key, switch[key])
4367 question += ' Either type the switch number (1 to %s) to change its default setting,\n' % (id+1)
4368 question += ' or set any switch explicitly (e.g. type \'madspin=ON\' at the prompt)\n'
4369 question += ' Type \'0\', \'auto\', \'done\' or just press enter when you are done.\n'
4370 answer = self.ask(question, '0', options)
4371 if answer.isdigit() and answer != '0':
4372 key = switch_order[int(answer) - 1]
4373 answer = '%s=%s' % (key, 'ON' if switch[key] == 'OFF' else 'OFF')
4374
4375 if '=' in answer:
4376 key, status = answer.split('=')
4377 switch[key] = status
4378 if (key, status) in force_switch:
4379 for key2, status2 in force_switch[(key, status)].items():
4380 if switch[key2] not in [status2, void]:
4381 logger.info('For coherence \'%s\' is set to \'%s\''
4382 % (key2, status2), '$MG:color:BLACK')
4383 switch[key2] = status2
4384 elif answer in ['0', 'auto', 'done']:
4385 continue
4386 else:
4387 logger.info('pass in %s only mode' % answer, '$MG:color:BLACK')
4388 switch_assign('madspin', 'OFF')
4389 switch_assign('reweight', 'OFF')
4390 if answer == 'parton':
4391 switch_assign('pythia', 'OFF')
4392 switch_assign('pgs', 'OFF')
4393 switch_assign('delphes', 'OFF')
4394 elif answer == 'pythia':
4395 switch_assign('pythia', 'ON')
4396 switch_assign('pgs', 'OFF')
4397 switch_assign('delphes', 'OFF')
4398 elif answer == 'pgs':
4399 switch_assign('pythia', 'ON')
4400 switch_assign('pgs', 'ON')
4401 switch_assign('delphes', 'OFF')
4402 elif answer == 'delphes':
4403 switch_assign('pythia', 'ON')
4404 switch_assign('pgs', 'OFF')
4405 switch_assign('delphes', 'ON')
4406 elif answer == 'madspin':
4407 switch_assign('madspin', 'ON')
4408 switch_assign('pythia', 'OFF')
4409 switch_assign('pgs', 'OFF')
4410 switch_assign('delphes', 'OF')
4411 elif answer == 'reweight':
4412 switch_assign('reweight', 'ON')
4413 switch_assign('pythia', 'OFF')
4414 switch_assign('pgs', 'OFF')
4415 switch_assign('delphes', 'OFF')
4416
4417
4418 if mode:
4419 answer = '0'
4420 else:
4421 answer = 'auto'
4422
4423
4424
4425
4426 cards = ['param_card.dat', 'run_card.dat']
4427 if switch['pythia'] == 'ON':
4428 cards.append('pythia_card.dat')
4429 if switch['pgs'] == 'ON':
4430 cards.append('pgs_card.dat')
4431 if switch['delphes'] == 'ON':
4432 cards.append('delphes_card.dat')
4433 delphes3 = True
4434 if os.path.exists(pjoin(self.options['delphes_path'], 'data')):
4435 delphes3 = False
4436 cards.append('delphes_trigger.dat')
4437 if switch['madspin'] == 'ON':
4438 cards.append('madspin_card.dat')
4439 if switch['reweight'] == 'ON':
4440 cards.append('reweight_card.dat')
4441 self.keep_cards(cards)
4442
4443 if os.path.isfile(pjoin(self.me_dir,'Cards','MadLoopParams.dat')):
4444 cards.append('MadLoopParams.dat')
4445
4446 if self.force:
4447 self.check_param_card(pjoin(self.me_dir,'Cards','param_card.dat' ))
4448 return
4449
4450 if answer == 'auto':
4451 self.ask_edit_cards(cards, mode='auto')
4452 else:
4453 self.ask_edit_cards(cards)
4454 return
4455
4456
4458 """Ask the question when launching pythia"""
4459
4460 available_mode = ['0', '1', '2']
4461 if self.options['delphes_path']:
4462 available_mode.append('3')
4463 name = {'0': 'auto', '1': 'pythia', '2':'pgs', '3':'delphes'}
4464 options = available_mode + [name[val] for val in available_mode]
4465 question = """Which programs do you want to run?
4466 0 / auto : running existing card
4467 1 / pythia : Pythia
4468 2 / pgs : Pythia + PGS\n"""
4469 if '3' in available_mode:
4470 question += """ 3 / delphes : Pythia + Delphes.\n"""
4471
4472 if not self.force:
4473 if not mode:
4474 mode = self.ask(question, '0', options)
4475 elif not mode:
4476 mode = 'auto'
4477
4478 if mode.isdigit():
4479 mode = name[mode]
4480
4481 auto = False
4482 if mode == 'auto':
4483 auto = True
4484 if os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')):
4485 mode = 'pgs'
4486 elif os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
4487 mode = 'delphes'
4488 else:
4489 mode = 'pythia'
4490 logger.info('Will run in mode %s' % mode)
4491
4492
4493
4494 cards = ['pythia_card.dat']
4495 if mode == 'pgs':
4496 cards.append('pgs_card.dat')
4497 if mode == 'delphes':
4498 cards.append('delphes_card.dat')
4499 delphes3 = True
4500 if os.path.exists(pjoin(self.options['delphes_path'], 'data')):
4501 delphes3 = False
4502 cards.append('delphes_trigger.dat')
4503 self.keep_cards(cards)
4504
4505 if self.force:
4506 return mode
4507
4508 if auto:
4509 self.ask_edit_cards(cards, mode='auto')
4510 else:
4511 self.ask_edit_cards(cards)
4512
4513 return mode
4514
4515
4516
4517
4518
4519
4520
4521
4522 -class MadEventCmdShell(MadEventCmd, cmd.CmdShell):
4523 """The command line processor of MadGraph"""
4524
4531
4532 name_to_pdg = {}
4533
4534 @classmethod
4537
4538 @staticmethod
4540 """return the list of Subprocesses"""
4541
4542 out = []
4543 for line in open(pjoin(me_dir,'SubProcesses', 'subproc.mg')):
4544 if not line:
4545 continue
4546 name = line.strip()
4547 if os.path.exists(pjoin(me_dir, 'SubProcesses', name)):
4548 out.append(pjoin(me_dir, 'SubProcesses', name))
4549
4550 return out
4551
4552
4553
4554 @staticmethod
4556 """ return the list of processes with their name"""
4557
4558 nb_sub = 0
4559 names = {}
4560 old_main = ''
4561
4562 if not os.path.exists(os.path.join(path,'processes.dat')):
4563 return SubProcesses.get_subP_info_v4(path)
4564
4565 for line in open(os.path.join(path,'processes.dat')):
4566 main = line[:8].strip()
4567 if main == 'mirror':
4568 main = old_main
4569 if line[8:].strip() == 'none':
4570 continue
4571 else:
4572 main = int(main)
4573 old_main = main
4574
4575 sub_proccess = line[8:]
4576 nb_sub += sub_proccess.count(',') + 1
4577 if main in names:
4578 names[main] += [sub_proccess.split(',')]
4579 else:
4580 names[main]= [sub_proccess.split(',')]
4581
4582 return names
4583
4584 @staticmethod
4586 """ return the list of processes with their name in case without grouping """
4587
4588 nb_sub = 0
4589 names = {'':[[]]}
4590 path = os.path.join(path, 'auto_dsig.f')
4591 found = 0
4592 for line in open(path):
4593 if line.startswith('C Process:'):
4594 found += 1
4595 names[''][0].append(line[15:])
4596 elif found >1:
4597 break
4598 return names
4599
4600
4601 @staticmethod
4603 """return the pdg codes of the particles present in the Subprocesses"""
4604
4605 all_ids = []
4606 for line in open(pjoin(path, 'leshouche.inc')):
4607 if not 'IDUP' in line:
4608 continue
4609 particles = re.search("/([\d,-]+)/", line)
4610 all_ids.append([int(p) for p in particles.group(1).split(',')])
4611 return all_ids
4612
4616 """The command for the gridpack --Those are not suppose to be use interactively--"""
4617
4618 - def __init__(self, me_dir = None, nb_event=0, seed=0, *completekey, **stdin):
4619 """Initialize the command and directly run"""
4620
4621
4622
4623 MadEventCmd.__init__(self, me_dir, *completekey, **stdin)
4624 self.run_mode = 0
4625 self.random = seed
4626 self.random_orig = self.random
4627 self.options['automatic_html_opening'] = False
4628
4629 if me_dir and nb_event and seed:
4630 self.launch(nb_event, seed)
4631 else:
4632 raise MadGraph5Error,\
4633 'Gridpack run failed: ' + str(me_dir) + str(nb_event) + \
4634 str(seed)
4635
4636 - def launch(self, nb_event, seed):
4659
4661 """Special refine for gridpack run."""
4662 self.nb_refine += 1
4663
4664 precision = nb_event
4665
4666
4667
4668 self.cluster_mode = 0
4669
4670
4671 self.save_random()
4672
4673 self.update_status('Refine results to %s' % precision, level=None)
4674 logger.info("Using random number seed offset = %s" % self.random)
4675
4676 self.total_jobs = 0
4677 subproc = [P for P in os.listdir(pjoin(self.me_dir,'SubProcesses')) if
4678 P.startswith('P') and os.path.isdir(pjoin(self.me_dir,'SubProcesses', P))]
4679 devnull = open(os.devnull, 'w')
4680 for nb_proc,subdir in enumerate(subproc):
4681 subdir = subdir.strip()
4682 Pdir = pjoin(self.me_dir, 'SubProcesses',subdir)
4683 bindir = pjoin(os.path.relpath(self.dirbin, Pdir))
4684
4685 logger.info(' %s ' % subdir)
4686
4687 for match in misc.glob('*ajob*', Pdir):
4688 if os.path.basename(match)[:4] in ['ajob', 'wait', 'run.', 'done']:
4689 os.remove(pjoin(Pdir, match))
4690
4691
4692 logfile = pjoin(Pdir, 'gen_ximprove.log')
4693 misc.call([pjoin(bindir, 'gen_ximprove')],
4694 stdin=subprocess.PIPE,
4695 stdout=open(logfile,'w'),
4696 cwd=Pdir)
4697
4698 if os.path.exists(pjoin(Pdir, 'ajob1')):
4699 alljobs = misc.glob('ajob*', Pdir)
4700 nb_tot = len(alljobs)
4701 self.total_jobs += nb_tot
4702 for i, job in enumerate(alljobs):
4703 job = os.path.basename(job)
4704 self.launch_job('%s' % job, cwd=Pdir, remaining=(nb_tot-i-1),
4705 run_type='Refine number %s on %s (%s/%s)' %
4706 (self.nb_refine, subdir, nb_proc+1, len(subproc)))
4707 if os.path.exists(pjoin(self.me_dir,'error')):
4708 self.monitor(html=True)
4709 raise MadEventError, \
4710 'Error detected in dir %s: %s' % \
4711 (Pdir, open(pjoin(self.me_dir,'error')).read())
4712 self.monitor(run_type='All job submitted for refine number %s' %
4713 self.nb_refine)
4714
4715 self.update_status("Combining runs", level='parton')
4716 try:
4717 os.remove(pjoin(Pdir, 'combine_runs.log'))
4718 except Exception:
4719 pass
4720
4721 bindir = pjoin(os.path.relpath(self.dirbin, pjoin(self.me_dir,'SubProcesses')))
4722 combine_runs.CombineRuns(self.me_dir)
4723
4724
4725 cross, error = sum_html.make_all_html_results(self)
4726 self.results.add_detail('cross', cross)
4727 self.results.add_detail('error', error)
4728
4729
4730 self.update_status('finish refine', 'parton', makehtml=False)
4731 devnull.close()
4732
4735 """ A container class for the various methods for initializing MadLoop. It is
4736 placed in MadEventInterface because it is used by Madevent for loop-induced
4737 simulations. """
4738
4739 @staticmethod
4741 """ Compile the check program in the directory dir_name.
4742 Return the compilation and running time. """
4743
4744
4745
4746 if os.path.isfile(pjoin(dir_name,'check')):
4747 os.remove(pjoin(dir_name,'check'))
4748 os.remove(pjoin(dir_name,'check_sa.o'))
4749 os.remove(pjoin(dir_name,'loop_matrix.o'))
4750
4751 devnull = open(os.devnull, 'w')
4752 start=time.time()
4753 retcode = subprocess.call(['make','check'],
4754 cwd=dir_name, stdout=devnull, stderr=devnull)
4755 compilation_time = time.time()-start
4756 if retcode != 0:
4757 logging.info("Error while executing make in %s" % dir_name)
4758 return None, None, None
4759
4760 if not checkRam:
4761 start=time.time()
4762 retcode = subprocess.call('./check',
4763 cwd=dir_name, stdout=devnull, stderr=devnull)
4764
4765 run_time = time.time()-start
4766 ram_usage = None
4767 else:
4768 ptimer = misc.ProcessTimer(['./check'], cwd=dir_name, shell=False, \
4769 stdout=devnull, stderr=devnull, close_fds=True)
4770 try:
4771 ptimer.execute()
4772
4773
4774
4775 while ptimer.poll():
4776 time.sleep(.2)
4777 finally:
4778
4779 ptimer.close()
4780
4781 ram_usage = ptimer.max_rss_memory
4782
4783
4784 run_time = (ptimer.t1 - ptimer.t0)
4785 retcode = ptimer.p.returncode
4786
4787 devnull.close()
4788
4789 if retcode != 0:
4790 logging.warning("Error while executing ./check in %s" % dir_name)
4791 return None, None, None
4792
4793 return compilation_time, run_time, ram_usage
4794
4795 @staticmethod
4796 - def fix_PSPoint_in_check(dir_path, read_ps = True, npoints = 1,
4797 hel_config = -1, mu_r=0.0, split_orders=-1):
4798 """Set check_sa.f to be reading PS.input assuming a working dir dir_name.
4799 if hel_config is different than -1 then check_sa.f is configured so to
4800 evaluate only the specified helicity.
4801 If mu_r > 0.0, then the renormalization constant value will be hardcoded
4802 directly in check_sa.f, if is is 0 it will be set to Sqrt(s) and if it
4803 is < 0.0 the value in the param_card.dat is used.
4804 If the split_orders target (i.e. the target squared coupling orders for
4805 the computation) is != -1, it will be changed in check_sa.f via the
4806 subroutine CALL SET_COUPLINGORDERS_TARGET(split_orders)."""
4807
4808 file_path = dir_path
4809 if not os.path.isfile(dir_path) or \
4810 not os.path.basename(dir_path)=='check_sa.f':
4811 file_path = pjoin(dir_path,'check_sa.f')
4812 if not os.path.isfile(file_path):
4813 directories = [d for d in misc.glob('P*_*', dir_path) \
4814 if (re.search(r'.*P\d+_\w*$', d) and os.path.isdir(d))]
4815 if len(directories)>0:
4816 file_path = pjoin(directories[0],'check_sa.f')
4817 if not os.path.isfile(file_path):
4818 raise MadGraph5Error('Could not find the location of check_sa.f'+\
4819 ' from the specified path %s.'%str(file_path))
4820
4821 file = open(file_path, 'r')
4822 check_sa = file.read()
4823 file.close()
4824
4825 file = open(file_path, 'w')
4826 check_sa = re.sub(r"READPS = \S+\)","READPS = %s)"%('.TRUE.' if read_ps \
4827 else '.FALSE.'), check_sa)
4828 check_sa = re.sub(r"NPSPOINTS = \d+","NPSPOINTS = %d"%npoints, check_sa)
4829 if hel_config != -1:
4830 check_sa = re.sub(r"SLOOPMATRIX\S+\(\S+,MATELEM,",
4831 "SLOOPMATRIXHEL_THRES(P,%d,MATELEM,"%hel_config, check_sa)
4832 else:
4833 check_sa = re.sub(r"SLOOPMATRIX\S+\(\S+,MATELEM,",
4834 "SLOOPMATRIX_THRES(P,MATELEM,",check_sa)
4835 if mu_r > 0.0:
4836 check_sa = re.sub(r"MU_R=SQRTS","MU_R=%s"%\
4837 (("%.17e"%mu_r).replace('e','d')),check_sa)
4838 elif mu_r < 0.0:
4839 check_sa = re.sub(r"MU_R=SQRTS","",check_sa)
4840
4841 if split_orders > 0:
4842 check_sa = re.sub(r"SET_COUPLINGORDERS_TARGET\(-?\d+\)",
4843 "SET_COUPLINGORDERS_TARGET(%d)"%split_orders,check_sa)
4844
4845 file.write(check_sa)
4846 file.close()
4847
4848 @staticmethod
4849 - def run_initialization(run_dir=None, SubProc_dir=None, infos=None,\
4850 req_files = ['HelFilter.dat','LoopFilter.dat'],
4851 attempts = [4,15]):
4852 """ Run the initialization of the process in 'run_dir' with success
4853 characterized by the creation of the files req_files in this directory.
4854 The directory containing the driving source code 'check_sa.f'.
4855 The list attempt gives the successive number of PS points the
4856 initialization should be tried with before calling it failed.
4857 Returns the number of PS points which were necessary for the init.
4858 Notice at least run_dir or SubProc_dir must be provided.
4859 A negative attempt number given in input means that quadprec will be
4860 forced for initialization."""
4861
4862
4863
4864 if infos is None:
4865 infos={}
4866
4867 if SubProc_dir is None and run_dir is None:
4868 raise MadGraph5Error, 'At least one of [SubProc_dir,run_dir] must'+\
4869 ' be provided in run_initialization.'
4870
4871
4872
4873 if SubProc_dir is None:
4874 SubProc_dir = os.path.abspath(pjoin(run_dir,os.pardir))
4875
4876 if run_dir is None:
4877 directories =[ dir for dir in misc.glob('P[0-9]*', SubProc_dir)
4878 if os.path.isdir(dir) ]
4879 if directories:
4880 run_dir = directories[0]
4881 else:
4882 raise MadGraph5Error, 'Could not find a valid running directory'+\
4883 ' in %s.'%str(SubProc_dir)
4884
4885
4886
4887
4888
4889 if not os.path.isfile(pjoin(run_dir,'born_matrix.f')):
4890 if len(attempts)>=1 and attempts[0]<8:
4891 attempts[0]=8
4892 if len(attempts)>=2 and attempts[1]<25:
4893 attempts[1]=25
4894
4895 to_attempt = list(attempts)
4896 to_attempt.reverse()
4897 my_req_files = list(req_files)
4898
4899 MLCardPath = pjoin(SubProc_dir,'MadLoopParams.dat')
4900 if not os.path.isfile(MLCardPath):
4901 raise MadGraph5Error, 'Could not find MadLoopParams.dat at %s.'\
4902 %MLCardPath
4903 else:
4904 MLCard = banner_mod.MadLoopParam(MLCardPath)
4905 MLCard_orig = banner_mod.MadLoopParam(MLCard)
4906
4907
4908 if not MLCard['UseLoopFilter']:
4909 try:
4910 my_req_files.remove('LoopFilter.dat')
4911 except ValueError:
4912 pass
4913
4914 if MLCard['HelicityFilterLevel']==0:
4915 try:
4916 my_req_files.remove('HelFilter.dat')
4917 except ValueError:
4918 pass
4919
4920 def need_init():
4921 """ True if init not done yet."""
4922 proc_prefix_file = open(pjoin(run_dir,'proc_prefix.txt'),'r')
4923 proc_prefix = proc_prefix_file.read()
4924 proc_prefix_file.close()
4925 return any([not os.path.exists(pjoin(run_dir,'MadLoop5_resources',
4926 proc_prefix+fname)) for fname in my_req_files]) or \
4927 not os.path.isfile(pjoin(run_dir,'check')) or \
4928 not os.access(pjoin(run_dir,'check'), os.X_OK)
4929
4930
4931
4932 is_loop_induced = os.path.exists(pjoin(run_dir,'born_matrix.f'))
4933
4934
4935
4936
4937 if not any(attempt<0 for attempt in to_attempt):
4938 to_attempt = [-attempt for attempt in to_attempt] + to_attempt
4939 use_quad_prec = 1
4940 curr_attempt = 1
4941
4942 MLCard.set('WriteOutFilters',True)
4943
4944 while to_attempt!=[] and need_init():
4945 curr_attempt = to_attempt.pop()
4946
4947
4948 if curr_attempt < 0:
4949 use_quad_prec = -1
4950
4951 MLCard.set('CTModeInit',4)
4952 MLCard.set('ZeroThres',1e-11)
4953 else:
4954
4955 MLCard.set('CTModeInit',1)
4956 MLCard.set('ZeroThres',1e-9)
4957
4958 curr_attempt = abs(curr_attempt+1)
4959 MLCard.set('MaxAttempts',curr_attempt)
4960 MLCard.write(pjoin(SubProc_dir,'MadLoopParams.dat'))
4961
4962
4963 MadLoopInitializer.fix_PSPoint_in_check(run_dir, read_ps = False,
4964 npoints = curr_attempt)
4965 compile_time, run_time, ram_usage = \
4966 MadLoopInitializer.make_and_run(run_dir)
4967 if compile_time==None:
4968 logging.error("Failed at running the process in %s."%run_dir)
4969 attempts = None
4970 return None
4971
4972 if 'Process_compilation' not in infos.keys() or \
4973 infos['Process_compilation']==None:
4974 infos['Process_compilation'] = compile_time
4975 infos['Initialization'] = run_time
4976
4977 MLCard_orig.write(pjoin(SubProc_dir,'MadLoopParams.dat'))
4978 if need_init():
4979 return None
4980 else:
4981 return use_quad_prec*(curr_attempt-1)
4982
4983 @staticmethod
4985 """Checks whether the necessary filters are present or not."""
4986
4987 def need_init(ML_resources_path, proc_prefix, r_files):
4988 """ Returns true if not all required files are present. """
4989 return any([not os.path.exists(pjoin(ML_resources_path,
4990 proc_prefix+fname)) for fname in r_files])
4991
4992 MLCardPath = pjoin(proc_dir,'SubProcesses','MadLoopParams.dat')
4993 if not os.path.isfile(MLCardPath):
4994 raise MadGraph5Error, 'Could not find MadLoopParams.dat at %s.'\
4995 %MLCardPath
4996 MLCard = banner_mod.MadLoopParam(MLCardPath)
4997
4998 req_files = ['HelFilter.dat','LoopFilter.dat']
4999
5000 if not MLCard['UseLoopFilter']:
5001 try:
5002 req_files.remove('LoopFilter.dat')
5003 except ValueError:
5004 pass
5005 if MLCard['HelicityFilterLevel']==0:
5006 try:
5007 req_files.remove('HelFilter.dat')
5008 except ValueError:
5009 pass
5010
5011 for v_folder in glob.iglob(pjoin(proc_dir,'SubProcesses',
5012 '%s*'%subproc_prefix)):
5013
5014 if not os.path.isdir(v_folder) or not os.path.isfile(\
5015 pjoin(v_folder,'loop_matrix.f')):
5016 continue
5017 proc_prefix_file = open(pjoin(v_folder,'proc_prefix.txt'),'r')
5018 proc_prefix = proc_prefix_file.read()
5019 proc_prefix_file.close()
5020 if need_init(pjoin(proc_dir,'SubProcesses','MadLoop5_resources'),
5021 proc_prefix, req_files):
5022 return True
5023
5024 return False
5025
5026 @staticmethod
5027 - def init_MadLoop(proc_dir, n_PS=None, subproc_prefix='PV', MG_options=None,
5028 interface = None):
5029 """Advanced commands: Compiles and run MadLoop on RAMBO random PS points to initilize the
5030 filters."""
5031
5032 logger.debug('Compiling Source materials necessary for MadLoop '+
5033 'initialization.')
5034
5035
5036
5037 if interface is None:
5038 misc.compile(arg=['treatCardsLoopNoInit'], cwd=pjoin(proc_dir,'Source'))
5039 else:
5040 interface.do_treatcards('all --no_MadLoopInit')
5041
5042
5043 if os.path.exists(pjoin(proc_dir,'Source','CUTTOOLS')):
5044 misc.compile(arg=['libcuttools'],cwd=pjoin(proc_dir,'Source'))
5045 if os.path.exists(pjoin(proc_dir,'Source','IREGI')):
5046 misc.compile(arg=['libiregi'],cwd=pjoin(proc_dir,'Source'))
5047
5048 misc.compile(arg=['libmodel'],cwd=pjoin(proc_dir,'Source'))
5049 misc.compile(arg=['libdhelas'],cwd=pjoin(proc_dir,'Source'))
5050
5051
5052 logger.info('Initializing MadLoop loop-induced matrix elements '+\
5053 '(this can take some time)...')
5054
5055
5056 if MG_options:
5057 mcore = cluster.MultiCore(**MG_options)
5058 else:
5059 mcore = cluster.MultiCore(nb_core=1)
5060 def run_initialization_wrapper(run_dir, infos, attempts):
5061 if attempts is None:
5062 n_PS = MadLoopInitializer.run_initialization(
5063 run_dir=run_dir, infos=infos)
5064 else:
5065 n_PS = MadLoopInitializer.run_initialization(
5066 run_dir=run_dir, infos=infos, attempts=attempts)
5067 infos['nPS'] = n_PS
5068 return 0
5069
5070 def wait_monitoring(Idle, Running, Done):
5071 if Idle+Running+Done == 0:
5072 return
5073 logger.debug('MadLoop initialization jobs: %d Idle, %d Running, %d Done'\
5074 %(Idle, Running, Done))
5075
5076 init_info = {}
5077
5078 VirtualFolders = [f for f in glob.iglob(pjoin(proc_dir,'SubProcesses',
5079 '%s*'%subproc_prefix)) if (os.path.isdir(f) or
5080 os.path.isfile(pjoin(f,'loop_matrix.f')))]
5081 logger.debug("Now Initializing MadLoop matrix element in %d folder%s:"%\
5082 (len(VirtualFolders),'s' if len(VirtualFolders)>1 else ''))
5083 logger.debug(', '.join("'%s'"%os.path.basename(v_folder) for v_folder in
5084 VirtualFolders))
5085 for v_folder in VirtualFolders:
5086 init_info[v_folder] = {}
5087
5088
5089
5090 max_mult = 3
5091 if n_PS is None:
5092
5093 mcore.submit(run_initialization_wrapper,
5094 [pjoin(v_folder), init_info[v_folder], None])
5095 else:
5096
5097 mcore.submit(run_initialization_wrapper, [pjoin(v_folder),
5098 init_info[v_folder],
5099 [n_PS*multiplier for multiplier in range(1,max_mult+1)]])
5100
5101
5102 mcore.wait('',wait_monitoring,update_first=wait_monitoring)
5103 for v_folder in VirtualFolders:
5104 init = init_info[v_folder]
5105 if init['nPS'] is None:
5106 raise MadGraph5Error, 'Failed the initialization of'+\
5107 " loop-induced matrix element '%s'%s."%\
5108 (os.path.basename(v_folder),' (using default n_PS points)' if\
5109 n_PS is None else ' (trying with a maximum of %d PS points)'\
5110 %(max_mult*n_PS))
5111 if init['nPS']==0:
5112 logger.debug("Nothing to be done in '%s', all filters already "%\
5113 os.path.basename(v_folder)+\
5114 "present (use the '-r' option to force their recomputation)")
5115 else:
5116 logger.debug("'%s' finished using "%os.path.basename(v_folder)+
5117 '%d PS points (%s), in %.3g(compil.) + %.3g(init.) secs.'%(
5118 abs(init['nPS']),'DP' if init['nPS']>0 else 'QP',
5119 init['Process_compilation'],init['Initialization']))
5120
5121 logger.info('MadLoop initialization finished.')
5122
5123 AskforEditCard = common_run.AskforEditCard
5124
5125
5126 if '__main__' == __name__:
5127
5128
5129 import sys
5130 if not sys.version_info[0] == 2 or sys.version_info[1] < 6:
5131 sys.exit('MadGraph/MadEvent 5 works only with python 2.6 or later (but not python 3.X).\n'+\
5132 'Please upgrate your version of python.')
5133
5134 import os
5135 import optparse
5136
5137
5138 root_path = os.path.dirname(os.path.dirname(os.path.realpath( __file__ )))
5139 sys.path.insert(0, root_path)
5143 - def error(self, msg=''):
5145
5146 usage = "usage: %prog [options] [FILE] "
5147 parser = MyOptParser(usage=usage)
5148 parser.add_option("-l", "--logging", default='INFO',
5149 help="logging level (DEBUG|INFO|WARNING|ERROR|CRITICAL) [%default]")
5150 parser.add_option("","--web", action="store_true", default=False, dest='web', \
5151 help='force toce to be in secure mode')
5152 parser.add_option("","--debug", action="store_true", default=False, dest='debug', \
5153 help='force to launch debug mode')
5154 parser_error = ''
5155 done = False
5156
5157 for i in range(len(sys.argv)-1):
5158 try:
5159 (options, args) = parser.parse_args(sys.argv[1:len(sys.argv)-i])
5160 done = True
5161 except MyOptParser.InvalidOption, error:
5162 pass
5163 else:
5164 args += sys.argv[len(sys.argv)-i:]
5165 if not done:
5166
5167 try:
5168 (options, args) = parser.parse_args()
5169 except MyOptParser.InvalidOption, error:
5170 print error
5171 sys.exit(2)
5172
5173 if len(args) == 0:
5174 args = ''
5175
5176 import subprocess
5177 import logging
5178 import logging.config
5179
5180
5181 import internal.coloring_logging
5182 try:
5183 if __debug__ and options.logging == 'INFO':
5184 options.logging = 'DEBUG'
5185 if options.logging.isdigit():
5186 level = int(options.logging)
5187 else:
5188 level = eval('logging.' + options.logging)
5189 print os.path.join(root_path, 'internal', 'me5_logging.conf')
5190 logging.config.fileConfig(os.path.join(root_path, 'internal', 'me5_logging.conf'))
5191 logging.root.setLevel(level)
5192 logging.getLogger('madgraph').setLevel(level)
5193 except:
5194 raise
5195 pass
5196
5197
5198 try:
5199 if args:
5200
5201 if '--web' in args:
5202 i = args.index('--web')
5203 args.pop(i)
5204 cmd_line = MadEventCmd(force_run=True)
5205 else:
5206 cmd_line = MadEventCmdShell(force_run=True)
5207 if not hasattr(cmd_line, 'do_%s' % args[0]):
5208 if parser_error:
5209 print parser_error
5210 print 'and %s can not be interpreted as a valid command.' % args[0]
5211 else:
5212 print 'ERROR: %s not a valid command. Please retry' % args[0]
5213 else:
5214 cmd_line.use_rawinput = False
5215 cmd_line.run_cmd(' '.join(args))
5216 cmd_line.run_cmd('quit')
5217
5218 except KeyboardInterrupt:
5219 print 'quit on KeyboardInterrupt'
5220 pass
5221