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