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