1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """A user friendly command line interface to access MadGraph5_aMC@NLO features.
16 Uses the cmd package for command interpretation and tab completion.
17 """
18 from __future__ import division
19
20 import atexit
21 import cmath
22 import cmd
23 import glob
24 import logging
25 import math
26 import optparse
27 import os
28 import pydoc
29 import random
30 import re
31 import shutil
32 import signal
33 import stat
34 import subprocess
35 import sys
36 import time
37 import traceback
38
39
40 try:
41 import readline
42 GNU_SPLITTING = ('GNU' in readline.__doc__)
43 except:
44 GNU_SPLITTING = True
45
46 root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
47 root_path = os.path.split(root_path)[0]
48 sys.path.insert(0, os.path.join(root_path,'bin'))
49
50
51 pjoin = os.path.join
52
53 logger = logging.getLogger('madgraph.stdout')
54 logger_stderr = logging.getLogger('madgraph.stderr')
55
56
57 try:
58
59 import madgraph.interface.extended_cmd as cmd
60 import madgraph.various.banner as banner_mod
61 import madgraph.various.misc as misc
62 import madgraph.iolibs.files as files
63 import madgraph.various.cluster as cluster
64 import models.check_param_card as check_param_card
65 from madgraph import InvalidCmd, MadGraph5Error, MG5DIR
66 MADEVENT=False
67 except Exception, error:
68 if __debug__:
69 print error
70
71 import internal.extended_cmd as cmd
72 import internal.banner as banner_mod
73 import internal.misc as misc
74 import internal.cluster as cluster
75 import internal.check_param_card as check_param_card
76 import internal.files as files
77 from internal import InvalidCmd, MadGraph5Error
78 MADEVENT=True
84 """ The Series of help routins in common between amcatnlo_run and
85 madevent interface"""
86
88 logger.info("syntax: treatcards [param|run] [--output_dir=] [--param_card=] [--run_card=]")
89 logger.info("-- create the .inc files containing the cards information." )
90
92 logger.info("syntax: set %s argument" % "|".join(self._set_options))
93 logger.info("-- set options")
94 logger.info(" stdout_level DEBUG|INFO|WARNING|ERROR|CRITICAL")
95 logger.info(" change the default level for printed information")
96 logger.info(" timeout VALUE")
97 logger.info(" (default 20) Seconds allowed to answer questions.")
98 logger.info(" Note that pressing tab always stops the timer.")
99 logger.info(" cluster_temp_path PATH")
100 logger.info(" (default None) Allow to perform the run in PATH directory")
101 logger.info(" This allow to not run on the central disk. This is not used")
102 logger.info(" by condor cluster (since condor has it's own way to prevent it).")
103
105 logger.info("syntax: help [RUN] [%s] [-f]" % '|'.join(self._plot_mode))
106 logger.info("-- create the plot for the RUN (current run by default)")
107 logger.info(" at the different stage of the event generation")
108 logger.info(" Note than more than one mode can be specified in the same command.")
109 logger.info(" This require to have MadAnalysis and td require. By default")
110 logger.info(" if those programs are installed correctly, the creation")
111 logger.info(" will be performed automaticaly during the event generation.")
112 logger.info(" -f options: answer all question by default.")
113
115 logger.info("syntax: compute_widths Particle [Particles] [--precision=] [--path=Param_card] [--output=PATH]")
116 logger.info("-- Compute the widths for the particles specified.")
117 logger.info(" By default, this takes the current param_card and overwrites it.")
118 logger.info(" Precision allows to define when to include three/four/... body decays (LO).")
119 logger.info(" If this number is an integer then all N-body decay will be included.")
120
121
123 logger.info("syntax: pythia [RUN] [--run_options]")
124 logger.info("-- run pythia on RUN (current one by default)")
125 self.run_options_help([('-f','answer all question by default'),
126 ('--tag=', 'define the tag for the pythia run'),
127 ('--no_default', 'not run if pythia_card not present')])
128
130 logger.info("syntax: pgs [RUN] [--run_options]")
131 logger.info("-- run pgs on RUN (current one by default)")
132 self.run_options_help([('-f','answer all question by default'),
133 ('--tag=', 'define the tag for the pgs run'),
134 ('--no_default', 'not run if pgs_card not present')])
135
137 logger.info("syntax: delphes [RUN] [--run_options]")
138 logger.info("-- run delphes on RUN (current one by default)")
139 self.run_options_help([('-f','answer all question by default'),
140 ('--tag=', 'define the tag for the delphes run'),
141 ('--no_default', 'not run if delphes_card not present')])
142
144 if not skip_syntax:
145 logger.info("syntax: decay_events [RUN]")
146 logger.info("This functionality allows for the decay of resonances")
147 logger.info("in a .lhe file, keeping track of the spin correlation effets.")
148 logger.info("BE AWARE OF THE CURRENT LIMITATIONS:")
149 logger.info(" (1) Only a succession of 2 body decay are currently allowed")
150
154 """ The Series of check routines in common between amcatnlo_run and
155 madevent interface"""
156
158 """ check the validity of the line"""
159
160 if len(args) < 2:
161 self.help_set()
162 raise self.InvalidCmd('set needs an option and an argument')
163
164 if args[0] not in self._set_options + self.options.keys():
165 self.help_set()
166 raise self.InvalidCmd('Possible options for set are %s' % \
167 self._set_options)
168
169 if args[0] in ['stdout_level']:
170 if args[1] not in ['DEBUG','INFO','WARNING','ERROR','CRITICAL'] \
171 and not args[1].isdigit():
172 raise self.InvalidCmd('output_level needs ' + \
173 'a valid level')
174
175 if args[0] in ['timeout']:
176 if not args[1].isdigit():
177 raise self.InvalidCmd('timeout values should be a integer')
178
180 """check that the model is loadable and check that the format is of the
181 type: PART PATH --output=PATH -f --precision=N
182 return the model.
183 """
184
185
186 if MADEVENT and not self.options['mg5_path']:
187 raise self.InvalidCmd, '''The automatic computations of widths requires that MG5 is installed on the system.
188 You can install it and set his path in ./Cards/me5_configuration.txt'''
189 elif MADEVENT:
190 sys.path.append(self.options['mg5_path'])
191 try:
192 import models.model_reader as model_reader
193 import models.import_ufo as import_ufo
194 except ImportError:
195 raise self.ConfigurationError, '''Can\'t load MG5.
196 The variable mg5_path should not be correctly configure.'''
197
198 ufo_path = pjoin(self.me_dir,'bin','internal', 'ufomodel')
199
200 if not MADEVENT:
201 modelname = self.find_model_name()
202
203
204
205 model = import_ufo.import_model(modelname, decay=True,
206 restrict=True)
207 if self.mother and self.mother.options['complex_mass_scheme']:
208 model.change_mass_to_complex_scheme()
209 else:
210 model = import_ufo.import_model(pjoin(self.me_dir,'bin','internal', 'ufomodel'),
211 decay=True)
212
213 has_cms = re.compile(r'''set\s+complex_mass_scheme\s*(True|T|1|true|$|;)''')
214 if has_cms.search(open(pjoin(self.me_dir,'Cards','proc_card_mg5.dat')\
215 ).read()):
216 model.change_mass_to_complex_scheme()
217
218
219
220
221
222
223 if '-modelname' in open(pjoin(self.me_dir,'Cards','proc_card_mg5.dat')).read():
224 model.pass_particles_name_in_mg_default()
225 model = model_reader.ModelReader(model)
226 particles_name = dict([(p.get('name'), p.get('pdg_code'))
227 for p in model.get('particles')])
228 particles_name.update(dict([(p.get('antiname'), p.get('pdg_code'))
229 for p in model.get('particles')]))
230
231 output = {'model': model, 'force': False, 'output': None,
232 'path':None, 'particles': set(), 'body_decay':4.0025,
233 'min_br':None, 'precision_channel':0.01}
234 for arg in args:
235 if arg.startswith('--output='):
236 output_path = arg.split('=',1)[1]
237 if not os.path.exists(output_path):
238 raise self.InvalidCmd, 'Invalid Path for the output. Please retry.'
239 if not os.path.isfile(output_path):
240 output_path = pjoin(output_path, 'param_card.dat')
241 output['output'] = output_path
242 elif arg == '-f':
243 output['force'] = True
244 elif os.path.isfile(arg):
245 ftype = self.detect_card_type(arg)
246 if ftype != 'param_card.dat':
247 raise self.InvalidCmd , '%s is not a valid param_card.' % arg
248 output['path'] = arg
249 elif arg.startswith('--path='):
250 arg = arg.split('=',1)[1]
251 ftype = self.detect_card_type(arg)
252 if ftype != 'param_card.dat':
253 raise self.InvalidCmd , '%s is not a valid param_card.' % arg
254 output['path'] = arg
255 elif arg.startswith('--'):
256 name, value = arg.split('=',1)
257 try:
258 value = float(value)
259 except Exception:
260 raise self.InvalidCmd, '--%s requires integer or a float' % name
261 output[name[2:]] = float(value)
262 elif arg in particles_name:
263
264 output['particles'].add(particles_name[arg])
265 elif arg.isdigit() and int(arg) in particles_name.values():
266 output['particles'].add(eval(arg))
267 elif arg == 'all':
268 output['particles'] = set(['all'])
269 else:
270 self.help_compute_widths()
271 raise self.InvalidCmd, '%s is not a valid argument for compute_widths' % arg
272 if self.force:
273 output['force'] = True
274
275 if not output['particles']:
276 raise self.InvalidCmd, '''This routines requires at least one particle in order to compute
277 the related width'''
278
279 if output['output'] is None:
280 output['output'] = output['path']
281
282 return output
283
285 """ check the validity of the line """
286
287 if len(args) != 1:
288 self.help_open()
289 raise self.InvalidCmd('OPEN command requires exactly one argument')
290
291 if args[0].startswith('./'):
292 if not os.path.isfile(args[0]):
293 raise self.InvalidCmd('%s: not such file' % args[0])
294 return True
295
296
297 if not self.me_dir:
298 if not os.path.isfile(args[0]):
299 self.help_open()
300 raise self.InvalidCmd('No MadEvent path defined. Unable to associate this name to a file')
301 else:
302 return True
303
304 path = self.me_dir
305 if os.path.isfile(os.path.join(path,args[0])):
306 args[0] = os.path.join(path,args[0])
307 elif os.path.isfile(os.path.join(path,'Cards',args[0])):
308 args[0] = os.path.join(path,'Cards',args[0])
309 elif os.path.isfile(os.path.join(path,'HTML',args[0])):
310 args[0] = os.path.join(path,'HTML',args[0])
311
312 elif '_card.dat' in args[0]:
313 name = args[0].replace('_card.dat','_card_default.dat')
314 if os.path.isfile(os.path.join(path,'Cards', name)):
315 files.cp(os.path.join(path,'Cards', name), os.path.join(path,'Cards', args[0]))
316 args[0] = os.path.join(path,'Cards', args[0])
317 else:
318 raise self.InvalidCmd('No default path for this file')
319 elif not os.path.isfile(args[0]):
320 raise self.InvalidCmd('No default path for this file')
321
323 """check that treatcards arguments are valid
324 [param|run|all] [--output_dir=] [--param_card=] [--run_card=]
325 """
326
327 opt = {'output_dir':pjoin(self.me_dir,'Source'),
328 'param_card':pjoin(self.me_dir,'Cards','param_card.dat'),
329 'run_card':pjoin(self.me_dir,'Cards','run_card.dat')}
330 mode = 'all'
331 for arg in args:
332 if arg.startswith('--') and '=' in arg:
333 key,value =arg[2:].split('=',1)
334 if not key in opt:
335 self.help_treatcards()
336 raise self.InvalidCmd('Invalid option for treatcards command:%s ' \
337 % key)
338 if key in ['param_card', 'run_card']:
339 if os.path.isfile(value):
340 card_name = self.detect_card_type(value)
341 if card_name != key:
342 raise self.InvalidCmd('Format for input file detected as %s while expecting %s'
343 % (card_name, key))
344 opt[key] = value
345 elif os.path.isfile(pjoin(self.me_dir,value)):
346 card_name = self.detect_card_type(pjoin(self.me_dir,value))
347 if card_name != key:
348 raise self.InvalidCmd('Format for input file detected as %s while expecting %s'
349 % (card_name, key))
350 opt[key] = value
351 else:
352 raise self.InvalidCmd('No such file: %s ' % value)
353 elif key in ['output_dir']:
354 if os.path.isdir(value):
355 opt[key] = value
356 elif os.path.isdir(pjoin(self.me_dir,value)):
357 opt[key] = pjoin(self.me_dir, value)
358 else:
359 raise self.InvalidCmd('No such directory: %s' % value)
360 elif arg in ['param','run','all']:
361 mode = arg
362 else:
363 self.help_treatcards()
364 raise self.InvalidCmd('Unvalid argument %s' % arg)
365
366 return mode, opt
367
369 """Check the argument for decay_events command
370 syntax: decay_events [NAME]
371 Note that other option are already remove at this point
372 """
373
374 opts = []
375 if '-from_cards' in args:
376 args.remove('-from_cards')
377 opts.append('-from_cards')
378
379 if len(args) == 0:
380 if self.run_name:
381 args.insert(0, self.run_name)
382 elif self.results.lastrun:
383 args.insert(0, self.results.lastrun)
384 else:
385 raise self.InvalidCmd('No run name currently defined. Please add this information.')
386 return
387
388 if args[0] != self.run_name:
389 self.set_run_name(args[0])
390
391 args[0] = self.get_events_path(args[0])
392
393 args += opts
394
396 """Check the argument for decay_events command
397 syntax: decay_events [NAME]
398 Note that other option are already remove at this point
399 """
400
401 if len(args) == 0:
402 if self.run_name:
403 args.insert(0, self.run_name)
404 elif self.results.lastrun:
405 args.insert(0, self.results.lastrun)
406 else:
407 raise self.InvalidCmd('No run name currently defined. Please add this information.')
408 return
409
410 if args[0] and os.path.isfile(args[0]):
411 pass
412 else:
413 if args[0] != self.run_name:
414 self.set_run_name(args[0], allow_new_tag=False)
415
416 args[0] = self.get_events_path(args[0])
417
418
420 """Check the argument for decay_events command
421 syntax: decay_events [NAME]
422 Note that other option are already remove at this point
423 """
424
425
426 if self.mode == 'madevent':
427 possible_path = [
428 pjoin(self.me_dir,'Events', run_name, 'unweighted_events.lhe.gz'),
429 pjoin(self.me_dir,'Events', run_name, 'unweighted_events.lhe')]
430 else:
431 possible_path = [
432 pjoin(self.me_dir,'Events', run_name, 'events.lhe.gz'),
433 pjoin(self.me_dir,'Events', run_name, 'events.lhe')]
434
435 for path in possible_path:
436 if os.path.exists(path):
437 correct_path = path
438 break
439 else:
440 raise self.InvalidCmd('No events file corresponding to %s run. ' % run_name)
441 return correct_path
442
449
450
451
452
453 -class CommonRunCmd(HelpToCmd, CheckValidForCmd, cmd.Cmd):
454
455 debug_output = 'ME5_debug'
456 helporder = ['Main Commands', 'Documented commands', 'Require MG5 directory',
457 'Advanced commands']
458
459
460
461 options_configuration = {'pythia8_path': './pythia8',
462 'hwpp_path': './herwigPP',
463 'thepeg_path': './thepeg',
464 'hepmc_path': './hepmc',
465 'madanalysis_path': './MadAnalysis',
466 'pythia-pgs_path':'./pythia-pgs',
467 'td_path':'./td',
468 'delphes_path':'./Delphes',
469 'exrootanalysis_path':'./ExRootAnalysis',
470 'syscalc_path': './SysCalc',
471 'lhapdf': 'lhapdf-config',
472 'timeout': 60,
473 'web_browser':None,
474 'eps_viewer':None,
475 'text_editor':None,
476 'fortran_compiler':None,
477 'cpp_compiler': None,
478 'auto_update':7,
479 'cluster_type': 'condor',
480 'cluster_status_update': (600, 30),
481 'cluster_nb_retry':1,
482 'cluster_retry_wait':300}
483
484 options_madgraph= {'stdout_level':None}
485
486 options_madevent = {'automatic_html_opening':True,
487 'run_mode':2,
488 'cluster_queue':'madgraph',
489 'cluster_time':None,
490 'cluster_memory':None,
491 'nb_core': None,
492 'cluster_temp_path':None}
493
494
495 - def __init__(self, me_dir, options, *args, **opts):
496 """common"""
497
498 cmd.Cmd.__init__(self, *args, **opts)
499
500 if me_dir is None and MADEVENT:
501 me_dir = root_path
502
503 self.me_dir = me_dir
504 self.options = options
505
506
507 self.status = pjoin(self.me_dir, 'status')
508 self.error = pjoin(self.me_dir, 'error')
509 self.dirbin = pjoin(self.me_dir, 'bin', 'internal')
510
511
512 if os.path.exists(pjoin(me_dir,'RunWeb')):
513 message = '''Another instance of the program is currently running.
514 (for this exact same directory) Please wait that this is instance is
515 closed. If no instance is running, you can delete the file
516 %s and try again.''' % pjoin(me_dir,'RunWeb')
517 raise AlreadyRunning, message
518 else:
519 pid = os.getpid()
520 fsock = open(pjoin(me_dir,'RunWeb'),'w')
521 fsock.write(`pid`)
522 fsock.close()
523
524 misc.Popen([os.path.relpath(pjoin(self.dirbin, 'gen_cardhtml-pl'), me_dir)],
525 cwd=me_dir)
526
527 self.to_store = []
528 self.run_name = None
529 self.run_tag = None
530 self.banner = None
531
532 self.set_configuration()
533 self.configure_run_mode(self.options['run_mode'])
534
535
536
537 nexternal = open(pjoin(self.me_dir,'Source','nexternal.inc')).read()
538 found = re.search("PARAMETER\s*\(NINCOMING=(\d)\)", nexternal)
539 self.ninitial = int(found.group(1))
540
541
542
576
577
579 """Advanced commands: create .inc files from param_card.dat/run_card.dat"""
580
581
582 keepwidth = False
583 if '--keepwidth' in line:
584 keepwidth = True
585 line = line.replace('--keepwidth', '')
586 args = self.split_arg(line)
587 mode, opt = self.check_treatcards(args)
588
589 if mode in ['run', 'all']:
590 if not hasattr(self, 'run_card'):
591 if amcatnlo:
592 run_card = banner_mod.RunCardNLO(opt['run_card'])
593 else:
594 run_card = banner_mod.RunCard(opt['run_card'])
595 else:
596 run_card = self.run_card
597
598 run_card.write_include_file(pjoin(opt['output_dir'],'run_card.inc'))
599
600 if mode in ['param', 'all']:
601 if os.path.exists(pjoin(self.me_dir, 'Source', 'MODEL', 'mp_coupl.inc')):
602 param_card = check_param_card.ParamCardMP(opt['param_card'])
603 else:
604 param_card = check_param_card.ParamCard(opt['param_card'])
605 outfile = pjoin(opt['output_dir'], 'param_card.inc')
606 ident_card = pjoin(self.me_dir,'Cards','ident_card.dat')
607 if os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')):
608 default = pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')
609 elif os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')):
610 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
611 elif not os.path.exists(pjoin(self.me_dir,'bin','internal','ufomodel')):
612 fsock = open(pjoin(self.me_dir,'Source','param_card.inc'),'w')
613 fsock.write(' ')
614 fsock.close()
615 return
616 else:
617 subprocess.call(['python', 'write_param_card.py'],
618 cwd=pjoin(self.me_dir,'bin','internal','ufomodel'))
619 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
620
621
622 if amcatnlo and not keepwidth:
623
624 pids = self.get_pid_final_states()
625
626 if not MADEVENT and pjoin(self.me_dir,'bin','internal') not in sys.path:
627 sys.path.insert(0,pjoin(self.me_dir,'bin','internal'))
628
629
630
631 to_del = [name for name in sys.modules.keys()
632 if name.startswith('internal.ufomodel')
633 or name.startswith('ufomodel')]
634 for name in to_del:
635 del(sys.modules[name])
636
637 import ufomodel as ufomodel
638 zero = ufomodel.parameters.ZERO
639 no_width = [p for p in ufomodel.all_particles
640 if (str(p.pdg_code) in pids or str(-p.pdg_code) in pids)
641 and p.color != 1 and p.width != zero]
642 done = []
643 for part in no_width:
644 if abs(part.pdg_code) in done:
645 continue
646 done.append(abs(part.pdg_code))
647 param = param_card['decay'].get((part.pdg_code,))
648
649 if param.value != 0:
650 logger.info('''For gauge cancellation, the width of \'%s\' has been set to zero.'''
651 % part.name,'$MG:color:BLACK')
652 param.value = 0
653
654 param_card.write_inc_file(outfile, ident_card, default)
655
656
658 """ """
659 if not self.options['madanalysis_path']:
660 plot = False
661
662 self.ask_edit_card_static(cards, mode, plot, self.options['timeout'],
663 self.ask)
664
665 @staticmethod
668 if not ask:
669 ask = CommonRunCmd.ask
670
671 def path2name(path):
672 if '_card' in path:
673 return path.split('_card')[0]
674 elif path == 'delphes_trigger.dat':
675 return 'trigger'
676 elif path == 'input.lhco':
677 return 'lhco'
678 else:
679 raise Exception, 'Unknow cards name %s' % path
680
681
682
683 question = """Do you want to edit a card (press enter to bypass editing)?\n"""
684 possible_answer = ['0', 'done']
685 card = {0:'done'}
686
687 for i, card_name in enumerate(cards):
688 imode = path2name(card_name)
689 possible_answer.append(i+1)
690 possible_answer.append(imode)
691 question += ' %s / %-10s : %s\n' % (i+1, imode, card_name)
692 card[i+1] = imode
693 if plot:
694 question += ' 9 / %-10s : plot_card.dat\n' % 'plot'
695 possible_answer.append(9)
696 possible_answer.append('plot')
697 card[9] = 'plot'
698
699 if 'param_card.dat' in cards:
700
701 question += ' you can also\n'
702 question += ' - enter the path to a valid card or banner.\n'
703 question += ' - use the \'set\' command to modify a parameter directly.\n'
704 question += ' The set option works only for param_card and run_card.\n'
705 question += ' Type \'help set\' for more information on this command.\n'
706 question += ' - call an external program (ASperGE/MadWidth/...).\n'
707 question += ' Type \'help\' for the list of available command\n'
708 else:
709 question += ' you can also\n'
710 question += ' - enter the path to a valid card.\n'
711 if 'transfer_card.dat' in cards:
712 question += ' - use the \'change_tf\' command to set a transfer functions.\n'
713
714 out = 'to_run'
715 while out not in ['0', 'done']:
716 out = ask(question, '0', possible_answer, timeout=int(1.5*timeout),
717 path_msg='enter path', ask_class = AskforEditCard,
718 cards=cards, mode=mode, **opt)
719
720
721 @staticmethod
723 """detect the type of the card. Return value are
724 banner
725 param_card.dat
726 run_card.dat
727 pythia_card.dat
728 plot_card.dat
729 pgs_card.dat
730 delphes_card.dat
731 delphes_trigger.dat
732 shower_card.dat [aMCatNLO]
733 madspin_card.dat [MS]
734 transfer_card.dat [MW]
735 madweight_card.dat [MW]
736 """
737
738 text = open(path).read(50000)
739 if text == '':
740 logger.warning('File %s is empty' % path)
741 return 'unknown'
742 text = re.findall('(<MGVersion>|ParticlePropagator|<mg5proccard>|CEN_max_tracker|#TRIGGER CARD|parameter set name|muon eta coverage|QES_over_ref|MSTP|b_stable|MSTU|Begin Minpts|gridpack|ebeam1|block\s+mw_run|BLOCK|DECAY|launch|madspin|transfer_card\.dat|set)', text, re.I)
743 text = [t.lower() for t in text]
744 if '<mgversion>' in text or '<mg5proccard>' in text:
745 return 'banner'
746 elif 'particlepropagator' in text:
747 return 'delphes_card.dat'
748 elif 'cen_max_tracker' in text:
749 return 'delphes_card.dat'
750 elif '#trigger card' in text:
751 return 'delphes_trigger.dat'
752 elif 'parameter set name' in text:
753 return 'pgs_card.dat'
754 elif 'muon eta coverage' in text:
755 return 'pgs_card.dat'
756 elif 'mstp' in text and not 'b_stable' in text:
757 return 'pythia_card.dat'
758 elif 'begin minpts' in text:
759 return 'plot_card.dat'
760 elif ('gridpack' in text and 'ebeam1' in text) or \
761 ('qes_over_ref' in text and 'ebeam1' in text):
762 return 'run_card.dat'
763 elif any(t.endswith('mw_run') for t in text):
764 return 'madweight_card.dat'
765 elif 'transfer_card.dat' in text:
766 return 'transfer_card.dat'
767 elif 'block' in text and 'decay' in text:
768 return 'param_card.dat'
769 elif 'b_stable' in text:
770 return 'shower_card.dat'
771 elif 'decay' in text and 'launch' in text and 'madspin' in text:
772 return 'madspin_card.dat'
773 elif 'launch' in text and 'set' in text:
774 return 'reweight_card.dat'
775 elif 'decay' in text and 'launch' in text:
776 return 'madspin_card.dat'
777 else:
778 return 'unknown'
779
780
781
783 """create automatically a tag"""
784
785 used_tags = [r['tag'] for r in self.results[self.run_name]]
786 i=0
787 while 1:
788 i+=1
789 if 'tag_%s' %i not in used_tags:
790 return 'tag_%s' % i
791
792
793
794 - def create_plot(self, mode='parton', event_path=None, output=None, tag=None):
795 """create the plot"""
796
797 madir = self.options['madanalysis_path']
798 if not tag:
799 tag = self.run_card['run_tag']
800 td = self.options['td_path']
801
802 if not madir or not td or \
803 not os.path.exists(pjoin(self.me_dir, 'Cards', 'plot_card.dat')):
804 return False
805
806 if 'ickkw' in self.run_card and int(self.run_card['ickkw']) and \
807 mode == 'Pythia':
808 self.update_status('Create matching plots for Pythia', level='pythia')
809
810 if not os.path.exists(pjoin(self.me_dir,'Events','events.tree')):
811 misc.gunzip(pjoin(self.me_dir,'Events',
812 self.run_name, '%s_pythia_events.tree.gz' % tag), keep=True,
813 stdout=pjoin(self.me_dir,'Events','events.tree'))
814 files.mv(pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_xsecs.tree'),
815 pjoin(self.me_dir,'Events','xsecs.tree'))
816
817
818 misc.call([self.dirbin+'/create_matching_plots.sh',
819 self.run_name, tag, madir],
820 stdout = os.open(os.devnull, os.O_RDWR),
821 cwd=pjoin(self.me_dir,'Events'))
822
823
824 misc.gzip(pjoin(self.me_dir,"Events","events.tree"),
825 stdout=pjoin(self.me_dir,'Events',self.run_name, tag + '_pythia_events.tree.gz'))
826 files.mv(pjoin(self.me_dir,'Events','xsecs.tree'),
827 pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_xsecs.tree'))
828
829
830 if not event_path:
831 if mode == 'parton':
832 possibilities=[
833 pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'),
834 pjoin(self.me_dir, 'Events', 'unweighted_events.lhe.gz'),
835 pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe'),
836 pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe.gz')]
837 for event_path in possibilities:
838 if os.path.exists(event_path):
839 break
840 output = pjoin(self.me_dir, 'HTML',self.run_name, 'plots_parton.html')
841
842 elif mode == 'Pythia':
843 event_path = pjoin(self.me_dir, 'Events','pythia_events.lhe')
844 output = pjoin(self.me_dir, 'HTML',self.run_name,
845 'plots_pythia_%s.html' % tag)
846 elif mode == 'PGS':
847 event_path = pjoin(self.me_dir, 'Events', self.run_name,
848 '%s_pgs_events.lhco' % tag)
849 output = pjoin(self.me_dir, 'HTML',self.run_name,
850 'plots_pgs_%s.html' % tag)
851 elif mode == 'Delphes':
852 event_path = pjoin(self.me_dir, 'Events', self.run_name,'%s_delphes_events.lhco' % tag)
853 output = pjoin(self.me_dir, 'HTML',self.run_name,
854 'plots_delphes_%s.html' % tag)
855 elif mode == "shower":
856 event_path = pjoin(self.me_dir, 'Events','pythia_events.lhe')
857 output = pjoin(self.me_dir, 'HTML',self.run_name,
858 'plots_shower_%s.html' % tag)
859 if not self.options['pythia-pgs_path']:
860 return
861 else:
862 raise self.InvalidCmd, 'Invalid mode %s' % mode
863 elif mode == 'reweight' and not output:
864 output = pjoin(self.me_dir, 'HTML',self.run_name,
865 'plots_%s.html' % tag)
866
867 if not os.path.exists(event_path):
868 if os.path.exists(event_path+'.gz'):
869 misc.gunzip('%s.gz' % event_path)
870 else:
871 raise self.InvalidCmd, 'Events file %s does not exist' % event_path
872 elif event_path.endswith(".gz"):
873 misc.gunzip(event_path)
874 event_path = event_path[:-3]
875
876
877 self.update_status('Creating Plots for %s level' % mode, level = mode.lower())
878
879 mode = mode.lower()
880 if mode not in ['parton', 'reweight']:
881 plot_dir = pjoin(self.me_dir, 'HTML', self.run_name,'plots_%s_%s' % (mode.lower(),tag))
882 elif mode == 'parton':
883 plot_dir = pjoin(self.me_dir, 'HTML', self.run_name,'plots_parton')
884 else:
885 plot_dir =pjoin(self.me_dir, 'HTML', self.run_name,'plots_%s' % (tag))
886
887 if not os.path.isdir(plot_dir):
888 os.makedirs(plot_dir)
889
890 files.ln(pjoin(self.me_dir, 'Cards','plot_card.dat'), plot_dir, 'ma_card.dat')
891
892 try:
893 proc = misc.Popen([os.path.join(madir, 'plot_events')],
894 stdout = open(pjoin(plot_dir, 'plot.log'),'w'),
895 stderr = subprocess.STDOUT,
896 stdin=subprocess.PIPE,
897 cwd=plot_dir)
898 proc.communicate('%s\n' % event_path)
899 del proc
900
901 misc.call(['%s/plot' % self.dirbin, madir, td],
902 stdout = open(pjoin(plot_dir, 'plot.log'),'a'),
903 stderr = subprocess.STDOUT,
904 cwd=plot_dir)
905
906 misc.call(['%s/plot_page-pl' % self.dirbin,
907 os.path.basename(plot_dir),
908 mode],
909 stdout = open(pjoin(plot_dir, 'plot.log'),'a'),
910 stderr = subprocess.STDOUT,
911 cwd=pjoin(self.me_dir, 'HTML', self.run_name))
912
913 shutil.move(pjoin(self.me_dir, 'HTML',self.run_name ,'plots.html'),
914 output)
915
916 logger.info("Plots for %s level generated, see %s" % \
917 (mode, output))
918 except OSError, error:
919 logger.error('fail to create plot: %s. Please check that MadAnalysis is correctly installed.' % error)
920
921 self.update_status('End Plots for %s level' % mode, level = mode.lower(),
922 makehtml=False)
923
924 return True
925
927 """Run hep2lhe on the file Events/pythia_events.hep"""
928
929 if not self.options['pythia-pgs_path']:
930 raise self.InvalidCmd, 'No pythia-pgs path defined'
931
932 pydir = pjoin(self.options['pythia-pgs_path'], 'src')
933 eradir = self.options['exrootanalysis_path']
934
935
936 if misc.is_executable(pjoin(pydir, 'hep2lhe')):
937 self.update_status('Creating shower LHE File (for plot)', level='pythia')
938
939 out = open(pjoin(self.me_dir,'Events','pythia_events.lhe'), 'w')
940
941 out.writelines('<!--\n')
942 out.writelines('# Warning! Never use this file for detector studies!\n')
943 out.writelines('-->\n<!--\n')
944 if banner_path:
945 out.writelines(open(banner_path).read().replace('<LesHouchesEvents version="1.0">',''))
946 out.writelines('\n-->\n')
947 out.close()
948
949 self.cluster.launch_and_wait(self.dirbin+'/run_hep2lhe',
950 argument= [pydir],
951 cwd=pjoin(self.me_dir,'Events'),
952 stdout=open(os.devnull,'w'))
953
954 logger.info('Warning! Never use this lhe file for detector studies!')
955
956 if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHEFConverter')):
957 self.update_status('Creating Pythia LHE Root File', level='pythia')
958 try:
959 misc.call([eradir+'/ExRootLHEFConverter',
960 'pythia_events.lhe',
961 pjoin(self.run_name, '%s_pythia_lhe_events.root' % self.run_tag)],
962 cwd=pjoin(self.me_dir,'Events'))
963 except Exception, error:
964 misc.sprint('ExRootLHEFConverter fails', str(error),
965 log=logger)
966 pass
967
969 """Dummy routine, to be overwritten by daughter classes"""
970
971 pass
972
973
975 """launch pgs"""
976
977 args = self.split_arg(line)
978
979 if '--no_default' in args:
980 no_default = True
981 args.remove('--no_default')
982 else:
983 no_default = False
984
985
986
987
988
989
990 lock = self.check_pgs(args)
991
992
993 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')):
994 if no_default:
995 logger.info('No pgs_card detected, so not run pgs')
996 return
997
998 files.cp(pjoin(self.me_dir, 'Cards', 'pgs_card_default.dat'),
999 pjoin(self.me_dir, 'Cards', 'pgs_card.dat'))
1000 logger.info('No pgs card found. Take the default one.')
1001
1002 if not (no_default or self.force):
1003 self.ask_edit_cards(['pgs_card.dat'])
1004
1005 self.update_status('prepare PGS run', level=None)
1006
1007 pgsdir = pjoin(self.options['pythia-pgs_path'], 'src')
1008 eradir = self.options['exrootanalysis_path']
1009 madir = self.options['madanalysis_path']
1010 td = self.options['td_path']
1011
1012
1013 if not misc.is_executable(pjoin(pgsdir, 'pgs')):
1014 logger.info('No PGS executable -- running make')
1015 misc.compile(cwd=pgsdir)
1016
1017 self.update_status('Running PGS', level='pgs')
1018
1019 tag = self.run_tag
1020
1021 banner_path = pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, self.run_tag))
1022 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')):
1023 self.banner.add(pjoin(self.me_dir, 'Cards','pgs_card.dat'))
1024 self.banner.write(banner_path)
1025 else:
1026 open(banner_path, 'w').close()
1027
1028
1029
1030
1031 if lock:
1032 lock.acquire()
1033
1034 ff = open(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'), 'w')
1035 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')):
1036 text = open(banner_path).read()
1037 text = '#%s' % text.replace('\n','\n#')
1038 dico = self.results[self.run_name].get_current_info()
1039 text +='\n## Integrated weight (pb) : %.4g' % dico['cross']
1040 text +='\n## Number of Event : %s\n' % dico['nb_event']
1041 ff.writelines(text)
1042 ff.close()
1043
1044 try:
1045 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done'))
1046 except Exception:
1047 pass
1048
1049 pgs_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_pgs.log" % tag)
1050 self.cluster.launch_and_wait('../bin/internal/run_pgs',
1051 argument=[pgsdir], cwd=pjoin(self.me_dir,'Events'),
1052 stdout=pgs_log, stderr=subprocess.STDOUT)
1053
1054 if not os.path.exists(pjoin(self.me_dir, 'Events', 'pgs.done')):
1055 logger.error('Fail to create LHCO events')
1056 return
1057 else:
1058 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done'))
1059
1060 if os.path.getsize(banner_path) == os.path.getsize(pjoin(self.me_dir, 'Events','pgs_events.lhco')):
1061 misc.call(['cat pgs_uncleaned_events.lhco >> pgs_events.lhco'],
1062 cwd=pjoin(self.me_dir, 'Events'))
1063 os.remove(pjoin(self.me_dir, 'Events', 'pgs_uncleaned_events.lhco '))
1064
1065
1066 if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHCOlympicsConverter')):
1067 self.update_status('Creating PGS Root File', level='pgs')
1068 try:
1069 misc.call([eradir+'/ExRootLHCOlympicsConverter',
1070 'pgs_events.lhco',pjoin('%s/%s_pgs_events.root' % (self.run_name, tag))],
1071 cwd=pjoin(self.me_dir, 'Events'))
1072 except Exception:
1073 logger.warning('fail to produce Root output [problem with ExRootAnalysis')
1074 if os.path.exists(pjoin(self.me_dir, 'Events', 'pgs_events.lhco')):
1075
1076 files.mv(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'),
1077 pjoin(self.me_dir, 'Events', self.run_name, '%s_pgs_events.lhco' % tag))
1078 self.create_plot('PGS')
1079 misc.gzip(pjoin(self.me_dir, 'Events', self.run_name, '%s_pgs_events.lhco' % tag))
1080
1081 self.update_status('finish', level='pgs', makehtml=False)
1082
1083
1085 """Require MG5 directory: Compute automatically the widths of a set
1086 of particles"""
1087
1088 args = self.split_arg(line)
1089 opts = self.check_compute_widths(args)
1090
1091
1092 from madgraph.interface.master_interface import MasterCmd
1093 cmd = MasterCmd()
1094 self.define_child_cmd_interface(cmd, interface=False)
1095 cmd.exec_cmd('set automatic_html_opening False --no_save')
1096 if not opts['path']:
1097 opts['path'] = pjoin(self.me_dir, 'Cards', 'param_card.dat')
1098 if not opts['force'] :
1099 self.ask_edit_cards(['param_card'],[], plot=False)
1100
1101
1102 line = 'compute_widths %s %s' % \
1103 (' '.join([str(i) for i in opts['particles']]),
1104 ' '.join('--%s=%s' % (key,value) for (key,value) in opts.items()
1105 if key not in ['model', 'force', 'particles'] and value))
1106
1107 cmd.exec_cmd(line, model=opts['model'])
1108 self.child = None
1109 del cmd
1110
1111
1113 """Not in help:Print the cross-section/ number of events for a given run"""
1114
1115 args = self.split_arg(line)
1116 options={'path':None, 'mode':'w'}
1117 for arg in list(args):
1118 if arg.startswith('--') and '=' in arg:
1119 name,value=arg.split('=',1)
1120 name = name [2:]
1121 options[name] = value
1122 args.remove(arg)
1123
1124
1125 if len(args) > 0:
1126 run_name = args[0]
1127 else:
1128 if not self.results.current:
1129 raise self.InvalidCmd('no run currently defined. Please specify one.')
1130 else:
1131 run_name = self.results.current['run_name']
1132 if run_name not in self.results:
1133 raise self.InvalidCmd('%s is not a valid run_name or it doesn\'t have any information' \
1134 % run_name)
1135
1136
1137 if len(args) == 2:
1138 tag = args[1]
1139 if tag.isdigit():
1140 tag = int(tag) - 1
1141 if len(self.results[run_name]) < tag:
1142 raise self.InvalidCmd('Only %s different tag available' % \
1143 len(self.results[run_name]))
1144 data = self.results[run_name][tag]
1145 else:
1146 data = self.results[run_name].return_tag(tag)
1147 else:
1148 data = self.results[run_name].return_tag(None)
1149
1150 if options['path']:
1151 self.print_results_in_file(data, options['path'], options['mode'])
1152 else:
1153 self.print_results_in_shell(data)
1154
1155
1156
1158 """ run delphes and make associate root file/plot """
1159
1160 args = self.split_arg(line)
1161
1162 if '--no_default' in args:
1163 no_default = True
1164 args.remove('--no_default')
1165 else:
1166 no_default = False
1167
1168
1169
1170
1171
1172 lock = self.check_delphes(args)
1173 self.update_status('prepare delphes run', level=None)
1174
1175
1176 if os.path.exists(pjoin(self.options['delphes_path'], 'data')):
1177 delphes3 = False
1178 prog = '../bin/internal/run_delphes'
1179 else:
1180 delphes3 = True
1181 prog = '../bin/internal/run_delphes3'
1182
1183
1184
1185 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
1186 if no_default:
1187 logger.info('No delphes_card detected, so not run Delphes')
1188 return
1189
1190 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_card_default.dat'),
1191 pjoin(self.me_dir, 'Cards', 'delphes_card.dat'))
1192 logger.info('No delphes card found. Take the default one.')
1193 if not delphes3 and not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat')):
1194 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_trigger_default.dat'),
1195 pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat'))
1196 if not (no_default or self.force):
1197 if delphes3:
1198 self.ask_edit_cards(['delphes_card.dat'], args)
1199 else:
1200 self.ask_edit_cards(['delphes_card.dat', 'delphes_trigger.dat'], args)
1201
1202 self.update_status('Running Delphes', level=None)
1203
1204 if lock:
1205 lock.acquire()
1206
1207
1208
1209 delphes_dir = self.options['delphes_path']
1210 tag = self.run_tag
1211 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')):
1212 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_card.dat'))
1213 if not delphes3:
1214 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_trigger.dat'))
1215 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, tag)))
1216
1217 cross = self.results[self.run_name].get_current_info()['cross']
1218
1219 delphes_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_delphes.log" % tag)
1220 self.cluster.launch_and_wait(prog,
1221 argument= [delphes_dir, self.run_name, tag, str(cross)],
1222 stdout=delphes_log, stderr=subprocess.STDOUT,
1223 cwd=pjoin(self.me_dir,'Events'))
1224
1225 if not os.path.exists(pjoin(self.me_dir, 'Events',
1226 self.run_name, '%s_delphes_events.lhco' % tag)):
1227 logger.error('Fail to create LHCO events from DELPHES')
1228 return
1229
1230 if os.path.exists(pjoin(self.me_dir,'Events','delphes.root')):
1231 source = pjoin(self.me_dir,'Events','delphes.root')
1232 target = pjoin(self.me_dir,'Events', self.run_name, "%s_delphes_events.root" % tag)
1233 files.mv(source, target)
1234
1235
1236 madir = self.options['madanalysis_path']
1237 td = self.options['td_path']
1238
1239
1240 self.create_plot('Delphes')
1241
1242 if os.path.exists(pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag)):
1243 misc.gzip(pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag))
1244
1245
1246
1247 self.update_status('delphes done', level='delphes', makehtml=False)
1248
1249
1251 """Find the pid of all particles in the final states"""
1252 pids = set()
1253 subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses',
1254 'subproc.mg'))]
1255 nb_init = self.ninitial
1256 pat = re.compile(r'''DATA \(IDUP\(I,\d+\),I=1,\d+\)/([\+\-\d,\s]*)/''', re.I)
1257 for Pdir in subproc:
1258 text = open(pjoin(self.me_dir, 'SubProcesses', Pdir, 'born_leshouche.inc')).read()
1259 group = pat.findall(text)
1260 for particles in group:
1261 particles = particles.split(',')
1262 pids.update(set(particles[nb_init:]))
1263
1264 return pids
1265
1266
1284
1286 """Not in help: exit """
1287
1288
1289 try:
1290 os.remove(pjoin(self.me_dir,'RunWeb'))
1291 except Exception, error:
1292 pass
1293
1294 try:
1295 self.store_result()
1296 except Exception:
1297
1298 pass
1299
1300 try:
1301 self.update_status('', level=None)
1302 except Exception, error:
1303 pass
1304 try:
1305 devnull = open(os.devnull, 'w')
1306 misc.call(['./bin/internal/gen_cardhtml-pl'], cwd=self.me_dir,
1307 stdout=devnull, stderr=devnull)
1308 except Exception:
1309 pass
1310 try:
1311 devnull.close()
1312 except Exception:
1313 pass
1314
1315 return super(CommonRunCmd, self).do_quit(line)
1316
1317
1318
1319 do_EOF = do_quit
1320 do_exit = do_quit
1321
1322
1332
1333
1334 - def do_set(self, line, log=True):
1335 """Set an option, which will be default for coming generations/outputs
1336 """
1337
1338
1339
1340 args = self.split_arg(line)
1341
1342 self.check_set(args)
1343
1344 if args[0] in self.options_configuration and '--no_save' not in args:
1345 self.do_save('options --auto')
1346
1347 if args[0] == "stdout_level":
1348 if args[1].isdigit():
1349 logging.root.setLevel(int(args[1]))
1350 logging.getLogger('madgraph').setLevel(int(args[1]))
1351 else:
1352 logging.root.setLevel(eval('logging.' + args[1]))
1353 logging.getLogger('madgraph').setLevel(eval('logging.' + args[1]))
1354 if log: logger.info('set output information to level: %s' % args[1])
1355 elif args[0] == "fortran_compiler":
1356 if args[1] == 'None':
1357 args[1] = None
1358 self.options['fortran_compiler'] = args[1]
1359 current = misc.detect_current_compiler(pjoin(self.me_dir,'Source','make_opts'), 'fortran')
1360 if current != args[1] and args[1] != None:
1361 misc.mod_compilator(self.me_dir, args[1], current, 'gfortran')
1362 elif args[0] == "cpp_compiler":
1363 if args[1] == 'None':
1364 args[1] = None
1365 self.options['cpp_compiler'] = args[1]
1366 current = misc.detect_current_compiler(pjoin(self.me_dir,'Source','make_opts'), 'cpp')
1367 if current != args[1] and args[1] != None:
1368 misc.mod_compilator(self.me_dir, args[1], current, 'cpp')
1369 elif args[0] == "run_mode":
1370 if not args[1] in [0,1,2,'0','1','2']:
1371 raise self.InvalidCmd, 'run_mode should be 0, 1 or 2.'
1372 self.cluster_mode = int(args[1])
1373 self.options['run_mode'] = self.cluster_mode
1374 elif args[0] in ['cluster_type', 'cluster_queue', 'cluster_temp_path']:
1375 if args[1] == 'None':
1376 args[1] = None
1377 self.options[args[0]] = args[1]
1378
1379
1380 elif args[0] in ['cluster_nb_retry', 'cluster_retry_wait']:
1381 self.options[args[0]] = int(args[1])
1382
1383 elif args[0] == 'nb_core':
1384 if args[1] == 'None':
1385 import multiprocessing
1386 self.nb_core = multiprocessing.cpu_count()
1387 self.options['nb_core'] = self.nb_core
1388 return
1389 if not args[1].isdigit():
1390 raise self.InvalidCmd('nb_core should be a positive number')
1391 self.nb_core = int(args[1])
1392 self.options['nb_core'] = self.nb_core
1393 elif args[0] == 'timeout':
1394 self.options[args[0]] = int(args[1])
1395 elif args[0] == 'cluster_status_update':
1396 if '(' in args[1]:
1397 data = ' '.join([a for a in args[1:] if not a.startswith('-')])
1398 data = data.replace('(','').replace(')','').replace(',',' ').split()
1399 first, second = data[:2]
1400 else:
1401 first, second = args[1:3]
1402
1403 self.options[args[0]] = (int(first), int(second))
1404 elif args[0] in self.options:
1405 if args[1] in ['None','True','False']:
1406 self.options[args[0]] = eval(args[1])
1407 elif args[0].endswith('path'):
1408 if os.path.exists(args[1]):
1409 self.options[args[0]] = args[1]
1410 elif os.path.exists(pjoin(self.me_dir, args[1])):
1411 self.options[args[0]] = pjoin(self.me_dir, args[1])
1412 else:
1413 raise self.InvalidCmd('Not a valid path: keep previous value: \'%s\'' % self.options[args[0]])
1414 else:
1415 self.options[args[0]] = args[1]
1416
1417 - def post_set(self, stop, line):
1418 """Check if we need to save this in the option file"""
1419 try:
1420 args = self.split_arg(line)
1421 if 'cluster' in args[0] or args[0] == 'run_mode':
1422 self.configure_run_mode(self.options['run_mode'])
1423
1424
1425
1426 self.check_set(args)
1427
1428 if args[0] in self.options_configuration and '--no_save' not in args:
1429 self.exec_cmd('save options --auto')
1430 elif args[0] in self.options_madevent:
1431 logger.info('This option will be the default in any output that you are going to create in this session.')
1432 logger.info('In order to keep this changes permanent please run \'save options\'')
1433 return stop
1434 except self.InvalidCmd:
1435 return stop
1436
1462
1464 """Check that all the width are define in the param_card.
1465 If some width are set on 'Auto', call the computation tools."""
1466
1467 pattern = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto''',re.I)
1468 text = open(path).read()
1469 pdg = pattern.findall(text)
1470 if pdg:
1471 if run:
1472 logger.info('Computing the width set on auto in the param_card.dat')
1473 self.do_compute_widths('%s %s' % (' '.join(pdg), path))
1474 else:
1475 logger.info('''Some width are on Auto in the card.
1476 Those will be computed as soon as you have finish the edition of the cards.
1477 If you want to force the computation right now and being able to re-edit
1478 the cards afterwards, you can type \"compute_wdiths\".''')
1479
1480
1482 """If a ME run is currently running add a link in the html output"""
1483
1484
1485
1486 if hasattr(self, 'results') and hasattr(self.results, 'current') and\
1487 self.results.current and 'run_name' in self.results.current and \
1488 hasattr(self, 'me_dir'):
1489 name = self.results.current['run_name']
1490 tag = self.results.current['tag']
1491 self.debug_output = pjoin(self.me_dir, '%s_%s_debug.log' % (name,tag))
1492 if errortype:
1493 self.results.current.debug = errortype
1494 else:
1495 self.results.current.debug = self.debug_output
1496
1497 else:
1498
1499 self.debug_output = CommonRunCmd.debug_output
1500 if os.path.exists('ME5_debug') and not 'ME5_debug' in self.debug_output:
1501 os.remove('ME5_debug')
1502 if not 'ME5_debug' in self.debug_output:
1503 os.system('ln -s %s ME5_debug &> /dev/null' % self.debug_output)
1504
1505
1507 """Not in help: exit """
1508
1509 try:
1510 os.remove(pjoin(self.me_dir,'RunWeb'))
1511 except Exception:
1512 pass
1513 try:
1514 self.store_result()
1515 except Exception:
1516
1517 pass
1518
1519 try:
1520 self.update_status('', level=None)
1521 except Exception, error:
1522 pass
1523 devnull = open(os.devnull, 'w')
1524 try:
1525 misc.call(['./bin/internal/gen_cardhtml-pl'], cwd=self.me_dir,
1526 stdout=devnull, stderr=devnull)
1527 except Exception:
1528 pass
1529 devnull.close()
1530
1531 return super(CommonRunCmd, self).do_quit(line)
1532
1533
1534 do_EOF = do_quit
1535 do_exit = do_quit
1536
1537
1538 - def update_status(self, status, level, makehtml=True, force=True,
1539 error=False, starttime = None, update_results=True,
1540 print_log=True):
1541 """ update the index status """
1542
1543 if makehtml and not force:
1544 if hasattr(self, 'next_update') and time.time() < self.next_update:
1545 return
1546 else:
1547 self.next_update = time.time() + 3
1548
1549 if print_log:
1550 if isinstance(status, str):
1551 if '<br>' not in status:
1552 logger.info(status)
1553 elif starttime:
1554 running_time = misc.format_timer(time.time()-starttime)
1555 logger.info(' Idle: %s, Running: %s, Completed: %s [ %s ]' % \
1556 (status[0], status[1], status[2], running_time))
1557 else:
1558 logger.info(' Idle: %s, Running: %s, Completed: %s' % status[:3])
1559
1560 if update_results:
1561 self.results.update(status, level, makehtml=makehtml, error=error)
1562
1563
1564
1566 """Ask the question when launching generate_events/multi_run"""
1567
1568 check_card = ['pythia_card.dat', 'pgs_card.dat','delphes_card.dat',
1569 'delphes_trigger.dat', 'madspin_card.dat', 'shower_card.dat',
1570 'reweight_card.dat']
1571
1572 cards_path = pjoin(self.me_dir,'Cards')
1573 for card in check_card:
1574 if card in ignore:
1575 continue
1576 if card not in need_card:
1577 if os.path.exists(pjoin(cards_path, card)):
1578 os.remove(pjoin(cards_path, card))
1579 else:
1580 if not os.path.exists(pjoin(cards_path, card)):
1581 default = card.replace('.dat', '_default.dat')
1582 files.cp(pjoin(cards_path, default),pjoin(cards_path, card))
1583
1584
1585 - def set_configuration(self, config_path=None, final=True, initdir=None, amcatnlo=False):
1586 """ assign all configuration variable from file
1587 ./Cards/mg5_configuration.txt. assign to default if not define """
1588
1589 if not hasattr(self, 'options') or not self.options:
1590 self.options = dict(self.options_configuration)
1591 self.options.update(self.options_madgraph)
1592 self.options.update(self.options_madevent)
1593
1594 if not config_path:
1595 if os.environ.has_key('MADGRAPH_BASE'):
1596 config_path = pjoin(os.environ['MADGRAPH_BASE'],'mg5_configuration.txt')
1597 self.set_configuration(config_path=config_path, final=final)
1598 return
1599 if 'HOME' in os.environ:
1600 config_path = pjoin(os.environ['HOME'],'.mg5',
1601 'mg5_configuration.txt')
1602 if os.path.exists(config_path):
1603 self.set_configuration(config_path=config_path, final=False)
1604 if amcatnlo:
1605 me5_config = pjoin(self.me_dir, 'Cards', 'amcatnlo_configuration.txt')
1606 else:
1607 me5_config = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
1608 self.set_configuration(config_path=me5_config, final=False, initdir=self.me_dir)
1609
1610 if self.options.has_key('mg5_path') and self.options['mg5_path']:
1611 MG5DIR = self.options['mg5_path']
1612 config_file = pjoin(MG5DIR, 'input', 'mg5_configuration.txt')
1613 self.set_configuration(config_path=config_file, final=False,initdir=MG5DIR)
1614 else:
1615 self.options['mg5_path'] = None
1616 return self.set_configuration(config_path=me5_config, final=final,initdir=self.me_dir)
1617
1618 config_file = open(config_path)
1619
1620
1621 logger.info('load configuration from %s ' % config_file.name)
1622 for line in config_file:
1623 if '#' in line:
1624 line = line.split('#',1)[0]
1625 line = line.replace('\n','').replace('\r\n','')
1626 try:
1627 name, value = line.split('=')
1628 except ValueError:
1629 pass
1630 else:
1631 name = name.strip()
1632 value = value.strip()
1633 if name.endswith('_path'):
1634 path = value
1635 if os.path.isdir(path):
1636 self.options[name] = os.path.realpath(path)
1637 continue
1638 if not initdir:
1639 continue
1640 path = pjoin(initdir, value)
1641 if os.path.isdir(path):
1642 self.options[name] = os.path.realpath(path)
1643 continue
1644 else:
1645 self.options[name] = value
1646 if value.lower() == "none":
1647 self.options[name] = None
1648
1649 if not final:
1650 return self.options
1651
1652
1653
1654
1655 for key in self.options:
1656
1657 if key.endswith('path'):
1658 path = self.options[key]
1659 if path is None:
1660 continue
1661 if os.path.isdir(path):
1662 self.options[key] = os.path.realpath(path)
1663 continue
1664 path = pjoin(self.me_dir, self.options[key])
1665 if os.path.isdir(path):
1666 self.options[key] = os.path.realpath(path)
1667 continue
1668 elif self.options.has_key('mg5_path') and self.options['mg5_path']:
1669 path = pjoin(self.options['mg5_path'], self.options[key])
1670 if os.path.isdir(path):
1671 self.options[key] = os.path.realpath(path)
1672 continue
1673 self.options[key] = None
1674 elif key.startswith('cluster') and key != 'cluster_status_update':
1675 if key in ('cluster_nb_retry','cluster_wait_retry'):
1676 self.options[key] = int(self.options[key])
1677 if hasattr(self,'cluster'):
1678 del self.cluster
1679 pass
1680 elif key == 'automatic_html_opening':
1681 if self.options[key] in ['False', 'True']:
1682 self.options[key] =eval(self.options[key])
1683 elif key not in ['text_editor','eps_viewer','web_browser','stdout_level',
1684 'complex_mass_scheme', 'gauge', 'group_subprocesses']:
1685
1686 try:
1687 self.do_set("%s %s --no_save" % (key, self.options[key]), log=False)
1688 except self.InvalidCmd:
1689 logger.warning("Option %s from config file not understood" \
1690 % key)
1691
1692
1693 misc.open_file.configure(self.options)
1694 self.configure_run_mode(self.options['run_mode'])
1695
1696 return self.options
1697
1698 @staticmethod
1700 """ find a valid run_name for the current job """
1701
1702 name = 'run_%02d'
1703 data = [int(s[4:]) for s in os.listdir(pjoin(me_dir,'Events')) if
1704 s.startswith('run_') and len(s)>5 and s[4:].isdigit()]
1705 return name % (max(data+[0])+1)
1706
1707
1708
1710 """Require MG5 directory: decay events with spin correlations
1711 """
1712
1713 if '-from_cards' in line and not os.path.exists(pjoin(self.me_dir, 'Cards', 'madspin_card.dat')):
1714 return
1715
1716
1717
1718
1719 if MADEVENT and not self.options['mg5_path']:
1720 raise self.InvalidCmd, '''The module decay_events requires that MG5 is installed on the system.
1721 You can install it and set its path in ./Cards/me5_configuration.txt'''
1722 elif MADEVENT:
1723 sys.path.append(self.options['mg5_path'])
1724 try:
1725 import MadSpin.decay as decay
1726 import MadSpin.interface_madspin as interface_madspin
1727 except ImportError:
1728 raise self.ConfigurationError, '''Can\'t load MadSpin
1729 The variable mg5_path might not be correctly configured.'''
1730
1731 self.update_status('Running MadSpin', level='madspin')
1732 if not '-from_cards' in line:
1733 self.keep_cards(['madspin_card.dat'])
1734 self.ask_edit_cards(['madspin_card.dat'], 'fixed', plot=False)
1735 self.help_decay_events(skip_syntax=True)
1736
1737
1738 args = self.split_arg(line)
1739 self.check_decay_events(args)
1740
1741 madspin_cmd = interface_madspin.MadSpinInterface(args[0])
1742 madspin_cmd.update_status = lambda *x,**opt: self.update_status(*x, level='madspin',**opt)
1743
1744 path = pjoin(self.me_dir, 'Cards', 'madspin_card.dat')
1745
1746 madspin_cmd.import_command_file(path)
1747
1748
1749 i = 1
1750 while os.path.exists(pjoin(self.me_dir,'Events', '%s_decayed_%i' % (self.run_name,i))):
1751 i+=1
1752 new_run = '%s_decayed_%i' % (self.run_name,i)
1753 evt_dir = pjoin(self.me_dir, 'Events')
1754
1755 os.mkdir(pjoin(evt_dir, new_run))
1756 current_file = args[0].replace('.lhe', '_decayed.lhe')
1757 new_file = pjoin(evt_dir, new_run, os.path.basename(args[0]))
1758 if not os.path.exists(current_file):
1759 if os.path.exists(current_file+'.gz'):
1760 current_file += '.gz'
1761 new_file += '.gz'
1762 else:
1763 logger.error('MadSpin fails to create any decayed file.')
1764 return
1765
1766 files.mv(current_file, new_file)
1767 logger.info("The decayed event file has been moved to the following location: ")
1768 logger.info(new_file)
1769
1770 if hasattr(self, 'results'):
1771 current = self.results.current
1772 nb_event = self.results.current['nb_event']
1773 if not nb_event:
1774 current = self.results[self.run_name][0]
1775 nb_event = current['nb_event']
1776
1777 cross = current['cross']
1778 error = current['error']
1779 self.results.add_run( new_run, self.run_card)
1780 self.results.add_detail('nb_event', nb_event)
1781 self.results.add_detail('cross', cross * madspin_cmd.branching_ratio)
1782 self.results.add_detail('error', error * madspin_cmd.branching_ratio)
1783 self.results.add_detail('run_mode', current['run_mode'])
1784
1785 self.run_name = new_run
1786 self.banner = madspin_cmd.banner
1787 self.banner.add(path)
1788 self.banner.write(pjoin(self.me_dir,'Events',self.run_name, '%s_%s_banner.txt' %
1789 (self.run_name, self.run_tag)))
1790 self.update_status('MadSpin Done', level='parton', makehtml=False)
1791 if 'unweighted' in os.path.basename(args[0]):
1792 self.create_plot('parton')
1793
1795 args = self.split_arg(line[0:begidx], error=False)
1796 if len(args) == 1:
1797 return self.complete_plot(text, line, begidx, endidx)
1798 else:
1799 return
1800
1802 "Complete the print results command"
1803 args = self.split_arg(line[0:begidx], error=False)
1804 if len(args) == 1:
1805
1806 data = glob.glob(pjoin(self.me_dir, 'Events', '*','unweighted_events.lhe.gz'))
1807 data = [n.rsplit('/',2)[1] for n in data]
1808 tmp1 = self.list_completion(text, data)
1809 return tmp1
1810 else:
1811 data = glob.glob(pjoin(self.me_dir, 'Events', args[0], '*_pythia_events.hep.gz'))
1812 data = [os.path.basename(p).rsplit('_',1)[0] for p in data]
1813 tmp1 = self.list_completion(text, data)
1814 return tmp1
1815
1817 logger.info("syntax: print_result [RUN] [TAG] [options]")
1818 logger.info("-- show in text format the status of the run (cross-section/nb-event/...)")
1819 logger.info("--path= defines the path of the output file.")
1820 logger.info("--mode=a allow to add the information at the end of the file.")
1821
1822
1823
1849
1850
1852 args = self.split_arg(line[0:begidx], error=False)
1853
1854 if len(args) == 1 and os.path.sep not in text:
1855
1856 data = glob.glob(pjoin(self.me_dir, 'Events', '*','*events.lhe*'))
1857 data = [n.rsplit('/',2)[1] for n in data]
1858 return self.list_completion(text, data, line)
1859 else:
1860 return self.path_completion(text,
1861 os.path.join('.',*[a for a in args \
1862 if a.endswith(os.path.sep)]))
1863
1865 "Complete the compute_widths command"
1866
1867 args = self.split_arg(line[0:begidx])
1868
1869 if args[-1] in ['--path=', '--output=']:
1870 completion = {'path': self.path_completion(text)}
1871 elif line[begidx-1] == os.path.sep:
1872 current_dir = pjoin(*[a for a in args if a.endswith(os.path.sep)])
1873 if current_dir.startswith('--path='):
1874 current_dir = current_dir[7:]
1875 if current_dir.startswith('--output='):
1876 current_dir = current_dir[9:]
1877 completion = {'path': self.path_completion(text, current_dir)}
1878 else:
1879 completion = {}
1880 completion['options'] = self.list_completion(text,
1881 ['--path=', '--output=', '--min_br=0.\$'
1882 '--precision_channel=0.\$', '--body_decay='])
1883
1884 return self.deal_multiple_categories(completion)
1885
1886
1887
1889 """links lhapdf into libdir"""
1890
1891 lhapdf_version = self.get_lhapdf_version()
1892 logger.info('Using LHAPDF v%s interface for PDFs' % lhapdf_version)
1893 lhalibdir = subprocess.Popen([self.options['lhapdf'], '--libdir'],
1894 stdout = subprocess.PIPE).stdout.read().strip()
1895
1896 if lhapdf_version.startswith('5.'):
1897 pdfsetsdir = subprocess.Popen([self.options['lhapdf'], '--pdfsets-path'],
1898 stdout = subprocess.PIPE).stdout.read().strip()
1899 else:
1900 pdfsetsdir = subprocess.Popen([self.options['lhapdf'], '--datadir'],
1901 stdout = subprocess.PIPE).stdout.read().strip()
1902
1903 self.lhapdf_pdfsets = self.get_lhapdf_pdfsets_list(pdfsetsdir)
1904
1905 lhalib = 'libLHAPDF.a'
1906
1907 if os.path.exists(pjoin(libdir, lhalib)):
1908 files.rm(pjoin(libdir, lhalib))
1909 files.ln(pjoin(lhalibdir, lhalib), libdir)
1910
1911 if not os.path.isdir(pjoin(libdir, 'PDFsets')):
1912 os.mkdir(pjoin(libdir, 'PDFsets'))
1913 os.environ['lhapdf'] = 'True'
1914 os.environ['lhapdf_config'] = self.options['lhapdf']
1915
1916
1918 """copy (if needed) the lhapdf set corresponding to the lhaid in lhaid_list
1919 into lib/PDFsets"""
1920
1921 pdfsetname = ''
1922 for lhaid in lhaid_list:
1923 try:
1924 if not pdfsetname:
1925 if lhaid in self.lhapdf_pdfsets:
1926 pdfsetname = self.lhapdf_pdfsets[lhaid]['filename']
1927 else:
1928 raise MadGraph5Error('lhaid %s not valid input number for the current lhapdf' % lhaid )
1929
1930 elif not \
1931 self.lhapdf_pdfsets[lhaid]['filename'] == pdfsetname:
1932 raise MadGraph5Error(\
1933 'lhaid and PDF_set_min/max in the run_card do not correspond to the' + \
1934 'same PDF set. Please check the run_card.')
1935 except KeyError:
1936 if self.lhapdf_version.startswith('5'):
1937 raise MadGraph5Error(\
1938 ('invalid lhaid set in th run_card: %d .\nPlease note that some sets' % lhaid) + \
1939 '(eg MSTW 90%CL error sets) \nare not available in aMC@NLO + LHAPDF 5.x.x')
1940 else:
1941 logger.debug('%d not found in pdfsets.index' % lhaid)
1942
1943
1944
1945
1946
1947 if not os.path.isdir(pdfsets_dir):
1948 try:
1949 os.mkdir(pdfsets_dir)
1950 except OSError:
1951 pdfsets_dir = pjoin(self.me_dir, 'lib', 'PDFsets')
1952
1953
1954 if not os.path.exists(pjoin(self.me_dir, 'lib', 'PDFsets', pdfsetname)) and \
1955 not os.path.isdir(pjoin(self.me_dir, 'lib', 'PDFsets', pdfsetname)):
1956
1957 if pdfsetname and not os.path.exists(pjoin(pdfsets_dir, pdfsetname)):
1958 self.install_lhapdf_pdfset(pdfsets_dir, pdfsetname)
1959
1960 if os.path.exists(pjoin(pdfsets_dir, pdfsetname)):
1961 files.cp(pjoin(pdfsets_dir, pdfsetname), pjoin(self.me_dir, 'lib', 'PDFsets'))
1962 elif os.path.exists(pjoin(os.path.dirname(pdfsets_dir), pdfsetname)):
1963 files.cp(pjoin(os.path.dirname(pdfsets_dir), pdfsetname), pjoin(self.me_dir, 'lib', 'PDFsets'))
1964
1965
1967 """idownloads and install the pdfset filename in the pdfsets_dir"""
1968 lhapdf_version = self.get_lhapdf_version()
1969 logger.info('Trying to download %s' % filename)
1970
1971 if lhapdf_version.startswith('5.'):
1972
1973
1974 getdata = self.options['lhapdf'].replace('lhapdf-config', ('lhapdf-getdata'))
1975 misc.call([getdata, filename], cwd = pdfsets_dir)
1976
1977 elif lhapdf_version.startswith('6.'):
1978
1979
1980 getdata = self.options['lhapdf'].replace('lhapdf-config', ('lhapdf'))
1981
1982 misc.call([getdata, 'install', filename], cwd = pdfsets_dir)
1983
1984 else:
1985 raise MadGraph5Error('Not valid LHAPDF version: %s' % lhapdf_version)
1986
1987
1988 if os.path.exists(pjoin(pdfsets_dir, filename)) or \
1989 os.path.isdir(pjoin(pdfsets_dir, filename)):
1990 logger.info('%s successfully downloaded and stored in %s' \
1991 % (filename, pdfsets_dir))
1992
1993 elif lhapdf_version.startswith('5.'):
1994 logger.warning('Could not download %s into %s. Trying to save it locally' \
1995 % (filename, pdfsets_dir))
1996 self.install_lhapdf_pdfset(pjoin(self.me_dir, 'lib', 'PDFsets'), filename)
1997 else:
1998 raise MadGraph5Error, \
1999 'Could not download %s into %s. Please try to install it manually.' \
2000 % (filename, pdfsets_dir)
2001
2002
2004 """read the PDFsets.index file, which should be located in the same
2005 place as pdfsets_dir, and return a list of dictionaries with the information
2006 about each pdf set"""
2007 lhapdf_version = self.get_lhapdf_version()
2008
2009 if lhapdf_version.startswith('5.'):
2010 if os.path.exists('%s.index' % pdfsets_dir):
2011 indexfile = '%s.index' % pdfsets_dir
2012 else:
2013 raise MadGraph5Error, 'index of lhapdf file not found'
2014 pdfsets_lines = \
2015 [l for l in open(indexfile).read().split('\n') if l.strip() and \
2016 not '90cl' in l]
2017 lhapdf_pdfsets = dict( (int(l.split()[0]), {'lhaid': int(l.split()[0]),
2018 'pdflib_ntype': int(l.split()[1]),
2019 'pdflib_ngroup': int(l.split()[2]),
2020 'pdflib_nset': int(l.split()[3]),
2021 'filename': l.split()[4],
2022 'lhapdf_nmem': int(l.split()[5]),
2023 'q2min': float(l.split()[6]),
2024 'q2max': float(l.split()[7]),
2025 'xmin': float(l.split()[8]),
2026 'xmax': float(l.split()[9]),
2027 'description': l.split()[10]}) \
2028 for l in pdfsets_lines)
2029
2030 elif lhapdf_version.startswith('6.'):
2031 pdfsets_lines = \
2032 [l for l in open(pjoin(pdfsets_dir, 'pdfsets.index')).read().split('\n') if l.strip()]
2033 lhapdf_pdfsets = dict( (int(l.split()[0]),
2034 {'lhaid': int(l.split()[0]),
2035 'filename': l.split()[1]}) \
2036 for l in pdfsets_lines)
2037
2038 else:
2039 raise MadGraph5Error('Not valid LHAPDF version: %s' % lhapdf_version)
2040
2041 return lhapdf_pdfsets
2042
2043
2045 """returns the lhapdf version number"""
2046 if not hasattr(self, 'lhapdfversion'):
2047 self.lhapdf_version = \
2048 subprocess.Popen([self.options['lhapdf'], '--version'],
2049 stdout = subprocess.PIPE).stdout.read().strip()
2050
2051
2052 if self.lhapdf_version.startswith('6.0'):
2053 raise MadGraph5Error('LHAPDF 6.0.x not supported. Please use v6.1 or later')
2054
2055 return self.lhapdf_version
2056
2057
2059 lhapdf_version = self.get_lhapdf_version()
2060
2061 if lhapdf_version.startswith('5.'):
2062 datadir = subprocess.Popen([self.options['lhapdf'], '--pdfsets-path'],
2063 stdout = subprocess.PIPE).stdout.read().strip()
2064
2065 elif lhapdf_version.startswith('6.'):
2066 datadir = subprocess.Popen([self.options['lhapdf'], '--datadir'],
2067 stdout = subprocess.PIPE).stdout.read().strip()
2068
2069 return datadir
2070
2072 """A class for asking a question where in addition you can have the
2073 set command define and modifying the param_card/run_card correctly"""
2074
2075 special_shortcut = {'ebeam':['run_card ebeam1 %(0)s', 'run_card ebeam2 %(0)s'],
2076 'lpp': ['run_card lpp1 %(0)s', 'run_card lpp2 %(0)s' ],
2077 'lhc': ['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2'],
2078 'lep': ['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2'],
2079 'ilc': ['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2'],
2080 'lcc':['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2'],
2081 'fixed_scale': ['run_card fixed_fac_scale T', 'run_card fixed_ren_scale T', 'run_card scale %(0)s', 'run_card dsqrt_q2fact1 %(0)s' ,'run_card dsqrt_q2fact2 %(0)s'],
2082 }
2083
2084 - def __init__(self, question, cards=[], mode='auto', *args, **opt):
2085
2086
2087 if 'pwd' in opt:
2088 self.me_dir = opt['pwd']
2089 del opt['pwd']
2090
2091 cmd.OneLinePathCompletion.__init__(self, question, *args, **opt)
2092
2093 if not hasattr(self, 'me_dir') or not self.me_dir:
2094 self.me_dir = self.mother_interface.me_dir
2095
2096
2097
2098 try:
2099 self.run_card = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card.dat'))
2100 except IOError:
2101 self.run_card = {}
2102 try:
2103 self.param_card = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card.dat'))
2104 except (check_param_card.InvalidParamCard, ValueError) as e:
2105 logger.error('Current param_card is not valid. We are going to use the default one.')
2106 logger.error('problem detected: %s' % e)
2107 files.cp(pjoin(self.me_dir,'Cards','param_card_default.dat'),
2108 pjoin(self.me_dir,'Cards','param_card.dat'))
2109 self.param_card = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card.dat'))
2110 default_param = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card_default.dat'))
2111 try:
2112 run_card_def = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card_default.dat'))
2113 except IOError:
2114 run_card_def = {}
2115
2116 self.pname2block = {}
2117 self.conflict = []
2118 self.restricted_value = {}
2119 self.mode = mode
2120 self.cards = cards
2121
2122
2123
2124
2125 for bname, block in default_param.items():
2126 for lha_id, param in block.param_dict.items():
2127 all_var = []
2128 comment = param.comment
2129
2130 if comment.strip().startswith('set of param :'):
2131 all_var = list(re.findall(r'''[^-]1\*(\w*)\b''', comment))
2132
2133 elif len(comment.split()) == 1:
2134 all_var = [comment.strip().lower()]
2135
2136 else:
2137 split = comment.split()
2138 if len(split) >2 and split[1] == ':':
2139
2140 self.restricted_value[(bname, lha_id)] = ' '.join(split[1:])
2141 elif len(split) == 2:
2142 if re.search(r'''\[[A-Z]\]eV\^''', split[1]):
2143 all_var = [comment.strip().lower()]
2144 else:
2145
2146 continue
2147
2148 for var in all_var:
2149 var = var.lower()
2150 if var in self.pname2block:
2151 self.pname2block[var].append((bname, lha_id))
2152 else:
2153 self.pname2block[var] = [(bname, lha_id)]
2154
2155 if run_card_def:
2156 self.run_set = run_card_def.keys() + self.run_card.hidden_param
2157 elif self.run_card:
2158 self.run_set = self.run_card.keys()
2159 else:
2160 self.run_set = []
2161
2162 for var in self.pname2block:
2163 if var in self.run_set:
2164 self.conflict.append(var)
2165
2166
2167
2168 self.has_mw = False
2169 if 'madweight_card.dat' in cards:
2170
2171 self.do_change_tf = self.mother_interface.do_define_transfer_fct
2172 self.complete_change_tf = self.mother_interface.complete_define_transfer_fct
2173 self.help_change_tf = self.mother_interface.help_define_transfer_fct
2174 if not os.path.exists(pjoin(self.me_dir,'Cards','transfer_card.dat')):
2175 logger.warning('No transfer function currently define. Please use the change_tf command to define one.')
2176
2177
2178 self.has_mw = True
2179 try:
2180 import madgraph.madweight.Cards as mwcards
2181 except:
2182 import internal.madweight.Cards as mwcards
2183 self.mw_card = mwcards.Card(pjoin(self.me_dir,'Cards','MadWeight_card.dat'))
2184 self.mw_card = self.mw_card.info
2185 self.mw_vars = []
2186 for key in self.mw_card:
2187 if key == 'comment':
2188 continue
2189 for key2 in self.mw_card.info[key]:
2190 if isinstance(key2, str) and not key2.isdigit():
2191 self.mw_vars.append(key2)
2192
2193
2194 for var in self.pname2block:
2195 if var in self.mw_vars:
2196 self.conflict.append(var)
2197 for var in self.mw_vars:
2198 if var in self.run_card:
2199 self.conflict.append(var)
2200
2202 """ Complete the set command"""
2203
2204 prev_timer = signal.alarm(0)
2205 if prev_timer:
2206 nb_back = len(line)
2207 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
2208 self.stdout.write(line)
2209 self.stdout.flush()
2210
2211 possibilities = {}
2212 allowed = {}
2213 args = self.split_arg(line[0:begidx])
2214 if args[-1] in ['Auto', 'default']:
2215 return
2216 if len(args) == 1:
2217 allowed = {'category':'', 'run_card':'', 'block':'all', 'param_card':'','shortcut':''}
2218 if self.has_mw:
2219 allowed['madweight_card'] = ''
2220 allowed['mw_block'] = 'all'
2221 elif len(args) == 2:
2222 if args[1] == 'run_card':
2223 allowed = {'run_card':'default'}
2224 elif args[1] == 'param_card':
2225 allowed = {'block':'all', 'param_card':'default'}
2226 elif args[1] in self.param_card.keys():
2227 allowed = {'block':args[1]}
2228 elif args[1] == 'width':
2229 allowed = {'block': 'decay'}
2230 elif args[1] == 'MadWeight_card':
2231 allowed = {'madweight_card':'default', 'mw_block': 'all'}
2232 elif self.has_mw and args[1] in self.mw_card.keys():
2233 allowed = {'mw_block':args[1]}
2234 else:
2235 allowed = {'value':''}
2236 else:
2237 start = 1
2238 if args[1] in ['run_card', 'param_card', 'MadWeight_card']:
2239 start = 2
2240 if args[-1] in self.pname2block.keys():
2241 allowed['value'] = 'default'
2242 elif args[start] in self.param_card.keys() or args[start] == 'width':
2243 if args[start] == 'width':
2244 args[start] = 'decay'
2245
2246 if args[start+1:]:
2247 allowed = {'block':(args[start], args[start+1:])}
2248 else:
2249 allowed = {'block':args[start]}
2250 elif self.has_mw and args[start] in self.mw_card.keys():
2251 if args[start+1:]:
2252 allowed = {'mw_block':(args[start], args[start+1:])}
2253 else:
2254 allowed = {'mw_block':args[start]}
2255
2256
2257 else:
2258 allowed['value'] = ''
2259
2260 if 'category' in allowed.keys():
2261 categories = ['run_card', 'param_card']
2262 if self.has_mw:
2263 categories.append('MadWeight_card')
2264
2265 possibilities['category of parameter (optional)'] = \
2266 self.list_completion(text, categories)
2267
2268 if 'shortcut' in allowed.keys():
2269 possibilities['special values'] = self.list_completion(text, self.special_shortcut.keys()+['qcut', 'showerkt'])
2270
2271 if 'run_card' in allowed.keys():
2272 opts = self.run_set
2273 if allowed['run_card'] == 'default':
2274 opts.append('default')
2275
2276 possibilities['Run Card'] = self.list_completion(text, opts)
2277
2278 if 'param_card' in allowed.keys():
2279 opts = self.pname2block.keys()
2280 if allowed['param_card'] == 'default':
2281 opts.append('default')
2282 possibilities['Param Card'] = self.list_completion(text, opts)
2283
2284 if 'madweight_card' in allowed.keys():
2285 opts = self.mw_vars + [k for k in self.mw_card.keys() if k !='comment']
2286 if allowed['madweight_card'] == 'default':
2287 opts.append('default')
2288 possibilities['MadWeight Card'] = self.list_completion(text, opts)
2289
2290 if 'value' in allowed.keys():
2291 opts = ['default']
2292 if 'decay' in args:
2293 opts.append('Auto')
2294 if args[-1] in self.pname2block and self.pname2block[args[-1]][0][0] == 'decay':
2295 opts.append('Auto')
2296 possibilities['Special Value'] = self.list_completion(text, opts)
2297
2298
2299 if 'block' in allowed.keys():
2300 if allowed['block'] == 'all':
2301 allowed_block = [i for i in self.param_card.keys() if 'qnumbers' not in i]
2302 allowed_block.append('width')
2303 possibilities['Param Card Block' ] = \
2304 self.list_completion(text, allowed_block)
2305 elif isinstance(allowed['block'], basestring):
2306 block = self.param_card[allowed['block']].param_dict
2307 ids = [str(i[0]) for i in block
2308 if (allowed['block'], i) not in self.restricted_value]
2309 possibilities['Param Card id' ] = self.list_completion(text, ids)
2310 varname = [name for name, all_var in self.pname2block.items()
2311 if any((bname == allowed['block']
2312 for bname,lhaid in all_var))]
2313 possibilities['Param card variable'] = self.list_completion(text,
2314 varname)
2315 else:
2316 block = self.param_card[allowed['block'][0]].param_dict
2317 nb = len(allowed['block'][1])
2318 ids = [str(i[nb]) for i in block if len(i) > nb and \
2319 [str(a) for a in i[:nb]] == allowed['block'][1]]
2320
2321 if not ids:
2322 if tuple([int(i) for i in allowed['block'][1]]) in block:
2323 opts = ['default']
2324 if allowed['block'][0] == 'decay':
2325 opts.append('Auto')
2326 possibilities['Special value'] = self.list_completion(text, opts)
2327 possibilities['Param Card id' ] = self.list_completion(text, ids)
2328
2329 if 'mw_block' in allowed.keys():
2330 if allowed['mw_block'] == 'all':
2331 allowed_block = [i for i in self.mw_card.keys() if 'comment' not in i]
2332 possibilities['MadWeight Block' ] = \
2333 self.list_completion(text, allowed_block)
2334 elif isinstance(allowed['mw_block'], basestring):
2335 block = self.mw_card[allowed['mw_block']]
2336 ids = [str(i[0]) if isinstance(i, tuple) else str(i) for i in block]
2337 possibilities['MadWeight Card id' ] = self.list_completion(text, ids)
2338 else:
2339 block = self.mw_card[allowed['mw_block'][0]]
2340 nb = len(allowed['mw_block'][1])
2341 ids = [str(i[nb]) for i in block if isinstance(i, tuple) and\
2342 len(i) > nb and \
2343 [str(a) for a in i[:nb]] == allowed['mw_block'][1]]
2344
2345 if not ids:
2346 if tuple([i for i in allowed['mw_block'][1]]) in block or \
2347 allowed['mw_block'][1][0] in block.keys():
2348 opts = ['default']
2349 possibilities['Special value'] = self.list_completion(text, opts)
2350 possibilities['MadWeight Card id' ] = self.list_completion(text, ids)
2351
2352 return self.deal_multiple_categories(possibilities)
2353
2355 """ edit the value of one parameter in the card"""
2356
2357 args = self.split_arg(line.lower())
2358 if '=' in args[-1]:
2359 arg1, arg2 = args.pop(-1).split('=')
2360 args += [arg1, arg2]
2361
2362
2363 if args[0] in self.special_shortcut:
2364 if len(args) == 1:
2365 values = {}
2366 elif len(args) == 2:
2367 try:
2368 values = {'0': float(args[1])}
2369 except ValueError as e:
2370 logger.warning("Wrong argument: The last entry should be a number.")
2371 return
2372 else:
2373 logger.warning("too many argument for this command")
2374 return
2375
2376 for arg in self.special_shortcut[args[0]]:
2377 try:
2378 text = arg % values
2379 except KeyError:
2380 logger.warning("This command requires one argument")
2381 return
2382 except Exception as e:
2383 logger.warning(str(e))
2384 return
2385 else:
2386 self.do_set(arg % values)
2387 return
2388
2389
2390 start = 0
2391 if len(args) < 2:
2392 logger.warning('Invalid set command %s (need two arguments)' % line)
2393 return
2394
2395
2396 if args[0].lower() == 'qcut':
2397 pythia_path = pjoin(self.me_dir, 'Cards','pythia_card.dat')
2398 if os.path.exists(pythia_path):
2399 logger.info('add line QCUT = %s in pythia_card.dat' % args[1])
2400 p_card = open(pythia_path,'r').read()
2401 p_card, n = re.subn('''^\s*QCUT\s*=\s*[\de\+\-\.]*\s*$''',
2402 ''' QCUT = %s ''' % args[1], \
2403 p_card, flags=(re.M+re.I))
2404 if n==0:
2405 p_card = '%s \n QCUT= %s' % (p_card, args[1])
2406 open(pythia_path, 'w').write(p_card)
2407 return
2408
2409 if args[0].lower() == 'showerkt':
2410 pythia_path = pjoin(self.me_dir, 'Cards','pythia_card.dat')
2411 if os.path.exists(pythia_path):
2412 logger.info('add line SHOWERKT = %s in pythia_card.dat' % args[1].upper())
2413 p_card = open(pythia_path,'r').read()
2414 p_card, n = re.subn('''^\s*SHOWERKT\s*=\s*[default\de\+\-\.]*\s*$''',
2415 ''' SHOWERKT = %s ''' % args[1].upper(), \
2416 p_card, flags=(re.M+re.I))
2417 if n==0:
2418 p_card = '%s \n SHOWERKT= %s' % (p_card, args[1].upper())
2419 open(pythia_path, 'w').write(p_card)
2420 return
2421
2422
2423 card = ''
2424 if args[0] == 'madweight_card':
2425 if not self.mw_card:
2426 logger.warning('Invalid Command: No MadWeight card defined.')
2427 return
2428 args[0] = 'MadWeight_card'
2429
2430 if args[0] in ['run_card', 'param_card', 'MadWeight_card']:
2431 if args[1] == 'default':
2432 logging.info('replace %s by the default card' % args[0])
2433 files.cp(pjoin(self.me_dir,'Cards','%s_default.dat' % args[0]),
2434 pjoin(self.me_dir,'Cards','%s.dat'% args[0]))
2435 if args[0] == 'param_card':
2436 self.param_card = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card.dat'))
2437 elif args[0] == 'run_card':
2438 self.run_card = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card.dat'))
2439 return
2440 else:
2441 card = args[0]
2442 start=1
2443 if len(args) < 3:
2444 logger.warning('Invalid set command: %s (not enough arguments)' % line)
2445 return
2446
2447
2448 if args[start] in [l.lower() for l in self.run_card.keys()] and card in ['', 'run_card']:
2449 if args[start] not in self.run_set:
2450 args[start] = [l for l in self.run_set if l.lower() == args[start]][0]
2451
2452 if args[start+1] in self.conflict and card == '':
2453 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
2454 logger.warning(text)
2455 return
2456
2457 if args[start+1] == 'default':
2458 default = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card_default.dat'))
2459 if args[start] in default.keys():
2460 self.setR(args[start],default[args[start]])
2461 else:
2462 logger.info('remove information %s from the run_card' % args[start])
2463 del self.run_card[args[start]]
2464 elif args[start+1].lower() in ['t','.true.','true']:
2465 self.setR(args[start], '.true.')
2466 elif args[start+1].lower() in ['f','.false.','false']:
2467 self.setR(args[start], '.false.')
2468 else:
2469 if args[0].startswith('sys_'):
2470 val = ' '.join(args[start+1:])
2471 val = val.split('#')[0]
2472 else:
2473 try:
2474 val = eval(args[start+1])
2475 except NameError:
2476 val = args[start+1]
2477 self.setR(args[start], val)
2478 self.run_card.write(pjoin(self.me_dir,'Cards','run_card.dat'),
2479 pjoin(self.me_dir,'Cards','run_card_default.dat'))
2480
2481
2482 elif (args[start] in self.param_card or args[start] == 'width') \
2483 and card in ['','param_card']:
2484 if args[start+1] in self.conflict and card == '':
2485 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
2486 logger.warning(text)
2487 return
2488
2489 if args[start] == 'width':
2490 args[start] = 'decay'
2491
2492 if args[start+1] in self.pname2block:
2493 all_var = self.pname2block[args[start+1]]
2494 key = None
2495 for bname, lhaid in all_var:
2496 if bname == args[start]:
2497 key = lhaid
2498 break
2499 else:
2500 logger.warning('%s is not part of block "%s" but "%s". please correct.' %
2501 (args[start+1], args[start], bname))
2502 return
2503 else:
2504 try:
2505 key = tuple([int(i) for i in args[start+1:-1]])
2506 except ValueError:
2507 if args[start] == 'decay' and args[start+1:-1] == ['all']:
2508 for key in self.param_card[args[start]].param_dict:
2509 if (args[start], key) in self.restricted_value:
2510 continue
2511 else:
2512 self.setP(args[start], key, args[-1])
2513 self.param_card.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2514 return
2515 logger.warning('invalid set command %s (failed to identify LHA information)' % line)
2516 return
2517
2518 if key in self.param_card[args[start]].param_dict:
2519 if (args[start], key) in self.restricted_value:
2520 text = "Note that this parameter seems to be ignore by MG.\n"
2521 text += "MG will use instead the expression: %s\n" % \
2522 self.restricted_value[(args[start], key)]
2523 text += "You need to match this expression for external program (such pythia)."
2524 logger.warning(text)
2525
2526 if args[-1].lower() in ['default', 'auto']:
2527 self.setP(args[start], key, args[-1])
2528 else:
2529 try:
2530 value = float(args[-1])
2531 except Exception:
2532 logger.warning('Invalid input: Expected number and not \'%s\'' \
2533 % args[-1])
2534 return
2535 self.setP(args[start], key, value)
2536 else:
2537 logger.warning('invalid set command %s' % line)
2538 return
2539 self.param_card.write(pjoin(self.me_dir,'Cards','param_card.dat'))
2540
2541
2542 elif args[start] in self.pname2block and card != 'run_card':
2543 if args[start] in self.conflict and card == '':
2544 text = 'ambiguous name (present in both param_card and run_card. Please specify'
2545 logger.warning(text)
2546 return
2547
2548 all_var = self.pname2block[args[start]]
2549 for bname, lhaid in all_var:
2550 new_line = 'param_card %s %s %s' % (bname,
2551 ' '.join([ str(i) for i in lhaid]), ' '.join(args[start+1:]))
2552 self.do_set(new_line)
2553 if len(all_var) > 1:
2554 logger.warning('This variable correspond to more than one parameter in the param_card.')
2555 for bname, lhaid in all_var:
2556 logger.warning(' %s %s' % (bname, ' '.join([str(i) for i in lhaid])))
2557 logger.warning('all listed variables have been modified')
2558
2559
2560 elif self.has_mw and (args[start] in self.mw_card and args[start] != 'comment') \
2561 and card in ['','MadWeight_card']:
2562
2563 if args[start] in self.conflict and card == '':
2564 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
2565 logger.warning(text)
2566 return
2567
2568 block = args[start]
2569 name = args[start+1]
2570 value = args[start+2:]
2571 self.setM(block, name, value)
2572 self.mw_card.write(pjoin(self.me_dir,'Cards','MadWeight_card.dat'))
2573
2574
2575 elif self.has_mw and args[start] in self.mw_vars \
2576 and card in ['', 'MadWeight_card']:
2577
2578 if args[start] in self.conflict and card == '':
2579 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
2580 logger.warning(text)
2581 return
2582
2583 block = [b for b, data in self.mw_card.items() if args[start] in data]
2584 if len(block) > 1:
2585 logger.warning('%s is define in more than one block: %s.Please specify.'
2586 % (args[start], ','.join(block)))
2587 return
2588
2589 block = block[0]
2590 name = args[start]
2591 value = args[start+1:]
2592 self.setM(block, name, value)
2593 self.mw_card.write(pjoin(self.me_dir,'Cards','MadWeight_card.dat'))
2594
2595
2596 elif self.has_mw and args[start].startswith('mw_') and len(args[start:]) == 3\
2597 and card == 'MadWeight_card':
2598 block = args[start]
2599 name = args[start+1]
2600 value = args[start+2]
2601 self.setM(block, name, value)
2602 self.mw_card.write(pjoin(self.me_dir,'Cards','MadWeight_card.dat'))
2603
2604 else:
2605 logger.warning('invalid set command %s ' % line)
2606 return
2607
2608 - def setM(self, block, name, value):
2609
2610 if isinstance(value, list) and len(value) == 1:
2611 value = value[0]
2612
2613 if block not in self.mw_card:
2614 logger.warning('block %s was not present in the current MadWeight card. We are adding it' % block)
2615 self.mw_card[block] = {}
2616 elif name not in self.mw_card[block]:
2617 logger.info('name %s was not present in the block %s for the current MadWeight card. We are adding it' % (name,block),'$MG:color:BLACK')
2618 if value == 'default':
2619 import madgraph.madweight.Cards as mwcards
2620 mw_default = mwcards.Card(pjoin(self.me_dir,'Cards','MadWeight_card_default.dat'))
2621 try:
2622 value = mw_default[block][name]
2623 except KeyError:
2624 logger.info('removing id "%s" from Block "%s" '% (name, block))
2625 if name in self.mw_card[block]:
2626 del self.mw_card[block][name]
2627 return
2628 if value:
2629 logger.info('modify madweight_card information BLOCK "%s" with id "%s" set to %s' %\
2630 (block, name, value))
2631 else:
2632 logger.value("Invalid command: No value. To set default value. Use \"default\" as value")
2633 return
2634
2635 self.mw_card[block][name] = value
2636
2637 - def setR(self, name, value):
2638 logger.info('modify parameter %s of the run_card.dat to %s' % (name, value))
2639 self.run_card[name] = value
2640
2641 - def setP(self, block, lhaid, value):
2642 if isinstance(value, str):
2643 value = value.lower()
2644 if value == 'default':
2645 default = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card_default.dat'))
2646 value = default[block].param_dict[lhaid].value
2647
2648 elif value == 'auto':
2649 value = 'Auto'
2650 if block != 'decay':
2651 logger.warning('Invalid input: \'Auto\' value only valid for DECAY')
2652 return
2653 else:
2654 try:
2655 value = float(value)
2656 except ValueError:
2657 logger.warning('Invalid input: \'%s\' not valid intput.'% value)
2658
2659 logger.info('modify param_card information BLOCK %s with id %s set to %s' %\
2660 (block, lhaid, value))
2661 self.param_card[block].param_dict[lhaid].value = value
2662
2663 - def reask(self, *args, **opt):
2664
2665 cmd.OneLinePathCompletion.reask(self,*args, **opt)
2666 if self.has_mw and not os.path.exists(pjoin(self.me_dir,'Cards','transfer_card.dat')):
2667 logger.warning('No transfer function currently define. Please use the change_tf command to define one.')
2668
2669
2697
2698
2700 """Default action if line is not recognized"""
2701
2702 line = line.strip()
2703 args = line.split()
2704 if line == '' and self.default_value is not None:
2705 self.value = self.default_value
2706
2707 elif hasattr(self, 'do_%s' % args[0]):
2708 self.do_set(' '.join(args[1:]))
2709 elif os.path.exists(line):
2710 self.copy_file(line)
2711 self.value = 'repeat'
2712 elif line.strip() != '0' and line.strip() != 'done' and \
2713 str(line) != 'EOF' and line.strip() in self.allow_arg:
2714 self.open_file(line)
2715 self.value = 'repeat'
2716 else:
2717 self.value = line
2718
2719 return line
2720
2722 signal.alarm(0)
2723 path = pjoin(self.me_dir,'Cards','param_card.dat')
2724 pattern = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto''',re.I)
2725 text = open(path).read()
2726 pdg = pattern.findall(text)
2727 line = '%s %s' % (line, ' '.join(pdg))
2728 if not '--path' in line:
2729 line += ' --path=%s' % path
2730 try:
2731 return self.mother_interface.do_compute_widths(line)
2732 except InvalidCmd, error:
2733 logger.error("Invalid command: %s " % error)
2734
2738
2742
2743
2745 """Help associated to the asperge command"""
2746 signal.alarm(0)
2747
2748 print '-- syntax: asperge [options]'
2749 print ' Call ASperGe to diagonalize all mass matrices in the model.'
2750 print ' This works only if the ASperGE module is part of the UFO model (a subdirectory).'
2751 print ' If you specify some names after the command (i.e. asperge m1 m2) then ASperGe will only'
2752 print ' diagonalize the associate mass matrices (here m1 and m2).'
2753
2755 signal.alarm(0)
2756
2757 blockname = self.pname2block.keys()
2758
2759 wrong = ['decay', 'mass', 'sminput']
2760 valid = [k for k in blockname if 'mix' in k]
2761 potential = [k for k in blockname if k not in valid+wrong]
2762 output = {'Mixing matrices': self.list_completion(text, valid, line),
2763 'Other potential valid input': self.list_completion(text, potential, line)}
2764
2765 return self.deal_multiple_categories(output)
2766
2767
2769 """Running ASperGe"""
2770 signal.alarm(0)
2771
2772 path = pjoin(self.me_dir,'bin','internal','ufomodel','ASperGE')
2773 if not os.path.exists(path):
2774 logger.error('ASperge has not been detected in the current model, therefore it will not be run.')
2775 return
2776 elif not os.path.exists(pjoin(path,'ASperGe')):
2777 logger.info('ASperGe has been detected but is not compiled. Running the compilation now.')
2778 try:
2779 misc.compile(cwd=path,shell=True)
2780 except MadGraph5Error, error:
2781 logger.error('''ASperGe failed to compile. Note that gsl is needed
2782 for this compilation to go trough. More information on how to install this package on
2783 http://www.gnu.org/software/gsl/
2784 Full compilation log is available at %s''' % pjoin(self.me_dir, 'ASperge_compilation.log'))
2785 open(pjoin(self.me_dir, 'ASperge_compilation.log'),'w').write(str(error))
2786 return
2787
2788 opts = line.split()
2789 card = pjoin(self.me_dir,'Cards', 'param_card.dat')
2790 logger.info('running ASperGE')
2791 returncode = misc.call([pjoin(path,'ASperGe'), card, '%s.new' % card] + opts)
2792 if returncode:
2793 logger.error('ASperGE fails with status %s' % returncode)
2794 else:
2795 logger.info('AsPerGe creates the file succesfully')
2796 files.mv(card, '%s.beforeasperge' % card)
2797 files.mv('%s.new' % card, card)
2798
2799
2800
2802 """detect the type of the file and overwritte the current file"""
2803
2804 if path.endswith('.lhco'):
2805
2806
2807 self.do_set('mw_run inputfile %s' % os.path.relpath(path, self.mother_interface.me_dir))
2808 return
2809 elif path.endswith('.lhco.gz'):
2810
2811
2812 self.do_set('mw_run inputfile %s' % os.path.relpath(path, self.mother_interface.me_dir))
2813 return
2814 else:
2815 card_name = CommonRunCmd.detect_card_type(path)
2816
2817 if card_name == 'unknown':
2818 logger.warning('Fail to determine the type of the file. Not copied')
2819 if card_name != 'banner':
2820 logger.info('copy %s as %s' % (path, card_name))
2821 files.cp(path, pjoin(self.mother_interface.me_dir, 'Cards', card_name))
2822 elif card_name == 'banner':
2823 banner_mod.split_banner(path, self.mother_interface.me_dir, proc_card=False)
2824 logger.info('Splitting the banner in it\'s component')
2825 if not self.mode == 'auto':
2826 self.mother_interface.keep_cards(self.cards)
2827
2829 """open the file"""
2830 me_dir = self.mother_interface.me_dir
2831 if answer.isdigit():
2832 if answer == '9':
2833 answer = 'plot'
2834 else:
2835 answer = self.cards[int(answer)-1]
2836 if 'madweight' in answer:
2837 answer = answer.replace('madweight', 'MadWeight')
2838
2839 if not '.dat' in answer and not '.lhco' in answer:
2840 if answer != 'trigger':
2841 path = pjoin(me_dir,'Cards','%s_card.dat' % answer)
2842 else:
2843 path = pjoin(me_dir,'Cards','delphes_trigger.dat')
2844 elif not '.lhco' in answer:
2845 path = pjoin(me_dir, 'Cards', answer)
2846 else:
2847 path = pjoin(me_dir, self.mw_card['mw_run']['inputfile'])
2848 if not os.path.exists(path):
2849 logger.info('Path in MW_card not existing')
2850 path = pjoin(me_dir, 'Events', answer)
2851
2852 path = path.replace('_card_card','_card')
2853 try:
2854 self.mother_interface.exec_cmd('open %s' % path)
2855 except InvalidCmd, error:
2856 if str(error) != 'No default path for this file':
2857 raise
2858 if answer == 'transfer_card.dat':
2859 logger.warning('You have to specify a transfer function first!')
2860 elif answer == 'input.lhco':
2861 path = pjoin(me_dir,'Events', 'input.lhco')
2862 ff = open(path,'w')
2863 ff.write('''No LHCO information imported at current time.
2864 To import a lhco file: Close this file and type the path of your file.
2865 You can also copy/paste, your event file here.''')
2866 ff.close()
2867 self.open_file(path)
2868 else:
2869 raise
2870
2871
2872 if path == pjoin(self.me_dir,'Cards','param_card.dat'):
2873 try:
2874 self.param_card = check_param_card.ParamCard(path)
2875 except (check_param_card.InvalidParamCard, ValueError) as e:
2876 logger.error('Current param_card is not valid. We are going to use the default one.')
2877 logger.error('problem detected: %s' % e)
2878 logger.error('Please re-open the file and fix the problem.')
2879 logger.warning('using the \'set\' command without opening the file will discard all your manual change')
2880 elif path == pjoin(self.me_dir,'Cards','run_card.dat'):
2881 self.run_card = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card.dat'))
2882 elif path == pjoin(self.me_dir,'Cards','MadWeight_card.dat'):
2883 try:
2884 import madgraph.madweight.Cards as mwcards
2885 except:
2886 import internal.madweight.Cards as mwcards
2887 self.mw_card = mwcards.Card(pjoin(self.me_dir,'Cards','MadWeight_card.dat'))
2888