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