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