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