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/madgraph5\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/madgraph5\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 nb_run = args.pop(0)
874 self.check_survey(args, cmd='multi_run')
875 args.insert(0, int(nb_run))
876
877 return run
878
880 """check that the argument for survey are valid"""
881
882
883 try:
884 float(args[-1])
885 except ValueError:
886 self.help_refine()
887 raise self.InvalidCmd('Not valid arguments')
888 except IndexError:
889 self.help_refine()
890 raise self.InvalidCmd('require_precision argument is require for refine cmd')
891
892
893 if not self.run_name:
894 if self.results.lastrun:
895 self.set_run_name(self.results.lastrun)
896 else:
897 raise self.InvalidCmd('No run_name currently define. Unable to run refine')
898
899 if len(args) > 2:
900 self.help_refine()
901 raise self.InvalidCmd('Too many argument for refine command')
902 else:
903 try:
904 [float(arg) for arg in args]
905 except ValueError:
906 self.help_refine()
907 raise self.InvalidCmd('refine arguments are suppose to be number')
908
909 return True
910
912 """ Check the argument for the combine events command """
913
914 tag = [a for a in arg if a.startswith('--tag=')]
915 if tag:
916 arg.remove(tag[0])
917 tag = tag[0][6:]
918 elif not self.run_tag:
919 tag = 'tag_1'
920 else:
921 tag = self.run_tag
922 self.run_tag = tag
923
924 if len(arg) > 1:
925 self.help_combine_events()
926 raise self.InvalidCmd('Too many argument for combine_events command')
927
928 if len(arg) == 1:
929 self.set_run_name(arg[0], self.run_tag, 'parton', True)
930
931 if not self.run_name:
932 if not self.results.lastrun:
933 raise self.InvalidCmd('No run_name currently define. Unable to run combine')
934 else:
935 self.set_run_name(self.results.lastrun)
936
937 return True
938
940 """Check the argument for pythia command
941 syntax: pythia [NAME]
942 Note that other option are already remove at this point
943 """
944
945 mode = None
946 laststep = [arg for arg in args if arg.startswith('--laststep=')]
947 if laststep and len(laststep)==1:
948 mode = laststep[0].split('=')[-1]
949 if mode not in ['auto', 'pythia', 'pgs', 'delphes']:
950 self.help_pythia()
951 raise self.InvalidCmd('invalid %s argument'% args[-1])
952 elif laststep:
953 raise self.InvalidCmd('only one laststep argument is allowed')
954
955
956 if not self.options['pythia-pgs_path']:
957 logger.info('Retry to read configuration file to find pythia-pgs path')
958 self.set_configuration()
959
960 if not self.options['pythia-pgs_path'] or not \
961 os.path.exists(pjoin(self.options['pythia-pgs_path'],'src')):
962 error_msg = 'No valid pythia-pgs path set.\n'
963 error_msg += 'Please use the set command to define the path and retry.\n'
964 error_msg += 'You can also define it in the configuration file.\n'
965 raise self.InvalidCmd(error_msg)
966
967
968
969 tag = [a for a in args if a.startswith('--tag=')]
970 if tag:
971 args.remove(tag[0])
972 tag = tag[0][6:]
973
974 if len(args) == 0 and not self.run_name:
975 if self.results.lastrun:
976 args.insert(0, self.results.lastrun)
977 else:
978 raise self.InvalidCmd('No run name currently define. Please add this information.')
979
980 if len(args) >= 1:
981 if args[0] != self.run_name and\
982 not os.path.exists(pjoin(self.me_dir,'Events',args[0], 'unweighted_events.lhe.gz')):
983 raise self.InvalidCmd('No events file corresponding to %s run. '% args[0])
984 self.set_run_name(args[0], tag, 'pythia')
985 else:
986 if tag:
987 self.run_card['run_tag'] = tag
988 self.set_run_name(self.run_name, tag, 'pythia')
989
990 input_file = pjoin(self.me_dir,'Events',self.run_name, 'unweighted_events.lhe')
991 output_file = pjoin(self.me_dir, 'Events', 'unweighted_events.lhe')
992 if not os.path.exists('%s.gz' % input_file):
993 if not os.path.exists(input_file):
994 raise self.InvalidCmd('No events file corresponding to %s run. '% self.run_name)
995 files.ln(input_file, os.path.dirname(output_file))
996 else:
997 misc.gunzip(input_file, keep=True, stdout=output_file)
998
999 args.append(mode)
1000
1002 """Check that the remove command is valid"""
1003
1004 tmp_args = args[:]
1005
1006 tag = [a[6:] for a in tmp_args if a.startswith('--tag=')]
1007 if tag:
1008 tag = tag[0]
1009 tmp_args.remove('--tag=%s' % tag)
1010
1011
1012 if len(tmp_args) == 0:
1013 self.help_remove()
1014 raise self.InvalidCmd('clean command require the name of the run to clean')
1015 elif len(tmp_args) == 1:
1016 return tmp_args[0], tag, ['all']
1017 else:
1018 for arg in tmp_args[1:]:
1019 if arg not in self._clean_mode:
1020 self.help_remove()
1021 raise self.InvalidCmd('%s is not a valid options for clean command'\
1022 % arg)
1023 return tmp_args[0], tag, tmp_args[1:]
1024
1026 """Check the argument for the plot command
1027 plot run_name modes"""
1028
1029 madir = self.options['madanalysis_path']
1030 td = self.options['td_path']
1031
1032 if not madir or not td:
1033 logger.info('Retry to read configuration file to find madanalysis/td')
1034 self.set_configuration()
1035
1036 madir = self.options['madanalysis_path']
1037 td = self.options['td_path']
1038
1039 if not madir:
1040 error_msg = 'No valid MadAnalysis path set.\n'
1041 error_msg += 'Please use the set command to define the path and retry.\n'
1042 error_msg += 'You can also define it in the configuration file.\n'
1043 raise self.InvalidCmd(error_msg)
1044 if not td:
1045 error_msg = 'No valid td path set.\n'
1046 error_msg += 'Please use the set command to define the path and retry.\n'
1047 error_msg += 'You can also define it in the configuration file.\n'
1048 raise self.InvalidCmd(error_msg)
1049
1050 if len(args) == 0:
1051 if not hasattr(self, 'run_name') or not self.run_name:
1052 self.help_plot()
1053 raise self.InvalidCmd('No run name currently define. Please add this information.')
1054 args.append('all')
1055 return
1056
1057
1058 if args[0] not in self._plot_mode:
1059 self.set_run_name(args[0], level='plot')
1060 del args[0]
1061 if len(args) == 0:
1062 args.append('all')
1063 elif not self.run_name:
1064 self.help_plot()
1065 raise self.InvalidCmd('No run name currently define. Please add this information.')
1066
1067 for arg in args:
1068 if arg not in self._plot_mode and arg != self.run_name:
1069 self.help_plot()
1070 raise self.InvalidCmd('unknown options %s' % arg)
1071
1073 """Check the argument for the syscalc command
1074 syscalc run_name modes"""
1075
1076 scdir = self.options['syscalc_path']
1077
1078 if not scdir:
1079 logger.info('Retry to read configuration file to find SysCalc')
1080 self.set_configuration()
1081
1082 scdir = self.options['syscalc_path']
1083
1084 if not scdir:
1085 error_msg = 'No valid SysCalc path set.\n'
1086 error_msg += 'Please use the set command to define the path and retry.\n'
1087 error_msg += 'You can also define it in the configuration file.\n'
1088 error_msg += 'Please note that you need to compile SysCalc first.'
1089 raise self.InvalidCmd(error_msg)
1090
1091 if len(args) == 0:
1092 if not hasattr(self, 'run_name') or not self.run_name:
1093 self.help_syscalc()
1094 raise self.InvalidCmd('No run name currently defined. Please add this information.')
1095 args.append('all')
1096 return
1097
1098
1099 tag = [a for a in args if a.startswith('--tag=')]
1100 if tag:
1101 args.remove(tag[0])
1102 tag = tag[0][6:]
1103
1104 if args[0] not in self._syscalc_mode:
1105 self.set_run_name(args[0], tag=tag, level='syscalc')
1106 del args[0]
1107 if len(args) == 0:
1108 args.append('all')
1109 elif not self.run_name:
1110 self.help_syscalc()
1111 raise self.InvalidCmd('No run name currently defined. Please add this information.')
1112 elif tag and tag != self.run_tag:
1113 self.set_run_name(self.run_name, tag=tag, level='syscalc')
1114
1115 for arg in args:
1116 if arg not in self._syscalc_mode and arg != self.run_name:
1117 self.help_syscalc()
1118 raise self.InvalidCmd('unknown options %s' % arg)
1119
1120 if self.run_card['use_syst'] not in self.true:
1121 raise self.InvalidCmd('Run %s does not include ' % self.run_name + \
1122 'systematics information needed for syscalc.')
1123
1124
1126 """Check the argument for pythia command
1127 syntax: pgs [NAME]
1128 Note that other option are already remove at this point
1129 """
1130
1131
1132 if not self.options['pythia-pgs_path']:
1133 logger.info('Retry to read configuration file to find pythia-pgs path')
1134 self.set_configuration()
1135
1136 if not self.options['pythia-pgs_path'] or not \
1137 os.path.exists(pjoin(self.options['pythia-pgs_path'],'src')):
1138 error_msg = 'No valid pythia-pgs path set.\n'
1139 error_msg += 'Please use the set command to define the path and retry.\n'
1140 error_msg += 'You can also define it in the configuration file.\n'
1141 raise self.InvalidCmd(error_msg)
1142
1143 tag = [a for a in arg if a.startswith('--tag=')]
1144 if tag:
1145 arg.remove(tag[0])
1146 tag = tag[0][6:]
1147
1148
1149 if len(arg) == 0 and not self.run_name:
1150 if self.results.lastrun:
1151 arg.insert(0, self.results.lastrun)
1152 else:
1153 raise self.InvalidCmd('No run name currently define. Please add this information.')
1154
1155 if len(arg) == 1 and self.run_name == arg[0]:
1156 arg.pop(0)
1157
1158 if not len(arg) and \
1159 not os.path.exists(pjoin(self.me_dir,'Events','pythia_events.hep')):
1160 self.help_pgs()
1161 raise self.InvalidCmd('''No file file pythia_events.hep currently available
1162 Please specify a valid run_name''')
1163
1164 lock = None
1165 if len(arg) == 1:
1166 prev_tag = self.set_run_name(arg[0], tag, 'pgs')
1167 if not os.path.exists(pjoin(self.me_dir,'Events',self.run_name,'%s_pythia_events.hep.gz' % prev_tag)):
1168 raise self.InvalidCmd('No events file corresponding to %s run with tag %s. '% (self.run_name, prev_tag))
1169 else:
1170 input_file = pjoin(self.me_dir,'Events', self.run_name, '%s_pythia_events.hep.gz' % prev_tag)
1171 output_file = pjoin(self.me_dir, 'Events', 'pythia_events.hep')
1172 lock = cluster.asyncrone_launch('gunzip',stdout=open(output_file,'w'),
1173 argument=['-c', input_file])
1174
1175 else:
1176 if tag:
1177 self.run_card['run_tag'] = tag
1178 self.set_run_name(self.run_name, tag, 'pgs')
1179
1180 return lock
1181
1183 """Check the argument for pythia command
1184 syntax: delphes [NAME]
1185 Note that other option are already remove at this point
1186 """
1187
1188
1189 if not self.options['delphes_path']:
1190 logger.info('Retry to read configuration file to find delphes path')
1191 self.set_configuration()
1192
1193 if not self.options['delphes_path']:
1194 error_msg = 'No valid Delphes path set.\n'
1195 error_msg += 'Please use the set command to define the path and retry.\n'
1196 error_msg += 'You can also define it in the configuration file.\n'
1197 raise self.InvalidCmd(error_msg)
1198
1199 tag = [a for a in arg if a.startswith('--tag=')]
1200 if tag:
1201 arg.remove(tag[0])
1202 tag = tag[0][6:]
1203
1204
1205 if len(arg) == 0 and not self.run_name:
1206 if self.results.lastrun:
1207 arg.insert(0, self.results.lastrun)
1208 else:
1209 raise self.InvalidCmd('No run name currently define. Please add this information.')
1210
1211 if len(arg) == 1 and self.run_name == arg[0]:
1212 arg.pop(0)
1213
1214 if not len(arg) and \
1215 not os.path.exists(pjoin(self.me_dir,'Events','pythia_events.hep')):
1216 self.help_pgs()
1217 raise self.InvalidCmd('''No file file pythia_events.hep currently available
1218 Please specify a valid run_name''')
1219
1220 lock = None
1221 if len(arg) == 1:
1222 prev_tag = self.set_run_name(arg[0], tag, 'delphes')
1223 if not os.path.exists(pjoin(self.me_dir,'Events',self.run_name, '%s_pythia_events.hep.gz' % prev_tag)):
1224 raise self.InvalidCmd('No events file corresponding to %s run with tag %s.:%s '\
1225 % (self.run_name, prev_tag,
1226 pjoin(self.me_dir,'Events',self.run_name, '%s_pythia_events.hep.gz' % prev_tag)))
1227 else:
1228 input_file = pjoin(self.me_dir,'Events', self.run_name, '%s_pythia_events.hep.gz' % prev_tag)
1229 output_file = pjoin(self.me_dir, 'Events', 'pythia_events.hep')
1230 lock = cluster.asyncrone_launch('gunzip',stdout=open(output_file,'w'),
1231 argument=['-c', input_file])
1232 else:
1233 if tag:
1234 self.run_card['run_tag'] = tag
1235 self.set_run_name(self.run_name, tag, 'delphes')
1236
1237 return lock
1238
1250
1251
1252
1253
1254
1256 """check the validity of line"""
1257
1258 if not args:
1259 self.help_import()
1260 raise self.InvalidCmd('wrong \"import\" format')
1261
1262 if args[0] != 'command':
1263 args.insert(0,'command')
1264
1265
1266 if not len(args) == 2 or not os.path.exists(args[1]):
1267 raise self.InvalidCmd('PATH is mandatory for import command\n')
1268
1274 """ The Series of help routine for the MadGraphCmd"""
1275
1276
1278 "Complete command"
1279
1280 args = self.split_arg(line[0:begidx], error=False)
1281
1282 if len(args) == 1:
1283
1284 data = glob.glob(pjoin(self.me_dir, 'Events', '*','unweighted_events.lhe.gz'))
1285 data = [n.rsplit('/',2)[1] for n in data]
1286 return self.list_completion(text, data + ['--threshold='], line)
1287 elif args[-1].endswith(os.path.sep):
1288 return self.path_completion(text,
1289 os.path.join('.',*[a for a in args \
1290 if a.endswith(os.path.sep)]))
1291 else:
1292 return self.list_completion(text, ['--threshold='], line)
1293
1295 "Complete the banner run command"
1296 try:
1297
1298
1299 args = self.split_arg(line[0:begidx], error=False)
1300
1301 if args[-1].endswith(os.path.sep):
1302 return self.path_completion(text,
1303 os.path.join('.',*[a for a in args \
1304 if a.endswith(os.path.sep)]))
1305
1306
1307 if len(args) > 1:
1308
1309 tags = glob.glob(pjoin(self.me_dir, 'Events' , args[1],'%s_*_banner.txt' % args[1]))
1310 tags = ['%s' % os.path.basename(t)[len(args[1])+1:-11] for t in tags]
1311
1312 if args[-1] != '--tag=':
1313 tags = ['--tag=%s' % t for t in tags]
1314 else:
1315 return self.list_completion(text, tags)
1316 return self.list_completion(text, tags +['--name=','-f'], line)
1317
1318
1319 possibilites = {}
1320
1321 comp = self.path_completion(text, os.path.join('.',*[a for a in args \
1322 if a.endswith(os.path.sep)]))
1323 if os.path.sep in line:
1324 return comp
1325 else:
1326 possibilites['Path from ./'] = comp
1327
1328 run_list = glob.glob(pjoin(self.me_dir, 'Events', '*','*_banner.txt'))
1329 run_list = [n.rsplit('/',2)[1] for n in run_list]
1330 possibilites['RUN Name'] = self.list_completion(text, run_list)
1331
1332 return self.deal_multiple_categories(possibilites)
1333
1334
1335 except Exception, error:
1336 print error
1337
1338
1339 - def complete_history(self, text, line, begidx, endidx):
1340 "Complete the history command"
1341
1342 args = self.split_arg(line[0:begidx], error=False)
1343
1344
1345 if args[-1].endswith(os.path.sep):
1346 return self.path_completion(text,
1347 os.path.join('.',*[a for a in args \
1348 if a.endswith(os.path.sep)]))
1349
1350 if len(args) == 1:
1351 return self.path_completion(text)
1352
1354 """ complete the open command """
1355
1356 args = self.split_arg(line[0:begidx])
1357
1358
1359 if os.path.sep in args[-1] + text:
1360 return self.path_completion(text,
1361 os.path.join('.',*[a for a in args if \
1362 a.endswith(os.path.sep)]))
1363
1364 possibility = []
1365 if self.me_dir:
1366 path = self.me_dir
1367 possibility = ['index.html']
1368 if os.path.isfile(os.path.join(path,'README')):
1369 possibility.append('README')
1370 if os.path.isdir(os.path.join(path,'Cards')):
1371 possibility += [f for f in os.listdir(os.path.join(path,'Cards'))
1372 if f.endswith('.dat')]
1373 if os.path.isdir(os.path.join(path,'HTML')):
1374 possibility += [f for f in os.listdir(os.path.join(path,'HTML'))
1375 if f.endswith('.html') and 'default' not in f]
1376 else:
1377 possibility.extend(['./','../'])
1378 if os.path.exists('ME5_debug'):
1379 possibility.append('ME5_debug')
1380 if os.path.exists('MG5_debug'):
1381 possibility.append('MG5_debug')
1382 return self.list_completion(text, possibility)
1383
1385 "Complete the set command"
1386
1387 args = self.split_arg(line[0:begidx])
1388
1389
1390 if len(args) == 1:
1391 return self.list_completion(text, self._set_options + self.options.keys() )
1392
1393 if len(args) == 2:
1394 if args[1] == 'stdout_level':
1395 return self.list_completion(text, ['DEBUG','INFO','WARNING','ERROR','CRITICAL'])
1396 else:
1397 first_set = ['None','True','False']
1398
1399 second_set = [name for name in self.path_completion(text, '.', only_dirs = True)]
1400 return self.list_completion(text, first_set + second_set)
1401 elif len(args) >2 and args[-1].endswith(os.path.sep):
1402 return self.path_completion(text,
1403 os.path.join('.',*[a for a in args if a.endswith(os.path.sep)]),
1404 only_dirs = True)
1405
1407 """ Complete the survey command """
1408
1409 if line.endswith('nb_core=') and not text:
1410 import multiprocessing
1411 max = multiprocessing.cpu_count()
1412 return [str(i) for i in range(2,max+1)]
1413
1414 return self.list_completion(text, self._run_options, line)
1415
1416 complete_refine = complete_survey
1417 complete_combine_events = complete_survey
1418 complite_store = complete_survey
1419 complete_generate_events = complete_survey
1420 complete_create_gridpack = complete_survey
1421
1423 """ Complete the generate events"""
1424
1425 if line.endswith('nb_core=') and not text:
1426 import multiprocessing
1427 max = multiprocessing.cpu_count()
1428 return [str(i) for i in range(2,max+1)]
1429 if line.endswith('laststep=') and not text:
1430 return ['parton','pythia','pgs','delphes']
1431 elif '--laststep=' in line.split()[-1] and line and line[-1] != ' ':
1432 return self.list_completion(text,['parton','pythia','pgs','delphes'],line)
1433
1434 opts = self._run_options + self._generate_options
1435 return self.list_completion(text, opts, line)
1436
1437
1439 "Complete the initMadLoop command"
1440
1441 numbers = [str(i) for i in range(10)]
1442 opts = ['-f','-r','--nPS=']
1443
1444 args = self.split_arg(line[0:begidx], error=False)
1445 if len(line) >=6 and line[begidx-6:begidx]=='--nPS=':
1446 return self.list_completion(text, numbers, line)
1447 else:
1448 return self.list_completion(text, [opt for opt in opts if not opt in
1449 line], line)
1450
1457
1459 """ Complete the calculate_decay_widths command"""
1460
1461 if line.endswith('nb_core=') and not text:
1462 import multiprocessing
1463 max = multiprocessing.cpu_count()
1464 return [str(i) for i in range(2,max+1)]
1465
1466 opts = self._run_options + self._calculate_decay_options
1467 return self.list_completion(text, opts, line)
1468
1477
1479 """complete multi run command"""
1480
1481 args = self.split_arg(line[0:begidx], error=False)
1482 if len(args) == 1:
1483 data = [str(i) for i in range(0,20)]
1484 return self.list_completion(text, data, line)
1485
1486 if line.endswith('run=') and not text:
1487 return ['parton','pythia','pgs','delphes']
1488 elif '--laststep=' in line.split()[-1] and line and line[-1] != ' ':
1489 return self.list_completion(text,['parton','pythia','pgs','delphes'],line)
1490
1491 opts = self._run_options + self._generate_options
1492 return self.list_completion(text, opts, line)
1493
1494
1495
1496 if line.endswith('nb_core=') and not text:
1497 import multiprocessing
1498 max = multiprocessing.cpu_count()
1499 return [str(i) for i in range(2,max+1)]
1500 opts = self._run_options + self._generate_options
1501 return self.list_completion(text, opts, line)
1502
1511
1529
1531 """Complete the remove command """
1532
1533 args = self.split_arg(line[0:begidx], error=False)
1534 if len(args) > 1 and (text.startswith('--t')):
1535 run = args[1]
1536 tags = ['--tag=%s' % tag['tag'] for tag in self.results[run]]
1537 return self.list_completion(text, tags)
1538 elif len(args) > 1 and '--' == args[-1]:
1539 run = args[1]
1540 tags = ['tag=%s' % tag['tag'] for tag in self.results[run]]
1541 return self.list_completion(text, tags)
1542 elif len(args) > 1 and '--tag=' == args[-1]:
1543 run = args[1]
1544 tags = [tag['tag'] for tag in self.results[run]]
1545 return self.list_completion(text, tags)
1546 elif len(args) > 1:
1547 return self.list_completion(text, self._clean_mode + ['-f','--tag='])
1548 else:
1549 data = glob.glob(pjoin(self.me_dir, 'Events','*','*_banner.txt'))
1550 data = [n.rsplit('/',2)[1] for n in data]
1551 return self.list_completion(text, ['all'] + data)
1552
1553
1555 "Complete the pythia command"
1556 args = self.split_arg(line[0:begidx], error=False)
1557
1558 if len(args) == 1:
1559
1560 data = glob.glob(pjoin(self.me_dir, 'Events', '*','unweighted_events.lhe.gz'))
1561 data = [n.rsplit('/',2)[1] for n in data]
1562 tmp1 = self.list_completion(text, data)
1563 if not self.run_name:
1564 return tmp1
1565 else:
1566 tmp2 = self.list_completion(text, self._run_options + ['-f',
1567 '--no_default', '--tag='], line)
1568 return tmp1 + tmp2
1569 elif line[-1] != '=':
1570 return self.list_completion(text, self._run_options + ['-f',
1571 '--no_default','--tag='], line)
1572
1574 "Complete the pythia command"
1575 args = self.split_arg(line[0:begidx], error=False)
1576 if len(args) == 1:
1577
1578 data = glob.glob(pjoin(self.me_dir, 'Events', '*', '*_pythia_events.hep.gz'))
1579 data = [n.rsplit('/',2)[1] for n in data]
1580 tmp1 = self.list_completion(text, data)
1581 if not self.run_name:
1582 return tmp1
1583 else:
1584 tmp2 = self.list_completion(text, self._run_options + ['-f',
1585 '--tag=' ,'--no_default'], line)
1586 return tmp1 + tmp2
1587 else:
1588 return self.list_completion(text, self._run_options + ['-f',
1589 '--tag=','--no_default'], line)
1590
1591 complete_delphes = complete_pgs
1592
1593
1594
1595
1596
1597
1598
1599
1600 -class MadEventCmd(CompleteForCmd, CmdExtended, HelpToCmd, common_run.CommonRunCmd):
1601
1602 """The command line processor of MadGraph"""
1603
1604
1605 true = ['T','.true.',True,'true']
1606
1607 _run_options = ['--cluster','--multicore','--nb_core=','--nb_core=2', '-c', '-m']
1608 _generate_options = ['-f', '--laststep=parton', '--laststep=pythia', '--laststep=pgs', '--laststep=delphes']
1609 _calculate_decay_options = ['-f', '--accuracy=0.']
1610 _set_options = ['stdout_level','fortran_compiler','timeout']
1611 _plot_mode = ['all', 'parton','pythia','pgs','delphes','channel', 'banner']
1612 _syscalc_mode = ['all', 'parton','pythia']
1613 _clean_mode = _plot_mode
1614 _display_opts = ['run_name', 'options', 'variable', 'results']
1615 _save_opts = ['options']
1616 _initMadLoop_opts = ['-f','-r','--nPS=']
1617
1618 _survey_options = {'points':('int', 1000,'Number of points for first iteration'),
1619 'iterations':('int', 5, 'Number of iterations'),
1620 'accuracy':('float', 0.1, 'Required accuracy'),
1621 'gridpack':('str', '.false.', 'Gridpack generation')}
1622
1623 true = ['T','.true.',True,'true', 1, '1']
1624 web = False
1625 cluster_mode = 0
1626 queue = 'madgraph'
1627 nb_core = None
1628
1629 next_possibility = {
1630 'start': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]',
1631 'calculate_decay_widths [OPTIONS]',
1632 'help generate_events'],
1633 'generate_events': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]', 'pythia', 'pgs','delphes'],
1634 'calculate_decay_widths': ['calculate_decay_widths [OPTIONS]',
1635 'generate_events [OPTIONS]'],
1636 'multi_run': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]'],
1637 'survey': ['refine'],
1638 'refine': ['combine_events'],
1639 'combine_events': ['store'],
1640 'store': ['pythia'],
1641 'pythia': ['pgs', 'delphes'],
1642 'pgs': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]'],
1643 'delphes' : ['generate_events [OPTIONS]', 'multi_run [OPTIONS]']
1644 }
1645
1646
1647 - def __init__(self, me_dir = None, options={}, *completekey, **stdin):
1648 """ add information to the cmd """
1649
1650 CmdExtended.__init__(self, me_dir, options, *completekey, **stdin)
1651
1652
1653 self.mode = 'madevent'
1654 self.nb_refine=0
1655 if self.web:
1656 os.system('touch %s' % pjoin(self.me_dir,'Online'))
1657
1658
1659
1660 if os.path.exists(pjoin(self.me_dir,'HTML','results.pkl')):
1661 try:
1662 self.results = save_load_object.load_from_file(pjoin(self.me_dir,'HTML','results.pkl'))
1663 except Exception:
1664
1665 model = self.find_model_name()
1666 process = self.process
1667 self.results = gen_crossxhtml.AllResults(model, process, self.me_dir)
1668 self.results.resetall(self.me_dir)
1669 else:
1670 self.results.resetall(self.me_dir)
1671 else:
1672 model = self.find_model_name()
1673 process = self.process
1674 self.results = gen_crossxhtml.AllResults(model, process, self.me_dir)
1675 self.results.resetall(self.me_dir)
1676 self.results.def_web_mode(self.web)
1677
1678 self.prompt = "%s>"%os.path.basename(pjoin(self.me_dir))
1679 self.configured = 0
1680 self._options = {}
1681
1682
1684 """configure web data"""
1685 self.web = True
1686 self.results.def_web_mode(True)
1687 self.force = True
1688 if os.environ['MADGRAPH_BASE']:
1689 self.options['mg5_path'] = pjoin(os.environ['MADGRAPH_BASE'],'MG5')
1690
1691
1693 """ Check that the output path is a valid madevent directory """
1694
1695 bin_path = os.path.join(path,'bin')
1696 if os.path.isfile(os.path.join(bin_path,'generate_events')):
1697 return True
1698 else:
1699 return False
1700
1701
1703 """assign all configuration variable from file
1704 loop over the different config file if config_file not define """
1705
1706 super(MadEventCmd,self).set_configuration(amcatnlo=amcatnlo,
1707 final=final, **opt)
1708
1709 if not final:
1710 return self.options
1711
1712
1713
1714
1715
1716 for key in (k for k in self.options if k.endswith('path')):
1717 path = self.options[key]
1718 if path is None or key.startswith("cluster"):
1719 continue
1720 if not os.path.isdir(path):
1721 path = pjoin(self.me_dir, self.options[key])
1722 if os.path.isdir(path):
1723 self.options[key] = None
1724 if key == "pythia-pgs_path":
1725 if not os.path.exists(pjoin(path, 'src','pythia')):
1726 logger.info("No valid pythia-pgs path found")
1727 continue
1728 elif key == "delphes_path":
1729 if not os.path.exists(pjoin(path, 'Delphes')) and not\
1730 os.path.exists(pjoin(path, 'DelphesSTDHEP')):
1731 logger.info("No valid Delphes path found")
1732 continue
1733 elif key == "madanalysis_path":
1734 if not os.path.exists(pjoin(path, 'plot_events')):
1735 logger.info("No valid MadAnalysis path found")
1736 continue
1737 elif key == "td_path":
1738 if not os.path.exists(pjoin(path, 'td')):
1739 logger.info("No valid td path found")
1740 continue
1741 elif key == "syscalc_path":
1742 if not os.path.exists(pjoin(path, 'sys_calc')):
1743 logger.info("No valid SysCalc path found")
1744 continue
1745
1746
1747 self.options[key] = os.path.realpath(path)
1748 continue
1749 else:
1750 self.options[key] = None
1751
1752
1753 return self.options
1754
1755
1809
1810
1812 """Make a run from the banner file"""
1813
1814 args = self.split_arg(line)
1815
1816 self.check_banner_run(args)
1817
1818
1819 for name in ['delphes_trigger.dat', 'delphes_card.dat',
1820 'pgs_card.dat', 'pythia_card.dat', 'madspin_card.dat',
1821 'reweight_card.dat']:
1822 try:
1823 os.remove(pjoin(self.me_dir, 'Cards', name))
1824 except Exception:
1825 pass
1826
1827 banner_mod.split_banner(args[0], self.me_dir, proc_card=False)
1828
1829
1830 if not self.force:
1831 ans = self.ask('Do you want to modify the Cards?', 'n', ['y','n'])
1832 if ans == 'n':
1833 self.force = True
1834
1835
1836 self.exec_cmd('generate_events %s %s' % (self.run_name, self.force and '-f' or ''))
1837
1838
1839
1840
1842 """Display current internal status"""
1843
1844 args = self.split_arg(line)
1845
1846 self.check_display(args)
1847
1848 if args[0] == 'run_name':
1849
1850 data = glob.glob(pjoin(self.me_dir, 'Events', '*','*_banner.txt'))
1851 data = [n.rsplit('/',2)[1:] for n in data]
1852
1853 if data:
1854 out = {}
1855 for name, tag in data:
1856 tag = tag[len(name)+1:-11]
1857 if name in out:
1858 out[name].append(tag)
1859 else:
1860 out[name] = [tag]
1861 print 'the runs available are:'
1862 for run_name, tags in out.items():
1863 print ' run: %s' % run_name
1864 print ' tags: ',
1865 print ', '.join(tags)
1866 else:
1867 print 'No run detected.'
1868
1869 elif args[0] == 'options':
1870 outstr = " Run Options \n"
1871 outstr += " ----------- \n"
1872 for key, default in self.options_madgraph.items():
1873 value = self.options[key]
1874 if value == default:
1875 outstr += " %25s \t:\t%s\n" % (key,value)
1876 else:
1877 outstr += " %25s \t:\t%s (user set)\n" % (key,value)
1878 outstr += "\n"
1879 outstr += " MadEvent Options \n"
1880 outstr += " ---------------- \n"
1881 for key, default in self.options_madevent.items():
1882 if key in self.options:
1883 value = self.options[key]
1884 else:
1885 default = ''
1886 if value == default:
1887 outstr += " %25s \t:\t%s\n" % (key,value)
1888 else:
1889 outstr += " %25s \t:\t%s (user set)\n" % (key,value)
1890 outstr += "\n"
1891 outstr += " Configuration Options \n"
1892 outstr += " --------------------- \n"
1893 for key, default in self.options_configuration.items():
1894 value = self.options[key]
1895 if value == default:
1896 outstr += " %25s \t:\t%s\n" % (key,value)
1897 else:
1898 outstr += " %25s \t:\t%s (user set)\n" % (key,value)
1899 output.write(outstr)
1900 elif args[0] == 'results':
1901 self.do_print_results(' '.join(args[1:]))
1902 else:
1903 super(MadEventCmd, self).do_display(line, output)
1904
1905 - def do_save(self, line, check=True, to_keep={}):
1906 """Not in help: Save information to file"""
1907
1908 args = self.split_arg(line)
1909
1910 if check:
1911 self.check_save(args)
1912
1913 if args[0] == 'options':
1914
1915 to_define = {}
1916 for key, default in self.options_configuration.items():
1917 if self.options[key] != self.options_configuration[key]:
1918 to_define[key] = self.options[key]
1919
1920 if not '--auto' in args:
1921 for key, default in self.options_madevent.items():
1922 if self.options[key] != self.options_madevent[key]:
1923 to_define[key] = self.options[key]
1924
1925 if '--all' in args:
1926 for key, default in self.options_madgraph.items():
1927 if self.options[key] != self.options_madgraph[key]:
1928 to_define[key] = self.options[key]
1929 elif not '--auto' in args:
1930 for key, default in self.options_madgraph.items():
1931 if self.options[key] != self.options_madgraph[key]:
1932 logger.info('The option %s is modified [%s] but will not be written in the configuration files.' \
1933 % (key,self.options_madgraph[key]) )
1934 logger.info('If you want to make this value the default for future session, you can run \'save options --all\'')
1935 if len(args) >1 and not args[1].startswith('--'):
1936 filepath = args[1]
1937 else:
1938 filepath = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
1939 basefile = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
1940 basedir = self.me_dir
1941
1942 if to_keep:
1943 to_define = to_keep
1944 self.write_configuration(filepath, basefile, basedir, to_define)
1945
1946
1947
1948
1957
1958
1959
1960
1962 """Main Commands: launch the full chain """
1963
1964 self.banner = None
1965 args = self.split_arg(line)
1966
1967 mode = self.check_generate_events(args)
1968 self.ask_run_configuration(mode, args)
1969 if not args:
1970
1971 self.set_run_name(self.find_available_run_name(self.me_dir), None, 'parton')
1972 else:
1973 self.set_run_name(args[0], None, 'parton', True)
1974 args.pop(0)
1975
1976 if self.run_card['gridpack'] in self.true:
1977
1978 gridpack_opts=[('accuracy', 0.01),
1979 ('points', 2000),
1980 ('iterations',8),
1981 ('gridpack','.true.')]
1982 logger.info('Generating gridpack with run name %s' % self.run_name)
1983 self.exec_cmd('survey %s %s' % \
1984 (self.run_name,
1985 " ".join(['--' + opt + '=' + str(val) for (opt,val) \
1986 in gridpack_opts])),
1987 postcmd=False)
1988 self.exec_cmd('combine_events', postcmd=False)
1989 self.exec_cmd('store_events', postcmd=False)
1990 self.exec_cmd('decay_events -from_cards', postcmd=False)
1991 self.exec_cmd('create_gridpack', postcmd=False)
1992 else:
1993
1994 logger.info('Generating %s events with run name %s' %
1995 (self.run_card['nevents'], self.run_name))
1996
1997 self.exec_cmd('survey %s %s' % (self.run_name,' '.join(args)),
1998 postcmd=False)
1999 nb_event = self.run_card['nevents']
2000 self.exec_cmd('refine %s' % nb_event, postcmd=False)
2001 if not float(self.results.current['cross']):
2002
2003 text = '''Survey return zero cross section.
2004 Typical reasons are the following:
2005 1) A massive s-channel particle has a width set to zero.
2006 2) The pdf are zero for at least one of the initial state particles
2007 or you are using maxjetflavor=4 for initial state b:s.
2008 3) The cuts are too strong.
2009 Please check/correct your param_card and/or your run_card.'''
2010 logger_stderr.critical(text)
2011 raise ZeroResult('See https://cp3.irmp.ucl.ac.be/projects/madgraph/wiki/FAQ-General-14')
2012
2013 self.exec_cmd('refine %s' % nb_event, postcmd=False)
2014
2015 self.exec_cmd('combine_events', postcmd=False)
2016 self.print_results_in_shell(self.results.current)
2017
2018
2019 self.run_syscalc('parton')
2020 self.create_plot('parton')
2021 self.exec_cmd('store_events', postcmd=False)
2022 self.exec_cmd('reweight -from_cards', postcmd=False)
2023 self.exec_cmd('decay_events -from_cards', postcmd=False)
2024 if self.run_card['time_of_flight']>=0:
2025 self.exec_cmd("add_time_of_flight --threshold=%s" % self.run_card['time_of_flight'] ,postcmd=False)
2026 self.exec_cmd('pythia --no_default', postcmd=False, printcmd=False)
2027
2028 self.store_result()
2029
2031 """Compile and run MadLoop for a certain number of PS point so as to
2032 initialize MadLoop (setup the zero helicity and loop filter.)"""
2033
2034 args = line.split()
2035
2036 options = self.check_initMadLoop(args)
2037
2038 if not options['force']:
2039 self.ask_edit_cards(['MadLoopParams.dat'], mode='fixed', plot=False)
2040 self.exec_cmd('treatcards loop --no_MadLoopInit')
2041
2042 if options['refresh']:
2043 for filter in glob.glob(pjoin(
2044 self.me_dir,'SubProcesses','MadLoop5_resources','*Filter*')):
2045 logger.debug("Resetting filter '%s'."%os.path.basename(filter))
2046 os.remove(filter)
2047
2048 MLCard = banner_mod.MadLoopParam(pjoin(self.me_dir,
2049 'Cards','MadLoopParams.dat'))
2050 if options['nPS'] is None:
2051 options['nPS'] = MLCard['CheckCycle']+2
2052 elif options['nPS'] < MLCard['CheckCycle']+2:
2053 new_n_PS = MLCard['CheckCycle']+2
2054 logger.debug('Hard-setting user-defined n_PS (%d) to %d, because '\
2055 %(options['nPS'],new_n_PS)+"of the 'CheckCycle' value (%d) "%MLCard['CheckCycle']+\
2056 "specified in the ML param card.")
2057 options['nPS'] = new_n_PS
2058
2059 MadLoopInitializer.init_MadLoop(self.me_dir,n_PS=options['nPS'],
2060 subproc_prefix='PV', MG_options=self.options, interface=self)
2061
2063 """Main Commands: exec generate_events for 2>N and calculate_width for 1>N"""
2064 if self.ninitial == 1:
2065 logger.info("Note that since 2.3. The launch for 1>N pass in event generation\n"+
2066 " To have the previous behavior use the calculate_decay_widths function")
2067 self.do_calculate_decay_widths(line, *args, **opt)
2068 else:
2069 self.do_generate_events(line, *args, **opt)
2070
2072 """Have a nice results prints in the shell,
2073 data should be of type: gen_crossxhtml.OneTagResults"""
2074
2075 if not data:
2076 return
2077
2078 if data['run_statistics']:
2079 globalstat = sum_html.RunStatistics()
2080
2081 logger.info(" " )
2082 logger.debug(" === Run statistics summary ===")
2083 for key, value in data['run_statistics'].items():
2084 globalstat.aggregate_statistics(value)
2085 level = 5
2086 if value.has_warning():
2087 level = 10
2088 logger.log(level, value.nice_output(str('/'.join([key[0],'G%s'%key[1]]))).\
2089 replace(' statistics',''))
2090 logger.info(" " )
2091 logger.debug(globalstat.nice_output('combined', no_warning=True))
2092 if globalstat.has_warning():
2093 logger.warning(globalstat.get_warning_text())
2094 logger.info(" ")
2095
2096
2097 logger.info(" === Results Summary for run: %s tag: %s ===\n" % (data['run_name'],data['tag']))
2098
2099 total_time = int(sum(_['cumulative_timing'] for _ in data['run_statistics'].values()))
2100 if total_time > 0:
2101 logger.info(" Cumulative sequential time for this run: %s"%misc.format_time(total_time))
2102
2103 if self.ninitial == 1:
2104 logger.info(" Width : %.4g +- %.4g GeV" % (data['cross'], data['error']))
2105 else:
2106 logger.info(" Cross-section : %.4g +- %.4g pb" % (data['cross'], data['error']))
2107 logger.info(" Nb of events : %s" % data['nb_event'] )
2108 if data['cross_pythia'] and data['nb_event_pythia']:
2109 if self.ninitial == 1:
2110 logger.info(" Matched Width : %.4g +- %.4g GeV" % (data['cross_pythia'], data['error_pythia']))
2111 else:
2112 logger.info(" Matched Cross-section : %.4g +- %.4g pb" % (data['cross_pythia'], data['error_pythia']))
2113 logger.info(" Nb of events after Matching : %s" % data['nb_event_pythia'])
2114 if self.run_card['use_syst'] in self.true:
2115 logger.info(" Be carefull that matched information are here NOT for the central value. Refer to SysCalc output for it")
2116
2117 logger.info(" " )
2118
2120 """Have a nice results prints in the shell,
2121 data should be of type: gen_crossxhtml.OneTagResults"""
2122 if not data:
2123 return
2124
2125 fsock = open(path, mode)
2126
2127 if data['run_statistics']:
2128 logger.debug(" === Run statistics summary ===")
2129 for key, value in data['run_statistics'].items():
2130 logger.debug(value.nice_output(str('/'.join([key[0],'G%s'%key[1]]))).\
2131 replace(' statistics',''))
2132 logger.info(" " )
2133
2134 if format == "full":
2135 fsock.write(" === Results Summary for run: %s tag: %s process: %s ===\n" % \
2136 (data['run_name'],data['tag'], os.path.basename(self.me_dir)))
2137
2138 if self.ninitial == 1:
2139 fsock.write(" Width : %.4g +- %.4g GeV\n" % (data['cross'], data['error']))
2140 else:
2141 fsock.write(" Cross-section : %.4g +- %.4g pb\n" % (data['cross'], data['error']))
2142 fsock.write(" Nb of events : %s\n" % data['nb_event'] )
2143 if data['cross_pythia'] and data['nb_event_pythia']:
2144 if self.ninitial == 1:
2145 fsock.write(" Matched Width : %.4g +- %.4g GeV\n" % (data['cross_pythia'], data['error_pythia']))
2146 else:
2147 fsock.write(" Matched Cross-section : %.4g +- %.4g pb\n" % (data['cross_pythia'], data['error_pythia']))
2148 fsock.write(" Nb of events after Matching : %s\n" % data['nb_event_pythia'])
2149 fsock.write(" \n" )
2150 elif format == "short":
2151 if mode == "w":
2152 fsock.write("# run_name tag cross error Nb_event cross_after_matching nb_event_after matching\n")
2153
2154 if data['cross_pythia'] and data['nb_event_pythia']:
2155 text = "%(run_name)s %(tag)s %(cross)s %(error)s %(nb_event)s %(cross_pythia)s %(nb_event_pythia)s\n"
2156 else:
2157 text = "%(run_name)s %(tag)s %(cross)s %(error)s %(nb_event)s\n"
2158 fsock.write(text % data)
2159
2160
2162 """Main Commands: launch decay width calculation and automatic inclusion of
2163 calculated widths and BRs in the param_card."""
2164
2165 args = self.split_arg(line)
2166
2167 accuracy = self.check_calculate_decay_widths(args)
2168 self.ask_run_configuration('parton')
2169 self.banner = None
2170 if not args:
2171
2172 self.set_run_name(self.find_available_run_name(self.me_dir))
2173 else:
2174 self.set_run_name(args[0], reload_card=True)
2175 args.pop(0)
2176
2177 self.configure_directory()
2178
2179
2180 opts=[('accuracy', accuracy),
2181 ('points', 1000),
2182 ('iterations',9)]
2183
2184 logger.info('Calculating decay widths with run name %s' % self.run_name)
2185
2186 self.exec_cmd('survey %s %s' % \
2187 (self.run_name,
2188 " ".join(['--' + opt + '=' + str(val) for (opt,val) \
2189 in opts])),
2190 postcmd=False)
2191 self.refine_mode = "old"
2192 self.exec_cmd('combine_events', postcmd=False)
2193 self.exec_cmd('store_events', postcmd=False)
2194
2195 self.collect_decay_widths()
2196 self.print_results_in_shell(self.results.current)
2197 self.update_status('calculate_decay_widths done',
2198 level='parton', makehtml=False)
2199
2200
2201
2203 """ Collect the decay widths and calculate BRs for all particles, and put
2204 in param_card form.
2205 """
2206
2207 particle_dict = {}
2208 run_name = self.run_name
2209
2210
2211 for P_path in SubProcesses.get_subP(self.me_dir):
2212 ids = SubProcesses.get_subP_ids(P_path)
2213
2214
2215
2216 nb_output = len(ids) / (len(set([p[0] for p in ids])))
2217 results = open(pjoin(P_path, run_name + '_results.dat')).read().split('\n')[0]
2218 result = float(results.strip().split(' ')[0])
2219 for particles in ids:
2220 try:
2221 particle_dict[particles[0]].append([particles[1:], result/nb_output])
2222 except KeyError:
2223 particle_dict[particles[0]] = [[particles[1:], result/nb_output]]
2224
2225 self.update_width_in_param_card(particle_dict,
2226 initial = pjoin(self.me_dir, 'Cards', 'param_card.dat'),
2227 output=pjoin(self.me_dir, 'Events', run_name, "param_card.dat"))
2228
2229 @staticmethod
2231
2232
2233 if not output:
2234 output = initial
2235
2236 param_card_file = open(initial)
2237 param_card = param_card_file.read().split('\n')
2238 param_card_file.close()
2239
2240 decay_lines = []
2241 line_number = 0
2242
2243 while line_number < len(param_card):
2244 line = param_card[line_number]
2245 if line.lower().startswith('decay'):
2246
2247
2248 line = param_card.pop(line_number)
2249 line = line.split()
2250 particle = 0
2251 if int(line[1]) not in decay_info:
2252 try:
2253 particle = int(line[1])
2254 width = float(line[2])
2255 except Exception:
2256 particle = 0
2257
2258 line = param_card[line_number]
2259 while line.startswith('#') or line.startswith(' '):
2260 line = param_card.pop(line_number)
2261 if not particle or line.startswith('#'):
2262 line=param_card[line_number]
2263 continue
2264
2265 line = line.split()
2266 try:
2267 partial_width = float(line[0])*width
2268 decay_products = [int(p) for p in line[2:2+int(line[1])]]
2269 except Exception:
2270 line=param_card[line_number]
2271 continue
2272 try:
2273 decay_info[particle].append([decay_products, partial_width])
2274 except KeyError:
2275 decay_info[particle] = [[decay_products, partial_width]]
2276 if line_number == len(param_card):
2277 break
2278 line=param_card[line_number]
2279 if particle and particle not in decay_info:
2280
2281 decay_info[particle] = [[[], width]]
2282 else:
2283 line_number += 1
2284
2285 while not param_card[-1] or param_card[-1].startswith('#'):
2286 param_card.pop(-1)
2287
2288
2289 param_card.append("#\n#*************************")
2290 param_card.append("# Decay widths *")
2291 param_card.append("#*************************")
2292 for key in sorted(decay_info.keys()):
2293 width = sum([r for p,r in decay_info[key]])
2294 param_card.append("#\n# PDG Width")
2295 param_card.append("DECAY %i %e" % (key, width.real))
2296 if not width:
2297 continue
2298 if decay_info[key][0][0]:
2299 param_card.append("# BR NDA ID1 ID2 ...")
2300 brs = [[(val[1]/width).real, val[0]] for val in decay_info[key] if val[1]]
2301 for val in sorted(brs, reverse=True):
2302 param_card.append(" %e %i %s # %s" %
2303 (val[0].real, len(val[1]),
2304 " ".join([str(v) for v in val[1]]),
2305 val[0] * width
2306 ))
2307 decay_table = open(output, 'w')
2308 decay_table.write("\n".join(param_card) + "\n")
2309 decay_table.close()
2310 logger.info("Results written to %s" % output)
2311
2312
2313
2315
2316 args = self.split_arg(line)
2317
2318 mode = self.check_multi_run(args)
2319 nb_run = args.pop(0)
2320 if nb_run == 1:
2321 logger.warn("'multi_run 1' command is not optimal. Think of using generate_events instead")
2322 self.ask_run_configuration(mode)
2323 main_name = self.run_name
2324
2325
2326
2327
2328
2329 crossoversig = 0
2330 inv_sq_err = 0
2331 nb_event = 0
2332 for i in range(nb_run):
2333 self.nb_refine = 0
2334 self.exec_cmd('generate_events %s_%s -f' % (main_name, i), postcmd=False)
2335
2336 nb_event += int(self.results[self.run_name][-1]['nb_event'])
2337 self.results.add_detail('nb_event', nb_event , run=main_name)
2338 cross = self.results[self.run_name][-1]['cross']
2339 error = self.results[self.run_name][-1]['error'] + 1e-99
2340 crossoversig+=cross/error**2
2341 inv_sq_err+=1.0/error**2
2342 self.results[main_name][-1]['cross'] = crossoversig/inv_sq_err
2343 self.results[main_name][-1]['error'] = math.sqrt(1.0/inv_sq_err)
2344 self.results.def_current(main_name)
2345 self.run_name = main_name
2346 self.update_status("Merging LHE files", level='parton')
2347 try:
2348 os.mkdir(pjoin(self.me_dir,'Events', self.run_name))
2349 except Exception:
2350 pass
2351 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'
2352 % {'bin': self.dirbin, 'event': pjoin(self.me_dir,'Events'),
2353 'name': self.run_name})
2354
2355 eradir = self.options['exrootanalysis_path']
2356 if eradir and misc.is_executable(pjoin(eradir,'ExRootLHEFConverter')):
2357 self.update_status("Create Root file", level='parton')
2358 misc.gunzip('%s/%s/unweighted_events.lhe.gz' %
2359 (pjoin(self.me_dir,'Events'), self.run_name))
2360
2361 self.create_root_file('%s/unweighted_events.lhe' % self.run_name,
2362 '%s/unweighted_events.root' % self.run_name)
2363
2364 path = pjoin(self.me_dir, "Events", self.run_name, "unweighted_events.lhe")
2365 self.create_plot('parton', path,
2366 pjoin(self.me_dir, 'HTML',self.run_name, 'plots_parton.html')
2367 )
2368
2369
2370 if not os.path.exists('%s.gz' % path):
2371 misc.gzip(path)
2372
2373 self.update_status('', level='parton')
2374 self.print_results_in_shell(self.results.current)
2375
2376
2377
2379 """Advanced commands: create .inc files from param_card.dat/run_card.dat"""
2380
2381 if not mode and not opt:
2382 args = self.split_arg(line)
2383 mode, opt = self.check_treatcards(args)
2384
2385
2386
2387
2388 need_MadLoopFilterUpdate = False
2389
2390
2391 type_of_change = ''
2392 if not opt['forbid_MadLoopInit'] and self.proc_characteristics['loop_induced'] \
2393 and mode in ['loop', 'all']:
2394 paramDat = pjoin(self.me_dir, 'Cards','param_card.dat')
2395 paramInc = pjoin(opt['output_dir'], 'param_card.inc')
2396 if (not os.path.isfile(paramDat)) or (not os.path.isfile(paramInc)) or \
2397 (os.path.getmtime(paramDat)-os.path.getmtime(paramInc)) > 0.0:
2398 need_MadLoopFilterUpdate = True
2399 type_of_change = 'model'
2400
2401 ML_in = pjoin(self.me_dir, 'Cards', 'MadLoopParams.dat')
2402 ML_out = pjoin(self.me_dir,"SubProcesses",
2403 "MadLoop5_resources", "MadLoopParams.dat")
2404 if (not os.path.isfile(ML_in)) or (not os.path.isfile(ML_out)) or \
2405 (os.path.getmtime(ML_in)-os.path.getmtime(ML_out)) > 0.0:
2406 need_MadLoopFilterUpdate = True
2407 type_of_change = 'MadLoop'
2408
2409
2410 self.check_param_card(pjoin(self.me_dir, 'Cards','param_card.dat'))
2411
2412 if mode in ['param', 'all']:
2413 model = self.find_model_name()
2414 tmp_model = os.path.basename(model)
2415 if tmp_model == 'mssm' or tmp_model.startswith('mssm-'):
2416 if not '--param_card=' in line:
2417 param_card = pjoin(self.me_dir, 'Cards','param_card.dat')
2418 mg5_param = pjoin(self.me_dir, 'Source', 'MODEL', 'MG5_param.dat')
2419 check_param_card.convert_to_mg5card(param_card, mg5_param)
2420 check_param_card.check_valid_param_card(mg5_param)
2421 opt['param_card'] = pjoin(self.me_dir, 'Source', 'MODEL', 'MG5_param.dat')
2422 else:
2423 check_param_card.check_valid_param_card(opt['param_card'])
2424
2425 logger.debug('write compile file for card: %s' % opt['param_card'])
2426 param_card = check_param_card.ParamCard(opt['param_card'])
2427 outfile = pjoin(opt['output_dir'], 'param_card.inc')
2428 ident_card = pjoin(self.me_dir,'Cards','ident_card.dat')
2429 if os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')):
2430 default = pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')
2431 elif os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')):
2432 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
2433 elif not os.path.exists(pjoin(self.me_dir,'bin','internal','ufomodel')):
2434 fsock = open(pjoin(self.me_dir,'Source','param_card.inc'),'w')
2435 fsock.write(' ')
2436 fsock.close()
2437 if mode == 'all':
2438 self.do_treatcards('', 'run', opt)
2439 return
2440 else:
2441 devnull = open(os.devnull,'w')
2442 subprocess.call([sys.executable, 'write_param_card.py'],
2443 cwd=pjoin(self.me_dir,'bin','internal','ufomodel'),
2444 stdout=devnull)
2445 devnull.close()
2446 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
2447
2448 need_mp = self.proc_characteristics['loop_induced']
2449 param_card.write_inc_file(outfile, ident_card, default, need_mp=need_mp)
2450
2451
2452 if mode in ['run', 'all']:
2453 if not hasattr(self, 'run_card'):
2454 run_card = banner_mod.RunCard(opt['run_card'])
2455 else:
2456 run_card = self.run_card
2457 if self.ninitial == 1:
2458 run_card['lpp1'] = 0
2459 run_card['lpp2'] = 0
2460 run_card['ebeam1'] = 0
2461 run_card['ebeam2'] = 0
2462
2463 run_card.write_include_file(pjoin(opt['output_dir'],'run_card.inc'))
2464
2465
2466 if self.proc_characteristics['loop_induced'] and mode in ['loop', 'all']:
2467 self.MadLoopparam = banner_mod.MadLoopParam(pjoin(self.me_dir,
2468 'Cards', 'MadLoopParams.dat'))
2469
2470
2471
2472
2473 if 'WriteOutFilters' in self.MadLoopparam.user_set and \
2474 self.MadLoopparam.get('WriteOutFilters'):
2475 logger.info(
2476 """You chose to have MadLoop writing out filters.
2477 Beware that this can be dangerous for local multicore runs.""")
2478 self.MadLoopparam.set('WriteOutFilters',False, ifnotdefault=False)
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499 self.MadLoopparam.set('HelicityFilterLevel',1, ifnotdefault=False)
2500
2501
2502
2503 self.MadLoopparam.set('CheckCycle',4, ifnotdefault=False)
2504
2505
2506
2507
2508
2509 self.MadLoopparam.set('DoubleCheckHelicityFilter',False,
2510 ifnotdefault=False)
2511
2512
2513
2514 if not hasattr(self, 'run_card'):
2515 run_card = banner_mod.RunCard(opt['run_card'])
2516 else:
2517 run_card = self.run_card
2518 if run_card['nhel'] == 0:
2519 if 'MLReductionLib' in self.MadLoopparam.user_set and \
2520 self.MadLoopparam.get('MLReductionLib').startswith('1'):
2521 logger.warning(
2522 """You chose to set the preferred reduction technique in MadLoop to be OPP (see parameter MLReductionLib).
2523 Beware that this can bring significant slowdown; the optimal choice --when not MC over helicity-- being to first start with TIR reduction.""")
2524
2525 self.MadLoopparam.set('MLReductionLib','2|3|1', ifnotdefault=False)
2526 else:
2527 if 'MLReductionLib' in self.MadLoopparam.user_set and \
2528 not self.MadLoopparam.get('MLReductionLib').startswith('1'):
2529 logger.warning(
2530 """You chose to set the preferred reduction technique in MadLoop to be different than OPP (see parameter MLReductionLib).
2531 Beware that this can bring significant slowdown; the optimal choice --when MC over helicity-- being to first start with OPP reduction.""")
2532 self.MadLoopparam.set('MLReductionLib','1|2|3|4', ifnotdefault=False)
2533
2534
2535
2536
2537
2538 if run_card['nhel'] == 0:
2539 if ('NRotations_DP' in self.MadLoopparam.user_set and \
2540 self.MadLoopparam.get('NRotations_DP')!=0) or \
2541 ('NRotations_QP' in self.MadLoopparam.user_set and \
2542 self.MadLoopparam.get('NRotations_QP')!=0):
2543 logger.warning(
2544 """You chose to also use a lorentz rotation for stability tests (see parameter NRotations_[DP|QP]).
2545 Beware that, for optimization purposes, MadEvent uses manual TIR cache clearing which is not compatible
2546 with the lorentz rotation stability test. The number of these rotations to be used will be reset to
2547 zero by MadLoop. You can avoid this by changing the parameter 'FORCE_ML_HELICITY_SUM' int he matrix<i>.f
2548 files to be .TRUE. so that the sum over helicity configurations is performed within MadLoop (in which case
2549 the helicity of final state particles cannot be speicfied in the LHE file.""")
2550 self.MadLoopparam.set('NRotations_DP',0,ifnotdefault=False)
2551 self.MadLoopparam.set('NRotations_QP',0,ifnotdefault=False)
2552 else:
2553
2554
2555
2556
2557
2558
2559 self.MadLoopparam.set('NRotations_DP',1,ifnotdefault=False)
2560 self.MadLoopparam.set('NRotations_QP',0,ifnotdefault=False)
2561
2562
2563
2564
2565
2566
2567
2568
2569 if self.proc_characteristics['nexternal']<=4:
2570 if ('MLStabThres' in self.MadLoopparam.user_set and \
2571 self.MadLoopparam.get('MLStabThres')>1.0e-7):
2572 logger.warning(
2573 """You chose to increase the default value of the MadLoop parameter 'MLStabThres' above 1.0e-7.
2574 Stability tests can be less reliable on the limited kinematic of processes with less or equal
2575 than four external legs, so this is not recommended (especially not for g g > z z).""")
2576 self.MadLoopparam.set('MLStabThres',1.0e-7,ifnotdefault=False)
2577 else:
2578 self.MadLoopparam.set('MLStabThres',1.0e-4,ifnotdefault=False)
2579
2580
2581 self.MadLoopparam.write(pjoin(self.me_dir,"SubProcesses","MadLoop5_resources",
2582 "MadLoopParams.dat"))
2583
2584 if self.proc_characteristics['loop_induced'] and mode in ['loop', 'all']:
2585
2586
2587 if need_MadLoopFilterUpdate:
2588 logger.debug('Changes to the %s parameters'%type_of_change+\
2589 ' have been detected. Madevent will then now reinitialize'+\
2590 ' MadLoop filters.')
2591 self.exec_cmd('initMadLoop -r -f')
2592
2593
2594
2595
2596
2597 elif not opt['forbid_MadLoopInit'] and \
2598 MadLoopInitializer.need_MadLoopInit(self.me_dir):
2599 self.exec_cmd('initMadLoop -f')
2600
2601
2603 """Advanced commands: launch survey for the current process """
2604
2605
2606 args = self.split_arg(line)
2607
2608 self.check_survey(args)
2609
2610
2611 if os.path.exists(pjoin(self.me_dir,'error')):
2612 os.remove(pjoin(self.me_dir,'error'))
2613
2614 self.configure_directory()
2615
2616 self.random_orig = self.random
2617 logger.info("Using random number seed offset = %s" % self.random)
2618
2619 self.update_random()
2620 self.save_random()
2621 self.update_status('Running Survey', level=None)
2622 if self.cluster_mode:
2623 logger.info('Creating Jobs')
2624
2625 self.total_jobs = 0
2626 subproc = [l.strip() for l in open(pjoin(self.me_dir,
2627 'SubProcesses', 'subproc.mg'))]
2628
2629 P_zero_result = []
2630
2631
2632 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
2633 'MadLoop5_resources')) and cluster.need_transfer(self.options):
2634 tf=tarfile.open(pjoin(self.me_dir, 'SubProcesses',
2635 'MadLoop5_resources.tar.gz'), 'w:gz', dereference=True)
2636 tf.add(pjoin(self.me_dir,'SubProcesses','MadLoop5_resources'),
2637 arcname='MadLoop5_resources')
2638 tf.close()
2639
2640 logger.info('Working on SubProcesses')
2641 ajobcreator = gen_ximprove.gensym(self)
2642
2643
2644 if float(self.run_card['mmjj']) > 0.01 * (float(self.run_card['ebeam1'])+float(self.run_card['ebeam2'])):
2645 self.pass_in_difficult_integration_mode()
2646
2647 jobs, P_zero_result = ajobcreator.launch()
2648
2649
2650 if P_zero_result:
2651 if len(P_zero_result) == len(subproc):
2652 Pdir = pjoin(self.me_dir, 'SubProcesses',subproc[0].strip())
2653 raise ZeroResult, '%s' % \
2654 open(pjoin(Pdir,'ajob.no_ps.log')).read()
2655 else:
2656 logger.warning(''' %s SubProcesses doesn\'t have available phase-space.
2657 Please check mass spectrum.''' % ','.join(P_zero_result))
2658
2659
2660 self.monitor(run_type='All jobs submitted for survey', html=True)
2661 if not self.history or 'survey' in self.history[-1] or self.ninitial ==1 or \
2662 self.run_card['gridpack']:
2663
2664 cross, error = sum_html.make_all_html_results(self)
2665 self.results.add_detail('cross', cross)
2666 self.results.add_detail('error', error)
2667 self.exec_cmd("print_results %s" % self.run_name,
2668 errorhandling=False, printcmd=False, precmd=False, postcmd=False)
2669
2670 self.results.add_detail('run_statistics', dict(ajobcreator.run_statistics))
2671 self.update_status('End survey', 'parton', makehtml=False)
2672
2673
2675 """be more secure for the integration to not miss it due to strong cut"""
2676
2677
2678 if self.opts['points'] == self._survey_options['points'][1]:
2679 self.opts['points'] = 2 * self._survey_options['points'][1]
2680 if self.opts['iterations'] == self._survey_options['iterations'][1]:
2681 self.opts['iterations'] = 1 + self._survey_options['iterations'][1]
2682 if self.opts['accuracy'] == self._survey_options['accuracy'][1]:
2683 self.opts['accuracy'] = self._survey_options['accuracy'][1]/2
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697 for name in ['../bin/internal/gen_ximprove', 'all',
2698 '../bin/internal/combine_events']:
2699 self.compile(arg=[name], cwd=os.path.join(self.me_dir, 'Source'))
2700
2701
2702
2704 """Advanced commands: launch survey for the current process """
2705 devnull = open(os.devnull, 'w')
2706 self.nb_refine += 1
2707 args = self.split_arg(line)
2708
2709 self.check_refine(args)
2710
2711 refine_opt = {'err_goal': args[0], 'split_channels': True}
2712 precision = args[0]
2713 if len(args) == 2:
2714 refine_opt['max_process']= args[1]
2715
2716
2717
2718 self.configure_directory()
2719
2720
2721 self.update_random()
2722 self.save_random()
2723
2724 if self.cluster_mode:
2725 logger.info('Creating Jobs')
2726 self.update_status('Refine results to %s' % precision, level=None)
2727
2728 self.total_jobs = 0
2729 subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses',
2730 'subproc.mg'))]
2731
2732
2733 for nb_proc,subdir in enumerate(subproc):
2734 subdir = subdir.strip()
2735 Pdir = pjoin(self.me_dir, 'SubProcesses', subdir)
2736 for match in glob.glob(pjoin(Pdir, '*ajob*')):
2737 if os.path.basename(match)[:4] in ['ajob', 'wait', 'run.', 'done']:
2738 os.remove(match)
2739
2740 x_improve = gen_ximprove.gen_ximprove(self, refine_opt)
2741
2742 survey_statistics = dict(self.results.get_detail('run_statistics'))
2743
2744 if __debug__ and survey_statistics:
2745 globalstat = sum_html.RunStatistics()
2746 logger.debug(" === Survey statistics summary ===")
2747 for key, value in survey_statistics.items():
2748 globalstat.aggregate_statistics(value)
2749 level = 5
2750 if value.has_warning():
2751 level = 10
2752 logger.log(level,
2753 value.nice_output(str('/'.join([key[0],'G%s'%key[1]]))).
2754 replace(' statistics',''))
2755 logger.debug(globalstat.nice_output('combined', no_warning=True))
2756
2757 if survey_statistics:
2758 x_improve.run_statistics = survey_statistics
2759
2760 x_improve.launch()
2761 if not self.history or 'refine' not in self.history[-1]:
2762 cross, error = x_improve.update_html()
2763 if cross == 0:
2764 return
2765 logger.info("Current estimate of cross-section: %s +- %s" % (cross, error))
2766
2767
2768 if isinstance(x_improve, gen_ximprove.gen_ximprove_v4):
2769
2770
2771 for nb_proc,subdir in enumerate(subproc):
2772 subdir = subdir.strip()
2773 Pdir = pjoin(self.me_dir, 'SubProcesses',subdir)
2774 bindir = pjoin(os.path.relpath(self.dirbin, Pdir))
2775
2776 logger.info(' %s ' % subdir)
2777
2778 if os.path.exists(pjoin(Pdir, 'ajob1')):
2779 self.compile(['madevent'], cwd=Pdir)
2780
2781 alljobs = glob.glob(pjoin(Pdir,'ajob*'))
2782
2783
2784 Gre = re.compile("\s*j=(G[\d\.\w]+)")
2785 for job in alljobs:
2786 Gdirs = Gre.findall(open(job).read())
2787 for Gdir in Gdirs:
2788 if os.path.exists(pjoin(Pdir, Gdir, 'results.dat')):
2789 os.remove(pjoin(Pdir, Gdir,'results.dat'))
2790
2791 nb_tot = len(alljobs)
2792 self.total_jobs += nb_tot
2793 for i, job in enumerate(alljobs):
2794 job = os.path.basename(job)
2795 self.launch_job('%s' % job, cwd=Pdir, remaining=(nb_tot-i-1),
2796 run_type='Refine number %s on %s (%s/%s)' %
2797 (self.nb_refine, subdir, nb_proc+1, len(subproc)))
2798
2799 self.monitor(run_type='All job submitted for refine number %s' % self.nb_refine,
2800 html=True)
2801
2802 self.update_status("Combining runs", level='parton')
2803 try:
2804 os.remove(pjoin(Pdir, 'combine_runs.log'))
2805 except Exception:
2806 pass
2807
2808 if isinstance(x_improve, gen_ximprove.gen_ximprove_v4):
2809
2810
2811 combine_runs.CombineRuns(self.me_dir)
2812 self.refine_mode = "old"
2813 else:
2814 self.refine_mode = "new"
2815
2816 cross, error = sum_html.make_all_html_results(self)
2817 self.results.add_detail('cross', cross)
2818 self.results.add_detail('error', error)
2819
2820 self.results.add_detail('run_statistics',
2821 dict(self.results.get_detail('run_statistics')))
2822
2823 self.update_status('finish refine', 'parton', makehtml=False)
2824 devnull.close()
2825
2826
2828 """Not in help: Combine a given iteration combine_iteration Pdir Gdir S|R step
2829 S is for survey
2830 R is for refine
2831 step is the iteration number (not very critical)"""
2832
2833 self.set_run_name("tmp")
2834 self.configure_directory(html_opening=False)
2835 Pdir, Gdir, mode, step = self.split_arg(line)
2836 if Gdir.startswith("G"):
2837 Gdir = Gdir[1:]
2838 if "SubProcesses" not in Pdir:
2839 Pdir = pjoin(self.me_dir, "SubProcesses", Pdir)
2840 if mode == "S":
2841 self.opts = dict([(key,value[1]) for (key,value) in \
2842 self._survey_options.items()])
2843 gensym = gen_ximprove.gensym(self)
2844 gensym.combine_iteration(Pdir, Gdir, int(step))
2845 elif mode == "R":
2846 refine = gen_ximprove.gen_ximprove_share(self)
2847 refine.combine_iteration(Pdir, Gdir, int(step))
2848
2849
2850
2851
2852
2854 """Advanced commands: Launch combine events"""
2855
2856 args = self.split_arg(line)
2857
2858 self.check_combine_events(args)
2859
2860 self.update_status('Combining Events', level='parton')
2861
2862
2863 if not hasattr(self, "refine_mode") or self.refine_mode == "old":
2864 try:
2865 os.remove(pjoin(self.me_dir,'SubProcesses', 'combine.log'))
2866 except Exception:
2867 pass
2868
2869 tmpcluster = cluster.MultiCore(nb_core=1)
2870 tmpcluster.launch_and_wait('../bin/internal/run_combine',
2871 args=[self.run_name],
2872 cwd=pjoin(self.me_dir,'SubProcesses'),
2873 stdout=pjoin(self.me_dir,'SubProcesses', 'combine.log'),
2874 required_output=[pjoin(self.me_dir,'SubProcesses', 'combine.log')])
2875
2876
2877
2878
2879
2880
2881 output = misc.mult_try_open(pjoin(self.me_dir,'SubProcesses','combine.log')).read()
2882
2883 pat = re.compile(r'''\s*Unweighting\s*selected\s*(\d+)\s*events''')
2884 try:
2885 nb_event = pat.search(output).groups()[0]
2886 except AttributeError:
2887 time.sleep(10)
2888 output = misc.mult_try_open(pjoin(self.me_dir,'SubProcesses','combine.log')).read()
2889 try:
2890 nb_event = pat.search(output).groups()[0]
2891 except AttributeError:
2892 logger.warning('Fail to read the number of unweighted events in the combine.log file')
2893 nb_event = 0
2894
2895 self.results.add_detail('nb_event', nb_event)
2896
2897
2898
2899 tag = self.run_card['run_tag']
2900
2901
2902 if not self.banner:
2903 self.banner = banner_mod.recover_banner(self.results, 'parton')
2904 self.banner.load_basic(self.me_dir)
2905
2906 self.banner.add_generation_info(self.results.current['cross'], nb_event)
2907 if not hasattr(self, 'random_orig'): self.random_orig = 0
2908 self.banner.change_seed(self.random_orig)
2909 if not os.path.exists(pjoin(self.me_dir, 'Events', self.run_name)):
2910 os.mkdir(pjoin(self.me_dir, 'Events', self.run_name))
2911 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name,
2912 '%s_%s_banner.txt' % (self.run_name, tag)))
2913
2914
2915 self.banner.add_to_file(pjoin(self.me_dir,'Events', 'events.lhe'),
2916 out=pjoin(self.me_dir,'Events', self.run_name, 'events.lhe'))
2917 self.banner.add_to_file(pjoin(self.me_dir,'Events', 'unweighted_events.lhe'),
2918 out=pjoin(self.me_dir,'Events', self.run_name, 'unweighted_events.lhe'))
2919
2920
2921 elif self.refine_mode == "new":
2922
2923 tag = self.run_card['run_tag']
2924
2925 if not self.banner:
2926 self.banner = banner_mod.recover_banner(self.results, 'parton')
2927 self.banner.load_basic(self.me_dir)
2928
2929 self.banner.add_generation_info(self.results.current['cross'], self.run_card['nevents'])
2930 if not hasattr(self, 'random_orig'): self.random_orig = 0
2931 self.banner.change_seed(self.random_orig)
2932 if not os.path.exists(pjoin(self.me_dir, 'Events', self.run_name)):
2933 os.mkdir(pjoin(self.me_dir, 'Events', self.run_name))
2934 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name,
2935 '%s_%s_banner.txt' % (self.run_name, tag)))
2936
2937
2938 AllEvent = lhe_parser.MultiEventFile()
2939 AllEvent.banner = self.banner
2940
2941 for Gdir,mfactor in self.get_Gdir():
2942 if os.path.exists(pjoin(Gdir, 'events.lhe')):
2943 result = sum_html.OneResult('')
2944 result.read_results(pjoin(Gdir, 'results.dat'))
2945 AllEvent.add(pjoin(Gdir, 'events.lhe'),
2946 result.get('xsec'),
2947 result.get('xerru'),
2948 result.get('axsec')
2949 )
2950
2951 get_wgt = lambda event: event.wgt
2952 nb_event = AllEvent.unweight(pjoin(self.me_dir, "Events", self.run_name, "unweighted_events.lhe.gz"),
2953 get_wgt, trunc_error=1e-2, event_target=self.run_card['nevents'],
2954 log_level=logging.DEBUG)
2955
2956 self.results.add_detail('nb_event', nb_event)
2957
2958 eradir = self.options['exrootanalysis_path']
2959 madir = self.options['madanalysis_path']
2960 td = self.options['td_path']
2961 if eradir and misc.is_executable(pjoin(eradir,'ExRootLHEFConverter')) and\
2962 os.path.exists(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe')):
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.create_root_file(output='%s/unweighted_events.root' % \
2966 self.run_name)
2967
2968
2970 """Advanced commands: Launch store events"""
2971
2972 args = self.split_arg(line)
2973
2974 self.check_combine_events(args)
2975 self.update_status('Storing parton level results', level='parton')
2976
2977 run = self.run_name
2978 tag = self.run_card['run_tag']
2979 devnull = open(os.devnull, 'w')
2980
2981 if not os.path.exists(pjoin(self.me_dir, 'Events', run)):
2982 os.mkdir(pjoin(self.me_dir, 'Events', run))
2983 if not os.path.exists(pjoin(self.me_dir, 'HTML', run)):
2984 os.mkdir(pjoin(self.me_dir, 'HTML', run))
2985
2986
2987 input = pjoin(self.me_dir, 'SubProcesses', 'results.dat')
2988 output = pjoin(self.me_dir, 'SubProcesses', '%s_results.dat' % run)
2989 files.cp(input, output)
2990
2991
2992
2993
2994 if self.results.current['nb_event'] == 0:
2995 logger.warning("No event detected. No cleaning performed! This should allow to run:\n" +
2996 " cd Subprocesses; ../bin/internal/combine_events\n"+
2997 " to have your events if those one are missing.")
2998 else:
2999 for P_path in SubProcesses.get_subP(self.me_dir):
3000 G_dir = [G for G in os.listdir(P_path) if G.startswith('G') and
3001 os.path.isdir(pjoin(P_path,G))]
3002 for G in G_dir:
3003 G_path = pjoin(P_path,G)
3004 try:
3005
3006 if os.path.exists(pjoin(G_path, 'events.lhe')):
3007 os.remove(pjoin(G_path, 'events.lhe'))
3008 except Exception:
3009 continue
3010 try:
3011
3012 if os.path.exists(pjoin(G_path, 'results.dat')):
3013 input = pjoin(G_path, 'results.dat')
3014 output = pjoin(G_path, '%s_results.dat' % run)
3015 files.cp(input, output)
3016 except Exception:
3017 continue
3018
3019 try:
3020 if os.path.exists(pjoin(G_path, 'log.txt')):
3021 input = pjoin(G_path, 'log.txt')
3022 output = pjoin(G_path, '%s_log.txt' % run)
3023 files.mv(input, output)
3024 except Exception:
3025 continue
3026 try:
3027
3028 for name in ['ftn26']:
3029 if os.path.exists(pjoin(G_path, name)):
3030 if os.path.exists(pjoin(G_path, '%s_%s.gz'%(run,name))):
3031 os.remove(pjoin(G_path, '%s_%s.gz'%(run,name)))
3032 input = pjoin(G_path, name)
3033 output = pjoin(G_path, '%s_%s' % (run,name))
3034 files.mv(input, output)
3035 misc.gzip(pjoin(G_path, output), error=None)
3036 except Exception:
3037 continue
3038
3039 if os.path.exists(pjoin(G_path, 'ftn25')):
3040 os.remove(pjoin(G_path, 'ftn25'))
3041
3042
3043 misc.call(['%s/gen_cardhtml-pl' % self.dirbin],
3044 cwd=pjoin(self.me_dir))
3045
3046
3047
3048 E_path = pjoin(self.me_dir, 'Events')
3049 O_path = pjoin(self.me_dir, 'Events', run)
3050
3051
3052 for name in ['events.lhe', 'unweighted_events.lhe']:
3053 finput = pjoin(E_path, name)
3054 foutput = pjoin(O_path, name)
3055 if os.path.exists(finput):
3056 logger.debug("File %s exists BAAAAD. Not move anymore!" % pjoin(E_path, name))
3057 if os.path.exists(foutput):
3058 misc.gzip(foutput, stdout="%s.gz" % foutput, error=False)
3059
3060
3061
3062
3063
3064
3065 self.update_status('End Parton', level='parton', makehtml=False)
3066 devnull.close()
3067
3068
3069
3071 """Advanced commands: Create gridpack from present run"""
3072
3073 self.update_status('Creating gridpack', level='parton')
3074
3075 misc.compile(['../bin/internal/gen_ximprove'], cwd=pjoin(self.me_dir, "Source"))
3076 args = self.split_arg(line)
3077 self.check_combine_events(args)
3078 if not self.run_tag: self.run_tag = 'tag_1'
3079 os.system("sed -i.bak \"s/ *.false.*=.*GridRun/ .true. = GridRun/g\" %s/Cards/grid_card.dat" \
3080 % self.me_dir)
3081 misc.call(['./bin/internal/restore_data', self.run_name],
3082 cwd=self.me_dir)
3083 misc.call(['./bin/internal/store4grid',
3084 self.run_name, self.run_tag],
3085 cwd=self.me_dir)
3086 misc.call(['./bin/internal/clean'], cwd=self.me_dir)
3087 misc.call(['./bin/internal/make_gridpack'], cwd=self.me_dir)
3088 files.mv(pjoin(self.me_dir, 'gridpack.tar.gz'),
3089 pjoin(self.me_dir, '%s_gridpack.tar.gz' % self.run_name))
3090 os.system("sed -i.bak \"s/\s*.true.*=.*GridRun/ .false. = GridRun/g\" %s/Cards/grid_card.dat" \
3091 % self.me_dir)
3092 self.update_status('gridpack created', level='gridpack')
3093
3094
3096 """launch pythia"""
3097
3098
3099 args = self.split_arg(line)
3100 if '--no_default' in args:
3101 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pythia_card.dat')):
3102 return
3103 no_default = True
3104 args.remove('--no_default')
3105 else:
3106 no_default = False
3107
3108 if not self.run_name:
3109 self.check_pythia(args)
3110 self.configure_directory(html_opening =False)
3111 else:
3112
3113 self.configure_directory(html_opening =False)
3114 self.check_pythia(args)
3115
3116
3117
3118 if not no_default:
3119 self.ask_pythia_run_configuration(args[-1])
3120
3121 if self.options['automatic_html_opening']:
3122 misc.open_file(os.path.join(self.me_dir, 'crossx.html'))
3123 self.options['automatic_html_opening'] = False
3124
3125
3126 if not self.banner or len(self.banner) <=1:
3127 self.banner = banner_mod.recover_banner(self.results, 'pythia')
3128
3129
3130
3131 pythia_src = pjoin(self.options['pythia-pgs_path'],'src')
3132
3133 self.update_status('Running Pythia', 'pythia')
3134 try:
3135 os.remove(pjoin(self.me_dir,'Events','pythia.done'))
3136 except Exception:
3137 pass
3138
3139
3140 tag = self.run_tag
3141 pythia_log = pjoin(self.me_dir, 'Events', self.run_name , '%s_pythia.log' % tag)
3142 self.cluster.launch_and_wait('../bin/internal/run_pythia',
3143 argument= [pythia_src], stdout= pythia_log,
3144 stderr=subprocess.STDOUT,
3145 cwd=pjoin(self.me_dir,'Events'))
3146
3147 os.remove(pjoin(self.me_dir, "Events", "unweighted_events.lhe"))
3148
3149
3150
3151 if not os.path.exists(pjoin(self.me_dir,'Events','pythia.done')):
3152 logger.warning('Fail to produce pythia output. More info in \n %s' % pythia_log)
3153 return
3154 else:
3155 os.remove(pjoin(self.me_dir,'Events','pythia.done'))
3156
3157 self.to_store.append('pythia')
3158
3159
3160 if int(self.run_card['ickkw']):
3161
3162 pythia_log = misc.BackRead(pjoin(self.me_dir,'Events', self.run_name,
3163 '%s_pythia.log' % tag))
3164 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")
3165 for line in pythia_log:
3166 info = pythiare.search(line)
3167 if not info:
3168 continue
3169 try:
3170
3171 sigma_m = float(info.group('xsec').replace('D','E')) *1e9
3172 Nacc = int(info.group('generated'))
3173 Ntry = int(info.group('tried'))
3174 except ValueError:
3175
3176 self.results.add_detail('cross_pythia', 0)
3177 self.results.add_detail('nb_event_pythia', 0)
3178 self.results.add_detail('error_pythia', 0)
3179 else:
3180 self.results.add_detail('cross_pythia', sigma_m)
3181 self.results.add_detail('nb_event_pythia', Nacc)
3182
3183 error = self.results[self.run_name].return_tag(self.run_tag)['error']
3184 error_m = math.sqrt((error * Nacc/Ntry)**2 + sigma_m**2 *(1-Nacc/Ntry)/Nacc)
3185
3186 self.results.add_detail('error_pythia', error_m)
3187 break
3188
3189 pythia_log.close()
3190
3191 pydir = pjoin(self.options['pythia-pgs_path'], 'src')
3192 eradir = self.options['exrootanalysis_path']
3193 madir = self.options['madanalysis_path']
3194 td = self.options['td_path']
3195
3196
3197
3198
3199
3200 self.banner.add(pjoin(self.me_dir, 'Cards','pythia_card.dat'))
3201 if int(self.run_card['ickkw']):
3202
3203 if 'MGGenerationInfo' in self.banner:
3204 self.banner['MGGenerationInfo'] += '# Matched Integrated weight (pb) : %s\n' % self.results.current['cross_pythia']
3205 else:
3206 self.banner['MGGenerationInfo'] = '# Matched Integrated weight (pb) : %s\n' % self.results.current['cross_pythia']
3207 banner_path = pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, tag))
3208 self.banner.write(banner_path)
3209
3210
3211 self.run_hep2lhe(banner_path)
3212 if int(self.run_card['ickkw']):
3213 misc.gzip(pjoin(self.me_dir,'Events','beforeveto.tree'),
3214 stdout=pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_beforeveto.tree.gz'))
3215 if self.run_card['use_syst'] in self.true:
3216
3217 try:
3218 self.run_syscalc('Pythia')
3219 except SysCalcError, error:
3220 logger.error(str(error))
3221 else:
3222
3223 misc.gzip(pjoin(self.me_dir,'Events', 'syst.dat'),
3224 stdout=pjoin(self.me_dir,'Events',self.run_name, tag + '_pythia_syst.dat.gz'))
3225
3226
3227 if os.path.exists(pjoin(self.me_dir, 'Events', 'syscalc.dat')):
3228 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
3229 '%s_syscalc.dat' % self.run_tag)
3230 misc.gzip(pjoin(self.me_dir, 'Events','syscalc.dat'),
3231 stdout = "%s.gz" % filename)
3232
3233
3234 self.create_plot('Pythia')
3235
3236 if os.path.exists(pjoin(self.me_dir,'Events','pythia_events.lhe')):
3237 misc.gzip(pjoin(self.me_dir,'Events','pythia_events.lhe'),
3238 stdout=pjoin(self.me_dir,'Events', self.run_name,'%s_pythia_events.lhe.gz' % tag))
3239
3240 self.update_status('finish', level='pythia', makehtml=False)
3241 self.exec_cmd('pgs --no_default', postcmd=False, printcmd=False)
3242 if self.options['delphes_path']:
3243 self.exec_cmd('delphes --no_default', postcmd=False, printcmd=False)
3244 self.print_results_in_shell(self.results.current)
3245
3246
3247
3249 """Remove one/all run or only part of it"""
3250
3251 args = self.split_arg(line)
3252 run, tag, mode = self.check_remove(args)
3253 if 'banner' in mode:
3254 mode.append('all')
3255
3256
3257 if run == 'all':
3258
3259 if os.path.exists(pjoin(self.me_dir, 'Events', 'all')):
3260 logger.warning('A run with name all exists. So we will not supress all processes.')
3261 else:
3262 for match in glob.glob(pjoin(self.me_dir, 'Events','*','*_banner.txt')):
3263 run = match.rsplit(os.path.sep,2)[1]
3264 if self.force:
3265 args.append('-f')
3266 try:
3267 self.exec_cmd('remove %s %s' % (run, ' '.join(args[1:]) ) )
3268 except self.InvalidCmd, error:
3269 logger.info(error)
3270 pass
3271 return
3272
3273
3274 if not os.path.exists(pjoin(self.me_dir, 'Events', run)):
3275 raise self.InvalidCmd('No run \'%s\' detected' % run)
3276
3277 try:
3278 self.resuls.def_current(run)
3279 self.update_status(' Cleaning %s' % run, level=None)
3280 except Exception:
3281 misc.sprint('fail to update results or html status')
3282 pass
3283
3284
3285
3286
3287 to_delete = glob.glob(pjoin(self.me_dir, 'Events', run, '*'))
3288 to_delete += glob.glob(pjoin(self.me_dir, 'HTML', run, '*'))
3289
3290 to_delete = [os.path.basename(f) for f in to_delete if 'banner' not in f]
3291 if tag:
3292 to_delete = [f for f in to_delete if tag in f]
3293 if 'parton' in mode or 'all' in mode:
3294 try:
3295 if self.results[run][0]['tag'] != tag:
3296 raise Exception, 'dummy'
3297 except Exception:
3298 pass
3299 else:
3300 nb_rm = len(to_delete)
3301 if os.path.exists(pjoin(self.me_dir, 'Events', run, 'events.lhe.gz')):
3302 to_delete.append('events.lhe.gz')
3303 if os.path.exists(pjoin(self.me_dir, 'Events', run, 'unweighted_events.lhe.gz')):
3304 to_delete.append('unweighted_events.lhe.gz')
3305 if os.path.exists(pjoin(self.me_dir, 'HTML', run,'plots_parton.html')):
3306 to_delete.append(pjoin(self.me_dir, 'HTML', run,'plots_parton.html'))
3307 if nb_rm != len(to_delete):
3308 logger.warning('Be carefull that partonic information are on the point to be removed.')
3309 if 'all' in mode:
3310 pass
3311 else:
3312 if 'pythia' not in mode:
3313 to_delete = [f for f in to_delete if 'pythia' not in f]
3314 if 'pgs' not in mode:
3315 to_delete = [f for f in to_delete if 'pgs' not in f]
3316 if 'delphes' not in mode:
3317 to_delete = [f for f in to_delete if 'delphes' not in f]
3318 if 'parton' not in mode:
3319 to_delete = [f for f in to_delete if 'delphes' in f
3320 or 'pgs' in f
3321 or 'pythia' in f]
3322 if not self.force and len(to_delete):
3323 question = 'Do you want to delete the following files?\n %s' % \
3324 '\n '.join(to_delete)
3325 ans = self.ask(question, 'y', choices=['y','n'])
3326 else:
3327 ans = 'y'
3328
3329 if ans == 'y':
3330 for file2rm in to_delete:
3331 if os.path.exists(pjoin(self.me_dir, 'Events', run, file2rm)):
3332 try:
3333 os.remove(pjoin(self.me_dir, 'Events', run, file2rm))
3334 except Exception:
3335 shutil.rmtree(pjoin(self.me_dir, 'Events', run, file2rm))
3336 else:
3337 try:
3338 os.remove(pjoin(self.me_dir, 'HTML', run, file2rm))
3339 except Exception:
3340 shutil.rmtree(pjoin(self.me_dir, 'HTML', run, file2rm))
3341
3342
3343
3344
3345 if 'all' in mode or 'channel' in mode:
3346 try:
3347 if tag and self.results[run][0]['tag'] != tag:
3348 raise Exception, 'dummy'
3349 except Exception:
3350 pass
3351 else:
3352 to_delete = glob.glob(pjoin(self.me_dir, 'SubProcesses', '%s*' % run))
3353 to_delete += glob.glob(pjoin(self.me_dir, 'SubProcesses', '*','%s*' % run))
3354 to_delete += glob.glob(pjoin(self.me_dir, 'SubProcesses', '*','*','%s*' % run))
3355
3356 if self.force or len(to_delete) == 0:
3357 ans = 'y'
3358 else:
3359 question = 'Do you want to delete the following files?\n %s' % \
3360 '\n '.join(to_delete)
3361 ans = self.ask(question, 'y', choices=['y','n'])
3362
3363 if ans == 'y':
3364 for file2rm in to_delete:
3365 os.remove(file2rm)
3366
3367 if 'banner' in mode:
3368 to_delete = glob.glob(pjoin(self.me_dir, 'Events', run, '*'))
3369 if tag:
3370
3371 try:
3372 os.remove(pjoin(self.me_dir, 'Events',run,'%s_%s_banner.txt' % (run,tag)))
3373 except Exception:
3374 logger.warning('fail to remove the banner')
3375
3376 if run in self.results:
3377 self.results.delete_run(run, tag)
3378 return
3379 elif any(['banner' not in os.path.basename(p) for p in to_delete]):
3380 if to_delete:
3381 raise MadGraph5Error, '''Some output still exists for this run.
3382 Please remove those output first. Do for example:
3383 remove %s all banner
3384 ''' % run
3385 else:
3386 shutil.rmtree(pjoin(self.me_dir, 'Events',run))
3387 if run in self.results:
3388 self.results.delete_run(run)
3389 return
3390 else:
3391 logger.info('''The banner is not removed. In order to remove it run:
3392 remove %s all banner %s''' % (run, tag and '--tag=%s ' % tag or ''))
3393
3394
3395 self.results.clean(mode, run, tag)
3396 self.update_status('', level='all')
3397
3398
3399
3400
3402 """Create the plot for a given run"""
3403
3404
3405 self.store_result()
3406 args = self.split_arg(line)
3407
3408 self.check_plot(args)
3409 logger.info('plot for run %s' % self.run_name)
3410 if not self.force:
3411 self.ask_edit_cards([], args, plot=True)
3412
3413 if any([arg in ['all','parton'] for arg in args]):
3414 filename = pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe')
3415 if os.path.exists(filename+'.gz'):
3416 misc.gunzip('%s.gz' % filename, keep=True)
3417 if os.path.exists(filename):
3418 files.ln(filename, pjoin(self.me_dir, 'Events'))
3419 self.create_plot('parton')
3420 if not os.path.exists(filename+'.gz'):
3421 misc.gzip(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'),
3422 stdout= "%s.gz" % filename)
3423 else:
3424 try:
3425 os.remove(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'))
3426 os.remove(filename)
3427 except Exception:
3428 pass
3429 else:
3430 logger.info('No valid files for partonic plot')
3431
3432 if any([arg in ['all','pythia'] for arg in args]):
3433 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
3434 '%s_pythia_events.lhe' % self.run_tag)
3435 if os.path.exists(filename+'.gz'):
3436 misc.gunzip("%s.gz" % filename)
3437 if os.path.exists(filename):
3438 shutil.move(filename, pjoin(self.me_dir, 'Events','pythia_events.lhe'))
3439 self.create_plot('Pythia')
3440 misc.gzip(pjoin(self.me_dir, 'Events','pythia_events.lhe'),
3441 stdout= "%s.gz" % filename)
3442 else:
3443 logger.info('No valid files for pythia plot')
3444
3445
3446 if any([arg in ['all','pgs'] for arg in args]):
3447 filename = pjoin(self.me_dir, 'Events', self.run_name,
3448 '%s_pgs_events.lhco' % self.run_tag)
3449 if os.path.exists(filename+'.gz'):
3450 misc.gunzip("%s.gz" % filename)
3451 if os.path.exists(filename):
3452 self.create_plot('PGS')
3453 misc.gzip(filename)
3454 else:
3455 logger.info('No valid files for pgs plot')
3456
3457 if any([arg in ['all','delphes'] for arg in args]):
3458 filename = pjoin(self.me_dir, 'Events', self.run_name,
3459 '%s_delphes_events.lhco' % self.run_tag)
3460 if os.path.exists(filename+'.gz'):
3461 misc.gunzip("%s.gz" % filename)
3462 if os.path.exists(filename):
3463 self.create_plot('Delphes')
3464 misc.gzip(filename)
3465 else:
3466 logger.info('No valid files for delphes plot')
3467
3468
3470 """Evaluate systematics variation weights for a given run"""
3471
3472
3473 self.store_result()
3474 args = self.split_arg(line)
3475
3476 self.check_syscalc(args)
3477 if self.ninitial == 1:
3478 logger.error('SysCalc can\'t be run for decay processes')
3479 return
3480
3481 logger.info('Calculating systematics for run %s' % self.run_name)
3482
3483 self.ask_edit_cards(['run_card'], args)
3484
3485 if any([arg in ['all','parton'] for arg in args]):
3486 filename = pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe')
3487 if os.path.exists(filename+'.gz'):
3488 misc.gunzip("%s.gz" % filename)
3489 if os.path.exists(filename):
3490 shutil.move(filename, pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'))
3491 self.run_syscalc('parton')
3492 misc.gzip(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'),
3493 stdout="%s.gz" % filename)
3494 else:
3495 logger.info('No valid files for parton level systematics run.')
3496
3497 if any([arg in ['all','pythia'] for arg in args]):
3498 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
3499 '%s_pythia_syst.dat' % self.run_tag)
3500 if os.path.exists(filename+'.gz'):
3501 misc.gunzip("%s.gz" % filename)
3502 if os.path.exists(filename):
3503 shutil.move(filename, pjoin(self.me_dir, 'Events','syst.dat'))
3504 try:
3505 self.run_syscalc('Pythia')
3506 except SysCalcError, error:
3507 logger.warning(str(error))
3508 return
3509 misc.gzip(pjoin(self.me_dir, 'Events','syst.dat'), "%s.gz" % filename)
3510 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
3511 '%s_syscalc.dat' % self.run_tag)
3512 misc.gzip(pjoin(self.me_dir, 'Events','syscalc.dat'),
3513 stdout=filename)
3514 else:
3515 logger.info('No valid files for pythia level')
3516
3517
3519 """ tar the pythia results. This is done when we are quite sure that
3520 the pythia output will not be use anymore """
3521
3522 if not self.run_name:
3523 return
3524
3525 self.results.save()
3526
3527
3528 if not self.to_store:
3529 return
3530
3531 tag = self.run_card['run_tag']
3532 self.update_status('storring files of previous run', level=None,\
3533 error=True)
3534 if 'event' in self.to_store:
3535 if not os.path.exists(pjoin(self.me_dir, 'Events',self.run_name, 'unweighted_events.lhe.gz')):
3536 misc.gzip(pjoin(self.me_dir,'Events',self.run_name,"unweighted_events.lhe"))
3537
3538 if 'pythia' in self.to_store:
3539 self.update_status('Storing Pythia files of previous run', level='pythia', error=True)
3540
3541 p = pjoin(self.me_dir,'Events')
3542 n = self.run_name
3543 t = tag
3544 misc.gzip(pjoin(p,'pythia_events.hep'),
3545 stdout=pjoin(p,'%s/%s_pythia_events.hep' % (n,t)))
3546
3547 self.to_store.remove('pythia')
3548 self.update_status('Done', level='pythia',makehtml=False,error=True)
3549
3550 self.to_store = []
3551
3552 - def launch_job(self,exe, cwd=None, stdout=None, argument = [], remaining=0,
3553 run_type='', mode=None, **opt):
3554 """ """
3555 argument = [str(arg) for arg in argument]
3556 if mode is None:
3557 mode = self.cluster_mode
3558
3559
3560 if os.path.exists(exe) and not os.access(exe, os.X_OK):
3561 os.system('chmod +x %s ' % exe)
3562 elif (cwd and os.path.exists(pjoin(cwd, exe))) and not \
3563 os.access(pjoin(cwd, exe), os.X_OK):
3564 os.system('chmod +x %s ' % pjoin(cwd, exe))
3565
3566 if mode == 0:
3567 self.update_status((remaining, 1,
3568 self.total_jobs - remaining -1, run_type), level=None, force=False)
3569 start = time.time()
3570
3571 status = misc.call([exe] + argument, cwd=cwd, stdout=stdout, **opt)
3572 logger.info('%s run in %f s' % (exe, time.time() -start))
3573 if status:
3574 raise MadGraph5Error, '%s didn\'t stop properly. Stop all computation' % exe
3575
3576
3577 elif mode in [1,2]:
3578
3579 if 'ajob' in exe:
3580 input_files = ['madevent','input_app.txt','symfact.dat','iproc.dat',
3581 pjoin(self.me_dir, 'SubProcesses','randinit')]
3582 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
3583 'MadLoop5_resources.tar.gz')) and cluster.need_transfer(self.options):
3584 input_files.append(pjoin(self.me_dir,'SubProcesses', 'MadLoop5_resources.tar.gz'))
3585
3586 output_files = []
3587 required_output = []
3588
3589
3590
3591 input_files.append(self.get_pdf_input_filename())
3592
3593
3594 Gre = re.compile("\s*j=(G[\d\.\w]+)")
3595 origre = re.compile("grid_directory=(G[\d\.\w]+)")
3596 try :
3597 fsock = open(exe)
3598 except Exception:
3599 fsock = open(pjoin(cwd,exe))
3600 text = fsock.read()
3601 output_files = Gre.findall(text)
3602 if not output_files:
3603 Ire = re.compile("for i in ([\d\.\s]*) ; do")
3604 data = Ire.findall(text)
3605 data = ' '.join(data).split()
3606 for nb in data:
3607 output_files.append('G%s' % nb)
3608 required_output.append('G%s/results.dat' % nb)
3609 else:
3610 for G in output_files:
3611 if os.path.isdir(pjoin(cwd,G)):
3612 input_files.append(G)
3613 required_output.append('%s/results.dat' % G)
3614
3615 if origre.search(text):
3616 G_grid = origre.search(text).groups()[0]
3617 input_files.append(pjoin(G_grid, 'ftn26'))
3618
3619
3620 self.cluster.submit2(exe, stdout=stdout, cwd=cwd,
3621 input_files=input_files, output_files=output_files,
3622 required_output=required_output)
3623 elif 'survey' in exe:
3624 input_files = ['madevent','input_app.txt','symfact.dat','iproc.dat',
3625 pjoin(self.me_dir, 'SubProcesses','randinit')]
3626 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
3627 'MadLoop5_resources.tar.gz')) and cluster.need_transfer(self.options):
3628 input_files.append(pjoin(self.me_dir,'SubProcesses',
3629 'MadLoop5_resources.tar.gz'))
3630
3631
3632 input_files.append(self.get_pdf_input_filename())
3633
3634
3635 output_files = []
3636 required_output = []
3637
3638
3639 suffix = "_%s" % int(float(argument[0]))
3640 if suffix == '_0':
3641 suffix = ''
3642 output_files = ['G%s%s' % (i, suffix) for i in argument[1:]]
3643 for G in output_files:
3644 required_output.append('%s/results.dat' % G)
3645
3646
3647 for G in output_files:
3648 if '.' in argument[0]:
3649 offset = int(str(argument[0]).split('.')[1])
3650 else:
3651 offset = 0
3652
3653 if offset ==0 or offset == int(float(argument[0])):
3654 if os.path.exists(pjoin(cwd, G, 'input_app.txt')):
3655 os.remove(pjoin(cwd, G, 'input_app.txt'))
3656
3657 if os.path.exists(os.path.realpath(pjoin(cwd, G, 'ftn25'))):
3658 if offset == 0 or offset == int(float(argument[0])):
3659 os.remove(pjoin(cwd, G, 'ftn25'))
3660 continue
3661 else:
3662 input_files.append(pjoin(cwd, G, 'ftn25'))
3663 input_files.remove('input_app.txt')
3664 input_files.append(pjoin(cwd, G, 'input_app.txt'))
3665 elif os.path.lexists(pjoin(cwd, G, 'ftn25')):
3666 try:
3667 os.remove(pjoin(cwd,G,'ftn25'))
3668 except:
3669 pass
3670
3671
3672 self.cluster.cluster_submit(exe, stdout=stdout, cwd=cwd, argument=argument,
3673 input_files=input_files, output_files=output_files,
3674 required_output=required_output, **opt)
3675 elif "refine_splitted.sh" in exe:
3676 input_files = ['madevent','symfact.dat','iproc.dat',
3677 pjoin(self.me_dir, 'SubProcesses','randinit')]
3678
3679 if os.path.exists(pjoin(self.me_dir,'SubProcesses',
3680 'MadLoop5_resources.tar.gz')) and cluster.need_transfer(self.options):
3681 input_files.append(pjoin(self.me_dir,'SubProcesses',
3682 'MadLoop5_resources.tar.gz'))
3683
3684
3685 input_files.append(self.get_pdf_input_filename())
3686
3687
3688 output_files = [argument[0]]
3689 required_output = []
3690 for G in output_files:
3691 required_output.append('%s/results.dat' % G)
3692 input_files.append(pjoin(argument[1], "input_app.txt"))
3693 input_files.append(pjoin(argument[1], "ftn26"))
3694
3695
3696 self.cluster.cluster_submit(exe, stdout=stdout, cwd=cwd, argument=argument,
3697 input_files=input_files, output_files=output_files,
3698 required_output=required_output, **opt)
3699
3700
3701
3702 else:
3703 self.cluster.submit(exe, stdout=stdout, cwd=cwd, **opt)
3704
3705
3706
3708 """Find if Madevent is in Group mode or not"""
3709
3710
3711
3712 file_path = pjoin(self.me_dir, 'Source', 'run_config.inc')
3713 text = open(file_path).read()
3714 if re.search(r'''s*parameter\s+\(ChanPerJob=2\)''', text, re.I+re.M):
3715 return 'group'
3716 else:
3717 return 'v4'
3718
3719
3720 - def monitor(self, run_type='monitor', mode=None, html=False):
3721 """ monitor the progress of running job """
3722
3723
3724 starttime = time.time()
3725 if mode is None:
3726 mode = self.cluster_mode
3727 if mode > 0:
3728 if html:
3729 update_status = lambda idle, run, finish: \
3730 self.update_status((idle, run, finish, run_type), level=None,
3731 force=False, starttime=starttime)
3732 update_first = lambda idle, run, finish: \
3733 self.update_status((idle, run, finish, run_type), level=None,
3734 force=True, starttime=starttime)
3735 else:
3736 update_status = lambda idle, run, finish: None
3737 update_first = None
3738 try:
3739 self.cluster.wait(self.me_dir, update_status, update_first=update_first)
3740 except Exception, error:
3741 logger.info(error)
3742 if not self.force:
3743 ans = self.ask('Cluster Error detected. Do you want to clean the queue? ("c"=continue the run anyway)',
3744 default = 'y', choices=['y','n', 'c'])
3745 else:
3746 ans = 'y'
3747 if ans == 'y':
3748 self.cluster.remove()
3749 elif ans == 'c':
3750 return self.monitor(run_type=run_type, mode=mode, html=html)
3751 raise
3752 except KeyboardInterrupt, error:
3753 self.cluster.remove()
3754 raise
3755
3756
3757
3758
3835
3836
3837
3838
3839
3840 @staticmethod
3842 """check if the directory exists. if so return the path otherwise the
3843 default"""
3844
3845 if os.path.isdir(path):
3846 return path
3847 else:
3848 return default
3849
3850
3852 """get the list of Pdirectory if not yet saved."""
3853
3854 if hasattr(self, "Pdirs"):
3855 if self.me_dir in self.Pdirs[0]:
3856 return self.Pdirs
3857 self.Pdirs = [pjoin(self.me_dir, 'SubProcesses', l.strip())
3858 for l in open(pjoin(self.me_dir,'SubProcesses', 'subproc.mg'))]
3859 return self.Pdirs
3860
3861
3863 """get the list of Gdirectory if not yet saved."""
3864
3865 if hasattr(self, "Gdirs"):
3866 if self.me_dir in self.Gdirs[0]:
3867 return self.Gdirs
3868
3869 Pdirs = self.get_Pdir()
3870 Gdirs = []
3871 for P in Pdirs:
3872 for line in open(pjoin(P, "symfact.dat")):
3873 tag, mfactor = line.split()
3874 Gdirs.append( (pjoin(P, "G%s" % tag), int(mfactor)) )
3875
3876
3877 self.Gdirs = Gdirs
3878 return self.Gdirs
3879
3880
3881 - def set_run_name(self, name, tag=None, level='parton', reload_card=False,
3882 allow_new_tag=True):
3883 """define the run name, the run_tag, the banner and the results."""
3884
3885
3886 upgrade_tag = {'parton': ['parton','pythia','pgs','delphes'],
3887 'pythia': ['pythia','pgs','delphes'],
3888 'pgs': ['pgs'],
3889 'delphes':['delphes'],
3890 'plot':[],
3891 'syscalc':[]}
3892
3893
3894
3895 if name == self.run_name:
3896 if reload_card:
3897 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
3898 self.run_card = banner_mod.RunCard(run_card)
3899
3900
3901 if tag:
3902 self.run_card['run_tag'] = tag
3903 self.run_tag = tag
3904 self.results.add_run(self.run_name, self.run_card)
3905 else:
3906 for tag in upgrade_tag[level]:
3907 if getattr(self.results[self.run_name][-1], tag):
3908 tag = self.get_available_tag()
3909 self.run_card['run_tag'] = tag
3910 self.run_tag = tag
3911 self.results.add_run(self.run_name, self.run_card)
3912 break
3913 return
3914
3915
3916 if self.run_name:
3917 self.store_result()
3918
3919 self.run_name = name
3920
3921 new_tag = False
3922
3923 self.banner = banner_mod.recover_banner(self.results, level, name)
3924 if 'mgruncard' in self.banner:
3925 self.run_card = self.banner.charge_card('run_card')
3926 else:
3927
3928 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
3929 self.run_card = banner_mod.RunCard(run_card)
3930
3931 if tag:
3932 self.run_card['run_tag'] = tag
3933 new_tag = True
3934 elif not self.run_name in self.results and level =='parton':
3935 pass
3936 elif not self.run_name in self.results:
3937
3938 logger.warning('Trying to run data on unknown run.')
3939 self.results.add_run(name, self.run_card)
3940 self.results.update('add run %s' % name, 'all', makehtml=False)
3941 else:
3942 for tag in upgrade_tag[level]:
3943
3944 if getattr(self.results[self.run_name][-1], tag):
3945
3946 tag = self.get_available_tag()
3947 self.run_card['run_tag'] = tag
3948 new_tag = True
3949 break
3950 if not new_tag:
3951
3952 tag = self.results[self.run_name][-1]['tag']
3953 self.run_card['run_tag'] = tag
3954
3955 if allow_new_tag and (name in self.results and not new_tag):
3956 self.results.def_current(self.run_name)
3957 else:
3958 self.results.add_run(self.run_name, self.run_card)
3959
3960 self.run_tag = self.run_card['run_tag']
3961
3962
3963
3964 if level == 'parton':
3965 return
3966 elif level == 'pythia':
3967 return self.results[self.run_name][0]['tag']
3968 else:
3969 for i in range(-1,-len(self.results[self.run_name])-1,-1):
3970 tagRun = self.results[self.run_name][i]
3971 if tagRun.pythia:
3972 return tagRun['tag']
3973
3974
3975
3976
3977
3978
3979
3980
3981
3983 """ return the model name """
3984 if hasattr(self, 'model_name'):
3985 return self.model_name
3986
3987 model = 'sm'
3988 proc = []
3989 for line in open(os.path.join(self.me_dir,'Cards','proc_card_mg5.dat')):
3990 line = line.split('#')[0]
3991
3992 if line.startswith('import') and 'model' in line:
3993 model = line.split()[2]
3994 proc = []
3995 elif line.startswith('generate'):
3996 proc.append(line.split(None,1)[1])
3997 elif line.startswith('add process'):
3998 proc.append(line.split(None,2)[2])
3999
4000 self.model = model
4001 self.process = proc
4002 return model
4003
4004
4005
4007 """Find the number of event in the run_card, and check that this is not
4008 too large"""
4009
4010
4011 nb_event = int(self.run_card['nevents'])
4012 if nb_event > 1000000:
4013 logger.warning("Attempting to generate more than 1M events")
4014 logger.warning("Limiting number to 1M. Use multi_run for larger statistics.")
4015 path = pjoin(self.me_dir, 'Cards', 'run_card.dat')
4016 os.system(r"""perl -p -i.bak -e "s/\d+\s*=\s*nevents/1000000 = nevents/" %s""" \
4017 % path)
4018 self.run_card['nevents'] = 1000000
4019
4020 return
4021
4022
4023
4025 """ change random number"""
4026
4027 self.random += 3
4028 if self.random > 30081*30081:
4029 raise MadGraph5Error,\
4030 'Random seed too large ' + str(self.random) + ' > 30081*30081'
4031
4032
4034 """save random number in appropirate file"""
4035
4036 fsock = open(pjoin(self.me_dir, 'SubProcesses','randinit'),'w')
4037 fsock.writelines('r=%s\n' % self.random)
4038
4039 - def do_quit(self, *args, **opts):
4043
4044
4046 """check for ckkw"""
4047
4048 lpp1 = self.run_card['lpp1']
4049 lpp2 = self.run_card['lpp2']
4050 e1 = self.run_card['ebeam1']
4051 e2 = self.run_card['ebeam2']
4052 pd = self.run_card['pdlabel']
4053 lha = self.run_card['lhaid']
4054 xq = self.run_card['xqcut']
4055 translation = {'e1': e1, 'e2':e2, 'pd':pd,
4056 'lha':lha, 'xq':xq}
4057
4058 if lpp1 or lpp2:
4059
4060 if pd.startswith("'"):
4061 pd = pd[1:]
4062 if pd.endswith("'"):
4063 pd = pd[:-1]
4064
4065 if xq >2 or xq ==2:
4066 xq = 2
4067
4068
4069 if pd == "lhapdf":
4070 issudfile = 'lib/issudgrid-%(e1)s-%(e2)s-%(pd)s-%(lha)s-%(xq)s.dat.gz'
4071 else:
4072 issudfile = 'lib/issudgrid-%(e1)s-%(e2)s-%(pd)s-%(xq)s.dat.gz'
4073 if self.web:
4074 issudfile = pjoin(self.webbin, issudfile % translation)
4075 else:
4076 issudfile = pjoin(self.me_dir, issudfile % translation)
4077
4078 logger.info('Sudakov grid file: %s' % issudfile)
4079
4080
4081 if os.path.exists(issudfile):
4082 path = pjoin(self.me_dir, 'lib', 'issudgrid.dat')
4083 misc.gunzip(issudfile, keep=True, stdout=path)
4084 else:
4085 msg = 'No sudakov grid file for parameter choice. Start to generate it. This might take a while'
4086 logger.info(msg)
4087 self.update_status('GENERATE SUDAKOF GRID', level='parton')
4088
4089 for i in range(-2,6):
4090 self.cluster.submit('%s/gensudgrid ' % self.dirbin,
4091 arguments = [i],
4092 cwd=self.me_dir,
4093 stdout=open(pjoin(self.me_dir, 'gensudgrid%s.log' % i,'w')))
4094 self.monitor()
4095 for i in range(-2,6):
4096 path = pjoin(self.me_dir, 'lib', 'issudgrid.dat')
4097 os.system('cat %s/gensudgrid%s.log >> %s' % (self.me_dir, path))
4098 misc.gzip(path, stdout=issudfile)
4099
4100
4101 - def create_root_file(self, input='unweighted_events.lhe',
4102 output='unweighted_events.root' ):
4103 """create the LHE root file """
4104 self.update_status('Creating root files', level='parton')
4105
4106 eradir = self.options['exrootanalysis_path']
4107 try:
4108 misc.call(['%s/ExRootLHEFConverter' % eradir,
4109 input, output],
4110 cwd=pjoin(self.me_dir, 'Events'))
4111 except Exception:
4112 logger.warning('fail to produce Root output [problem with ExRootAnalysis]')
4113
4114 - def run_syscalc(self, mode='parton', event_path=None, output=None):
4115 """create the syscalc output"""
4116
4117 if self.run_card['use_syst'] not in self.true:
4118 return
4119
4120 logger.info('running syscalc on mode %s' % mode)
4121 scdir = self.options['syscalc_path']
4122 tag = self.run_card['run_tag']
4123 card = pjoin(self.me_dir, 'bin','internal', 'syscalc_card.dat')
4124 template = open(pjoin(self.me_dir, 'bin','internal', 'syscalc_template.dat')).read()
4125 self.run_card['sys_pdf'] = self.run_card['sys_pdf'].split('#',1)[0].replace('&&',' \n ')
4126
4127 if not 'sys_scalecorrelation' in self.run_card:
4128 self.run_card['sys_scalecorrelation'] = -1
4129 open(card,'w').write(template % self.run_card)
4130
4131 if not scdir or \
4132 not os.path.exists(card):
4133 return False
4134 event_dir = pjoin(self.me_dir, 'Events')
4135
4136 if not event_path:
4137 if mode == 'parton':
4138 event_path = pjoin(event_dir,self.run_name, 'unweighted_events.lhe')
4139 if not (os.path.exists(event_path) or os.path.exists(event_path+".gz")):
4140 event_path = pjoin(event_dir, 'unweighted_events.lhe')
4141 output = pjoin(event_dir, 'syscalc.lhe')
4142 elif mode == 'Pythia':
4143 if 'mgpythiacard' in self.banner:
4144 pat = re.compile('''^\s*qcut\s*=\s*([\+\-\d.e]*)''', re.M+re.I)
4145 data = pat.search(self.banner['mgpythiacard'])
4146 if data:
4147 qcut = float(data.group(1))
4148 xqcut = abs(self.run_card['xqcut'])
4149 for value in self.run_card['sys_matchscale'].split():
4150 if float(value) < qcut:
4151 raise SysCalcError, 'qcut value for sys_matchscale lower than qcut in pythia_card. Bypass syscalc'
4152 if float(value) < xqcut:
4153 raise SysCalcError, 'qcut value for sys_matchscale lower than xqcut in run_card. Bypass syscalc'
4154
4155
4156 event_path = pjoin(event_dir,'syst.dat')
4157 output = pjoin(event_dir, 'syscalc.dat')
4158 else:
4159 raise self.InvalidCmd, 'Invalid mode %s' % mode
4160
4161 if not os.path.exists(event_path):
4162 if os.path.exists(event_path+'.gz'):
4163 misc.gunzip(event_path+'.gz')
4164 else:
4165 raise SysCalcError, 'Events file %s does not exits' % event_path
4166
4167 self.update_status('Calculating systematics for %s level' % mode, level = mode.lower())
4168 try:
4169 proc = misc.call([os.path.join(scdir, 'sys_calc'),
4170 event_path, card, output],
4171 stdout = open(pjoin(event_dir, self.run_name, '%s_%s_syscalc.log' % (tag,mode)),'w'),
4172 stderr = subprocess.STDOUT,
4173 cwd=event_dir)
4174
4175 time.sleep(5)
4176 except OSError, error:
4177 logger.error('fail to run syscalc: %s. Please check that SysCalc is correctly installed.' % error)
4178 else:
4179 if mode == 'parton' and os.path.exists(output):
4180 files.mv(output, event_path)
4181 else:
4182 logger.warning('SysCalc Failed. Please read the associate log to see the reason. Did you install the associate PDF set?')
4183 self.update_status('End syscalc for %s level' % mode, level = mode.lower(),
4184 makehtml=False)
4185
4186 return True
4187
4188
4189
4190
4192 """Ask the question when launching generate_events/multi_run"""
4193
4194 available_mode = ['0']
4195 void = 'NOT INSTALLED'
4196 switch_order = ['pythia', 'pgs', 'delphes', 'madspin', 'reweight']
4197 switch = {'pythia': void, 'pgs': void, 'delphes': void,
4198 'madspin': void, 'reweight': void}
4199 description = {'pythia': 'Run the pythia shower/hadronization:',
4200 'pgs': 'Run PGS as detector simulator:',
4201 'delphes':'Run Delphes as detector simulator:',
4202 'madspin':'Decay particles with the MadSpin module:',
4203 'reweight':'Add weights to the events based on changing model parameters:',
4204 }
4205 force_switch = {('pythia', 'OFF'): {'pgs': 'OFF', 'delphes': 'OFF'},
4206 ('pgs', 'ON'): {'pythia':'ON'},
4207 ('delphes', 'ON'): {'pythia': 'ON'}}
4208 switch_assign = lambda key, value: switch.__setitem__(key, value if switch[key] != void else void )
4209
4210
4211
4212 if self.options['pythia-pgs_path']:
4213 available_mode.append('1')
4214 available_mode.append('2')
4215 if os.path.exists(pjoin(self.me_dir,'Cards','pythia_card.dat')):
4216 switch['pythia'] = 'ON'
4217 else:
4218 switch['pythia'] = 'OFF'
4219 if os.path.exists(pjoin(self.me_dir,'Cards','pgs_card.dat')):
4220 switch['pgs'] = 'ON'
4221 else:
4222 switch['pgs'] = 'OFF'
4223 if self.options['delphes_path']:
4224 available_mode.append('3')
4225 if os.path.exists(pjoin(self.me_dir,'Cards','delphes_card.dat')):
4226 switch['delphes'] = 'ON'
4227 else:
4228 switch['delphes'] = 'OFF'
4229
4230
4231 if not MADEVENT or ('mg5_path' in self.options and self.options['mg5_path']):
4232 available_mode.append('4')
4233 available_mode.append('5')
4234 if os.path.exists(pjoin(self.me_dir,'Cards','madspin_card.dat')):
4235 switch['madspin'] = 'ON'
4236 else:
4237 switch['madspin'] = 'OFF'
4238 if misc.has_f2py() or self.options['f2py_compiler']:
4239 if os.path.exists(pjoin(self.me_dir,'Cards','reweight_card.dat')):
4240 switch['reweight'] = 'ON'
4241 else:
4242 switch['reweight'] = 'OFF'
4243 else:
4244 switch['reweight'] = 'Not available (requires NumPy)'
4245
4246 if '-R' in args or '--reweight' in args:
4247 if switch['reweight'] == 'OFF':
4248 switch['reweight'] = 'ON'
4249 elif switch['reweight'] != 'ON':
4250 logger.critical("Cannot run reweight: %s", switch['reweight'])
4251 if '-M' in args or '--madspin' in args:
4252 switch['madspin'] = 'ON'
4253
4254 options = list(available_mode) + ['auto', 'done']
4255 for id, key in enumerate(switch_order):
4256 if switch[key] not in [void, 'Not available (requires NumPy)']:
4257 options += ['%s=%s' % (key, s) for s in ['ON','OFF']]
4258 options.append(key)
4259 options.append('parton')
4260
4261
4262 if mode or not self.force:
4263 answer = ''
4264 while answer not in ['0', 'done', 'auto']:
4265 if mode:
4266 answer = mode
4267 else:
4268 switch_format = " %i %-61s %10s=%s\n"
4269 question = "The following switches determine which programs are run:\n"
4270 for id, key in enumerate(switch_order):
4271 question += switch_format % (id+1, description[key], key, switch[key])
4272 question += ' Either type the switch number (1 to %s) to change its default setting,\n' % (id+1)
4273 question += ' or set any switch explicitly (e.g. type \'madspin=ON\' at the prompt)\n'
4274 question += ' Type \'0\', \'auto\', \'done\' or just press enter when you are done.\n'
4275 answer = self.ask(question, '0', options)
4276 if answer.isdigit() and answer != '0':
4277 key = switch_order[int(answer) - 1]
4278 answer = '%s=%s' % (key, 'ON' if switch[key] == 'OFF' else 'OFF')
4279
4280 if '=' in answer:
4281 key, status = answer.split('=')
4282 switch[key] = status
4283 if (key, status) in force_switch:
4284 for key2, status2 in force_switch[(key, status)].items():
4285 if switch[key2] not in [status2, void]:
4286 logger.info('For coherence \'%s\' is set to \'%s\''
4287 % (key2, status2), '$MG:color:BLACK')
4288 switch[key2] = status2
4289 elif answer in ['0', 'auto', 'done']:
4290 continue
4291 else:
4292 logger.info('pass in %s only mode' % answer, '$MG:color:BLACK')
4293 switch_assign('madspin', 'OFF')
4294 switch_assign('reweight', 'OFF')
4295 if answer == 'parton':
4296 switch_assign('pythia', 'OFF')
4297 switch_assign('pgs', 'OFF')
4298 switch_assign('delphes', 'OFF')
4299 elif answer == 'pythia':
4300 switch_assign('pythia', 'ON')
4301 switch_assign('pgs', 'OFF')
4302 switch_assign('delphes', 'OFF')
4303 elif answer == 'pgs':
4304 switch_assign('pythia', 'ON')
4305 switch_assign('pgs', 'ON')
4306 switch_assign('delphes', 'OFF')
4307 elif answer == 'delphes':
4308 switch_assign('pythia', 'ON')
4309 switch_assign('pgs', 'OFF')
4310 switch_assign('delphes', 'ON')
4311 elif answer == 'madspin':
4312 switch_assign('madspin', 'ON')
4313 switch_assign('pythia', 'OFF')
4314 switch_assign('pgs', 'OFF')
4315 switch_assign('delphes', 'OF')
4316 elif answer == 'reweight':
4317 switch_assign('reweight', 'ON')
4318 switch_assign('pythia', 'OFF')
4319 switch_assign('pgs', 'OFF')
4320 switch_assign('delphes', 'OFF')
4321
4322
4323 if mode:
4324 answer = '0'
4325 else:
4326 answer = 'auto'
4327
4328
4329
4330
4331 cards = ['param_card.dat', 'run_card.dat']
4332 if switch['pythia'] == 'ON':
4333 cards.append('pythia_card.dat')
4334 if switch['pgs'] == 'ON':
4335 cards.append('pgs_card.dat')
4336 if switch['delphes'] == 'ON':
4337 cards.append('delphes_card.dat')
4338 delphes3 = True
4339 if os.path.exists(pjoin(self.options['delphes_path'], 'data')):
4340 delphes3 = False
4341 cards.append('delphes_trigger.dat')
4342 if switch['madspin'] == 'ON':
4343 cards.append('madspin_card.dat')
4344 if switch['reweight'] == 'ON':
4345 cards.append('reweight_card.dat')
4346 self.keep_cards(cards)
4347
4348 if os.path.isfile(pjoin(self.me_dir,'Cards','MadLoopParams.dat')):
4349 cards.append('MadLoopParams.dat')
4350
4351 if self.force:
4352 self.check_param_card(pjoin(self.me_dir,'Cards','param_card.dat' ))
4353 return
4354
4355 if answer == 'auto':
4356 self.ask_edit_cards(cards, mode='auto')
4357 else:
4358 self.ask_edit_cards(cards)
4359 return
4360
4361
4363 """Ask the question when launching pythia"""
4364
4365 available_mode = ['0', '1', '2']
4366 if self.options['delphes_path']:
4367 available_mode.append('3')
4368 name = {'0': 'auto', '1': 'pythia', '2':'pgs', '3':'delphes'}
4369 options = available_mode + [name[val] for val in available_mode]
4370 question = """Which programs do you want to run?
4371 0 / auto : running existing card
4372 1 / pythia : Pythia
4373 2 / pgs : Pythia + PGS\n"""
4374 if '3' in available_mode:
4375 question += """ 3 / delphes : Pythia + Delphes.\n"""
4376
4377 if not self.force:
4378 if not mode:
4379 mode = self.ask(question, '0', options)
4380 elif not mode:
4381 mode = 'auto'
4382
4383 if mode.isdigit():
4384 mode = name[mode]
4385
4386 auto = False
4387 if mode == 'auto':
4388 auto = True
4389 if os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')):
4390 mode = 'pgs'
4391 elif os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
4392 mode = 'delphes'
4393 else:
4394 mode = 'pythia'
4395 logger.info('Will run in mode %s' % mode)
4396
4397
4398
4399 cards = ['pythia_card.dat']
4400 if mode == 'pgs':
4401 cards.append('pgs_card.dat')
4402 if mode == 'delphes':
4403 cards.append('delphes_card.dat')
4404 delphes3 = True
4405 if os.path.exists(pjoin(self.options['delphes_path'], 'data')):
4406 delphes3 = False
4407 cards.append('delphes_trigger.dat')
4408 self.keep_cards(cards)
4409
4410 if self.force:
4411 return mode
4412
4413 if auto:
4414 self.ask_edit_cards(cards, mode='auto')
4415 else:
4416 self.ask_edit_cards(cards)
4417
4418 return mode
4419
4420
4421
4422
4423
4424
4425
4426
4427 -class MadEventCmdShell(MadEventCmd, cmd.CmdShell):
4428 """The command line processor of MadGraph"""
4429
4436
4437 name_to_pdg = {}
4438
4439 @classmethod
4442
4443 @staticmethod
4445 """return the list of Subprocesses"""
4446
4447 out = []
4448 for line in open(pjoin(me_dir,'SubProcesses', 'subproc.mg')):
4449 if not line:
4450 continue
4451 name = line.strip()
4452 if os.path.exists(pjoin(me_dir, 'SubProcesses', name)):
4453 out.append(pjoin(me_dir, 'SubProcesses', name))
4454
4455 return out
4456
4457
4458
4459 @staticmethod
4461 """ return the list of processes with their name"""
4462
4463 nb_sub = 0
4464 names = {}
4465 old_main = ''
4466
4467 if not os.path.exists(os.path.join(path,'processes.dat')):
4468 return SubProcesses.get_subP_info_v4(path)
4469
4470 for line in open(os.path.join(path,'processes.dat')):
4471 main = line[:8].strip()
4472 if main == 'mirror':
4473 main = old_main
4474 if line[8:].strip() == 'none':
4475 continue
4476 else:
4477 main = int(main)
4478 old_main = main
4479
4480 sub_proccess = line[8:]
4481 nb_sub += sub_proccess.count(',') + 1
4482 if main in names:
4483 names[main] += [sub_proccess.split(',')]
4484 else:
4485 names[main]= [sub_proccess.split(',')]
4486
4487 return names
4488
4489 @staticmethod
4491 """ return the list of processes with their name in case without grouping """
4492
4493 nb_sub = 0
4494 names = {'':[[]]}
4495 path = os.path.join(path, 'auto_dsig.f')
4496 found = 0
4497 for line in open(path):
4498 if line.startswith('C Process:'):
4499 found += 1
4500 names[''][0].append(line[15:])
4501 elif found >1:
4502 break
4503 return names
4504
4505
4506 @staticmethod
4508 """return the pdg codes of the particles present in the Subprocesses"""
4509
4510 all_ids = []
4511 for line in open(pjoin(path, 'leshouche.inc')):
4512 if not 'IDUP' in line:
4513 continue
4514 particles = re.search("/([\d,-]+)/", line)
4515 all_ids.append([int(p) for p in particles.group(1).split(',')])
4516 return all_ids
4517
4521 """The command for the gridpack --Those are not suppose to be use interactively--"""
4522
4523 - def __init__(self, me_dir = None, nb_event=0, seed=0, *completekey, **stdin):
4524 """Initialize the command and directly run"""
4525
4526
4527
4528 MadEventCmd.__init__(self, me_dir, *completekey, **stdin)
4529 self.run_mode = 0
4530 self.random = seed
4531 self.random_orig = self.random
4532 self.options['automatic_html_opening'] = False
4533
4534 if me_dir and nb_event and seed:
4535 self.launch(nb_event, seed)
4536 else:
4537 raise MadGraph5Error,\
4538 'Gridpack run failed: ' + str(me_dir) + str(nb_event) + \
4539 str(seed)
4540
4541 - def launch(self, nb_event, seed):
4542 """ launch the generation for the grid """
4543
4544
4545 logger.info('generate %s events' % nb_event)
4546 self.set_run_name('GridRun_%s' % seed)
4547 self.update_status('restoring default data', level=None)
4548 misc.call([pjoin(self.me_dir,'bin','internal','restore_data'),
4549 'default'],
4550 cwd=self.me_dir)
4551
4552
4553 self.update_status('Generating Events', level=None)
4554
4555
4556
4557 self.refine4grid(nb_event)
4558
4559
4560 self.exec_cmd('combine_events')
4561 self.exec_cmd('store_events')
4562 self.print_results_in_shell(self.results.current)
4563 self.exec_cmd('decay_events -from_cards', postcmd=False)
4564
4566 """Special refine for gridpack run."""
4567 self.nb_refine += 1
4568
4569 precision = nb_event
4570
4571
4572
4573 self.cluster_mode = 0
4574
4575
4576 self.save_random()
4577
4578 self.update_status('Refine results to %s' % precision, level=None)
4579 logger.info("Using random number seed offset = %s" % self.random)
4580
4581 self.total_jobs = 0
4582 subproc = [P for P in os.listdir(pjoin(self.me_dir,'SubProcesses')) if
4583 P.startswith('P') and os.path.isdir(pjoin(self.me_dir,'SubProcesses', P))]
4584 devnull = open(os.devnull, 'w')
4585 for nb_proc,subdir in enumerate(subproc):
4586 subdir = subdir.strip()
4587 Pdir = pjoin(self.me_dir, 'SubProcesses',subdir)
4588 bindir = pjoin(os.path.relpath(self.dirbin, Pdir))
4589
4590 logger.info(' %s ' % subdir)
4591
4592 for match in glob.glob(pjoin(Pdir, '*ajob*')):
4593 if os.path.basename(match)[:4] in ['ajob', 'wait', 'run.', 'done']:
4594 os.remove(pjoin(Pdir, match))
4595
4596
4597 logfile = pjoin(Pdir, 'gen_ximprove.log')
4598 misc.call([pjoin(bindir, 'gen_ximprove')],
4599 stdin=subprocess.PIPE,
4600 stdout=open(logfile,'w'),
4601 cwd=Pdir)
4602
4603 if os.path.exists(pjoin(Pdir, 'ajob1')):
4604 alljobs = glob.glob(pjoin(Pdir,'ajob*'))
4605 nb_tot = len(alljobs)
4606 self.total_jobs += nb_tot
4607 for i, job in enumerate(alljobs):
4608 job = os.path.basename(job)
4609 self.launch_job('%s' % job, cwd=Pdir, remaining=(nb_tot-i-1),
4610 run_type='Refine number %s on %s (%s/%s)' %
4611 (self.nb_refine, subdir, nb_proc+1, len(subproc)))
4612 if os.path.exists(pjoin(self.me_dir,'error')):
4613 self.monitor(html=True)
4614 raise MadEventError, \
4615 'Error detected in dir %s: %s' % \
4616 (Pdir, open(pjoin(self.me_dir,'error')).read())
4617 self.monitor(run_type='All job submitted for refine number %s' %
4618 self.nb_refine)
4619
4620 self.update_status("Combining runs", level='parton')
4621 try:
4622 os.remove(pjoin(Pdir, 'combine_runs.log'))
4623 except Exception:
4624 pass
4625
4626 bindir = pjoin(os.path.relpath(self.dirbin, pjoin(self.me_dir,'SubProcesses')))
4627 combine_runs.CombineRuns(self.me_dir)
4628
4629
4630 cross, error = sum_html.make_all_html_results(self)
4631 self.results.add_detail('cross', cross)
4632 self.results.add_detail('error', error)
4633
4634
4635 self.update_status('finish refine', 'parton', makehtml=False)
4636 devnull.close()
4637
4640 """ A container class for the various methods for initializing MadLoop. It is
4641 placed in MadEventInterface because it is used by Madevent for loop-induced
4642 simulations. """
4643
4644 @staticmethod
4646 """ Compile the check program in the directory dir_name.
4647 Return the compilation and running time. """
4648
4649
4650
4651 if os.path.isfile(pjoin(dir_name,'check')):
4652 os.remove(pjoin(dir_name,'check'))
4653 os.remove(pjoin(dir_name,'check_sa.o'))
4654 os.remove(pjoin(dir_name,'loop_matrix.o'))
4655
4656 devnull = open(os.devnull, 'w')
4657 start=time.time()
4658 retcode = subprocess.call(['make','check'],
4659 cwd=dir_name, stdout=devnull, stderr=devnull)
4660 compilation_time = time.time()-start
4661 if retcode != 0:
4662 logging.info("Error while executing make in %s" % dir_name)
4663 return None, None, None
4664
4665 if not checkRam:
4666 start=time.time()
4667 retcode = subprocess.call('./check',
4668 cwd=dir_name, stdout=devnull, stderr=devnull)
4669
4670 run_time = time.time()-start
4671 ram_usage = None
4672 else:
4673 ptimer = misc.ProcessTimer(['./check'], cwd=dir_name, shell=False, \
4674 stdout=devnull, stderr=devnull, close_fds=True)
4675 try:
4676 ptimer.execute()
4677
4678
4679
4680 while ptimer.poll():
4681 time.sleep(.2)
4682 finally:
4683
4684 ptimer.close()
4685
4686 ram_usage = ptimer.max_rss_memory
4687
4688
4689 run_time = (ptimer.t1 - ptimer.t0)
4690 retcode = ptimer.p.returncode
4691
4692 devnull.close()
4693
4694 if retcode != 0:
4695 logging.warning("Error while executing ./check in %s" % dir_name)
4696 return None, None, None
4697
4698 return compilation_time, run_time, ram_usage
4699
4700 @staticmethod
4701 - def fix_PSPoint_in_check(dir_path, read_ps = True, npoints = 1,
4702 hel_config = -1, mu_r=0.0, split_orders=-1):
4703 """Set check_sa.f to be reading PS.input assuming a working dir dir_name.
4704 if hel_config is different than -1 then check_sa.f is configured so to
4705 evaluate only the specified helicity.
4706 If mu_r > 0.0, then the renormalization constant value will be hardcoded
4707 directly in check_sa.f, if is is 0 it will be set to Sqrt(s) and if it
4708 is < 0.0 the value in the param_card.dat is used.
4709 If the split_orders target (i.e. the target squared coupling orders for
4710 the computation) is != -1, it will be changed in check_sa.f via the
4711 subroutine CALL SET_COUPLINGORDERS_TARGET(split_orders)."""
4712
4713 file_path = dir_path
4714 if not os.path.isfile(dir_path) or \
4715 not os.path.basename(dir_path)=='check_sa.f':
4716 file_path = pjoin(dir_path,'check_sa.f')
4717 if not os.path.isfile(file_path):
4718 directories = [d for d in glob.glob(pjoin(dir_path,'P*_*')) \
4719 if (re.search(r'.*P\d+_\w*$', d) and os.path.isdir(d))]
4720 if len(directories)>0:
4721 file_path = pjoin(directories[0],'check_sa.f')
4722 if not os.path.isfile(file_path):
4723 raise MadGraph5Error('Could not find the location of check_sa.f'+\
4724 ' from the specified path %s.'%str(file_path))
4725
4726 file = open(file_path, 'r')
4727 check_sa = file.read()
4728 file.close()
4729
4730 file = open(file_path, 'w')
4731 check_sa = re.sub(r"READPS = \S+\)","READPS = %s)"%('.TRUE.' if read_ps \
4732 else '.FALSE.'), check_sa)
4733 check_sa = re.sub(r"NPSPOINTS = \d+","NPSPOINTS = %d"%npoints, check_sa)
4734 if hel_config != -1:
4735 check_sa = re.sub(r"SLOOPMATRIX\S+\(\S+,MATELEM,",
4736 "SLOOPMATRIXHEL_THRES(P,%d,MATELEM,"%hel_config, check_sa)
4737 else:
4738 check_sa = re.sub(r"SLOOPMATRIX\S+\(\S+,MATELEM,",
4739 "SLOOPMATRIX_THRES(P,MATELEM,",check_sa)
4740 if mu_r > 0.0:
4741 check_sa = re.sub(r"MU_R=SQRTS","MU_R=%s"%\
4742 (("%.17e"%mu_r).replace('e','d')),check_sa)
4743 elif mu_r < 0.0:
4744 check_sa = re.sub(r"MU_R=SQRTS","",check_sa)
4745
4746 if split_orders > 0:
4747 check_sa = re.sub(r"SET_COUPLINGORDERS_TARGET\(-?\d+\)",
4748 "SET_COUPLINGORDERS_TARGET(%d)"%split_orders,check_sa)
4749
4750 file.write(check_sa)
4751 file.close()
4752
4753 @staticmethod
4754 - def run_initialization(run_dir=None, SubProc_dir=None, infos=None,\
4755 req_files = ['HelFilter.dat','LoopFilter.dat'],
4756 attempts = [4,15]):
4757 """ Run the initialization of the process in 'run_dir' with success
4758 characterized by the creation of the files req_files in this directory.
4759 The directory containing the driving source code 'check_sa.f'.
4760 The list attempt gives the successive number of PS points the
4761 initialization should be tried with before calling it failed.
4762 Returns the number of PS points which were necessary for the init.
4763 Notice at least run_dir or SubProc_dir must be provided.
4764 A negative attempt number given in input means that quadprec will be
4765 forced for initialization."""
4766
4767
4768
4769 if infos is None:
4770 infos={}
4771
4772 if SubProc_dir is None and run_dir is None:
4773 raise MadGraph5Error, 'At least one of [SubProc_dir,run_dir] must'+\
4774 ' be provided in run_initialization.'
4775
4776
4777
4778 if SubProc_dir is None:
4779 SubProc_dir = os.path.abspath(pjoin(run_dir,os.pardir))
4780
4781 if run_dir is None:
4782 directories =[ dir for dir in glob.glob(pjoin(SubProc_dir,\
4783 'P[0-9]*')) if os.path.isdir(dir) ]
4784 if directories:
4785 run_dir = directories[0]
4786 else:
4787 raise MadGraph5Error, 'Could not find a valid running directory'+\
4788 ' in %s.'%str(SubProc_dir)
4789
4790
4791
4792
4793
4794 if not os.path.isfile(pjoin(run_dir,'born_matrix.f')):
4795 if len(attempts)>=1 and attempts[0]<8:
4796 attempts[0]=8
4797 if len(attempts)>=2 and attempts[1]<25:
4798 attempts[1]=25
4799
4800 to_attempt = list(attempts)
4801 to_attempt.reverse()
4802 my_req_files = list(req_files)
4803
4804 MLCardPath = pjoin(SubProc_dir,'MadLoopParams.dat')
4805 if not os.path.isfile(MLCardPath):
4806 raise MadGraph5Error, 'Could not find MadLoopParams.dat at %s.'\
4807 %MLCardPath
4808 else:
4809 MLCard = banner_mod.MadLoopParam(MLCardPath)
4810 MLCard_orig = banner_mod.MadLoopParam(MLCard)
4811
4812
4813 if not MLCard['UseLoopFilter']:
4814 try:
4815 my_req_files.remove('LoopFilter.dat')
4816 except ValueError:
4817 pass
4818
4819 if MLCard['HelicityFilterLevel']==0:
4820 try:
4821 my_req_files.remove('HelFilter.dat')
4822 except ValueError:
4823 pass
4824
4825 def need_init():
4826 """ True if init not done yet."""
4827 proc_prefix_file = open(pjoin(run_dir,'proc_prefix.txt'),'r')
4828 proc_prefix = proc_prefix_file.read()
4829 proc_prefix_file.close()
4830 return any([not os.path.exists(pjoin(run_dir,'MadLoop5_resources',
4831 proc_prefix+fname)) for fname in my_req_files]) or \
4832 not os.path.isfile(pjoin(run_dir,'check')) or \
4833 not os.access(pjoin(run_dir,'check'), os.X_OK)
4834
4835
4836
4837 is_loop_induced = os.path.exists(pjoin(run_dir,'born_matrix.f'))
4838
4839
4840
4841
4842 if not any(attempt<0 for attempt in to_attempt):
4843 to_attempt = [-attempt for attempt in to_attempt] + to_attempt
4844 use_quad_prec = 1
4845 curr_attempt = 1
4846
4847 MLCard.set('WriteOutFilters',True)
4848
4849 while to_attempt!=[] and need_init():
4850 curr_attempt = to_attempt.pop()
4851
4852
4853 if curr_attempt < 0:
4854 use_quad_prec = -1
4855
4856 MLCard.set('CTModeInit',4)
4857 MLCard.set('ZeroThres',1e-11)
4858 else:
4859
4860 MLCard.set('CTModeInit',1)
4861 MLCard.set('ZeroThres',1e-9)
4862
4863 curr_attempt = abs(curr_attempt+1)
4864 MLCard.set('MaxAttempts',curr_attempt)
4865 MLCard.write(pjoin(SubProc_dir,'MadLoopParams.dat'))
4866
4867
4868 MadLoopInitializer.fix_PSPoint_in_check(run_dir, read_ps = False,
4869 npoints = curr_attempt)
4870 compile_time, run_time, ram_usage = \
4871 MadLoopInitializer.make_and_run(run_dir)
4872 if compile_time==None:
4873 logging.error("Failed at running the process in %s."%run_dir)
4874 attempts = None
4875 return None
4876
4877 if 'Process_compilation' not in infos.keys() or \
4878 infos['Process_compilation']==None:
4879 infos['Process_compilation'] = compile_time
4880 infos['Initialization'] = run_time
4881
4882 MLCard_orig.write(pjoin(SubProc_dir,'MadLoopParams.dat'))
4883 if need_init():
4884 return None
4885 else:
4886 return use_quad_prec*(curr_attempt-1)
4887
4888 @staticmethod
4890 """Checks whether the necessary filters are present or not."""
4891
4892 def need_init(ML_resources_path, proc_prefix, r_files):
4893 """ Returns true if not all required files are present. """
4894 return any([not os.path.exists(pjoin(ML_resources_path,
4895 proc_prefix+fname)) for fname in r_files])
4896
4897 MLCardPath = pjoin(proc_dir,'SubProcesses','MadLoopParams.dat')
4898 if not os.path.isfile(MLCardPath):
4899 raise MadGraph5Error, 'Could not find MadLoopParams.dat at %s.'\
4900 %MLCardPath
4901 MLCard = banner_mod.MadLoopParam(MLCardPath)
4902
4903 req_files = ['HelFilter.dat','LoopFilter.dat']
4904
4905 if not MLCard['UseLoopFilter']:
4906 try:
4907 req_files.remove('LoopFilter.dat')
4908 except ValueError:
4909 pass
4910 if MLCard['HelicityFilterLevel']==0:
4911 try:
4912 req_files.remove('HelFilter.dat')
4913 except ValueError:
4914 pass
4915
4916 for v_folder in glob.iglob(pjoin(proc_dir,'SubProcesses',
4917 '%s*'%subproc_prefix)):
4918
4919 if not os.path.isdir(v_folder) or not os.path.isfile(\
4920 pjoin(v_folder,'loop_matrix.f')):
4921 continue
4922 proc_prefix_file = open(pjoin(v_folder,'proc_prefix.txt'),'r')
4923 proc_prefix = proc_prefix_file.read()
4924 proc_prefix_file.close()
4925 if need_init(pjoin(proc_dir,'SubProcesses','MadLoop5_resources'),
4926 proc_prefix, req_files):
4927 return True
4928
4929 return False
4930
4931 @staticmethod
4932 - def init_MadLoop(proc_dir, n_PS=None, subproc_prefix='PV', MG_options=None,
4933 interface = None):
4934 """Advanced commands: Compiles and run MadLoop on RAMBO random PS points to initilize the
4935 filters."""
4936
4937 logger.debug('Compiling Source materials necessary for MadLoop '+
4938 'initialization.')
4939
4940
4941
4942 if interface is None:
4943 misc.compile(arg=['treatCardsLoopNoInit'], cwd=pjoin(proc_dir,'Source'))
4944 else:
4945 interface.do_treatcards('all --no_MadLoopInit')
4946
4947
4948 if os.path.exists(pjoin(proc_dir,'Source','CUTTOOLS')):
4949 misc.compile(arg=['libcuttools'],cwd=pjoin(proc_dir,'Source'))
4950 if os.path.exists(pjoin(proc_dir,'Source','IREGI')):
4951 misc.compile(arg=['libiregi'],cwd=pjoin(proc_dir,'Source'))
4952
4953 misc.compile(arg=['libmodel'],cwd=pjoin(proc_dir,'Source'))
4954 misc.compile(arg=['libdhelas'],cwd=pjoin(proc_dir,'Source'))
4955
4956
4957 logger.info('Initializing MadLoop loop-induced matrix elements '+\
4958 '(this can take some time)...')
4959
4960
4961 if MG_options:
4962 mcore = cluster.MultiCore(**MG_options)
4963 else:
4964 mcore = cluster.MultiCore(nb_core=1)
4965 def run_initialization_wrapper(run_dir, infos, attempts):
4966 if attempts is None:
4967 n_PS = MadLoopInitializer.run_initialization(
4968 run_dir=run_dir, infos=infos)
4969 else:
4970 n_PS = MadLoopInitializer.run_initialization(
4971 run_dir=run_dir, infos=infos, attempts=attempts)
4972 infos['nPS'] = n_PS
4973 return 0
4974
4975 def wait_monitoring(Idle, Running, Done):
4976 if Idle+Running+Done == 0:
4977 return
4978 logger.debug('MadLoop initialization jobs: %d Idle, %d Running, %d Done'\
4979 %(Idle, Running, Done))
4980
4981 init_info = {}
4982
4983 VirtualFolders = [f for f in glob.iglob(pjoin(proc_dir,'SubProcesses',
4984 '%s*'%subproc_prefix)) if (os.path.isdir(f) or
4985 os.path.isfile(pjoin(f,'loop_matrix.f')))]
4986 logger.debug("Now Initializing MadLoop matrix element in %d folder%s:"%\
4987 (len(VirtualFolders),'s' if len(VirtualFolders)>1 else ''))
4988 logger.debug(', '.join("'%s'"%os.path.basename(v_folder) for v_folder in
4989 VirtualFolders))
4990 for v_folder in VirtualFolders:
4991 init_info[v_folder] = {}
4992
4993
4994
4995 max_mult = 3
4996 if n_PS is None:
4997
4998 mcore.submit(run_initialization_wrapper,
4999 [pjoin(v_folder), init_info[v_folder], None])
5000 else:
5001
5002 mcore.submit(run_initialization_wrapper, [pjoin(v_folder),
5003 init_info[v_folder],
5004 [n_PS*multiplier for multiplier in range(1,max_mult+1)]])
5005
5006
5007 mcore.wait('',wait_monitoring,update_first=wait_monitoring)
5008 for v_folder in VirtualFolders:
5009 init = init_info[v_folder]
5010 if init['nPS'] is None:
5011 raise MadGraph5Error, 'Failed the initialization of'+\
5012 " loop-induced matrix element '%s'%s."%\
5013 (os.path.basename(v_folder),' (using default n_PS points)' if\
5014 n_PS is None else ' (trying with a maximum of %d PS points)'\
5015 %(max_mult*n_PS))
5016 if init['nPS']==0:
5017 logger.debug("Nothing to be done in '%s', all filters already "%\
5018 os.path.basename(v_folder)+\
5019 "present (use the '-r' option to force their recomputation)")
5020 else:
5021 logger.debug("'%s' finished using "%os.path.basename(v_folder)+
5022 '%d PS points (%s), in %.3g(compil.) + %.3g(init.) secs.'%(
5023 abs(init['nPS']),'DP' if init['nPS']>0 else 'QP',
5024 init['Process_compilation'],init['Initialization']))
5025
5026 logger.info('MadLoop initialization finished.')
5027
5028 AskforEditCard = common_run.AskforEditCard
5029