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 import sets
39
40
41 try:
42 import readline
43 GNU_SPLITTING = ('GNU' in readline.__doc__)
44 except:
45 GNU_SPLITTING = True
46
47 root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
48 root_path = os.path.split(root_path)[0]
49 sys.path.insert(0, os.path.join(root_path,'bin'))
50
51
52 pjoin = os.path.join
53
54 logger = logging.getLogger('madgraph.stdout')
55 logger_stderr = logging.getLogger('madgraph.stderr')
56
57
58 try:
59 import madgraph
60 except ImportError:
61
62 import internal.extended_cmd as cmd
63 import internal.banner as banner_mod
64 import internal.shower_card as shower_card_mod
65 import internal.misc as misc
66 import internal.cluster as cluster
67 import internal.check_param_card as check_param_card
68 import internal.files as files
69 import internal.save_load_object as save_load_object
70 import internal.gen_crossxhtml as gen_crossxhtml
71 from internal import InvalidCmd, MadGraph5Error
72 MADEVENT=True
73 else:
74
75 import madgraph.interface.extended_cmd as cmd
76 import madgraph.various.banner as banner_mod
77 import madgraph.various.shower_card as shower_card_mod
78 import madgraph.various.misc as misc
79 import madgraph.iolibs.files as files
80 import madgraph.various.cluster as cluster
81 import madgraph.iolibs.save_load_object as save_load_object
82 import madgraph.madevent.gen_crossxhtml as gen_crossxhtml
83 import models.check_param_card as check_param_card
84
85 from madgraph import InvalidCmd, MadGraph5Error, MG5DIR
86 MADEVENT=False
92 """ The Series of help routins in common between amcatnlo_run and
93 madevent interface"""
94
96 logger.info("syntax: treatcards [param|run] [--output_dir=] [--param_card=] [--run_card=]")
97 logger.info("-- create the .inc files containing the cards information." )
98
100 logger.info("syntax: set %s argument" % "|".join(self._set_options))
101 logger.info("-- set options")
102 logger.info(" stdout_level DEBUG|INFO|WARNING|ERROR|CRITICAL")
103 logger.info(" change the default level for printed information")
104 logger.info(" timeout VALUE")
105 logger.info(" (default 20) Seconds allowed to answer questions.")
106 logger.info(" Note that pressing tab always stops the timer.")
107 logger.info(" cluster_temp_path PATH")
108 logger.info(" (default None) Allow to perform the run in PATH directory")
109 logger.info(" This allow to not run on the central disk. This is not used")
110 logger.info(" by condor cluster (since condor has it's own way to prevent it).")
111
113 logger.info("syntax: help [RUN] [%s] [-f]" % '|'.join(self._plot_mode))
114 logger.info("-- create the plot for the RUN (current run by default)")
115 logger.info(" at the different stage of the event generation")
116 logger.info(" Note than more than one mode can be specified in the same command.")
117 logger.info(" This require to have MadAnalysis and td require. By default")
118 logger.info(" if those programs are installed correctly, the creation")
119 logger.info(" will be performed automaticaly during the event generation.")
120 logger.info(" -f options: answer all question by default.")
121
123 logger.info("syntax: compute_widths Particle [Particles] [OPTIONS]")
124 logger.info("-- Compute the widths for the particles specified.")
125 logger.info(" By default, this takes the current param_card and overwrites it.")
126 logger.info(" Precision allows to define when to include three/four/... body decays (LO).")
127 logger.info(" If this number is an integer then all N-body decay will be included.")
128 logger.info(" Various options:\n")
129 logger.info(" --body_decay=X: Parameter to control the precision of the computation")
130 logger.info(" if X is an integer, we compute all channels up to X-body decay.")
131 logger.info(" if X <1, then we stop when the estimated error is lower than X.")
132 logger.info(" if X >1 BUT not an integer, then we X = N + M, with M <1 and N an integer")
133 logger.info(" We then either stop at the N-body decay or when the estimated error is lower than M.")
134 logger.info(" default: 4.0025")
135 logger.info(" --min_br=X: All channel which are estimated below this value will not be integrated numerically.")
136 logger.info(" default: precision (decimal part of the body_decay options) divided by four")
137 logger.info(" --precision_channel=X: requested numerical precision for each channel")
138 logger.info(" default: 0.01")
139 logger.info(" --path=X: path for param_card")
140 logger.info(" default: take value from the model")
141 logger.info(" --output=X: path where to write the resulting card. ")
142 logger.info(" default: overwrite input file. If no input file, write it in the model directory")
143 logger.info(" --nlo: Compute NLO width [if the model support it]")
144
145
147 logger.info("syntax: pythia [RUN] [--run_options]")
148 logger.info("-- run pythia on RUN (current one by default)")
149 self.run_options_help([('-f','answer all question by default'),
150 ('--tag=', 'define the tag for the pythia run'),
151 ('--no_default', 'not run if pythia_card not present')])
152
154 logger.info("syntax: pgs [RUN] [--run_options]")
155 logger.info("-- run pgs on RUN (current one by default)")
156 self.run_options_help([('-f','answer all question by default'),
157 ('--tag=', 'define the tag for the pgs run'),
158 ('--no_default', 'not run if pgs_card not present')])
159
161 logger.info("syntax: delphes [RUN] [--run_options]")
162 logger.info("-- run delphes on RUN (current one by default)")
163 self.run_options_help([('-f','answer all question by default'),
164 ('--tag=', 'define the tag for the delphes run'),
165 ('--no_default', 'not run if delphes_card not present')])
166
168 if not skip_syntax:
169 logger.info("syntax: decay_events [RUN]")
170 logger.info("This functionality allows for the decay of resonances")
171 logger.info("in a .lhe file, keeping track of the spin correlation effets.")
172 logger.info("BE AWARE OF THE CURRENT LIMITATIONS:")
173 logger.info(" (1) Only a succession of 2 body decay are currently allowed")
174
178 """ The Series of check routines in common between amcatnlo_run and
179 madevent interface"""
180
182 """ check the validity of the line"""
183
184
185 if len(args) < 2:
186 if len(args)==1 and "=" in args[0]:
187 args[:] = args[0].split("=",1)
188 else:
189 self.help_set()
190 raise self.InvalidCmd('set needs an option and an argument')
191
192 if args[0] not in self._set_options + self.options.keys():
193 self.help_set()
194 raise self.InvalidCmd('Possible options for set are %s' % \
195 (self._set_options+self.options.keys()))
196
197 if args[0] in ['stdout_level']:
198 if args[1] not in ['DEBUG','INFO','WARNING','ERROR','CRITICAL'] \
199 and not args[1].isdigit():
200 raise self.InvalidCmd('output_level needs ' + \
201 'a valid level')
202
203 if args[0] in ['timeout']:
204 if not args[1].isdigit():
205 raise self.InvalidCmd('timeout values should be a integer')
206
208 """check that the model is loadable and check that the format is of the
209 type: PART PATH --output=PATH -f --precision=N
210 return the model.
211 """
212
213
214 if MADEVENT and not self.options['mg5_path']:
215 raise self.InvalidCmd, '''The automatic computations of widths requires that MG5 is installed on the system.
216 You can install it and set his path in ./Cards/me5_configuration.txt'''
217 elif MADEVENT:
218 sys.path.append(self.options['mg5_path'])
219 try:
220 import models.model_reader as model_reader
221 import models.import_ufo as import_ufo
222 except ImportError:
223 raise self.ConfigurationError, '''Can\'t load MG5.
224 The variable mg5_path should not be correctly configure.'''
225
226
227 ufo_path = pjoin(self.me_dir,'bin','internal', 'ufomodel')
228
229 if not MADEVENT:
230 modelname = self.find_model_name()
231
232
233
234
235 force_CMS = self.mother and self.mother.options['complex_mass_scheme']
236 model = import_ufo.import_model(modelname, decay=True,
237 restrict=True, complex_mass_scheme=force_CMS)
238 else:
239
240 has_cms = re.compile(r'''set\s+complex_mass_scheme\s*(True|T|1|true|$|;)''')
241 force_CMS = has_cms.search(open(pjoin(self.me_dir,'Cards',
242 'proc_card_mg5.dat')).read())
243 model = import_ufo.import_model(pjoin(self.me_dir,'bin','internal',
244 'ufomodel'), decay=True, complex_mass_scheme=force_CMS)
245
246
247
248
249
250 if '-modelname' not in open(pjoin(self.me_dir,'Cards','proc_card_mg5.dat')).read():
251 model.pass_particles_name_in_mg_default()
252 model = model_reader.ModelReader(model)
253 particles_name = dict([(p.get('name'), p.get('pdg_code'))
254 for p in model.get('particles')])
255 particles_name.update(dict([(p.get('antiname'), p.get('pdg_code'))
256 for p in model.get('particles')]))
257
258 output = {'model': model, 'force': False, 'output': None,
259 'path':None, 'particles': set(), 'body_decay':4.0025,
260 'min_br':None, 'precision_channel':0.01}
261 for arg in args:
262 if arg.startswith('--output='):
263 output_path = arg.split('=',1)[1]
264 if not os.path.exists(output_path):
265 raise self.InvalidCmd, 'Invalid Path for the output. Please retry.'
266 if not os.path.isfile(output_path):
267 output_path = pjoin(output_path, 'param_card.dat')
268 output['output'] = output_path
269 elif arg == '-f':
270 output['force'] = True
271 elif os.path.isfile(arg):
272 ftype = self.detect_card_type(arg)
273 if ftype != 'param_card.dat':
274 raise self.InvalidCmd , '%s is not a valid param_card.' % arg
275 output['path'] = arg
276 elif arg.startswith('--path='):
277 arg = arg.split('=',1)[1]
278 ftype = self.detect_card_type(arg)
279 if ftype != 'param_card.dat':
280 raise self.InvalidCmd , '%s is not a valid param_card.' % arg
281 output['path'] = arg
282 elif arg.startswith('--'):
283 if "=" in arg:
284 name, value = arg.split('=',1)
285 try:
286 value = float(value)
287 except Exception:
288 raise self.InvalidCmd, '--%s requires integer or a float' % name
289 output[name[2:]] = float(value)
290 elif arg == "--nlo":
291 output["nlo"] = True
292 elif arg in particles_name:
293
294 output['particles'].add(particles_name[arg])
295 elif arg.isdigit() and int(arg) in particles_name.values():
296 output['particles'].add(eval(arg))
297 elif arg == 'all':
298 output['particles'] = set(['all'])
299 else:
300 self.help_compute_widths()
301 raise self.InvalidCmd, '%s is not a valid argument for compute_widths' % arg
302 if self.force:
303 output['force'] = True
304
305 if not output['particles']:
306 raise self.InvalidCmd, '''This routines requires at least one particle in order to compute
307 the related width'''
308
309 if output['output'] is None:
310 output['output'] = output['path']
311
312 return output
313
315 """ check the validity of the line """
316
317 if len(args) != 1:
318 self.help_open()
319 raise self.InvalidCmd('OPEN command requires exactly one argument')
320
321 if args[0].startswith('./'):
322 if not os.path.isfile(args[0]):
323 raise self.InvalidCmd('%s: not such file' % args[0])
324 return True
325
326
327 if not self.me_dir:
328 if not os.path.isfile(args[0]):
329 self.help_open()
330 raise self.InvalidCmd('No MadEvent path defined. Unable to associate this name to a file')
331 else:
332 return True
333
334 path = self.me_dir
335 if os.path.isfile(os.path.join(path,args[0])):
336 args[0] = os.path.join(path,args[0])
337 elif os.path.isfile(os.path.join(path,'Cards',args[0])):
338 args[0] = os.path.join(path,'Cards',args[0])
339 elif os.path.isfile(os.path.join(path,'HTML',args[0])):
340 args[0] = os.path.join(path,'HTML',args[0])
341
342 elif '_card.dat' in args[0]:
343 name = args[0].replace('_card.dat','_card_default.dat')
344 if os.path.isfile(os.path.join(path,'Cards', name)):
345 files.cp(os.path.join(path,'Cards', name), os.path.join(path,'Cards', args[0]))
346 args[0] = os.path.join(path,'Cards', args[0])
347 else:
348 raise self.InvalidCmd('No default path for this file')
349 elif not os.path.isfile(args[0]):
350 raise self.InvalidCmd('No default path for this file')
351
353 """check that treatcards arguments are valid
354 [param|run|all] [--output_dir=] [--param_card=] [--run_card=]
355 """
356
357 opt = {'output_dir':pjoin(self.me_dir,'Source'),
358 'param_card':pjoin(self.me_dir,'Cards','param_card.dat'),
359 'run_card':pjoin(self.me_dir,'Cards','run_card.dat')}
360 mode = 'all'
361 for arg in args:
362 if arg.startswith('--') and '=' in arg:
363 key,value =arg[2:].split('=',1)
364 if not key in opt:
365 self.help_treatcards()
366 raise self.InvalidCmd('Invalid option for treatcards command:%s ' \
367 % key)
368 if key in ['param_card', 'run_card']:
369 if os.path.isfile(value):
370 card_name = self.detect_card_type(value)
371 if card_name != key:
372 raise self.InvalidCmd('Format for input file detected as %s while expecting %s'
373 % (card_name, key))
374 opt[key] = value
375 elif os.path.isfile(pjoin(self.me_dir,value)):
376 card_name = self.detect_card_type(pjoin(self.me_dir,value))
377 if card_name != key:
378 raise self.InvalidCmd('Format for input file detected as %s while expecting %s'
379 % (card_name, key))
380 opt[key] = value
381 else:
382 raise self.InvalidCmd('No such file: %s ' % value)
383 elif key in ['output_dir']:
384 if os.path.isdir(value):
385 opt[key] = value
386 elif os.path.isdir(pjoin(self.me_dir,value)):
387 opt[key] = pjoin(self.me_dir, value)
388 else:
389 raise self.InvalidCmd('No such directory: %s' % value)
390 elif arg in ['MadLoop','param','run','all']:
391 mode = arg
392 else:
393 self.help_treatcards()
394 raise self.InvalidCmd('Unvalid argument %s' % arg)
395
396 return mode, opt
397
399 """Check the argument for decay_events command
400 syntax is "decay_events [NAME]"
401 Note that other option are already remove at this point
402 """
403
404 opts = []
405 if '-from_cards' in args:
406 args.remove('-from_cards')
407 opts.append('-from_cards')
408
409 if len(args) == 0:
410 if self.run_name:
411 args.insert(0, self.run_name)
412 elif self.results.lastrun:
413 args.insert(0, self.results.lastrun)
414 else:
415 raise self.InvalidCmd('No run name currently defined. Please add this information.')
416 return
417
418 if args[0] != self.run_name:
419 self.set_run_name(args[0])
420
421 args[0] = self.get_events_path(args[0])
422
423 args += opts
424
426 """Check the argument for decay_events command
427 syntax is "decay_events [NAME]"
428 Note that other option are already remove at this point
429 """
430
431 if len(args) == 0:
432 if self.run_name:
433 args.insert(0, self.run_name)
434 elif self.results.lastrun:
435 args.insert(0, self.results.lastrun)
436 else:
437 raise self.InvalidCmd('No run name currently defined. Please add this information.')
438 return
439
440 if args[0] and os.path.isfile(args[0]):
441 pass
442 else:
443 if args[0] != self.run_name:
444 self.set_run_name(args[0], allow_new_tag=False)
445
446 args[0] = self.get_events_path(args[0])
447
448
450 """return the path to the output events
451 """
452
453
454 if self.mode == 'madevent':
455 possible_path = [
456 pjoin(self.me_dir,'Events', run_name, 'unweighted_events.lhe.gz'),
457 pjoin(self.me_dir,'Events', run_name, 'unweighted_events.lhe')]
458 else:
459 possible_path = [
460 pjoin(self.me_dir,'Events', run_name, 'events.lhe.gz'),
461 pjoin(self.me_dir,'Events', run_name, 'events.lhe')]
462
463 for path in possible_path:
464 if os.path.exists(path):
465 correct_path = path
466 break
467 else:
468 raise self.InvalidCmd('No events file corresponding to %s run. ' % run_name)
469 return correct_path
470
477
478
479
480
481 -class CommonRunCmd(HelpToCmd, CheckValidForCmd, cmd.Cmd):
482
483 debug_output = 'ME5_debug'
484 helporder = ['Main Commands', 'Documented commands', 'Require MG5 directory',
485 'Advanced commands']
486
487
488
489 options_configuration = {'pythia8_path': './pythia8',
490 'hwpp_path': './herwigPP',
491 'thepeg_path': './thepeg',
492 'hepmc_path': './hepmc',
493 'madanalysis_path': './MadAnalysis',
494 'pythia-pgs_path':'./pythia-pgs',
495 'td_path':'./td',
496 'delphes_path':'./Delphes',
497 'exrootanalysis_path':'./ExRootAnalysis',
498 'syscalc_path': './SysCalc',
499 'lhapdf': 'lhapdf-config',
500 'timeout': 60,
501 'f2py_compiler':None,
502 'web_browser':None,
503 'eps_viewer':None,
504 'text_editor':None,
505 'fortran_compiler':None,
506 'cpp_compiler': None,
507 'auto_update':7,
508 'cluster_type': 'condor',
509 'cluster_status_update': (600, 30),
510 'cluster_nb_retry':1,
511 'cluster_local_path': "/cvmfs/cp3.uclouvain.be/madgraph/",
512 'cluster_retry_wait':300}
513
514 options_madgraph= {'stdout_level':None}
515
516 options_madevent = {'automatic_html_opening':True,
517 'notification_center':True,
518 'run_mode':2,
519 'cluster_queue':'madgraph',
520 'cluster_time':None,
521 'cluster_size':100,
522 'cluster_memory':None,
523 'nb_core': None,
524 'cluster_temp_path':None}
525
526
527 - def __init__(self, me_dir, options, *args, **opts):
528 """common"""
529
530 self.force_run = False
531 if 'force_run' in opts and opts['force_run']:
532 self.force_run = True
533 del opts['force_run']
534
535 cmd.Cmd.__init__(self, *args, **opts)
536
537 if me_dir is None and MADEVENT:
538 me_dir = root_path
539
540 self.me_dir = me_dir
541 self.options = options
542
543 self.param_card_iterator = []
544
545
546 self.status = pjoin(self.me_dir, 'status')
547 self.error = pjoin(self.me_dir, 'error')
548 self.dirbin = pjoin(self.me_dir, 'bin', 'internal')
549
550
551 if not self.force_run:
552 if os.path.exists(pjoin(me_dir,'RunWeb')):
553 message = '''Another instance of the program is currently running.
554 (for this exact same directory) Please wait that this is instance is
555 closed. If no instance is running, you can delete the file
556 %s and try again.''' % pjoin(me_dir,'RunWeb')
557 raise AlreadyRunning, message
558 else:
559 pid = os.getpid()
560 fsock = open(pjoin(me_dir,'RunWeb'),'w')
561 fsock.write(`pid`)
562 fsock.close()
563
564 misc.Popen([os.path.relpath(pjoin(self.dirbin, 'gen_cardhtml-pl'), me_dir)],
565 cwd=me_dir)
566
567 self.to_store = []
568 self.run_name = None
569 self.run_tag = None
570 self.banner = None
571
572 self.set_configuration()
573 self.configure_run_mode(self.options['run_mode'])
574
575
576 self.get_characteristics()
577
578 if not self.proc_characteristics['ninitial']:
579
580 nexternal = open(pjoin(self.me_dir,'Source','nexternal.inc')).read()
581 found = re.search("PARAMETER\s*\(NINCOMING=(\d)\)", nexternal)
582 self.ninitial = int(found.group(1))
583 else:
584 self.ninitial = self.proc_characteristics['ninitial']
585
586
587
621
622 @misc.multiple_try(nb_try=5, sleep=2)
624 """load the current results status"""
625
626
627 if os.path.exists(pjoin(self.me_dir,'HTML','results.pkl')):
628 try:
629 self.results = save_load_object.load_from_file(pjoin(self.me_dir,'HTML','results.pkl'))
630 except Exception:
631
632 model = self.find_model_name()
633 process = self.process
634 self.results = gen_crossxhtml.AllResults(model, process, self.me_dir)
635 self.results.resetall(self.me_dir)
636 else:
637 self.results.resetall(self.me_dir)
638 try:
639 self.last_mode = self.results[self.results.lastrun][-1]['run_mode']
640 except:
641 self.results.resetall(self.me_dir)
642 self.last_mode = ''
643 else:
644 model = self.find_model_name()
645 process = self.process
646 self.results = gen_crossxhtml.AllResults(model, process, self.me_dir)
647 self.results.resetall(self.me_dir)
648 self.last_mode=''
649 return self.results
650
651
653 """Advanced commands: create .inc files from param_card.dat/run_card.dat"""
654
655 keepwidth = False
656 if '--keepwidth' in line:
657 keepwidth = True
658 line = line.replace('--keepwidth', '')
659 args = self.split_arg(line)
660 mode, opt = self.check_treatcards(args)
661
662 if mode in ['run', 'all']:
663 if not hasattr(self, 'run_card'):
664 if amcatnlo:
665 run_card = banner_mod.RunCardNLO(opt['run_card'])
666 else:
667 run_card = banner_mod.RunCard(opt['run_card'])
668 else:
669 run_card = self.run_card
670
671
672 if amcatnlo and run_card['pdlabel']=='lhapdf':
673 pdfsetsdir=self.get_lhapdf_pdfsetsdir()
674 pdfsets=self.get_lhapdf_pdfsets_list(pdfsetsdir)
675 lhapdfsetname=[]
676 for lhaid in run_card['lhaid']:
677 if lhaid in pdfsets:
678 lhapdfsetname.append(pdfsets[lhaid]['filename'])
679 else:
680 raise MadGraph5Error("lhaid %s is not a valid PDF identification number. This can be due to the use of an outdated version of LHAPDF, or %s is not a LHAGlue number corresponding to a central PDF set (but rather one of the error sets)." % (lhaid,lhaid))
681 run_card['lhapdfsetname']=lhapdfsetname
682 run_card.write_include_file(pjoin(opt['output_dir'],'run_card.inc'))
683
684 if mode in ['MadLoop', 'all']:
685 if os.path.exists(pjoin(self.me_dir, 'Cards', 'MadLoopParams.dat')):
686 self.MadLoopparam = banner_mod.MadLoopParam(pjoin(self.me_dir,
687 'Cards', 'MadLoopParams.dat'))
688
689 self.MadLoopparam.write(pjoin(self.me_dir,"SubProcesses",
690 "MadLoopParams.dat"))
691
692 if mode in ['param', 'all']:
693 if os.path.exists(pjoin(self.me_dir, 'Source', 'MODEL', 'mp_coupl.inc')):
694 param_card = check_param_card.ParamCardMP(opt['param_card'])
695 else:
696 param_card = check_param_card.ParamCard(opt['param_card'])
697 outfile = pjoin(opt['output_dir'], 'param_card.inc')
698 ident_card = pjoin(self.me_dir,'Cards','ident_card.dat')
699 if os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')):
700 default = pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')
701 elif os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')):
702 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
703 elif not os.path.exists(pjoin(self.me_dir,'bin','internal','ufomodel')):
704 fsock = open(pjoin(self.me_dir,'Source','param_card.inc'),'w')
705 fsock.write(' ')
706 fsock.close()
707 return
708 else:
709 subprocess.call(['python', 'write_param_card.py'],
710 cwd=pjoin(self.me_dir,'bin','internal','ufomodel'))
711 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
712
713
714 if amcatnlo and not keepwidth:
715
716 pids = self.get_pid_final_initial_states()
717
718 if not MADEVENT and pjoin(self.me_dir,'bin','internal') not in sys.path:
719 sys.path.insert(0,pjoin(self.me_dir,'bin','internal'))
720
721
722
723 to_del = [name for name in sys.modules.keys()
724 if name.startswith('internal.ufomodel')
725 or name.startswith('ufomodel')]
726 for name in to_del:
727 del(sys.modules[name])
728
729 import ufomodel as ufomodel
730 zero = ufomodel.parameters.ZERO
731 no_width = [p for p in ufomodel.all_particles
732 if (str(p.pdg_code) in pids or str(-p.pdg_code) in pids)
733 and p.color != 1 and p.width != zero]
734 done = []
735 for part in no_width:
736 if abs(part.pdg_code) in done:
737 continue
738 done.append(abs(part.pdg_code))
739 param = param_card['decay'].get((part.pdg_code,))
740
741 if param.value != 0:
742 logger.info('''For gauge cancellation, the width of \'%s\' has been set to zero.'''
743 % part.name,'$MG:color:BLACK')
744 param.value = 0
745
746 param_card.write_inc_file(outfile, ident_card, default)
747
748
749 - def ask_edit_cards(self, cards, mode='fixed', plot=True, first_cmd=None):
750 """ """
751 if not self.options['madanalysis_path']:
752 plot = False
753
754 self.ask_edit_card_static(cards, mode, plot, self.options['timeout'],
755 self.ask, first_cmd=first_cmd)
756
757 @staticmethod
760 if not ask:
761 ask = CommonRunCmd.ask
762
763 def path2name(path):
764 if '_card' in path:
765 return path.split('_card')[0]
766 elif path == 'delphes_trigger.dat':
767 return 'trigger'
768 elif path == 'input.lhco':
769 return 'lhco'
770 elif path == 'MadLoopParams.dat':
771 return 'MadLoopParams'
772 else:
773 raise Exception, 'Unknow cards name %s' % path
774
775
776
777 question = """Do you want to edit a card (press enter to bypass editing)?\n"""
778 possible_answer = ['0', 'done']
779 card = {0:'done'}
780
781 for i, card_name in enumerate(cards):
782 imode = path2name(card_name)
783 possible_answer.append(i+1)
784 possible_answer.append(imode)
785 question += ' %s / %-10s : %s\n' % (i+1, imode, card_name)
786 card[i+1] = imode
787 if plot:
788 question += ' 9 / %-10s : plot_card.dat\n' % 'plot'
789 possible_answer.append(9)
790 possible_answer.append('plot')
791 card[9] = 'plot'
792
793 if 'param_card.dat' in cards:
794
795 question += ' you can also\n'
796 question += ' - enter the path to a valid card or banner.\n'
797 question += ' - use the \'set\' command to modify a parameter directly.\n'
798 question += ' The set option works only for param_card and run_card.\n'
799 question += ' Type \'help set\' for more information on this command.\n'
800 question += ' - call an external program (ASperGE/MadWidth/...).\n'
801 question += ' Type \'help\' for the list of available command\n'
802 else:
803 question += ' you can also\n'
804 question += ' - enter the path to a valid card.\n'
805 if 'transfer_card.dat' in cards:
806 question += ' - use the \'change_tf\' command to set a transfer functions.\n'
807
808 out = 'to_run'
809 while out not in ['0', 'done']:
810 out = ask(question, '0', possible_answer, timeout=int(1.5*timeout),
811 path_msg='enter path', ask_class = AskforEditCard,
812 cards=cards, mode=mode, **opt)
813
814
815
816 @staticmethod
818 """detect the type of the card. Return value are
819 banner
820 param_card.dat
821 run_card.dat
822 pythia_card.dat
823 plot_card.dat
824 pgs_card.dat
825 delphes_card.dat
826 delphes_trigger.dat
827 shower_card.dat [aMCatNLO]
828 FO_analyse_card.dat [aMCatNLO]
829 madspin_card.dat [MS]
830 transfer_card.dat [MW]
831 madweight_card.dat [MW]
832 """
833
834 fulltext = open(path).read(50000)
835 if fulltext == '':
836 logger.warning('File %s is empty' % path)
837 return 'unknown'
838 text = re.findall('(<MGVersion>|ParticlePropagator|ExecutionPath|Treewriter|<mg5proccard>|CEN_max_tracker|#TRIGGER CARD|parameter set name|muon eta coverage|req_acc_FO|MSTP|b_stable|FO_ANALYSIS_FORMAT|MSTU|Begin Minpts|gridpack|ebeam1|block\s+mw_run|BLOCK|DECAY|launch|madspin|transfer_card\.dat|set)', fulltext, re.I)
839 text = [t.lower() for t in text]
840 if '<mgversion>' in text or '<mg5proccard>' in text:
841 return 'banner'
842 elif 'particlepropagator' in text or 'executionpath' in text or 'treewriter' in text:
843 return 'delphes_card.dat'
844 elif 'cen_max_tracker' in text:
845 return 'delphes_card.dat'
846 elif '#trigger card' in text:
847 return 'delphes_trigger.dat'
848 elif 'parameter set name' in text:
849 return 'pgs_card.dat'
850 elif 'muon eta coverage' in text:
851 return 'pgs_card.dat'
852 elif 'mstp' in text and not 'b_stable' in text:
853 return 'pythia_card.dat'
854 elif 'begin minpts' in text:
855 return 'plot_card.dat'
856 elif ('gridpack' in text and 'ebeam1' in text) or \
857 ('req_acc_fo' in text and 'ebeam1' in text):
858 return 'run_card.dat'
859 elif any(t.endswith('mw_run') for t in text):
860 return 'madweight_card.dat'
861 elif 'transfer_card.dat' in text:
862 return 'transfer_card.dat'
863 elif 'block' in text and 'decay' in text:
864 return 'param_card.dat'
865 elif 'b_stable' in text:
866 return 'shower_card.dat'
867 elif 'fo_analysis_format' in text:
868 return 'FO_analyse_card.dat'
869 elif 'launch' in text:
870
871
872 if 'madspin' in text:
873 return 'madspin_card.dat'
874 if 'decay' in text:
875
876 if re.search("(^|;)\s*decay", fulltext):
877 return 'madspin_card.dat'
878 else:
879 return 'reweight_card.dat'
880 else:
881 return 'reweight_card.dat'
882 else:
883 return 'unknown'
884
885
886
888 """create automatically a tag"""
889
890 used_tags = [r['tag'] for r in self.results[self.run_name]]
891 i=0
892 while 1:
893 i+=1
894 if 'tag_%s' %i not in used_tags:
895 return 'tag_%s' % i
896
897
898
899 - def create_plot(self, mode='parton', event_path=None, output=None, tag=None):
900 """create the plot"""
901
902 madir = self.options['madanalysis_path']
903 if not tag:
904 tag = self.run_card['run_tag']
905 td = self.options['td_path']
906
907 if not madir or not td or \
908 not os.path.exists(pjoin(self.me_dir, 'Cards', 'plot_card.dat')):
909 return False
910
911 if 'ickkw' in self.run_card and int(self.run_card['ickkw']) and \
912 mode == 'Pythia':
913 self.update_status('Create matching plots for Pythia', level='pythia')
914
915 if not os.path.exists(pjoin(self.me_dir,'Events','events.tree')):
916 misc.gunzip(pjoin(self.me_dir,'Events',
917 self.run_name, '%s_pythia_events.tree.gz' % tag), keep=True,
918 stdout=pjoin(self.me_dir,'Events','events.tree'))
919 files.mv(pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_xsecs.tree'),
920 pjoin(self.me_dir,'Events','xsecs.tree'))
921
922
923 misc.call([self.dirbin+'/create_matching_plots.sh',
924 self.run_name, tag, madir],
925 stdout = os.open(os.devnull, os.O_RDWR),
926 cwd=pjoin(self.me_dir,'Events'))
927
928
929 misc.gzip(pjoin(self.me_dir,"Events","events.tree"),
930 stdout=pjoin(self.me_dir,'Events',self.run_name, tag + '_pythia_events.tree.gz'))
931 files.mv(pjoin(self.me_dir,'Events','xsecs.tree'),
932 pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_xsecs.tree'))
933
934
935 if not event_path:
936 if mode == 'parton':
937 possibilities=[
938 pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'),
939 pjoin(self.me_dir, 'Events', 'unweighted_events.lhe.gz'),
940 pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe'),
941 pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe.gz')]
942 for event_path in possibilities:
943 if os.path.exists(event_path):
944 break
945 output = pjoin(self.me_dir, 'HTML',self.run_name, 'plots_parton.html')
946
947 elif mode == 'Pythia':
948 event_path = pjoin(self.me_dir, 'Events','pythia_events.lhe')
949 output = pjoin(self.me_dir, 'HTML',self.run_name,
950 'plots_pythia_%s.html' % tag)
951 elif mode == 'PGS':
952 event_path = pjoin(self.me_dir, 'Events', self.run_name,
953 '%s_pgs_events.lhco' % tag)
954 output = pjoin(self.me_dir, 'HTML',self.run_name,
955 'plots_pgs_%s.html' % tag)
956 elif mode == 'Delphes':
957 event_path = pjoin(self.me_dir, 'Events', self.run_name,'%s_delphes_events.lhco' % tag)
958 output = pjoin(self.me_dir, 'HTML',self.run_name,
959 'plots_delphes_%s.html' % tag)
960 elif mode == "shower":
961 event_path = pjoin(self.me_dir, 'Events','pythia_events.lhe')
962 output = pjoin(self.me_dir, 'HTML',self.run_name,
963 'plots_shower_%s.html' % tag)
964 if not self.options['pythia-pgs_path']:
965 return
966 else:
967 raise self.InvalidCmd, 'Invalid mode %s' % mode
968 elif mode == 'reweight' and not output:
969 output = pjoin(self.me_dir, 'HTML',self.run_name,
970 'plots_%s.html' % tag)
971
972 if not os.path.exists(event_path):
973 if os.path.exists(event_path+'.gz'):
974 misc.gunzip('%s.gz' % event_path)
975 else:
976 raise self.InvalidCmd, 'Events file %s does not exist' % event_path
977 elif event_path.endswith(".gz"):
978 misc.gunzip(event_path)
979 event_path = event_path[:-3]
980
981
982 self.update_status('Creating Plots for %s level' % mode, level = mode.lower())
983
984 mode = mode.lower()
985 if mode not in ['parton', 'reweight']:
986 plot_dir = pjoin(self.me_dir, 'HTML', self.run_name,'plots_%s_%s' % (mode.lower(),tag))
987 elif mode == 'parton':
988 plot_dir = pjoin(self.me_dir, 'HTML', self.run_name,'plots_parton')
989 else:
990 plot_dir =pjoin(self.me_dir, 'HTML', self.run_name,'plots_%s' % (tag))
991
992 if not os.path.isdir(plot_dir):
993 os.makedirs(plot_dir)
994
995 files.ln(pjoin(self.me_dir, 'Cards','plot_card.dat'), plot_dir, 'ma_card.dat')
996
997 try:
998 proc = misc.Popen([os.path.join(madir, 'plot_events')],
999 stdout = open(pjoin(plot_dir, 'plot.log'),'w'),
1000 stderr = subprocess.STDOUT,
1001 stdin=subprocess.PIPE,
1002 cwd=plot_dir)
1003 proc.communicate('%s\n' % event_path)
1004 del proc
1005
1006 misc.call(['%s/plot' % self.dirbin, madir, td],
1007 stdout = open(pjoin(plot_dir, 'plot.log'),'a'),
1008 stderr = subprocess.STDOUT,
1009 cwd=plot_dir)
1010
1011 misc.call(['%s/plot_page-pl' % self.dirbin,
1012 os.path.basename(plot_dir),
1013 mode],
1014 stdout = open(pjoin(plot_dir, 'plot.log'),'a'),
1015 stderr = subprocess.STDOUT,
1016 cwd=pjoin(self.me_dir, 'HTML', self.run_name))
1017
1018 shutil.move(pjoin(self.me_dir, 'HTML',self.run_name ,'plots.html'),
1019 output)
1020
1021 logger.info("Plots for %s level generated, see %s" % \
1022 (mode, output))
1023 except OSError, error:
1024 logger.error('fail to create plot: %s. Please check that MadAnalysis is correctly installed.' % error)
1025
1026 self.update_status('End Plots for %s level' % mode, level = mode.lower(),
1027 makehtml=False)
1028
1029 return True
1030
1032 """Run hep2lhe on the file Events/pythia_events.hep"""
1033
1034 if not self.options['pythia-pgs_path']:
1035 raise self.InvalidCmd, 'No pythia-pgs path defined'
1036
1037 pydir = pjoin(self.options['pythia-pgs_path'], 'src')
1038 eradir = self.options['exrootanalysis_path']
1039
1040
1041 if misc.is_executable(pjoin(pydir, 'hep2lhe')):
1042 self.update_status('Creating shower LHE File (for plot)', level='pythia')
1043
1044 out = open(pjoin(self.me_dir,'Events','pythia_events.lhe'), 'w')
1045
1046 out.writelines('<!--\n')
1047 out.writelines('# Warning! Never use this file for detector studies!\n')
1048 out.writelines('-->\n<!--\n')
1049 if banner_path:
1050 out.writelines(open(banner_path).read().replace('<LesHouchesEvents version="1.0">',''))
1051 out.writelines('\n-->\n')
1052 out.close()
1053
1054 self.cluster.launch_and_wait(self.dirbin+'/run_hep2lhe',
1055 argument= [pydir],
1056 cwd=pjoin(self.me_dir,'Events'),
1057 stdout=os.devnull)
1058
1059 logger.info('Warning! Never use this lhe file for detector studies!')
1060
1061 if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHEFConverter')):
1062 self.update_status('Creating Pythia LHE Root File', level='pythia')
1063 try:
1064 misc.call([eradir+'/ExRootLHEFConverter',
1065 'pythia_events.lhe',
1066 pjoin(self.run_name, '%s_pythia_lhe_events.root' % self.run_tag)],
1067 cwd=pjoin(self.me_dir,'Events'))
1068 except Exception, error:
1069 misc.sprint('ExRootLHEFConverter fails', str(error),
1070 log=logger)
1071 pass
1072
1074 """Dummy routine, to be overwritten by daughter classes"""
1075
1076 pass
1077
1078
1080 """ syntax is "reweight RUN_NAME"
1081 Allow to reweight the events generated with a new choices of model
1082 parameter. Description of the methods are available here
1083 cp3.irmp.ucl.ac.be/projects/madgraph/wiki/Reweight
1084 """
1085
1086 if '-from_cards' in line and not os.path.exists(pjoin(self.me_dir, 'Cards', 'reweight_card.dat')):
1087 return
1088
1089
1090 if MADEVENT and not self.options['mg5_path']:
1091 raise self.InvalidCmd, '''The module reweight requires that MG5 is installed on the system.
1092 You can install it and set its path in ./Cards/me5_configuration.txt'''
1093 elif MADEVENT:
1094 sys.path.append(self.options['mg5_path'])
1095 try:
1096 import madgraph.interface.reweight_interface as reweight_interface
1097 except ImportError:
1098 raise self.ConfigurationError, '''Can\'t load Reweight module.
1099 The variable mg5_path might not be correctly configured.'''
1100
1101
1102
1103 if not '-from_cards' in line:
1104 self.keep_cards(['reweight_card.dat'], ignore=['*'])
1105 self.ask_edit_cards(['reweight_card.dat'], 'fixed', plot=False)
1106
1107
1108 args = self.split_arg(line)
1109
1110 if not self.force_run:
1111
1112 if self.run_name and self.results.current and self.results.current['cross'] == 0:
1113 self.results.delete_run(self.run_name, self.run_tag)
1114 self.results.save()
1115
1116 command = [sys.executable]
1117 if os.path.exists(pjoin(self.me_dir, 'bin', 'madevent')):
1118 command.append(pjoin(self.me_dir, 'bin', 'internal','madevent_interface.py'))
1119 else:
1120 command.append(pjoin(self.me_dir, 'bin', 'internal', 'amcatnlo_run_interface.py'))
1121 if not isinstance(self, cmd.CmdShell):
1122 command.append('--web')
1123 command.append('reweight')
1124 if self.run_name:
1125 command.append(self.run_name)
1126 else:
1127 command += args
1128 if '-from_cards' not in command:
1129 command.append('-from_cards')
1130 p = misc.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, cwd=self.me_dir)
1131 while p.poll() is None:
1132 line = p.stdout.readline()
1133 if any(t in line for t in ['INFO:', 'WARNING:', 'CRITICAL:', 'ERROR:', 'root:','KEEP:']) and \
1134 not '***********' in line:
1135 print line[:-1].replace('INFO', 'REWEIGHT').replace('KEEP:','')
1136 elif __debug__ and line:
1137 logger.debug(line[:-1])
1138 if p.returncode !=0:
1139 logger.error("Reweighting failed")
1140 return
1141 self.results = self.load_results_db()
1142
1143 try:
1144 if self.results[self.run_name][-2]['cross']==0:
1145 self.results.delete_run(self.run_name,self.results[self.run_name][-2]['tag'])
1146 except:
1147 pass
1148 try:
1149 if self.results.current['cross'] == 0 and self.run_name:
1150 self.results.delete_run(self.run_name, self.run_tag)
1151 except:
1152 pass
1153
1154 try:
1155 self.results.def_current(self.run_name, self.run_tag)
1156 except Exception:
1157 pass
1158 return
1159
1160 self.to_store.append('event')
1161
1162 if self.results.current['cross'] == 0 and self.run_name:
1163 self.results.delete_run(self.run_name, self.run_tag)
1164
1165 self.check_decay_events(args)
1166
1167 reweight_cmd = reweight_interface.ReweightInterface(args[0], mother=self)
1168
1169
1170 wgt_names = reweight_cmd.get_weight_names()
1171 if wgt_names == [''] and reweight_cmd.has_nlo:
1172 self.update_status('Running Reweighting (LO approximate)', level='madspin')
1173 else:
1174 self.update_status('Running Reweighting', level='madspin')
1175
1176 path = pjoin(self.me_dir, 'Cards', 'reweight_card.dat')
1177 reweight_cmd.raw_input=False
1178 reweight_cmd.me_dir = self.me_dir
1179 reweight_cmd.import_command_file(path)
1180 reweight_cmd.do_quit('')
1181
1182 logger.info("quit rwgt")
1183
1184
1185
1186
1187 try:
1188 self.results.def_current(self.run_name, self.run_tag)
1189 except Exception:
1190 pass
1191
1192
1194 """launch pgs"""
1195
1196 args = self.split_arg(line)
1197
1198 if '--no_default' in args:
1199 no_default = True
1200 args.remove('--no_default')
1201 else:
1202 no_default = False
1203
1204 if no_default and not os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')):
1205 logger.info('No pgs_card detected, so not run pgs')
1206 return
1207
1208
1209
1210
1211
1212
1213 lock = self.check_pgs(args, no_default=no_default)
1214
1215
1216 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')):
1217 files.cp(pjoin(self.me_dir, 'Cards', 'pgs_card_default.dat'),
1218 pjoin(self.me_dir, 'Cards', 'pgs_card.dat'))
1219 logger.info('No pgs card found. Take the default one.')
1220
1221 if not (no_default or self.force):
1222 self.ask_edit_cards(['pgs_card.dat'])
1223
1224 self.update_status('prepare PGS run', level=None)
1225
1226 pgsdir = pjoin(self.options['pythia-pgs_path'], 'src')
1227 eradir = self.options['exrootanalysis_path']
1228 madir = self.options['madanalysis_path']
1229 td = self.options['td_path']
1230
1231
1232 if not misc.is_executable(pjoin(pgsdir, 'pgs')):
1233 logger.info('No PGS executable -- running make')
1234 misc.compile(cwd=pgsdir)
1235
1236 self.update_status('Running PGS', level='pgs')
1237
1238 tag = self.run_tag
1239
1240 banner_path = pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, self.run_tag))
1241 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')):
1242 self.banner.add(pjoin(self.me_dir, 'Cards','pgs_card.dat'))
1243 self.banner.write(banner_path)
1244 else:
1245 open(banner_path, 'w').close()
1246
1247
1248
1249
1250 if lock:
1251 lock.wait()
1252
1253 ff = open(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'), 'w')
1254 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')):
1255 text = open(banner_path).read()
1256 text = '#%s' % text.replace('\n','\n#')
1257 dico = self.results[self.run_name].get_current_info()
1258 text +='\n## Integrated weight (pb) : %.4g' % dico['cross']
1259 text +='\n## Number of Event : %s\n' % dico['nb_event']
1260 ff.writelines(text)
1261 ff.close()
1262
1263 try:
1264 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done'))
1265 except Exception:
1266 pass
1267
1268 pgs_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_pgs.log" % tag)
1269 self.cluster.launch_and_wait('../bin/internal/run_pgs',
1270 argument=[pgsdir], cwd=pjoin(self.me_dir,'Events'),
1271 stdout=pgs_log, stderr=subprocess.STDOUT)
1272
1273 if not os.path.exists(pjoin(self.me_dir, 'Events', 'pgs.done')):
1274 logger.error('Fail to create LHCO events')
1275 return
1276 else:
1277 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done'))
1278
1279 if os.path.getsize(banner_path) == os.path.getsize(pjoin(self.me_dir, 'Events','pgs_events.lhco')):
1280 misc.call(['cat pgs_uncleaned_events.lhco >> pgs_events.lhco'],
1281 cwd=pjoin(self.me_dir, 'Events'))
1282 os.remove(pjoin(self.me_dir, 'Events', 'pgs_uncleaned_events.lhco '))
1283
1284
1285 if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHCOlympicsConverter')):
1286 self.update_status('Creating PGS Root File', level='pgs')
1287 try:
1288 misc.call([eradir+'/ExRootLHCOlympicsConverter',
1289 'pgs_events.lhco',pjoin('%s/%s_pgs_events.root' % (self.run_name, tag))],
1290 cwd=pjoin(self.me_dir, 'Events'))
1291 except Exception:
1292 logger.warning('fail to produce Root output [problem with ExRootAnalysis')
1293 if os.path.exists(pjoin(self.me_dir, 'Events', 'pgs_events.lhco')):
1294
1295 files.mv(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'),
1296 pjoin(self.me_dir, 'Events', self.run_name, '%s_pgs_events.lhco' % tag))
1297 self.create_plot('PGS')
1298 misc.gzip(pjoin(self.me_dir, 'Events', self.run_name, '%s_pgs_events.lhco' % tag))
1299
1300 self.update_status('finish', level='pgs', makehtml=False)
1301
1302
1304 """Require MG5 directory: Compute automatically the widths of a set
1305 of particles"""
1306
1307
1308
1309 args = self.split_arg(line)
1310 opts = self.check_compute_widths(args)
1311
1312 from madgraph.interface.master_interface import MasterCmd
1313 cmd = MasterCmd()
1314 self.define_child_cmd_interface(cmd, interface=False)
1315 cmd.exec_cmd('set automatic_html_opening False --no_save')
1316 if not opts['path']:
1317 opts['path'] = pjoin(self.me_dir, 'Cards', 'param_card.dat')
1318 if not opts['force'] :
1319 self.ask_edit_cards(['param_card'],[], plot=False)
1320
1321
1322 line = 'compute_widths %s %s' % \
1323 (' '.join([str(i) for i in opts['particles']]),
1324 ' '.join('--%s=%s' % (key,value) for (key,value) in opts.items()
1325 if key not in ['model', 'force', 'particles'] and value))
1326 cmd.exec_cmd(line, model=opts['model'])
1327 self.child = None
1328 del cmd
1329
1330
1332 """Not in help:Print the cross-section/ number of events for a given run"""
1333
1334 args = self.split_arg(line)
1335 options={'path':None, 'mode':'w', 'format':'full'}
1336 for arg in list(args):
1337 if arg.startswith('--') and '=' in arg:
1338 name,value=arg.split('=',1)
1339 name = name [2:]
1340 options[name] = value
1341 args.remove(arg)
1342
1343
1344 if len(args) > 0:
1345 run_name = args[0]
1346 else:
1347 for i, run_name in enumerate(self.results.order):
1348 for j, one_result in enumerate(self.results[run_name]):
1349 if i or j:
1350 options['mode'] = "a"
1351 if options['path']:
1352 self.print_results_in_file(one_result, options['path'], options['mode'], options['format'])
1353 else:
1354 self.print_results_in_shell(one_result)
1355 return
1356
1357 if run_name not in self.results:
1358 raise self.InvalidCmd('%s is not a valid run_name or it doesn\'t have any information' \
1359 % run_name)
1360
1361
1362 if len(args) == 2:
1363 tag = args[1]
1364 if tag.isdigit():
1365 tag = int(tag) - 1
1366 if len(self.results[run_name]) < tag:
1367 raise self.InvalidCmd('Only %s different tag available' % \
1368 len(self.results[run_name]))
1369 data = self.results[run_name][tag]
1370 else:
1371 data = self.results[run_name].return_tag(tag)
1372 else:
1373 data = self.results[run_name].return_tag(None)
1374
1375 if options['path']:
1376 self.print_results_in_file(data, options['path'], options['mode'], options['format'])
1377 else:
1378 self.print_results_in_shell(data)
1379
1380
1381
1383 """ run delphes and make associate root file/plot """
1384
1385 args = self.split_arg(line)
1386
1387 if '--no_default' in args:
1388 no_default = True
1389 args.remove('--no_default')
1390 else:
1391 no_default = False
1392
1393 if no_default and not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
1394 logger.info('No delphes_card detected, so not run Delphes')
1395 return
1396
1397
1398
1399
1400
1401
1402 lock = self.check_delphes(args)
1403 self.update_status('prepare delphes run', level=None)
1404
1405
1406 if os.path.exists(pjoin(self.options['delphes_path'], 'data')):
1407 delphes3 = False
1408 prog = '../bin/internal/run_delphes'
1409 else:
1410 delphes3 = True
1411 prog = '../bin/internal/run_delphes3'
1412
1413
1414
1415 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
1416 if no_default:
1417 logger.info('No delphes_card detected, so not run Delphes')
1418 return
1419
1420 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_card_default.dat'),
1421 pjoin(self.me_dir, 'Cards', 'delphes_card.dat'))
1422 logger.info('No delphes card found. Take the default one.')
1423 if not delphes3 and not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat')):
1424 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_trigger_default.dat'),
1425 pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat'))
1426 if not (no_default or self.force):
1427 if delphes3:
1428 self.ask_edit_cards(['delphes_card.dat'], args)
1429 else:
1430 self.ask_edit_cards(['delphes_card.dat', 'delphes_trigger.dat'], args)
1431
1432 self.update_status('Running Delphes', level=None)
1433
1434 if lock:
1435 lock.wait()
1436
1437
1438
1439 delphes_dir = self.options['delphes_path']
1440 tag = self.run_tag
1441 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')):
1442 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_card.dat'))
1443 if not delphes3:
1444 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_trigger.dat'))
1445 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, tag)))
1446
1447 cross = self.results[self.run_name].get_current_info()['cross']
1448
1449 delphes_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_delphes.log" % tag)
1450 self.cluster.launch_and_wait(prog,
1451 argument= [delphes_dir, self.run_name, tag, str(cross)],
1452 stdout=delphes_log, stderr=subprocess.STDOUT,
1453 cwd=pjoin(self.me_dir,'Events'))
1454
1455 if not os.path.exists(pjoin(self.me_dir, 'Events',
1456 self.run_name, '%s_delphes_events.lhco' % tag)):
1457 logger.error('Fail to create LHCO events from DELPHES')
1458 return
1459
1460 if os.path.exists(pjoin(self.me_dir,'Events','delphes.root')):
1461 source = pjoin(self.me_dir,'Events','delphes.root')
1462 target = pjoin(self.me_dir,'Events', self.run_name, "%s_delphes_events.root" % tag)
1463 files.mv(source, target)
1464
1465
1466 madir = self.options['madanalysis_path']
1467 td = self.options['td_path']
1468
1469
1470 self.create_plot('Delphes')
1471
1472 if os.path.exists(pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag)):
1473 misc.gzip(pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag))
1474
1475
1476
1477 self.update_status('delphes done', level='delphes', makehtml=False)
1478
1479
1481 """Find the pid of all particles in the final and initial states"""
1482 pids = set()
1483 subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses',
1484 'subproc.mg'))]
1485 nb_init = self.ninitial
1486 pat = re.compile(r'''DATA \(IDUP\(I,\d+\),I=1,\d+\)/([\+\-\d,\s]*)/''', re.I)
1487 for Pdir in subproc:
1488 text = open(pjoin(self.me_dir, 'SubProcesses', Pdir, 'born_leshouche.inc')).read()
1489 group = pat.findall(text)
1490 for particles in group:
1491 particles = particles.split(',')
1492 pids.update(set(particles))
1493
1494 return pids
1495
1496
1521
1522
1523 if hasattr(self, 'pdffile') and self.pdffile:
1524 return self.pdffile
1525 else:
1526 for line in open(pjoin(self.me_dir,'Source','PDF','pdf_list.txt')):
1527 data = line.split()
1528 if len(data) < 4:
1529 continue
1530 if data[1].lower() == self.run_card['pdlabel'].lower():
1531 self.pdffile = check_cluster(pjoin(self.me_dir, 'lib', 'Pdfdata', data[2]))
1532 return self.pdffile
1533 else:
1534
1535 path = pjoin(self.me_dir, 'lib', 'PDFsets')
1536 if os.path.exists(path):
1537 self.pdffile = path
1538 else:
1539 self.pdffile = " "
1540 return self.pdffile
1541
1542
1552
1553
1554 - def do_set(self, line, log=True):
1555 """Set an option, which will be default for coming generations/outputs
1556 """
1557
1558
1559
1560 args = self.split_arg(line)
1561
1562 self.check_set(args)
1563
1564 if args[0] in self.options_configuration and '--no_save' not in args:
1565 self.do_save('options --auto')
1566
1567 if args[0] == "stdout_level":
1568 if args[1].isdigit():
1569 logging.root.setLevel(int(args[1]))
1570 logging.getLogger('madgraph').setLevel(int(args[1]))
1571 else:
1572 logging.root.setLevel(eval('logging.' + args[1]))
1573 logging.getLogger('madgraph').setLevel(eval('logging.' + args[1]))
1574 if log: logger.info('set output information to level: %s' % args[1])
1575 elif args[0] == "fortran_compiler":
1576 if args[1] == 'None':
1577 args[1] = None
1578 self.options['fortran_compiler'] = args[1]
1579 current = misc.detect_current_compiler(pjoin(self.me_dir,'Source','make_opts'), 'fortran')
1580 if current != args[1] and args[1] != None:
1581 misc.mod_compilator(self.me_dir, args[1], current, 'gfortran')
1582 elif args[0] == "cpp_compiler":
1583 if args[1] == 'None':
1584 args[1] = None
1585 self.options['cpp_compiler'] = args[1]
1586 current = misc.detect_current_compiler(pjoin(self.me_dir,'Source','make_opts'), 'cpp')
1587 if current != args[1] and args[1] != None:
1588 misc.mod_compilator(self.me_dir, args[1], current, 'cpp')
1589 elif args[0] == "run_mode":
1590 if not args[1] in [0,1,2,'0','1','2']:
1591 raise self.InvalidCmd, 'run_mode should be 0, 1 or 2.'
1592 self.cluster_mode = int(args[1])
1593 self.options['run_mode'] = self.cluster_mode
1594 elif args[0] in ['cluster_type', 'cluster_queue', 'cluster_temp_path']:
1595 if args[1] == 'None':
1596 args[1] = None
1597 self.options[args[0]] = args[1]
1598
1599
1600 elif args[0] in ['cluster_nb_retry', 'cluster_retry_wait', 'cluster_size']:
1601 self.options[args[0]] = int(args[1])
1602
1603 elif args[0] == 'nb_core':
1604 if args[1] == 'None':
1605 import multiprocessing
1606 self.nb_core = multiprocessing.cpu_count()
1607 self.options['nb_core'] = self.nb_core
1608 return
1609 if not args[1].isdigit():
1610 raise self.InvalidCmd('nb_core should be a positive number')
1611 self.nb_core = int(args[1])
1612 self.options['nb_core'] = self.nb_core
1613 elif args[0] == 'timeout':
1614 self.options[args[0]] = int(args[1])
1615 elif args[0] == 'cluster_status_update':
1616 if '(' in args[1]:
1617 data = ' '.join([a for a in args[1:] if not a.startswith('-')])
1618 data = data.replace('(','').replace(')','').replace(',',' ').split()
1619 first, second = data[:2]
1620 else:
1621 first, second = args[1:3]
1622
1623 self.options[args[0]] = (int(first), int(second))
1624 elif args[0] == 'notification_center':
1625 if args[1] in ['None','True','False']:
1626 self.allow_notification_center = eval(args[1])
1627 self.options[args[0]] = eval(args[1])
1628 else:
1629 raise self.InvalidCmd('Not a valid value for notification_center')
1630 elif args[0] in self.options:
1631 if args[1] in ['None','True','False']:
1632 self.options[args[0]] = eval(args[1])
1633 elif args[0].endswith('path'):
1634 if os.path.exists(args[1]):
1635 self.options[args[0]] = args[1]
1636 elif os.path.exists(pjoin(self.me_dir, args[1])):
1637 self.options[args[0]] = pjoin(self.me_dir, args[1])
1638 else:
1639 raise self.InvalidCmd('Not a valid path: keep previous value: \'%s\'' % self.options[args[0]])
1640 else:
1641 self.options[args[0]] = args[1]
1642
1643 - def post_set(self, stop, line):
1644 """Check if we need to save this in the option file"""
1645 try:
1646 args = self.split_arg(line)
1647 if 'cluster' in args[0] or args[0] == 'run_mode':
1648 self.configure_run_mode(self.options['run_mode'])
1649
1650
1651
1652 self.check_set(args)
1653
1654 if args[0] in self.options_configuration and '--no_save' not in args:
1655 self.exec_cmd('save options --auto')
1656 elif args[0] in self.options_madevent:
1657 logger.info('This option will be the default in any output that you are going to create in this session.')
1658 logger.info('In order to keep this changes permanent please run \'save options\'')
1659 return stop
1660 except self.InvalidCmd:
1661 return stop
1662
1689
1690
1692 """
1693 1) Check that no scan parameter are present
1694 2) Check that all the width are define in the param_card.
1695 - If a scan parameter is define. create the iterator and recall this fonction
1696 on the first element.
1697 - If some width are set on 'Auto', call the computation tools."""
1698
1699 pattern_scan = re.compile(r'''^(decay)?[\s\d]*scan''', re.I+re.M)
1700 pattern_width = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto(@NLO|)''',re.I)
1701 text = open(path).read()
1702
1703 if pattern_scan.search(text):
1704 if not isinstance(self, cmd.CmdShell):
1705
1706 raise Exception, "Scan are not allowed in web mode"
1707
1708 main_card = check_param_card.ParamCardIterator(text)
1709 self.param_card_iterator = main_card
1710 first_card = main_card.next(autostart=True)
1711 first_card.write(path)
1712 return self.check_param_card(path, run)
1713
1714 pdg_info = pattern_width.findall(text)
1715 if pdg_info:
1716 if run:
1717 logger.info('Computing the width set on auto in the param_card.dat')
1718 has_nlo = any(nlo.lower()=="@nlo" for _,nlo in pdg_info)
1719 pdg = [pdg for pdg,nlo in pdg_info]
1720 if not has_nlo:
1721 self.do_compute_widths('%s %s' % (' '.join(pdg), path))
1722 else:
1723 self.do_compute_widths('%s %s --nlo' % (' '.join(pdg), path))
1724 else:
1725 logger.info('''Some width are on Auto in the card.
1726 Those will be computed as soon as you have finish the edition of the cards.
1727 If you want to force the computation right now and being able to re-edit
1728 the cards afterwards, you can type \"compute_wdiths\".''')
1729
1730
1732 """If a ME run is currently running add a link in the html output"""
1733
1734
1735
1736 if hasattr(self, 'results') and hasattr(self.results, 'current') and\
1737 self.results.current and 'run_name' in self.results.current and \
1738 hasattr(self, 'me_dir'):
1739 name = self.results.current['run_name']
1740 tag = self.results.current['tag']
1741 self.debug_output = pjoin(self.me_dir, '%s_%s_debug.log' % (name,tag))
1742 if errortype:
1743 self.results.current.debug = errortype
1744 else:
1745 self.results.current.debug = self.debug_output
1746
1747 else:
1748
1749 self.debug_output = CommonRunCmd.debug_output
1750 if os.path.exists('ME5_debug') and not 'ME5_debug' in self.debug_output:
1751 os.remove('ME5_debug')
1752 if not 'ME5_debug' in self.debug_output:
1753 os.system('ln -s %s ME5_debug &> /dev/null' % self.debug_output)
1754
1755
1757 """Not in help: exit """
1758
1759 if not self.force_run:
1760 try:
1761 os.remove(pjoin(self.me_dir,'RunWeb'))
1762 except Exception:
1763 pass
1764 try:
1765 self.store_result()
1766 except Exception:
1767
1768 pass
1769
1770 try:
1771 self.update_status('', level=None)
1772 except Exception, error:
1773 pass
1774 devnull = open(os.devnull, 'w')
1775 try:
1776 misc.call(['./bin/internal/gen_cardhtml-pl'], cwd=self.me_dir,
1777 stdout=devnull, stderr=devnull)
1778 except Exception:
1779 pass
1780 devnull.close()
1781
1782 return super(CommonRunCmd, self).do_quit(line)
1783
1784
1785 do_EOF = do_quit
1786 do_exit = do_quit
1787
1788
1789 - def update_status(self, status, level, makehtml=True, force=True,
1790 error=False, starttime = None, update_results=True,
1791 print_log=True):
1792 """ update the index status """
1793
1794 if makehtml and not force:
1795 if hasattr(self, 'next_update') and time.time() < self.next_update:
1796 return
1797 else:
1798 self.next_update = time.time() + 3
1799
1800 if print_log:
1801 if isinstance(status, str):
1802 if '<br>' not in status:
1803 logger.info(status)
1804 elif starttime:
1805 running_time = misc.format_timer(time.time()-starttime)
1806 logger.info(' Idle: %s, Running: %s, Completed: %s [ %s ]' % \
1807 (status[0], status[1], status[2], running_time))
1808 else:
1809 logger.info(' Idle: %s, Running: %s, Completed: %s' % status[:3])
1810
1811 if update_results:
1812 self.results.update(status, level, makehtml=makehtml, error=error)
1813
1814
1816 """Ask the question when launching generate_events/multi_run"""
1817
1818 check_card = ['pythia_card.dat', 'pgs_card.dat','delphes_card.dat',
1819 'delphes_trigger.dat', 'madspin_card.dat', 'shower_card.dat',
1820 'reweight_card.dat']
1821
1822 cards_path = pjoin(self.me_dir,'Cards')
1823 for card in check_card:
1824 if card in ignore or (ignore == ['*'] and card not in need_card):
1825 continue
1826 if card not in need_card:
1827 if os.path.exists(pjoin(cards_path, card)):
1828 files.mv(pjoin(cards_path, card), pjoin(cards_path, '.%s' % card))
1829 else:
1830 if not os.path.exists(pjoin(cards_path, card)):
1831 if os.path.exists(pjoin(cards_path, '.%s' % card)):
1832 files.mv(pjoin(cards_path, '.%s' % card), pjoin(cards_path, card))
1833 else:
1834 default = card.replace('.dat', '_default.dat')
1835 files.cp(pjoin(cards_path, default),pjoin(cards_path, card))
1836
1837
1838 - def set_configuration(self, config_path=None, final=True, initdir=None, amcatnlo=False):
1839 """ assign all configuration variable from file
1840 ./Cards/mg5_configuration.txt. assign to default if not define """
1841
1842 if not hasattr(self, 'options') or not self.options:
1843 self.options = dict(self.options_configuration)
1844 self.options.update(self.options_madgraph)
1845 self.options.update(self.options_madevent)
1846
1847 if not config_path:
1848 if os.environ.has_key('MADGRAPH_BASE'):
1849 config_path = pjoin(os.environ['MADGRAPH_BASE'],'mg5_configuration.txt')
1850 self.set_configuration(config_path=config_path, final=False)
1851 if 'HOME' in os.environ:
1852 config_path = pjoin(os.environ['HOME'],'.mg5',
1853 'mg5_configuration.txt')
1854 if os.path.exists(config_path):
1855 self.set_configuration(config_path=config_path, final=False)
1856 if amcatnlo:
1857 me5_config = pjoin(self.me_dir, 'Cards', 'amcatnlo_configuration.txt')
1858 else:
1859 me5_config = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
1860 self.set_configuration(config_path=me5_config, final=False, initdir=self.me_dir)
1861
1862 if self.options.has_key('mg5_path') and self.options['mg5_path']:
1863 MG5DIR = self.options['mg5_path']
1864 config_file = pjoin(MG5DIR, 'input', 'mg5_configuration.txt')
1865 self.set_configuration(config_path=config_file, final=False,initdir=MG5DIR)
1866 else:
1867 self.options['mg5_path'] = None
1868 return self.set_configuration(config_path=me5_config, final=final,initdir=self.me_dir)
1869
1870 config_file = open(config_path)
1871
1872
1873 logger.info('load configuration from %s ' % config_file.name)
1874 for line in config_file:
1875
1876 if '#' in line:
1877 line = line.split('#',1)[0]
1878 line = line.replace('\n','').replace('\r\n','')
1879 try:
1880 name, value = line.split('=')
1881 except ValueError:
1882 pass
1883 else:
1884 name = name.strip()
1885 value = value.strip()
1886 if name.endswith('_path') and not name.startswith('cluster'):
1887 path = value
1888 if os.path.isdir(path):
1889 self.options[name] = os.path.realpath(path)
1890 continue
1891 if not initdir:
1892 continue
1893 path = pjoin(initdir, value)
1894 if os.path.isdir(path):
1895 self.options[name] = os.path.realpath(path)
1896 continue
1897 else:
1898 self.options[name] = value
1899 if value.lower() == "none":
1900 self.options[name] = None
1901
1902 if not final:
1903 return self.options
1904
1905
1906
1907 for key in self.options:
1908
1909 if key.endswith('path') and not key.startswith("cluster"):
1910 path = self.options[key]
1911 if path is None:
1912 continue
1913 if os.path.isdir(path):
1914 self.options[key] = os.path.realpath(path)
1915 continue
1916 path = pjoin(self.me_dir, self.options[key])
1917 if os.path.isdir(path):
1918 self.options[key] = os.path.realpath(path)
1919 continue
1920 elif self.options.has_key('mg5_path') and self.options['mg5_path']:
1921 path = pjoin(self.options['mg5_path'], self.options[key])
1922 if os.path.isdir(path):
1923 self.options[key] = os.path.realpath(path)
1924 continue
1925 self.options[key] = None
1926 elif key.startswith('cluster') and key != 'cluster_status_update':
1927 if key in ('cluster_nb_retry','cluster_wait_retry'):
1928 self.options[key] = int(self.options[key])
1929 if hasattr(self,'cluster'):
1930 del self.cluster
1931 pass
1932 elif key == 'automatic_html_opening':
1933 if self.options[key] in ['False', 'True']:
1934 self.options[key] =eval(self.options[key])
1935 elif key == "notification_center":
1936 if self.options[key] in ['False', 'True']:
1937 self.allow_notification_center =eval(self.options[key])
1938 self.options[key] =eval(self.options[key])
1939 elif key not in ['text_editor','eps_viewer','web_browser','stdout_level',
1940 'complex_mass_scheme', 'gauge', 'group_subprocesses']:
1941
1942 try:
1943 self.do_set("%s %s --no_save" % (key, self.options[key]), log=False)
1944 except self.InvalidCmd:
1945 logger.warning("Option %s from config file not understood" \
1946 % key)
1947
1948
1949 misc.open_file.configure(self.options)
1950 self.configure_run_mode(self.options['run_mode'])
1951 return self.options
1952
1953 @staticmethod
1955 """ find a valid run_name for the current job """
1956
1957 name = 'run_%02d'
1958 data = [int(s[4:j]) for s in os.listdir(pjoin(me_dir,'Events')) for
1959 j in range(4,len(s)+1) if \
1960 s.startswith('run_') and s[4:j].isdigit()]
1961 return name % (max(data+[0])+1)
1962
1963
1964
1966 """Require MG5 directory: decay events with spin correlations
1967 """
1968
1969 if '-from_cards' in line and not os.path.exists(pjoin(self.me_dir, 'Cards', 'madspin_card.dat')):
1970 return
1971
1972
1973
1974
1975 if MADEVENT and not self.options['mg5_path']:
1976 raise self.InvalidCmd, '''The module decay_events requires that MG5 is installed on the system.
1977 You can install it and set its path in ./Cards/me5_configuration.txt'''
1978 elif MADEVENT:
1979 sys.path.append(self.options['mg5_path'])
1980 try:
1981 import MadSpin.decay as decay
1982 import MadSpin.interface_madspin as interface_madspin
1983 except ImportError:
1984 if __debug__:
1985 raise
1986 else:
1987 raise self.ConfigurationError, '''Can\'t load MadSpin
1988 The variable mg5_path might not be correctly configured.'''
1989
1990 self.update_status('Running MadSpin', level='madspin')
1991 if not '-from_cards' in line:
1992 self.keep_cards(['madspin_card.dat'], ignore=['*'])
1993 self.ask_edit_cards(['madspin_card.dat'], 'fixed', plot=False)
1994 self.help_decay_events(skip_syntax=True)
1995
1996
1997 args = self.split_arg(line)
1998 self.check_decay_events(args)
1999
2000 madspin_cmd = interface_madspin.MadSpinInterface(args[0])
2001 madspin_cmd.update_status = lambda *x,**opt: self.update_status(*x, level='madspin',**opt)
2002
2003 path = pjoin(self.me_dir, 'Cards', 'madspin_card.dat')
2004
2005 madspin_cmd.import_command_file(path)
2006
2007
2008 i = 1
2009 while os.path.exists(pjoin(self.me_dir,'Events', '%s_decayed_%i' % (self.run_name,i))):
2010 i+=1
2011 new_run = '%s_decayed_%i' % (self.run_name,i)
2012 evt_dir = pjoin(self.me_dir, 'Events')
2013
2014 os.mkdir(pjoin(evt_dir, new_run))
2015 current_file = args[0].replace('.lhe', '_decayed.lhe')
2016 new_file = pjoin(evt_dir, new_run, os.path.basename(args[0]))
2017 if not os.path.exists(current_file):
2018 if os.path.exists(current_file+'.gz'):
2019 current_file += '.gz'
2020 new_file += '.gz'
2021 else:
2022 logger.error('MadSpin fails to create any decayed file.')
2023 return
2024
2025 files.mv(current_file, new_file)
2026 logger.info("The decayed event file has been moved to the following location: ")
2027 logger.info(new_file)
2028
2029 if hasattr(self, 'results'):
2030 current = self.results.current
2031 nb_event = self.results.current['nb_event']
2032 if not nb_event:
2033 current = self.results[self.run_name][0]
2034 nb_event = current['nb_event']
2035
2036 cross = current['cross']
2037 error = current['error']
2038 self.results.add_run( new_run, self.run_card)
2039 self.results.add_detail('nb_event', nb_event)
2040 self.results.add_detail('cross', cross * madspin_cmd.branching_ratio)
2041 self.results.add_detail('error', error * madspin_cmd.branching_ratio + cross * madspin_cmd.err_branching_ratio)
2042 self.results.add_detail('run_mode', current['run_mode'])
2043
2044 self.run_name = new_run
2045 self.banner = madspin_cmd.banner
2046 self.banner.add(path)
2047 self.banner.write(pjoin(self.me_dir,'Events',self.run_name, '%s_%s_banner.txt' %
2048 (self.run_name, self.run_tag)))
2049 self.update_status('MadSpin Done', level='parton', makehtml=False)
2050 if 'unweighted' in os.path.basename(args[0]):
2051 self.create_plot('parton')
2052
2059
2061 "Complete the print results command"
2062 args = self.split_arg(line[0:begidx], error=False)
2063 if len(args) == 1:
2064
2065 data = misc.glob(pjoin('*','unweighted_events.lhe.gz'),
2066 pjoin(self.me_dir, 'Events'))
2067
2068 data = [n.rsplit('/',2)[1] for n in data]
2069 tmp1 = self.list_completion(text, data)
2070 return tmp1
2071 else:
2072 data = misc.glob('*_pythia_events.hep.gz', pjoin(self.me_dir, 'Events', args[0]))
2073 data = [os.path.basename(p).rsplit('_',1)[0] for p in data]
2074 data += ["--mode=a", "--mode=w", "--path=", "--format=short"]
2075 tmp1 = self.list_completion(text, data)
2076 return tmp1
2077
2079 logger.info("syntax: print_result [RUN] [TAG] [options]")
2080 logger.info("-- show in text format the status of the run (cross-section/nb-event/...)")
2081 logger.info("--path= defines the path of the output file.")
2082 logger.info("--mode=a allow to add the information at the end of the file.")
2083 logger.info("--format=short (only if --path is define)")
2084 logger.info(" allows to have a multi-column output easy to parse")
2085
2086
2112
2113
2115 args = self.split_arg(line[0:begidx], error=False)
2116
2117 if len(args) == 1 and os.path.sep not in text:
2118
2119 data = misc.glob(pjoin('*','*events.lhe*'), pjoin(self.me_dir, 'Events'))
2120 data = [n.rsplit('/',2)[1] for n in data]
2121 return self.list_completion(text, data, line)
2122 else:
2123 return self.path_completion(text,
2124 os.path.join('.',*[a for a in args \
2125 if a.endswith(os.path.sep)]))
2126
2138
2139
2140
2142 "Complete the compute_widths command"
2143
2144 args = self.split_arg(line[0:begidx])
2145
2146 if args[-1] in ['--path=', '--output=']:
2147 completion = {'path': self.path_completion(text)}
2148 elif line[begidx-1] == os.path.sep:
2149 current_dir = pjoin(*[a for a in args if a.endswith(os.path.sep)])
2150 if current_dir.startswith('--path='):
2151 current_dir = current_dir[7:]
2152 if current_dir.startswith('--output='):
2153 current_dir = current_dir[9:]
2154 completion = {'path': self.path_completion(text, current_dir)}
2155 else:
2156 completion = {}
2157 completion['options'] = self.list_completion(text,
2158 ['--path=', '--output=', '--min_br=0.\$', '--nlo',
2159 '--precision_channel=0.\$', '--body_decay='])
2160
2161 return self.deal_multiple_categories(completion)
2162
2163
2165 """update the make_opts file writing the environmental variables
2166 stored in make_opts_var"""
2167 make_opts = os.path.join(self.me_dir, 'Source', 'make_opts')
2168
2169 return self.update_make_opts_full(make_opts, self.make_opts_var)
2170
2171
2172 @staticmethod
2174 """update the make_opts file writing the environmental variables
2175 of def_variables.
2176 if a value of the dictionary is None then it is not written.
2177 """
2178 make_opts = path
2179 pattern = re.compile(r'^(\w+)\s*=\s*(.*)$',re.DOTALL)
2180 diff = False
2181
2182
2183 tag = '#end_of_make_opts_variables\n'
2184 make_opts_variable = True
2185 content = []
2186 variables = dict(def_variables)
2187 need_keys = variables.keys()
2188 for line in open(make_opts):
2189 line = line.strip()
2190 if make_opts_variable:
2191 if line.startswith('#') or not line:
2192 if line.startswith('#end_of_make_opts_variables'):
2193 make_opts_variable = False
2194 continue
2195 elif pattern.search(line):
2196 key, value = pattern.search(line).groups()
2197 if key not in variables:
2198 variables[key] = value
2199 elif value != variables[key]:
2200 diff=True
2201 else:
2202 need_keys.remove(key)
2203 else:
2204 misc.sprint("end on line", line)
2205 make_opts_variable = False
2206 content.append(line)
2207 else:
2208 content.append(line)
2209
2210 if need_keys:
2211 diff=True
2212
2213 content_variables = '\n'.join('%s=%s' % (k,v) for k, v in variables.items() if v is not None)
2214 content_variables += '\n%s' % tag
2215
2216 if diff:
2217 open(make_opts, 'w').write(content_variables + '\n'.join(content))
2218 return
2219
2220
2221
2223 """links lhapdf into libdir"""
2224
2225 lhapdf_version = self.get_lhapdf_version()
2226 logger.info('Using LHAPDF v%s interface for PDFs' % lhapdf_version)
2227 lhalibdir = subprocess.Popen([self.options['lhapdf'], '--libdir'],
2228 stdout = subprocess.PIPE).stdout.read().strip()
2229
2230 if lhapdf_version.startswith('5.'):
2231 pdfsetsdir = subprocess.Popen([self.options['lhapdf'], '--pdfsets-path'],
2232 stdout = subprocess.PIPE).stdout.read().strip()
2233 else:
2234 pdfsetsdir = subprocess.Popen([self.options['lhapdf'], '--datadir'],
2235 stdout = subprocess.PIPE).stdout.read().strip()
2236
2237 self.lhapdf_pdfsets = self.get_lhapdf_pdfsets_list(pdfsetsdir)
2238
2239 lhalib = 'libLHAPDF.a'
2240
2241 if os.path.exists(pjoin(libdir, lhalib)):
2242 files.rm(pjoin(libdir, lhalib))
2243 files.ln(pjoin(lhalibdir, lhalib), libdir)
2244
2245 if not os.path.isdir(pjoin(libdir, 'PDFsets')):
2246 os.mkdir(pjoin(libdir, 'PDFsets'))
2247 self.make_opts_var['lhapdf'] = self.options['lhapdf']
2248 self.make_opts_var['lhapdfversion'] = lhapdf_version[0]
2249 self.make_opts_var['lhapdf_config'] = self.options['lhapdf']
2250
2251
2253 """reads the proc_characteristics file and initialises the correspondant
2254 dictionary"""
2255
2256 if not path:
2257 path = os.path.join(self.me_dir, 'SubProcesses', 'proc_characteristics')
2258
2259 self.proc_characteristics = banner_mod.ProcCharacteristic(path)
2260 return self.proc_characteristics
2261
2262
2264 """copy (if needed) the lhapdf set corresponding to the lhaid in lhaid_list
2265 into lib/PDFsets"""
2266
2267 if not hasattr(self, 'lhapdf_pdfsets'):
2268 self.lhapdf_pdfsets = self.get_lhapdf_pdfsets_list(pdfsets_dir)
2269
2270 pdfsetname=set()
2271 for lhaid in lhaid_list:
2272 if isinstance(lhaid, (int,float)):
2273 try:
2274 if lhaid in self.lhapdf_pdfsets:
2275 pdfsetname.add(self.lhapdf_pdfsets[lhaid]['filename'])
2276 else:
2277 raise MadGraph5Error('lhaid %s not valid input number for the current lhapdf' % lhaid )
2278 except KeyError:
2279 if self.lhapdf_version.startswith('5'):
2280 raise MadGraph5Error(\
2281 ('invalid lhaid set in th run_card: %d .\nPlease note that some sets' % lhaid) + \
2282 '(eg MSTW 90%CL error sets) \nare not available in aMC@NLO + LHAPDF 5.x.x')
2283 else:
2284 logger.debug('%d not found in pdfsets.index' % lhaid)
2285 else:
2286 pdfsetname.add(lhaid)
2287
2288
2289
2290
2291 if not os.path.isdir(pdfsets_dir):
2292 try:
2293 os.mkdir(pdfsets_dir)
2294 except OSError:
2295 pdfsets_dir = pjoin(self.me_dir, 'lib', 'PDFsets')
2296 elif os.path.exists(pjoin(self.me_dir, 'lib', 'PDFsets')):
2297
2298 for name in os.listdir(pjoin(self.me_dir, 'lib', 'PDFsets')):
2299 if name not in pdfsetname:
2300 try:
2301 if os.path.isdir(pjoin(self.me_dir, 'lib', 'PDFsets', name)):
2302 shutil.rmtree(pjoin(self.me_dir, 'lib', 'PDFsets', name))
2303 else:
2304 os.remove(pjoin(self.me_dir, 'lib', 'PDFsets', name))
2305 except Exception, error:
2306 logger.debug('%s', error)
2307
2308 if self.options["cluster_local_path"]:
2309 lhapdf_cluster_possibilities = [self.options["cluster_local_path"],
2310 pjoin(self.options["cluster_local_path"], "lhapdf"),
2311 pjoin(self.options["cluster_local_path"], "lhapdf", "pdfsets"),
2312 pjoin(self.options["cluster_local_path"], "..", "lhapdf"),
2313 pjoin(self.options["cluster_local_path"], "..", "lhapdf", "pdfsets"),
2314 pjoin(self.options["cluster_local_path"], "..", "lhapdf","pdfsets", "6.1")
2315 ]
2316 else:
2317 lhapdf_cluster_possibilities = []
2318
2319 for pdfset in pdfsetname:
2320
2321 if self.options["cluster_local_path"] and self.options["run_mode"] == 1 and \
2322 any((os.path.exists(pjoin(d, pdfset)) for d in lhapdf_cluster_possibilities)):
2323
2324 os.environ["LHAPATH"] = [d for d in lhapdf_cluster_possibilities if os.path.exists(pjoin(d, pdfset))][0]
2325 os.environ["CLUSTER_LHAPATH"] = os.environ["LHAPATH"]
2326
2327 if os.path.exists(pjoin(pdfsets_dir, pdfset)):
2328 try:
2329 if os.path.isdir(pjoin(pdfsets_dir, name)):
2330 shutil.rmtree(pjoin(pdfsets_dir, name))
2331 else:
2332 os.remove(pjoin(pdfsets_dir, name))
2333 except Exception, error:
2334 logger.debug('%s', error)
2335
2336
2337 elif not os.path.exists(pjoin(self.me_dir, 'lib', 'PDFsets', pdfset)) and \
2338 not os.path.isdir(pjoin(self.me_dir, 'lib', 'PDFsets', pdfset)):
2339
2340 if pdfset and not os.path.exists(pjoin(pdfsets_dir, pdfset)):
2341 self.install_lhapdf_pdfset(pdfsets_dir, pdfset)
2342
2343 if os.path.exists(pjoin(pdfsets_dir, pdfset)):
2344 files.cp(pjoin(pdfsets_dir, pdfset), pjoin(self.me_dir, 'lib', 'PDFsets'))
2345 elif os.path.exists(pjoin(os.path.dirname(pdfsets_dir), pdfset)):
2346 files.cp(pjoin(os.path.dirname(pdfsets_dir), pdfset), pjoin(self.me_dir, 'lib', 'PDFsets'))
2347
2349 """idownloads and install the pdfset filename in the pdfsets_dir"""
2350 lhapdf_version = self.get_lhapdf_version()
2351 local_path = pjoin(self.me_dir, 'lib', 'PDFsets')
2352 return self.install_lhapdf_pdfset_static(self.options['lhapdf'],
2353 pdfsets_dir, filename,
2354 lhapdf_version=lhapdf_version,
2355 alternate_path=local_path)
2356
2357
2358 @staticmethod
2361 """idownloads and install the pdfset filename in the pdfsets_dir.
2362 Version which can be used independently of the class.
2363 local path is used if the global installation fails.
2364 """
2365
2366 if not lhapdf_version:
2367 lhapdf_version = subprocess.Popen([lhapdf_config, '--version'],
2368 stdout = subprocess.PIPE).stdout.read().strip()
2369 if not pdfsets_dir:
2370 pdfsets_dir = subprocess.Popen([lhapdf_config, '--datadir'],
2371 stdout = subprocess.PIPE).stdout.read().strip()
2372
2373 if isinstance(filename, int):
2374 pdf_info = CommonRunCmd.get_lhapdf_pdfsets_list_static(pdfsets_dir, lhapdf_version)
2375 filename = pdf_info[filename]['filename']
2376
2377 if os.path.exists(pjoin(pdfsets_dir, filename)):
2378 logger.debug('%s is already present in %s', (filename, pdfsets_dir))
2379 return
2380
2381 logger.info('Trying to download %s' % filename)
2382
2383 if lhapdf_version.startswith('5.'):
2384
2385
2386
2387 getdata = lhapdf_config.replace('lhapdf-config', ('lhapdf-getdata'))
2388 misc.call([getdata, filename], cwd = pdfsets_dir)
2389
2390 elif lhapdf_version.startswith('6.'):
2391
2392
2393 getdata = lhapdf_config.replace('lhapdf-config', ('lhapdf'))
2394
2395 misc.call([getdata, 'install', filename], cwd = pdfsets_dir)
2396
2397 else:
2398 raise MadGraph5Error('Not valid LHAPDF version: %s' % lhapdf_version)
2399
2400
2401 if os.path.exists(pjoin(pdfsets_dir, filename)) or \
2402 os.path.isdir(pjoin(pdfsets_dir, filename)):
2403 logger.info('%s successfully downloaded and stored in %s' \
2404 % (filename, pdfsets_dir))
2405
2406 elif lhapdf_version.startswith('5.'):
2407 logger.warning('Could not download %s into %s. Trying to save it locally' \
2408 % (filename, pdfsets_dir))
2409 CommonRunCmd.install_lhapdf_pdfset_static(lhapdf_config, alternate_path, filename,
2410 lhapdf_version=lhapdf_version)
2411 elif lhapdf_version.startswith('6.') and '.LHgrid' in filename:
2412 logger.info('Could not download %s: Try %s', filename, filename.replace('.LHgrid',''))
2413 return CommonRunCmd.install_lhapdf_pdfset_static(lhapdf_config, pdfsets_dir,
2414 filename.replace('.LHgrid',''),
2415 lhapdf_version, alternate_path)
2416
2417 else:
2418 raise MadGraph5Error, \
2419 'Could not download %s into %s. Please try to install it manually.' \
2420 % (filename, pdfsets_dir)
2421
2422
2423
2425 """read the PDFsets.index file, which should be located in the same
2426 place as pdfsets_dir, and return a list of dictionaries with the information
2427 about each pdf set"""
2428 lhapdf_version = self.get_lhapdf_version()
2429 return self.get_lhapdf_pdfsets_list_static(pdfsets_dir, lhapdf_version)
2430
2431 @staticmethod
2433
2434 if lhapdf_version.startswith('5.'):
2435 if os.path.exists('%s.index' % pdfsets_dir):
2436 indexfile = '%s.index' % pdfsets_dir
2437 else:
2438 raise MadGraph5Error, 'index of lhapdf file not found'
2439 pdfsets_lines = \
2440 [l for l in open(indexfile).read().split('\n') if l.strip() and \
2441 not '90cl' in l]
2442 lhapdf_pdfsets = dict( (int(l.split()[0]), {'lhaid': int(l.split()[0]),
2443 'pdflib_ntype': int(l.split()[1]),
2444 'pdflib_ngroup': int(l.split()[2]),
2445 'pdflib_nset': int(l.split()[3]),
2446 'filename': l.split()[4],
2447 'lhapdf_nmem': int(l.split()[5]),
2448 'q2min': float(l.split()[6]),
2449 'q2max': float(l.split()[7]),
2450 'xmin': float(l.split()[8]),
2451 'xmax': float(l.split()[9]),
2452 'description': l.split()[10]}) \
2453 for l in pdfsets_lines)
2454
2455 elif lhapdf_version.startswith('6.'):
2456 pdfsets_lines = \
2457 [l for l in open(pjoin(pdfsets_dir, 'pdfsets.index')).read().split('\n') if l.strip()]
2458 lhapdf_pdfsets = dict( (int(l.split()[0]),
2459 {'lhaid': int(l.split()[0]),
2460 'filename': l.split()[1]}) \
2461 for l in pdfsets_lines)
2462
2463 else:
2464 raise MadGraph5Error('Not valid LHAPDF version: %s' % lhapdf_version)
2465
2466 return lhapdf_pdfsets
2467
2468
2470 """returns the lhapdf version number"""
2471 if not hasattr(self, 'lhapdfversion'):
2472 try:
2473 self.lhapdf_version = \
2474 subprocess.Popen([self.options['lhapdf'], '--version'],
2475 stdout = subprocess.PIPE).stdout.read().strip()
2476 except OSError, error:
2477 if error.errno == 2:
2478 raise Exception, 'lhapdf executable (%s) is not found on your system. Please install it and/or indicate the path to the correct executable in input/mg5_configuration.txt' % self.options['lhapdf']
2479 else:
2480 raise
2481
2482
2483 if self.lhapdf_version.startswith('6.0'):
2484 raise MadGraph5Error('LHAPDF 6.0.x not supported. Please use v6.1 or later')
2485
2486 return self.lhapdf_version
2487
2488
2490 lhapdf_version = self.get_lhapdf_version()
2491
2492
2493 if 'LHAPDF_DATA_PATH' in os.environ.keys() and os.environ['LHAPDF_DATA_PATH']:
2494 datadir = os.environ['LHAPDF_DATA_PATH']
2495
2496 elif lhapdf_version.startswith('5.'):
2497 datadir = subprocess.Popen([self.options['lhapdf'], '--pdfsets-path'],
2498 stdout = subprocess.PIPE).stdout.read().strip()
2499
2500 elif lhapdf_version.startswith('6.'):
2501 datadir = subprocess.Popen([self.options['lhapdf'], '--datadir'],
2502 stdout = subprocess.PIPE).stdout.read().strip()
2503
2504 return datadir
2505
2507 lhapdf_version = self.get_lhapdf_version()
2508
2509 if lhapdf_version.startswith('5.'):
2510 libdir = subprocess.Popen([self.options['lhapdf-config'], '--libdir'],
2511 stdout = subprocess.PIPE).stdout.read().strip()
2512
2513 elif lhapdf_version.startswith('6.'):
2514 libdir = subprocess.Popen([self.options['lhapdf'], '--libs'],
2515 stdout = subprocess.PIPE).stdout.read().strip()
2516
2517 return libdir
2518
2520 """A class for asking a question where in addition you can have the
2521 set command define and modifying the param_card/run_card correctly"""
2522
2523 special_shortcut = {'ebeam':['run_card ebeam1 %(0)s', 'run_card ebeam2 %(0)s'],
2524 'lpp': ['run_card lpp1 %(0)s', 'run_card lpp2 %(0)s' ],
2525 'lhc': ['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2'],
2526 'lep': ['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2'],
2527 'ilc': ['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2'],
2528 'lcc':['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2'],
2529 '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'],
2530 }
2531
2532 - def __init__(self, question, cards=[], mode='auto', *args, **opt):
2533
2534
2535 if 'pwd' in opt:
2536 self.me_dir = opt['pwd']
2537 del opt['pwd']
2538
2539 cmd.OneLinePathCompletion.__init__(self, question, *args, **opt)
2540
2541 if not hasattr(self, 'me_dir') or not self.me_dir:
2542 self.me_dir = self.mother_interface.me_dir
2543
2544
2545
2546
2547 try:
2548 self.param_card = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card.dat'))
2549 except (check_param_card.InvalidParamCard, ValueError) as e:
2550 logger.error('Current param_card is not valid. We are going to use the default one.')
2551 logger.error('problem detected: %s' % e)
2552 files.cp(pjoin(self.me_dir,'Cards','param_card_default.dat'),
2553 pjoin(self.me_dir,'Cards','param_card.dat'))
2554 self.param_card = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card.dat'))
2555 default_param = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card_default.dat'))
2556
2557
2558 try:
2559 self.run_card = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card.dat'))
2560 except IOError:
2561 self.run_card = {}
2562 try:
2563 run_card_def = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card_default.dat'))
2564 except IOError:
2565 run_card_def = {}
2566
2567 self.pname2block = {}
2568 self.conflict = []
2569 self.restricted_value = {}
2570 self.mode = mode
2571 self.cards = cards
2572
2573
2574
2575
2576 self.pname2block, self.restricted_value = \
2577 default_param.analyze_param_card()
2578
2579 if run_card_def:
2580 self.run_set = run_card_def.keys() + self.run_card.hidden_param
2581 elif self.run_card:
2582 self.run_set = self.run_card.keys()
2583 else:
2584 self.run_set = []
2585
2586 for var in self.pname2block:
2587 if var in self.run_set:
2588 self.conflict.append(var)
2589
2590
2591
2592 self.has_mw = False
2593 if 'madweight_card.dat' in cards:
2594
2595 self.do_change_tf = self.mother_interface.do_define_transfer_fct
2596 self.complete_change_tf = self.mother_interface.complete_define_transfer_fct
2597 self.help_change_tf = self.mother_interface.help_define_transfer_fct
2598 if not os.path.exists(pjoin(self.me_dir,'Cards','transfer_card.dat')):
2599 logger.warning('No transfer function currently define. Please use the change_tf command to define one.')
2600
2601
2602 self.has_mw = True
2603 try:
2604 import madgraph.madweight.Cards as mwcards
2605 except:
2606 import internal.madweight.Cards as mwcards
2607 self.mw_card = mwcards.Card(pjoin(self.me_dir,'Cards','MadWeight_card.dat'))
2608 self.mw_card = self.mw_card.info
2609 self.mw_vars = []
2610 for key in self.mw_card:
2611 if key == 'comment':
2612 continue
2613 for key2 in self.mw_card.info[key]:
2614 if isinstance(key2, str) and not key2.isdigit():
2615 self.mw_vars.append(key2)
2616
2617
2618 for var in self.pname2block:
2619 if var in self.mw_vars:
2620 self.conflict.append(var)
2621 for var in self.mw_vars:
2622 if var in self.run_card:
2623 self.conflict.append(var)
2624
2625
2626 self.has_ml = False
2627 if os.path.isfile(pjoin(self.me_dir,'Cards','MadLoopParams.dat')):
2628 self.has_ml = True
2629 self.MLcard = banner_mod.MadLoopParam(pjoin(self.me_dir,'Cards','MadLoopParams.dat'))
2630 self.MLcardDefault = banner_mod.MadLoopParam()
2631
2632 self.ml_vars = [k.lower() for k in self.MLcard.keys()]
2633
2634 for var in self.MLcard:
2635 if var in self.run_card:
2636 self.conflict.append(var)
2637 if var in self.pname2block:
2638 self.conflict.append(var)
2639 if self.has_mw and var in self.mw_vars:
2640 self.conflict.append(var)
2641
2642
2643 self.has_shower = False
2644 if 'shower_card.dat' in cards:
2645 self.has_shower = True
2646 try:
2647 import madgraph.various.shower_card as showercards
2648 except:
2649 import internal.shower_card as showercards
2650 self.shower_card = showercards.ShowerCard(pjoin(self.me_dir,'Cards','shower_card.dat'))
2651 self.shower_vars = self.shower_card.keys()
2652
2653
2654 for var in self.pname2block:
2655 if var in self.shower_vars:
2656 self.conflict.append(var)
2657 for var in self.shower_vars:
2658 if var in self.run_card:
2659 self.conflict.append(var)
2660
2661
2663 """ Complete the set command"""
2664
2665 prev_timer = signal.alarm(0)
2666 if prev_timer:
2667 nb_back = len(line)
2668 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
2669 self.stdout.write(line)
2670 self.stdout.flush()
2671
2672 possibilities = {}
2673 allowed = {}
2674 args = self.split_arg(line[0:begidx])
2675 if args[-1] in ['Auto', 'default']:
2676 return
2677 if len(args) == 1:
2678 allowed = {'category':'', 'run_card':'', 'block':'all', 'param_card':'','shortcut':''}
2679 if self.has_mw:
2680 allowed['madweight_card'] = ''
2681 allowed['mw_block'] = 'all'
2682 if self.has_shower:
2683 allowed['shower_card'] = ''
2684 if self.has_ml:
2685 allowed['madloop_card'] = ''
2686 elif len(args) == 2:
2687 if args[1] == 'run_card':
2688 allowed = {'run_card':'default'}
2689 elif args[1] == 'param_card':
2690 allowed = {'block':'all', 'param_card':'default'}
2691 elif args[1] in self.param_card.keys():
2692 allowed = {'block':args[1]}
2693 elif args[1] == 'width':
2694 allowed = {'block': 'decay'}
2695 elif args[1] == 'MadWeight_card':
2696 allowed = {'madweight_card':'default', 'mw_block': 'all'}
2697 elif args[1] == 'MadLoop_card':
2698 allowed = {'madloop_card':'default'}
2699 elif self.has_mw and args[1] in self.mw_card.keys():
2700 allowed = {'mw_block':args[1]}
2701 elif args[1] == 'shower_card':
2702 allowed = {'shower_card':'default'}
2703 else:
2704 allowed = {'value':''}
2705 else:
2706 start = 1
2707 if args[1] in ['run_card', 'param_card', 'MadWeight_card', 'shower_card', 'MadLoop_card']:
2708 start = 2
2709 if args[-1] in self.pname2block.keys():
2710 allowed['value'] = 'default'
2711 elif args[start] in self.param_card.keys() or args[start] == 'width':
2712 if args[start] == 'width':
2713 args[start] = 'decay'
2714
2715 if args[start+1:]:
2716 allowed = {'block':(args[start], args[start+1:])}
2717 else:
2718 allowed = {'block':args[start]}
2719 elif self.has_mw and args[start] in self.mw_card.keys():
2720 if args[start+1:]:
2721 allowed = {'mw_block':(args[start], args[start+1:])}
2722 else:
2723 allowed = {'mw_block':args[start]}
2724
2725
2726 else:
2727 allowed['value'] = ''
2728
2729 if 'category' in allowed.keys():
2730 categories = ['run_card', 'param_card']
2731 if self.has_mw:
2732 categories.append('MadWeight_card')
2733 if self.has_shower:
2734 categories.append('shower_card')
2735 if self.has_ml:
2736 categories.append('MadLoop_card')
2737
2738 possibilities['category of parameter (optional)'] = \
2739 self.list_completion(text, categories)
2740
2741 if 'shortcut' in allowed.keys():
2742 possibilities['special values'] = self.list_completion(text, self.special_shortcut.keys()+['qcut', 'showerkt'])
2743
2744 if 'run_card' in allowed.keys():
2745 opts = self.run_set
2746 if allowed['run_card'] == 'default':
2747 opts.append('default')
2748
2749 possibilities['Run Card'] = self.list_completion(text, opts)
2750
2751 if 'param_card' in allowed.keys():
2752 opts = self.pname2block.keys()
2753 if allowed['param_card'] == 'default':
2754 opts.append('default')
2755 possibilities['Param Card'] = self.list_completion(text, opts)
2756
2757 if 'madweight_card' in allowed.keys():
2758 opts = self.mw_vars + [k for k in self.mw_card.keys() if k !='comment']
2759 if allowed['madweight_card'] == 'default':
2760 opts.append('default')
2761 possibilities['MadWeight Card'] = self.list_completion(text, opts)
2762
2763 if 'madloop_card' in allowed.keys():
2764 opts = self.ml_vars
2765 if allowed['madloop_card'] == 'default':
2766 opts.append('default')
2767
2768 possibilities['MadLoop Parameter'] = self.list_completion(text, opts)
2769
2770 if 'shower_card' in allowed.keys():
2771 opts = self.shower_vars + [k for k in self.shower_card.keys() if k !='comment']
2772 if allowed['shower_card'] == 'default':
2773 opts.append('default')
2774 possibilities['Shower Card'] = self.list_completion(text, opts)
2775
2776 if 'value' in allowed.keys():
2777 opts = ['default']
2778 if 'decay' in args:
2779 opts.append('Auto')
2780 opts.append('Auto@NLO')
2781 elif args[-1] in self.pname2block and self.pname2block[args[-1]][0][0] == 'decay':
2782 opts.append('Auto')
2783 opts.append('Auto@NLO')
2784 possibilities['Special Value'] = self.list_completion(text, opts)
2785
2786 if 'block' in allowed.keys():
2787 if allowed['block'] == 'all':
2788 allowed_block = [i for i in self.param_card.keys() if 'qnumbers' not in i]
2789 allowed_block.append('width')
2790 possibilities['Param Card Block' ] = \
2791 self.list_completion(text, allowed_block)
2792 elif isinstance(allowed['block'], basestring):
2793 block = self.param_card[allowed['block']].param_dict
2794 ids = [str(i[0]) for i in block
2795 if (allowed['block'], i) not in self.restricted_value]
2796 possibilities['Param Card id' ] = self.list_completion(text, ids)
2797 varname = [name for name, all_var in self.pname2block.items()
2798 if any((bname == allowed['block']
2799 for bname,lhaid in all_var))]
2800 possibilities['Param card variable'] = self.list_completion(text,
2801 varname)
2802 else:
2803 block = self.param_card[allowed['block'][0]].param_dict
2804 nb = len(allowed['block'][1])
2805 ids = [str(i[nb]) for i in block if len(i) > nb and \
2806 [str(a) for a in i[:nb]] == allowed['block'][1]]
2807
2808 if not ids:
2809 if tuple([int(i) for i in allowed['block'][1]]) in block:
2810 opts = ['default']
2811 if allowed['block'][0] == 'decay':
2812 opts.append('Auto')
2813 opts.append('Auto@NLO')
2814 possibilities['Special value'] = self.list_completion(text, opts)
2815 possibilities['Param Card id' ] = self.list_completion(text, ids)
2816
2817 if 'mw_block' in allowed.keys():
2818 if allowed['mw_block'] == 'all':
2819 allowed_block = [i for i in self.mw_card.keys() if 'comment' not in i]
2820 possibilities['MadWeight Block' ] = \
2821 self.list_completion(text, allowed_block)
2822 elif isinstance(allowed['mw_block'], basestring):
2823 block = self.mw_card[allowed['mw_block']]
2824 ids = [str(i[0]) if isinstance(i, tuple) else str(i) for i in block]
2825 possibilities['MadWeight Card id' ] = self.list_completion(text, ids)
2826 else:
2827 block = self.mw_card[allowed['mw_block'][0]]
2828 nb = len(allowed['mw_block'][1])
2829 ids = [str(i[nb]) for i in block if isinstance(i, tuple) and\
2830 len(i) > nb and \
2831 [str(a) for a in i[:nb]] == allowed['mw_block'][1]]
2832
2833 if not ids:
2834 if tuple([i for i in allowed['mw_block'][1]]) in block or \
2835 allowed['mw_block'][1][0] in block.keys():
2836 opts = ['default']
2837 possibilities['Special value'] = self.list_completion(text, opts)
2838 possibilities['MadWeight Card id' ] = self.list_completion(text, ids)
2839
2840 return self.deal_multiple_categories(possibilities)
2841
2843 """ edit the value of one parameter in the card"""
2844
2845 args = self.split_arg(line)
2846
2847 if '=' in args[-1]:
2848 arg1, arg2 = args.pop(-1).split('=')
2849 args += [arg1, arg2]
2850 if '=' in args:
2851 args.remove('=')
2852
2853 if not ( args[0].lower() in ['analyse', 'extralibs', 'extrapaths', 'includepaths'] or \
2854 args[0].lower().startswith('dm_') ):
2855 args[:-1] = [ a.lower() for a in args[:-1]]
2856
2857 if args[0] in self.special_shortcut:
2858 if len(args) == 1:
2859 values = {}
2860 elif len(args) == 2:
2861 targettype = float
2862 if args[1].strip().isdigit():
2863 targettype = int
2864
2865 try:
2866 values = {'0': targettype(args[1])}
2867 except ValueError as e:
2868 logger.warning("Wrong argument: The last entry should be a number.")
2869 return
2870 else:
2871 logger.warning("too many argument for this command")
2872 return
2873
2874 for arg in self.special_shortcut[args[0]]:
2875 try:
2876 text = arg % values
2877 except KeyError:
2878 logger.warning("This command requires one argument")
2879 return
2880 except Exception as e:
2881 logger.warning(str(e))
2882 return
2883 else:
2884 self.do_set(arg % values)
2885 return
2886
2887
2888 start = 0
2889 if len(args) < 2:
2890 logger.warning('Invalid set command %s (need two arguments)' % line)
2891 return
2892
2893
2894 if args[0].lower() == 'qcut':
2895 pythia_path = pjoin(self.me_dir, 'Cards','pythia_card.dat')
2896 if os.path.exists(pythia_path):
2897 logger.info('add line QCUT = %s in pythia_card.dat' % args[1])
2898 p_card = open(pythia_path,'r').read()
2899 p_card, n = re.subn('''^\s*QCUT\s*=\s*[\de\+\-\.]*\s*$''',
2900 ''' QCUT = %s ''' % args[1], \
2901 p_card, flags=(re.M+re.I))
2902 if n==0:
2903 p_card = '%s \n QCUT= %s' % (p_card, args[1])
2904 open(pythia_path, 'w').write(p_card)
2905 return
2906
2907 if args[0].lower() == 'showerkt':
2908 pythia_path = pjoin(self.me_dir, 'Cards','pythia_card.dat')
2909 if os.path.exists(pythia_path):
2910 logger.info('add line SHOWERKT = %s in pythia_card.dat' % args[1].upper())
2911 p_card = open(pythia_path,'r').read()
2912 p_card, n = re.subn('''^\s*SHOWERKT\s*=\s*[default\de\+\-\.]*\s*$''',
2913 ''' SHOWERKT = %s ''' % args[1].upper(), \
2914 p_card, flags=(re.M+re.I))
2915 if n==0:
2916 p_card = '%s \n SHOWERKT= %s' % (p_card, args[1].upper())
2917 open(pythia_path, 'w').write(p_card)
2918 return
2919
2920
2921 card = ''
2922 if args[0] == 'madweight_card':
2923 if not self.mw_card:
2924 logger.warning('Invalid Command: No MadWeight card defined.')
2925 return
2926 args[0] = 'MadWeight_card'
2927
2928 if args[0] == 'shower_card':
2929 if not self.shower_card:
2930 logger.warning('Invalid Command: No Shower card defined.')
2931 return
2932 args[0] = 'shower_card'
2933
2934 if args[0] == "madloop_card":
2935 if not self.has_ml:
2936 logger.warning('Invalid Command: No MadLoopParam card defined.')
2937 return
2938 args[0] = 'MadLoop_card'
2939
2940 if args[0] in ['run_card', 'param_card', 'MadWeight_card', 'shower_card']:
2941 if args[1] == 'default':
2942 logging.info('replace %s by the default card' % args[0])
2943 files.cp(pjoin(self.me_dir,'Cards','%s_default.dat' % args[0]),
2944 pjoin(self.me_dir,'Cards','%s.dat'% args[0]))
2945 if args[0] == 'param_card':
2946 self.param_card = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card.dat'))
2947 elif args[0] == 'run_card':
2948 self.run_card = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card.dat'))
2949 elif args[0] == 'shower_card':
2950 self.shower_card = shower_card_mod.ShowerCard(pjoin(self.me_dir,'Cards','shower_card.dat'))
2951 return
2952 else:
2953 card = args[0]
2954 start=1
2955 if len(args) < 3:
2956 logger.warning('Invalid set command: %s (not enough arguments)' % line)
2957 return
2958
2959 elif args[0] in ['MadLoop_card']:
2960 if args[1] == 'default':
2961 logging.info('replace MadLoopParams.dat by the default card')
2962 self.MLcard = banner_mod.MadLoopParam(self.MLcardDefault)
2963 self.MLcard.write(pjoin(self.me_dir,'Cards','MadLoopParams.dat'),
2964 commentdefault=True)
2965 return
2966 else:
2967 card = args[0]
2968 start=1
2969 if len(args) < 3:
2970 logger.warning('Invalid set command: %s (not enough arguments)' % line)
2971 return
2972 elif args[0] in ['madspin_card']:
2973 if args[1] == 'default':
2974 logging.info('replace madspin_card.dat by the default card')
2975 files.cp(pjoin(self.me_dir,'Cards/madspin_card_default.dat'),
2976 pjoin(self.me_dir,'Cards/madspin_card.dat'))
2977 return
2978 else:
2979 logger.warning("""Command set not allowed for modifying the madspin_card.
2980 Check the command \"decay\" instead.""")
2981 return
2982
2983
2984 if args[start] in [l.lower() for l in self.run_card.keys()] and card in ['', 'run_card']:
2985 if args[start] not in self.run_set:
2986 args[start] = [l for l in self.run_set if l.lower() == args[start]][0]
2987
2988 if args[start] in self.conflict and card == '':
2989 text = 'Ambiguous name (present in more than one card). Will assume it to be referred to run_card.\n'
2990 text += 'If this is not intended, please reset it in the run_card and specify the relevant card to \n'
2991 text += 'edit, in the format < set card parameter value >'
2992 logger.warning(text)
2993
2994 if args[start+1] == 'default':
2995 default = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card_default.dat'))
2996 if args[start] in default.keys():
2997 self.setR(args[start],default[args[start]])
2998 else:
2999 logger.info('remove information %s from the run_card' % args[start])
3000 del self.run_card[args[start]]
3001 else:
3002 if args[0].startswith('sys_') or args[0] in self.run_card.list_parameter:
3003 val = ' '.join(args[start+1:])
3004 val = val.split('#')[0]
3005 else:
3006 try:
3007 val = eval(args[start+1])
3008 except NameError:
3009 val = args[start+1]
3010 self.setR(args[start], val)
3011 self.run_card.write(pjoin(self.me_dir,'Cards','run_card.dat'),
3012 pjoin(self.me_dir,'Cards','run_card_default.dat'))
3013
3014
3015 elif (args[start] in self.param_card or args[start] == 'width') \
3016 and card in ['','param_card']:
3017
3018 if any(t.startswith('scan') for t in args):
3019 index = [i for i,t in enumerate(args) if t.startswith('scan')][0]
3020 args = args[:index] + [' '.join(args[index:])]
3021
3022 if args[start] in self.conflict and card == '':
3023 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
3024 text += ' in the format < set card parameter value>'
3025 logger.warning(text)
3026 return
3027
3028 if args[start] == 'width':
3029 args[start] = 'decay'
3030
3031 if args[start+1] in self.pname2block:
3032 all_var = self.pname2block[args[start+1]]
3033 key = None
3034 for bname, lhaid in all_var:
3035 if bname == args[start]:
3036 key = lhaid
3037 break
3038 else:
3039 logger.warning('%s is not part of block "%s" but "%s". please correct.' %
3040 (args[start+1], args[start], bname))
3041 return
3042 else:
3043 try:
3044 key = tuple([int(i) for i in args[start+1:-1]])
3045 except ValueError:
3046 if args[start] == 'decay' and args[start+1:-1] == ['all']:
3047 for key in self.param_card[args[start]].param_dict:
3048 if (args[start], key) in self.restricted_value:
3049 continue
3050 else:
3051 self.setP(args[start], key, args[-1])
3052 self.param_card.write(pjoin(self.me_dir,'Cards','param_card.dat'))
3053 return
3054 logger.warning('invalid set command %s (failed to identify LHA information)' % line)
3055 return
3056
3057 if key in self.param_card[args[start]].param_dict:
3058 if (args[start], key) in self.restricted_value:
3059 text = "Note that this parameter seems to be ignore by MG.\n"
3060 text += "MG will use instead the expression: %s\n" % \
3061 self.restricted_value[(args[start], key)]
3062 text += "You need to match this expression for external program (such pythia)."
3063 logger.warning(text)
3064
3065 if args[-1].lower() in ['default', 'auto', 'auto@nlo'] or args[-1].startswith('scan'):
3066 self.setP(args[start], key, args[-1])
3067 else:
3068 try:
3069 value = float(args[-1])
3070 except Exception:
3071 logger.warning('Invalid input: Expected number and not \'%s\'' \
3072 % args[-1])
3073 return
3074 self.setP(args[start], key, value)
3075 else:
3076 logger.warning('invalid set command %s' % line)
3077 return
3078 self.param_card.write(pjoin(self.me_dir,'Cards','param_card.dat'))
3079
3080
3081 elif args[start] in self.pname2block and card != 'run_card':
3082 if args[start] in self.conflict and card == '':
3083 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
3084 text += ' in the format < set card parameter value>'
3085 logger.warning(text)
3086 return
3087
3088 all_var = self.pname2block[args[start]]
3089 for bname, lhaid in all_var:
3090 new_line = 'param_card %s %s %s' % (bname,
3091 ' '.join([ str(i) for i in lhaid]), ' '.join(args[start+1:]))
3092 self.do_set(new_line)
3093 if len(all_var) > 1:
3094 logger.warning('This variable correspond to more than one parameter in the param_card.')
3095 for bname, lhaid in all_var:
3096 logger.warning(' %s %s' % (bname, ' '.join([str(i) for i in lhaid])))
3097 logger.warning('all listed variables have been modified')
3098
3099
3100 elif self.has_mw and (args[start] in self.mw_card and args[start] != 'comment') \
3101 and card in ['','MadWeight_card']:
3102
3103 if args[start] in self.conflict and card == '':
3104 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
3105 text += ' in the format < set card parameter value>'
3106 logger.warning(text)
3107 return
3108
3109 block = args[start]
3110 name = args[start+1]
3111 value = args[start+2:]
3112 self.setM(block, name, value)
3113 self.mw_card.write(pjoin(self.me_dir,'Cards','MadWeight_card.dat'))
3114
3115
3116 elif self.has_mw and args[start] in self.mw_vars \
3117 and card in ['', 'MadWeight_card']:
3118
3119 if args[start] in self.conflict and card == '':
3120 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
3121 text += ' in the format < set card parameter value>'
3122 logger.warning(text)
3123 return
3124
3125 block = [b for b, data in self.mw_card.items() if args[start] in data]
3126 if len(block) > 1:
3127 logger.warning('%s is define in more than one block: %s.Please specify.'
3128 % (args[start], ','.join(block)))
3129 return
3130
3131 block = block[0]
3132 name = args[start]
3133 value = args[start+1:]
3134 self.setM(block, name, value)
3135 self.mw_card.write(pjoin(self.me_dir,'Cards','MadWeight_card.dat'))
3136
3137
3138 elif self.has_mw and args[start].startswith('mw_') and len(args[start:]) == 3\
3139 and card == 'MadWeight_card':
3140 block = args[start]
3141 name = args[start+1]
3142 value = args[start+2]
3143 self.setM(block, name, value)
3144 self.mw_card.write(pjoin(self.me_dir,'Cards','MadWeight_card.dat'))
3145
3146
3147 elif self.has_shower and args[start].lower() in [l.lower() for l in \
3148 self.shower_card.keys()] and card in ['', 'shower_card']:
3149 if args[start] not in self.shower_card:
3150 args[start] = [l for l in self.shower_card if l.lower() == args[start].lower()][0]
3151
3152 if args[start] in self.conflict and card == '':
3153 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
3154 text += ' in the format < set card parameter value>'
3155 logger.warning(text)
3156 return
3157
3158 if args[start+1].lower() == 'default':
3159 default = shower_card_mod.ShowerCard(pjoin(self.me_dir,'Cards','shower_card_default.dat'))
3160 if args[start] in default.keys():
3161 self.shower_card.set_param(args[start],default[args[start]],pjoin(self.me_dir,'Cards','shower_card.dat'))
3162 else:
3163 logger.info('remove information %s from the shower_card' % args[start])
3164 del self.shower_card[args[start]]
3165 elif args[start+1].lower() in ['t','.true.','true']:
3166 self.shower_card.set_param(args[start],'.true.',pjoin(self.me_dir,'Cards','shower_card.dat'))
3167 elif args[start+1].lower() in ['f','.false.','false']:
3168 self.shower_card.set_param(args[start],'.false.',pjoin(self.me_dir,'Cards','shower_card.dat'))
3169 else:
3170 args_str = ' '.join(str(a) for a in args[start+1:len(args)])
3171 self.shower_card.set_param(args[start],args_str,pjoin(self.me_dir,'Cards','shower_card.dat'))
3172
3173
3174 elif self.has_ml and args[start] in self.ml_vars \
3175 and card in ['', 'MadLoop_card']:
3176
3177 if args[start] in self.conflict and card == '':
3178 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
3179 logger.warning(text)
3180 return
3181
3182 if args[start+1] == 'default':
3183 value = self.MLcardDefault[args[start]]
3184 default = True
3185 else:
3186 value = args[start+1]
3187 default = False
3188 self.setML(args[start], value, default=default)
3189 self.MLcard.write(pjoin(self.me_dir,'Cards','MadLoopParams.dat'),
3190 commentdefault=True)
3191
3192
3193 else:
3194 logger.warning('invalid set command %s ' % line)
3195 return
3196
3197 - def setM(self, block, name, value):
3198
3199 if isinstance(value, list) and len(value) == 1:
3200 value = value[0]
3201
3202 if block not in self.mw_card:
3203 logger.warning('block %s was not present in the current MadWeight card. We are adding it' % block)
3204 self.mw_card[block] = {}
3205 elif name not in self.mw_card[block]:
3206 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')
3207 if value == 'default':
3208 import madgraph.madweight.Cards as mwcards
3209 mw_default = mwcards.Card(pjoin(self.me_dir,'Cards','MadWeight_card_default.dat'))
3210 try:
3211 value = mw_default[block][name]
3212 except KeyError:
3213 logger.info('removing id "%s" from Block "%s" '% (name, block))
3214 if name in self.mw_card[block]:
3215 del self.mw_card[block][name]
3216 return
3217 if value:
3218 logger.info('modify madweight_card information BLOCK "%s" with id "%s" set to %s' %\
3219 (block, name, value), '$MG:color:BLACK')
3220 else:
3221 logger.value("Invalid command: No value. To set default value. Use \"default\" as value")
3222 return
3223
3224 self.mw_card[block][name] = value
3225
3226 - def setR(self, name, value):
3227 logger.info('modify parameter %s of the run_card.dat to %s' % (name, value))
3228 self.run_card.set(name, value, user=True)
3229
3230 - def setML(self, name, value, default=False):
3231
3232 try:
3233 self.MLcard.set(name, value, user=True)
3234 except Exception, error:
3235 logger.warning("Fail to change parameter. Please Retry. Reason: %s." % error)
3236 return
3237 logger.info('modify parameter %s of the MadLoopParam.dat to %s' % (name, value))
3238 if default and name.lower() in self.MLcard.user_set:
3239 self.MLcard.user_set.remove(name.lower())
3240
3241 - def setP(self, block, lhaid, value):
3242 if isinstance(value, str):
3243 value = value.lower()
3244 if value == 'default':
3245 default = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card_default.dat'))
3246 value = default[block].param_dict[lhaid].value
3247
3248 elif value in ['auto', 'auto@nlo']:
3249 if 'nlo' in value:
3250 value = 'Auto@NLO'
3251 else:
3252 value = 'Auto'
3253 if block != 'decay':
3254 logger.warning('Invalid input: \'Auto\' value only valid for DECAY')
3255 return
3256 elif value.startswith('scan'):
3257 if ':' not in value:
3258 logger.warning('Invalid input: \'scan\' mode requires a \':\' before the definition.')
3259 return
3260 tag = value.split(':')[0]
3261 tag = tag[4:].strip()
3262 if tag and not tag.isdigit():
3263 logger.warning('Invalid input: scan tag need to be integer and not "%s"' % tag)
3264 return
3265
3266
3267 pass
3268 else:
3269 try:
3270 value = float(value)
3271 except ValueError:
3272 logger.warning('Invalid input: \'%s\' not valid intput.'% value)
3273
3274 logger.info('modify param_card information BLOCK %s with id %s set to %s' %\
3275 (block, lhaid, value), '$MG:color:BLACK')
3276 self.param_card[block].param_dict[lhaid].value = value
3277
3279 """This is run on quitting the class. Apply here all the self-consistency
3280 rule that you want. Do the modification via the set command."""
3281
3282
3283 if 'reweight' in self.allow_arg and 'run' in self.allow_arg and \
3284 isinstance(self.run_card,banner_mod.RunCardNLO) and \
3285 not self.run_card['store_rwgt_info']:
3286
3287 re_pattern = re.compile(r'''^\s*change\s*mode\s* (LO\+NLO|LO|NLO)\s*(?:#|$)''', re.M+re.I)
3288 text = open(pjoin(self.me_dir,'Cards','reweight_card.dat')).read()
3289 options = re_pattern.findall(text)
3290 if any(o in ['NLO', 'LO+NLO'] for o in options):
3291 logger.info('NLO reweighting is on ON. Automatically set store_rwgt_info to True', '$MG:color:BLACK' )
3292 self.do_set('run_card store_rwgt_info True')
3293
3294
3295 - def reask(self, *args, **opt):
3296
3297 cmd.OneLinePathCompletion.reask(self,*args, **opt)
3298 if self.has_mw and not os.path.exists(pjoin(self.me_dir,'Cards','transfer_card.dat')):
3299 logger.warning('No transfer function currently define. Please use the change_tf command to define one.')
3300
3301 - def postcmd(self, stop, line):
3302
3303 ending_question = cmd.OneLinePathCompletion.postcmd(self,stop,line)
3304 if ending_question:
3305 self.check_card_consistency()
3306 return ending_question
3307
3311
3339
3340
3342 """Default action if line is not recognized"""
3343
3344 line = line.strip()
3345 args = line.split()
3346 if line == '' and self.default_value is not None:
3347 self.value = self.default_value
3348
3349 elif hasattr(self, 'do_%s' % args[0]):
3350 self.do_set(' '.join(args[1:]))
3351 elif os.path.isfile(line):
3352 self.copy_file(line)
3353 self.value = 'repeat'
3354 elif os.path.exists(pjoin(self.me_dir, line)):
3355 self.copy_file(pjoin(self.me_dir,line))
3356 self.value = 'repeat'
3357 elif line.strip() != '0' and line.strip() != 'done' and \
3358 str(line) != 'EOF' and line.strip() in self.allow_arg:
3359 self.open_file(line)
3360 self.value = 'repeat'
3361 else:
3362 self.value = line
3363
3364 return line
3365
3367 """edit the madspin_card to define the decay of the associate particle"""
3368 signal.alarm(0)
3369 path = pjoin(self.me_dir,'Cards','madspin_card.dat')
3370
3371 if 'madspin_card.dat' not in self.cards or not os.path.exists(path):
3372 logger.warning("Command decay not valid. Since MadSpin is not available.")
3373 return
3374
3375 if ">" not in line:
3376 logger.warning("invalid command for decay. Line ignored")
3377 return
3378
3379 if "-add" in line:
3380
3381 particle = line.split('>')[0].strip()
3382 text = open(path).read()
3383 line = line.replace('--add', '').replace('-add','')
3384 logger.info("change madspin_card to add one decay to %s: %s" %(particle, line.strip()), '$MG:color:BLACK')
3385
3386 text = text.replace('launch', "\ndecay %s\nlaunch\n" % line,1)
3387 open(path,'w').write(text)
3388 else:
3389
3390
3391 particle = line.split('>')[0].strip()
3392 logger.info("change madspin_card to define the decay of %s: %s" %(particle, line.strip()), '$MG:color:BLACK')
3393 particle = particle.replace('+','\+').replace('-','\-')
3394 decay_pattern = re.compile(r"^\s*decay\s+%s\s*>[\s\w+-~]*?$" % particle, re.I+re.M)
3395 text= open(path).read()
3396 text = decay_pattern.sub('', text)
3397 text = text.replace('launch', "\ndecay %s\nlaunch\n" % line,1)
3398 open(path,'w').write(text)
3399
3400
3401
3403 signal.alarm(0)
3404 path = pjoin(self.me_dir,'Cards','param_card.dat')
3405 pattern = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto(@NLO|)''',re.I)
3406 text = open(path).read()
3407 pdg_info = pattern.findall(text)
3408 has_nlo = any("@nlo"==nlo.lower() for _, nlo in pdg_info)
3409 pdg = [p for p,_ in pdg_info]
3410
3411
3412 line = '%s %s' % (line, ' '.join(pdg))
3413 if not '--path' in line:
3414 line += ' --path=%s' % path
3415 if has_nlo:
3416 line += ' --nlo'
3417
3418 try:
3419 return self.mother_interface.do_compute_widths(line)
3420 except InvalidCmd, error:
3421 logger.error("Invalid command: %s " % error)
3422
3426
3428 """help for command decay which modifies MadSpin_card"""
3429
3430 signal.alarm(0)
3431 print '--syntax: decay PROC [--add]'
3432 print ' '
3433 print ' modify the madspin_card to modify the decay of the associate particle.'
3434 print ' and define it to PROC.'
3435 print ' if --add is present, just add a new decay for the associate particle.'
3436
3440
3441
3442
3444 """Help associated to the asperge command"""
3445 signal.alarm(0)
3446
3447 print '-- syntax: asperge [options]'
3448 print ' Call ASperGe to diagonalize all mass matrices in the model.'
3449 print ' This works only if the ASperGE module is part of the UFO model (a subdirectory).'
3450 print ' If you specify some names after the command (i.e. asperge m1 m2) then ASperGe will only'
3451 print ' diagonalize the associate mass matrices (here m1 and m2).'
3452
3454 signal.alarm(0)
3455
3456 blockname = self.pname2block.keys()
3457
3458 wrong = ['decay', 'mass', 'sminput']
3459 valid = [k for k in blockname if 'mix' in k]
3460 potential = [k for k in blockname if k not in valid+wrong]
3461 output = {'Mixing matrices': self.list_completion(text, valid, line),
3462 'Other potential valid input': self.list_completion(text, potential, line)}
3463
3464 return self.deal_multiple_categories(output)
3465
3466
3468 """Running ASperGe"""
3469 signal.alarm(0)
3470
3471 path = pjoin(self.me_dir,'bin','internal','ufomodel','ASperGE')
3472 if not os.path.exists(path):
3473 logger.error('ASperge has not been detected in the current model, therefore it will not be run.')
3474 return
3475 elif not os.path.exists(pjoin(path,'ASperGe')):
3476 logger.info('ASperGe has been detected but is not compiled. Running the compilation now.')
3477 try:
3478 misc.compile(cwd=path,shell=True)
3479 except MadGraph5Error, error:
3480 logger.error('''ASperGe failed to compile. Note that gsl is needed
3481 for this compilation to go trough. More information on how to install this package on
3482 http://www.gnu.org/software/gsl/
3483 Full compilation log is available at %s''' % pjoin(self.me_dir, 'ASperge_compilation.log'))
3484 open(pjoin(self.me_dir, 'ASperge_compilation.log'),'w').write(str(error))
3485 return
3486
3487 opts = line.split()
3488 card = pjoin(self.me_dir,'Cards', 'param_card.dat')
3489 logger.info('running ASperGE')
3490 returncode = misc.call([pjoin(path,'ASperGe'), card, '%s.new' % card] + opts)
3491 if returncode:
3492 logger.error('ASperGE fails with status %s' % returncode)
3493 else:
3494 logger.info('AsPerGe creates the file succesfully')
3495 files.mv(card, '%s.beforeasperge' % card)
3496 files.mv('%s.new' % card, card)
3497
3498
3499
3501 """detect the type of the file and overwritte the current file"""
3502
3503 if path.endswith('.lhco'):
3504
3505
3506 self.do_set('mw_run inputfile %s' % os.path.relpath(path, self.mother_interface.me_dir))
3507 return
3508 elif path.endswith('.lhco.gz'):
3509
3510
3511 self.do_set('mw_run inputfile %s' % os.path.relpath(path, self.mother_interface.me_dir))
3512 return
3513 else:
3514 card_name = CommonRunCmd.detect_card_type(path)
3515
3516 if card_name == 'unknown':
3517 logger.warning('Fail to determine the type of the file. Not copied')
3518 if card_name != 'banner':
3519 logger.info('copy %s as %s' % (path, card_name))
3520 files.cp(path, pjoin(self.me_dir, 'Cards', card_name))
3521 elif card_name == 'banner':
3522 banner_mod.split_banner(path, self.mother_interface.me_dir, proc_card=False)
3523 logger.info('Splitting the banner in it\'s component')
3524 if not self.mode == 'auto':
3525 self.mother_interface.keep_cards(self.cards)
3526
3528 """open the file"""
3529 me_dir = self.mother_interface.me_dir
3530 if answer.isdigit():
3531 if answer == '9':
3532 answer = 'plot'
3533 else:
3534 answer = self.cards[int(answer)-1]
3535 if 'madweight' in answer:
3536 answer = answer.replace('madweight', 'MadWeight')
3537
3538 if 'MadLoopParams' in answer:
3539 answer = pjoin(me_dir,'Cards','MadLoopParams.dat')
3540 if not '.dat' in answer and not '.lhco' in answer:
3541 if answer != 'trigger':
3542 path = pjoin(me_dir,'Cards','%s_card.dat' % answer)
3543 else:
3544 path = pjoin(me_dir,'Cards','delphes_trigger.dat')
3545 elif not '.lhco' in answer:
3546 path = pjoin(me_dir, 'Cards', answer)
3547 else:
3548 path = pjoin(me_dir, self.mw_card['mw_run']['inputfile'])
3549 if not os.path.exists(path):
3550 logger.info('Path in MW_card not existing')
3551 path = pjoin(me_dir, 'Events', answer)
3552
3553 path = path.replace('_card_card','_card')
3554 try:
3555 self.mother_interface.exec_cmd('open %s' % path)
3556 except InvalidCmd, error:
3557 if str(error) != 'No default path for this file':
3558 raise
3559 if answer == 'transfer_card.dat':
3560 logger.warning('You have to specify a transfer function first!')
3561 elif answer == 'input.lhco':
3562 path = pjoin(me_dir,'Events', 'input.lhco')
3563 ff = open(path,'w')
3564 ff.write('''No LHCO information imported at current time.
3565 To import a lhco file: Close this file and type the path of your file.
3566 You can also copy/paste, your event file here.''')
3567 ff.close()
3568 self.open_file(path)
3569 else:
3570 raise
3571
3572
3573 if path == pjoin(self.me_dir,'Cards','param_card.dat'):
3574 try:
3575 self.param_card = check_param_card.ParamCard(path)
3576 except (check_param_card.InvalidParamCard, ValueError) as e:
3577 logger.error('Current param_card is not valid. We are going to use the default one.')
3578 logger.error('problem detected: %s' % e)
3579 logger.error('Please re-open the file and fix the problem.')
3580 logger.warning('using the \'set\' command without opening the file will discard all your manual change')
3581 elif path == pjoin(self.me_dir,'Cards','run_card.dat'):
3582 self.run_card = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card.dat'))
3583 elif path == pjoin(self.me_dir,'Cards','MadLoopParams.dat'):
3584 self.MLcard = banner_mod.MadLoopParam(pjoin(self.me_dir,'Cards','MadLoopParams.dat'))
3585 elif path == pjoin(self.me_dir,'Cards','MadWeight_card.dat'):
3586 try:
3587 import madgraph.madweight.Cards as mwcards
3588 except:
3589 import internal.madweight.Cards as mwcards
3590 self.mw_card = mwcards.Card(pjoin(self.me_dir,'Cards','MadWeight_card.dat'))
3591