1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """A user friendly command line interface to access MadGraph features.
16 Uses the cmd package for command interpretation and tab completion.
17 """
18 from __future__ import division
19
20 import atexit
21 import glob
22 import logging
23 import math
24 import optparse
25 import os
26 import pydoc
27 import random
28 import re
29 import shutil
30 import subprocess
31 import sys
32 import traceback
33 import time
34
35 try:
36 import readline
37 GNU_SPLITTING = ('GNU' in readline.__doc__)
38 except:
39 GNU_SPLITTING = True
40
41 root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
42 root_path = os.path.split(root_path)[0]
43 sys.path.insert(0, os.path.join(root_path,'bin'))
44
45
46 pjoin = os.path.join
47
48 logger = logging.getLogger('madevent.stdout')
49 logger_stderr = logging.getLogger('madevent.stderr')
50
51 try:
52
53 import madgraph.interface.extended_cmd as cmd
54 import madgraph.iolibs.files as files
55 import madgraph.iolibs.save_load_object as save_load_object
56 import madgraph.various.banner as banner_mod
57 import madgraph.various.cluster as cluster
58 import madgraph.various.gen_crossxhtml as gen_crossxhtml
59 import madgraph.various.sum_html as sum_html
60 import madgraph.various.misc as misc
61
62 import models.check_param_card as check_param_card
63 from madgraph import InvalidCmd, MadGraph5Error
64 MADEVENT = False
65 except Exception, error:
66 if __debug__:
67 print error
68
69 import internal.extended_cmd as cmd
70 import internal.banner as banner_mod
71 import internal.misc as misc
72 from internal import InvalidCmd, MadGraph5Error
73 import internal.files as files
74 import internal.gen_crossxhtml as gen_crossxhtml
75 import internal.save_load_object as save_load_object
76 import internal.cluster as cluster
77 import internal.check_param_card as check_param_card
78 import internal.sum_html as sum_html
79 MADEVENT = True
85
90 """Particularisation of the cmd command for MadEvent"""
91
92
93 next_possibility = {
94 'start': [],
95 }
96
97 debug_output = 'ME5_debug'
98 error_debug = 'Please report this bug on https://bugs.launchpad.net/madgraph5\n'
99 error_debug += 'More information is found in \'%(debug)s\'.\n'
100 error_debug += 'Please attach this file to your report.'
101
102 config_debug = 'If you need help with this issue please contact us on https://answers.launchpad.net/madgraph5\n'
103
104
105 keyboard_stop_msg = """stopping all operation
106 in order to quit madevent please enter exit"""
107
108
109 InvalidCmd = InvalidCmd
110 ConfigurationError = MadGraph5Error
111
113 """Init history and line continuation"""
114
115
116 self.force = False
117
118
119
120 info = misc.get_pkg_info()
121 info_line = ""
122 if info and info.has_key('version') and info.has_key('date'):
123 len_version = len(info['version'])
124 len_date = len(info['date'])
125 if len_version + len_date < 30:
126 info_line = "#* VERSION %s %s %s *\n" % \
127 (info['version'],
128 (30 - len_version - len_date) * ' ',
129 info['date'])
130 else:
131 version = open(pjoin(root_path,'MGMEVersion.txt')).readline().strip()
132 info_line = "#* VERSION %s %s *\n" % \
133 (version, (24 - len(version)) * ' ')
134
135
136
137 self.history_header = \
138 '#************************************************************\n' + \
139 '#* MadGraph/MadEvent 5 *\n' + \
140 '#* *\n' + \
141 "#* * * *\n" + \
142 "#* * * * * *\n" + \
143 "#* * * * * 5 * * * * *\n" + \
144 "#* * * * * *\n" + \
145 "#* * * *\n" + \
146 "#* *\n" + \
147 "#* *\n" + \
148 info_line + \
149 "#* *\n" + \
150 "#* The MadGraph Development Team - Please visit us at *\n" + \
151 "#* https://server06.fynu.ucl.ac.be/projects/madgraph *\n" + \
152 '#* *\n' + \
153 '#************************************************************\n' + \
154 '#* *\n' + \
155 '#* Command File for MadEvent *\n' + \
156 '#* *\n' + \
157 '#* run as ./bin/madevent.py filename *\n' + \
158 '#* *\n' + \
159 '#************************************************************\n'
160
161 if info_line:
162 info_line = info_line[1:]
163
164 logger.info(\
165 "************************************************************\n" + \
166 "* *\n" + \
167 "* W E L C O M E to M A D G R A P H 5 *\n" + \
168 "* M A D E V E N T *\n" + \
169 "* *\n" + \
170 "* * * *\n" + \
171 "* * * * * *\n" + \
172 "* * * * * 5 * * * * *\n" + \
173 "* * * * * *\n" + \
174 "* * * *\n" + \
175 "* *\n" + \
176 info_line + \
177 "* *\n" + \
178 "* The MadGraph Development Team - Please visit us at *\n" + \
179 "* https://server06.fynu.ucl.ac.be/projects/madgraph *\n" + \
180 "* *\n" + \
181 "* Type 'help' for in-line help. *\n" + \
182 "* *\n" + \
183 "************************************************************")
184
185 cmd.Cmd.__init__(self, *arg, **opt)
186
188 """return the history header"""
189 return self.history_header % misc.get_time_info()
190
192 """action to perform to close nicely on a keyboard interupt"""
193 try:
194 if hasattr(self, 'results'):
195 self.update_status('Stop by the user', level=None, makehtml=False, error=True)
196 self.add_error_log_in_html()
197 except:
198 pass
199
200 - def postcmd(self, stop, line):
201 """ Update the status of the run for finishing interactive command """
202
203
204 self.force = False
205
206 if not self.use_rawinput:
207 return stop
208
209 if self.results and not self.results.current:
210 return stop
211
212 arg = line.split()
213 if len(arg) == 0:
214 return stop
215 if isinstance(self.results.status, str) and self.results.status.startswith('Error'):
216 return stop
217 if isinstance(self.results.status, str) and self.results.status == 'Stop by the user':
218 self.update_status('%s Stop by the user' % arg[0], level=None, error=True)
219 return stop
220 elif not self.results.status:
221 return stop
222 elif str(arg[0]) in ['exit','quit','EOF']:
223 return stop
224
225 try:
226 self.update_status('Command \'%s\' done.<br> Waiting for instruction.' % arg[0],
227 level=None, error=True)
228 except:
229 pass
230
232 """If a ME run is currently running add a link in the html output"""
233
234
235
236 if hasattr(self, 'results') and hasattr(self.results, 'current') and\
237 self.results.current and 'run_name' in self.results.current and \
238 hasattr(self, 'me_dir'):
239 name = self.results.current['run_name']
240 tag = self.results.current['tag']
241 self.debug_output = pjoin(self.me_dir, '%s_%s_debug.log' % (name,tag))
242 self.results.current.debug = self.debug_output
243 else:
244
245 self.debug_output = MadEventCmd.debug_output
246 if os.path.exists('ME5_debug') and not 'ME5_debug' in self.debug_output:
247 os.remove('ME5_debug')
248 if not 'ME5_debug' in self.debug_output:
249 os.system('ln -s %s ME5_debug &> /dev/null' % self.debug_output)
250
251
257
263
269
276 """ The Series of help routine for the MadEventCmd"""
277
279 logger.info("syntax: banner_run Path|RUN [--run_options]")
280 logger.info("-- Reproduce a run following a given banner")
281 logger.info(" One of the following argument is require:")
282 logger.info(" Path should be the path of a valid banner.")
283 logger.info(" RUN should be the name of a run of the current directory")
284 self.run_options_help([('-f','answer all question by default'),
285 ('--name=X', 'Define the name associated with the new run')])
286
288 logger.info("syntax: open FILE ")
289 logger.info("-- open a file with the appropriate editor.")
290 logger.info(' If FILE belongs to index.html, param_card.dat, run_card.dat')
291 logger.info(' the path to the last created/used directory is used')
292 logger.info(' The program used to open those files can be chosen in the')
293 logger.info(' configuration file ./input/mg5_configuration.txt')
294
296 logger.info("syntax: set %s argument" % "|".join(self._set_options))
297 logger.info("-- set options")
298 logger.info(" stdout_level DEBUG|INFO|WARNING|ERROR|CRITICAL")
299 logger.info(" change the default level for printed information")
300 logger.info(" timeout VALUE")
301 logger.info(" (default 20) Seconds allowed to answer questions.")
302 logger.info(" Note that pressing tab always stops the timer.")
303
305 if data:
306 logger.info('-- local options:')
307 for name, info in data:
308 logger.info(' %s : %s' % (name, info))
309
310 logger.info("-- session options:")
311 logger.info(" Note that those options will be kept for the current session")
312 logger.info(" --cluster : Submit to the cluster. Current cluster: %s" % self.options['cluster_mode'])
313 logger.info(" --multicore : Run in multi-core configuration")
314 logger.info(" --nb_core=X : limit the number of core to use to X.")
315
316
318 logger.info("syntax: generate_events [run_name] [options])")
319 logger.info("-- Launch the full chain of script for the generation of events")
320 logger.info(" Including possible plotting, shower and detector resolution.")
321 logger.info(" Those steps are performed if the related program are installed")
322 logger.info(" and if the related card are present in the Cards directory.")
323 self.run_options_help([('-f', 'Use default for all questions.'),
324 ('--laststep=', 'argument might be parton/pythia/pgs/delphes and indicate the last level to be run.')])
325
327 logger.info("syntax: calculate_decay_widths [run_name] [options])")
328 logger.info("-- Calculate decay widths and enter widths and BRs in param_card")
329 logger.info(" for a series of processes of type A > B C ...")
330 logger.info(" Note that you want to do \"set group_subprocesses False\"")
331 logger.info(" before generating the processes.")
332 self.run_options_help([('-f', 'Use default for all questions.'),
333 ('--accuracy=', 'accuracy (for each partial decay width).'\
334 + ' Default is 0.01.')])
335
337 logger.info("syntax: multi_run NB_RUN [run_name] [--run_options])")
338 logger.info("-- Launch the full chain of script for the generation of events")
339 logger.info(" NB_RUN times. This chains includes possible plotting, shower")
340 logger.info(" and detector resolution.")
341 self.run_options_help([('-f', 'Use default for all questions.'),
342 ('--laststep=', 'argument might be parton/pythia/pgs/delphes and indicate the last level to be run.')])
343
345 logger.info("syntax: survey [run_name] [--run_options])")
346 logger.info("-- evaluate the different channel associate to the process")
347 self.run_options_help([("--" + key,value[-1]) for (key,value) in \
348 self._survey_options.items()])
349
351 logger.info("syntax: refine require_precision [max_channel] [--run_options]")
352 logger.info("-- refine the LAST run to achieve a given precision.")
353 logger.info(" require_precision: can be either the targeted number of events")
354 logger.info(' or the required relative error')
355 logger.info(' max_channel:[5] maximal number of channel per job')
356 self.run_options_help([])
357
359 """ """
360 logger.info("syntax: combine_events [run_name] [--tag=tag_name] [--run_options]")
361 logger.info("-- Combine the last run in order to write the number of events")
362 logger.info(" asked in the run_card.")
363 self.run_options_help([])
364
366 """ """
367 logger.info("syntax: store_events [--run_options]")
368 logger.info("-- Write physically the events in the files.")
369 logger.info(" should be launch after \'combine_events\'")
370 self.run_options_help([])
371
373 """ """
374 logger.info("syntax: create_gridpack [--run_options]")
375 logger.info("-- create the gridpack. ")
376 logger.info(" should be launch after \'store_events\'")
377 self.run_options_help([])
378
380 """ """
381 logger.info("syntax: import command PATH")
382 logger.info("-- Execute the command present in the file")
383 self.run_options_help([])
384
386 logger.info("syntax: help [RUN] [%s] [-f]" % '|'.join(self._plot_mode))
387 logger.info("-- create the plot for the RUN (current run by default)")
388 logger.info(" at the different stage of the event generation")
389 logger.info(" Note than more than one mode can be specified in the same command.")
390 logger.info(" This require to have MadAnalysis and td require. By default")
391 logger.info(" if those programs are installed correctly, the creation")
392 logger.info(" will be performed automaticaly during the event generation.")
393 logger.info(" -f options: answer all question by default.")
394
396 logger.info("syntax: remove RUN [all|parton|pythia|pgs|delphes|banner] [-f] [--tag=]")
397 logger.info("-- Remove all the files linked to previous run RUN")
398 logger.info(" if RUN is 'all', then all run will be cleaned.")
399 logger.info(" The optional argument precise which part should be cleaned.")
400 logger.info(" By default we clean all the related files but the banners.")
401 logger.info(" the optional '-f' allows to by-pass all security question")
402 logger.info(" The banner can be remove only if all files are removed first.")
403
405 logger.info("syntax: pythia [RUN] [--run_options]")
406 logger.info("-- run pythia on RUN (current one by default)")
407 self.run_options_help([('-f','answer all question by default'),
408 ('--tag=', 'define the tag for the pythia run'),
409 ('--no_default', 'not run if pythia_card not present')])
410
412 logger.info("syntax: pgs [RUN] [--run_options]")
413 logger.info("-- run pgs on RUN (current one by default)")
414 self.run_options_help([('-f','answer all question by default'),
415 ('--tag=', 'define the tag for the pgs run'),
416 ('--no_default', 'not run if pgs_card not present')])
417
419 logger.info("syntax: delphes [RUN] [--run_options]")
420 logger.info("-- run delphes on RUN (current one by default)")
421 self.run_options_help([('-f','answer all question by default'),
422 ('--tag=', 'define the tag for the delphes run'),
423 ('--no_default', 'not run if delphes_card not present')])
424
429 """ The Series of check routine for the MadEventCmd"""
430
432 """check the validity of line"""
433
434 if len(args) == 0:
435 self.help_banner_run()
436 raise self.InvalidCmd('banner_run reauires at least one argument.')
437
438 tag = [a[6:] for a in args if a.startswith('--tag=')]
439
440
441 if os.path.isfile(args[0]):
442 type ='banner'
443 format = self.detect_card_type(args[0])
444 if format != 'banner':
445 raise self.InvalidCmd('The file is not a valid banner.')
446 elif tag:
447 args[0] = pjoin(self.me_dir,'Events', args[0], '%s_%s_banner.txt' % \
448 (args[0], tag))
449 if not os.path.exists(args[0]):
450 raise self.InvalidCmd('No banner associates to this name and tag.')
451 else:
452 name = args[0]
453 type = 'run'
454 banners = glob.glob(pjoin(self.me_dir,'Events', args[0], '*_banner.txt'))
455 if not banners:
456 raise self.InvalidCmd('No banner associates to this name.')
457 elif len(banners) == 1:
458 args[0] = banners[0]
459 else:
460
461 tags = [os.path.basename(p)[len(args[0])+1:-11] for p in banners]
462 tag = self.ask('which tag do you want to use?', tags[0], tags)
463 args[0] = pjoin(self.me_dir,'Events', args[0], '%s_%s_banner.txt' % \
464 (args[0], tag))
465
466 run_name = [arg[7:] for arg in args if arg.startswith('--name=')]
467 if run_name:
468 try:
469 os.exec_cmd('remove %s all banner' % run_name)
470 except:
471 pass
472 self.set_run_name(args[0], tag=None, level='parton', reload_card=True)
473 elif type == 'banner':
474 self.set_run_name(self.find_available_run_name(self.me_dir))
475 elif type == 'run':
476 if os.path.exists(pjoin(self.me_dir, 'Events', name)):
477 run_name = self.find_available_run_name(self.me_dir)
478 logger.info('Run %s is not empty so will use run_name: %s' % \
479 (name, run_name))
480 self.set_run_name(run_name)
481 else:
482 self.set_run_name(name)
483
484 - def check_history(self, args):
485 """check the validity of line"""
486
487 if len(args) > 1:
488 self.help_history()
489 raise self.InvalidCmd('\"history\" command takes at most one argument')
490
491 if not len(args):
492 return
493 elif args[0] != 'clean':
494 dirpath = os.path.dirname(args[0])
495 if dirpath and not os.path.exists(dirpath) or \
496 os.path.isdir(args[0]):
497 raise self.InvalidCmd("invalid path %s " % dirpath)
498
500 """ check the validity of the line"""
501
502 if len(args) < 2:
503 self.help_set()
504 raise self.InvalidCmd('set needs an option and an argument')
505
506 if args[0] not in self._set_options + self.options.keys():
507 self.help_set()
508 raise self.InvalidCmd('Possible options for set are %s' % \
509 self._set_options)
510
511 if args[0] in ['stdout_level']:
512 if args[1] not in ['DEBUG','INFO','WARNING','ERROR','CRITICAL']:
513 raise self.InvalidCmd('output_level needs ' + \
514 'a valid level')
515
516 if args[0] in ['timeout']:
517 if not args[1].isdigit():
518 raise self.InvalidCmd('timeout values should be a integer')
519
521 """ check the validity of the line """
522
523 if len(args) != 1:
524 self.help_open()
525 raise self.InvalidCmd('OPEN command requires exactly one argument')
526
527 if args[0].startswith('./'):
528 if not os.path.isfile(args[0]):
529 raise self.InvalidCmd('%s: not such file' % args[0])
530 return True
531
532
533 if not self.me_dir:
534 if not os.path.isfile(args[0]):
535 self.help_open()
536 raise self.InvalidCmd('No MadEvent path defined. Unable to associate this name to a file')
537 else:
538 return True
539
540 path = self.me_dir
541 if os.path.isfile(os.path.join(path,args[0])):
542 args[0] = os.path.join(path,args[0])
543 elif os.path.isfile(os.path.join(path,'Cards',args[0])):
544 args[0] = os.path.join(path,'Cards',args[0])
545 elif os.path.isfile(os.path.join(path,'HTML',args[0])):
546 args[0] = os.path.join(path,'HTML',args[0])
547
548 elif '_card.dat' in args[0]:
549 name = args[0].replace('_card.dat','_card_default.dat')
550 if os.path.isfile(os.path.join(path,'Cards', name)):
551 files.cp(path + '/Cards/' + name, path + '/Cards/'+ args[0])
552 args[0] = os.path.join(path,'Cards', args[0])
553 else:
554 raise self.InvalidCmd('No default path for this file')
555 elif not os.path.isfile(args[0]):
556 raise self.InvalidCmd('No default path for this file')
557
559 """check that the argument for survey are valid"""
560
561
562 self.opts = dict([(key,value[1]) for (key,value) in \
563 self._survey_options.items()])
564
565
566 while args and args[-1].startswith('--'):
567 arg = args.pop(-1)
568 try:
569 for opt,value in self._survey_options.items():
570 if arg.startswith('--%s=' % opt):
571 exec('self.opts[\'%s\'] = %s(arg.split(\'=\')[-1])' % \
572 (opt, value[0]))
573 arg = ""
574 if arg != "": raise Exception
575 except Exception:
576 self.help_survey()
577 raise self.InvalidCmd('invalid %s argument'% arg)
578
579 if len(args) > 1:
580 self.help_survey()
581 raise self.InvalidCmd('Too many argument for %s command' % cmd)
582 elif not args:
583
584 self.set_run_name(self.find_available_run_name(self.me_dir))
585 else:
586 self.set_run_name(args[0], None,'parton', True)
587 args.pop(0)
588
589 return True
590
592 """check that the argument for generate_events are valid"""
593
594 run = None
595 if args and args[-1].startswith('--laststep='):
596 run = args[-1].split('=')[-1]
597 if run not in ['auto','parton', 'pythia', 'pgs', 'delphes']:
598 self.help_generate_events()
599 raise self.InvalidCmd('invalid %s argument'% args[-1])
600 if run != 'parton' and not self.options['pythia-pgs_path']:
601 raise self.InvalidCmd('''pythia-pgs not install. Please install this package first.
602 To do so type: \'install pythia-pgs\' in the mg5 interface''')
603 if run == 'delphes' and not self.options['delphes_path']:
604 raise self.InvalidCmd('''delphes not install. Please install this package first.
605 To do so type: \'install Delphes\' in the mg5 interface''')
606 del args[-1]
607
608 if len(args) > 1:
609 self.help_generate_events()
610 raise self.InvalidCmd('Too many argument for generate_events command: %s' % cmd)
611
612 return run
613
615 """check that the argument for calculate_decay_widths are valid"""
616
617 if self.ninitial != 1:
618 raise self.InvalidCmd('Can only calculate decay widths for decay processes A > B C ...')
619
620 accuracy = 0.01
621 run = None
622 if args and args[-1].startswith('--accuracy='):
623 try:
624 accuracy = float(args[-1].split('=')[-1])
625 except:
626 self.InvalidCmd('Argument error in calculate_decay_widths command')
627 del args[-1]
628 if len(args) > 1:
629 self.help_calculate_decay_widths()
630 raise self.InvalidCmd('Too many argument for calculate_decay_widths command: %s' % cmd)
631
632 return accuracy
633
634
635
637 """check that the argument for survey are valid"""
638
639 run = None
640
641 if not len(args):
642 self.help_multi_run()
643 raise self.InvalidCmd("""multi_run command requires at least one argument for
644 the number of times that it call generate_events command""")
645
646 if args[-1].startswith('--laststep='):
647 run = args[-1].split('=')[-1]
648 if run not in ['parton', 'pythia', 'pgs', 'delphes']:
649 self.help_multi_run()
650 raise self.InvalidCmd('invalid %s argument'% args[-1])
651 if run != 'parton' and not self.options['pythia-pgs_path']:
652 raise self.InvalidCmd('''pythia-pgs not install. Please install this package first.
653 To do so type: \'install pythia-pgs\' in the mg5 interface''')
654 if run == 'delphes' and not self.options['delphes_path']:
655 raise self.InvalidCmd('''delphes not install. Please install this package first.
656 To do so type: \'install Delphes\' in the mg5 interface''')
657 del args[-1]
658
659
660 elif not args[0].isdigit():
661 self.help_multi_run()
662 raise self.InvalidCmd("The first argument of multi_run should be a integer.")
663 nb_run = args.pop(0)
664 self.check_survey(args, cmd='multi_run')
665 args.insert(0, int(nb_run))
666
667 return run
668
670 """check that the argument for survey are valid"""
671
672
673 try:
674 float(args[-1])
675 except ValueError:
676 self.help_refine()
677 raise self.InvalidCmd('Not valid arguments')
678 except IndexError:
679 self.help_refine()
680 raise self.InvalidCmd('require_precision argument is require for refine cmd')
681
682
683 if not self.run_name:
684 if self.results.lastrun:
685 self.set_run_name(self.results.lastrun)
686 else:
687 raise self.InvalidCmd('No run_name currently define. Unable to run refine')
688
689 if len(args) > 2:
690 self.help_refine()
691 raise self.InvalidCmd('Too many argument for refine command')
692 else:
693 try:
694 [float(arg) for arg in args]
695 except ValueError:
696 self.help_refine()
697 raise self.InvalidCmd('refine arguments are suppose to be number')
698
699 return True
700
702 """ Check the argument for the combine events command """
703
704 tag = [a for a in arg if a.startswith('--tag=')]
705 if tag:
706 args.remove(tag[0])
707 tag = tag[0][6:]
708 elif not self.run_tag:
709 tag = 'tag_1'
710 else:
711 tag = self.run_tag
712 self.run_tag = tag
713
714 if len(arg) > 1:
715 self.help_combine_events()
716 raise self.InvalidCmd('Too many argument for combine_events command')
717
718 if len(arg) == 1:
719 self.set_run_name(arg[0], self.run_tag, 'parton', True)
720
721 if not self.run_name:
722 if not self.results.lastrun:
723 raise self.InvalidCmd('No run_name currently define. Unable to run combine')
724 else:
725 self.set_run_name(self.results.lastrun)
726
727 return True
728
730 """Check the argument for pythia command
731 syntax: pythia [NAME]
732 Note that other option are already remove at this point
733 """
734
735 mode = None
736 laststep = [arg for arg in args if arg.startswith('--laststep=')]
737 if laststep and len(laststep)==1:
738 mode = laststep[0].split('=')[-1]
739 if mode not in ['auto', 'pythia', 'pgs', 'delphes']:
740 self.help_pythia()
741 raise self.InvalidCmd('invalid %s argument'% args[-1])
742 elif laststep:
743 raise self.InvalidCmd('only one laststep argument is allowed')
744
745
746 if not self.options['pythia-pgs_path']:
747 logger.info('Retry to read configuration file to find pythia-pgs path')
748 self.set_configuration()
749
750 if not self.options['pythia-pgs_path'] or not \
751 os.path.exists(pjoin(self.options['pythia-pgs_path'],'src')):
752 error_msg = 'No pythia-pgs path correctly set.'
753 error_msg += 'Please use the set command to define the path and retry.'
754 error_msg += 'You can also define it in the configuration file.'
755 raise self.InvalidCmd(error_msg)
756
757
758
759 tag = [a for a in args if a.startswith('--tag=')]
760 if tag:
761 args.remove(tag[0])
762 tag = tag[0][6:]
763
764 if len(args) == 0 and not self.run_name:
765 if self.results.lastrun:
766 args.insert(0, self.results.lastrun)
767 else:
768 raise self.InvalidCmd('No run name currently define. Please add this information.')
769
770 if len(args) >= 1:
771 if args[0] != self.run_name and\
772 not os.path.exists(pjoin(self.me_dir,'Events',args[0], 'unweighted_events.lhe.gz')):
773 raise self.InvalidCmd('No events file corresponding to %s run. '% args[0])
774 self.set_run_name(args[0], tag, 'pythia')
775 else:
776 if tag:
777 self.run_card['run_tag'] = tag
778 self.set_run_name(self.run_name, tag, 'pythia')
779
780 if not os.path.exists(pjoin(self.me_dir,'Events',self.run_name,'unweighted_events.lhe.gz')):
781 raise self.InvalidCmd('No events file corresponding to %s run. '% self.run_name)
782
783
784 input_file = pjoin(self.me_dir,'Events',self.run_name, 'unweighted_events.lhe')
785 output_file = pjoin(self.me_dir, 'Events', 'unweighted_events.lhe')
786 os.system('gunzip -c %s > %s' % (input_file, output_file))
787
788 args.append(mode)
789
791 """Check that the remove command is valid"""
792
793 tmp_args = args[:]
794
795 tag = [a[6:] for a in tmp_args if a.startswith('--tag=')]
796 if tag:
797 tag = tag[0]
798 tmp_args.remove('--tag=%s' % tag)
799
800
801 if len(tmp_args) == 0:
802 self.help_remove()
803 raise self.InvalidCmd('clean command require the name of the run to clean')
804 elif len(tmp_args) == 1:
805 return tmp_args[0], tag, ['all']
806 else:
807 for arg in tmp_args[1:]:
808 if arg not in self._clean_mode:
809 self.help_remove()
810 raise self.InvalidCmd('%s is not a valid options for clean command'\
811 % arg)
812 return tmp_args[0], tag, tmp_args[1:]
813
815 """Check the argument for the plot command
816 plot run_name modes"""
817
818 madir = self.options['madanalysis_path']
819 td = self.options['td_path']
820
821 if not madir or not td:
822 logger.info('Retry to read configuration file to find madanalysis/td')
823 self.set_configuration()
824
825 madir = self.options['madanalysis_path']
826 td = self.options['td_path']
827
828 if not madir:
829 error_msg = 'No Madanalysis path correctly set.'
830 error_msg += 'Please use the set command to define the path and retry.'
831 error_msg += 'You can also define it in the configuration file.'
832 raise self.InvalidCmd(error_msg)
833 if not td:
834 error_msg = 'No path to td directory correctly set.'
835 error_msg += 'Please use the set command to define the path and retry.'
836 error_msg += 'You can also define it in the configuration file.'
837 raise self.InvalidCmd(error_msg)
838
839 if len(args) == 0:
840 if not hasattr(self, 'run_name') or not self.run_name:
841 self.help_plot()
842 raise self.InvalidCmd('No run name currently define. Please add this information.')
843 args.append('all')
844 return
845
846
847 if args[0] not in self._plot_mode:
848 self.set_run_name(args[0], level='plot')
849 del args[0]
850 if len(args) == 0:
851 args.append('all')
852 elif not self.run_name:
853 self.help_plot()
854 raise self.InvalidCmd('No run name currently define. Please add this information.')
855
856 for arg in args:
857 if arg not in self._plot_mode and arg != self.run_name:
858 self.help_plot()
859 raise self.InvalidCmd('unknown options %s' % arg)
860
861
863 """Check the argument for pythia command
864 syntax: pgs [NAME]
865 Note that other option are already remove at this point
866 """
867
868
869 if not self.options['pythia-pgs_path']:
870 logger.info('Retry to read configuration file to find pythia-pgs path')
871 self.set_configuration()
872
873 if not self.options['pythia-pgs_path'] or not \
874 os.path.exists(pjoin(self.options['pythia-pgs_path'],'src')):
875 error_msg = 'No pythia-pgs path correctly set.'
876 error_msg += 'Please use the set command to define the path and retry.'
877 error_msg += 'You can also define it in the configuration file.'
878 raise self.InvalidCmd(error_msg)
879
880 tag = [a for a in arg if a.startswith('--tag=')]
881 if tag:
882 arg.remove(tag[0])
883 tag = tag[0][6:]
884
885
886 if len(arg) == 0 and not self.run_name:
887 if self.results.lastrun:
888 arg.insert(0, self.results.lastrun)
889 else:
890 raise self.InvalidCmd('No run name currently define. Please add this information.')
891
892 if len(arg) == 1 and self.run_name == arg[0]:
893 arg.pop(0)
894
895 if not len(arg) and \
896 not os.path.exists(pjoin(self.me_dir,'Events','pythia_events.hep')):
897 self.help_pgs()
898 raise self.InvalidCmd('''No file file pythia_events.hep currently available
899 Please specify a valid run_name''')
900
901 if len(arg) == 1:
902 prev_tag = self.set_run_name(arg[0], tag, 'pgs')
903 if not os.path.exists(pjoin(self.me_dir,'Events',self.run_name,'%s_pythia_events.hep.gz' % prev_tag)):
904 raise self.InvalidCmd('No events file corresponding to %s run with tag %s. '% (self.run_name, prev_tag))
905 else:
906 input_file = pjoin(self.me_dir,'Events', self.run_name, '%s_pythia_events.hep.gz' % prev_tag)
907 output_file = pjoin(self.me_dir, 'Events', 'pythia_events.hep')
908 self.launch_job('gunzip',stdout=open(output_file,'w'),
909 argument=['-c', input_file], mode=2)
910 else:
911 if tag:
912 self.run_card['run_tag'] = tag
913 self.set_run_name(self.run_name, tag, 'pgs')
914
915
917 """Check the argument for pythia command
918 syntax: delphes [NAME]
919 Note that other option are already remove at this point
920 """
921
922
923 if not self.options['delphes_path']:
924 logger.info('Retry to read configuration file to find delphes path')
925 self.set_configuration()
926
927 if not self.options['delphes_path']:
928 error_msg = 'No delphes path correctly set.'
929 error_msg += 'Please use the set command to define the path and retry.'
930 error_msg += 'You can also define it in the configuration file.'
931 raise self.InvalidCmd(error_msg)
932
933 tag = [a for a in arg if a.startswith('--tag=')]
934 if tag:
935 arg.remove(tag[0])
936 tag = tag[0][6:]
937
938
939 if len(arg) == 0 and not self.run_name:
940 if self.results.lastrun:
941 arg.insert(0, self.results.lastrun)
942 else:
943 raise self.InvalidCmd('No run name currently define. Please add this information.')
944
945 if len(arg) == 1 and self.run_name == arg[0]:
946 arg.pop(0)
947
948 if not len(arg) and \
949 not os.path.exists(pjoin(self.me_dir,'Events','pythia_events.hep')):
950 self.help_pgs()
951 raise self.InvalidCmd('''No file file pythia_events.hep currently available
952 Please specify a valid run_name''')
953
954 if len(arg) == 1:
955 prev_tag = self.set_run_name(arg[0], tag, 'delphes')
956 if not os.path.exists(pjoin(self.me_dir,'Events',self.run_name, '%s_pythia_events.hep.gz' % prev_tag)):
957 raise self.InvalidCmd('No events file corresponding to %s run with tag %s.:%s '\
958 % (self.run_name, prev_tag,
959 pjoin(self.me_dir,'Events',self.run_name, '%s_pythia_events.hep.gz' % prev_tag)))
960 else:
961 input_file = pjoin(self.me_dir,'Events', self.run_name, '%s_pythia_events.hep.gz' % prev_tag)
962 output_file = pjoin(self.me_dir, 'Events', 'pythia_events.hep')
963 self.launch_job('gunzip',stdout=open(output_file,'w'),
964 argument=['-c', input_file], mode=2)
965 else:
966 if tag:
967 self.run_card['run_tag'] = tag
968 self.set_run_name(self.run_name, tag, 'delphes')
969
971 """check the validity of line
972 syntax: display XXXXX
973 """
974
975 if len(args) < 1 or args[0] not in self._display_opts:
976 self.help_display()
977 raise self.InvalidCmd
978
979 if args[0] == 'variable' and len(args) !=2:
980 raise self.InvalidCmd('variable need a variable name')
981
982
983
984
985
987 """check the validity of line"""
988
989 if not args:
990 self.help_import()
991 raise self.InvalidCmd('wrong \"import\" format')
992
993 if args[0] != 'command':
994 args.insert(0,'command')
995
996
997 if not len(args) == 2 or not os.path.exists(args[1]):
998 raise self.InvalidCmd('PATH is mandatory for import command\n')
999
1005 """ The Series of help routine for the MadGraphCmd"""
1006
1008 "Complete the banner run command"
1009 try:
1010
1011
1012 args = self.split_arg(line[0:begidx], error=False)
1013
1014 if args[-1].endswith(os.path.sep):
1015 return self.path_completion(text,
1016 os.path.join('.',*[a for a in args \
1017 if a.endswith(os.path.sep)]))
1018
1019
1020 if len(args) > 1:
1021
1022 tags = glob.glob(pjoin(self.me_dir, 'Events' , args[1],'%s_*_banner.txt' % args[1]))
1023 tags = ['%s' % os.path.basename(t)[len(args[1])+1:-11] for t in tags]
1024
1025 if args[-1] != '--tag=':
1026 tags = ['--tag=%s' % t for t in tags]
1027 else:
1028 return self.list_completion(text, tags)
1029 return self.list_completion(text, tags +['--name=','-f'], line)
1030
1031
1032 possibilites = {}
1033
1034 comp = self.path_completion(text, os.path.join('.',*[a for a in args \
1035 if a.endswith(os.path.sep)]))
1036 if os.path.sep in line:
1037 return comp
1038 else:
1039 possibilites['Path from ./'] = comp
1040
1041 run_list = glob.glob(pjoin(self.me_dir, 'Events', '*','*_banner.txt'))
1042 run_list = [n.rsplit('/',2)[1] for n in run_list]
1043 possibilites['RUN Name'] = self.list_completion(text, run_list)
1044
1045 return self.deal_multiple_categories(possibilites)
1046
1047
1048 except Exception, error:
1049 print error
1050 - def complete_history(self, text, line, begidx, endidx):
1051 "Complete the history command"
1052
1053 args = self.split_arg(line[0:begidx], error=False)
1054
1055
1056 if args[-1].endswith(os.path.sep):
1057 return self.path_completion(text,
1058 os.path.join('.',*[a for a in args \
1059 if a.endswith(os.path.sep)]))
1060
1061 if len(args) == 1:
1062 return self.path_completion(text)
1063
1065 """ complete the open command """
1066
1067 args = self.split_arg(line[0:begidx])
1068
1069
1070 if os.path.sep in args[-1] + text:
1071 return self.path_completion(text,
1072 os.path.join('.',*[a for a in args if \
1073 a.endswith(os.path.sep)]))
1074
1075 possibility = []
1076 if self.me_dir:
1077 path = self.me_dir
1078 possibility = ['index.html']
1079 if os.path.isfile(os.path.join(path,'README')):
1080 possibility.append('README')
1081 if os.path.isdir(os.path.join(path,'Cards')):
1082 possibility += [f for f in os.listdir(os.path.join(path,'Cards'))
1083 if f.endswith('.dat')]
1084 if os.path.isdir(os.path.join(path,'HTML')):
1085 possibility += [f for f in os.listdir(os.path.join(path,'HTML'))
1086 if f.endswith('.html') and 'default' not in f]
1087 else:
1088 possibility.extend(['./','../'])
1089 if os.path.exists('ME5_debug'):
1090 possibility.append('ME5_debug')
1091 if os.path.exists('MG5_debug'):
1092 possibility.append('MG5_debug')
1093 return self.list_completion(text, possibility)
1094
1096 "Complete the set command"
1097
1098 args = self.split_arg(line[0:begidx])
1099
1100
1101 if len(args) == 1:
1102 return self.list_completion(text, self._set_options + self.options.keys() )
1103
1104 if len(args) == 2:
1105 if args[1] == 'stdout_level':
1106 return self.list_completion(text, ['DEBUG','INFO','WARNING','ERROR','CRITICAL'])
1107 else:
1108 first_set = ['None','True','False']
1109
1110 second_set = [name for name in self.path_completion(text, '.', only_dirs = True)]
1111 return self.list_completion(text, first_set + second_set)
1112 elif len(args) >2 and args[-1].endswith(os.path.sep):
1113 return self.path_completion(text,
1114 os.path.join('.',*[a for a in args if a.endswith(os.path.sep)]),
1115 only_dirs = True)
1116
1118 """ Complete the survey command """
1119
1120 if line.endswith('nb_core=') and not text:
1121 import multiprocessing
1122 max = multiprocessing.cpu_count()
1123 return [str(i) for i in range(2,max+1)]
1124
1125 return self.list_completion(text, self._run_options, line)
1126
1127 complete_refine = complete_survey
1128 complete_combine_events = complete_survey
1129 complite_store = complete_survey
1130 complete_generate_events = complete_survey
1131 complete_create_gridpack = complete_survey
1132
1134 """ Complete the generate events"""
1135
1136 if line.endswith('nb_core=') and not text:
1137 import multiprocessing
1138 max = multiprocessing.cpu_count()
1139 return [str(i) for i in range(2,max+1)]
1140 if line.endswith('laststep=') and not text:
1141 return ['parton','pythia','pgs','delphes']
1142 elif '--laststep=' in line.split()[-1] and line and line[-1] != ' ':
1143 return self.list_completion(text,['parton','pythia','pgs','delphes'],line)
1144
1145 opts = self._run_options + self._generate_options
1146 return self.list_completion(text, opts, line)
1147
1149 """ Complete the calculate_decay_widths command"""
1150
1151 if line.endswith('nb_core=') and not text:
1152 import multiprocessing
1153 max = multiprocessing.cpu_count()
1154 return [str(i) for i in range(2,max+1)]
1155
1156 opts = self._run_options + self._calculate_decay_options
1157 return self.list_completion(text, opts, line)
1158
1160 """complete multi run command"""
1161
1162 args = self.split_arg(line[0:begidx], error=False)
1163 if len(args) == 1:
1164 data = [str(i) for i in range(0,20)]
1165 return self.list_completion(text, data, line)
1166
1167 if line.endswith('run=') and not text:
1168 return ['parton','pythia','pgs','delphes']
1169 elif '--laststep=' in line.split()[-1] and line and line[-1] != ' ':
1170 return self.list_completion(text,['parton','pythia','pgs','delphes'],line)
1171
1172 opts = self._run_options + self._generate_options
1173 return self.list_completion(text, opts, line)
1174
1175
1176
1177 if line.endswith('nb_core=') and not text:
1178 import multiprocessing
1179 max = multiprocessing.cpu_count()
1180 return [str(i) for i in range(2,max+1)]
1181 opts = self._run_options + self._generate_options
1182 return self.list_completion(text, opts, line)
1183
1192
1194 """Complete the remove command """
1195
1196 args = self.split_arg(line[0:begidx], error=False)
1197 if len(args) > 1 and (text.startswith('--t')):
1198 run = args[1]
1199 tags = ['--tag=%s' % tag['tag'] for tag in self.results[run]]
1200 return self.list_completion(text, tags)
1201 elif len(args) > 1 and '--' == args[-1]:
1202 run = args[1]
1203 tags = ['tag=%s' % tag['tag'] for tag in self.results[run]]
1204 return self.list_completion(text, tags)
1205 elif len(args) > 1 and '--tag=' == args[-1]:
1206 run = args[1]
1207 tags = [tag['tag'] for tag in self.results[run]]
1208 return self.list_completion(text, tags)
1209 elif len(args) > 1:
1210 return self.list_completion(text, self._clean_mode + ['-f','--tag='])
1211 else:
1212 data = glob.glob(pjoin(self.me_dir, 'Events','*','*_banner.txt'))
1213 data = [n.rsplit('/',2)[1] for n in data]
1214 return self.list_completion(text, ['all'] + data)
1215
1216
1218 "Complete the pythia command"
1219 args = self.split_arg(line[0:begidx], error=False)
1220
1221 if len(args) == 1:
1222
1223 data = glob.glob(pjoin(self.me_dir, 'Events', '*','unweighted_events.lhe.gz'))
1224 data = [n.rsplit('/',2)[1] for n in data]
1225 tmp1 = self.list_completion(text, data)
1226 if not self.run_name:
1227 return tmp1
1228 else:
1229 tmp2 = self.list_completion(text, self._run_options + ['-f',
1230 '--no_default', '--tag='], line)
1231 return tmp1 + tmp2
1232 elif line[-1] != '=':
1233 return self.list_completion(text, self._run_options + ['-f',
1234 '--no_default','--tag='], line)
1235
1237 "Complete the pythia command"
1238 args = self.split_arg(line[0:begidx], error=False)
1239 if len(args) == 1:
1240
1241 data = glob.glob(pjoin(self.me_dir, 'Events', '*', '*_pythia_events.hep.gz'))
1242 data = [n.rsplit('/',2)[1] for n in data]
1243 tmp1 = self.list_completion(text, data)
1244 if not self.run_name:
1245 return tmp1
1246 else:
1247 tmp2 = self.list_completion(text, self._run_options + ['-f',
1248 '--tag=' ,'--no_default'], line)
1249 return tmp1 + tmp2
1250 else:
1251 return self.list_completion(text, self._run_options + ['-f',
1252 '--tag=','--no_default'], line)
1253
1254 complete_delphes = complete_pgs
1255
1259
1260
1261
1262
1263 -class MadEventCmd(CmdExtended, HelpToCmd, CompleteForCmd):
1264 """The command line processor of MadGraph"""
1265
1266
1267 true = ['T','.true.',True,'true']
1268
1269 _run_options = ['--cluster','--multicore','--nb_core=','--nb_core=2', '-c', '-m']
1270 _generate_options = ['-f', '--laststep=parton', '--laststep=pythia', '--laststep=pgs', '--laststep=delphes']
1271 _calculate_decay_options = ['-f', '--accuracy=0.']
1272 _set_options = ['stdout_level','fortran_compiler','timeout']
1273 _plot_mode = ['all', 'parton','pythia','pgs','delphes','channel', 'banner']
1274 _clean_mode = _plot_mode
1275 _display_opts = ['run_name', 'options', 'variable']
1276
1277 _survey_options = {'points':('int', 1000,'Number of points for first iteration'),
1278 'iterations':('int', 5, 'Number of iterations'),
1279 'accuracy':('float', 0.1, 'Required accuracy'),
1280 'gridpack':('str', '.false.', 'Gridpack generation')}
1281
1282 true = ['T','.true.',True,'true', 1, '1']
1283 web = False
1284 prompt = 'MGME5>'
1285 cluster_mode = 0
1286 queue = 'madgraph'
1287 nb_core = None
1288
1289 next_possibility = {
1290 'start': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]',
1291 'calculate_decay_widths [OPTIONS]',
1292 'help generate_events'],
1293 'generate_events': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]', 'pythia', 'pgs','delphes'],
1294 'calculate_decay_widths': ['calculate_decay_widths [OPTIONS]',
1295 'generate_events [OPTIONS]'],
1296 'multi_run': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]'],
1297 'survey': ['refine'],
1298 'refine': ['combine_events'],
1299 'combine_events': ['store'],
1300 'store': ['pythia'],
1301 'pythia': ['pgs', 'delphes'],
1302 'pgs': ['generate_events [OPTIONS]', 'multi_run [OPTIONS]'],
1303 'delphes' : ['generate_events [OPTIONS]', 'multi_run [OPTIONS]']
1304 }
1305
1306
1307
1308
1309 - def __init__(self, me_dir = None, *completekey, **stdin):
1310 """ add information to the cmd """
1311
1312 CmdExtended.__init__(self, *completekey, **stdin)
1313
1314
1315 if me_dir is None and MADEVENT:
1316 me_dir = root_path
1317
1318 self.me_dir = me_dir
1319
1320
1321 self.status = pjoin(self.me_dir, 'status')
1322 self.error = pjoin(self.me_dir, 'error')
1323 self.dirbin = pjoin(self.me_dir, 'bin', 'internal')
1324
1325
1326 if os.path.exists(pjoin(me_dir,'RunWeb')):
1327 message = '''Another instance of madevent is currently running.
1328 Please wait that all instance of madevent are closed. If no
1329 instance is running, you can delete the file
1330 %s and try again.''' % pjoin(me_dir,'RunWeb')
1331 raise MadEventAlreadyRunning, message
1332 else:
1333 os.system('touch %s' % pjoin(me_dir,'RunWeb'))
1334 misc.Popen([pjoin(self.dirbin, 'gen_cardhtml-pl')], cwd=me_dir)
1335
1336 self.to_store = []
1337 self.run_name = None
1338 self.run_tag = None
1339 self.banner = None
1340
1341
1342 try:
1343 nexternal = open(pjoin(me_dir,'Source','nexternal.inc')).read()
1344 found = re.search("PARAMETER\s*\(NINCOMING=(\d)\)", nexternal)
1345 self.ninitial = int(found.group(1))
1346 except:
1347
1348
1349 self.ninitial = 2
1350
1351
1352 self.set_configuration()
1353 self.nb_refine=0
1354 if self.web:
1355 os.system('touch %s' % pjoin(self.me_dir,'Online'))
1356
1357
1358
1359 if os.path.exists(pjoin(self.me_dir,'HTML','results.pkl')):
1360 self.results = save_load_object.load_from_file(pjoin(self.me_dir,'HTML','results.pkl'))
1361 self.results.resetall(self.me_dir)
1362 else:
1363 model = self.find_model_name()
1364 process = self.process
1365 self.results = gen_crossxhtml.AllResults(model, process, self.me_dir)
1366 self.results.def_web_mode(self.web)
1367
1368 self.configured = 0
1369 self._options = {}
1370
1371
1373 """split argument and remove run_options"""
1374
1375 args = CmdExtended.split_arg(line)
1376
1377 for arg in args[:]:
1378 if not arg.startswith('-'):
1379 continue
1380 elif arg == '-c':
1381 self.cluster_mode = 1
1382 elif arg == '-m':
1383 self.cluster_mode = 2
1384 elif arg == '-f':
1385 self.force = True
1386 elif not arg.startswith('--'):
1387 if error:
1388 raise self.InvalidCmd('%s argument cannot start with - symbol' % arg)
1389 else:
1390 continue
1391 elif arg.startswith('--cluster'):
1392 self.cluster_mode = 1
1393 elif arg.startswith('--multicore'):
1394 self.cluster_mode = 2
1395 elif arg.startswith('--nb_core'):
1396 self.cluster_mode = 2
1397 self.nb_core = int(arg.split('=',1)[1])
1398 elif arg.startswith('--web'):
1399 self.web = True
1400 self.cluster_mode = 1
1401 self.results.def_web_mode(True)
1402 self.force = True
1403 else:
1404 continue
1405 args.remove(arg)
1406
1407 if self.cluster_mode == 2 and not self.nb_core:
1408 import multiprocessing
1409 self.nb_core = multiprocessing.cpu_count()
1410
1411 if self.cluster_mode == 1 and not hasattr(self, 'cluster'):
1412 cluster_name = self.options['cluster_type']
1413 self.cluster = cluster.from_name[cluster_name](self.options['cluster_queue'])
1414 return args
1415
1416
1418 """ Check that the output path is a valid madevent directory """
1419
1420 bin_path = os.path.join(path,'bin')
1421 if os.path.isfile(os.path.join(bin_path,'generate_events')):
1422 return True
1423 else:
1424 return False
1425
1426
1428 """ assign all configuration variable from file
1429 ./Cards/mg5_configuration.txt. assign to default if not define """
1430
1431 self.options = {'pythia8_path': './pythia8',
1432 'pythia-pgs_path': '../pythia-pgs',
1433 'delphes_path': '../Delphes',
1434 'madanalysis_path': '../MadAnalysis',
1435 'exrootanalysis_path': '../ExRootAnalysis',
1436 'td_path': '../',
1437 'web_browser':None,
1438 'eps_viewer':None,
1439 'text_editor':None,
1440 'fortran_compiler':None,
1441 'cluster_mode':'pbs',
1442 'automatic_html_opening':True,
1443 'run_mode':0,
1444 'cluster_queue':'madgraph',
1445 'nb_core':None,
1446 'timeout':20}
1447
1448 if os.environ.has_key('MADGRAPH_BASE'):
1449 config_file = open(os.path.join(os.environ['MADGRAPH_BASE'],'mg5_configuration.txt'))
1450 elif not config_path:
1451 try:
1452 config_file = open(os.path.join(os.environ['HOME'],'.mg5','mg5_configuration.txt'))
1453 except:
1454 if self.me_dir:
1455 config_file = open(os.path.relpath(
1456 os.path.join(self.me_dir, 'Cards', 'me5_configuration.txt')))
1457 main = self.me_dir
1458 elif not MADEVENT:
1459 config_file = open(os.path.relpath(
1460 os.path.join(MG5DIR, 'input', 'mg5_configuration.txt')))
1461 main = MG5DIR
1462 else:
1463 config_file = open(config_path)
1464 if self.me_dir:
1465 main = self.me_dir
1466 else:
1467 main = MG5DIR
1468
1469
1470 logger.info('load configuration from %s ' % config_file.name)
1471 for line in config_file:
1472 if '#' in line:
1473 line = line.split('#',1)[0]
1474 line = line.replace('\n','').replace('\r\n','')
1475 try:
1476 name, value = line.split('=')
1477 except ValueError:
1478 pass
1479 else:
1480 name = name.strip()
1481 value = value.strip()
1482 self.options[name] = value
1483 if value.lower() == "none":
1484 self.options[name] = None
1485
1486
1487
1488 for key in self.options:
1489 if key.endswith('path'):
1490 if self.options[key] in ['None', None]:
1491 self.options[key] = ''
1492 continue
1493 path = os.path.join(self.me_dir, self.options[key])
1494 if os.path.isdir(path):
1495 self.options[key] = os.path.realpath(path)
1496 continue
1497 if os.path.isdir(self.options[key]):
1498 self.options[key] = os.path.realpath(self.options[key])
1499 continue
1500 elif not os.path.isdir(self.options[key]):
1501 self.options[key] = ''
1502 elif key.startswith('cluster'):
1503 pass
1504 elif key == 'automatic_html_opening':
1505 if self.options[key] in ['False', 'True']:
1506 self.options[key] =eval(self.options[key])
1507 elif key not in ['text_editor','eps_viewer','web_browser']:
1508
1509 try:
1510 self.do_set("%s %s" % (key, self.options[key]))
1511 except self.InvalidCmd:
1512 logger.warning("Option %s from config file not understood" \
1513 % key)
1514
1515
1516 misc.open_file.configure(self.options)
1517
1518 return self.options
1519
1520
1522 """Make a run from the banner file"""
1523
1524 args = self.split_arg(line)
1525
1526 self.check_banner_run(args)
1527
1528 banner_mod.split_banner(args[0], self.me_dir, proc_card=False)
1529
1530
1531 for name in ['delphes_trigger.dat', 'delphes_card.dat',
1532 'pgs_card.dat', 'pythia_card.dat']:
1533 try:
1534 os.remove(pjoin(self.me_dir, 'Cards', name))
1535 except:
1536 pass
1537
1538
1539
1540 if not self.force:
1541 ans = self.ask('Do you want to modify the Cards?', 'n', ['y','n'])
1542 if ans == 'n':
1543 self.force = True
1544
1545
1546 self.exec_cmd('generate_events %s %s' % (self.run_name, self.force and '-f' or ''))
1547
1548
1549
1550
1552 """Display current internal status"""
1553
1554 args = self.split_arg(line)
1555
1556 self.check_display(args)
1557
1558 if args[0] == 'run_name':
1559
1560 data = glob.glob(pjoin(self.me_dir, 'Events', '*','*_banner.txt'))
1561 data = [n.rsplit('/',2)[1:] for n in data]
1562
1563 if data:
1564 out = {}
1565 for name, tag in data:
1566 tag = tag[len(name)+1:-11]
1567 if name in out:
1568 out[name].append(tag)
1569 else:
1570 out[name] = [tag]
1571 print 'the runs available are:'
1572 for run_name, tags in out.items():
1573 print ' run: %s' % run_name
1574 print ' tags: ',
1575 print ', '.join(tags)
1576 else:
1577 print 'No run detected.'
1578 else:
1579 super(MadEventCmd, self).do_display(line, output)
1580
1581
1582
1594
1595
1597 """Open a text file/ eps file / html file"""
1598
1599 args = self.split_arg(line)
1600
1601 self.check_open(args)
1602 file_path = args[0]
1603
1604 misc.open_file(file_path)
1605
1606
1608 """Set an option, which will be default for coming generations/outputs
1609 """
1610
1611 args = self.split_arg(line)
1612
1613 self.check_set(args)
1614
1615 if args[0] == "stdout_level":
1616 logging.root.setLevel(eval('logging.' + args[1]))
1617 logging.getLogger('madgraph').setLevel(eval('logging.' + args[1]))
1618 logger.info('set output information to level: %s' % args[1])
1619 elif args[0] == "fortran_compiler":
1620 self.options['fortran_compiler'] = args[1]
1621 elif args[0] == "run_mode":
1622 if not args[1] in [0,1,2,'0','1','2']:
1623 raise self.InvalidCmd, 'run_mode should be 0, 1 or 2.'
1624 self.cluster_mode = int(args[1])
1625 self.options['cluster_mode'] = self.cluster_mode
1626 elif args[0] == 'cluster_type':
1627 self.options['cluster_mode'] = args[1]
1628 self.cluster = cluster.from_name[args[1]](self.options['cluster_queue'])
1629 elif args[0] == 'nb_core':
1630 if args[1] == 'None':
1631 import multiprocessing
1632 self.nb_core = multiprocessing.cpu_count()
1633 self.options['nb_core'] = self.nb_core
1634 return
1635 if not args[1].isdigit():
1636 raise self.InvalidCmd('nb_core should be a positive number')
1637 self.nb_core = int(args[1])
1638 self.options['nb_core'] = self.nb_core
1639 elif args[0] == 'timeout':
1640 self.options[args[0]] = int(args[1])
1641 elif args[0] in self.options:
1642 if args[1] in ['None','True','False']:
1643 self.options[args[0]] = eval(args[1])
1644 elif args[0].endswith('path'):
1645 if os.path.exists(args[1]):
1646 self.options[args[0]] = args[1]
1647 elif os.path.exists(pjoin(self.me_dir, args[1])):
1648 self.options[args[0]] = pjoin(self.me_dir, args[1])
1649 else:
1650 raise self.InvalidCmd('Not a valid path: keep previous value: \'%s\'' % self.options[args[0]])
1651 else:
1652 self.options[args[0]] = args[1]
1653
1654
1655
1656 - def update_status(self, status, level, makehtml=True, force=True, error=False):
1657 """ update the index status """
1658
1659
1660 if makehtml and not force:
1661 if hasattr(self, 'next_update') and time.time() < self.next_update:
1662 return
1663 else:
1664 self.next_update = time.time() + 3
1665
1666
1667 if isinstance(status, str):
1668 if '<br>' not in status:
1669 logger.info(status)
1670 else:
1671 logger.info(' Idle: %s Running: %s Finish: %s' % status[:3])
1672
1673 self.last_update = time
1674 self.results.update(status, level, makehtml=makehtml, error=error)
1675
1676
1678 """ launch the full chain """
1679
1680 args = self.split_arg(line)
1681
1682 mode = self.check_generate_events(args)
1683 self.ask_run_configuration(mode)
1684 if not args:
1685
1686 self.set_run_name(self.find_available_run_name(self.me_dir), None, 'parton')
1687 else:
1688 self.set_run_name(args[0], None, 'parton', True)
1689 args.pop(0)
1690
1691 if self.run_card['gridpack'] in self.true:
1692
1693 gridpack_opts=[('accuracy', 0.01),
1694 ('points', 2000),
1695 ('iterations',8),
1696 ('gridpack','.true.')]
1697 logger.info('Generating gridpack with run name %s' % self.run_name)
1698 self.exec_cmd('survey %s %s' % \
1699 (self.run_name,
1700 " ".join(['--' + opt + '=' + str(val) for (opt,val) \
1701 in gridpack_opts])),
1702 postcmd=False)
1703 self.exec_cmd('combine_events', postcmd=False)
1704 self.exec_cmd('store_events', postcmd=False)
1705 self.exec_cmd('create_gridpack', postcmd=False)
1706 else:
1707
1708 logger.info('Generating %s events with run name %s' %
1709 (self.run_card['nevents'], self.run_name))
1710
1711 self.exec_cmd('survey %s %s' % (self.run_name,' '.join(args)),
1712 postcmd=False)
1713 if not float(self.results.current['cross']):
1714
1715 raise MadGraph5Error('''Survey return zero cross section.
1716 Typical reasons are the following:
1717 1) A massive s-channel particle has a width set to zero.
1718 2) The pdf are zero for at least one of the initial state particles.
1719 3) The cuts are too strong.
1720 Please check/correct your param_card and/or your run_card.''')
1721
1722 nb_event = self.run_card['nevents']
1723 self.exec_cmd('refine %s' % nb_event, postcmd=False)
1724 self.exec_cmd('refine %s' % nb_event, postcmd=False)
1725 self.exec_cmd('combine_events', postcmd=False)
1726 self.print_results_in_shell(self.results.current)
1727 self.create_plot('parton')
1728 self.exec_cmd('store_events', postcmd=False)
1729 self.exec_cmd('pythia --no_default', postcmd=False, printcmd=False)
1730
1731 self.store_result()
1732
1733
1734
1736 """Have a nice results prints in the shell,
1737 data should be of type: gen_crossxhtml.OneTagResults"""
1738
1739 logger.info(" === Results Summary for run: %s tag: %s ===\n" % (data['run_name'],data['tag']))
1740 if self.ninitial == 1:
1741 logger.info(" Width : %.4g +- %.4g GeV" % (data['cross'], data['error']))
1742 else:
1743 logger.info(" Cross-section : %.4g +- %.4g pb" % (data['cross'], data['error']))
1744 logger.info(" Nb of events : %s" % data['nb_event'] )
1745 if data['cross_pythia'] and data['nb_event_pythia']:
1746 if self.ninitial == 1:
1747 logger.info(" Matched Width : %.4g +- %.4g GeV" % (data['cross_pythia'], data['error_pythia']))
1748 else:
1749 logger.info(" Matched Cross-section : %.4g +- %.4g pb" % (data['cross_pythia'], data['error_pythia']))
1750 logger.info(" Nb of events after Matching : %s" % data['nb_event_pythia'])
1751 logger.info(" " )
1752
1753
1755 """ launch decay width calculation and automatic inclusion of
1756 calculated widths and BRs in the param_card."""
1757
1758 args = self.split_arg(line)
1759
1760 accuracy = self.check_calculate_decay_widths(args)
1761 self.ask_run_configuration('parton')
1762 if not args:
1763
1764 self.set_run_name(self.find_available_run_name(self.me_dir))
1765 else:
1766 self.set_run_name(args[0], reload_card=True)
1767 args.pop(0)
1768
1769
1770 opts=[('accuracy', accuracy),
1771 ('points', 1000),
1772 ('iterations',9)]
1773
1774 logger.info('Calculating decay widths with run name %s' % self.run_name)
1775
1776 self.exec_cmd('survey %s %s' % \
1777 (self.run_name,
1778 " ".join(['--' + opt + '=' + str(val) for (opt,val) \
1779 in opts])),
1780 postcmd=False)
1781 self.exec_cmd('combine_events', postcmd=False)
1782 self.exec_cmd('store_events', postcmd=False)
1783
1784 self.collect_decay_widths()
1785 self.update_status('calculate_decay_widths done',
1786 level='parton', makehtml=False)
1787
1788
1789
1791 """ Collect the decay widths and calculate BRs for all particles, and put
1792 in param_card form.
1793 """
1794
1795 particle_dict = {}
1796 run_name = self.run_name
1797
1798
1799 for P_path in SubProcesses.get_subP(self.me_dir):
1800 ids = SubProcesses.get_subP_ids(P_path)
1801
1802
1803
1804 nb_output = len(ids) / (len(set([p[0] for p in ids])))
1805 results = open(pjoin(P_path, run_name + '_results.dat')).read().split('\n')[0]
1806 result = float(results.strip().split(' ')[0])
1807 for particles in ids:
1808 try:
1809 particle_dict[particles[0]].append([particles[1:], result/nb_output])
1810 except KeyError:
1811 particle_dict[particles[0]] = [[particles[1:], result/nb_output]]
1812
1813
1814 param_card_file = open(pjoin(self.me_dir, 'Cards', 'param_card.dat'))
1815 param_card = param_card_file.read().split('\n')
1816 param_card_file.close()
1817
1818 decay_lines = []
1819 line_number = 0
1820
1821 while line_number < len(param_card):
1822 line = param_card[line_number]
1823 if line.lower().startswith('decay'):
1824
1825
1826 line = param_card.pop(line_number)
1827 line = line.split()
1828 particle = 0
1829 if int(line[1]) not in particle_dict:
1830 try:
1831 particle = int(line[1])
1832 width = float(line[2])
1833 except:
1834 particle = 0
1835
1836 line = param_card[line_number]
1837 while line.startswith('#') or line.startswith(' '):
1838 line = param_card.pop(line_number)
1839 if not particle or line.startswith('#'):
1840 line=param_card[line_number]
1841 continue
1842
1843 line = line.split()
1844 try:
1845 partial_width = float(line[0])*width
1846 decay_products = [int(p) for p in line[2:2+int(line[1])]]
1847 except:
1848 line=param_card[line_number]
1849 continue
1850 try:
1851 particle_dict[particle].append([decay_products, partial_width])
1852 except KeyError:
1853 particle_dict[particle] = [[decay_products, partial_width]]
1854 line=param_card[line_number]
1855 if particle and particle not in particle_dict:
1856
1857 particle_dict[particle] = [[[], width]]
1858 else:
1859 line_number += 1
1860
1861 while not param_card[-1] or param_card[-1].startswith('#'):
1862 param_card.pop(-1)
1863
1864
1865 param_card.append("#\n#*************************")
1866 param_card.append("# Decay widths *")
1867 param_card.append("#*************************")
1868 for key in sorted(particle_dict.keys()):
1869 width = sum([r for p,r in particle_dict[key]])
1870 param_card.append("#\n# PDG Width")
1871 param_card.append("DECAY %i %e" % (key, width))
1872 if not width:
1873 continue
1874 if particle_dict[key][0][0]:
1875 param_card.append("# BR NDA ID1 ID2 ...")
1876 brs = [[val[1]/width, val[0]] for val in particle_dict[key] if val[1]]
1877 for val in sorted(brs, reverse=True):
1878 param_card.append(" %e %i %s" % (val[0], len(val[1]),
1879 " ".join([str(v) for v in val[1]])))
1880 output_name = pjoin(self.me_dir, 'Events', run_name, "param_card.dat")
1881 decay_table = open(output_name, 'w')
1882 decay_table.write("\n".join(param_card) + "\n")
1883 logger.info("Results written to %s" % output_name)
1884
1885
1886
1887
1888
1889
1890
1891
1893
1894 args = self.split_arg(line)
1895
1896 mode = self.check_multi_run(args)
1897 nb_run = args.pop(0)
1898 if nb_run == 1:
1899 logger.warn("'multi_run 1' command is not optimal. Think of using generate_events instead")
1900 self.ask_run_configuration(mode)
1901 main_name = self.run_name
1902
1903
1904
1905
1906
1907 crossoversig = 0
1908 inv_sq_err = 0
1909 nb_event = 0
1910 for i in range(nb_run):
1911 self.exec_cmd('generate_events %s_%s -f' % (main_name, i), postcmd=False)
1912
1913 nb_event += int(self.results[self.run_name][-1]['nb_event'])
1914 self.results.add_detail('nb_event', nb_event , run=main_name)
1915 cross = self.results[self.run_name][-1]['cross']
1916 error = self.results[self.run_name][-1]['error'] + 1e-99
1917 crossoversig+=cross/error**2
1918 inv_sq_err+=1.0/error**2
1919 self.results[main_name][-1]['cross'] = crossoversig/inv_sq_err
1920 self.results[main_name][-1]['error'] = math.sqrt(1.0/inv_sq_err)
1921 self.results.def_current(main_name)
1922 self.run_name = main_name
1923 self.update_status("Merging LHE files", level='parton')
1924 try:
1925 os.mkdir(pjoin(self.me_dir,'Events', self.run_name))
1926 except:
1927 pass
1928 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'
1929 % {'bin': self.dirbin, 'event': pjoin(self.me_dir,'Events'),
1930 'name': self.run_name})
1931
1932 eradir = self.options['exrootanalysis_path']
1933 if eradir and misc.is_executable(pjoin(eradir,'ExRootLHEFConverter')):
1934 self.update_status("Create Root file", level='parton')
1935 os.system('gunzip %s/%s/unweighted_events.lhe.gz' %
1936 (pjoin(self.me_dir,'Events'), self.run_name))
1937 self.create_root_file('%s/unweighted_events.lhe' % self.run_name,
1938 '%s/unweighted_events.root' % self.run_name)
1939
1940
1941 self.create_plot('parton', '%s/%s/unweighted_events.lhe' %
1942 (pjoin(self.me_dir, 'Events'),self.run_name),
1943 pjoin(self.me_dir, 'HTML',self.run_name, 'plots_parton.html')
1944 )
1945
1946 os.system('gzip -f %s/%s/unweighted_events.lhe' %
1947 (pjoin(self.me_dir, 'Events'), self.run_name))
1948
1949 self.update_status('', level='parton')
1950 self.print_results_in_shell(self.results.current)
1951 self.results.def_current(None)
1952
1953
1955 """Advanced commands: launch survey for the current process """
1956
1957 args = self.split_arg(line)
1958
1959 self.check_survey(args)
1960
1961
1962 if os.path.exists(pjoin(self.me_dir,'error')):
1963 os.remove(pjoin(self.me_dir,'error'))
1964
1965 self.configure_directory()
1966
1967 self.random_orig = self.random
1968 logger.info("Using random number seed offset = %s" % self.random)
1969
1970 self.update_random()
1971 self.save_random()
1972 self.update_status('Running Survey', level=None)
1973 if self.cluster_mode:
1974 logger.info('Creating Jobs')
1975
1976 logger.info('Working on SubProcesses')
1977 self.total_jobs = 0
1978 subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses',
1979 'subproc.mg'))]
1980 for nb_proc,subdir in enumerate(subproc):
1981 subdir = subdir.strip()
1982 Pdir = pjoin(self.me_dir, 'SubProcesses',subdir)
1983 logger.info(' %s ' % subdir)
1984
1985 for match in glob.glob(pjoin(Pdir, '*ajob*')):
1986 if os.path.basename(match)[:4] in ['ajob', 'wait', 'run.', 'done']:
1987 os.remove(pjoin(Pdir, match))
1988
1989
1990 misc.compile(['gensym'], cwd=Pdir)
1991 if not os.path.exists(pjoin(Pdir, 'gensym')):
1992 raise MadEventError, 'Error make gensym not successful'
1993
1994
1995 p = misc.Popen(['./gensym'], stdin=subprocess.PIPE,
1996 stdout=subprocess.PIPE,
1997 stderr=subprocess.STDOUT, cwd=Pdir)
1998 sym_input = "%(points)d %(iterations)d %(accuracy)f %(gridpack)s\n" % self.opts
1999 (stdout, stderr) = p.communicate(sym_input)
2000 if not os.path.exists(pjoin(Pdir, 'ajob1')) or p.returncode:
2001 logger.critical(stdout)
2002 raise MadEventError, 'Error gensym run not successful'
2003
2004 os.system("chmod +x %s/ajob*" % Pdir)
2005
2006 misc.compile(['madevent'], cwd=Pdir)
2007
2008 alljobs = glob.glob(pjoin(Pdir,'ajob*'))
2009 self.total_jobs += len(alljobs)
2010 for i, job in enumerate(alljobs):
2011 job = os.path.basename(job)
2012 self.launch_job('./%s' % job, cwd=Pdir, remaining=(len(alljobs)-i-1),
2013 run_type='survey on %s (%s/%s)' % (subdir,nb_proc+1,len(subproc)))
2014 if os.path.exists(pjoin(self.me_dir,'error')):
2015 self.monitor(html=True)
2016 raise MadEventError, 'Error detected Stop running: %s' % \
2017 open(pjoin(self.me_dir,'error')).read()
2018
2019
2020 self.monitor(run_type='All jobs submitted for survey', html=True)
2021 cross, error = sum_html.make_all_html_results(self)
2022 self.results.add_detail('cross', cross)
2023 self.results.add_detail('error', error)
2024 self.update_status('End survey', 'parton', makehtml=False)
2025
2026
2028 """Advanced commands: launch survey for the current process """
2029 self.nb_refine += 1
2030 args = self.split_arg(line)
2031
2032 self.check_refine(args)
2033
2034 precision = args[0]
2035 if len(args) == 2:
2036 max_process = args[1]
2037 else:
2038 max_process = 5
2039
2040
2041 self.configure_directory()
2042
2043
2044 self.update_random()
2045 self.save_random()
2046
2047 if self.cluster_mode:
2048 logger.info('Creating Jobs')
2049 self.update_status('Refine results to %s' % precision, level=None)
2050
2051 self.total_jobs = 0
2052 subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses',
2053 'subproc.mg'))]
2054 devnull = os.open(os.devnull, os.O_RDWR)
2055 for nb_proc,subdir in enumerate(subproc):
2056 subdir = subdir.strip()
2057 Pdir = pjoin(self.me_dir, 'SubProcesses',subdir)
2058 bindir = pjoin(os.path.relpath(self.dirbin, Pdir))
2059
2060 logger.info(' %s ' % subdir)
2061
2062 for match in glob.glob(pjoin(Pdir, '*ajob*')):
2063 if os.path.basename(match)[:4] in ['ajob', 'wait', 'run.', 'done']:
2064 os.remove(pjoin(Pdir, match))
2065
2066 proc = misc.Popen([pjoin(bindir, 'gen_ximprove')],
2067 stdout=devnull,
2068 stdin=subprocess.PIPE,
2069 cwd=Pdir)
2070 proc.communicate('%s %s T\n' % (precision, max_process))
2071
2072 if os.path.exists(pjoin(Pdir, 'ajob1')):
2073 misc.compile(['madevent'], cwd=Pdir)
2074
2075 os.system("chmod +x %s/ajob*" % Pdir)
2076 alljobs = glob.glob(pjoin(Pdir,'ajob*'))
2077 nb_tot = len(alljobs)
2078 self.total_jobs += nb_tot
2079 for i, job in enumerate(alljobs):
2080 job = os.path.basename(job)
2081 self.launch_job('./%s' % job, cwd=Pdir, remaining=(nb_tot-i-1),
2082 run_type='Refine number %s on %s (%s/%s)' %
2083 (self.nb_refine, subdir, nb_proc+1, len(subproc)))
2084 self.monitor(run_type='All job submitted for refine number %s' % self.nb_refine,
2085 html=True)
2086
2087 self.update_status("Combining runs", level='parton')
2088 try:
2089 os.remove(pjoin(Pdir, 'combine_runs.log'))
2090 except:
2091 pass
2092
2093 bindir = pjoin(os.path.relpath(self.dirbin, pjoin(self.me_dir,'SubProcesses')))
2094 misc.call([pjoin(bindir, 'combine_runs')],
2095 cwd=pjoin(self.me_dir,'SubProcesses'),
2096 stdout=devnull)
2097
2098 cross, error = sum_html.make_all_html_results(self)
2099 self.results.add_detail('cross', cross)
2100 self.results.add_detail('error', error)
2101
2102 self.update_status('finish refine', 'parton', makehtml=False)
2103
2104
2106 """Advanced commands: Launch combine events"""
2107
2108 args = self.split_arg(line)
2109
2110 self.check_combine_events(args)
2111
2112 self.update_status('Combining Events', level='parton')
2113 try:
2114 os.remove(pjoin(self.me_dir,'SubProcesses', 'combine.log'))
2115 except:
2116 pass
2117 if self.cluster_mode == 1:
2118 out = self.cluster.launch_and_wait('../bin/internal/run_combine',
2119 cwd=pjoin(self.me_dir,'SubProcesses'),
2120 stdout=pjoin(self.me_dir,'SubProcesses', 'combine.log'))
2121 else:
2122 out = misc.call(['../bin/internal/run_combine'],
2123 cwd=pjoin(self.me_dir,'SubProcesses'),
2124 stdout=open(pjoin(self.me_dir,'SubProcesses','combine.log'),'w'))
2125
2126 output = open(pjoin(self.me_dir,'SubProcesses','combine.log')).read()
2127
2128 pat = re.compile(r'''\s*Unweighting selected\s*(\d+)\s*events''',re.MULTILINE)
2129 if output:
2130 nb_event = pat.search(output).groups()[0]
2131 self.results.add_detail('nb_event', nb_event)
2132
2133
2134 tag = self.run_card['run_tag']
2135
2136 if not self.banner:
2137 self.banner = banner_mod.recover_banner(self.results, 'parton')
2138 self.banner.load_basic(self.me_dir)
2139
2140 self.banner.add_generation_info(self.results.current['cross'], nb_event)
2141 if not hasattr(self, 'random_orig'): self.random_orig = 0
2142 self.banner.change_seed(self.random_orig)
2143 if not os.path.exists(pjoin(self.me_dir, 'Events', self.run_name)):
2144 os.mkdir(pjoin(self.me_dir, 'Events', self.run_name))
2145 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name,
2146 '%s_%s_banner.txt' % (self.run_name, tag)))
2147 self.banner.add(pjoin(self.me_dir, 'Cards', 'param_card.dat'))
2148 self.banner.add(pjoin(self.me_dir, 'Cards', 'run_card.dat'))
2149
2150
2151 misc.call(['%s/put_banner' % self.dirbin, 'events.lhe'],
2152 cwd=pjoin(self.me_dir, 'Events'))
2153 misc.call(['%s/put_banner'% self.dirbin, 'unweighted_events.lhe'],
2154 cwd=pjoin(self.me_dir, 'Events'))
2155
2156 eradir = self.options['exrootanalysis_path']
2157 madir = self.options['madanalysis_path']
2158 td = self.options['td_path']
2159 if eradir and misc.is_executable(pjoin(eradir,'ExRootLHEFConverter')) and\
2160 os.path.exists(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe')):
2161 if not os.path.exists(pjoin(self.me_dir, 'Events', self.run_name)):
2162 os.mkdir(pjoin(self.me_dir, 'Events', self.run_name))
2163 self.create_root_file(output='%s/unweighted_events.root' % self.run_name)
2164
2165
2167 """Advanced commands: Launch store events"""
2168
2169 args = self.split_arg(line)
2170
2171 self.check_combine_events(args)
2172 self.update_status('Storing parton level results', level='parton')
2173
2174 run = self.run_name
2175 tag = self.run_card['run_tag']
2176 devnull = os.open(os.devnull, os.O_RDWR)
2177
2178 if not os.path.exists(pjoin(self.me_dir, 'Events', run)):
2179 os.mkdir(pjoin(self.me_dir, 'Events', run))
2180 if not os.path.exists(pjoin(self.me_dir, 'HTML', run)):
2181 os.mkdir(pjoin(self.me_dir, 'HTML', run))
2182
2183
2184 for P_path in SubProcesses.get_subP(self.me_dir):
2185 G_dir = [G for G in os.listdir(P_path) if G.startswith('G') and
2186 os.path.isdir(pjoin(P_path,G))]
2187 for G in G_dir:
2188 G_path = pjoin(P_path,G)
2189
2190 if os.path.exists(pjoin(G_path, 'events.lhe')):
2191 os.remove(pjoin(G_path, 'events.lhe'))
2192
2193 if self.run_card['gridpack'] not in self.true:
2194 if os.path.exists(pjoin(G_path, 'results.dat')):
2195 os.remove(pjoin(G_path, 'results.dat'))
2196
2197 if os.path.exists(pjoin(G_path, 'log.txt')):
2198 input = pjoin(G_path, 'log.txt')
2199 output = pjoin(G_path, '%s_log.txt' % run)
2200 files.mv(input, output)
2201
2202 for name in ['ftn26']:
2203 if os.path.exists(pjoin(G_path, name)):
2204 if os.path.exists(pjoin(G_path, '%s_%s.gz'%(run,name))):
2205 os.remove(pjoin(G_path, '%s_%s.gz'%(run,name)))
2206 input = pjoin(G_path, name)
2207 output = pjoin(G_path, '%s_%s' % (run,name))
2208 files.mv(input, output)
2209 misc.call(['gzip', output], stdout=devnull,
2210 stderr=devnull, cwd=G_path)
2211
2212
2213 if not self.web:
2214 results = pjoin(self.me_dir, 'HTML', run, 'results.html')
2215 text = open(results).read()
2216 text = text.replace('''if ( ! UrlExists(alt)){
2217 obj.href = alt;''','''if ( ! UrlExists(alt)){
2218 obj.href = url;''')
2219 open(results, 'w').write(text)
2220
2221
2222 misc.call(['%s/gen_cardhtml-pl' % self.dirbin],
2223 cwd=pjoin(self.me_dir))
2224
2225
2226 E_path = pjoin(self.me_dir, 'Events')
2227 O_path = pjoin(self.me_dir, 'Events', run)
2228
2229 for name in ['events.lhe', 'unweighted_events.lhe']:
2230 if os.path.exists(pjoin(E_path, name)):
2231 if os.path.exists(pjoin(O_path, '%s.gz' % name)):
2232 os.remove(pjoin(O_path, '%s.gz' % name))
2233 input = pjoin(E_path, name)
2234 output = pjoin(O_path, name)
2235 files.mv(input, output)
2236 misc.call(['gzip', output], stdout=devnull, stderr=devnull,
2237 cwd=O_path)
2238 self.update_status('End Parton', level='parton', makehtml=False)
2239
2240
2242 """Advanced commands: Create gridpack from present run"""
2243
2244 self.update_status('Creating gridpack', level='parton')
2245 args = self.split_arg(line)
2246 self.check_combine_events(args)
2247 if not self.run_tag: self.run_tag = 'tag_1'
2248 os.system("sed -i.bak \"s/ *.false.*=.*GridRun/ .true. = GridRun/g\" %s/Cards/grid_card.dat" \
2249 % self.me_dir)
2250 misc.call(['./bin/internal/restore_data', self.run_name],
2251 cwd=self.me_dir)
2252 misc.call(['./bin/internal/store4grid',
2253 self.run_name, self.run_tag],
2254 cwd=self.me_dir)
2255 misc.call(['./bin/internal/clean'], cwd=self.me_dir)
2256 misc.call(['./bin/internal/make_gridpack'], cwd=self.me_dir)
2257 files.mv(pjoin(self.me_dir, 'gridpack.tar.gz'),
2258 pjoin(self.me_dir, '%s_gridpack.tar.gz' % self.run_name))
2259 os.system("sed -i.bak \"s/\s*.true.*=.*GridRun/ .false. = GridRun/g\" %s/Cards/grid_card.dat" \
2260 % self.me_dir)
2261 self.update_status('gridpack created', level='gridpack')
2262
2263
2265 """launch pythia"""
2266
2267
2268 args = self.split_arg(line)
2269 if '--no_default' in args:
2270 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pythia_card.dat')):
2271 return
2272 no_default = True
2273 args.remove('--no_default')
2274 else:
2275 no_default = False
2276
2277 self.check_pythia(args)
2278
2279 if not no_default:
2280 self.ask_pythia_run_configuration(args[-1])
2281
2282
2283 if not self.banner:
2284 self.banner = banner_mod.recover_banner(self.results, 'pythia')
2285
2286
2287 self.configure_directory()
2288
2289 pythia_src = pjoin(self.options['pythia-pgs_path'],'src')
2290
2291 self.update_status('Running Pythia', 'pythia')
2292 try:
2293 os.remove(pjoin(self.me_dir,'Events','pythia.done'))
2294 except:
2295 pass
2296
2297
2298 tag = self.run_tag
2299
2300 if self.cluster_mode == 1:
2301 pythia_log = pjoin(self.me_dir, 'Events', self.run_name , '%s_pythia.log' % tag)
2302 self.cluster.launch_and_wait('../bin/internal/run_pythia',
2303 argument= [pythia_src], stdout= pythia_log,
2304 stderr=subprocess.STDOUT,
2305 cwd=pjoin(self.me_dir,'Events'))
2306 else:
2307 pythia_log = open(pjoin(self.me_dir, 'Events', self.run_name , '%s_pythia.log' % tag), 'w')
2308 misc.call(['../bin/internal/run_pythia', pythia_src],
2309 stdout=pythia_log,
2310 stderr=subprocess.STDOUT,
2311 cwd=pjoin(self.me_dir,'Events'))
2312
2313 if not os.path.exists(pjoin(self.me_dir,'Events','pythia.done')):
2314 if self.cluster_mode == 1:
2315 logger.warning('Fail to produce pythia output. More info in \n %s' % pythia_log)
2316 else:
2317 logger.warning('Fail to produce pythia output. More info in \n %s' % pythia_log.name)
2318 return
2319 else:
2320 os.remove(pjoin(self.me_dir,'Events','pythia.done'))
2321
2322 self.to_store.append('pythia')
2323
2324
2325 if int(self.run_card['ickkw']):
2326
2327 pythia_log = misc.BackRead(pjoin(self.me_dir,'Events', self.run_name,
2328 '%s_pythia.log' % tag))
2329 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")
2330 for line in pythia_log:
2331 info = pythiare.search(line)
2332 if not info:
2333 continue
2334 try:
2335
2336 sigma_m = float(info.group('xsec').replace('D','E')) *1e9
2337 Nacc = int(info.group('generated'))
2338 Ntry = int(info.group('tried'))
2339 except ValueError:
2340
2341 self.results.add_detail('cross_pythia', 0)
2342 self.results.add_detail('nb_event_pythia', 0)
2343 self.results.add_detail('error_pythia', 0)
2344 else:
2345 self.results.add_detail('cross_pythia', sigma_m)
2346 self.results.add_detail('nb_event_pythia', Nacc)
2347
2348 error = self.results[self.run_name].return_tag(self.run_tag)['error']
2349 error_m = math.sqrt((error * Nacc/Ntry)**2 + sigma_m**2 *(1-Nacc/Ntry)/Nacc)
2350
2351 self.results.add_detail('error_pythia', error_m)
2352 break
2353
2354 pythia_log.close()
2355
2356 pydir = pjoin(self.options['pythia-pgs_path'], 'src')
2357 eradir = self.options['exrootanalysis_path']
2358 madir = self.options['madanalysis_path']
2359 td = self.options['td_path']
2360
2361
2362 self.banner.add(pjoin(self.me_dir, 'Cards','pythia_card.dat'))
2363 banner_path = pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, tag))
2364 self.banner.write(banner_path)
2365
2366
2367 if misc.is_executable(pjoin(pydir, 'hep2lhe')):
2368 self.update_status('Creating Pythia LHE File', level='pythia')
2369
2370 out = open(pjoin(self.me_dir,'Events','pythia_events.lhe'), 'w')
2371
2372 out.writelines('<!--\n')
2373 out.writelines('# Warning! Never use this file for detector studies!\n')
2374 out.writelines('-->\n<!--\n')
2375 out.writelines(open(banner_path).read())
2376 out.writelines('\n-->\n')
2377 out.close()
2378
2379 if self.cluster_mode == 1:
2380 self.cluster.launch_and_wait(self.dirbin+'/run_hep2lhe',
2381 argument= [pydir],
2382 cwd=pjoin(self.me_dir,'Events'))
2383 else:
2384 misc.call([self.dirbin+'/run_hep2lhe', pydir],
2385 cwd=pjoin(self.me_dir,'Events'))
2386
2387
2388 if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHEFConverter')):
2389 self.update_status('Creating Pythia LHE Root File', level='pythia')
2390 misc.call([eradir+'/ExRootLHEFConverter',
2391 'pythia_events.lhe',
2392 pjoin(self.run_name, '%s_pythia_lhe_events.root' % tag)],
2393 cwd=pjoin(self.me_dir,'Events'))
2394
2395 if int(self.run_card['ickkw']):
2396 misc.call(['gzip','-f','beforeveto.tree'],
2397 cwd=pjoin(self.me_dir,'Events'))
2398 files.mv(pjoin(self.me_dir,'Events','beforeveto.tree.gz'),
2399 pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_beforeveto.tree.gz'))
2400
2401
2402 self.create_plot('Pythia')
2403
2404 if os.path.exists(pjoin(self.me_dir,'Events','pythia_events.lhe')):
2405 shutil.move(pjoin(self.me_dir,'Events','pythia_events.lhe'),
2406 pjoin(self.me_dir,'Events', self.run_name,'%s_pythia_events.lhe' % tag))
2407 os.system('gzip -f %s' % pjoin(self.me_dir,'Events', self.run_name,
2408 '%s_pythia_events.lhe' % tag))
2409
2410
2411 self.update_status('finish', level='pythia', makehtml=False)
2412 self.exec_cmd('pgs --no_default', postcmd=False, printcmd=False)
2413 if self.options['delphes_path']:
2414 self.exec_cmd('delphes --no_default', postcmd=False, printcmd=False)
2415
2416 self.print_results_in_shell(self.results.current)
2417
2419 """create automatically a tag"""
2420
2421 used_tags = [r['tag'] for r in self.results[self.run_name]]
2422 i=0
2423 while 1:
2424 i+=1
2425 if 'tag_%s' %i not in used_tags:
2426 return 'tag_%s' % i
2427
2428
2429
2430
2432 """Remove one/all run or only part of it"""
2433
2434 args = self.split_arg(line)
2435 run, tag, mode = self.check_remove(args)
2436 if run == 'all':
2437
2438 if os.path.exists(pjoin(self.me_dir, 'Events', 'all')):
2439 logger.warning('A run with name all exists. So we will not supress all processes.')
2440 else:
2441 for match in glob.glob(pjoin(self.me_dir, 'Events','*','*_banner.txt')):
2442 run = match.rsplit(os.path.sep,2)[1]
2443 try:
2444 self.exec_cmd('remove %s %s' % (run, ' '.join(args[1:]) ) )
2445 except self.InvalidCmd, error:
2446 logger.info(error)
2447 pass
2448 return
2449
2450
2451 if not os.path.exists(pjoin(self.me_dir, 'Events', run)):
2452 raise self.InvalidCmd('No run \'%s\' detected' % run)
2453
2454 try:
2455 self.resuls.def_current(run)
2456 self.update_status(' Cleaning %s' % run, level=None)
2457 except:
2458 pass
2459
2460
2461
2462
2463 to_delete = glob.glob(pjoin(self.me_dir, 'Events', run, '*'))
2464 to_delete += glob.glob(pjoin(self.me_dir, 'HTML', run, '*'))
2465
2466 to_delete = [os.path.basename(f) for f in to_delete if 'banner' not in f]
2467 if tag:
2468 to_delete = [f for f in to_delete if tag in f]
2469 if 'parton' in mode or 'all' in mode:
2470 try:
2471 if self.results[run][0]['tag'] != tag:
2472 raise Exception, 'dummy'
2473 except:
2474 pass
2475 else:
2476 nb_rm = len(to_delete)
2477 if os.path.exists(pjoin(self.me_dir, 'Events', run, 'events.lhe.gz')):
2478 to_delete.append('events.lhe.gz')
2479 if os.path.exists(pjoin(self.me_dir, 'Events', run, 'unweighted_events.lhe.gz')):
2480 to_delete.append('unweighted_events.lhe.gz')
2481 if nb_rm != len(to_delete):
2482 logger.warning('Be carefull that partonic information are on the point to be removed.')
2483 if 'all' in mode:
2484 pass
2485 else:
2486 if 'pythia' not in mode:
2487 to_delete = [f for f in to_delete if 'pythia' not in f]
2488 if 'pgs' not in mode:
2489 to_delete = [f for f in to_delete if 'pgs' not in f]
2490 if 'delphes' not in mode:
2491 to_delete = [f for f in to_delete if 'delphes' not in f]
2492 if 'parton' not in mode:
2493 to_delete = [f for f in to_delete if 'delphes' in f
2494 or 'pgs' in f
2495 or 'pythia' in f]
2496 if not self.force and len(to_delete):
2497 question = 'Do you want to delete the following files?\n %s' % \
2498 '\n '.join(to_delete)
2499 ans = self.ask(question, 'y', choices=['y','n'])
2500 else:
2501 ans = 'y'
2502
2503 if ans == 'y':
2504 for file2rm in to_delete:
2505 if os.path.exists(pjoin(self.me_dir, 'Events', run, file2rm)):
2506 try:
2507 os.remove(pjoin(self.me_dir, 'Events', run, file2rm))
2508 except:
2509 shutil.rmtree(pjoin(self.me_dir, 'Events', run, file2rm))
2510 else:
2511 try:
2512 os.remove(pjoin(self.me_dir, 'HTML', run, file2rm))
2513 except:
2514 shutil.rmtree(pjoin(self.me_dir, 'HTML', run, file2rm))
2515
2516
2517
2518
2519 if 'all' in mode or 'channel' in mode:
2520 try:
2521 if self.results[run][0]['tag'] != tag:
2522 raise Exception, 'dummy'
2523 except:
2524 pass
2525 else:
2526 to_delete = glob.glob(pjoin(self.me_dir, 'SubProcesses', '%s*' % run))
2527 to_delete += glob.glob(pjoin(self.me_dir, 'SubProcesses', '*','%s*' % run))
2528 to_delete += glob.glob(pjoin(self.me_dir, 'SubProcesses', '*','*','%s*' % run))
2529
2530 if self.force or len(to_delete) == 0:
2531 ans = 'y'
2532 else:
2533 question = 'Do you want to delete the following files?\n %s' % \
2534 '\n '.join(to_delete)
2535 ans = self.ask(question, 'y', choices=['y','n'])
2536
2537 if ans == 'y':
2538 for file2rm in to_delete:
2539 os.remove(file2rm)
2540
2541 if 'banner' in mode:
2542 to_delete = glob.glob(pjoin(self.me_dir, 'Events', run, '*'))
2543 if tag:
2544
2545 try:
2546 os.remove(pjoin(self.me_dir, 'Events',run,'%s_%s_banner.txt' % (run,tag)))
2547 except:
2548 logger.warning('fail to remove the banner')
2549
2550 if run in self.results:
2551 self.results.delete_run(run, tag)
2552 return
2553 elif any(['banner' not in os.path.basename(p) for p in to_delete]):
2554 if to_delete:
2555 raise MadGraph5Error, '''Some output still exists for this run.
2556 Please remove those output first. Do for example:
2557 remove %s all banner
2558 ''' % run
2559 else:
2560 shutil.rmtree(pjoin(self.me_dir, 'Events',run))
2561 if run in self.results:
2562 self.results.delete_run(run)
2563 return
2564 else:
2565 logger.info('''The banner is not removed. In order to remove it run:
2566 remove %s all banner %s''' % (run, tag and '--tag=%s ' % tag or ''))
2567
2568
2569 self.results.clean(mode, run, tag)
2570 self.update_status('', level='all')
2571
2572
2573
2574
2576 """Create the plot for a given run"""
2577
2578
2579 self.store_result()
2580 args = self.split_arg(line)
2581
2582 self.check_plot(args)
2583 logger.info('plot for run %s' % self.run_name)
2584
2585 self.ask_edit_cards([], args)
2586
2587 if any([arg in ['all','parton'] for arg in args]):
2588 filename = pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe')
2589 if os.path.exists(filename+'.gz'):
2590 os.system('gunzip -f %s' % (filename+'.gz') )
2591 if os.path.exists(filename):
2592 shutil.move(filename, pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'))
2593 self.create_plot('parton')
2594 shutil.move(pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'), filename)
2595 os.system('gzip -f %s' % filename)
2596 else:
2597 logger.info('No valid files for partonic plot')
2598
2599 if any([arg in ['all','pythia'] for arg in args]):
2600 filename = pjoin(self.me_dir, 'Events' ,self.run_name,
2601 '%s_pythia_events.lhe' % self.run_tag)
2602 if os.path.exists(filename+'.gz'):
2603 os.system('gunzip -f %s' % (filename+'.gz') )
2604 if os.path.exists(filename):
2605 shutil.move(filename, pjoin(self.me_dir, 'Events','pythia_events.lhe'))
2606 self.create_plot('Pythia')
2607 shutil.move(pjoin(self.me_dir, 'Events','pythia_events.lhe'), filename)
2608 os.system('gzip -f %s' % filename)
2609 else:
2610 logger.info('No valid files for pythia plot')
2611
2612
2613 if any([arg in ['all','pgs'] for arg in args]):
2614 filename = pjoin(self.me_dir, 'Events', self.run_name,
2615 '%s_pgs_events.lhco' % self.run_tag)
2616 if os.path.exists(filename+'.gz'):
2617 os.system('gunzip -f %s' % (filename+'.gz') )
2618 if os.path.exists(filename):
2619 self.create_plot('PGS')
2620 os.system('gzip -f %s' % filename)
2621 else:
2622 logger.info('No valid files for pgs plot')
2623
2624 if any([arg in ['all','delphes'] for arg in args]):
2625 filename = pjoin(self.me_dir, 'Events', self.run_name,
2626 '%s_delphes_events.lhco' % self.run_tag)
2627 if os.path.exists(filename+'.gz'):
2628 os.system('gunzip -f %s' % (filename+'.gz') )
2629 if os.path.exists(filename):
2630
2631 self.create_plot('Delphes')
2632
2633 os.system('gzip -f %s' % filename)
2634 else:
2635 logger.info('No valid files for delphes plot')
2636
2637
2638
2640 """ tar the pythia results. This is done when we are quite sure that
2641 the pythia output will not be use anymore """
2642
2643
2644 if not self.run_name:
2645 return
2646
2647 self.results.save()
2648
2649 if not self.to_store:
2650 return
2651
2652 tag = self.run_card['run_tag']
2653 if 'pythia' in self.to_store:
2654 self.update_status('Storing Pythia files of Previous run', level='pythia', error=True)
2655 os.system('mv -f %(path)s/pythia_events.hep %(path)s/%(name)s/%(tag)s_pythia_events.hep' %
2656 {'name': self.run_name, 'path' : pjoin(self.me_dir,'Events'),
2657 'tag':tag})
2658 os.system('gzip -f %s/%s_pythia_events.hep' % (
2659 pjoin(self.me_dir,'Events',self.run_name), tag))
2660 self.to_store.remove('pythia')
2661 self.update_status('Done', level='pythia',makehtml=False,error=True)
2662
2663 self.to_store = []
2664
2665
2666
2668 """launch pgs"""
2669
2670 args = self.split_arg(line)
2671
2672 if '--no_default' in args:
2673 no_default = True
2674 args.remove('--no_default')
2675 else:
2676 no_default = False
2677
2678
2679
2680
2681
2682 self.check_pgs(args)
2683
2684
2685 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')):
2686 if no_default:
2687 logger.info('No pgs_card detected, so not run pgs')
2688 return
2689
2690 files.cp(pjoin(self.me_dir, 'Cards', 'pgs_card_default.dat'),
2691 pjoin(self.me_dir, 'Cards', 'pgs_card.dat'))
2692 logger.info('No pgs card found. Take the default one.')
2693
2694 if not (no_default or self.force):
2695 self.ask_edit_cards(['pgs'], args)
2696
2697 self.update_status('prepare PGS run', level=None)
2698
2699 if hasattr(self, 'control_thread') and self.control_thread[0]:
2700 self.monitor(mode=2)
2701
2702 pgsdir = pjoin(self.options['pythia-pgs_path'], 'src')
2703 eradir = self.options['exrootanalysis_path']
2704 madir = self.options['madanalysis_path']
2705 td = self.options['td_path']
2706
2707
2708 if not misc.is_executable(pjoin(pgsdir, 'pgs')):
2709 logger.info('No PGS executable -- running make')
2710 misc.compile(cwd=pgsdir)
2711
2712
2713
2714
2715
2716 self.update_status('Running PGS', level='pgs')
2717
2718 tag = self.run_tag
2719
2720 self.banner.add(pjoin(self.me_dir, 'Cards','pgs_card.dat'))
2721 banner_path = pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, self.run_tag))
2722 self.banner.write(banner_path)
2723
2724
2725
2726
2727
2728
2729 ff = open(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'), 'w')
2730 text = open(banner_path).read()
2731 text = '#%s' % text.replace('\n','\n#')
2732 dico = self.results[self.run_name].get_current_info()
2733 text +='\n## Integrated weight (pb) : %.4g' % dico['cross']
2734 text +='\n## Number of Event : %s\n' % dico['nb_event']
2735 ff.writelines(text)
2736 ff.close()
2737
2738 try:
2739 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done'))
2740 except:
2741 pass
2742 if self.cluster_mode == 1:
2743 pgs_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_pgs.log" % tag)
2744 self.cluster.launch_and_wait('../bin/internal/run_pgs',
2745 argument=[pgsdir], cwd=pjoin(self.me_dir,'Events'),
2746 stdout=pgs_log, stderr=subprocess.STDOUT)
2747 else:
2748 pgs_log = open(pjoin(self.me_dir, 'Events', self.run_name,"%s_pgs.log" % tag),'w')
2749 misc.call([self.dirbin+'/run_pgs', pgsdir], stdout= pgs_log,
2750 stderr=subprocess.STDOUT,
2751 cwd=pjoin(self.me_dir, 'Events'))
2752
2753 if not os.path.exists(pjoin(self.me_dir, 'Events', 'pgs.done')):
2754 logger.error('Fail to create LHCO events')
2755 return
2756 else:
2757 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done'))
2758
2759 if os.path.getsize(banner_path) == os.path.getsize(pjoin(self.me_dir, 'Events','pgs_events.lhco')):
2760 misc.call(['cat pgs_uncleaned_events.lhco >> pgs_events.lhco'],
2761 cwd=pjoin(self.me_dir, 'Events'))
2762 os.remove(pjoin(self.me_dir, 'Events', 'pgs_uncleaned_events.lhco '))
2763
2764
2765 if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHCOlympicsConverter')):
2766 self.update_status('Creating PGS Root File', level='pgs')
2767 misc.call([eradir+'/ExRootLHCOlympicsConverter',
2768 'pgs_events.lhco',pjoin('%s/%s_pgs_events.root' % (self.run_name, tag))],
2769 cwd=pjoin(self.me_dir, 'Events'))
2770
2771 if os.path.exists(pjoin(self.me_dir, 'Events', 'pgs_events.lhco')):
2772
2773 self.create_plot('PGS')
2774 files.mv(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'),
2775 pjoin(self.me_dir, 'Events', self.run_name, '%s_pgs_events.lhco' % tag))
2776 misc.call(['gzip','-f', pjoin(self.me_dir, 'Events',
2777 self.run_name, '%s_pgs_events.lhco' % tag)])
2778
2779
2780
2781 self.update_status('finish', level='pgs', makehtml=False)
2782
2783
2785 """ run delphes and make associate root file/plot """
2786
2787 args = self.split_arg(line)
2788
2789 if '--no_default' in args:
2790 no_default = True
2791 args.remove('--no_default')
2792 else:
2793 no_default = False
2794 self.check_delphes(args)
2795 self.update_status('prepare delphes run', level=None)
2796
2797
2798
2799 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
2800 if no_default:
2801 logger.info('No delphes_card detected, so not run Delphes')
2802 return
2803
2804 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_card_default.dat'),
2805 pjoin(self.me_dir, 'Cards', 'delphes_card.dat'))
2806 logger.info('No delphes card found. Take the default one.')
2807 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat')):
2808 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_trigger_default.dat'),
2809 pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat'))
2810 if not (no_default or self.force):
2811 self.ask_edit_cards(['delphes', 'trigger'], args)
2812
2813 self.update_status('Running Delphes', level=None)
2814
2815 if hasattr(self, 'control_thread') and self.control_thread[0]:
2816 self.monitor(mode=2)
2817
2818
2819
2820 delphes_dir = self.options['delphes_path']
2821 tag = self.run_tag
2822 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_card.dat'))
2823 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_trigger.dat'))
2824 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, tag)))
2825
2826 cross = self.results[self.run_name].get_current_info()['cross']
2827
2828 if self.cluster_mode == 1:
2829 delphes_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_delphes.log" % tag)
2830 self.cluster.launch_and_wait('../bin/internal/run_delphes',
2831 argument= [delphes_dir, self.run_name, tag, str(cross)],
2832 stdout=delphes_log, stderr=subprocess.STDOUT,
2833 cwd=pjoin(self.me_dir,'Events'))
2834 else:
2835 delphes_log = open(pjoin(self.me_dir, 'Events', self.run_name, "%s_delphes.log" % tag),'w')
2836 misc.call(['../bin/internal/run_delphes', delphes_dir,
2837 self.run_name, tag, str(cross)],
2838 stdout= delphes_log, stderr=subprocess.STDOUT,
2839 cwd=pjoin(self.me_dir,'Events'))
2840
2841 if not os.path.exists(pjoin(self.me_dir, 'Events',
2842 self.run_name, '%s_delphes_events.lhco' % tag)):
2843 logger.error('Fail to create LHCO events from DELPHES')
2844 return
2845
2846 if os.path.exists(pjoin(self.me_dir,'Events','delphes.root')):
2847 source = pjoin(self.me_dir,'Events','delphes.root')
2848 target = pjoin(self.me_dir,'Events', self.run_name, "%s_delphes_events.root" % tag)
2849 files.mv(source, target)
2850
2851
2852 madir = self.options['madanalysis_path']
2853 td = self.options['td_path']
2854
2855
2856 self.create_plot('Delphes')
2857
2858 if os.path.exists(pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag)):
2859 misc.call(['gzip','-f', pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag)])
2860
2861
2862
2863 self.update_status('delphes done', level='delphes', makehtml=False)
2864
2865 - def launch_job(self,exe, cwd=None, stdout=None, argument = [], remaining=0,
2866 run_type='', mode=None, **opt):
2867 """ """
2868 argument = [str(arg) for arg in argument]
2869 if mode is None:
2870 mode = self.cluster_mode
2871
2872 def launch_in_thread(exe, argument, cwd, stdout, control_thread):
2873 """ way to launch for multicore"""
2874
2875 start = time.time()
2876 if (cwd and os.path.exists(pjoin(cwd, exe))) or os.path.exists(exe):
2877 exe = './' + exe
2878 misc.call([exe] + argument, cwd=cwd, stdout=stdout,
2879 stderr=subprocess.STDOUT, **opt)
2880
2881
2882
2883 while not control_thread[1].locked():
2884
2885 if not control_thread[2]:
2886
2887 control_thread[0] -= 1
2888 return
2889 time.sleep(1)
2890 control_thread[0] -= 1
2891 control_thread[1].release()
2892
2893
2894
2895 if mode == 0:
2896 self.update_status((remaining, 1,
2897 self.total_jobs - remaining -1, run_type), level=None, force=False)
2898 start = time.time()
2899
2900 status = misc.call(['./'+exe] + argument, cwd=cwd,
2901 stdout=stdout, **opt)
2902 logger.info('%s run in %f s' % (exe, time.time() -start))
2903 if status:
2904 raise MadGraph5Error, '%s didn\'t stop properly. Stop all computation' % exe
2905
2906
2907 elif mode == 1:
2908 self.cluster.submit(exe, stdout=stdout, cwd=cwd)
2909
2910 elif mode == 2:
2911 import thread
2912 if not hasattr(self, 'control_thread'):
2913 self.control_thread = [0]
2914 self.control_thread.append(thread.allocate_lock())
2915 self.control_thread.append(False)
2916
2917
2918 if self.control_thread[2]:
2919 self.update_status((remaining + 1, self.control_thread[0],
2920 self.total_jobs - remaining - self.control_thread[0] - 1, run_type),
2921 level=None, force=False)
2922 self.control_thread[1].acquire()
2923 self.control_thread[0] += 1
2924 thread.start_new_thread(launch_in_thread,(exe, argument, cwd, stdout, self.control_thread))
2925 elif self.control_thread[0] < self.nb_core -1:
2926 self.control_thread[0] += 1
2927 thread.start_new_thread(launch_in_thread,(exe, argument, cwd, stdout, self.control_thread))
2928 elif self.control_thread[0] == self.nb_core -1:
2929 self.control_thread[0] += 1
2930 thread.start_new_thread(launch_in_thread,(exe, argument, cwd, stdout, self.control_thread))
2931 self.control_thread[2] = True
2932 self.control_thread[1].acquire()
2933
2934
2935
2937 """Find if Madevent is in Group mode or not"""
2938
2939
2940
2941 file_path = pjoin(self.me_dir, 'Source', 'run_config.inc')
2942 text = open(file_path).read()
2943 if re.search(r'''s*parameter\s+\(ChanPerJob=2\)''', text, re.I+re.M):
2944 return 'group'
2945 else:
2946 return 'v4'
2947
2948
2949 - def monitor(self, run_type='monitor', mode=None, html=False):
2950 """ monitor the progress of running job """
2951
2952 if mode is None:
2953 mode = self.cluster_mode
2954
2955 if mode == 1:
2956 if html:
2957 update_status = lambda idle, run, finish: \
2958 self.update_status((idle, run, finish, run_type), level=None)
2959 else:
2960 update_status = lambda idle, run, finish: None
2961 try:
2962 self.cluster.wait(self.me_dir, update_status)
2963 except Exception, error:
2964 logger.info(error)
2965 if not self.force:
2966 ans = self.ask('Cluster Error detected. Do you want to clean the queue?',
2967 default = 'y', answers=['y','n'])
2968 else:
2969 ans = 'y'
2970 if ans:
2971 self.cluster.remove()
2972 raise
2973
2974 if mode == 2:
2975
2976 if not self.control_thread[2]:
2977
2978 nb = self.control_thread[0]
2979 while self.control_thread[0]:
2980 time.sleep(5)
2981 if nb != self.control_thread[0] and html:
2982 self.update_status((0, self.control_thread[0],
2983 self.total_jobs - self.control_thread[0], run_type),
2984 level=None, force=False)
2985 nb = self.control_thread[0]
2986 try:
2987 del self.next_update
2988 except:
2989 pass
2990 else:
2991 for i in range(0,self.nb_core):
2992 if html:
2993 self.update_status((0, self.control_thread[0],
2994 self.total_jobs - self.control_thread[0], run_type),
2995 level=None, force=False)
2996 self.control_thread[1].acquire()
2997 self.control_thread[2] = False
2998 self.control_thread[1].release()
2999 try:
3000 del self.next_update
3001 except:
3002 pass
3003
3004
3005 @staticmethod
3007 """ find a valid run_name for the current job """
3008
3009 name = 'run_%02d'
3010 data = [int(s[4:6]) for s in os.listdir(pjoin(me_dir,'Events')) if
3011 s.startswith('run_') and len(s)>5 and s[4:6].isdigit()]
3012 return name % (max(data+[0])+1)
3013
3014
3081
3082
3083
3084
3086 """ """
3087 output={}
3088 for line in file(run_card,'r'):
3089 line = line.split('#')[0]
3090 line = line.split('!')[0]
3091 line = line.split('=')
3092 if len(line) != 2:
3093 continue
3094 output[line[1].strip()] = line[0].replace('\'','').strip()
3095 return output
3096
3097
3098 @staticmethod
3100 """check if the directory exists. if so return the path otherwise the
3101 default"""
3102
3103 if os.path.isdir(path):
3104 return path
3105 else:
3106 return default
3107
3108
3109 - def set_run_name(self, name, tag=None, level='parton', reload_card=False):
3110 """define the run name, the run_tag, the banner and the results."""
3111
3112
3113 upgrade_tag = {'parton': ['parton','pythia','pgs','delphes'],
3114 'pythia': ['pythia','pgs','delphes'],
3115 'pgs': ['pgs'],
3116 'delphes':['delphes'],
3117 'plot':[]}
3118
3119
3120
3121 if name == self.run_name:
3122 if reload_card:
3123 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
3124 self.run_card = self.read_run_card(run_card)
3125
3126
3127 if tag:
3128 self.run_card['run_tag'] = tag
3129 self.run_tag = tag
3130 self.results.add_run(self.run_name, self.run_card)
3131 else:
3132 for tag in upgrade_tag[level]:
3133 if getattr(self.results[self.run_name][-1], tag):
3134 tag = self.get_available_tag()
3135 self.run_card['run_tag'] = tag
3136 self.run_tag = tag
3137 self.results.add_run(self.run_name, self.run_card)
3138 break
3139 return
3140
3141
3142 if self.run_name:
3143 self.store_result()
3144
3145 self.run_name = name
3146
3147
3148 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
3149 self.run_card = self.read_run_card(run_card)
3150
3151 new_tag = False
3152
3153 self.banner = banner_mod.recover_banner(self.results, level)
3154 if tag:
3155 self.run_card['run_tag'] = tag
3156 new_tag = True
3157 elif not self.run_name in self.results and level =='parton':
3158 pass
3159 elif not self.run_name in self.results:
3160
3161 logger.warning('Trying to run data on unknown run.')
3162 self.results.add_run(name, self.run_card)
3163 self.results.update('add run %s' % name, 'all', makehtml=False)
3164 else:
3165 for tag in upgrade_tag[level]:
3166
3167 if getattr(self.results[self.run_name][-1], tag):
3168
3169 tag = self.get_available_tag()
3170 self.run_card['run_tag'] = tag
3171 new_tag = True
3172 break
3173 if not new_tag:
3174
3175 tag = self.results[self.run_name][-1]['tag']
3176 self.run_card['run_tag'] = tag
3177
3178
3179 if name in self.results and not new_tag:
3180 self.results.def_current(self.run_name)
3181 else:
3182 self.results.add_run(self.run_name, self.run_card)
3183
3184 self.run_tag = self.run_card['run_tag']
3185
3186
3187
3188 if level == 'parton':
3189 return
3190 elif level == 'pythia':
3191 return self.results[self.run_name][0]['tag']
3192 else:
3193 for i in range(-1,-len(self.results[self.run_name])-1,-1):
3194 tagRun = self.results[self.run_name][i]
3195 if tagRun.pythia:
3196 return tagRun['tag']
3197
3198
3199
3200
3201
3202
3203
3204
3205
3207 """ return the model name """
3208 if hasattr(self, 'model_name'):
3209 return self.model_name
3210
3211 model = 'sm'
3212 proc = []
3213 for line in open(os.path.join(self.me_dir,'Cards','proc_card_mg5.dat')):
3214 line = line.split('#')[0]
3215
3216 if line.startswith('import') and 'model' in line:
3217 model = line.split()[2]
3218 proc = []
3219 elif line.startswith('generate'):
3220 proc.append(line.split(None,1)[1])
3221 elif line.startswith('add process'):
3222 proc.append(line.split(None,2)[2])
3223
3224 self.model = model
3225 self.process = proc
3226 return model
3227
3228
3229
3231 """Find the number of event in the run_card, and check that this is not
3232 too large"""
3233
3234
3235 nb_event = int(self.run_card['nevents'])
3236 if nb_event > 1000000:
3237 logger.warning("Attempting to generate more than 1M events")
3238 logger.warning("Limiting number to 1M. Use multi_run for larger statistics.")
3239 path = pjoin(self.me_dir, 'Cards', 'run_card.dat')
3240 os.system(r"""perl -p -i.bak -e "s/\d+\s*=\s*nevents/1000000 = nevents/" %s""" \
3241 % path)
3242 self.run_card['nevents'] = 1000000
3243
3244 return
3245
3246
3247
3249 """ change random number"""
3250
3251 self.random += 3
3252 if self.random > 30081*30081:
3253 raise MadGraph5Error,\
3254 'Random seed too large ' + str(self.random) + ' > 30081*30081'
3255
3256
3258 """save random number in appropirate file"""
3259
3260 fsock = open(pjoin(self.me_dir, 'SubProcesses','randinit'),'w')
3261 fsock.writelines('r=%s\n' % self.random)
3262
3264 """ """
3265
3266 try:
3267 os.remove(pjoin(self.me_dir,'RunWeb'))
3268 except:
3269 pass
3270 try:
3271 self.store_result()
3272 except:
3273
3274 pass
3275 try:
3276 self.update_status('', level=None)
3277 except Exception, error:
3278 pass
3279 try:
3280 misc.call(['./bin/internal/gen_cardhtml-pl'], cwd=self.me_dir,
3281 stdout=devnull, stderr=devnull)
3282 except:
3283 pass
3284
3285 return super(MadEventCmd, self).do_quit(line)
3286
3287
3288 do_EOF = do_quit
3289 do_exit = do_quit
3290
3291
3293 """check for ckkw"""
3294
3295 lpp1 = self.run_card['lpp1']
3296 lpp2 = self.run_card['lpp2']
3297 e1 = self.run_card['ebeam1']
3298 e2 = self.run_card['ebeam2']
3299 pd = self.run_card['pdlabel']
3300 lha = self.run_card['lhaid']
3301 xq = self.run_card['xqcut']
3302 translation = {'e1': e1, 'e2':e2, 'pd':pd,
3303 'lha':lha, 'xq':xq}
3304
3305 if lpp1 or lpp2:
3306
3307 if pd.startswith("'"):
3308 pd = pd[1:]
3309 if pd.endswith("'"):
3310 pd = pd[:-1]
3311
3312 if xq >2 or xq ==2:
3313 xq = 2
3314
3315
3316 if pd == "lhapdf":
3317 issudfile = 'lib/issudgrid-%(e1)s-%(e2)s-%(pd)s-%(lha)s-%(xq)s.dat.gz'
3318 else:
3319 issudfile = 'lib/issudgrid-%(e1)s-%(e2)s-%(pd)s-%(xq)s.dat.gz'
3320 if self.web:
3321 issudfile = pjoin(self.webbin, issudfile % translation)
3322 else:
3323 issudfile = pjoin(self.me_dir, issudfile % translation)
3324
3325 logger.info('Sudakov grid file: %s' % issudfile)
3326
3327
3328 if os.path.exists(issudfile):
3329 path = pjoin(self.me_dir, 'lib', 'issudgrid.dat')
3330 os.system('gunzip -fc %s > %s' % (issudfile, path))
3331 else:
3332 msg = 'No sudakov grid file for parameter choice. Start to generate it. This might take a while'
3333 self.update_status('GENERATE SUDAKOF GRID', level='parton')
3334
3335 for i in range(-2,6):
3336 self.launch_job('%s/gensudgrid ' % self.dirbin,
3337 arguments = [i],
3338 cwd=self.me_dir,
3339 stdout=open(pjoin(self.me_dir, 'gensudgrid%s.log' % s,'w')))
3340 self.monitor()
3341 for i in range(-2,6):
3342 path = pjoin(self.me_dir, 'lib', 'issudgrid.dat')
3343 os.system('cat %s/gensudgrid%s.log >> %s' % (self.me_dir, path))
3344 os.system('gzip -fc %s > %s' % (path, issudfile))
3345
3346
3347 - def create_root_file(self, input='unweighted_events.lhe',
3348 output='unweighted_events.root' ):
3349 """create the LHE root file """
3350 self.update_status('Creating root files', level='parton')
3351
3352 eradir = self.options['exrootanalysis_path']
3353 misc.call(['%s/ExRootLHEFConverter' % eradir,
3354 input, output],
3355 cwd=pjoin(self.me_dir, 'Events'))
3356
3357
3358 - def create_plot(self, mode='parton', event_path=None, output=None):
3359 """create the plot"""
3360
3361 madir = self.options['madanalysis_path']
3362 tag = self.run_card['run_tag']
3363 td = self.options['td_path']
3364
3365 if not madir or not td or \
3366 not os.path.exists(pjoin(self.me_dir, 'Cards', 'plot_card.dat')):
3367 return False
3368
3369 if int(self.run_card['ickkw']) and mode == 'Pythia':
3370 self.update_status('Create matching plots for Pythia', level='pythia')
3371
3372 if not os.path.exists(pjoin(self.me_dir,'Events','events.tree')):
3373 misc.call(['gunzip', '-c', pjoin(self.me_dir,'Events',
3374 self.run_name, '%s_pythia_events.tree.gz' % tag)],
3375 stdout=open(pjoin(self.me_dir,'Events','events.tree'),'w')
3376 )
3377 files.mv(pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_xsecs.tree'),
3378 pjoin(self.me_dir,'Events','xsecs.tree'))
3379
3380
3381 misc.call([self.dirbin+'/create_matching_plots.sh',
3382 self.run_name, tag, madir],
3383 stdout = os.open(os.devnull, os.O_RDWR),
3384 cwd=pjoin(self.me_dir,'Events'))
3385
3386
3387 misc.call(['gzip','-f','events.tree'],
3388 cwd=pjoin(self.me_dir,'Events'))
3389 files.mv(pjoin(self.me_dir,'Events','events.tree.gz'),
3390 pjoin(self.me_dir,'Events',self.run_name, tag + '_pythia_events.tree.gz'))
3391 files.mv(pjoin(self.me_dir,'Events','xsecs.tree'),
3392 pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_xsecs.tree'))
3393
3394
3395
3396
3397 if not event_path:
3398 if mode == 'parton':
3399 event_path = pjoin(self.me_dir, 'Events','unweighted_events.lhe')
3400 output = pjoin(self.me_dir, 'HTML',self.run_name, 'plots_parton.html')
3401 elif mode == 'Pythia':
3402 event_path = pjoin(self.me_dir, 'Events','pythia_events.lhe')
3403 output = pjoin(self.me_dir, 'HTML',self.run_name,
3404 'plots_pythia_%s.html' % tag)
3405 elif mode == 'PGS':
3406 event_path = pjoin(self.me_dir, 'Events', 'pgs_events.lhco')
3407 output = pjoin(self.me_dir, 'HTML',self.run_name,
3408 'plots_pgs_%s.html' % tag)
3409 elif mode == 'Delphes':
3410 event_path = pjoin(self.me_dir, 'Events', self.run_name,'%s_delphes_events.lhco' % tag)
3411 output = pjoin(self.me_dir, 'HTML',self.run_name,
3412 'plots_delphes_%s.html' % tag)
3413 else:
3414 raise self.InvalidCmd, 'Invalid mode %s' % mode
3415
3416
3417
3418 if not os.path.exists(event_path):
3419 if os.path.exists(event_path+'.gz'):
3420 os.system('gzip -f %s.gz ' % event_path)
3421 else:
3422 raise self.InvalidCmd, 'Events file %s does not exits' % event_path
3423
3424 self.update_status('Creating Plots for %s level' % mode, level = mode.lower())
3425
3426 plot_dir = pjoin(self.me_dir, 'HTML', self.run_name,'plots_%s_%s' % (mode.lower(),tag))
3427
3428 if not os.path.isdir(plot_dir):
3429 os.makedirs(plot_dir)
3430
3431 files.ln(pjoin(self.me_dir, 'Cards','plot_card.dat'), plot_dir, 'ma_card.dat')
3432
3433 try:
3434 proc = misc.Popen([os.path.join(madir, 'plot_events')],
3435 stdout = open(pjoin(plot_dir, 'plot.log'),'w'),
3436 stderr = subprocess.STDOUT,
3437 stdin=subprocess.PIPE,
3438 cwd=plot_dir)
3439 proc.communicate('%s\n' % event_path)
3440 del proc
3441
3442 misc.call(['%s/plot' % self.dirbin, madir, td],
3443 stdout = open(pjoin(plot_dir, 'plot.log'),'a'),
3444 stderr = subprocess.STDOUT,
3445 cwd=plot_dir)
3446
3447 misc.call(['%s/plot_page-pl' % self.dirbin,
3448 os.path.basename(plot_dir),
3449 mode],
3450 stdout = open(pjoin(plot_dir, 'plot.log'),'a'),
3451 stderr = subprocess.STDOUT,
3452 cwd=pjoin(self.me_dir, 'HTML', self.run_name))
3453 shutil.move(pjoin(self.me_dir, 'HTML',self.run_name ,'plots.html'),
3454 output)
3455
3456 except OSError, error:
3457 logger.error('fail to create plot: %s. Please check that MadAnalysis is correctly installed.' % error)
3458
3459 self.update_status('End Plots for %s level' % mode, level = mode.lower(),
3460 makehtml=False)
3461
3462 return True
3463
3464
3466 """ Clean the pointless card """
3467
3468 if mode == 'parton':
3469 if os.path.exists(pjoin(self.me_dir,'Cards','pythia_card.dat')):
3470 os.remove(pjoin(self.me_dir,'Cards','pythia_card.dat'))
3471 elif mode in ['parton', 'pythia', 'delphes']:
3472 if os.path.exists(pjoin(self.me_dir,'Cards','pgs_card.dat')):
3473 os.remove(pjoin(self.me_dir,'Cards','pgs_card.dat'))
3474 elif mode in ['pythia', 'pgs']:
3475 if os.path.exists(pjoin(self.me_dir,'Cards','delphes_card.dat')):
3476 os.remove(pjoin(self.me_dir,'Cards','delphes_card.dat'))
3477 if os.path.exists(pjoin(self.me_dir,'Cards','delphes_trigger.dat')):
3478 os.remove(pjoin(self.me_dir,'Cards','delphes_trigger.dat'))
3479
3480
3481
3483 """Ask the question when launching generate_events/multi_run"""
3484
3485 available_mode = ['0', '1']
3486 if self.options['pythia-pgs_path']:
3487 available_mode.append('2')
3488 available_mode.append('3')
3489
3490 if self.options['delphes_path']:
3491 available_mode.append('4')
3492
3493 if len(available_mode) == 2:
3494 mode = 'parton'
3495 else:
3496 name = {'0': 'auto', '1': 'parton', '2':'pythia', '3':'pgs', '4':'delphes'}
3497 options = available_mode + [name[val] for val in available_mode]
3498 question = """Which programs do you want to run?
3499 0 / auto : running existing card
3500 1 / parton : Madevent\n"""
3501 if '2' in available_mode:
3502 question += """ 2 / pythia : MadEvent + Pythia.
3503 3 / pgs : MadEvent + Pythia + PGS.\n"""
3504 if '4' in available_mode:
3505 question += """ 4 / delphes : MadEvent + Pythia + Delphes.\n"""
3506
3507 if not self.force:
3508 if not mode:
3509 mode = self.ask(question, '0', options)
3510 elif not mode:
3511 mode = 'auto'
3512
3513 if mode.isdigit():
3514 mode = name[mode]
3515 auto = False
3516 if mode == 'auto':
3517 auto = True
3518 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pythia_card.dat')):
3519 mode = 'parton'
3520 elif os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')):
3521 mode = 'pgs'
3522 elif os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
3523 mode = 'delphes'
3524 else:
3525 mode = 'pythia'
3526 else:
3527 self.clean_pointless_card(mode)
3528 logger.info('Will run in mode %s' % mode)
3529
3530
3531
3532
3533
3534 cards = ['param_card.dat', 'run_card.dat']
3535 if mode in ['pythia', 'pgs', 'delphes']:
3536 self.add_card_to_run('pythia')
3537 cards.append('pythia_card.dat')
3538 if mode == 'pgs':
3539 self.add_card_to_run('pgs')
3540 cards.append('pgs_card.dat')
3541 elif mode == 'delphes':
3542 self.add_card_to_run('delphes')
3543 self.add_card_to_run('trigger')
3544 cards.append('delphes_card.dat')
3545
3546 if self.force:
3547 return
3548
3549 def get_question(mode):
3550
3551
3552 question = """Do you want to edit one cards (press enter to bypass editing)?
3553 1 / param : param_card.dat (be carefull about parameter consistency, especially widths)
3554 2 / run : run_card.dat\n"""
3555 possible_answer = ['0','done', 1, 'param', 2, 'run']
3556 if mode in ['pythia', 'pgs', 'delphes']:
3557 question += ' 3 / pythia : pythia_card.dat\n'
3558 possible_answer.append(3)
3559 possible_answer.append('pythia')
3560 if mode == 'pgs':
3561 question += ' 4 / pgs : pgs_card.dat\n'
3562 possible_answer.append(4)
3563 possible_answer.append('pgs')
3564 elif mode == 'delphes':
3565 question += ' 5 / delphes : delphes_card.dat\n'
3566 question += ' 6 / trigger : delphes_trigger.dat\n'
3567 possible_answer.append(5)
3568 possible_answer.append('delphes')
3569 possible_answer.append(6)
3570 possible_answer.append('trigger')
3571 if self.options['madanalysis_path']:
3572 question += ' 9 / plot : plot_card.dat\n'
3573 possible_answer.append(9)
3574 possible_answer.append('plot')
3575 card = {0:'done', 1:'param', 2:'run', 3:'pythia',
3576 4: 'pgs', 5: 'delphes', 6:'trigger',9:'plot'}
3577
3578 question += ' Path to a valid card.\n'
3579 return question, possible_answer, card
3580
3581
3582 answer = 'no'
3583 while answer != 'done':
3584 question, possible_answer, card = get_question(mode)
3585 answer = self.ask(question, '0', possible_answer, timeout=int(1.5*self.options['timeout']), path_msg='enter path')
3586 if answer.isdigit():
3587 answer = card[int(answer)]
3588 if answer == 'done':
3589 return
3590 if not os.path.isfile(answer):
3591 if answer != 'trigger':
3592 path = pjoin(self.me_dir,'Cards','%s_card.dat' % answer)
3593 else:
3594 path = pjoin(self.me_dir,'Cards','delphes_trigger.dat')
3595 self.exec_cmd('open %s' % path)
3596 else:
3597
3598 card_name = self.detect_card_type(answer)
3599 if card_name == 'unknown':
3600 card_name = self.ask('Fail to determine the type of the file. Please specify the format',
3601 ['param_card.dat', 'run_card.dat','pythia_card.dat','pgs_card.dat',
3602 'delphes_card.dat', 'delphes_trigger.dat','plot_card.dat'])
3603 elif card_name != 'banner':
3604 logger.info('copy %s as %s' % (answer, card_name))
3605 files.cp(answer, pjoin(self.me_dir, 'Cards', card_name))
3606 elif card_name == 'banner':
3607 banner_mod.split_banner(answer, self.me_dir, proc_card=False)
3608 logger.info('Splitting the banner in it\'s component')
3609 if auto:
3610
3611 mode = 'parton'
3612 for level in ['delphes','pgs','pythia']:
3613 if os.path.exists(pjoin(self.me_dir,'Cards','%s_card.dat' % level)):
3614 mode = level
3615 break
3616 else:
3617 clean_pointless_card(mode)
3618
3619
3620
3622 """Ask the question when launching pythia"""
3623
3624 available_mode = ['0', '1', '2']
3625 if self.options['delphes_path']:
3626 available_mode.append('3')
3627 name = {'0': 'auto', '1': 'pythia', '2':'pgs', '3':'delphes'}
3628 options = available_mode + [name[val] for val in available_mode]
3629 question = """Which programs do you want to run?
3630 0 / auto : running existing card
3631 1 / pythia : Pythia
3632 2 / pgs : Pythia + PGS\n"""
3633 if '3' in available_mode:
3634 question += """ 3 / delphes : Pythia + Delphes.\n"""
3635
3636 if not self.force:
3637 if not mode:
3638 mode = self.ask(question, '0', options)
3639 elif not mode:
3640 mode = 'auto'
3641
3642 if mode.isdigit():
3643 mode = name[mode]
3644
3645 if mode == 'auto':
3646 if os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')):
3647 mode = 'pgs'
3648 elif os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
3649 mode = 'delphes'
3650 else:
3651 mode = 'pythia'
3652 logger.info('Will run in mode %s' % mode)
3653
3654 self.clean_pointless_card(mode)
3655
3656
3657
3658
3659 cards = ['pythia_card.dat']
3660 self.add_card_to_run('pythia')
3661 if mode == 'pgs':
3662 self.add_card_to_run('pgs')
3663 cards.append('pgs_card.dat')
3664 if mode == 'delphes':
3665 self.add_card_to_run('delphes')
3666 self.add_card_to_run('trigger')
3667 cards.append('delphes_card.dat')
3668
3669 if self.force:
3670 return mode
3671
3672
3673
3674 question = """Do you want to edit one cards (press enter to bypass editing)?\n"""
3675 question += """ 1 / pythia : pythia_card.dat\n"""
3676 possible_answer = ['0','done', '1', 'pythia']
3677 card = {0:'done', 1:'pythia', 9:'plot'}
3678 if mode == 'pgs':
3679 question += ' 2 / pgs : pgs_card.dat\n'
3680 possible_answer.append(2)
3681 possible_answer.append('pgs')
3682 card[2] = 'pgs'
3683 if mode == 'delphes':
3684 question += ' 2 / delphes : delphes_card.dat\n'
3685 question += ' 3 / trigger : delphes_trigger.dat\n'
3686 possible_answer.append(2)
3687 possible_answer.append('delphes')
3688 possible_answer.append(3)
3689 possible_answer.append('trigger')
3690 card[2] = 'delphes'
3691 card[3] = 'trigger'
3692 if self.options['madanalysis_path']:
3693 question += ' 9 / plot : plot_card.dat\n'
3694 possible_answer.append(9)
3695 possible_answer.append('plot')
3696
3697
3698 question += ' Path to a valid card.\n'
3699
3700
3701 answer = 'no'
3702 while answer != 'done':
3703 answer = self.ask(question, '0', possible_answer, timeout=int(1.5*self.options['timeout']), path_msg='enter path')
3704 if answer.isdigit():
3705 answer = card[int(answer)]
3706 if answer == 'done':
3707 return
3708 if os.path.isfile(answer):
3709
3710 card_name = self.detect_card_type(answer)
3711 if card_name == 'unknown':
3712 card_name = self.ask('Fail to determine the type of the file. Please specify the format',
3713 ['pythia_card.dat','pgs_card.dat',
3714 'delphes_card.dat', 'delphes_trigger.dat','plot_card.dat'])
3715
3716 logger.info('copy %s as %s' % (answer, card_name))
3717 files.cp(answer, pjoin(self.me_dir, 'Cards', card_name))
3718 continue
3719 if answer != 'trigger':
3720 path = pjoin(self.me_dir,'Cards','%s_card.dat' % answer)
3721 else:
3722 path = pjoin(self.me_dir,'Cards','delphes_trigger.dat')
3723 self.exec_cmd('open %s' % path)
3724
3725 return mode
3726
3728 """Question for cards editions (used for pgs/delphes)"""
3729
3730 if self.force or '--no_default' in fct_args:
3731 return
3732
3733 card_name = {'pgs': 'pgs_card.dat',
3734 'delphes': 'delphes_card.dat',
3735 'trigger': 'delphes_trigger.dat'
3736 }
3737
3738
3739
3740 question = """Do you want to edit one cards (press enter to bypass editing)?\n"""
3741 possible_answer = ['0', 'done']
3742 card = {0:'done'}
3743
3744 for i, mode in enumerate(cards):
3745 possible_answer.append(i+1)
3746 possible_answer.append(mode)
3747 question += ' %s / %-9s : %s\n' % (i+1, mode, card_name[mode])
3748 card[i+1] = mode
3749
3750 if self.options['madanalysis_path']:
3751 question += ' 9 / %-9s : plot_card.dat\n' % 'plot'
3752 possible_answer.append(9)
3753 possible_answer.append('plot')
3754 card[9] = 'plot'
3755
3756
3757 question += ' Path to a valid card.\n'
3758
3759
3760 answer = 'no'
3761 while answer != 'done':
3762 answer = self.ask(question, '0', possible_answer, timeout=int(1.5*self.options['timeout']), path_msg='enter path')
3763 if answer.isdigit():
3764 answer = card[int(answer)]
3765 if answer == 'done':
3766 return
3767 if os.path.isfile(answer):
3768
3769 card_name = self.detect_card_type(answer)
3770 if card_name == 'unknown':
3771 card_name = self.ask('Fail to determine the type of the file. Please specify the format',
3772 ['pgs_card.dat', 'delphes_card.dat', 'delphes_trigger.dat'])
3773
3774 logger.info('copy %s as %s' % (answer, card_name))
3775 files.cp(answer, pjoin(self.me_dir, 'Cards', card_name))
3776 continue
3777 if answer != 'trigger':
3778 path = pjoin(self.me_dir,'Cards','%s_card.dat' % answer)
3779 else:
3780 path = pjoin(self.me_dir,'Cards','delphes_trigger.dat')
3781 self.exec_cmd('open %s' % path)
3782
3783 return mode
3784
3785
3786 question = """Do you want to edit the %s?""" % card
3787 answer = self.ask(question, 'n', ['y','n'],path_msg='enter path')
3788 if answer == 'y':
3789 path = pjoin(self.me_dir,'Cards', card)
3790 self.exec_cmd('open %s' % path)
3791 elif answer != 'n':
3792 card_name = self.detect_card_type(answer)
3793 if card_name != card:
3794 raise self.InvalidCmd('Invalid File Format for a %s' % card)
3795 logger.info('copy %s as %s' % (answer, card_name))
3796 files.cp(answer, pjoin(self.me_dir, 'Cards', card_name))
3797
3798
3799
3801 """ensure that card name is define. If not use the default one"""
3802 dico = {'dir': self.me_dir, 'name': name }
3803
3804 if name != 'trigger':
3805 if not os.path.isfile('%(dir)s/Cards/%(name)s_card.dat' % dico):
3806 files.cp('%(dir)s/Cards/%(name)s_card_default.dat' % dico,
3807 '%(dir)s/Cards/%(name)s_card.dat' % dico)
3808 else:
3809 if not os.path.isfile('%(dir)s/Cards/delphes_trigger.dat' % dico):
3810 files.cp('%(dir)s/Cards/delphes_trigger_default.dat' % dico,
3811 '%(dir)s/Cards/delphes_trigger.dat' % dico)
3812
3813 @staticmethod
3815 """detect the type of the card. Return value are
3816 banner
3817 param_card.dat
3818 run_card.dat
3819 pythia_card.dat
3820 plot_card.dat
3821 pgs_card.dat
3822 delphes_card.dat
3823 delphes_trigger.dat
3824 """
3825
3826 text = open(path).read()
3827 text = re.findall('(<MGVersion>|CEN_max_tracker|#TRIGGER CARD|parameter set name|muon eta coverage|MSTP|MSTU|Begin Minpts|gridpack|ebeam1|BLOCK|DECAY)', text, re.I)
3828 text = [t.lower() for t in text]
3829 if '<mgversion>' in text:
3830 return 'banner'
3831 elif 'cen_max_tracker' in text:
3832 return 'delphes_card.dat'
3833 elif '#trigger card' in text:
3834 return 'delphes_trigger.dat'
3835 elif 'parameter set name' in text:
3836 return 'pgs_card.dat'
3837 elif 'muon eta coverage' in text:
3838 return 'pgs_card.dat'
3839 elif 'mstp' in text:
3840 return 'pythia_card.dat'
3841 elif 'mstu' in text:
3842 return 'pythia_param_card.dat'
3843 elif 'begin minpts' in text:
3844 return 'plot_card.dat'
3845 elif 'gridpack' in text and 'ebeam1' in text:
3846 return 'run_card.dat'
3847 elif 'block' in text and 'decay' in text:
3848 return 'param_card.dat'
3849 else:
3850 return 'unknown'
3851
3857 """The command line processor of MadGraph"""
3858
3865
3866 name_to_pdg = {}
3867
3868 @classmethod
3871
3872 @staticmethod
3874 """return the list of Subprocesses"""
3875
3876 out = []
3877 for line in open(pjoin(me_dir,'SubProcesses', 'subproc.mg')):
3878 if not line:
3879 continue
3880 name = line.strip()
3881 if os.path.exists(pjoin(me_dir, 'SubProcesses', name)):
3882 out.append(pjoin(me_dir, 'SubProcesses', name))
3883
3884 return out
3885
3886
3887
3888 @staticmethod
3890 """ return the list of processes with their name"""
3891
3892 nb_sub = 0
3893 names = {}
3894 old_main = ''
3895
3896 if not os.path.exists(os.path.join(path,'processes.dat')):
3897 return make_info_html.get_subprocess_info_v4(path)
3898
3899 for line in open(os.path.join(path,'processes.dat')):
3900 main = line[:8].strip()
3901 if main == 'mirror':
3902 main = old_main
3903 if line[8:].strip() == 'none':
3904 continue
3905 else:
3906 main = int(main)
3907 old_main = main
3908
3909 sub_proccess = line[8:]
3910 nb_sub += sub_proccess.count(',') + 1
3911 if main in names:
3912 names[main] += [sub_proccess.split(',')]
3913 else:
3914 names[main]= [sub_proccess.split(',')]
3915
3916 return names
3917
3918 @staticmethod
3920 """ return the list of processes with their name in case without grouping """
3921
3922 nb_sub = 0
3923 names = {'':[[]]}
3924 path = os.path.join(path, 'auto_dsig.f')
3925 found = 0
3926 for line in open(path):
3927 if line.startswith('C Process:'):
3928 found += 1
3929 names[''][0].append(line[15:])
3930 elif found >1:
3931 break
3932 return names
3933
3934
3935 @staticmethod
3937 """return the pdg codes of the particles present in the Subprocesses"""
3938
3939 all_ids = []
3940 for line in open(pjoin(path, 'leshouche.inc')):
3941 if not 'IDUP' in line:
3942 continue
3943 particles = re.search("/([\d,-]+)/", line)
3944 all_ids.append([int(p) for p in particles.group(1).split(',')])
3945 return all_ids
3946
3950 """The command for the gridpack --Those are not suppose to be use interactively--"""
3951
3952 - def __init__(self, me_dir = None, nb_event=0, seed=0, *completekey, **stdin):
3953 """Initialize the command and directly run"""
3954
3955
3956
3957 MadEventCmd.__init__(self, me_dir, *completekey, **stdin)
3958 self.run_mode = 0
3959 self.random = seed
3960 self.options['automatic_html_opening'] = False
3961
3962 if me_dir and nb_event and seed:
3963 self.launch(nb_event, seed)
3964 else:
3965 raise MadGraph5Error,\
3966 'Gridpack run failed: ' + str(me_dir) + str(nb_event) + \
3967 str(seed)
3968
3969 - def launch(self, nb_event, seed):
3970 """ launch the generation for the grid """
3971
3972
3973 logger.info('generate %s events' % nb_event)
3974 self.set_run_name('GridRun_%s' % seed)
3975 self.update_status('restoring default data', level=None)
3976 misc.call([pjoin(self.me_dir,'bin','internal','restore_data'),
3977 'default'],
3978 cwd=self.me_dir)
3979
3980
3981 self.update_status('Generating Events', level=None)
3982
3983
3984
3985 self.refine4grid(nb_event)
3986
3987
3988 self.exec_cmd('combine_events')
3989 self.exec_cmd('store_events')
3990 self.print_results_in_shell(self.results.current)
3991
3993 """Special refine for gridpack run."""
3994 self.nb_refine += 1
3995
3996 precision = nb_event
3997
3998
3999
4000 self.cluster_mode = 0
4001
4002 self.update_status('Refine results to %s' % precision, level=None)
4003 logger.info("Using random number seed offset = %s" % self.random)
4004
4005 self.total_jobs = 0
4006 subproc = [P for P in os.listdir(pjoin(self.me_dir,'SubProcesses')) if
4007 P.startswith('P') and os.path.isdir(pjoin(self.me_dir,'SubProcesses', P))]
4008 for nb_proc,subdir in enumerate(subproc):
4009 subdir = subdir.strip()
4010 Pdir = pjoin(self.me_dir, 'SubProcesses',subdir)
4011 bindir = pjoin(os.path.relpath(self.dirbin, Pdir))
4012
4013 logger.info(' %s ' % subdir)
4014
4015 for match in glob.glob(pjoin(Pdir, '*ajob*')):
4016 if os.path.basename(match)[:4] in ['ajob', 'wait', 'run.', 'done']:
4017 os.remove(pjoin(Pdir, match))
4018
4019 devnull = os.open(os.devnull, os.O_RDWR)
4020 logfile = pjoin(Pdir, 'gen_ximprove.log')
4021 proc = misc.Popen([pjoin(bindir, 'gen_ximprove')],
4022 stdin=subprocess.PIPE,
4023 stdout=open(logfile,'w'),
4024 cwd=Pdir)
4025 proc.communicate('%s 1 F\n' % (precision))
4026
4027 if os.path.exists(pjoin(Pdir, 'ajob1')):
4028
4029
4030 os.system("chmod +x %s/ajob*" % Pdir)
4031 alljobs = glob.glob(pjoin(Pdir,'ajob*'))
4032 nb_tot = len(alljobs)
4033 self.total_jobs += nb_tot
4034 for i, job in enumerate(alljobs):
4035 job = os.path.basename(job)
4036 self.launch_job('./%s' % job, cwd=Pdir, remaining=(nb_tot-i-1),
4037 run_type='Refine number %s on %s (%s/%s)' %
4038 (self.nb_refine, subdir, nb_proc+1, len(subproc)))
4039 self.monitor(run_type='All job submitted for refine number %s' %
4040 self.nb_refine)
4041
4042 self.update_status("Combining runs", level='parton')
4043 try:
4044 os.remove(pjoin(Pdir, 'combine_runs.log'))
4045 except:
4046 pass
4047
4048 bindir = pjoin(os.path.relpath(self.dirbin, pjoin(self.me_dir,'SubProcesses')))
4049 misc.call([pjoin(bindir, 'combine_runs')],
4050 cwd=pjoin(self.me_dir,'SubProcesses'),
4051 stdout=devnull)
4052
4053
4054 cross, error = sum_html.make_all_html_results(self)
4055 self.results.add_detail('cross', cross)
4056 self.results.add_detail('error', error)
4057
4058
4059 self.update_status('finish refine', 'parton', makehtml=False)
4060