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 ast
21 import atexit
22 import cmath
23 import cmd
24 import glob
25 import logging
26 import math
27 import optparse
28 import os
29 import pydoc
30 import random
31 import re
32 import shutil
33 import signal
34 import stat
35 import subprocess
36 import sys
37 import time
38 import traceback
39 import glob
40 import StringIO
41
42 try:
43 import readline
44 GNU_SPLITTING = ('GNU' in readline.__doc__)
45 except:
46 GNU_SPLITTING = True
47
48 root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
49 root_path = os.path.split(root_path)[0]
50 sys.path.insert(0, os.path.join(root_path,'bin'))
51
52
53 pjoin = os.path.join
54
55 logger = logging.getLogger('madgraph.stdout')
56 logger_stderr = logging.getLogger('madgraph.stderr')
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.histograms as histograms
70 import internal.save_load_object as save_load_object
71 import internal.gen_crossxhtml as gen_crossxhtml
72 import internal.lhe_parser as lhe_parser
73 from internal import InvalidCmd, MadGraph5Error
74 MADEVENT=True
75 else:
76
77 import madgraph.interface.extended_cmd as cmd
78 import madgraph.various.banner as banner_mod
79 import madgraph.various.shower_card as shower_card_mod
80 import madgraph.various.misc as misc
81 import madgraph.iolibs.files as files
82 import madgraph.various.cluster as cluster
83 import madgraph.various.lhe_parser as lhe_parser
84 import madgraph.iolibs.save_load_object as save_load_object
85 import madgraph.madevent.gen_crossxhtml as gen_crossxhtml
86 import models.check_param_card as check_param_card
87 import madgraph.various.histograms as histograms
88
89 from madgraph import InvalidCmd, MadGraph5Error, MG5DIR
90 MADEVENT=False
96 """ The Series of help routins in common between amcatnlo_run and
97 madevent interface"""
98
100 logger.info("syntax: treatcards [param|run] [--output_dir=] [--param_card=] [--run_card=]")
101 logger.info("-- create the .inc files containing the cards information." )
102
104 logger.info("syntax: set %s argument" % "|".join(self._set_options))
105 logger.info("-- set options")
106 logger.info(" stdout_level DEBUG|INFO|WARNING|ERROR|CRITICAL")
107 logger.info(" change the default level for printed information")
108 logger.info(" timeout VALUE")
109 logger.info(" (default 20) Seconds allowed to answer questions.")
110 logger.info(" Note that pressing tab always stops the timer.")
111 logger.info(" cluster_temp_path PATH")
112 logger.info(" (default None) Allow to perform the run in PATH directory")
113 logger.info(" This allow to not run on the central disk. This is not used")
114 logger.info(" by condor cluster (since condor has it's own way to prevent it).")
115
117 logger.info("syntax: help [RUN] [%s] [-f]" % '|'.join(self._plot_mode))
118 logger.info("-- create the plot for the RUN (current run by default)")
119 logger.info(" at the different stage of the event generation")
120 logger.info(" Note than more than one mode can be specified in the same command.")
121 logger.info(" This require to have MadAnalysis and td require. By default")
122 logger.info(" if those programs are installed correctly, the creation")
123 logger.info(" will be performed automaticaly during the event generation.")
124 logger.info(" -f options: answer all question by default.")
125
127 logger.info("syntax: compute_widths Particle [Particles] [OPTIONS]")
128 logger.info("-- Compute the widths for the particles specified.")
129 logger.info(" By default, this takes the current param_card and overwrites it.")
130 logger.info(" Precision allows to define when to include three/four/... body decays (LO).")
131 logger.info(" If this number is an integer then all N-body decay will be included.")
132 logger.info(" Various options:\n")
133 logger.info(" --body_decay=X: Parameter to control the precision of the computation")
134 logger.info(" if X is an integer, we compute all channels up to X-body decay.")
135 logger.info(" if X <1, then we stop when the estimated error is lower than X.")
136 logger.info(" if X >1 BUT not an integer, then we X = N + M, with M <1 and N an integer")
137 logger.info(" We then either stop at the N-body decay or when the estimated error is lower than M.")
138 logger.info(" default: 4.0025")
139 logger.info(" --min_br=X: All channel which are estimated below this value will not be integrated numerically.")
140 logger.info(" default: precision (decimal part of the body_decay options) divided by four")
141 logger.info(" --precision_channel=X: requested numerical precision for each channel")
142 logger.info(" default: 0.01")
143 logger.info(" --path=X: path for param_card")
144 logger.info(" default: take value from the model")
145 logger.info(" --output=X: path where to write the resulting card. ")
146 logger.info(" default: overwrite input file. If no input file, write it in the model directory")
147 logger.info(" --nlo: Compute NLO width [if the model support it]")
148
150 logger.info("syntax: shower [shower_name] [shower_options]")
151 logger.info("-- This is equivalent to running '[shower_name] [shower_options]'")
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(ast.literal_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 argument for pythia command
316 syntax: delphes [NAME]
317 Note that other option are already remove at this point
318 """
319
320
321 if not self.options['delphes_path']:
322 logger.info('Retry to read configuration file to find delphes path')
323 self.set_configuration()
324
325 if not self.options['delphes_path']:
326 error_msg = 'No valid Delphes path set.\n'
327 error_msg += 'Please use the set command to define the path and retry.\n'
328 error_msg += 'You can also define it in the configuration file.\n'
329 raise self.InvalidCmd(error_msg)
330
331 tag = [a for a in arg if a.startswith('--tag=')]
332 if tag:
333 arg.remove(tag[0])
334 tag = tag[0][6:]
335
336
337 if len(arg) == 0 and not self.run_name:
338 if self.results.lastrun:
339 arg.insert(0, self.results.lastrun)
340 else:
341 raise self.InvalidCmd('No run name currently define. Please add this information.')
342
343 if len(arg) == 1 and self.run_name == arg[0]:
344 arg.pop(0)
345
346 filepath = None
347 if not len(arg):
348 prev_tag = self.set_run_name(self.run_name, tag, 'delphes')
349 paths = [pjoin(self.me_dir,'Events',self.run_name, '%(tag)s_pythia_events.hep.gz'),
350 pjoin(self.me_dir,'Events',self.run_name, '%(tag)s_pythia8_events.hepmc.gz'),
351 pjoin(self.me_dir,'Events',self.run_name, '%(tag)s_pythia_events.hep'),
352 pjoin(self.me_dir,'Events',self.run_name, '%(tag)s_pythia8_events.hepmc'),
353 pjoin(self.me_dir,'Events','pythia_events.hep'),
354 pjoin(self.me_dir,'Events','pythia_events.hepmc'),
355 pjoin(self.me_dir,'Events','pythia8_events.hep.gz'),
356 pjoin(self.me_dir,'Events','pythia8_events.hepmc.gz')
357 ]
358 for p in paths:
359 if os.path.exists(p % {'tag': prev_tag}):
360 filepath = p % {'tag': prev_tag}
361 break
362 else:
363 a = raw_input("NO INPUT")
364 if nodefault:
365 return False
366 else:
367 self.help_pgs()
368 raise self.InvalidCmd('''No file file pythia_events.* currently available
369 Please specify a valid run_name''')
370
371 if len(arg) == 1:
372 prev_tag = self.set_run_name(arg[0], tag, 'delphes')
373 if os.path.exists(pjoin(self.me_dir,'Events',self.run_name, '%s_pythia_events.hep.gz' % prev_tag)):
374 filepath = pjoin(self.me_dir,'Events',self.run_name, '%s_pythia_events.hep.gz' % prev_tag)
375 elif os.path.exists(pjoin(self.me_dir,'Events',self.run_name, '%s_pythia8_events.hepmc.gz' % prev_tag)):
376 filepath = pjoin(self.me_dir,'Events',self.run_name, '%s_pythia8_events.hepmc.gz' % prev_tag)
377 elif os.path.exists(pjoin(self.me_dir,'Events',self.run_name, '%s_pythia_events.hep' % prev_tag)):
378 filepath = pjoin(self.me_dir,'Events',self.run_name, '%s_pythia_events.hep.gz' % prev_tag)
379 elif os.path.exists(pjoin(self.me_dir,'Events',self.run_name, '%s_pythia8_events.hepmc' % prev_tag)):
380 filepath = pjoin(self.me_dir,'Events',self.run_name, '%s_pythia8_events.hepmc.gz' % prev_tag)
381 else:
382 raise self.InvalidCmd('No events file corresponding to %s run with tag %s.:%s '\
383 % (self.run_name, prev_tag,
384 pjoin(self.me_dir,'Events',self.run_name, '%s_pythia_events.hep.gz' % prev_tag)))
385 else:
386 if tag:
387 self.run_card['run_tag'] = tag
388 self.set_run_name(self.run_name, tag, 'delphes')
389
390 return filepath
391
392
393
394
395
396
397
399 """ check the validity of the line """
400
401 if len(args) != 1:
402 self.help_open()
403 raise self.InvalidCmd('OPEN command requires exactly one argument')
404
405 if args[0].startswith('./'):
406 if not os.path.isfile(args[0]):
407 raise self.InvalidCmd('%s: not such file' % args[0])
408 return True
409
410
411 if not self.me_dir:
412 if not os.path.isfile(args[0]):
413 self.help_open()
414 raise self.InvalidCmd('No MadEvent path defined. Unable to associate this name to a file')
415 else:
416 return True
417
418 path = self.me_dir
419 if os.path.isfile(os.path.join(path,args[0])):
420 args[0] = os.path.join(path,args[0])
421 elif os.path.isfile(os.path.join(path,'Cards',args[0])):
422 args[0] = os.path.join(path,'Cards',args[0])
423 elif os.path.isfile(os.path.join(path,'HTML',args[0])):
424 args[0] = os.path.join(path,'HTML',args[0])
425
426 elif '_card.dat' in args[0]:
427 name = args[0].replace('_card.dat','_card_default.dat')
428 if os.path.isfile(os.path.join(path,'Cards', name)):
429 files.cp(os.path.join(path,'Cards', name), os.path.join(path,'Cards', args[0]))
430 args[0] = os.path.join(path,'Cards', args[0])
431 else:
432 raise self.InvalidCmd('No default path for this file')
433 elif not os.path.isfile(args[0]):
434 raise self.InvalidCmd('No default path for this file')
435
437 """check that treatcards arguments are valid
438 [param|run|all] [--output_dir=] [--param_card=] [--run_card=]
439 """
440
441 opt = {'output_dir':pjoin(self.me_dir,'Source'),
442 'param_card':pjoin(self.me_dir,'Cards','param_card.dat'),
443 'run_card':pjoin(self.me_dir,'Cards','run_card.dat')}
444 mode = 'all'
445 for arg in args:
446 if arg.startswith('--') and '=' in arg:
447 key,value =arg[2:].split('=',1)
448 if not key in opt:
449 self.help_treatcards()
450 raise self.InvalidCmd('Invalid option for treatcards command:%s ' \
451 % key)
452 if key in ['param_card', 'run_card']:
453 if os.path.isfile(value):
454 card_name = self.detect_card_type(value)
455 if card_name != key:
456 raise self.InvalidCmd('Format for input file detected as %s while expecting %s'
457 % (card_name, key))
458 opt[key] = value
459 elif os.path.isfile(pjoin(self.me_dir,value)):
460 card_name = self.detect_card_type(pjoin(self.me_dir,value))
461 if card_name != key:
462 raise self.InvalidCmd('Format for input file detected as %s while expecting %s'
463 % (card_name, key))
464 opt[key] = value
465 else:
466 raise self.InvalidCmd('No such file: %s ' % value)
467 elif key in ['output_dir']:
468 if os.path.isdir(value):
469 opt[key] = value
470 elif os.path.isdir(pjoin(self.me_dir,value)):
471 opt[key] = pjoin(self.me_dir, value)
472 else:
473 raise self.InvalidCmd('No such directory: %s' % value)
474 elif arg in ['MadLoop','param','run','all']:
475 mode = arg
476 else:
477 self.help_treatcards()
478 raise self.InvalidCmd('Unvalid argument %s' % arg)
479
480 return mode, opt
481
483 """Check the argument for decay_events command
484 syntax is "decay_events [NAME]"
485 Note that other option are already remove at this point
486 """
487
488 opts = []
489 if '-from_cards' in args:
490 args.remove('-from_cards')
491 opts.append('-from_cards')
492
493 if len(args) == 0:
494 if self.run_name:
495 args.insert(0, self.run_name)
496 elif self.results.lastrun:
497 args.insert(0, self.results.lastrun)
498 else:
499 raise self.InvalidCmd('No run name currently defined. Please add this information.')
500 return
501
502 if args[0] != self.run_name:
503 self.set_run_name(args[0])
504
505 args[0] = self.get_events_path(args[0])
506
507 args += opts
508
510 """Check the argument for decay_events command
511 syntax is "decay_events [NAME]"
512 Note that other option are already remove at this point
513 """
514
515 if len(args) == 0:
516 if self.run_name:
517 args.insert(0, self.run_name)
518 elif self.results.lastrun:
519 args.insert(0, self.results.lastrun)
520 else:
521 raise self.InvalidCmd('No run name currently defined. Please add this information.')
522 return
523
524 if args[0] and os.path.isfile(args[0]):
525 pass
526 else:
527 if args[0] != self.run_name:
528 self.set_run_name(args[0], allow_new_tag=False)
529
530 args[0] = self.get_events_path(args[0])
531
532
534 """return the path to the output events
535 """
536
537 if self.mode == 'madevent':
538 possible_path = [
539 pjoin(self.me_dir,'Events', run_name, 'unweighted_events.lhe.gz'),
540 pjoin(self.me_dir,'Events', run_name, 'unweighted_events.lhe')]
541 else:
542 possible_path = [
543 pjoin(self.me_dir,'Events', run_name, 'events.lhe.gz'),
544 pjoin(self.me_dir,'Events', run_name, 'events.lhe')]
545
546 for path in possible_path:
547 if os.path.exists(path):
548 correct_path = path
549 break
550 else:
551 if os.path.exists(run_name):
552 correct_path = run_name
553 else:
554 raise self.InvalidCmd('No events file corresponding to %s run. ' % run_name)
555 return correct_path
556
563
564
565
566
567 -class CommonRunCmd(HelpToCmd, CheckValidForCmd, cmd.Cmd):
568
569 debug_output = 'ME5_debug'
570 helporder = ['Main Commands', 'Documented commands', 'Require MG5 directory',
571 'Advanced commands']
572
573
574
575 options_configuration = {'pythia8_path': './pythia8',
576 'hwpp_path': './herwigPP',
577 'thepeg_path': './thepeg',
578 'hepmc_path': './hepmc',
579 'madanalysis_path': './MadAnalysis',
580 'madanalysis5_path': './HEPTools/madanalysis5',
581 'pythia-pgs_path':'./pythia-pgs',
582 'td_path':'./td',
583 'delphes_path':'./Delphes',
584 'exrootanalysis_path':'./ExRootAnalysis',
585 'syscalc_path': './SysCalc',
586 'lhapdf': 'lhapdf-config',
587 'timeout': 60,
588 'f2py_compiler':None,
589 'web_browser':None,
590 'eps_viewer':None,
591 'text_editor':None,
592 'fortran_compiler':None,
593 'cpp_compiler': None,
594 'auto_update':7,
595 'cluster_type': 'condor',
596 'cluster_status_update': (600, 30),
597 'cluster_nb_retry':1,
598 'cluster_local_path': "/cvmfs/cp3.uclouvain.be/madgraph/",
599 'cluster_retry_wait':300}
600
601 options_madgraph= {'stdout_level':None}
602
603 options_madevent = {'automatic_html_opening':True,
604 'notification_center':True,
605 'run_mode':2,
606 'cluster_queue':None,
607 'cluster_time':None,
608 'cluster_size':100,
609 'cluster_memory':None,
610 'nb_core': None,
611 'cluster_temp_path':None}
612
613
614 - def __init__(self, me_dir, options, *args, **opts):
615 """common"""
616
617 self.force_run = False
618 if 'force_run' in opts and opts['force_run']:
619 self.force_run = True
620 del opts['force_run']
621
622 cmd.Cmd.__init__(self, *args, **opts)
623
624 if me_dir is None and MADEVENT:
625 me_dir = root_path
626
627 if os.path.isabs(me_dir):
628 self.me_dir = me_dir
629 else:
630 self.me_dir = pjoin(os.getcwd(),me_dir)
631
632 self.options = options
633
634 self.param_card_iterator = []
635
636
637 self.status = pjoin(self.me_dir, 'status')
638 self.error = pjoin(self.me_dir, 'error')
639 self.dirbin = pjoin(self.me_dir, 'bin', 'internal')
640
641
642 if not self.force_run:
643 if os.path.exists(pjoin(me_dir,'RunWeb')):
644 message = '''Another instance of the program is currently running.
645 (for this exact same directory) Please wait that this is instance is
646 closed. If no instance is running, you can delete the file
647 %s and try again.''' % pjoin(me_dir,'RunWeb')
648 raise AlreadyRunning, message
649 else:
650 pid = os.getpid()
651 fsock = open(pjoin(me_dir,'RunWeb'),'w')
652 fsock.write(`pid`)
653 fsock.close()
654
655 misc.Popen([os.path.relpath(pjoin(self.dirbin, 'gen_cardhtml-pl'), me_dir)],
656 cwd=me_dir)
657
658 self.to_store = []
659 self.run_name = None
660 self.run_tag = None
661 self.banner = None
662
663 self.set_configuration()
664 self.configure_run_mode(self.options['run_mode'])
665
666
667 self.get_characteristics()
668
669 if not self.proc_characteristics['ninitial']:
670
671 nexternal = open(pjoin(self.me_dir,'Source','nexternal.inc')).read()
672 found = re.search("PARAMETER\s*\(NINCOMING=(\d)\)", nexternal)
673 self.ninitial = int(found.group(1))
674 else:
675 self.ninitial = self.proc_characteristics['ninitial']
676
677
678
712
713
714 @misc.multiple_try(nb_try=5, sleep=2)
716 """load the current results status"""
717
718
719 if os.path.exists(pjoin(self.me_dir,'HTML','results.pkl')):
720 try:
721 self.results = save_load_object.load_from_file(pjoin(self.me_dir,'HTML','results.pkl'))
722 except Exception:
723
724 model = self.find_model_name()
725 process = self.process
726 self.results = gen_crossxhtml.AllResults(model, process, self.me_dir)
727 self.results.resetall(self.me_dir)
728 else:
729 try:
730 self.results.resetall(self.me_dir)
731 except Exception, error:
732 logger.debug(error)
733
734 model = self.find_model_name()
735 process = self.process
736 self.results = gen_crossxhtml.AllResults(model, process, self.me_dir)
737 self.results.resetall(self.me_dir)
738 self.last_mode = ''
739 try:
740 self.last_mode = self.results[self.results.lastrun][-1]['run_mode']
741 except:
742 self.results.resetall(self.me_dir)
743 self.last_mode = ''
744
745 else:
746 model = self.find_model_name()
747 process = self.process
748 self.results = gen_crossxhtml.AllResults(model, process, self.me_dir)
749 self.results.resetall(self.me_dir)
750 self.last_mode=''
751
752 return self.results
753
754
756 """Advanced commands: create .inc files from param_card.dat/run_card.dat"""
757
758 keepwidth = False
759 if '--keepwidth' in line:
760 keepwidth = True
761 line = line.replace('--keepwidth', '')
762 args = self.split_arg(line)
763 mode, opt = self.check_treatcards(args)
764
765 if mode in ['run', 'all']:
766 if not hasattr(self, 'run_card'):
767 if amcatnlo:
768 run_card = banner_mod.RunCardNLO(opt['run_card'])
769 else:
770 run_card = banner_mod.RunCard(opt['run_card'])
771 else:
772 run_card = self.run_card
773
774
775 if amcatnlo and run_card['pdlabel']=='lhapdf':
776 pdfsetsdir=self.get_lhapdf_pdfsetsdir()
777 pdfsets=self.get_lhapdf_pdfsets_list(pdfsetsdir)
778 lhapdfsetname=[]
779 for lhaid in run_card['lhaid']:
780 if lhaid in pdfsets:
781 lhapdfsetname.append(pdfsets[lhaid]['filename'])
782 else:
783 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))
784 run_card['lhapdfsetname']=lhapdfsetname
785 run_card.write_include_file(opt['output_dir'])
786
787 if mode in ['MadLoop', 'all']:
788 if os.path.exists(pjoin(self.me_dir, 'Cards', 'MadLoopParams.dat')):
789 self.MadLoopparam = banner_mod.MadLoopParam(pjoin(self.me_dir,
790 'Cards', 'MadLoopParams.dat'))
791
792 self.MadLoopparam.write(pjoin(self.me_dir,"SubProcesses",
793 "MadLoopParams.dat"))
794
795 if mode in ['param', 'all']:
796 if os.path.exists(pjoin(self.me_dir, 'Source', 'MODEL', 'mp_coupl.inc')):
797 param_card = check_param_card.ParamCardMP(opt['param_card'])
798 else:
799 param_card = check_param_card.ParamCard(opt['param_card'])
800 outfile = pjoin(opt['output_dir'], 'param_card.inc')
801 ident_card = pjoin(self.me_dir,'Cards','ident_card.dat')
802 if os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')):
803 default = pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')
804 elif os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')):
805 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
806 elif not os.path.exists(pjoin(self.me_dir,'bin','internal','ufomodel')):
807 fsock = open(pjoin(self.me_dir,'Source','param_card.inc'),'w')
808 fsock.write(' ')
809 fsock.close()
810 return
811 else:
812 subprocess.call(['python', 'write_param_card.py'],
813 cwd=pjoin(self.me_dir,'bin','internal','ufomodel'))
814 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')
815
816
817 if amcatnlo and not keepwidth:
818
819 pids = self.get_pid_final_initial_states()
820
821 if not MADEVENT and pjoin(self.me_dir,'bin','internal') not in sys.path:
822 sys.path.insert(0,pjoin(self.me_dir,'bin','internal'))
823
824
825
826 to_del = [name for name in sys.modules.keys()
827 if name.startswith('internal.ufomodel')
828 or name.startswith('ufomodel')]
829 for name in to_del:
830 del(sys.modules[name])
831
832 import ufomodel as ufomodel
833 zero = ufomodel.parameters.ZERO
834 no_width = [p for p in ufomodel.all_particles
835 if (str(p.pdg_code) in pids or str(-p.pdg_code) in pids)
836 and p.color != 1 and p.width != zero]
837 done = []
838 for part in no_width:
839 if abs(part.pdg_code) in done:
840 continue
841 done.append(abs(part.pdg_code))
842 param = param_card['decay'].get((part.pdg_code,))
843
844 if param.value != 0:
845 logger.info('''For gauge cancellation, the width of \'%s\' has been set to zero.'''\
846 % part.name,'$MG:color:BLACK')
847 param.value = 0
848
849 param_card.write_inc_file(outfile, ident_card, default)
850
852 """return the model related to this process"""
853
854 if self.options['mg5_path']:
855 sys.path.append(self.options['mg5_path'])
856 import models.import_ufo as import_ufo
857 complexmass = self.proc_characteristics['complex_mass_scheme']
858 with misc.MuteLogger(['madgraph.model'],[50]):
859 out= import_ufo.import_model(pjoin(self.me_dir,'bin','internal','ufomodel'),
860 complex_mass_scheme=complexmass)
861 return out
862
863
864
865 else:
866 return None
867
868 - def ask_edit_cards(self, cards, mode='fixed', plot=True, first_cmd=None):
869 """ """
870 if not self.options['madanalysis_path']:
871 plot = False
872
873 self.ask_edit_card_static(cards, mode, plot, self.options['timeout'],
874 self.ask, first_cmd=first_cmd)
875
876 @staticmethod
879 if not ask:
880 ask = CommonRunCmd.ask
881
882 def path2name(path):
883 if '_card' in path:
884 return path.split('_card')[0]
885 elif path == 'delphes_trigger.dat':
886 return 'trigger'
887 elif path == 'input.lhco':
888 return 'lhco'
889 elif path == 'MadLoopParams.dat':
890 return 'MadLoopParams'
891 else:
892 raise Exception, 'Unknow cards name %s' % path
893
894
895
896 question = """Do you want to edit a card (press enter to bypass editing)?\n"""
897 possible_answer = ['0', 'done']
898 card = {0:'done'}
899
900 indent = max(len(path2name(card_name)) for card_name in cards)
901 question += '/'+'-'*60+'\\\n'
902 for i, card_name in enumerate(cards):
903 imode = path2name(card_name)
904 possible_answer.append(i+1)
905 possible_answer.append(imode)
906 question += '| %-77s|\n'%((' \x1b[31m%%s\x1b[0m. %%-%ds : \x1b[32m%%s\x1b[0m'%indent)%(i+1, imode, card_name))
907 card[i+1] = imode
908
909 if plot and not 'plot_card.dat' in cards:
910 question += '| %-77s|\n'%((' \x1b[31m9\x1b[0m. %%-%ds : \x1b[32mplot_card.dat\x1b[0m'%indent) % 'plot')
911 possible_answer.append(9)
912 possible_answer.append('plot')
913 card[9] = 'plot'
914
915 question += '\\'+'-'*60+'/\n'
916
917 if 'param_card.dat' in cards:
918
919 question += ' you can also\n'
920 question += ' - enter the path to a valid card or banner.\n'
921 question += ' - use the \'set\' command to modify a parameter directly.\n'
922 question += ' The set option works only for param_card and run_card.\n'
923 question += ' Type \'help set\' for more information on this command.\n'
924 question += ' - call an external program (ASperGE/MadWidth/...).\n'
925 question += ' Type \'help\' for the list of available command\n'
926 else:
927 question += ' you can also\n'
928 question += ' - enter the path to a valid card.\n'
929 if 'transfer_card.dat' in cards:
930 question += ' - use the \'change_tf\' command to set a transfer functions.\n'
931
932 out = 'to_run'
933 while out not in ['0', 'done']:
934 out = ask(question, '0', possible_answer, timeout=int(1.5*timeout),
935 path_msg='enter path', ask_class = AskforEditCard,
936 cards=cards, mode=mode, **opt)
937
938 @staticmethod
940 """detect the type of the card. Return value are
941 banner
942 param_card.dat
943 run_card.dat
944 pythia_card.dat
945 pythia8_card.dat
946 plot_card.dat
947 pgs_card.dat
948 delphes_card.dat
949 delphes_trigger.dat
950 shower_card.dat [aMCatNLO]
951 FO_analyse_card.dat [aMCatNLO]
952 madspin_card.dat [MS]
953 transfer_card.dat [MW]
954 madweight_card.dat [MW]
955 madanalysis5_hadron_card.dat
956 madanalysis5_parton_card.dat
957
958 Please update the unit-test: test_card_type_recognition when adding
959 cards.
960 """
961
962 fulltext = open(path).read(50000)
963 if fulltext == '':
964 logger.warning('File %s is empty' % path)
965 return 'unknown'
966
967 to_search = ['<MGVersion>',
968 '<mg5proccard>'
969 'ParticlePropagator',
970 'ExecutionPath',
971 'Treewriter',
972 'CEN_max_tracker',
973 '#TRIGGER CARD',
974 'parameter set name',
975 'muon eta coverage',
976 'req_acc_FO',
977 'MSTP',
978 'b_stable',
979 'FO_ANALYSIS_FORMAT',
980 'MSTU',
981 'Begin Minpts',
982 'gridpack',
983 'ebeam1',
984 'block\s+mw_run',
985 'BLOCK',
986 'DECAY',
987 'launch',
988 'madspin',
989 'transfer_card\.dat',
990 'set',
991 'main:numberofevents',
992 '@MG5aMC skip_analysis',
993 '@MG5aMC\s*inputs\s*=\s*\*\.(?:hepmc|lhe)',
994 '@MG5aMC\s*reconstruction_name',
995 '@MG5aMC'
996 ]
997
998
999 text = re.findall('(%s)' % '|'.join(to_search), fulltext, re.I)
1000 text = [t.lower() for t in text]
1001 if '<mgversion>' in text or '<mg5proccard>' in text:
1002 return 'banner'
1003 elif 'particlepropagator' in text or 'executionpath' in text or 'treewriter' in text:
1004 return 'delphes_card.dat'
1005 elif 'cen_max_tracker' in text:
1006 return 'delphes_card.dat'
1007 elif '@mg5amc' in text:
1008 ma5_flag = [f[7:].strip() for f in text if f.startswith('@mg5amc')]
1009 if any(f.startswith('reconstruction_name') for f in ma5_flag):
1010 return 'madanalysis5_hadron_card.dat'
1011 ma5_flag = [f.split('*.')[1] for f in ma5_flag if '*.' in f]
1012 if any(f.startswith('lhe') for f in ma5_flag):
1013 return 'madanalysis5_parton_card.dat'
1014 if any(f.startswith(('hepmc','hep','stdhep','lhco')) for f in ma5_flag):
1015 return 'madanalysis5_hadron_card.dat'
1016 else:
1017 return 'unknown'
1018 elif '#trigger card' in text:
1019 return 'delphes_trigger.dat'
1020 elif 'parameter set name' in text:
1021 return 'pgs_card.dat'
1022 elif 'muon eta coverage' in text:
1023 return 'pgs_card.dat'
1024 elif 'mstp' in text and not 'b_stable' in text:
1025 return 'pythia_card.dat'
1026 elif 'begin minpts' in text:
1027 return 'plot_card.dat'
1028 elif ('gridpack' in text and 'ebeam1' in text) or \
1029 ('req_acc_fo' in text and 'ebeam1' in text):
1030 return 'run_card.dat'
1031 elif any(t.endswith('mw_run') for t in text):
1032 return 'madweight_card.dat'
1033 elif 'transfer_card.dat' in text:
1034 return 'transfer_card.dat'
1035 elif 'block' in text and 'decay' in text:
1036 return 'param_card.dat'
1037 elif 'b_stable' in text:
1038 return 'shower_card.dat'
1039 elif 'fo_analysis_format' in text:
1040 return 'FO_analyse_card.dat'
1041 elif 'main:numberofevents' in text:
1042 return 'pythia8_card.dat'
1043 elif 'launch' in text:
1044
1045
1046 if 'madspin' in text:
1047 return 'madspin_card.dat'
1048 if 'decay' in text:
1049
1050 if re.search("(^|;)\s*decay", fulltext):
1051 return 'madspin_card.dat'
1052 else:
1053 return 'reweight_card.dat'
1054 else:
1055 return 'reweight_card.dat'
1056 else:
1057 return 'unknown'
1058
1059
1060
1062 """create automatically a tag"""
1063
1064 used_tags = [r['tag'] for r in self.results[self.run_name]]
1065 i=0
1066 while 1:
1067 i+=1
1068 if 'tag_%s' %i not in used_tags:
1069 return 'tag_%s' % i
1070
1071
1072
1073 @misc.mute_logger(names=['madgraph.various.histograms',
1074 'internal.histograms'],levels=[20,20])
1078 """Generated the HwU plots from Pythia8 driver output for a specific
1079 observable."""
1080
1081
1082 if not os.path.isfile(data_path):
1083 return False
1084
1085
1086 histos = histograms.HwUList(data_path, consider_reweights='ALL',run_id=0)
1087 if len(histos)==0:
1088 return False
1089
1090
1091 merging_scales_available = [label[1] for label in \
1092 histos[0].bins.weight_labels if
1093 histograms.HwU.get_HwU_wgt_label_type(label)=='merging_scale']
1094 if len(merging_scales_available)>=2:
1095 min_merging_scale = min(merging_scales_available)
1096 max_merging_scale = max(merging_scales_available)
1097 else:
1098 min_merging_scale = None
1099 max_merging_scale = None
1100
1101
1102 histo_output_options = {
1103 'format':'gnuplot',
1104 'uncertainties':['scale','pdf','statistical',
1105 'merging_scale','alpsfact'],
1106 'ratio_correlations':True,
1107 'arg_string':'Automatic plotting from MG5aMC',
1108 'jet_samples_to_keep':None,
1109 'use_band':['merging_scale','alpsfact'],
1110 'auto_open':False
1111 }
1112
1113 if not (int(self.run_card['ickkw'])==1):
1114 histo_output_options['uncertainties'].pop(
1115 histo_output_options['uncertainties'].index('alpsfact'))
1116 histo_output_options['use_band'].pop(
1117 histo_output_options['use_band'].index('alpsfact'))
1118
1119 histos.output(pjoin(plot_root_path,
1120 'central_%s_%s_plots'%(merging_scale_name,observable_name)),
1121 **histo_output_options)
1122
1123 for scale in merging_scales_available:
1124 that_scale_histos = histograms.HwUList(
1125 data_path, run_id=0, merging_scale=scale)
1126 that_scale_histos.output(pjoin(plot_root_path,
1127 '%s_%.3g_%s_plots'%(merging_scale_name,scale,observable_name)),
1128 **histo_output_options)
1129
1130
1131
1132
1133 if not min_merging_scale is None:
1134 min_scale_histos = histograms.HwUList(data_path,
1135 consider_reweights=[], run_id=0,
1136 merging_scale=min_merging_scale)
1137 max_scale_histos = histograms.HwUList(data_path,
1138 consider_reweights=[], run_id=0,
1139 merging_scale=max_merging_scale)
1140
1141
1142 for histo in min_scale_histos:
1143 if histo.type is None:
1144 histo.type = '%s=%.4g'%(merging_scale_name, min_merging_scale)
1145 else:
1146 histo.type += '|%s=%.4g'%(merging_scale_name, min_merging_scale)
1147 for histo in max_scale_histos:
1148 if histo.type is None:
1149 histo.type = '%s=%.4g'%(merging_scale_name, max_merging_scale)
1150 else:
1151 histo.type += '|%s=%.4g'%(merging_scale_name, max_merging_scale)
1152
1153
1154 histograms.HwUList(min_scale_histos+max_scale_histos).output(
1155 pjoin(plot_root_path,'min_max_%s_%s_comparison'
1156 %(merging_scale_name,observable_name)),
1157 format='gnuplot',
1158 uncertainties=[],
1159 ratio_correlations=True,
1160 arg_string='Automatic plotting from MG5aMC',
1161 jet_samples_to_keep=[],
1162 use_band=[],
1163 auto_open=False)
1164 return True
1165
1166 - def create_plot(self, mode='parton', event_path=None, output=None, tag=None):
1167 """create the plot"""
1168
1169 if not tag:
1170 tag = self.run_card['run_tag']
1171
1172 if mode != 'Pythia8':
1173 madir = self.options['madanalysis_path']
1174 td = self.options['td_path']
1175
1176 if not madir or not td or \
1177 not os.path.exists(pjoin(self.me_dir, 'Cards', 'plot_card.dat')):
1178 return False
1179 else:
1180 PY8_plots_root_path = pjoin(self.me_dir,'HTML',
1181 self.run_name,'%s_PY8_plots'%tag)
1182
1183 if 'ickkw' in self.run_card:
1184 if int(self.run_card['ickkw']) and mode == 'Pythia':
1185 self.update_status('Create matching plots for Pythia', level='pythia')
1186
1187 if not os.path.exists(pjoin(self.me_dir,'Events','events.tree')):
1188 misc.gunzip(pjoin(self.me_dir,'Events',
1189 self.run_name, '%s_pythia_events.tree.gz' % tag), keep=True,
1190 stdout=pjoin(self.me_dir,'Events','events.tree'))
1191 files.mv(pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_xsecs.tree'),
1192 pjoin(self.me_dir,'Events','xsecs.tree'))
1193
1194
1195 misc.call([self.dirbin+'/create_matching_plots.sh',
1196 self.run_name, tag, madir],
1197 stdout = os.open(os.devnull, os.O_RDWR),
1198 cwd=pjoin(self.me_dir,'Events'))
1199
1200
1201 misc.gzip(pjoin(self.me_dir,"Events","events.tree"),
1202 stdout=pjoin(self.me_dir,'Events',self.run_name, tag + '_pythia_events.tree.gz'))
1203 files.mv(pjoin(self.me_dir,'Events','xsecs.tree'),
1204 pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_xsecs.tree'))
1205
1206 elif mode == 'Pythia8' and (int(self.run_card['ickkw'])==1 or \
1207 self.run_card['ktdurham']>0.0 or self.run_card['ptlund']>0.0):
1208
1209 self.update_status('Create matching plots for Pythia8',
1210 level='pythia8')
1211
1212
1213 if not os.path.isdir(PY8_plots_root_path):
1214 os.makedirs(PY8_plots_root_path)
1215
1216 merging_scale_name = 'qCut' if int(self.run_card['ickkw'])==1 \
1217 else 'TMS'
1218
1219 djr_path = pjoin(self.me_dir,'Events',
1220 self.run_name, '%s_djrs.dat' % tag)
1221 pt_path = pjoin(self.me_dir,'Events',
1222 self.run_name, '%s_pts.dat' % tag)
1223 for observable_name, data_path in [('djr',djr_path),
1224 ('pt',pt_path)]:
1225 if not self.generate_Pythia8_HwU_plots(
1226 PY8_plots_root_path, merging_scale_name,
1227 observable_name,data_path):
1228 return False
1229
1230 if mode == 'Pythia8':
1231 plot_files = glob.glob(pjoin(PY8_plots_root_path,'*.gnuplot'))
1232 if not misc.which('gnuplot'):
1233 logger.warning("Install gnuplot to be able to view the plots"+\
1234 " generated at :\n "+\
1235 '\n '.join('%s.gnuplot'%p for p in plot_files))
1236 return True
1237 for plot in plot_files:
1238 command = ['gnuplot',plot]
1239 try:
1240 subprocess.call(command,cwd=PY8_plots_root_path,stderr=subprocess.PIPE)
1241 except Exception as e:
1242 logger.warning("Automatic processing of the Pythia8 "+\
1243 "merging plots with gnuplot failed. Try the"+\
1244 " following command by hand:\n %s"%(' '.join(command))+\
1245 "\nException was: %s"%str(e))
1246 return False
1247
1248 plot_files = glob.glob(pjoin(PY8_plots_root_path,'*.pdf'))
1249 if len(plot_files)>0:
1250
1251 html = "<html>\n<head>\n<TITLE>PLOT FOR PYTHIA8</TITLE>"
1252 html+= '<link rel=stylesheet href="../../mgstyle.css" type="text/css">\n</head>\n<body>\n'
1253 html += "<h2> Plot for Pythia8 </h2>\n"
1254 html += '<a href=../../../crossx.html>return to summary</a><br>'
1255 html += "<table>\n<tr> <td> <b>Obs.</b> </td> <td> <b>Type of plot</b> </td> <td><b> PDF</b> </td> <td><b> input file</b> </td> </tr>\n"
1256 def sorted_plots(elem):
1257 name = os.path.basename(elem[1])
1258 if 'central' in name:
1259 return -100
1260 if 'min_max' in name:
1261 return -10
1262 merging_re = re.match(r'^.*_(\d+)_.*$',name)
1263 if not merging_re is None:
1264 return int(merging_re.group(1))
1265 else:
1266 return 1e10
1267 djr_plot_files = sorted(
1268 (('DJR',p) for p in plot_files if '_djr_' in p),
1269 key = sorted_plots)
1270 pt_plot_files = sorted(
1271 (('Pt',p) for p in plot_files if '_pt_' in p),
1272 key = sorted_plots)
1273 last_obs = None
1274 for obs, one_plot in djr_plot_files+pt_plot_files:
1275 if obs!=last_obs:
1276
1277 html += "<tr><td></td></tr>"
1278 last_obs = obs
1279 name = os.path.basename(one_plot).replace('.pdf','')
1280 short_name = name
1281 for dummy in ['_plots','_djr','_pt']:
1282 short_name = short_name.replace(dummy,'')
1283 short_name = short_name.replace('_',' ')
1284 if 'min max' in short_name:
1285 short_name = "%s comparison with min/max merging scale"%obs
1286 if 'central' in short_name:
1287 short_name = "Merging uncertainty band around central scale"
1288 html += "<tr><td>%(obs)s</td><td>%(sn)s</td><td> <a href=./%(n)s.pdf>PDF</a> </td><td> <a href=./%(n)s.HwU>HwU</a> <a href=./%(n)s.gnuplot>GNUPLOT</a> </td></tr>\n" %\
1289 {'obs':obs, 'sn': short_name, 'n': name}
1290 html += '</table>\n'
1291 html += '<a href=../../../bin/internal/plot_djrs.py> Example of code to plot the above with matplotlib </a><br><br>'
1292 html+='</body>\n</html>'
1293 ff=open(pjoin(PY8_plots_root_path, 'index.html'),'w')
1294 ff.write(html)
1295 return True
1296
1297 if not event_path:
1298 if mode == 'parton':
1299 possibilities=[
1300 pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'),
1301 pjoin(self.me_dir, 'Events', 'unweighted_events.lhe.gz'),
1302 pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe'),
1303 pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe.gz')]
1304 for event_path in possibilities:
1305 if os.path.exists(event_path):
1306 break
1307 output = pjoin(self.me_dir, 'HTML',self.run_name, 'plots_parton.html')
1308
1309 elif mode == 'Pythia':
1310 event_path = pjoin(self.me_dir, 'Events','pythia_events.lhe')
1311 output = pjoin(self.me_dir, 'HTML',self.run_name,
1312 'plots_pythia_%s.html' % tag)
1313 elif mode == 'PGS':
1314 event_path = pjoin(self.me_dir, 'Events', self.run_name,
1315 '%s_pgs_events.lhco' % tag)
1316 output = pjoin(self.me_dir, 'HTML',self.run_name,
1317 'plots_pgs_%s.html' % tag)
1318 elif mode == 'Delphes':
1319 event_path = pjoin(self.me_dir, 'Events', self.run_name,'%s_delphes_events.lhco' % tag)
1320 output = pjoin(self.me_dir, 'HTML',self.run_name,
1321 'plots_delphes_%s.html' % tag)
1322 elif mode == "shower":
1323 event_path = pjoin(self.me_dir, 'Events','pythia_events.lhe')
1324 output = pjoin(self.me_dir, 'HTML',self.run_name,
1325 'plots_shower_%s.html' % tag)
1326 if not self.options['pythia-pgs_path']:
1327 return
1328 else:
1329 raise self.InvalidCmd, 'Invalid mode %s' % mode
1330 elif mode == 'reweight' and not output:
1331 output = pjoin(self.me_dir, 'HTML',self.run_name,
1332 'plots_%s.html' % tag)
1333
1334 if not os.path.exists(event_path):
1335 if os.path.exists(event_path+'.gz'):
1336 misc.gunzip('%s.gz' % event_path)
1337 else:
1338 raise self.InvalidCmd, 'Events file %s does not exist' % event_path
1339 elif event_path.endswith(".gz"):
1340 misc.gunzip(event_path)
1341 event_path = event_path[:-3]
1342
1343
1344 self.update_status('Creating Plots for %s level' % mode, level = mode.lower())
1345
1346 mode = mode.lower()
1347 if mode not in ['parton', 'reweight']:
1348 plot_dir = pjoin(self.me_dir, 'HTML', self.run_name,'plots_%s_%s' % (mode.lower(),tag))
1349 elif mode == 'parton':
1350 plot_dir = pjoin(self.me_dir, 'HTML', self.run_name,'plots_parton')
1351 else:
1352 plot_dir =pjoin(self.me_dir, 'HTML', self.run_name,'plots_%s' % (tag))
1353
1354 if not os.path.isdir(plot_dir):
1355 os.makedirs(plot_dir)
1356
1357 files.ln(pjoin(self.me_dir, 'Cards','plot_card.dat'), plot_dir, 'ma_card.dat')
1358
1359 try:
1360 proc = misc.Popen([os.path.join(madir, 'plot_events')],
1361 stdout = open(pjoin(plot_dir, 'plot.log'),'w'),
1362 stderr = subprocess.STDOUT,
1363 stdin=subprocess.PIPE,
1364 cwd=plot_dir)
1365 proc.communicate('%s\n' % event_path)
1366 del proc
1367
1368 misc.call(['%s/plot' % self.dirbin, madir, td],
1369 stdout = open(pjoin(plot_dir, 'plot.log'),'a'),
1370 stderr = subprocess.STDOUT,
1371 cwd=plot_dir)
1372
1373 misc.call(['%s/plot_page-pl' % self.dirbin,
1374 os.path.basename(plot_dir),
1375 mode],
1376 stdout = open(pjoin(plot_dir, 'plot.log'),'a'),
1377 stderr = subprocess.STDOUT,
1378 cwd=pjoin(self.me_dir, 'HTML', self.run_name))
1379
1380 shutil.move(pjoin(self.me_dir, 'HTML',self.run_name ,'plots.html'),
1381 output)
1382
1383 logger.info("Plots for %s level generated, see %s" % \
1384 (mode, output))
1385 except OSError, error:
1386 logger.error('fail to create plot: %s. Please check that MadAnalysis is correctly installed.' % error)
1387
1388 self.update_status('End Plots for %s level' % mode, level = mode.lower(),
1389 makehtml=False)
1390
1391 return True
1392
1394 """Run hep2lhe on the file Events/pythia_events.hep"""
1395
1396 if not self.options['pythia-pgs_path']:
1397 raise self.InvalidCmd, 'No pythia-pgs path defined'
1398
1399 pydir = pjoin(self.options['pythia-pgs_path'], 'src')
1400 eradir = self.options['exrootanalysis_path']
1401
1402
1403 if misc.is_executable(pjoin(pydir, 'hep2lhe')):
1404 self.update_status('Creating shower LHE File (for plot)', level='pythia')
1405
1406 out = open(pjoin(self.me_dir,'Events','pythia_events.lhe'), 'w')
1407
1408 out.writelines('<!--\n')
1409 out.writelines('# Warning! Never use this file for detector studies!\n')
1410 out.writelines('-->\n<!--\n')
1411 if banner_path:
1412 out.writelines(open(banner_path).read().replace('<LesHouchesEvents version="1.0">',''))
1413 out.writelines('\n-->\n')
1414 out.close()
1415
1416 self.cluster.launch_and_wait(self.dirbin+'/run_hep2lhe',
1417 argument= [pydir],
1418 cwd=pjoin(self.me_dir,'Events'),
1419 stdout=os.devnull)
1420
1421 logger.info('Warning! Never use this lhe file for detector studies!')
1422
1423 if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHEFConverter')):
1424 self.update_status('Creating Pythia LHE Root File', level='pythia')
1425 try:
1426 misc.call([eradir+'/ExRootLHEFConverter',
1427 'pythia_events.lhe',
1428 pjoin(self.run_name, '%s_pythia_lhe_events.root' % self.run_tag)],
1429 cwd=pjoin(self.me_dir,'Events'))
1430 except Exception, error:
1431 misc.sprint('ExRootLHEFConverter fails', str(error),
1432 log=logger)
1433 pass
1434
1436 """Dummy routine, to be overwritten by daughter classes"""
1437
1438 pass
1439
1440
1442 """help for systematics command"""
1443 logger.info("syntax: systematics RUN_NAME [OUTPUT] [options]",'$MG:color:BLACK')
1444 logger.info("-- Run the systematics run on the RUN_NAME run.")
1445 logger.info(" RUN_NAME can be a path to a lhef file.")
1446 logger.info(" OUTPUT can be the path to the output lhe file, otherwise the input file will be overwritten")
1447 logger.info("")
1448 logger.info("options: (values written are the default)", '$MG:color:BLACK')
1449 logger.info("")
1450 logger.info(" --mur=0.5,1,2 # specify the values for renormalisation scale variation")
1451 logger.info(" --muf=0.5,1,2 # specify the values for factorisation scale variation")
1452 logger.info(" --alps=1 # specify the values for MLM emission scale variation (LO only)")
1453 logger.info(" --dyn=-1,1,2,3,4 # specify the dynamical schemes to use.")
1454 logger.info(" # -1 is the one used by the sample.")
1455 logger.info(" # > 0 correspond to options of dynamical_scale_choice of the run_card.")
1456 logger.info(" --pdf=errorset # specify the pdfs to use for pdf variation. (see below)")
1457 logger.info(" --together=mur,muf,dyn # lists the parameter that must be varied simultaneously so as to ")
1458 logger.info(" # compute the weights for all combinations of their variations.")
1459 logger.info(" --from_card # use the information from the run_card (LO only).")
1460 logger.info("")
1461 logger.info(" Allowed value for the pdf options:", '$MG:color:BLACK')
1462 logger.info(" central : Do not perform any pdf variation" )
1463 logger.info(" errorset : runs over the all the members of the PDF set used to generate the events")
1464 logger.info(" 244800 : runs over the associated set and all its members")
1465 logger.info(" 244800@0 : runs over the central member of the associated set")
1466
1467 logger.info(" CT10 : runs over the associated set and all its members")
1468 logger.info(" CT10@0 : runs over the central member of the associated set")
1469 logger.info(" CT10@X : runs over the Xth member of the associated PDF set")
1470 logger.info(" XX,YY,ZZ : runs over the sets for XX,YY,ZZ (those three follows above syntax)")
1471
1473 """auto completion for the systematics command"""
1474
1475 args = self.split_arg(line[0:begidx], error=False)
1476 options = ['--mur=', '--muf=', '--pdf=', '--dyn=','--alps=','--together=','--from_card ']
1477
1478 if len(args) == 1 and os.path.sep not in text:
1479
1480 data = misc.glob(pjoin('*','*events.lhe*'), pjoin(self.me_dir, 'Events'))
1481 data = [n.rsplit('/',2)[1] for n in data]
1482 return self.list_completion(text, data, line)
1483 elif len(args)==1:
1484
1485 return self.path_completion(text,
1486 os.path.join('.',*[a for a in args \
1487 if a.endswith(os.path.sep)]))
1488 elif len(args)==2 and os.path.sep in args[1]:
1489
1490 return self.path_completion(text, '.')
1491
1492 elif not line.endswith(tuple(options)):
1493 return self.list_completion(text, options)
1494
1495
1496
1498 """ syntax is 'systematics [INPUT [OUTPUT]] OPTIONS'
1499 --mur=0.5,1,2
1500 --muf=0.5,1,2
1501 --alps=1
1502 --dyn=-1
1503 --together=mur,muf #can be repeated
1504
1505 #special options
1506 --from_card=
1507 """
1508
1509 lhapdf = misc.import_python_lhapdf(self.options['lhapdf'])
1510 if not lhapdf:
1511 logger.info('can not run systematics since can not link python to lhapdf')
1512 return
1513
1514 self.update_status('Running Systematics computation', level='parton')
1515 args = self.split_arg(line)
1516
1517 opts= []
1518 args = [a for a in args if not a.startswith('-') or opts.append(a)]
1519
1520
1521 if any(not o.startswith(('--mur=', '--muf=', '--alps=','--dyn=','--together=','--from_card','--pdf='))
1522 for o in opts):
1523 raise self.InvalidCmd, "command systematics called with invalid option syntax. Please retry."
1524
1525
1526 if len(args) == 0:
1527 if self.run_name:
1528 args[0] = self.run_name
1529 else:
1530 raise self.InvalidCmd, 'no default run. Please specify the run_name'
1531
1532 if args[0] != self.run_name:
1533 self.set_run_name(args[0])
1534
1535
1536 result_file= sys.stdout
1537 if not os.path.sep in args[0]:
1538 path = [pjoin(self.me_dir, 'Events', args[0], 'unweighted_events.lhe.gz'),
1539 pjoin(self.me_dir, 'Events', args[0], 'unweighted_events.lhe'),
1540 pjoin(self.me_dir, 'Events', args[0], 'events.lhe.gz'),
1541 pjoin(self.me_dir, 'Events', args[0], 'events.lhe')]
1542
1543 for p in path:
1544 if os.path.exists(p):
1545 nb_event = self.results[args[0]].get_current_info()['nb_event']
1546
1547
1548 if self.run_name != args[0]:
1549 tag = self.results[args[0]].tags[0]
1550 self.set_run_name(args[0], tag,'parton', False)
1551 result_file = open(pjoin(self.me_dir,'Events', self.run_name, 'parton_systematics.log'),'w')
1552 args[0] = p
1553 break
1554 else:
1555 raise self.InvalidCmd, 'Invalid run name. Please retry'
1556 elif self.options['nb_core'] != 1:
1557 lhe = lhe_parser.EventFile(args)
1558 nb_event = len(lhe)
1559 lhe.close()
1560
1561 input = args[0]
1562 if len(args)>1:
1563 output = pjoin(os.getcwd(),args[1])
1564 else:
1565 output = input
1566
1567 lhaid = [self.run_card.get_lhapdf_id()]
1568 if 'store_rwgt_info' in self.run_card and not self.run_card['store_rwgt_info']:
1569 raise self.InvalidCmd, "The events was not generated with store_rwgt_info=True. Can not evaluate systematics error on this event file."
1570 elif 'use_syst' in self.run_card:
1571 if not self.run_card['use_syst']:
1572 raise self.InvalidCmd, "The events was not generated with use_syst=True. Can not evaluate systematics error on this event file."
1573 elif self.proc_characteristics['ninitial'] ==1:
1574 if '--from_card' in opts:
1575 logger.warning('systematics not available for decay processes. Bypass it')
1576 return
1577 else:
1578 raise self.InvalidCmd, 'systematics not available for decay processes.'
1579
1580 try:
1581 pdfsets_dir = self.get_lhapdf_pdfsetsdir()
1582 except Exception, error:
1583 logger.debug(str(error))
1584 logger.warning('Systematic computation requires lhapdf to run. Bypass Systematics')
1585 return
1586
1587 if '--from_card' in opts:
1588 opts.remove('--from_card')
1589 opts.append('--from_card=internal')
1590
1591
1592 if 'sys_pdf' in self.run_card:
1593 sys_pdf = self.run_card['sys_pdf'].split('&&')
1594 lhaid += [l.split()[0] for l in sys_pdf]
1595
1596 else:
1597
1598 pdf = [a[6:] for a in opts if a.startswith('--pdf=')]
1599 lhaid += [t.split('@')[0] for p in pdf for t in p.split(',')
1600 if t not in ['errorset', 'central']]
1601
1602
1603 [self.copy_lhapdf_set([onelha], pdfsets_dir) for onelha in lhaid]
1604
1605
1606 if self.options['run_mode'] ==2:
1607 nb_submit = min(self.options['nb_core'], nb_event//2500)
1608 elif self.options['run_mode'] ==1:
1609 nb_submit = min(self.options['cluster_size'], nb_event//25000)
1610 else:
1611 nb_submit =1
1612
1613 if MADEVENT:
1614 import internal.systematics as systematics
1615 else:
1616 import madgraph.various.systematics as systematics
1617
1618
1619 if nb_submit in [0,1]:
1620 systematics.call_systematics([input, output] + opts,
1621 log=lambda x: logger.info(str(x)),
1622 result=result_file
1623 )
1624
1625 elif self.options['run_mode'] in [1,2]:
1626 event_per_job = nb_event // nb_submit
1627 nb_job_with_plus_one = nb_event % nb_submit
1628 start_event, stop_event = 0,0
1629 for i in range(nb_submit):
1630
1631 event_requested = event_per_job
1632 if i < nb_job_with_plus_one:
1633 event_requested += 1
1634 start_event = stop_event
1635 stop_event = start_event + event_requested
1636
1637 prog = sys.executable
1638 input_files = [os.path.basename(input)]
1639 output_files = ['./tmp_%s_%s' % (i, os.path.basename(output)),
1640 './log_sys_%s.txt' % (i)]
1641 argument = []
1642 if not __debug__:
1643 argument.append('-O')
1644 argument += [pjoin(self.me_dir, 'bin', 'internal', 'systematics.py'),
1645 input_files[0], output_files[0]] + opts +\
1646 ['--start_event=%i' % start_event,
1647 '--stop_event=%i' %stop_event,
1648 '--result=./log_sys_%s.txt' %i,
1649 '--lhapdf_config=%s' % self.options['lhapdf']]
1650 required_output = output_files
1651 self.cluster.cluster_submit(prog, argument,
1652 input_files=input_files,
1653 output_files=output_files,
1654 cwd=os.path.dirname(output),
1655 required_output=required_output,
1656 stdout='/dev/null'
1657 )
1658 starttime = time.time()
1659 update_status = lambda idle, run, finish: \
1660 self.update_status((idle, run, finish, 'running systematics'), level=None,
1661 force=False, starttime=starttime)
1662
1663 try:
1664 self.cluster.wait(os.path.dirname(output), update_status, update_first=update_status)
1665 except Exception:
1666 self.cluster.remove()
1667 old_run_mode = self.options['run_mode']
1668 self.options['run_mode'] =0
1669 try:
1670 out = self.do_systematics(line)
1671 finally:
1672 self.options['run_mode'] = old_run_mode
1673
1674 all_cross = []
1675 for i in range(nb_submit):
1676 pos=0
1677 for line in open(pjoin(os.path.dirname(output), 'log_sys_%s.txt'%i)):
1678 if line.startswith('#'):
1679 continue
1680 split = line.split()
1681 if len(split) in [0,1]:
1682 continue
1683 key = tuple(float(x) for x in split[:-1])
1684 cross= float(split[-1])
1685 if 'event_norm' in self.run_card and \
1686 self.run_card['event_norm'] in ['average', 'unity']:
1687 cross *= (event_per_job+1 if i <nb_job_with_plus_one else event_per_job)
1688 if len(all_cross) > pos:
1689 all_cross[pos] += cross
1690 else:
1691 all_cross.append(cross)
1692 pos+=1
1693
1694 if 'event_norm' in self.run_card and \
1695 self.run_card['event_norm'] in ['unity']:
1696 all_cross= [cross/nb_event for cross in all_cross]
1697
1698 sys_obj = systematics.call_systematics([input, None] + opts,
1699 log=lambda x: logger.info(str(x)),
1700 result=result_file,
1701 running=False
1702 )
1703 sys_obj.print_cross_sections(all_cross, nb_event, result_file)
1704
1705
1706 subprocess.call(['cat']+\
1707 ['./tmp_%s_%s' % (i, os.path.basename(output)) for i in range(nb_submit)],
1708 stdout=open(output,'w'),
1709 cwd=os.path.dirname(output))
1710 for i in range(nb_submit):
1711 os.remove('%s/tmp_%s_%s' %(os.path.dirname(output),i,os.path.basename(output)))
1712
1713
1714
1715
1716
1717
1718 self.update_status('End of systematics computation', level='parton', makehtml=False)
1719
1720
1721
1723 """ syntax is "reweight RUN_NAME"
1724 Allow to reweight the events generated with a new choices of model
1725 parameter. Description of the methods are available here
1726 cp3.irmp.ucl.ac.be/projects/madgraph/wiki/Reweight
1727 """
1728
1729
1730 def check_multicore(self):
1731 """ determine if the cards are save for multicore use"""
1732 card = pjoin(self.me_dir, 'Cards', 'reweight_card.dat')
1733
1734 multicore = True
1735 if self.options['run_mode'] in [0,1]:
1736 multicore = False
1737
1738 lines = [l.strip() for l in open(card) if not l.strip().startswith('#')]
1739 while lines and not lines[0].startswith('launch'):
1740 line = lines.pop(0)
1741
1742 if line.startswith('change') and line[6:].strip().startswith('output'):
1743 return False
1744 if line.startswith('change') and line[6:].strip().startswith('multicore'):
1745 split_line = line.split()
1746 if len(split_line) > 2:
1747 multicore = bool(split_line[2])
1748
1749
1750 lines = [line[6:].strip() for line in lines if line.startswith('change')]
1751 for line in lines:
1752 if line.startswith(('process','model','output', 'rwgt_dir')):
1753 return False
1754 elif line.startswith('multicore'):
1755 split_line = line.split()
1756 if len(split_line) > 1:
1757 multicore = bool(split_line[1])
1758
1759 return multicore
1760
1761
1762
1763 if '-from_cards' in line and not os.path.exists(pjoin(self.me_dir, 'Cards', 'reweight_card.dat')):
1764 return
1765
1766 if '--multicore=create' in line:
1767 multicore='create'
1768 elif '--multicore=wait' in line:
1769 multicore='wait'
1770 else:
1771 multicore=False
1772
1773
1774 if MADEVENT and not self.options['mg5_path']:
1775 raise self.InvalidCmd, '''The module reweight requires that MG5 is installed on the system.
1776 You can install it and set its path in ./Cards/me5_configuration.txt'''
1777 elif MADEVENT:
1778 sys.path.append(self.options['mg5_path'])
1779 try:
1780 import madgraph.interface.reweight_interface as reweight_interface
1781 except ImportError:
1782 raise self.ConfigurationError, '''Can\'t load Reweight module.
1783 The variable mg5_path might not be correctly configured.'''
1784
1785
1786
1787 if not '-from_cards' in line:
1788 self.keep_cards(['reweight_card.dat'], ignore=['*'])
1789 self.ask_edit_cards(['reweight_card.dat'], 'fixed', plot=False)
1790
1791
1792 args = self.split_arg(line)
1793
1794 if not self.force_run:
1795
1796 if self.run_name and self.results.current and self.results.current['cross'] == 0:
1797 self.results.delete_run(self.run_name, self.run_tag)
1798 self.results.save()
1799
1800 if not hasattr(self, 'run_card'):
1801 self.run_card = banner_mod.RunCard(pjoin(self.me_dir, 'Cards', 'run_card.dat'))
1802
1803
1804 command = [sys.executable]
1805 if os.path.exists(pjoin(self.me_dir, 'bin', 'madevent')):
1806 command.append(pjoin(self.me_dir, 'bin', 'internal','madevent_interface.py'))
1807 else:
1808 command.append(pjoin(self.me_dir, 'bin', 'internal', 'amcatnlo_run_interface.py'))
1809 if not isinstance(self, cmd.CmdShell):
1810 command.append('--web')
1811 command.append('reweight')
1812
1813
1814 if self.options['nb_core']==1 or self.run_card['nevents'] < 101 or not check_multicore(self):
1815 if self.run_name:
1816 command.append(self.run_name)
1817 else:
1818 command += args
1819 if '-from_cards' not in command:
1820 command.append('-from_cards')
1821 p = misc.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, cwd=os.getcwd())
1822 while p.poll() is None:
1823 line = p.stdout.readline()
1824 if any(t in line for t in ['INFO:', 'WARNING:', 'CRITICAL:', 'ERROR:', 'root:','KEEP:']) and \
1825 not '***********' in line:
1826 print line[:-1].replace('INFO', 'REWEIGHT').replace('KEEP:','')
1827 elif __debug__ and line:
1828 logger.debug(line[:-1])
1829 if p.returncode !=0:
1830 logger.error("Reweighting failed")
1831 return
1832 self.results = self.load_results_db()
1833
1834 try:
1835 if self.results[self.run_name][-2]['cross']==0:
1836 self.results.delete_run(self.run_name,self.results[self.run_name][-2]['tag'])
1837 except:
1838 pass
1839 try:
1840 if self.results.current['cross'] == 0 and self.run_name:
1841 self.results.delete_run(self.run_name, self.run_tag)
1842 except:
1843 pass
1844
1845 try:
1846 self.results.def_current(self.run_name, self.run_tag)
1847 except Exception:
1848 pass
1849 return
1850
1851 else:
1852
1853 if not isinstance(self.cluster, cluster.MultiCore):
1854 mycluster = cluster.MultiCore(nb_core=self.options['nb_core'])
1855 else:
1856 mycluster = self.cluster
1857
1858 new_args=list(args)
1859 self.check_decay_events(new_args)
1860 try:
1861 os.remove(pjoin(self.me_dir,'rw_me','rwgt.pkl'))
1862 except Exception, error:
1863 pass
1864
1865 import madgraph.various.lhe_parser as lhe_parser
1866
1867 if 'nevt_job' in self.run_card and self.run_card['nevt_job'] !=-1:
1868 nevt_job = self.run_card['nevt_job']
1869 else:
1870 nevt_job = max(5000, self.run_card['nevents']/50)
1871 logger.info("split the event file in bunch of %s events" % nevt_job)
1872 nb_file = lhe_parser.EventFile(new_args[0]).split(nevt_job)
1873 starttime = time.time()
1874 update_status = lambda idle, run, finish: \
1875 self.update_status((idle, run, finish, 'reweight'), level=None,
1876 force=False, starttime=starttime)
1877
1878 all_lhe = []
1879 devnull= open(os.devnull)
1880 for i in range(nb_file):
1881 new_command = list(command)
1882 new_command.append('%s_%s.lhe' % (new_args[0],i))
1883 all_lhe.append('%s_%s.lhe' % (new_args[0],i))
1884 if '-from_cards' not in command:
1885 new_command.append('-from_cards')
1886 if i==0:
1887 if __debug__:
1888 stdout = None
1889 else:
1890 stdout = open(pjoin(self.me_dir,'Events', self.run_name, 'reweight.log'),'w')
1891 new_command.append('--multicore=create')
1892 else:
1893 stdout = devnull
1894
1895 new_command.append('--multicore=wait')
1896 mycluster.submit(prog=command[0], argument=new_command[1:], stdout=stdout, cwd=os.getcwd())
1897 mycluster.wait(self.me_dir,update_status)
1898 devnull.close()
1899 logger.info("Collect and combine the various output file.")
1900 lhe = lhe_parser.MultiEventFile(all_lhe, parse=False)
1901 nb_event, cross_sections = lhe.write(new_args[0], get_info=True)
1902 if any(os.path.exists('%s_%s_debug.log' % (f, self.run_tag)) for f in all_lhe):
1903 for f in all_lhe:
1904 if os.path.exists('%s_%s_debug.log' % (f, self.run_tag)):
1905 raise Exception, "Some of the run failed: Please read %s_%s_debug.log" % (f, self.run_tag)
1906
1907
1908 if 'event_norm' in self.run_card and self.run_card['event_norm'] == 'average':
1909 for key, value in cross_sections.items():
1910 cross_sections[key] = value / (nb_event+1)
1911 lhe.remove()
1912 for key in cross_sections:
1913 if key == 'orig' or key.isdigit():
1914 continue
1915 logger.info('%s : %s pb' % (key, cross_sections[key]))
1916 return
1917
1918
1919
1920 self.to_store.append('event')
1921
1922 if self.results.current['cross'] == 0 and self.run_name:
1923 self.results.delete_run(self.run_name, self.run_tag)
1924
1925 self.check_decay_events(args)
1926
1927 reweight_cmd = reweight_interface.ReweightInterface(args[0], mother=self)
1928
1929
1930 wgt_names = reweight_cmd.get_weight_names()
1931 if wgt_names == [''] and reweight_cmd.has_nlo:
1932 self.update_status('Running Reweighting (LO approximate)', level='madspin')
1933 else:
1934 self.update_status('Running Reweighting', level='madspin')
1935
1936 path = pjoin(self.me_dir, 'Cards', 'reweight_card.dat')
1937 reweight_cmd.raw_input=False
1938 reweight_cmd.me_dir = self.me_dir
1939 reweight_cmd.multicore = multicore
1940 print "We are in mode", multicore
1941 reweight_cmd.import_command_file(path)
1942 reweight_cmd.do_quit('')
1943
1944 logger.info("quit rwgt")
1945
1946
1947
1948
1949 try:
1950 self.results.def_current(self.run_name, self.run_tag)
1951 except Exception:
1952 pass
1953
1954
1956 """launch pgs"""
1957
1958 args = self.split_arg(line)
1959
1960 if '--no_default' in args:
1961 no_default = True
1962 args.remove('--no_default')
1963 else:
1964 no_default = False
1965
1966 if no_default and not os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')):
1967 logger.info('No pgs_card detected, so not run pgs')
1968 return
1969
1970
1971
1972
1973
1974
1975 lock = self.check_pgs(args, no_default=no_default)
1976
1977
1978 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')):
1979 files.cp(pjoin(self.me_dir, 'Cards', 'pgs_card_default.dat'),
1980 pjoin(self.me_dir, 'Cards', 'pgs_card.dat'))
1981 logger.info('No pgs card found. Take the default one.')
1982
1983 if not (no_default or self.force):
1984 self.ask_edit_cards(['pgs_card.dat'])
1985
1986 self.update_status('prepare PGS run', level=None)
1987
1988 pgsdir = pjoin(self.options['pythia-pgs_path'], 'src')
1989 eradir = self.options['exrootanalysis_path']
1990 madir = self.options['madanalysis_path']
1991 td = self.options['td_path']
1992
1993
1994 if not misc.is_executable(pjoin(pgsdir, 'pgs')):
1995 logger.info('No PGS executable -- running make')
1996 misc.compile(cwd=pgsdir)
1997
1998 self.update_status('Running PGS', level='pgs')
1999
2000 tag = self.run_tag
2001
2002 banner_path = pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, self.run_tag))
2003 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')):
2004 self.banner.add(pjoin(self.me_dir, 'Cards','pgs_card.dat'))
2005 self.banner.write(banner_path)
2006 else:
2007 open(banner_path, 'w').close()
2008
2009
2010
2011
2012 if lock:
2013 lock.wait()
2014
2015 ff = open(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'), 'w')
2016 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')):
2017 text = open(banner_path).read()
2018 text = '#%s' % text.replace('\n','\n#')
2019 dico = self.results[self.run_name].get_current_info()
2020 text +='\n## Integrated weight (pb) : %.4g' % dico['cross']
2021 text +='\n## Number of Event : %s\n' % dico['nb_event']
2022 ff.writelines(text)
2023 ff.close()
2024
2025 try:
2026 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done'))
2027 except Exception:
2028 pass
2029
2030 pgs_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_pgs.log" % tag)
2031 self.cluster.launch_and_wait('../bin/internal/run_pgs',
2032 argument=[pgsdir], cwd=pjoin(self.me_dir,'Events'),
2033 stdout=pgs_log, stderr=subprocess.STDOUT)
2034
2035 if not os.path.exists(pjoin(self.me_dir, 'Events', 'pgs.done')):
2036 logger.error('Fail to create LHCO events')
2037 return
2038 else:
2039 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done'))
2040
2041 if os.path.getsize(banner_path) == os.path.getsize(pjoin(self.me_dir, 'Events','pgs_events.lhco')):
2042 misc.call(['cat pgs_uncleaned_events.lhco >> pgs_events.lhco'],
2043 cwd=pjoin(self.me_dir, 'Events'))
2044 os.remove(pjoin(self.me_dir, 'Events', 'pgs_uncleaned_events.lhco '))
2045
2046
2047 if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHCOlympicsConverter')):
2048 self.update_status('Creating PGS Root File', level='pgs')
2049 try:
2050 misc.call([eradir+'/ExRootLHCOlympicsConverter',
2051 'pgs_events.lhco',pjoin('%s/%s_pgs_events.root' % (self.run_name, tag))],
2052 cwd=pjoin(self.me_dir, 'Events'))
2053 except Exception:
2054 logger.warning('fail to produce Root output [problem with ExRootAnalysis')
2055 if os.path.exists(pjoin(self.me_dir, 'Events', 'pgs_events.lhco')):
2056
2057 files.mv(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'),
2058 pjoin(self.me_dir, 'Events', self.run_name, '%s_pgs_events.lhco' % tag))
2059 self.create_plot('PGS')
2060 misc.gzip(pjoin(self.me_dir, 'Events', self.run_name, '%s_pgs_events.lhco' % tag))
2061
2062 self.update_status('finish', level='pgs', makehtml=False)
2063
2064
2066 """Require MG5 directory: Compute automatically the widths of a set
2067 of particles"""
2068
2069
2070
2071 args = self.split_arg(line)
2072 opts = self.check_compute_widths(args)
2073
2074 from madgraph.interface.master_interface import MasterCmd
2075 cmd = MasterCmd()
2076 self.define_child_cmd_interface(cmd, interface=False)
2077 cmd.exec_cmd('set automatic_html_opening False --no_save')
2078 if not opts['path']:
2079 opts['path'] = pjoin(self.me_dir, 'Cards', 'param_card.dat')
2080 if not opts['force'] :
2081 self.ask_edit_cards(['param_card'],[], plot=False)
2082
2083
2084 line = 'compute_widths %s %s' % \
2085 (' '.join([str(i) for i in opts['particles']]),
2086 ' '.join('--%s=%s' % (key,value) for (key,value) in opts.items()
2087 if key not in ['model', 'force', 'particles'] and value))
2088 cmd.exec_cmd(line, model=opts['model'])
2089 self.child = None
2090 del cmd
2091
2092
2094 """Not in help:Print the cross-section/ number of events for a given run"""
2095
2096 args = self.split_arg(line)
2097 options={'path':None, 'mode':'w', 'format':'full'}
2098 for arg in list(args):
2099 if arg.startswith('--') and '=' in arg:
2100 name,value=arg.split('=',1)
2101 name = name [2:]
2102 options[name] = value
2103 args.remove(arg)
2104
2105
2106 if len(args) > 0:
2107 run_name = args[0]
2108 else:
2109 for i, run_name in enumerate(self.results.order):
2110 for j, one_result in enumerate(self.results[run_name]):
2111 if i or j:
2112 options['mode'] = "a"
2113 if options['path']:
2114 self.print_results_in_file(one_result, options['path'], options['mode'], options['format'])
2115 else:
2116 self.print_results_in_shell(one_result)
2117 return
2118
2119 if run_name not in self.results:
2120 raise self.InvalidCmd('%s is not a valid run_name or it doesn\'t have any information' \
2121 % run_name)
2122
2123
2124 if len(args) == 2:
2125 tag = args[1]
2126 if tag.isdigit():
2127 tag = int(tag) - 1
2128 if len(self.results[run_name]) < tag:
2129 raise self.InvalidCmd('Only %s different tag available' % \
2130 len(self.results[run_name]))
2131 data = self.results[run_name][tag]
2132 else:
2133 data = self.results[run_name].return_tag(tag)
2134 else:
2135 data = self.results[run_name].return_tag(None)
2136
2137 if options['path']:
2138 self.print_results_in_file(data, options['path'], options['mode'], options['format'])
2139 else:
2140 self.print_results_in_shell(data)
2141
2146
2147
2148
2149
2150
2151 @staticmethod
2152 - def runMA5(MA5_interpreter, MA5_cmds, MA5_runtag, logfile_path, advertise_log=True):
2153 """ Run MA5 in a controlled environnment."""
2154 successfull_MA5_run = True
2155
2156 try:
2157
2158 MA5_logger = None
2159 MA5_logger = logging.getLogger('MA5')
2160 BackUp_MA5_handlers = MA5_logger.handlers
2161 for handler in BackUp_MA5_handlers:
2162 MA5_logger.removeHandler(handler)
2163 file_handler = logging.FileHandler(logfile_path)
2164 MA5_logger.addHandler(file_handler)
2165 if advertise_log:
2166 logger.info("Follow Madanalysis5 run with the following command in a separate terminal:")
2167 logger.info(' tail -f %s'%logfile_path)
2168
2169 with misc.stdchannel_redirected(sys.stdout, os.devnull):
2170 with misc.stdchannel_redirected(sys.stderr, os.devnull):
2171 MA5_interpreter.print_banner()
2172 MA5_interpreter.load(MA5_cmds)
2173 except Exception as e:
2174 logger.warning("MadAnalysis5 failed to run the commands for task "+
2175 "'%s'. Madanalys5 analysis will be skipped."%MA5_runtag)
2176 error=StringIO.StringIO()
2177 traceback.print_exc(file=error)
2178 logger.debug('MadAnalysis5 error was:')
2179 logger.debug('-'*60)
2180 logger.debug(error.getvalue()[:-1])
2181 logger.debug('-'*60)
2182 successfull_MA5_run = False
2183 finally:
2184 if not MA5_logger is None:
2185 for handler in MA5_logger.handlers:
2186 MA5_logger.removeHandler(handler)
2187 for handler in BackUp_MA5_handlers:
2188 MA5_logger.addHandler(handler)
2189
2190 return successfull_MA5_run
2191
2192
2193
2194
2195 @staticmethod
2198 """ Makes sure to correctly setup paths and constructs and return an MA5 path"""
2199
2200 MA5path = os.path.normpath(pjoin(mg5_path,ma5_path))
2201
2202 if MA5path is None or not os.path.isfile(pjoin(MA5path,'bin','ma5')):
2203 return None
2204 if MA5path not in sys.path:
2205 sys.path.insert(0, MA5path)
2206
2207 try:
2208
2209
2210 import readline
2211 old_completer = readline.get_completer()
2212 old_delims = readline.get_completer_delims()
2213 old_history = [readline.get_history_item(i) for i in range(1,readline.get_current_history_length()+1)]
2214 except ImportError:
2215 old_completer, old_delims, old_history = None, None, None
2216 try:
2217 from madanalysis.interpreter.ma5_interpreter import MA5Interpreter
2218 with misc.stdchannel_redirected(sys.stdout, os.devnull):
2219 with misc.stdchannel_redirected(sys.stderr, os.devnull):
2220 MA5_interpreter = MA5Interpreter(MA5path, LoggerLevel=loglevel,
2221 LoggerStream=logstream,forced=forced)
2222 except Exception as e:
2223 logger.warning('MadAnalysis5 failed to start so that MA5 analysis will be skipped.')
2224 error=StringIO.StringIO()
2225 traceback.print_exc(file=error)
2226 logger.debug('MadAnalysis5 error was:')
2227 logger.debug('-'*60)
2228 logger.debug(error.getvalue()[:-1])
2229 logger.debug('-'*60)
2230 MA5_interpreter = None
2231 finally:
2232
2233 if not old_history is None:
2234 readline.clear_history()
2235 for line in old_history:
2236 readline.add_history(line)
2237 if not old_completer is None:
2238 readline.set_completer(old_completer)
2239 if not old_delims is None:
2240 readline.set_completer_delims(old_delims)
2241
2242
2243 if not mg5_interface is None and any(not elem is None for elem in [old_completer, old_delims, old_history]):
2244 mg5_interface.set_readline_completion_display_matches_hook()
2245
2246 return MA5_interpreter
2247
2249 """Check the argument for the madanalysis5 command
2250 syntax: madanalysis5_parton [NAME]
2251 """
2252
2253 MA5_options = {'MA5_stdout_lvl':'default'}
2254
2255 stdout_level_tags = [a for a in args if a.startswith('--MA5_stdout_lvl=')]
2256 for slt in stdout_level_tags:
2257 lvl = slt.split('=')[1].strip()
2258 try:
2259
2260 MA5_options['MA5_stdout_lvl']=int(lvl)
2261 except ValueError:
2262 if lvl.startswith('logging.'):
2263 lvl = lvl[8:]
2264 try:
2265 MA5_options['MA5_stdout_lvl'] = getattr(logging, lvl)
2266 except:
2267 raise InvalidCmd("MA5 output level specification"+\
2268 " '%s' is incorrect." % str(lvl))
2269 args.remove(slt)
2270
2271 if mode=='parton':
2272
2273
2274 MA5_options['inputs'] = '*.lhe'
2275 elif mode=='hadron':
2276
2277
2278
2279 MA5_options['inputs'] = ['fromCard']
2280 else:
2281 raise MadGraph5Error('Mode %s not reckognized'%mode+
2282 ' in function check_madanalysis5.')
2283
2284 if not self.options['madanalysis5_path']:
2285 logger.info('Now trying to read the configuration file again'+
2286 ' to find MadAnalysis5 path')
2287 self.set_configuration()
2288
2289 if not self.options['madanalysis5_path'] or not \
2290 os.path.exists(pjoin(self.options['madanalysis5_path'],'bin','ma5')):
2291 error_msg = 'No valid MadAnalysis5 path set.\n'
2292 error_msg += 'Please use the set command to define the path and retry.\n'
2293 error_msg += 'You can also define it in the configuration file.\n'
2294 error_msg += 'Finally, it can be installed automatically using the'
2295 error_msg += ' install command.\n'
2296 raise self.InvalidCmd(error_msg)
2297
2298
2299 if not os.path.isfile(pjoin(self.me_dir,
2300 'Cards','madanalysis5_%s_card.dat'%mode)):
2301 raise self.InvalidCmd('Your installed version of MadAnalysis5 and/or'+\
2302 ' MadGraph5_aMCatNLO does not seem to support analysis at'+
2303 '%s level.'%mode)
2304
2305 tag = [a for a in args if a.startswith('--tag=')]
2306 if tag:
2307 args.remove(tag[0])
2308 tag = tag[0][6:]
2309
2310 if len(args) == 0 and not self.run_name:
2311 if self.results.lastrun:
2312 args.insert(0, self.results.lastrun)
2313 else:
2314 raise self.InvalidCmd('No run name currently defined. '+
2315 'Please add this information.')
2316
2317 if len(args) >= 1:
2318 if mode=='parton' and args[0] != self.run_name and \
2319 not os.path.exists(pjoin(self.me_dir,'Events',args[0],
2320 'unweighted_events.lhe.gz')) and not os.path.exists(
2321 pjoin(self.me_dir,'Events',args[0])):
2322 raise self.InvalidCmd('No events file in the %s run.'%args[0])
2323 self.set_run_name(args[0], tag, level='madanalysis5_%s'%mode)
2324 else:
2325 if tag:
2326 self.run_card['run_tag'] = args[0]
2327 self.set_run_name(self.run_name, tag, level='madanalysis5_%s'%mode)
2328
2329 if mode=='parton':
2330 if any(t for t in args if t.startswith('--input=')):
2331 raise InvalidCmd('The option --input=<input_file> is not'+
2332 ' available when running partonic MadAnalysis5 analysis. The'+
2333 ' .lhe output of the selected run is used automatically.')
2334 input_file = pjoin(self.me_dir,'Events',self.run_name, 'unweighted_events.lhe')
2335 MA5_options['inputs'] = '%s.gz'%input_file
2336 if not os.path.exists('%s.gz'%input_file):
2337 if os.path.exists(input_file):
2338 misc.gzip(input_file, keep=True, stdout=output_file)
2339 else:
2340 logger.warning("LHE event file not found in \n%s\ns"%input_file+
2341 "Parton-level MA5 analysis will be skipped.")
2342
2343 if mode=='hadron':
2344
2345
2346 self.store_result()
2347
2348 hadron_tag = [t for t in args if t.startswith('--input=')]
2349 if hadron_tag and hadron_tag[0][8:]:
2350 hadron_inputs = hadron_tag[0][8:].split(',')
2351
2352
2353 elif MA5_options['inputs'] == ['fromCard']:
2354 hadron_inputs = banner_mod.MadAnalysis5Card(pjoin(self.me_dir,
2355 'Cards','madanalysis5_hadron_card.dat'),mode='hadron')['inputs']
2356
2357
2358
2359 MA5_options['inputs'] = []
2360 special_source_tags = []
2361 for htag in hadron_inputs:
2362
2363 if htag in special_source_tags:
2364
2365 continue
2366
2367 if os.path.isfile(htag) or (os.path.exists(htag) and
2368 stat.S_ISFIFO(os.stat(htag).st_mode)):
2369 MA5_options['inputs'].append(htag)
2370 continue
2371
2372
2373
2374 file_candidates = misc.glob(htag, pjoin(self.me_dir,'Events',self.run_name))+\
2375 misc.glob('%s.gz'%htag, pjoin(self.me_dir,'Events',self.run_name))
2376 priority_files = [f for f in file_candidates if
2377 self.run_card['run_tag'] in os.path.basename(f)]
2378 priority_files = [f for f in priority_files if
2379 'EVENTS' in os.path.basename(f).upper()]
2380
2381 for f in file_candidates:
2382 if os.path.basename(f).startswith('unweighted_events.lhe'):
2383 priority_files.append(f)
2384 if priority_files:
2385 MA5_options['inputs'].append(priority_files[-1])
2386 continue
2387 if file_candidates:
2388 MA5_options['inputs'].append(file_candidates[-1])
2389 continue
2390
2391 return MA5_options
2392
2394 """Ask the question when launching madanalysis5.
2395 In the future we can ask here further question about the MA5 run, but
2396 for now we just edit the cards"""
2397
2398 cards = ['madanalysis5_%s_card.dat'%runtype]
2399 self.keep_cards(cards)
2400
2401 if self.force:
2402 return runtype
2403
2404
2405
2406 auto=False
2407 if mode=='auto':
2408 auto=True
2409 if auto:
2410 self.ask_edit_cards(cards, mode='auto', plot=False)
2411 else:
2412 self.ask_edit_cards(cards, plot=False)
2413
2414
2415
2416 mode = runtype
2417 return mode
2418
2420 "Complete the madanalysis5 command"
2421 args = self.split_arg(line[0:begidx], error=False)
2422 if len(args) == 1:
2423
2424 data = []
2425 for name in banner_mod.MadAnalysis5Card._default_hadron_inputs:
2426 data += misc.glob(pjoin('*','%s'%name), pjoin(self.me_dir, 'Events'))
2427 data += misc.glob(pjoin('*','%s.gz'%name), pjoin(self.me_dir, 'Events'))
2428 data = [n.rsplit('/',2)[1] for n in data]
2429 tmp1 = self.list_completion(text, data)
2430 if not self.run_name:
2431 return tmp1
2432 else:
2433 tmp2 = self.list_completion(text, ['-f',
2434 '--MA5_stdout_lvl=','--input=','--no_default', '--tag='], line)
2435 return tmp1 + tmp2
2436
2437 elif '--MA5_stdout_lvl=' in line and not any(arg.startswith(
2438 '--MA5_stdout_lvl=') for arg in args):
2439 return self.list_completion(text,
2440 ['--MA5_stdout_lvl=%s'%opt for opt in
2441 ['logging.INFO','logging.DEBUG','logging.WARNING',
2442 'logging.CRITICAL','90']], line)
2443 elif '--input=' in line and not any(arg.startswith(
2444 '--input=') for arg in args):
2445 return self.list_completion(text, ['--input=%s'%opt for opt in
2446 (banner_mod.MadAnalysis5Card._default_hadron_inputs +['path'])], line)
2447 else:
2448 return self.list_completion(text, ['-f',
2449 '--MA5_stdout_lvl=','--input=','--no_default', '--tag='], line)
2450
2452 """launch MadAnalysis5 at the hadron level."""
2453 return self.run_madanalysis5(line,mode='hadron')
2454
2456 """launch MadAnalysis5 at the parton level or at the hadron level with
2457 a specific command line."""
2458
2459
2460 args = self.split_arg(line)
2461
2462 if '--no_default' in args:
2463 no_default = True
2464 args.remove('--no_default')
2465 else:
2466 no_default = False
2467
2468 if no_default:
2469
2470 if mode=='parton' and not os.path.exists(pjoin(self.me_dir, 'Cards',
2471 'madanalysis5_parton_card.dat')):
2472 return
2473 if mode=='hadron' and not os.path.exists(pjoin(self.me_dir, 'Cards',
2474 'madanalysis5_hadron_card.dat')):
2475 return
2476 else:
2477
2478
2479 self.ask_madanalysis5_run_configuration(runtype=mode)
2480
2481 if not self.options['madanalysis5_path'] or \
2482 all(not os.path.exists(pjoin(self.me_dir, 'Cards',card)) for card in
2483 ['madanalysis5_parton_card.dat','madanalysis5_hadron_card.dat']):
2484 if no_default:
2485 return
2486 else:
2487 raise InvalidCmd('You must have MadAnalysis5 available to run'+
2488 " this command. Consider installing it with the 'install' function.")
2489
2490 if not self.run_name:
2491 MA5_opts = self.check_madanalysis5(args, mode=mode)
2492 self.configure_directory(html_opening =False)
2493 else:
2494
2495 self.configure_directory(html_opening =False)
2496 MA5_opts = self.check_madanalysis5(args, mode=mode)
2497
2498
2499 if MA5_opts['inputs']==[]:
2500 if no_default:
2501 logger.warning('No hadron level input found to run MadAnalysis5 on.'+
2502 ' Skipping its hadron-level analysis.')
2503 return
2504 else:
2505 raise self.InvalidCmd('\nNo input files specified or availabled for'+
2506 ' this MadAnalysis5 hadron-level run.\nPlease double-check the options of this'+
2507 ' MA5 command (or card) and which output files\nare currently in the chosen'+
2508 " run directory '%s'."%self.run_name)
2509
2510 MA5_card = banner_mod.MadAnalysis5Card(pjoin(self.me_dir, 'Cards',
2511 'madanalysis5_%s_card.dat'%mode), mode=mode)
2512
2513 if MA5_card._skip_analysis:
2514 logger.info('Madanalysis5 %s-level analysis was skipped following user request.'%mode)
2515 logger.info("To run the analysis, remove or comment the tag '%s skip_analysis' "
2516 %banner_mod.MadAnalysis5Card._MG5aMC_escape_tag+
2517 "in\n '%s'."%pjoin(self.me_dir, 'Cards','madanalysis5_%s_card.dat'%mode))
2518 return
2519
2520 MA5_cmds_list = MA5_card.get_MA5_cmds(MA5_opts['inputs'],
2521 pjoin(self.me_dir,'MA5_%s_ANALYSIS'%mode.upper()),
2522 run_dir_path = pjoin(self.me_dir,'Events', self.run_name),
2523 UFO_model_path=pjoin(self.me_dir,'bin','internal','ufomodel'),
2524 run_tag = self.run_tag)
2525
2526
2527
2528
2529
2530
2531
2532
2533 self.update_status('\033[92mRunning MadAnalysis5 [arXiv:1206.1599]\033[0m',
2534 level='madanalysis5_%s'%mode)
2535 if mode=='hadron':
2536 logger.info('Hadron input files considered:')
2537 for input in MA5_opts['inputs']:
2538 logger.info(' --> %s'%input)
2539 elif mode=='parton':
2540 logger.info('Parton input file considered:')
2541 logger.info(' --> %s'%MA5_opts['inputs'])
2542
2543
2544
2545
2546 if MA5_opts['MA5_stdout_lvl']=='default':
2547 if MA5_card['stdout_lvl'] is None:
2548 MA5_lvl = self.options['stdout_level']
2549 else:
2550 MA5_lvl = MA5_card['stdout_lvl']
2551 else:
2552 MA5_lvl = MA5_opts['MA5_stdout_lvl']
2553
2554
2555 MA5_interpreter = CommonRunCmd.get_MadAnalysis5_interpreter(
2556 self.options['mg5_path'],
2557 self.options['madanalysis5_path'],
2558 logstream=sys.stdout,
2559 loglevel=100,
2560 forced=True)
2561
2562
2563
2564 if MA5_interpreter is None:
2565 return
2566
2567
2568 used_up_fifos = []
2569
2570 for MA5_runtag, MA5_cmds in MA5_cmds_list:
2571
2572
2573 MA5_interpreter.setLogLevel(100)
2574
2575 if mode=='hadron':
2576 MA5_interpreter.init_reco()
2577 else:
2578 MA5_interpreter.init_parton()
2579 MA5_interpreter.setLogLevel(MA5_lvl)
2580
2581 if MA5_runtag!='default':
2582 if MA5_runtag.startswith('_reco_'):
2583 logger.info("MadAnalysis5 now running the reconstruction '%s'..."%
2584 MA5_runtag[6:],'$MG:color:GREEN')
2585 elif MA5_runtag=='Recasting':
2586 logger.info("MadAnalysis5 now running the recasting...",
2587 '$MG:color:GREEN')
2588 else:
2589 logger.info("MadAnalysis5 now running the '%s' analysis..."%
2590 MA5_runtag,'$MG:color:GREEN')
2591
2592
2593
2594 if not CommonRunCmd.runMA5(MA5_interpreter, MA5_cmds, MA5_runtag,
2595 pjoin(self.me_dir,'Events',self.run_name,'%s_MA5_%s.log'%(self.run_tag,MA5_runtag))):
2596
2597 return
2598
2599 if MA5_runtag.startswith('_reco_'):
2600
2601
2602
2603
2604 links_created=[]
2605 for i, input in enumerate(MA5_opts['inputs']):
2606
2607
2608 if not banner_mod.MadAnalysis5Card.events_can_be_reconstructed(input):
2609 continue
2610
2611 if input.endswith('.fifo'):
2612 if input in used_up_fifos:
2613
2614 continue
2615 else:
2616 used_up_fifos.append(input)
2617
2618 reco_output = pjoin(self.me_dir,
2619 'MA5_%s_ANALYSIS%s_%d'%(mode.upper(),MA5_runtag,i+1))
2620
2621 reco_event_file = misc.glob('*.lhe.gz',pjoin(reco_output,'Output','_reco_events'))+\
2622 misc.glob('*.root',pjoin(reco_output,'Output','_reco_events'))
2623 if len(reco_event_file)==0:
2624 raise MadGraph5Error, "MadAnalysis5 failed to produce the "+\
2625 "reconstructed event file for reconstruction '%s'."%MA5_runtag[6:]
2626 reco_event_file = reco_event_file[0]
2627
2628 shutil.move(reco_output,pjoin(self.me_dir,'HTML',
2629 self.run_name,'%s_MA5_%s_ANALYSIS%s_%d'%
2630 (self.run_tag,mode.upper(),MA5_runtag,i+1)))
2631
2632 links_created.append(os.path.basename(reco_event_file))
2633 files.ln(pjoin(self.me_dir,'HTML',self.run_name,
2634 '%s_MA5_%s_ANALYSIS%s_%d'%(self.run_tag,mode.upper(),
2635 MA5_runtag,i+1),'Output','_reco_events',links_created[-1]),
2636 pjoin(self.me_dir,'Events',self.run_name))
2637
2638 logger.info("MadAnalysis5 successfully completed the reconstruction "+
2639 "'%s'. Links to the reconstructed event files are:"%MA5_runtag[6:])
2640 for link in links_created:
2641 logger.info(' --> %s'%pjoin(self.me_dir,'Events',self.run_name,link))
2642 continue
2643
2644 if MA5_runtag.upper()=='RECASTING':
2645 target = pjoin(self.me_dir,'MA5_%s_ANALYSIS_%s'\
2646 %(mode.upper(),MA5_runtag),'Output','CLs_output_summary.dat')
2647 else:
2648 target = pjoin(self.me_dir,'MA5_%s_ANALYSIS_%s'\
2649 %(mode.upper(),MA5_runtag),'PDF','main.pdf')
2650 if not os.path.isfile(target):
2651 raise MadGraph5Error, "MadAnalysis5 failed to produced "+\
2652 "an output for the analysis '%s' in\n %s"%(MA5_runtag,target)
2653
2654
2655 if MA5_runtag.upper()=='RECASTING':
2656 carboncopy_name = '%s_MA5_CLs.dat'%(self.run_tag)
2657 else:
2658 carboncopy_name = '%s_MA5_%s_analysis_%s.pdf'%(
2659 self.run_tag,mode,MA5_runtag)
2660 shutil.copy(target, pjoin(self.me_dir,'Events',self.run_name,carboncopy_name))
2661 if MA5_runtag!='default':
2662 logger.info("MadAnalysis5 successfully completed the "+
2663 "%s. Reported results are placed in:"%("analysis '%s'"%MA5_runtag
2664 if MA5_runtag.upper()!='RECASTING' else "recasting"))
2665 else:
2666 logger.info("MadAnalysis5 successfully completed the analysis."+
2667 " Reported results are placed in:")
2668 logger.info(' --> %s'%pjoin(self.me_dir,'Events',self.run_name,carboncopy_name))
2669
2670
2671 shutil.move(pjoin(self.me_dir,'MA5_%s_ANALYSIS_%s'\
2672 %(mode.upper(),MA5_runtag)), pjoin(self.me_dir,'HTML',self.run_name,
2673 '%s_MA5_%s_ANALYSIS_%s'%(self.run_tag,mode.upper(),MA5_runtag)))
2674
2675
2676
2677 new_details={}
2678 for detail in ['nb_event','cross','error']:
2679 new_details[detail] = \
2680 self.results[self.run_name].get_current_info()[detail]
2681 for detail in new_details:
2682 self.results.add_detail(detail,new_details[detail])
2683
2684 self.update_status('Finished MA5 analyses.', level='madanalysis5_%s'%mode,
2685 makehtml=False)
2686
2687
2688 self.banner.add(pjoin(self.me_dir, 'Cards',
2689 'madanalysis5_%s_card.dat'%mode))
2690 banner_path = pjoin(self.me_dir,'Events', self.run_name,
2691 '%s_%s_banner.txt'%(self.run_name, self.run_tag))
2692 self.banner.write(banner_path)
2693
2694 if not no_default:
2695 logger.info('Find more information about this run on the HTML local page')
2696 logger.info(' --> %s'%pjoin(self.me_dir,'index.html'))
2697
2698
2699
2700
2701
2703 """ run delphes and make associate root file/plot """
2704
2705 args = self.split_arg(line)
2706
2707 if '--no_default' in args:
2708 no_default = True
2709 args.remove('--no_default')
2710 else:
2711 no_default = False
2712
2713 if no_default and not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
2714 logger.info('No delphes_card detected, so not run Delphes')
2715 return
2716
2717
2718 filepath = self.check_delphes(args, nodefault=no_default)
2719 if no_default and not filepath:
2720 return
2721
2722 self.update_status('prepare delphes run', level=None)
2723
2724 if os.path.exists(pjoin(self.options['delphes_path'], 'data')):
2725 delphes3 = False
2726 prog = '../bin/internal/run_delphes'
2727 if filepath and '.hepmc' in filepath[:-10]:
2728 raise self.InvalidCmd, 'delphes2 do not support hepmc'
2729 else:
2730 delphes3 = True
2731 prog = '../bin/internal/run_delphes3'
2732
2733
2734
2735 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
2736 if no_default:
2737 logger.info('No delphes_card detected, so not running Delphes')
2738 return
2739 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_card_default.dat'),
2740 pjoin(self.me_dir, 'Cards', 'delphes_card.dat'))
2741 logger.info('No delphes card found. Take the default one.')
2742 if not delphes3 and not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat')):
2743 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_trigger_default.dat'),
2744 pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat'))
2745 if not (no_default or self.force):
2746 if delphes3:
2747 self.ask_edit_cards(['delphes_card.dat'], args)
2748 else:
2749 self.ask_edit_cards(['delphes_card.dat', 'delphes_trigger.dat'], args)
2750
2751 self.update_status('Running Delphes', level=None)
2752
2753 delphes_dir = self.options['delphes_path']
2754 tag = self.run_tag
2755 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')):
2756 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_card.dat'))
2757 if not delphes3:
2758 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_trigger.dat'))
2759 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, tag)))
2760
2761 cross = self.results[self.run_name].get_current_info()['cross']
2762
2763 delphes_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_delphes.log" % tag)
2764 self.cluster.launch_and_wait(prog,
2765 argument= [delphes_dir, self.run_name, tag, str(cross), filepath],
2766 stdout=delphes_log, stderr=subprocess.STDOUT,
2767 cwd=pjoin(self.me_dir,'Events'))
2768
2769 if not os.path.exists(pjoin(self.me_dir, 'Events',
2770 self.run_name, '%s_delphes_events.lhco.gz' % tag))\
2771 and not os.path.exists(pjoin(self.me_dir, 'Events',
2772 self.run_name, '%s_delphes_events.lhco' % tag)):
2773 logger.info('If you are interested in lhco output. please run root2lhco converter.')
2774 logger.info(' or edit bin/internal/run_delphes3 to run the converter automatically.')
2775
2776
2777
2778 madir = self.options['madanalysis_path']
2779 td = self.options['td_path']
2780
2781 if os.path.exists(pjoin(self.me_dir, 'Events',
2782 self.run_name, '%s_delphes_events.lhco' % tag)):
2783
2784 self.create_plot('Delphes')
2785
2786 if os.path.exists(pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag)):
2787 misc.gzip(pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag))
2788
2789 self.update_status('delphes done', level='delphes', makehtml=False)
2790
2791
2792
2794 """Find the pid of all particles in the final and initial states"""
2795 pids = set()
2796 subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses',
2797 'subproc.mg'))]
2798 nb_init = self.ninitial
2799 pat = re.compile(r'''DATA \(IDUP\(I,\d+\),I=1,\d+\)/([\+\-\d,\s]*)/''', re.I)
2800 for Pdir in subproc:
2801 text = open(pjoin(self.me_dir, 'SubProcesses', Pdir, 'born_leshouche.inc')).read()
2802 group = pat.findall(text)
2803 for particles in group:
2804 particles = particles.split(',')
2805 pids.update(set(particles))
2806
2807 return pids
2808
2809
2834
2835
2836 if hasattr(self, 'pdffile') and self.pdffile:
2837 return self.pdffile
2838 else:
2839 for line in open(pjoin(self.me_dir,'Source','PDF','pdf_list.txt')):
2840 data = line.split()
2841 if len(data) < 4:
2842 continue
2843 if data[1].lower() == self.run_card['pdlabel'].lower():
2844 self.pdffile = check_cluster(pjoin(self.me_dir, 'lib', 'Pdfdata', data[2]))
2845 return self.pdffile
2846 else:
2847
2848 path = pjoin(self.me_dir, 'lib', 'PDFsets')
2849 if os.path.exists(path):
2850 self.pdffile = path
2851 else:
2852 self.pdffile = " "
2853 return self.pdffile
2854
2855
2865
2866
2867 - def do_set(self, line, log=True):
2868 """Set an option, which will be default for coming generations/outputs
2869 """
2870
2871
2872
2873 args = self.split_arg(line)
2874
2875 self.check_set(args)
2876
2877 if args[0] in self.options_configuration and '--no_save' not in args:
2878 self.do_save('options --auto')
2879
2880 if args[0] == "stdout_level":
2881 if args[1].isdigit():
2882 logging.root.setLevel(int(args[1]))
2883 logging.getLogger('madgraph').setLevel(int(args[1]))
2884 else:
2885 logging.root.setLevel(eval('logging.' + args[1]))
2886 logging.getLogger('madgraph').setLevel(eval('logging.' + args[1]))
2887 if log: logger.info('set output information to level: %s' % args[1])
2888 elif args[0] == "fortran_compiler":
2889 if args[1] == 'None':
2890 args[1] = None
2891 self.options['fortran_compiler'] = args[1]
2892 current = misc.detect_current_compiler(pjoin(self.me_dir,'Source','make_opts'), 'fortran')
2893 if current != args[1] and args[1] != None:
2894 misc.mod_compilator(self.me_dir, args[1], current, 'gfortran')
2895 elif args[0] == "cpp_compiler":
2896 if args[1] == 'None':
2897 args[1] = None
2898 self.options['cpp_compiler'] = args[1]
2899 current = misc.detect_current_compiler(pjoin(self.me_dir,'Source','make_opts'), 'cpp')
2900 if current != args[1] and args[1] != None:
2901 misc.mod_compilator(self.me_dir, args[1], current, 'cpp')
2902 elif args[0] == "run_mode":
2903 if not args[1] in [0,1,2,'0','1','2']:
2904 raise self.InvalidCmd, 'run_mode should be 0, 1 or 2.'
2905 self.cluster_mode = int(args[1])
2906 self.options['run_mode'] = self.cluster_mode
2907 elif args[0] in ['cluster_type', 'cluster_queue', 'cluster_temp_path']:
2908 if args[1] == 'None':
2909 args[1] = None
2910 self.options[args[0]] = args[1]
2911
2912
2913 elif args[0] in ['cluster_nb_retry', 'cluster_retry_wait', 'cluster_size']:
2914 self.options[args[0]] = int(args[1])
2915
2916 elif args[0] == 'nb_core':
2917 if args[1] == 'None':
2918 import multiprocessing
2919 self.nb_core = multiprocessing.cpu_count()
2920 self.options['nb_core'] = self.nb_core
2921 return
2922 if not args[1].isdigit():
2923 raise self.InvalidCmd('nb_core should be a positive number')
2924 self.nb_core = int(args[1])
2925 self.options['nb_core'] = self.nb_core
2926 elif args[0] == 'timeout':
2927 self.options[args[0]] = int(args[1])
2928 elif args[0] == 'cluster_status_update':
2929 if '(' in args[1]:
2930 data = ' '.join([a for a in args[1:] if not a.startswith('-')])
2931 data = data.replace('(','').replace(')','').replace(',',' ').split()
2932 first, second = data[:2]
2933 else:
2934 first, second = args[1:3]
2935
2936 self.options[args[0]] = (int(first), int(second))
2937 elif args[0] == 'notification_center':
2938 if args[1] in ['None','True','False']:
2939 self.allow_notification_center = eval(args[1])
2940 self.options[args[0]] = eval(args[1])
2941 else:
2942 raise self.InvalidCmd('Not a valid value for notification_center')
2943 elif args[0] in self.options:
2944 if args[1] in ['None','True','False']:
2945 self.options[args[0]] = ast.literal_eval(args[1])
2946 elif args[0].endswith('path'):
2947 if os.path.exists(args[1]):
2948 self.options[args[0]] = args[1]
2949 elif os.path.exists(pjoin(self.me_dir, args[1])):
2950 self.options[args[0]] = pjoin(self.me_dir, args[1])
2951 else:
2952 raise self.InvalidCmd('Not a valid path: keep previous value: \'%s\'' % self.options[args[0]])
2953 else:
2954 self.options[args[0]] = args[1]
2955
2956 - def post_set(self, stop, line):
2957 """Check if we need to save this in the option file"""
2958 try:
2959 args = self.split_arg(line)
2960 if 'cluster' in args[0] or args[0] == 'run_mode':
2961 self.configure_run_mode(self.options['run_mode'])
2962
2963
2964
2965 self.check_set(args)
2966
2967 if args[0] in self.options_configuration and '--no_save' not in args:
2968 self.exec_cmd('save options --auto')
2969 elif args[0] in self.options_madevent:
2970 logger.info('This option will be the default in any output that you are going to create in this session.')
2971 logger.info('In order to keep this changes permanent please run \'save options\'')
2972 return stop
2973 except self.InvalidCmd:
2974 return stop
2975
3041
3042
3044 """
3045 1) Check that no scan parameter are present
3046 2) Check that all the width are define in the param_card.
3047 - If a scan parameter is define. create the iterator and recall this fonction
3048 on the first element.
3049 - If some width are set on 'Auto', call the computation tools.
3050 3) if dependent is on True check for dependent parameter (automatic for scan)"""
3051
3052 pattern_scan = re.compile(r'''^(decay)?[\s\d]*scan''', re.I+re.M)
3053 pattern_width = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto(@NLO|)''',re.I)
3054 text = open(path).read()
3055
3056 if pattern_scan.search(text):
3057 if not isinstance(self, cmd.CmdShell):
3058
3059 raise Exception, "Scan are not allowed in web mode"
3060
3061 main_card = check_param_card.ParamCardIterator(text)
3062 self.param_card_iterator = main_card
3063 first_card = main_card.next(autostart=True)
3064 first_card.write(path)
3065 return self.check_param_card(path, run, dependent=True)
3066
3067 pdg_info = pattern_width.findall(text)
3068 if pdg_info:
3069 if run:
3070 logger.info('Computing the width set on auto in the param_card.dat')
3071 has_nlo = any(nlo.lower()=="@nlo" for _,nlo in pdg_info)
3072 pdg = [pdg for pdg,nlo in pdg_info]
3073 if not has_nlo:
3074 self.do_compute_widths('%s %s' % (' '.join(pdg), path))
3075 else:
3076 self.do_compute_widths('%s %s --nlo' % (' '.join(pdg), path))
3077 else:
3078 logger.info('''Some width are on Auto in the card.
3079 Those will be computed as soon as you have finish the edition of the cards.
3080 If you want to force the computation right now and being able to re-edit
3081 the cards afterwards, you can type \"compute_wdiths\".''')
3082
3083 if dependent:
3084 card = check_param_card.ParamCard(path)
3085 AskforEditCard.update_dependent(self, self.me_dir, card, path, timer=20)
3086
3087 return
3088
3090 """If a ME run is currently running add a link in the html output"""
3091
3092
3093
3094 if hasattr(self, 'results') and hasattr(self.results, 'current') and\
3095 self.results.current and 'run_name' in self.results.current and \
3096 hasattr(self, 'me_dir'):
3097 name = self.results.current['run_name']
3098 tag = self.results.current['tag']
3099 self.debug_output = pjoin(self.me_dir, '%s_%s_debug.log' % (name,tag))
3100 if errortype:
3101 self.results.current.debug = errortype
3102 else:
3103 self.results.current.debug = self.debug_output
3104
3105 else:
3106
3107 self.debug_output = CommonRunCmd.debug_output
3108 if os.path.exists('ME5_debug') and not 'ME5_debug' in self.debug_output:
3109 os.remove('ME5_debug')
3110 if not 'ME5_debug' in self.debug_output:
3111 os.system('ln -s %s ME5_debug &> /dev/null' % self.debug_output)
3112
3113
3115 """Not in help: exit """
3116
3117 if not self.force_run:
3118 try:
3119 os.remove(pjoin(self.me_dir,'RunWeb'))
3120 except Exception:
3121 pass
3122 try:
3123 self.store_result()
3124 except Exception:
3125
3126 pass
3127
3128 try:
3129 self.update_status('', level=None)
3130 except Exception, error:
3131 pass
3132 devnull = open(os.devnull, 'w')
3133 try:
3134 misc.call(['./bin/internal/gen_cardhtml-pl'], cwd=self.me_dir,
3135 stdout=devnull, stderr=devnull)
3136 except Exception:
3137 pass
3138 devnull.close()
3139
3140 return super(CommonRunCmd, self).do_quit(line)
3141
3142
3143 do_EOF = do_quit
3144 do_exit = do_quit
3145
3146
3147 - def update_status(self, status, level, makehtml=True, force=True,
3148 error=False, starttime = None, update_results=True,
3149 print_log=True):
3150 """ update the index status """
3151
3152 if makehtml and not force:
3153 if hasattr(self, 'next_update') and time.time() < self.next_update:
3154 return
3155 else:
3156 self.next_update = time.time() + 3
3157
3158 if print_log:
3159 if isinstance(status, str):
3160 if '<br>' not in status:
3161 logger.info(status)
3162 elif starttime:
3163 running_time = misc.format_timer(time.time()-starttime)
3164 logger.info(' Idle: %s, Running: %s, Completed: %s [ %s ]' % \
3165 (status[0], status[1], status[2], running_time))
3166 else:
3167 logger.info(' Idle: %s, Running: %s, Completed: %s' % status[:3])
3168
3169 if isinstance(status, str) and status.startswith('\x1b['):
3170 status = status[status.index('m')+1:-7]
3171 if 'arXiv' in status:
3172 if '[' in status:
3173 status = status.split('[',1)[0]
3174 else:
3175 status = status.split('arXiv',1)[0]
3176
3177 if update_results:
3178 self.results.update(status, level, makehtml=makehtml, error=error)
3179
3180
3182 """Ask the question when launching generate_events/multi_run"""
3183
3184 check_card = ['pythia_card.dat', 'pgs_card.dat','delphes_card.dat',
3185 'delphes_trigger.dat', 'madspin_card.dat', 'shower_card.dat',
3186 'reweight_card.dat','pythia8_card.dat',
3187 'madanalysis5_parton_card.dat','madanalysis5_hadron_card.dat',
3188 'plot_card.dat']
3189
3190 cards_path = pjoin(self.me_dir,'Cards')
3191 for card in check_card:
3192 if card in ignore or (ignore == ['*'] and card not in need_card):
3193 continue
3194 if card not in need_card:
3195 if os.path.exists(pjoin(cards_path, card)):
3196 files.mv(pjoin(cards_path, card), pjoin(cards_path, '.%s' % card))
3197 else:
3198 if not os.path.exists(pjoin(cards_path, card)):
3199 if os.path.exists(pjoin(cards_path, '.%s' % card)):
3200 files.mv(pjoin(cards_path, '.%s' % card), pjoin(cards_path, card))
3201 else:
3202 default = card.replace('.dat', '_default.dat')
3203 files.cp(pjoin(cards_path, default),pjoin(cards_path, card))
3204
3205
3206 - def set_configuration(self, config_path=None, final=True, initdir=None, amcatnlo=False):
3207 """ assign all configuration variable from file
3208 ./Cards/mg5_configuration.txt. assign to default if not define """
3209
3210 if not hasattr(self, 'options') or not self.options:
3211 self.options = dict(self.options_configuration)
3212 self.options.update(self.options_madgraph)
3213 self.options.update(self.options_madevent)
3214
3215 if not config_path:
3216 if os.environ.has_key('MADGRAPH_BASE'):
3217 config_path = pjoin(os.environ['MADGRAPH_BASE'],'mg5_configuration.txt')
3218 self.set_configuration(config_path=config_path, final=False)
3219 if 'HOME' in os.environ:
3220 config_path = pjoin(os.environ['HOME'],'.mg5',
3221 'mg5_configuration.txt')
3222 if os.path.exists(config_path):
3223 self.set_configuration(config_path=config_path, final=False)
3224 if amcatnlo:
3225 me5_config = pjoin(self.me_dir, 'Cards', 'amcatnlo_configuration.txt')
3226 else:
3227 me5_config = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
3228 self.set_configuration(config_path=me5_config, final=False, initdir=self.me_dir)
3229
3230 if self.options.has_key('mg5_path') and self.options['mg5_path']:
3231 MG5DIR = self.options['mg5_path']
3232 config_file = pjoin(MG5DIR, 'input', 'mg5_configuration.txt')
3233 self.set_configuration(config_path=config_file, final=False,initdir=MG5DIR)
3234 else:
3235 self.options['mg5_path'] = None
3236 return self.set_configuration(config_path=me5_config, final=final,initdir=self.me_dir)
3237
3238 config_file = open(config_path)
3239
3240
3241 logger.info('load configuration from %s ' % config_file.name)
3242 for line in config_file:
3243
3244 if '#' in line:
3245 line = line.split('#',1)[0]
3246 line = line.replace('\n','').replace('\r\n','')
3247 try:
3248 name, value = line.split('=')
3249 except ValueError:
3250 pass
3251 else:
3252 name = name.strip()
3253 value = value.strip()
3254 if name.endswith('_path') and not name.startswith('cluster'):
3255 path = value
3256 if os.path.isdir(path):
3257 self.options[name] = os.path.realpath(path)
3258 continue
3259 if not initdir:
3260 continue
3261 path = pjoin(initdir, value)
3262 if os.path.isdir(path):
3263 self.options[name] = os.path.realpath(path)
3264 continue
3265 else:
3266 self.options[name] = value
3267 if value.lower() == "none":
3268 self.options[name] = None
3269
3270 if not final:
3271 return self.options
3272
3273
3274
3275 for key in self.options:
3276
3277 if key.endswith('path') and not key.startswith("cluster"):
3278 path = self.options[key]
3279 if path is None:
3280 continue
3281 if os.path.isdir(path):
3282 self.options[key] = os.path.realpath(path)
3283 continue
3284 path = pjoin(self.me_dir, self.options[key])
3285 if os.path.isdir(path):
3286 self.options[key] = os.path.realpath(path)
3287 continue
3288 elif self.options.has_key('mg5_path') and self.options['mg5_path']:
3289 path = pjoin(self.options['mg5_path'], self.options[key])
3290 if os.path.isdir(path):
3291 self.options[key] = os.path.realpath(path)
3292 continue
3293 self.options[key] = None
3294 elif key.startswith('cluster') and key != 'cluster_status_update':
3295 if key in ('cluster_nb_retry','cluster_wait_retry'):
3296 self.options[key] = int(self.options[key])
3297 if hasattr(self,'cluster'):
3298 del self.cluster
3299 pass
3300 elif key == 'automatic_html_opening':
3301 if self.options[key] in ['False', 'True']:
3302 self.options[key] =ast.literal_eval(self.options[key])
3303 elif key == "notification_center":
3304 if self.options[key] in ['False', 'True']:
3305 self.allow_notification_center =ast.literal_eval(self.options[key])
3306 self.options[key] =ast.literal_eval(self.options[key])
3307 elif key not in ['text_editor','eps_viewer','web_browser','stdout_level',
3308 'complex_mass_scheme', 'gauge', 'group_subprocesses']:
3309
3310 try:
3311 self.do_set("%s %s --no_save" % (key, self.options[key]), log=False)
3312 except self.InvalidCmd:
3313 logger.warning("Option %s from config file not understood" \
3314 % key)
3315
3316
3317 misc.open_file.configure(self.options)
3318 self.configure_run_mode(self.options['run_mode'])
3319 return self.options
3320
3321 @staticmethod
3323 """ find a valid run_name for the current job """
3324
3325 name = 'run_%02d'
3326 data = [int(s[4:j]) for s in os.listdir(pjoin(me_dir,'Events')) for
3327 j in range(4,len(s)+1) if \
3328 s.startswith('run_') and s[4:j].isdigit()]
3329 return name % (max(data+[0])+1)
3330
3331
3332
3334 """Require MG5 directory: decay events with spin correlations
3335 """
3336
3337 if '-from_cards' in line and not os.path.exists(pjoin(self.me_dir, 'Cards', 'madspin_card.dat')):
3338 return
3339
3340
3341
3342
3343 if MADEVENT and not self.options['mg5_path']:
3344 raise self.InvalidCmd, '''The module decay_events requires that MG5 is installed on the system.
3345 You can install it and set its path in ./Cards/me5_configuration.txt'''
3346 elif MADEVENT:
3347 sys.path.append(self.options['mg5_path'])
3348 try:
3349 import MadSpin.decay as decay
3350 import MadSpin.interface_madspin as interface_madspin
3351 except ImportError:
3352 if __debug__:
3353 raise
3354 else:
3355 raise self.ConfigurationError, '''Can\'t load MadSpin
3356 The variable mg5_path might not be correctly configured.'''
3357
3358 self.update_status('Running MadSpin', level='madspin')
3359 if not '-from_cards' in line:
3360 self.keep_cards(['madspin_card.dat'], ignore=['*'])
3361 self.ask_edit_cards(['madspin_card.dat'], 'fixed', plot=False)
3362 self.help_decay_events(skip_syntax=True)
3363
3364
3365 args = self.split_arg(line)
3366 self.check_decay_events(args)
3367
3368 madspin_cmd = interface_madspin.MadSpinInterface(args[0])
3369 madspin_cmd.update_status = lambda *x,**opt: self.update_status(*x, level='madspin',**opt)
3370
3371 path = pjoin(self.me_dir, 'Cards', 'madspin_card.dat')
3372
3373 madspin_cmd.import_command_file(path)
3374
3375
3376 i = 1
3377 while os.path.exists(pjoin(self.me_dir,'Events', '%s_decayed_%i' % (self.run_name,i))):
3378 i+=1
3379 new_run = '%s_decayed_%i' % (self.run_name,i)
3380 evt_dir = pjoin(self.me_dir, 'Events')
3381
3382 os.mkdir(pjoin(evt_dir, new_run))
3383 current_file = args[0].replace('.lhe', '_decayed.lhe')
3384 new_file = pjoin(evt_dir, new_run, os.path.basename(args[0]))
3385 if not os.path.exists(current_file):
3386 if os.path.exists(current_file+'.gz'):
3387 current_file += '.gz'
3388 new_file += '.gz'
3389 else:
3390 logger.error('MadSpin fails to create any decayed file.')
3391 return
3392
3393 files.mv(current_file, new_file)
3394 logger.info("The decayed event file has been moved to the following location: ")
3395 logger.info(new_file)
3396
3397 if hasattr(self, 'results'):
3398 current = self.results.current
3399 nb_event = self.results.current['nb_event']
3400 if not nb_event:
3401 current = self.results[self.run_name][0]
3402 nb_event = current['nb_event']
3403
3404 cross = current['cross']
3405 error = current['error']
3406 self.results.add_run( new_run, self.run_card)
3407 self.results.add_detail('nb_event', int(nb_event*madspin_cmd.efficiency))
3408 self.results.add_detail('cross', madspin_cmd.cross)
3409 self.results.add_detail('error', madspin_cmd.error+ cross * madspin_cmd.err_branching_ratio)
3410 self.results.add_detail('run_mode', current['run_mode'])
3411
3412 self.run_name = new_run
3413 self.banner = madspin_cmd.banner
3414 self.banner.add(path)
3415 self.banner.write(pjoin(self.me_dir,'Events',self.run_name, '%s_%s_banner.txt' %
3416 (self.run_name, self.run_tag)))
3417 self.update_status('MadSpin Done', level='parton', makehtml=False)
3418 if 'unweighted' in os.path.basename(args[0]):
3419 self.create_plot('parton')
3420
3427
3429 "Complete the print results command"
3430 args = self.split_arg(line[0:begidx], error=False)
3431 if len(args) == 1:
3432
3433 data = misc.glob(pjoin('*','unweighted_events.lhe.gz'),
3434 pjoin(self.me_dir, 'Events'))
3435
3436 data = [n.rsplit('/',2)[1] for n in data]
3437 tmp1 = self.list_completion(text, data)
3438 return tmp1
3439 else:
3440 data = misc.glob('*_pythia_events.hep.gz', pjoin(self.me_dir, 'Events', args[0]))
3441 data = [os.path.basename(p).rsplit('_',1)[0] for p in data]
3442 data += ["--mode=a", "--mode=w", "--path=", "--format=short"]
3443 tmp1 = self.list_completion(text, data)
3444 return tmp1
3445
3447 logger.info("syntax: print_result [RUN] [TAG] [options]")
3448 logger.info("-- show in text format the status of the run (cross-section/nb-event/...)")
3449 logger.info("--path= defines the path of the output file.")
3450 logger.info("--mode=a allow to add the information at the end of the file.")
3451 logger.info("--format=short (only if --path is define)")
3452 logger.info(" allows to have a multi-column output easy to parse")
3453
3454
3480
3481
3483 args = self.split_arg(line[0:begidx], error=False)
3484
3485 if len(args) == 1 and os.path.sep not in text:
3486
3487 data = misc.glob(pjoin('*','*events.lhe*'), pjoin(self.me_dir, 'Events'))
3488 data = [n.rsplit('/',2)[1] for n in data]
3489 return self.list_completion(text, data, line)
3490 else:
3491 return self.path_completion(text,
3492 os.path.join('.',*[a for a in args \
3493 if a.endswith(os.path.sep)]))
3494
3506
3507
3508
3510 "Complete the compute_widths command"
3511
3512 args = self.split_arg(line[0:begidx])
3513
3514 if args[-1] in ['--path=', '--output=']:
3515 completion = {'path': self.path_completion(text)}
3516 elif line[begidx-1] == os.path.sep:
3517 current_dir = pjoin(*[a for a in args if a.endswith(os.path.sep)])
3518 if current_dir.startswith('--path='):
3519 current_dir = current_dir[7:]
3520 if current_dir.startswith('--output='):
3521 current_dir = current_dir[9:]
3522 completion = {'path': self.path_completion(text, current_dir)}
3523 else:
3524 completion = {}
3525 completion['options'] = self.list_completion(text,
3526 ['--path=', '--output=', '--min_br=0.\$', '--nlo',
3527 '--precision_channel=0.\$', '--body_decay='])
3528
3529 return self.deal_multiple_categories(completion, formatting)
3530
3531
3533 """update the make_opts file writing the environmental variables
3534 stored in make_opts_var"""
3535 make_opts = os.path.join(self.me_dir, 'Source', 'make_opts')
3536
3537
3538 if not hasattr(self,'options') or not 'pythia8_path' in self.options or \
3539 not self.options['pythia8_path'] or \
3540 not os.path.isfile(pjoin(self.options['pythia8_path'],'bin','pythia8-config')):
3541 self.make_opts_var['PYTHIA8_PATH']='NotInstalled'
3542 else:
3543 self.make_opts_var['PYTHIA8_PATH']=self.options['pythia8_path']
3544
3545 self.make_opts_var['MG5AMC_VERSION'] = misc.get_pkg_info()['version']
3546
3547 return self.update_make_opts_full(make_opts, self.make_opts_var)
3548
3549 @staticmethod
3551 """update the make_opts file writing the environmental variables
3552 of def_variables.
3553 if a value of the dictionary is None then it is not written.
3554 """
3555 make_opts = path
3556 pattern = re.compile(r'^(\w+)\s*=\s*(.*)$',re.DOTALL)
3557 diff = False
3558
3559
3560 tag = '#end_of_make_opts_variables\n'
3561 make_opts_variable = True
3562 content = []
3563 variables = dict(def_variables)
3564 need_keys = variables.keys()
3565 for line in open(make_opts):
3566 line = line.strip()
3567 if make_opts_variable:
3568 if line.startswith('#') or not line:
3569 if line.startswith('#end_of_make_opts_variables'):
3570 make_opts_variable = False
3571 continue
3572 elif pattern.search(line):
3573 key, value = pattern.search(line).groups()
3574 if key not in variables:
3575 variables[key] = value
3576 elif value != variables[key]:
3577 diff=True
3578 else:
3579 need_keys.remove(key)
3580 else:
3581 make_opts_variable = False
3582 content.append(line)
3583 else:
3584 content.append(line)
3585
3586 if need_keys:
3587 diff=True
3588
3589 content_variables = '\n'.join('%s=%s' % (k,v) for k, v in variables.items() if v is not None)
3590 content_variables += '\n%s' % tag
3591
3592 if diff:
3593 with open(make_opts, 'w') as fsock:
3594 fsock.write(content_variables + '\n'.join(content))
3595 return
3596
3597
3598
3600 """links lhapdf into libdir"""
3601
3602 lhapdf_version = self.get_lhapdf_version()
3603 logger.info('Using LHAPDF v%s interface for PDFs' % lhapdf_version)
3604 lhalibdir = subprocess.Popen([self.options['lhapdf'], '--libdir'],
3605 stdout = subprocess.PIPE).stdout.read().strip()
3606
3607 if lhapdf_version.startswith('5.'):
3608 pdfsetsdir = subprocess.Popen([self.options['lhapdf'], '--pdfsets-path'],
3609 stdout = subprocess.PIPE).stdout.read().strip()
3610 else:
3611 pdfsetsdir = subprocess.Popen([self.options['lhapdf'], '--datadir'],
3612 stdout = subprocess.PIPE).stdout.read().strip()
3613
3614 self.lhapdf_pdfsets = self.get_lhapdf_pdfsets_list(pdfsetsdir)
3615
3616 lhalib = 'libLHAPDF.a'
3617
3618 if os.path.exists(pjoin(libdir, lhalib)):
3619 files.rm(pjoin(libdir, lhalib))
3620 files.ln(pjoin(lhalibdir, lhalib), libdir)
3621
3622 if not os.path.isdir(pjoin(libdir, 'PDFsets')):
3623 os.mkdir(pjoin(libdir, 'PDFsets'))
3624 self.make_opts_var['lhapdf'] = self.options['lhapdf']
3625 self.make_opts_var['lhapdfversion'] = lhapdf_version[0]
3626 self.make_opts_var['lhapdf_config'] = self.options['lhapdf']
3627
3628
3630 """reads the proc_characteristics file and initialises the correspondant
3631 dictionary"""
3632
3633 if not path:
3634 path = os.path.join(self.me_dir, 'SubProcesses', 'proc_characteristics')
3635
3636 self.proc_characteristics = banner_mod.ProcCharacteristic(path)
3637 return self.proc_characteristics
3638
3639
3641 """copy (if needed) the lhapdf set corresponding to the lhaid in lhaid_list
3642 into lib/PDFsets"""
3643
3644 if not hasattr(self, 'lhapdf_pdfsets'):
3645 self.lhapdf_pdfsets = self.get_lhapdf_pdfsets_list(pdfsets_dir)
3646
3647 pdfsetname=set()
3648 for lhaid in lhaid_list:
3649 if isinstance(lhaid, str) and lhaid.isdigit():
3650 lhaid = int(lhaid)
3651 if isinstance(lhaid, (int,float)):
3652 try:
3653 if lhaid in self.lhapdf_pdfsets:
3654 pdfsetname.add(self.lhapdf_pdfsets[lhaid]['filename'])
3655 else:
3656 raise MadGraph5Error('lhaid %s not valid input number for the current lhapdf' % lhaid )
3657 except KeyError:
3658 if self.lhapdf_version.startswith('5'):
3659 raise MadGraph5Error(\
3660 ('invalid lhaid set in th run_card: %d .\nPlease note that some sets' % lhaid) + \
3661 '(eg MSTW 90%CL error sets) \nare not available in aMC@NLO + LHAPDF 5.x.x')
3662 else:
3663 logger.debug('%d not found in pdfsets.index' % lhaid)
3664 else:
3665 pdfsetname.add(lhaid)
3666
3667
3668
3669
3670 if not os.path.isdir(pdfsets_dir):
3671 try:
3672 os.mkdir(pdfsets_dir)
3673 except OSError:
3674 pdfsets_dir = pjoin(self.me_dir, 'lib', 'PDFsets')
3675 elif os.path.exists(pjoin(self.me_dir, 'lib', 'PDFsets')):
3676
3677 for name in os.listdir(pjoin(self.me_dir, 'lib', 'PDFsets')):
3678 if name not in pdfsetname:
3679 try:
3680 if os.path.isdir(pjoin(self.me_dir, 'lib', 'PDFsets', name)):
3681 shutil.rmtree(pjoin(self.me_dir, 'lib', 'PDFsets', name))
3682 else:
3683 os.remove(pjoin(self.me_dir, 'lib', 'PDFsets', name))
3684 except Exception, error:
3685 logger.debug('%s', error)
3686
3687 if self.options["cluster_local_path"]:
3688 lhapdf_cluster_possibilities = [self.options["cluster_local_path"],
3689 pjoin(self.options["cluster_local_path"], "lhapdf"),
3690 pjoin(self.options["cluster_local_path"], "lhapdf", "pdfsets"),
3691 pjoin(self.options["cluster_local_path"], "..", "lhapdf"),
3692 pjoin(self.options["cluster_local_path"], "..", "lhapdf", "pdfsets"),
3693 pjoin(self.options["cluster_local_path"], "..", "lhapdf","pdfsets", "6.1")
3694 ]
3695 else:
3696 lhapdf_cluster_possibilities = []
3697
3698 for pdfset in pdfsetname:
3699
3700 if self.options["cluster_local_path"] and self.options["run_mode"] == 1 and \
3701 any((os.path.exists(pjoin(d, pdfset)) for d in lhapdf_cluster_possibilities)):
3702
3703 os.environ["LHAPATH"] = [d for d in lhapdf_cluster_possibilities if os.path.exists(pjoin(d, pdfset))][0]
3704 os.environ["CLUSTER_LHAPATH"] = os.environ["LHAPATH"]
3705
3706 if os.path.exists(pjoin(pdfsets_dir, pdfset)):
3707 try:
3708 if os.path.isdir(pjoin(pdfsets_dir, name)):
3709 shutil.rmtree(pjoin(pdfsets_dir, name))
3710 else:
3711 os.remove(pjoin(pdfsets_dir, name))
3712 except Exception, error:
3713 logger.debug('%s', error)
3714
3715
3716 elif not os.path.exists(pjoin(self.me_dir, 'lib', 'PDFsets', pdfset)) and \
3717 not os.path.isdir(pjoin(self.me_dir, 'lib', 'PDFsets', pdfset)):
3718
3719 if pdfset and not os.path.exists(pjoin(pdfsets_dir, pdfset)):
3720 self.install_lhapdf_pdfset(pdfsets_dir, pdfset)
3721
3722 if os.path.exists(pjoin(pdfsets_dir, pdfset)):
3723 files.cp(pjoin(pdfsets_dir, pdfset), pjoin(self.me_dir, 'lib', 'PDFsets'))
3724 elif os.path.exists(pjoin(os.path.dirname(pdfsets_dir), pdfset)):
3725 files.cp(pjoin(os.path.dirname(pdfsets_dir), pdfset), pjoin(self.me_dir, 'lib', 'PDFsets'))
3726
3728 """idownloads and install the pdfset filename in the pdfsets_dir"""
3729 lhapdf_version = self.get_lhapdf_version()
3730 local_path = pjoin(self.me_dir, 'lib', 'PDFsets')
3731 return self.install_lhapdf_pdfset_static(self.options['lhapdf'],
3732 pdfsets_dir, filename,
3733 lhapdf_version=lhapdf_version,
3734 alternate_path=local_path)
3735
3736
3737 @staticmethod
3740 """idownloads and install the pdfset filename in the pdfsets_dir.
3741 Version which can be used independently of the class.
3742 local path is used if the global installation fails.
3743 """
3744
3745 if not lhapdf_version:
3746 lhapdf_version = subprocess.Popen([lhapdf_config, '--version'],
3747 stdout = subprocess.PIPE).stdout.read().strip()
3748 if not pdfsets_dir:
3749 pdfsets_dir = subprocess.Popen([lhapdf_config, '--datadir'],
3750 stdout = subprocess.PIPE).stdout.read().strip()
3751
3752 if isinstance(filename, int):
3753 pdf_info = CommonRunCmd.get_lhapdf_pdfsets_list_static(pdfsets_dir, lhapdf_version)
3754 filename = pdf_info[filename]['filename']
3755
3756 if os.path.exists(pjoin(pdfsets_dir, filename)):
3757 logger.debug('%s is already present in %s', filename, pdfsets_dir)
3758 return
3759
3760 logger.info('Trying to download %s' % filename)
3761
3762 if lhapdf_version.startswith('5.'):
3763
3764
3765
3766 getdata = lhapdf_config.replace('lhapdf-config', ('lhapdf-getdata'))
3767 misc.call([getdata, filename], cwd = pdfsets_dir)
3768
3769 elif lhapdf_version.startswith('6.'):
3770
3771
3772 getdata = lhapdf_config.replace('lhapdf-config', ('lhapdf'))
3773
3774 misc.call([getdata, 'install', filename], cwd = pdfsets_dir)
3775
3776 else:
3777 raise MadGraph5Error('Not valid LHAPDF version: %s' % lhapdf_version)
3778
3779
3780 if os.path.exists(pjoin(pdfsets_dir, filename)) or \
3781 os.path.isdir(pjoin(pdfsets_dir, filename)):
3782 logger.info('%s successfully downloaded and stored in %s' \
3783 % (filename, pdfsets_dir))
3784
3785 elif lhapdf_version.startswith('5.'):
3786 logger.warning('Could not download %s into %s. Trying to save it locally' \
3787 % (filename, pdfsets_dir))
3788 CommonRunCmd.install_lhapdf_pdfset_static(lhapdf_config, alternate_path, filename,
3789 lhapdf_version=lhapdf_version)
3790 elif lhapdf_version.startswith('6.') and '.LHgrid' in filename:
3791 logger.info('Could not download %s: Try %s', filename, filename.replace('.LHgrid',''))
3792 return CommonRunCmd.install_lhapdf_pdfset_static(lhapdf_config, pdfsets_dir,
3793 filename.replace('.LHgrid',''),
3794 lhapdf_version, alternate_path)
3795
3796 else:
3797 raise MadGraph5Error, \
3798 'Could not download %s into %s. Please try to install it manually.' \
3799 % (filename, pdfsets_dir)
3800
3801
3802
3804 """read the PDFsets.index file, which should be located in the same
3805 place as pdfsets_dir, and return a list of dictionaries with the information
3806 about each pdf set"""
3807 lhapdf_version = self.get_lhapdf_version()
3808 return self.get_lhapdf_pdfsets_list_static(pdfsets_dir, lhapdf_version)
3809
3810 @staticmethod
3812
3813 if lhapdf_version.startswith('5.'):
3814 if os.path.exists('%s.index' % pdfsets_dir):
3815 indexfile = '%s.index' % pdfsets_dir
3816 else:
3817 raise MadGraph5Error, 'index of lhapdf file not found'
3818 pdfsets_lines = \
3819 [l for l in open(indexfile).read().split('\n') if l.strip() and \
3820 not '90cl' in l]
3821 lhapdf_pdfsets = dict( (int(l.split()[0]), {'lhaid': int(l.split()[0]),
3822 'pdflib_ntype': int(l.split()[1]),
3823 'pdflib_ngroup': int(l.split()[2]),
3824 'pdflib_nset': int(l.split()[3]),
3825 'filename': l.split()[4],
3826 'lhapdf_nmem': int(l.split()[5]),
3827 'q2min': float(l.split()[6]),
3828 'q2max': float(l.split()[7]),
3829 'xmin': float(l.split()[8]),
3830 'xmax': float(l.split()[9]),
3831 'description': l.split()[10]}) \
3832 for l in pdfsets_lines)
3833
3834 elif lhapdf_version.startswith('6.'):
3835 pdfsets_lines = \
3836 [l for l in open(pjoin(pdfsets_dir, 'pdfsets.index')).read().split('\n') if l.strip()]
3837 lhapdf_pdfsets = dict( (int(l.split()[0]),
3838 {'lhaid': int(l.split()[0]),
3839 'filename': l.split()[1]}) \
3840 for l in pdfsets_lines)
3841
3842 else:
3843 raise MadGraph5Error('Not valid LHAPDF version: %s' % lhapdf_version)
3844
3845 return lhapdf_pdfsets
3846
3847
3849 """returns the lhapdf version number"""
3850 if not hasattr(self, 'lhapdfversion'):
3851 try:
3852 self.lhapdf_version = \
3853 subprocess.Popen([self.options['lhapdf'], '--version'],
3854 stdout = subprocess.PIPE).stdout.read().strip()
3855 except OSError, error:
3856 if error.errno == 2:
3857 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']
3858 else:
3859 raise
3860
3861
3862 if self.lhapdf_version.startswith('6.0'):
3863 raise MadGraph5Error('LHAPDF 6.0.x not supported. Please use v6.1 or later')
3864
3865 return self.lhapdf_version
3866
3867
3869 lhapdf_version = self.get_lhapdf_version()
3870
3871
3872 if 'LHAPDF_DATA_PATH' in os.environ.keys() and os.environ['LHAPDF_DATA_PATH']:
3873 datadir = os.environ['LHAPDF_DATA_PATH']
3874
3875 elif lhapdf_version.startswith('5.'):
3876 datadir = subprocess.Popen([self.options['lhapdf'], '--pdfsets-path'],
3877 stdout = subprocess.PIPE).stdout.read().strip()
3878
3879 elif lhapdf_version.startswith('6.'):
3880 datadir = subprocess.Popen([self.options['lhapdf'], '--datadir'],
3881 stdout = subprocess.PIPE).stdout.read().strip()
3882
3883 return datadir
3884
3886 lhapdf_version = self.get_lhapdf_version()
3887
3888 if lhapdf_version.startswith('5.'):
3889 libdir = subprocess.Popen([self.options['lhapdf-config'], '--libdir'],
3890 stdout = subprocess.PIPE).stdout.read().strip()
3891
3892 elif lhapdf_version.startswith('6.'):
3893 libdir = subprocess.Popen([self.options['lhapdf'], '--libs'],
3894 stdout = subprocess.PIPE).stdout.read().strip()
3895
3896 return libdir
3897
3899 """A class for asking a question where in addition you can have the
3900 set command define and modifying the param_card/run_card correctly"""
3901
3902 all_card_name = ['param_card', 'run_card', 'pythia_card', 'pythia8_card',
3903 'madweight_card', 'MadLoopParams', 'shower_card']
3904
3905 special_shortcut = {'ebeam':([float],['run_card ebeam1 %(0)s', 'run_card ebeam2 %(0)s']),
3906 'lpp': ([int],['run_card lpp1 %(0)s', 'run_card lpp2 %(0)s' ]),
3907 'lhc': ([int],['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2']),
3908 'lep': ([int],['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2']),
3909 'ilc': ([int],['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2']),
3910 'lcc': ([int],['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2']),
3911 'fixed_scale': ([float],['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']),
3912 'simplepy8':([],['pythia8_card hadronlevel:all False',
3913 'pythia8_card partonlevel:mpi False',
3914 'pythia8_card BeamRemnants:primordialKT False',
3915 'pythia8_card PartonLevel:Remnants False',
3916 'pythia8_card Check:event False',
3917 'pythia8_card TimeShower:QEDshowerByQ False',
3918 'pythia8_card TimeShower:QEDshowerByL False',
3919 'pythia8_card SpaceShower:QEDshowerByQ False',
3920 'pythia8_card SpaceShower:QEDshowerByL False',
3921 'pythia8_card PartonLevel:FSRinResonances False',
3922 'pythia8_card ProcessLevel:resonanceDecays False',
3923 ]),
3924 'mpi':([bool],['pythia8_card partonlevel:mpi %(0)s'])
3925 }
3926
3927 special_shortcut_help = {
3928 'ebeam' : 'syntax: set ebeam VALUE:\n This parameter sets the energy to both beam to the value in GeV',
3929 'lpp' : 'syntax: set ebeam VALUE:\n'+\
3930 ' Set the type of beam to a given value for both beam\n'+\
3931 ' 0 : means no PDF\n'+\
3932 ' 1 : means proton PDF\n'+\
3933 ' -1 : means antiproton PDF\n'+\
3934 ' 2 : means PDF for elastic photon emited from a proton\n'+\
3935 ' 3 : means PDF for elastic photon emited from an electron',
3936 'lhc' : 'syntax: set lhc VALUE:\n Set for a proton-proton collision with that given center of mass energy (in TeV)',
3937 'lep' : 'syntax: set lep VALUE:\n Set for a electron-positron collision with that given center of mass energy (in GeV)',
3938 'fixed_scale' : 'syntax: set fixed_scale VALUE:\n Set all scales to the give value (in GeV)',
3939 'simplepy8' : 'Turn off non-perturbative slow features of Pythia8.',
3940 'mpi' : 'syntax: set mpi value: allow to turn mpi in Pythia8 on/off'
3941 }
3942
3944 """ define all default variable. No load of card here.
3945 This allow to subclass this class and just change init and still have
3946 all variables defined."""
3947
3948 self.me_dir = None
3949 self.param_card = None
3950 self.run_card = {}
3951 self.pname2block = {}
3952 self.conflict = []
3953 self.restricted_value = {}
3954 self.mode = ''
3955 self.cards = []
3956 self.run_set = []
3957 self.has_mw = False
3958 self.has_ml = False
3959 self.has_shower = False
3960 self.has_PY8 = False
3961 self.paths = {}
3962
3963
3965
3966 if 'pwd' in opt:
3967 self.me_dir = opt['pwd']
3968 elif 'mother_interface' in opt:
3969 self.mother_interface = opt['mother_interface']
3970 if not hasattr(self, 'me_dir') or not self.me_dir:
3971 self.me_dir = self.mother_interface.me_dir
3972
3973
3974 self.paths['param'] = pjoin(self.me_dir,'Cards','param_card.dat')
3975 self.paths['param_default'] = pjoin(self.me_dir,'Cards','param_card_default.dat')
3976 self.paths['run'] = pjoin(self.me_dir,'Cards','run_card.dat')
3977 self.paths['run_default'] = pjoin(self.me_dir,'Cards','run_card_default.dat')
3978 self.paths['transfer'] =pjoin(self.me_dir,'Cards','transfer_card.dat')
3979 self.paths['MadWeight'] =pjoin(self.me_dir,'Cards','MadWeight_card.dat')
3980 self.paths['MadWeight_default'] =pjoin(self.me_dir,'Cards','MadWeight_card_default.dat')
3981 self.paths['ML'] =pjoin(self.me_dir,'Cards','MadLoopParams.dat')
3982 self.paths['shower'] = pjoin(self.me_dir,'Cards','shower_card.dat')
3983 self.paths['shower_default'] = pjoin(self.me_dir,'Cards','shower_card_default.dat')
3984 self.paths['pythia'] =pjoin(self.me_dir, 'Cards','pythia_card.dat')
3985 self.paths['PY8'] = pjoin(self.me_dir, 'Cards','pythia8_card.dat')
3986 self.paths['PY8_default'] = pjoin(self.me_dir, 'Cards','pythia8_card_default.dat')
3987 self.paths['madspin_default'] = pjoin(self.me_dir,'Cards/madspin_card_default.dat')
3988 self.paths['madspin'] = pjoin(self.me_dir,'Cards/madspin_card.dat')
3989 self.paths['reweight'] = pjoin(self.me_dir,'Cards','reweight_card.dat')
3990 self.paths['delphes'] = pjoin(self.me_dir,'Cards','delphes_card.dat')
3991 self.paths['plot'] = pjoin(self.me_dir,'Cards','plot_card.dat')
3992 self.paths['plot_default'] = pjoin(self.me_dir,'Cards','plot_card_default.dat')
3993 self.paths['madanalysis5_parton'] = pjoin(self.me_dir,'Cards','madanalysis5_parton_card.dat')
3994 self.paths['madanalysis5_hadron'] = pjoin(self.me_dir,'Cards','madanalysis5_hadron_card.dat')
3995 self.paths['madanalysis5_parton_default'] = pjoin(self.me_dir,'Cards','madanalysis5_parton_card_default.dat')
3996 self.paths['madanalysis5_hadron_default'] = pjoin(self.me_dir,'Cards','madanalysis5_hadron_card_default.dat')
3997
3998 - def __init__(self, question, cards=[], mode='auto', *args, **opt):
3999
4000 self.load_default()
4001 self.define_paths(**opt)
4002 cmd.OneLinePathCompletion.__init__(self, question, *args, **opt)
4003
4004
4005 try:
4006 self.param_card = check_param_card.ParamCard(self.paths['param'])
4007 except (check_param_card.InvalidParamCard, ValueError) as e:
4008 logger.error('Current param_card is not valid. We are going to use the default one.')
4009 logger.error('problem detected: %s' % e)
4010 files.cp(self.paths['param_default'], self.paths['param'])
4011 self.param_card = check_param_card.ParamCard(self.paths['param'])
4012 default_param = check_param_card.ParamCard(self.paths['param_default'])
4013 self.param_card_default = default_param
4014
4015 try:
4016 self.run_card = banner_mod.RunCard(self.paths['run'], consistency='warning')
4017 except IOError:
4018 self.run_card = {}
4019 try:
4020 run_card_def = banner_mod.RunCard(self.paths['run_default'])
4021 except IOError:
4022 run_card_def = {}
4023
4024 self.pname2block = {}
4025 self.conflict = []
4026 self.restricted_value = {}
4027 self.mode = mode
4028 self.cards = cards
4029
4030
4031
4032
4033 self.pname2block, self.restricted_value = \
4034 default_param.analyze_param_card()
4035
4036 if run_card_def:
4037 self.run_set = run_card_def.keys() + self.run_card.hidden_param
4038 elif self.run_card:
4039 self.run_set = self.run_card.keys()
4040 else:
4041 self.run_set = []
4042
4043 for var in self.pname2block:
4044 if var in self.run_set:
4045 self.conflict.append(var)
4046
4047
4048 self.has_delphes = False
4049 if 'delphes_card.dat' in cards:
4050 self.has_delphes = True
4051
4052
4053 self.has_mw = False
4054 if 'madweight_card.dat' in cards:
4055
4056 self.do_change_tf = self.mother_interface.do_define_transfer_fct
4057 self.complete_change_tf = self.mother_interface.complete_define_transfer_fct
4058 self.help_change_tf = self.mother_interface.help_define_transfer_fct
4059 if not os.path.exists(self.paths['transfer']):
4060 logger.warning('No transfer function currently define. Please use the change_tf command to define one.')
4061
4062
4063 self.has_mw = True
4064 try:
4065 import madgraph.madweight.Cards as mwcards
4066 except:
4067 import internal.madweight.Cards as mwcards
4068 self.mw_card = mwcards.Card(self.paths['MadWeight'])
4069 self.mw_card = self.mw_card.info
4070 self.mw_vars = []
4071 for key in self.mw_card:
4072 if key == 'comment':
4073 continue
4074 for key2 in self.mw_card.info[key]:
4075 if isinstance(key2, str) and not key2.isdigit():
4076 self.mw_vars.append(key2)
4077
4078
4079 for var in self.pname2block:
4080 if var in self.mw_vars:
4081 self.conflict.append(var)
4082 for var in self.mw_vars:
4083 if var in self.run_card:
4084 self.conflict.append(var)
4085
4086
4087 self.has_ml = False
4088 if os.path.isfile(self.paths['ML']):
4089 self.has_ml = True
4090 self.MLcard = banner_mod.MadLoopParam(self.paths['ML'])
4091 self.MLcardDefault = banner_mod.MadLoopParam()
4092
4093 self.ml_vars = [k.lower() for k in self.MLcard.keys()]
4094
4095 for var in self.ml_vars:
4096 if var in self.run_card:
4097 self.conflict.append(var)
4098 if var in self.pname2block:
4099 self.conflict.append(var)
4100 if self.has_mw and var in self.mw_vars:
4101 self.conflict.append(var)
4102
4103
4104 self.has_shower = False
4105 if 'shower_card.dat' in cards:
4106 self.has_shower = True
4107 try:
4108 import madgraph.various.shower_card as showercards
4109 except:
4110 import internal.shower_card as showercards
4111 self.shower_card = showercards.ShowerCard(self.paths['shower'])
4112 self.shower_vars = self.shower_card.keys()
4113
4114
4115 for var in self.pname2block:
4116 if var in self.shower_vars:
4117 self.conflict.append(var)
4118 for var in self.shower_vars:
4119 if var in self.run_card:
4120 self.conflict.append(var)
4121
4122
4123 self.has_PY8 = False
4124 if 'pythia8_card.dat' in cards:
4125 self.has_PY8 = True
4126 self.PY8Card = banner_mod.PY8Card(self.paths['PY8'])
4127 self.PY8CardDefault = banner_mod.PY8Card()
4128
4129 self.py8_vars = [k.lower() for k in self.PY8Card.keys()]
4130
4131 for var in self.py8_vars:
4132 if var in self.run_card:
4133 self.conflict.append(var)
4134 if var in self.pname2block:
4135 self.conflict.append(var)
4136 if self.has_mw and var in self.mw_vars:
4137 self.conflict.append(var)
4138 if self.has_ml and var in self.ml_vars:
4139 self.conflict.append(var)
4140
4141 - def do_help(self, line, conflict_raise=False, banner=True):
4142
4143 if banner:
4144 logger.info('*** HELP MESSAGE ***', '$MG:color:BLACK')
4145
4146 args = self.split_arg(line)
4147
4148 if len(args)==0 or (len(args) == 1 and hasattr(self, 'do_%s' % args[0])):
4149 out = cmd.BasicCmd.do_help(self, line)
4150 if len(args)==0:
4151 print 'Allowed Argument'
4152 print '================'
4153 print '\t'.join(self.allow_arg)
4154 print
4155 print 'Special shortcut: (type help <name>)'
4156 print '===================================='
4157 print ' syntax: set <name> <value>'
4158 print '\t'.join(self.special_shortcut)
4159 print
4160 if banner:
4161 logger.info('*** END HELP ***', '$MG:color:BLACK')
4162 return out
4163
4164
4165 if args[0] in self.special_shortcut:
4166 if args[0] in self.special_shortcut_help:
4167 print self.special_shortcut_help[args[0]]
4168 if banner:
4169 logger.info('*** END HELP ***', '$MG:color:BLACK')
4170 return
4171
4172 start = 0
4173 card = ''
4174 if args[0]+'_card' in self.all_card_name+ self.cards:
4175 args[0] += '_card'
4176 elif args[0]+'.dat' in self.all_card_name+ self.cards:
4177 args[0] += '.dat'
4178 elif args[0]+'_card.dat' in self.all_card_name+ self.cards:
4179 args[0] += '_card.dat'
4180 if args[0] in self.all_card_name + self.cards:
4181 start += 1
4182 card = args[0]
4183 if len(args) == 1:
4184 if args[0] == 'pythia8_card':
4185 args[0] = 'PY8Card'
4186 if args[0] == 'param_card':
4187 logger.info("Param_card information: ", '$MG:color:BLUE')
4188 print "File to define the various model parameter"
4189 logger.info("List of the Block defined:",'$MG:color:BLUE')
4190 print "\t".join(self.param_card.keys())
4191 elif args[0].startswith('madanalysis5'):
4192 print 'This card allow to make plot with the madanalysis5 package'
4193 print 'An example card is provided. For more information about the '
4194 print 'syntax please refer to: https://madanalysis.irmp.ucl.ac.be/'
4195 print 'or to the user manual [arXiv:1206.1599]'
4196 if args[0].startswith('madanalysis5_hadron'):
4197 print
4198 print 'This card also allow to make recasting analysis'
4199 print 'For more detail, see: arXiv:1407.3278'
4200 elif hasattr(self, args[0]):
4201 logger.info("%s information: " % args[0], '$MG:color:BLUE')
4202 print(eval('self.%s' % args[0]).__doc__)
4203 logger.info("List of parameter associated", '$MG:color:BLUE')
4204 print "\t".join(eval('self.%s' % args[0]).keys())
4205 if banner:
4206 logger.info('*** END HELP ***', '$MG:color:BLACK')
4207 return
4208
4209
4210 if args[start] in [l.lower() for l in self.run_card.keys()] and card in ['', 'run_card']:
4211 if args[start] not in self.run_set:
4212 args[start] = [l for l in self.run_set if l.lower() == args[start]][0]
4213
4214 if args[start] in self.conflict and not conflict_raise:
4215 conflict_raise = True
4216 logger.info('** AMBIGUOUS NAME: %s **', args[start], '$MG:color:BLACK')
4217 if card == '':
4218 logger.info('** If not explicitely speficy this parameter will modif the run_card file', '$MG:color:BLACK')
4219
4220 self.run_card.do_help(args[start])
4221
4222 elif (args[start] in self.param_card or args[start] == 'width') \
4223 and card in ['','param_card']:
4224 if args[start] in self.conflict and not conflict_raise:
4225 conflict_raise = True
4226 logger.info('** AMBIGUOUS NAME: %s **', args[start], '$MG:color:BLACK')
4227 if card == '':
4228 logger.info('** If not explicitely speficy this parameter will modif the param_card file', '$MG:color:BLACK')
4229
4230 if args[start] == 'width':
4231 args[start] = 'decay'
4232
4233 if len(args) == start+1:
4234 self.param_card.do_help(args[start], tuple())
4235 key = None
4236 elif args[start+1] in self.pname2block:
4237 all_var = self.pname2block[args[start+1]]
4238 key = None
4239 for bname, lhaid in all_var:
4240 if bname == args[start]:
4241 key = lhaid
4242 break
4243 else:
4244 logger.warning('%s is not part of block "%s" but "%s". please correct.' %
4245 (args[start+1], args[start], bname))
4246 else:
4247 try:
4248 key = tuple([int(i) for i in args[start+1:]])
4249 except ValueError:
4250 logger.warning('Failed to identify LHA information')
4251 return
4252
4253 if key in self.param_card[args[start]].param_dict:
4254 self.param_card.do_help(args[start], key, default=self.param_card_default)
4255 elif key:
4256 logger.warning('invalid information: %s not defined in the param_card' % (key,))
4257
4258 elif args[start] in self.pname2block and card in ['','param_card']:
4259 if args[start] in self.conflict and not conflict_raise:
4260 conflict_raise = True
4261 logger.info('** AMBIGUOUS NAME: %s **', args[start], '$MG:color:BLACK')
4262 if card == '':
4263 logger.info('** If not explicitely speficy this parameter will modif the param_card file', '$MG:color:BLACK')
4264
4265 all_var = self.pname2block[args[start]]
4266 for bname, lhaid in all_var:
4267 new_line = 'param_card %s %s %s' % (bname,
4268 ' '.join([ str(i) for i in lhaid]), ' '.join(args[start+1:]))
4269 self.do_help(new_line, conflict_raise=True, banner=False)
4270
4271
4272 elif self.has_ml and args[start] in self.ml_vars \
4273 and card in ['', 'MadLoop_card']:
4274
4275 if args[start] in self.conflict and not conflict_raise:
4276 conflict_raise = True
4277 logger.info('** AMBIGUOUS NAME: %s **', args[start], '$MG:color:BLACK')
4278 if card == '':
4279 logger.info('** If not explicitely speficy this parameter will modif the madloop_card file', '$MG:color:BLACK')
4280
4281 self.MLcard.do_help(args[start])
4282
4283
4284 elif self.has_PY8 and args[start] in self.PY8Card:
4285 if args[start] in self.conflict and not conflict_raise:
4286 conflict_raise = True
4287 logger.info('** AMBIGUOUS NAME: %s **', args[start], '$MG:color:BLACK')
4288 if card == '':
4289 logger.info('** If not explicitely speficy this parameter will modif the pythia8_card file', '$MG:color:BLACK')
4290
4291 self.PY8Card.do_help(args[start])
4292 elif card.startswith('madanalysis5'):
4293 print 'MA5'
4294
4295
4296 else:
4297 print "no help available"
4298
4299 if banner:
4300 logger.info('*** END HELP ***', '$MG:color:BLACK')
4301
4302 return
4303
4304
4305
4306
4307
4308
4310 prev_timer = signal.alarm(0)
4311 if prev_timer:
4312 nb_back = len(line)
4313 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
4314 self.stdout.write(line)
4315 self.stdout.flush()
4316
4317 possibilities = self.complete_set(text, line, begidx, endidx,formatting=False)
4318 if line[:begidx].strip() == 'help':
4319 possibilities['Defined command'] = cmd.BasicCmd.completenames(self, text, line)
4320 possibilities.update(self.complete_add(text, line, begidx, endidx,formatting=False))
4321 return self.deal_multiple_categories(possibilities)
4322
4323
4324
4325
4326
4328 prev_timer = signal.alarm(0)
4329 if prev_timer:
4330 nb_back = len(line)
4331 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
4332 self.stdout.write(line)
4333 self.stdout.flush()
4334
4335 arg = line[:begidx].split()
4336 if len(arg) <=1:
4337 return self.list_completion(text, ['dependent', 'missing'], line)
4338
4339
4340 - def complete_set(self, text, line, begidx, endidx, formatting=True):
4341 """ Complete the set command"""
4342
4343 prev_timer = signal.alarm(0)
4344 if prev_timer:
4345 nb_back = len(line)
4346 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
4347 self.stdout.write(line)
4348 self.stdout.flush()
4349
4350 possibilities = {}
4351 allowed = {}
4352 args = self.split_arg(line[0:begidx])
4353 if args[-1] in ['Auto', 'default']:
4354 return
4355 if len(args) == 1:
4356 allowed = {'category':'', 'run_card':'', 'block':'all', 'param_card':'','shortcut':''}
4357 if self.has_mw:
4358 allowed['madweight_card'] = ''
4359 allowed['mw_block'] = 'all'
4360 if self.has_shower:
4361 allowed['shower_card'] = ''
4362 if self.has_ml:
4363 allowed['madloop_card'] = ''
4364 if self.has_PY8:
4365 allowed['pythia8_card'] = ''
4366 if self.has_delphes:
4367 allowed['delphes_card'] = ''
4368
4369 elif len(args) == 2:
4370 if args[1] == 'run_card':
4371 allowed = {'run_card':'default'}
4372 elif args[1] == 'param_card':
4373 allowed = {'block':'all', 'param_card':'default'}
4374 elif args[1] in self.param_card.keys():
4375 allowed = {'block':args[1]}
4376 elif args[1] == 'width':
4377 allowed = {'block': 'decay'}
4378 elif args[1] == 'MadWeight_card':
4379 allowed = {'madweight_card':'default', 'mw_block': 'all'}
4380 elif args[1] == 'MadLoop_card':
4381 allowed = {'madloop_card':'default'}
4382 elif args[1] == 'pythia8_card':
4383 allowed = {'pythia8_card':'default'}
4384 elif self.has_mw and args[1] in self.mw_card.keys():
4385 allowed = {'mw_block':args[1]}
4386 elif args[1] == 'shower_card':
4387 allowed = {'shower_card':'default'}
4388 elif args[1] == 'delphes_card':
4389 allowed = {'delphes_card':'default'}
4390 else:
4391 allowed = {'value':''}
4392 else:
4393 start = 1
4394 if args[1] in ['run_card', 'param_card', 'MadWeight_card', 'shower_card',
4395 'MadLoop_card','pythia8_card','delphes_card','plot_card',
4396 'madanalysis5_parton_card','madanalysis5_hadron_card']:
4397 start = 2
4398 if args[-1] in self.pname2block.keys():
4399 allowed['value'] = 'default'
4400 elif args[start] in self.param_card.keys() or args[start] == 'width':
4401 if args[start] == 'width':
4402 args[start] = 'decay'
4403
4404 if args[start+1:]:
4405 allowed = {'block':(args[start], args[start+1:])}
4406 else:
4407 allowed = {'block':args[start]}
4408 elif self.has_mw and args[start] in self.mw_card.keys():
4409 if args[start+1:]:
4410 allowed = {'mw_block':(args[start], args[start+1:])}
4411 else:
4412 allowed = {'mw_block':args[start]}
4413
4414
4415 else:
4416 allowed['value'] = ''
4417
4418 if 'category' in allowed.keys():
4419 categories = ['run_card', 'param_card']
4420 if self.has_mw:
4421 categories.append('MadWeight_card')
4422 if self.has_shower:
4423 categories.append('shower_card')
4424 if self.has_ml:
4425 categories.append('MadLoop_card')
4426 if self.has_PY8:
4427 categories.append('pythia8_card')
4428 if self.has_delphes:
4429 categories.append('delphes_card')
4430
4431 possibilities['category of parameter (optional)'] = \
4432 self.list_completion(text, categories)
4433
4434 if 'shortcut' in allowed.keys():
4435 possibilities['special values'] = self.list_completion(text, self.special_shortcut.keys()+['qcut', 'showerkt'])
4436
4437 if 'run_card' in allowed.keys():
4438 opts = self.run_set
4439 if allowed['run_card'] == 'default':
4440 opts.append('default')
4441
4442 possibilities['Run Card'] = self.list_completion(text, opts)
4443
4444 if 'param_card' in allowed.keys():
4445 opts = self.pname2block.keys()
4446 if allowed['param_card'] == 'default':
4447 opts.append('default')
4448 possibilities['Param Card'] = self.list_completion(text, opts)
4449
4450 if 'madweight_card' in allowed.keys():
4451 opts = self.mw_vars + [k for k in self.mw_card.keys() if k !='comment']
4452 if allowed['madweight_card'] == 'default':
4453 opts.append('default')
4454 possibilities['MadWeight Card'] = self.list_completion(text, opts)
4455
4456 if 'madloop_card' in allowed.keys():
4457 opts = self.ml_vars
4458 if allowed['madloop_card'] == 'default':
4459 opts.append('default')
4460 possibilities['MadLoop Parameter'] = self.list_completion(text, opts)
4461
4462 if 'pythia8_card' in allowed.keys():
4463 opts = self.py8_vars
4464 if allowed['pythia8_card'] == 'default':
4465 opts.append('default')
4466 possibilities['Pythia8 Parameter'] = self.list_completion(text, opts)
4467
4468 if 'shower_card' in allowed.keys():
4469 opts = self.shower_vars + [k for k in self.shower_card.keys() if k !='comment']
4470 if allowed['shower_card'] == 'default':
4471 opts.append('default')
4472 possibilities['Shower Card'] = self.list_completion(text, opts)
4473
4474 if 'delphes_card' in allowed:
4475 if allowed['delphes_card'] == 'default':
4476 opts = ['default', 'atlas', 'cms']
4477 possibilities['Delphes Card'] = self.list_completion(text, opts)
4478
4479 if 'value' in allowed.keys():
4480 opts = ['default']
4481 if 'decay' in args:
4482 opts.append('Auto')
4483 opts.append('Auto@NLO')
4484 elif args[-1] in self.pname2block and self.pname2block[args[-1]][0][0] == 'decay':
4485 opts.append('Auto')
4486 opts.append('Auto@NLO')
4487 possibilities['Special Value'] = self.list_completion(text, opts)
4488
4489 if 'block' in allowed.keys():
4490 if allowed['block'] == 'all':
4491 allowed_block = [i for i in self.param_card.keys() if 'qnumbers' not in i]
4492 allowed_block.append('width')
4493 possibilities['Param Card Block' ] = \
4494 self.list_completion(text, allowed_block)
4495 elif isinstance(allowed['block'], basestring):
4496 block = self.param_card[allowed['block']].param_dict
4497 ids = [str(i[0]) for i in block
4498 if (allowed['block'], i) not in self.restricted_value]
4499 possibilities['Param Card id' ] = self.list_completion(text, ids)
4500 varname = [name for name, all_var in self.pname2block.items()
4501 if any((bname == allowed['block']
4502 for bname,lhaid in all_var))]
4503 possibilities['Param card variable'] = self.list_completion(text,
4504 varname)
4505 else:
4506 block = self.param_card[allowed['block'][0]].param_dict
4507 nb = len(allowed['block'][1])
4508 ids = [str(i[nb]) for i in block if len(i) > nb and \
4509 [str(a) for a in i[:nb]] == allowed['block'][1]]
4510
4511 if not ids:
4512 if tuple([int(i) for i in allowed['block'][1]]) in block:
4513 opts = ['default']
4514 if allowed['block'][0] == 'decay':
4515 opts.append('Auto')
4516 opts.append('Auto@NLO')
4517 possibilities['Special value'] = self.list_completion(text, opts)
4518 possibilities['Param Card id' ] = self.list_completion(text, ids)
4519
4520 if 'mw_block' in allowed.keys():
4521 if allowed['mw_block'] == 'all':
4522 allowed_block = [i for i in self.mw_card.keys() if 'comment' not in i]
4523 possibilities['MadWeight Block' ] = \
4524 self.list_completion(text, allowed_block)
4525 elif isinstance(allowed['mw_block'], basestring):
4526 block = self.mw_card[allowed['mw_block']]
4527 ids = [str(i[0]) if isinstance(i, tuple) else str(i) for i in block]
4528 possibilities['MadWeight Card id' ] = self.list_completion(text, ids)
4529 else:
4530 block = self.mw_card[allowed['mw_block'][0]]
4531 nb = len(allowed['mw_block'][1])
4532 ids = [str(i[nb]) for i in block if isinstance(i, tuple) and\
4533 len(i) > nb and \
4534 [str(a) for a in i[:nb]] == allowed['mw_block'][1]]
4535
4536 if not ids:
4537 if tuple([i for i in allowed['mw_block'][1]]) in block or \
4538 allowed['mw_block'][1][0] in block.keys():
4539 opts = ['default']
4540 possibilities['Special value'] = self.list_completion(text, opts)
4541 possibilities['MadWeight Card id' ] = self.list_completion(text, ids)
4542
4543 return self.deal_multiple_categories(possibilities, formatting)
4544
4546 """ edit the value of one parameter in the card"""
4547
4548
4549 args = self.split_arg(line)
4550 if len(args) == 0:
4551 logger.warning("No argument. For help type 'help set'.")
4552
4553 if len(args)==1 and '=' in args[-1]:
4554 arg1, arg2 = args.pop(-1).split('=',1)
4555 args += [arg1, arg2]
4556 if '=' in args:
4557 args.remove('=')
4558
4559 args[:-1] = [ a.lower() for a in args[:-1]]
4560
4561 if args[0] in self.special_shortcut:
4562 targettypes , cmd = self.special_shortcut[args[0]]
4563 if len(args) != len(targettypes) +1:
4564 logger.warning('shortcut %s requires %s argument' % (args[0], len(targettypes)))
4565 if len(args) < len(targettypes) +1:
4566 return
4567 else:
4568 logger.warning('additional argument will be ignored')
4569 values ={}
4570 for i, argtype in enumerate(targettypes):
4571 try:
4572 values = {str(i): banner_mod.ConfigFile.format_variable(args[i+1], argtype, args[0])}
4573 except ValueError as e:
4574 logger.warning("Wrong argument: The entry #%s should be of type %s.", i+1, argtype)
4575 return
4576
4577
4578
4579
4580 for arg in cmd:
4581 try:
4582 text = arg % values
4583 except KeyError:
4584 logger.warning("This command requires one argument")
4585 return
4586 except Exception as e:
4587 logger.warning(str(e))
4588 return
4589 else:
4590 self.do_set(arg % values)
4591 return
4592
4593
4594 start = 0
4595 if len(args) < 2:
4596 logger.warning('Invalid set command %s (need two arguments)' % line)
4597 return
4598
4599
4600 if args[0].lower() == 'qcut':
4601 pythia_path = self.paths['pythia']
4602 if os.path.exists(pythia_path):
4603 logger.info('add line QCUT = %s in pythia_card.dat' % args[1])
4604 p_card = open(pythia_path,'r').read()
4605 p_card, n = re.subn('''^\s*QCUT\s*=\s*[\de\+\-\.]*\s*$''',
4606 ''' QCUT = %s ''' % args[1], \
4607 p_card, flags=(re.M+re.I))
4608 if n==0:
4609 p_card = '%s \n QCUT= %s' % (p_card, args[1])
4610 with open(pythia_path, 'w') as fsock:
4611 fsock.write(p_card)
4612 return
4613
4614 if args[0].lower() == 'showerkt':
4615 pythia_path = self.paths['pythia']
4616 if os.path.exists(pythia_path):
4617 logger.info('add line SHOWERKT = %s in pythia_card.dat' % args[1].upper())
4618 p_card = open(pythia_path,'r').read()
4619 p_card, n = re.subn('''^\s*SHOWERKT\s*=\s*[default\de\+\-\.]*\s*$''',
4620 ''' SHOWERKT = %s ''' % args[1].upper(), \
4621 p_card, flags=(re.M+re.I))
4622 if n==0:
4623 p_card = '%s \n SHOWERKT= %s' % (p_card, args[1].upper())
4624 with open(pythia_path, 'w') as fsock:
4625 fsock.write(p_card)
4626 return
4627
4628
4629 card = ''
4630 if args[0] == 'madweight_card':
4631 if not self.mw_card:
4632 logger.warning('Invalid Command: No MadWeight card defined.')
4633 return
4634 args[0] = 'MadWeight_card'
4635
4636 if args[0] == 'shower_card':
4637 if not self.shower_card:
4638 logger.warning('Invalid Command: No Shower card defined.')
4639 return
4640 args[0] = 'shower_card'
4641
4642 if args[0] == "madloop_card":
4643 if not self.has_ml:
4644 logger.warning('Invalid Command: No MadLoopParam card defined.')
4645 return
4646 args[0] = 'MadLoop_card'
4647
4648 if args[0] == "pythia8_card":
4649 if not self.has_PY8:
4650 logger.warning('Invalid Command: No Pythia8 card defined.')
4651 return
4652 args[0] = 'pythia8_card'
4653
4654 if args[0] == 'delphes_card':
4655 if not self.has_delphes:
4656 logger.warning('Invalid Command: No Delphes card defined.')
4657 return
4658 if args[1] == 'atlas':
4659 logger.info("set default ATLAS configuration for Delphes", '$MG:color:BLACK')
4660 files.cp(pjoin(self.me_dir,'Cards', 'delphes_card_ATLAS.dat'),
4661 pjoin(self.me_dir,'Cards', 'delphes_card.dat'))
4662 return
4663 elif args[1] == 'cms':
4664 logger.info("set default CMS configuration for Delphes",'$MG:color:BLACK')
4665 files.cp(pjoin(self.me_dir,'Cards', 'delphes_card_CMS.dat'),
4666 pjoin(self.me_dir,'Cards', 'delphes_card.dat'))
4667 return
4668
4669
4670 if args[0] in ['run_card', 'param_card', 'MadWeight_card', 'shower_card',
4671 'delphes_card','madanalysis5_hadron_card','madanalysis5_parton_card']:
4672 if args[1] == 'default':
4673 logger.info('replace %s by the default card' % args[0],'$MG:color:BLACK')
4674 files.cp(self.paths['%s_default' %args[0][:-5]], self.paths[args[0][:-5]])
4675 if args[0] == 'param_card':
4676 self.param_card = check_param_card.ParamCard(self.paths['param'])
4677 elif args[0] == 'run_card':
4678 self.run_card = banner_mod.RunCard(self.paths['run'])
4679 elif args[0] == 'shower_card':
4680 self.shower_card = shower_card_mod.ShowerCard(self.paths['shower'])
4681 return
4682 else:
4683 card = args[0]
4684 start=1
4685 if len(args) < 3:
4686 logger.warning('Invalid set command: %s (not enough arguments)' % line)
4687 return
4688
4689 elif args[0] in ['MadLoop_card']:
4690 if args[1] == 'default':
4691 logger.info('replace MadLoopParams.dat by the default card','$MG:color:BLACK')
4692 self.MLcard = banner_mod.MadLoopParam(self.MLcardDefault)
4693 self.MLcard.write(self.paths['ML'],
4694 commentdefault=True)
4695 return
4696 else:
4697 card = args[0]
4698 start=1
4699 if len(args) < 3:
4700 logger.warning('Invalid set command: %s (not enough arguments)' % line)
4701 return
4702 elif args[0] in ['pythia8_card']:
4703 if args[1] == 'default':
4704 logger.info('replace pythia8_card.dat by the default card','$MG:color:BLACK')
4705 self.PY8Card = banner_mod.PY8Card(self.PY8CardDefault)
4706 self.PY8Card.write(pjoin(self.me_dir,'Cards','pythia8_card.dat'),
4707 pjoin(self.me_dir,'Cards','pythia8_card_default.dat'),
4708 print_only_visible=True)
4709 return
4710 else:
4711 card = args[0]
4712 start=1
4713 if len(args) < 3:
4714 logger.warning('Invalid set command: %s (not enough arguments)' % line)
4715 return
4716 elif args[0] in ['madspin_card']:
4717 if args[1] == 'default':
4718 logger.info('replace madspin_card.dat by the default card','$MG:color:BLACK')
4719 files.cp(self.paths['MS_default'], self.paths['madspin'])
4720 return
4721 else:
4722 logger.warning("""Command set not allowed for modifying the madspin_card.
4723 Check the command \"decay\" instead.""")
4724 return
4725
4726
4727 if args[start] in [l.lower() for l in self.run_card.keys()] and card in ['', 'run_card']:
4728 if args[start] not in self.run_set:
4729 args[start] = [l for l in self.run_set if l.lower() == args[start]][0]
4730
4731 if args[start] in self.conflict and card == '':
4732 text = 'Ambiguous name (present in more than one card). Will assume it to be referred to run_card.\n'
4733 text += 'If this is not intended, please reset it in the run_card and specify the relevant card to \n'
4734 text += 'edit, in the format < set card parameter value >'
4735 logger.warning(text)
4736
4737 if args[start+1] == 'default':
4738 default = banner_mod.RunCard(self.paths['run_default'])
4739 if args[start] in default.keys():
4740 self.setR(args[start],default[args[start]])
4741 else:
4742 logger.info('remove information %s from the run_card' % args[start],'$MG:color:BLACK')
4743 del self.run_card[args[start]]
4744 else:
4745 if args[0].startswith('sys_') or \
4746 args[0] in self.run_card.list_parameter or \
4747 args[0] in self.run_card.dict_parameter:
4748 val = ' '.join(args[start+1:])
4749 val = val.split('#')[0]
4750 else:
4751 val = args[start+1]
4752 self.setR(args[start], val)
4753 self.run_card.write(self.paths['run'], self.paths['run_default'])
4754
4755
4756 elif (args[start] in self.param_card or args[start] == 'width') \
4757 and card in ['','param_card']:
4758
4759 if any(t.startswith('scan') for t in args):
4760 index = [i for i,t in enumerate(args) if t.startswith('scan')][0]
4761 args = args[:index] + [' '.join(args[index:])]
4762
4763 if args[start] in self.conflict and card == '':
4764 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4765 text += ' in the format < set card parameter value>'
4766 logger.warning(text)
4767 return
4768
4769 if args[start] == 'width':
4770 args[start] = 'decay'
4771
4772 if args[start+1] in self.pname2block:
4773 all_var = self.pname2block[args[start+1]]
4774 key = None
4775 for bname, lhaid in all_var:
4776 if bname == args[start]:
4777 key = lhaid
4778 break
4779 else:
4780 logger.warning('%s is not part of block "%s" but "%s". please correct.' %
4781 (args[start+1], args[start], bname))
4782 return
4783 else:
4784 try:
4785 key = tuple([int(i) for i in args[start+1:-1]])
4786 except ValueError:
4787 if args[start] == 'decay' and args[start+1:-1] == ['all']:
4788 for key in self.param_card[args[start]].param_dict:
4789 if (args[start], key) in self.restricted_value:
4790 continue
4791 else:
4792 self.setP(args[start], key, args[-1])
4793 self.param_card.write(self.paths['param'])
4794 return
4795 logger.warning('invalid set command %s (failed to identify LHA information)' % line)
4796 return
4797
4798 if key in self.param_card[args[start]].param_dict:
4799 if (args[start], key) in self.restricted_value:
4800 text = "Note that this parameter seems to be ignore by MG.\n"
4801 text += "MG will use instead the expression: %s\n" % \
4802 self.restricted_value[(args[start], key)]
4803 text += "You need to match this expression for external program (such pythia)."
4804 logger.warning(text)
4805
4806 if args[-1].lower() in ['default', 'auto', 'auto@nlo'] or args[-1].startswith('scan'):
4807 self.setP(args[start], key, args[-1])
4808 else:
4809 try:
4810 value = float(args[-1])
4811 except Exception:
4812 logger.warning('Invalid input: Expected number and not \'%s\'' \
4813 % args[-1])
4814 return
4815 self.setP(args[start], key, value)
4816 else:
4817 logger.warning('invalid set command %s' % line)
4818 return
4819 self.param_card.write(self.paths['param'])
4820
4821
4822 elif args[start] in self.pname2block and card in ['','param_card']:
4823 if args[start] in self.conflict and card == '':
4824 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4825 text += ' in the format < set card parameter value>'
4826 logger.warning(text)
4827 return
4828
4829 all_var = self.pname2block[args[start]]
4830 for bname, lhaid in all_var:
4831 new_line = 'param_card %s %s %s' % (bname,
4832 ' '.join([ str(i) for i in lhaid]), ' '.join(args[start+1:]))
4833 self.do_set(new_line)
4834 if len(all_var) > 1:
4835 logger.warning('This variable correspond to more than one parameter in the param_card.')
4836 for bname, lhaid in all_var:
4837 logger.warning(' %s %s' % (bname, ' '.join([str(i) for i in lhaid])))
4838 logger.warning('all listed variables have been modified')
4839
4840
4841 elif self.has_mw and (args[start] in self.mw_card and args[start] != 'comment') \
4842 and card in ['','MadWeight_card']:
4843
4844 if args[start] in self.conflict and card == '':
4845 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4846 text += ' in the format < set card parameter value>'
4847 logger.warning(text)
4848 return
4849
4850 block = args[start]
4851 name = args[start+1]
4852 value = args[start+2:]
4853 self.setM(block, name, value)
4854 self.mw_card.write(self.paths['MadWeight'])
4855
4856
4857 elif self.has_mw and args[start] in self.mw_vars \
4858 and card in ['', 'MadWeight_card']:
4859
4860 if args[start] in self.conflict and card == '':
4861 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4862 text += ' in the format < set card parameter value>'
4863 logger.warning(text)
4864 return
4865
4866 block = [b for b, data in self.mw_card.items() if args[start] in data]
4867 if len(block) > 1:
4868 logger.warning('%s is define in more than one block: %s.Please specify.'
4869 % (args[start], ','.join(block)))
4870 return
4871
4872 block = block[0]
4873 name = args[start]
4874 value = args[start+1:]
4875 self.setM(block, name, value)
4876 self.mw_card.write(self.paths['MadWeight'])
4877
4878
4879 elif self.has_mw and args[start].startswith('mw_') and len(args[start:]) == 3\
4880 and card == 'MadWeight_card':
4881 block = args[start]
4882 name = args[start+1]
4883 value = args[start+2]
4884 self.setM(block, name, value)
4885 self.mw_card.write(self.paths['MadWeight'])
4886
4887
4888 elif self.has_shower and args[start].lower() in [l.lower() for l in \
4889 self.shower_card.keys()] and card in ['', 'shower_card']:
4890 if args[start] not in self.shower_card:
4891 args[start] = [l for l in self.shower_card if l.lower() == args[start].lower()][0]
4892
4893 if args[start] in self.conflict and card == '':
4894 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4895 text += ' in the format < set card parameter value>'
4896 logger.warning(text)
4897 return
4898
4899 if args[start+1].lower() == 'default':
4900 default = shower_card_mod.ShowerCard(self.paths['shower_default'])
4901 if args[start] in default.keys():
4902 self.shower_card.set_param(args[start],default[args[start]], self.paths['shower'])
4903 else:
4904 logger.info('remove information %s from the shower_card' % args[start],'$MG:color:BLACK')
4905 del self.shower_card[args[start]]
4906 elif args[start+1].lower() in ['t','.true.','true']:
4907 self.shower_card.set_param(args[start],'.true.',self.paths['shower'])
4908 elif args[start+1].lower() in ['f','.false.','false']:
4909 self.shower_card.set_param(args[start],'.false.',self.paths['shower'])
4910 elif args[start] in ['analyse', 'extralibs', 'extrapaths', 'includepaths'] or\
4911 args[start].startswith('dm_'):
4912
4913 args = line.split()
4914 args_str = ' '.join(str(a) for a in args[start+1:len(args)])
4915 self.shower_card.set_param(args[start],args_str,pjoin(self.me_dir,'Cards','shower_card.dat'))
4916 else:
4917 args_str = ' '.join(str(a) for a in args[start+1:len(args)])
4918 self.shower_card.set_param(args[start],args_str,self.paths['shower'])
4919
4920
4921 elif self.has_ml and args[start] in self.ml_vars \
4922 and card in ['', 'MadLoop_card']:
4923
4924 if args[start] in self.conflict and card == '':
4925 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4926 logger.warning(text)
4927 return
4928
4929 if args[start+1] == 'default':
4930 value = self.MLcardDefault[args[start]]
4931 default = True
4932 else:
4933 value = args[start+1]
4934 default = False
4935 self.setML(args[start], value, default=default)
4936 self.MLcard.write(self.paths['ML'],
4937 commentdefault=True)
4938
4939
4940 elif self.has_PY8 and (card == 'pythia8_card' or (card == '' and \
4941 args[start] in self.PY8Card)):
4942
4943 if args[start] in self.conflict and card == '':
4944 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4945 logger.warning(text)
4946 return
4947
4948 if args[start+1] == 'default':
4949 value = self.PY8CardDefault[args[start]]
4950 default = True
4951 else:
4952 value = ' '.join(args[start+1:])
4953 default = False
4954 self.setPY8(args[start], value, default=default)
4955 self.PY8Card.write(pjoin(self.me_dir,'Cards','pythia8_card.dat'),
4956 pjoin(self.me_dir,'Cards','pythia8_card_default.dat'),
4957 print_only_visible=True)
4958
4959
4960 else:
4961 logger.warning('invalid set command %s ' % line)
4962 arg = args[start].lower()
4963 if self.has_PY8:
4964 close_opts = [name for name in self.PY8Card if name.lower().startswith(arg[:3]) or arg in name.lower()]
4965 if close_opts:
4966 logger.info('Did you mean one of the following PY8 options:\n%s' % '\t'.join(close_opts))
4967 if self.run_card:
4968 close_opts = [name for name in self.run_card if name.lower().startswith(arg[:3]) or arg in name.lower()]
4969 if close_opts:
4970 logger.info('Did you mean one of the following run_card options:\n%s' % '\t'.join(close_opts))
4971
4972 return
4973
4974 - def setM(self, block, name, value):
4975
4976 if isinstance(value, list) and len(value) == 1:
4977 value = value[0]
4978
4979 if block not in self.mw_card:
4980 logger.warning('block %s was not present in the current MadWeight card. We are adding it' % block)
4981 self.mw_card[block] = {}
4982 elif name not in self.mw_card[block]:
4983 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')
4984 if value == 'default':
4985 import madgraph.madweight.Cards as mwcards
4986 mw_default = mwcards.Card(self.paths['MadWeight_default'])
4987 try:
4988 value = mw_default[block][name]
4989 except KeyError:
4990 logger.info('removing id "%s" from Block "%s" '% (name, block),'$MG:color:BLACK')
4991 if name in self.mw_card[block]:
4992 del self.mw_card[block][name]
4993 return
4994 if value:
4995 logger.info('modify madweight_card information BLOCK "%s" with id "%s" set to %s',
4996 block, name, value, '$MG:color:BLACK')
4997 else:
4998 logger.warning("Invalid command: No value. To set default value. Use \"default\" as value")
4999 return
5000
5001 self.mw_card[block][name] = value
5002
5003 - def setR(self, name, value):
5004 logger.info('modify parameter %s of the run_card.dat to %s' % (name, value),'$MG:color:BLACK')
5005 self.run_card.set(name, value, user=True)
5006
5007 - def setML(self, name, value, default=False):
5008
5009 try:
5010 self.MLcard.set(name, value, user=True)
5011 except Exception, error:
5012 logger.warning("Fail to change parameter. Please Retry. Reason: %s." % error)
5013 return
5014 logger.info('modify parameter %s of the MadLoopParam.dat to %s' % (name, value),'$MG:color:BLACK')
5015 if default and name.lower() in self.MLcard.user_set:
5016 self.MLcard.user_set.remove(name.lower())
5017
5018 - def setPY8(self, name, value, default=False):
5027
5028 - def setP(self, block, lhaid, value):
5029 if isinstance(value, str):
5030 value = value.lower()
5031 if value == 'default':
5032 default = check_param_card.ParamCard(self.paths['param_default'])
5033 value = default[block].param_dict[lhaid].value
5034
5035 elif value in ['auto', 'auto@nlo']:
5036 if 'nlo' in value:
5037 value = 'Auto@NLO'
5038 else:
5039 value = 'Auto'
5040 if block != 'decay':
5041 logger.warning('Invalid input: \'Auto\' value only valid for DECAY')
5042 return
5043 elif value.startswith('scan'):
5044 if ':' not in value:
5045 logger.warning('Invalid input: \'scan\' mode requires a \':\' before the definition.')
5046 return
5047 tag = value.split(':')[0]
5048 tag = tag[4:].strip()
5049 if tag and not tag.isdigit():
5050 logger.warning('Invalid input: scan tag need to be integer and not "%s"' % tag)
5051 return
5052
5053
5054 pass
5055 else:
5056 try:
5057 value = float(value)
5058 except ValueError:
5059 logger.warning('Invalid input: \'%s\' not valid intput.'% value)
5060
5061 logger.info('modify param_card information BLOCK %s with id %s set to %s' %\
5062 (block, lhaid, value), '$MG:color:BLACK')
5063 self.param_card[block].param_dict[lhaid].value = value
5064
5066 """This is run on quitting the class. Apply here all the self-consistency
5067 rule that you want. Do the modification via the set command."""
5068
5069
5070 if 'reweight' in self.allow_arg and 'run' in self.allow_arg and \
5071 isinstance(self.run_card,banner_mod.RunCardNLO) and \
5072 not self.run_card['store_rwgt_info']:
5073
5074 re_pattern = re.compile(r'''^\s*change\s*mode\s* (LO\+NLO|LO|NLO)\s*(?:#|$)''', re.M+re.I)
5075 text = open(self.paths['reweight']).read()
5076 options = re_pattern.findall(text)
5077 if any(o in ['NLO', 'LO+NLO'] for o in options):
5078 logger.info('NLO reweighting is on ON. Automatically set store_rwgt_info to True', '$MG:color:BLACK' )
5079 self.do_set('run_card store_rwgt_info True')
5080
5081
5082
5083 if 'run' in self.allow_arg and \
5084 self.run_card['systematics_program'] == 'systematics' and \
5085 isinstance(self.run_card,banner_mod.RunCardNLO) and \
5086 not self.run_card['store_rwgt_info']:
5087 logger.warning('To be able to run systematics program, we set store_rwgt_info to True')
5088 self.do_set('run_card store_rwgt_info True')
5089
5090
5091 if 'pythia_card.dat' in self.cards:
5092 if self.run_card['event_norm'] != 'sum':
5093 logger.info('Pythia6 needs a specific normalisation of the events. We will change it accordingly.', '$MG:color:BLACK' )
5094 self.do_set('run_card event_norm sum')
5095
5096 elif 'pythia8_card.dat' in self.cards:
5097 if self.run_card['event_norm'] == 'sum':
5098 logger.info('Pythia8 needs a specific normalisation of the events. We will change it accordingly.', '$MG:color:BLACK' )
5099 self.do_set('run_card event_norm average')
5100
5101
5102 if self.has_shower and isinstance(self.run_card, banner_mod.RunCardNLO):
5103 modify_extralibs, modify_extrapaths = False,False
5104 extralibs = self.shower_card['extralibs'].split()
5105 extrapaths = self.shower_card['extrapaths'].split()
5106
5107 if self.run_card['parton_shower'] in ['PYTHIA8', 'HERWIGPP', 'HW7']:
5108 if 'stdhep' in self.shower_card['extralibs']:
5109 extralibs.remove('stdhep')
5110 modify_extralibs = True
5111 if 'Fmcfio' in self.shower_card['extralibs']:
5112 extralibs.remove('Fmcfio')
5113 modify_extralibs = True
5114 if self.run_card['parton_shower'] == 'PYTHIA8':
5115
5116 if not self.mother_interface.options['pythia8_path']:
5117 raise self.mother.InvalidCmd, 'Pythia8 is not correctly specified to MadGraph5_aMC@NLO'
5118 executable = pjoin(self.mother_interface.options['pythia8_path'], 'bin', 'pythia8-config')
5119 if not os.path.exists(executable):
5120 raise self.mother.InvalidCmd, 'Pythia8 is not correctly specified to MadGraph5_aMC@NLO'
5121
5122
5123 libs , paths = [], []
5124 p = misc.subprocess.Popen([executable, '--libs'], stdout=subprocess.PIPE)
5125 stdout, _ = p. communicate()
5126 libs = [x[2:] for x in stdout.split() if x.startswith('-l') or paths.append(x[2:])]
5127
5128
5129 p = misc.subprocess.Popen([executable, '--config'], stdout=subprocess.PIPE)
5130 stdout, _ = p. communicate()
5131 for lib in ['-ldl','-lstdc++','-lc++']:
5132 if lib in stdout:
5133 libs.append(lib[2:])
5134
5135
5136
5137 supports_HEPMCHACK = '-DHEPMC2HACK' in stdout
5138
5139
5140 for l in libs:
5141 if l not in extralibs:
5142 modify_extralibs = True
5143 extralibs.append(l)
5144 for L in paths:
5145 if L not in extrapaths:
5146 modify_extrapaths = True
5147 extrapaths.append(L)
5148
5149
5150 if modify_extralibs:
5151 if extralibs:
5152 self.do_set('shower_card extralibs %s ' % ' '.join(extralibs))
5153 else:
5154 self.do_set('shower_card extralibs None ')
5155 if modify_extrapaths:
5156 if extrapaths:
5157 self.do_set('shower_card extrapaths %s ' % ' '.join(extrapaths))
5158 else:
5159 self.do_set('shower_card extrapaths None ')
5160
5161 - def reask(self, *args, **opt):
5162
5163 cmd.OneLinePathCompletion.reask(self,*args, **opt)
5164 if self.has_mw and not os.path.exists(pjoin(self.me_dir,'Cards','transfer_card.dat')):
5165 logger.warning('No transfer function currently define. Please use the change_tf command to define one.')
5166
5167 fail_due_to_format = 0
5168 - def postcmd(self, stop, line):
5169 ending_question = cmd.OneLinePathCompletion.postcmd(self,stop,line)
5170
5171 if ending_question:
5172 self.check_card_consistency()
5173 try:
5174 self.do_update('dependent', timer=20)
5175 except MadGraph5Error, error:
5176 if 'Missing block:' in str(error):
5177 self.fail_due_to_format +=1
5178 if self.fail_due_to_format == 10:
5179 missing, unknow = str(error).split('\n')[-2:]
5180 logger.warning("Invalid param_card:\n%s\n%s\n" % (missing, unknow))
5181 logger.info("Type \"update missing\" to use default value.\n ", '$MG:color:BLACK')
5182 self.value = False
5183 return self.reask(True)
5184 else:
5185 raise
5186
5187 return ending_question
5188
5189
5190
5191
5192
5194 """ syntax: update dependent: Change the mass/width of particles which are not free parameter for the model.
5195 update missing: add to the current param_card missing blocks/parameters."""
5196
5197 args = self.split_arg(line)
5198 if len(args)==0:
5199 logger.warning('miss an argument (dependent or missing). Please retry')
5200 return
5201
5202 if args[0] == 'dependent':
5203 if not self.mother_interface:
5204 logger.warning('Failed to update dependent parameter. This might create trouble for external program (like MadSpin/shower/...)')
5205
5206 pattern_width = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto(@NLO|)''',re.I)
5207 pattern_scan = re.compile(r'''^(decay)?[\s\d]*scan''', re.I+re.M)
5208 param_text= open(self.paths['param']).read()
5209
5210 if pattern_scan.search(param_text):
5211
5212
5213
5214 return
5215 elif pattern_width.search(param_text):
5216 self.do_compute_widths('')
5217 self.param_card = check_param_card.ParamCard(self.paths['param'])
5218
5219
5220 self.update_dependent(self.mother_interface, self.me_dir, self.param_card,
5221 self.paths['param'], timer)
5222
5223 elif args[0] == 'missing':
5224 self.update_missing()
5225 return
5226
5227
5228
5229 @staticmethod
5231 """static method which can also be called from outside the class
5232 usefull in presence of scan.
5233 return if the param_card was updated or not
5234 """
5235 logger.info('Update the dependent parameter of the param_card.dat')
5236 modify = True
5237 class TimeOutError(Exception):
5238 pass
5239 def handle_alarm(signum, frame):
5240 raise TimeOutError
5241 signal.signal(signal.SIGALRM, handle_alarm)
5242 if timer:
5243 signal.alarm(timer)
5244 log_level=30
5245 else:
5246 log_level=20
5247
5248 try:
5249 model = mecmd.get_model()
5250 signal.alarm(0)
5251 except TimeOutError:
5252 logger.warning('The model takes too long to load so we bypass the updating of dependent parameter.\n'+\
5253 'This might create trouble for external program (like MadSpin/shower/...)\n'+\
5254 'The update can be forced without timer by typing \'update dependent\' at the time of the card edition')
5255 modify =False
5256 except Exception,error:
5257 logger.debug(str(error))
5258 logger.warning('Failed to update dependent parameter. This might create trouble for external program (like MadSpin/shower/...)')
5259 signal.alarm(0)
5260 else:
5261 restrict_card = pjoin(me_dir,'Source','MODEL','param_card_rule.dat')
5262 if not os.path.exists(restrict_card):
5263 restrict_card = None
5264
5265 if model:
5266 modify = param_card.update_dependent(model, restrict_card, log_level)
5267 if modify and path:
5268 param_card.write(path)
5269 else:
5270 logger.warning('missing MG5aMC code. Fail to update dependent parameter. This might create trouble for program like MadSpin/shower/...')
5271
5272 if log_level==20:
5273 logger.info('param_card up to date.')
5274
5275 return modify
5276
5277
5278
5280
5281 def check_block(self, blockname):
5282 add_entry = 0
5283 block = self.param_card_default[blockname]
5284 for key in block.keys():
5285 if key not in input_in_block:
5286 param = block.get(key)
5287 if blockname != 'decay':
5288 text.append('\t%s\t%s # %s\n' % (' \t'.join([`i` for i in param.lhacode]), param.value, param.comment))
5289 else:
5290 text.append('DECAY \t%s\t%s # %s\n' % (' \t'.join([`i` for i in param.lhacode]), param.value, param.comment))
5291 add_entry += 1
5292 if add_entry:
5293 text.append('\n')
5294 return add_entry
5295
5296
5297 current_block = ''
5298 input_in_block = set()
5299 defined_blocks = set()
5300 decay = set()
5301 text = []
5302 add_entry = 0
5303 for line in open(self.paths['param']):
5304
5305 new_block = re.findall(r'^\s*(block|decay)\s*(\w*)', line, re.I)
5306 if new_block:
5307 new_block = new_block[0]
5308 defined_blocks.add(new_block[1].lower())
5309 if current_block:
5310 add_entry += check_block(self, current_block)
5311
5312 current_block= new_block[1]
5313 input_in_block = set()
5314 if new_block[0].lower() == 'decay':
5315 decay.add((int(new_block[1]),))
5316 current_block = ''
5317 if new_block[1].lower() == 'qnumbers':
5318 current_block = ''
5319
5320 text.append(line)
5321 if not current_block:
5322 continue
5323
5324
5325
5326 line = line.split('#',1)[0]
5327 split = line.split()
5328 if not split:
5329 continue
5330 else:
5331 try:
5332 lhacode = [int(i) for i in split[:-1]]
5333 except:
5334 continue
5335 input_in_block.add(tuple(lhacode))
5336
5337 if current_block:
5338 add_entry += check_block(self, current_block)
5339
5340
5341 for block in self.param_card_default:
5342
5343 if block.startswith(('qnumbers', 'decay')):
5344 continue
5345
5346 if block not in defined_blocks:
5347 add_entry += len(self.param_card_default[block])
5348 text.append(str(self.param_card_default[block]))
5349
5350
5351 input_in_block = decay
5352 add_entry += check_block(self, 'decay')
5353
5354 if add_entry:
5355 logger.info('write new param_card with %s new parameter(s).', add_entry, '$MG:color:BLACK')
5356 open(self.paths['param'],'w').write(''.join(text))
5357 self.reload_card(self.paths['param'])
5358 else:
5359 logger.info('No missing parameter detected.', '$MG:color:BLACK')
5360
5361
5366
5394
5395
5397 """Default action if line is not recognized"""
5398
5399 line = line.strip()
5400 args = line.split()
5401 if line == '' and self.default_value is not None:
5402 self.value = self.default_value
5403
5404 elif hasattr(self, 'do_%s' % args[0]):
5405 self.do_set(' '.join(args[1:]))
5406 elif os.path.isfile(line):
5407 self.copy_file(line)
5408 self.value = 'repeat'
5409 elif self.me_dir and os.path.exists(pjoin(self.me_dir, line)):
5410 self.copy_file(pjoin(self.me_dir,line))
5411 self.value = 'repeat'
5412 elif line.strip() != '0' and line.strip() != 'done' and \
5413 str(line) != 'EOF' and line.strip() in self.allow_arg:
5414 self.open_file(line)
5415 self.value = 'repeat'
5416 else:
5417 self.value = line
5418
5419 return line
5420
5422 """edit the madspin_card to define the decay of the associate particle"""
5423 signal.alarm(0)
5424 path = self.paths['madspin']
5425
5426 if 'madspin_card.dat' not in self.cards or not os.path.exists(path):
5427 logger.warning("Command decay not valid. Since MadSpin is not available.")
5428 return
5429
5430 if ">" not in line:
5431 logger.warning("invalid command for decay. Line ignored")
5432 return
5433
5434 if "-add" in line:
5435
5436 particle = line.split('>')[0].strip()
5437 text = open(path).read()
5438 line = line.replace('--add', '').replace('-add','')
5439 logger.info("change madspin_card to add one decay to %s: %s" %(particle, line.strip()), '$MG:color:BLACK')
5440
5441 text = text.replace('launch', "\ndecay %s\nlaunch\n" % line,1)
5442 else:
5443
5444
5445 particle = line.split('>')[0].strip()
5446 logger.info("change madspin_card to define the decay of %s: %s" %(particle, line.strip()), '$MG:color:BLACK')
5447 particle = particle.replace('+','\+').replace('-','\-')
5448 decay_pattern = re.compile(r"^\s*decay\s+%s\s*>[\s\w+-~]*?$" % particle, re.I+re.M)
5449 text= open(path).read()
5450 text = decay_pattern.sub('', text)
5451 text = text.replace('launch', "\ndecay %s\nlaunch\n" % line,1)
5452
5453 with open(path,'w') as fsock:
5454 fsock.write(text)
5455
5456
5457
5459 signal.alarm(0)
5460 path = self.paths['param']
5461 pattern = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto(@NLO|)''',re.I)
5462 text = open(path).read()
5463 pdg_info = pattern.findall(text)
5464 has_nlo = any("@nlo"==nlo.lower() for _, nlo in pdg_info)
5465 pdg = [p for p,_ in pdg_info]
5466
5467
5468 line = '%s %s' % (line, ' '.join(pdg))
5469 if not '--path' in line:
5470 line += ' --path=%s' % path
5471 if has_nlo:
5472 line += ' --nlo'
5473
5474 try:
5475 return self.mother_interface.do_compute_widths(line)
5476 except InvalidCmd, error:
5477 logger.error("Invalid command: %s " % error)
5478
5482
5484 """help for command decay which modifies MadSpin_card"""
5485
5486 signal.alarm(0)
5487 print '--syntax: decay PROC [--add]'
5488 print ' '
5489 print ' modify the madspin_card to modify the decay of the associate particle.'
5490 print ' and define it to PROC.'
5491 print ' if --add is present, just add a new decay for the associate particle.'
5492
5494 prev_timer = signal.alarm(0)
5495 if prev_timer:
5496 nb_back = len(line)
5497 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
5498 self.stdout.write(line)
5499 self.stdout.flush()
5500 return self.mother_interface.complete_compute_widths(*args,**opts)
5501
5502
5504 """help for add command"""
5505
5506 logger.info('********************* HELP ADD ***************************')
5507 logger.info( '-- syntax: add pythia8_card NAME VALUE')
5508 logger.info( " add a definition of name in the pythia8_card with the given value")
5509 logger.info( " Do not work for the param_card" )
5510 logger.info( '-- syntax: add filename [OPTION] line')
5511 logger.info( ' add the given LINE to the end of the associate file (all file supportedd).')
5512 logger.info( ' OPTION parameter allows to change the position where to write in the file')
5513 logger.info( ' --after_line=banner : write the line at the end of the banner')
5514 logger.info( ' --line_position=X : insert the line before line X (starts at 0)')
5515 logger.info( ' --after_line="<regular-expression>" write the line after the first line matching the regular expression')
5516 logger.info( ' --before_line="<regular-expression>" write the line before the first line matching the regular expression')
5517 logger.info( ' example: change reweight --after_line="^\s*change mode" change model heft')
5518 logger.info('********************* HELP ADD ***************************')
5519
5520 - def complete_add(self, text, line, begidx, endidx, formatting=True):
5521 """ auto-completion for add command"""
5522
5523 prev_timer = signal.alarm(0)
5524 if prev_timer:
5525 nb_back = len(line)
5526 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
5527 self.stdout.write(line)
5528 self.stdout.flush()
5529
5530 split = line[:begidx].split()
5531 if len(split)==1:
5532 possibilities = {}
5533 cards = [c.rsplit('.',1)[0] for c in self.cards]
5534 possibilities['category of parameter (optional)'] = \
5535 self.list_completion(text, cards)
5536 elif len(split) == 2:
5537 possibilities = {}
5538 options = ['--line_position=','--after_line=banner', '--after_line="','--before_line="']
5539 possibilities['category of parameter (optional)'] = \
5540 self.list_completion(text, options, line)
5541 else:
5542 return
5543 return self.deal_multiple_categories(possibilities, formatting)
5544
5546 """ syntax: add filename NAME VALUE
5547 syntax: add filename LINE"""
5548
5549 args = self.split_arg(line)
5550 if len(args) == 3 and args[0] in ['pythia8_card', 'pythia8_card.dat'] and self.has_PY8:
5551 name= args[1]
5552 value = args[2]
5553 self.PY8Card.userSet(name, value)
5554 self.PY8Card.write(pjoin(self.me_dir,'Cards','pythia8_card.dat'),
5555 pjoin(self.me_dir,'Cards','pythia8_card_default.dat'),
5556 print_only_visible=True)
5557 logger.info("add in the pythia8_card the parameter \"%s\" with value \"%s\"" % (name, value), '$MG:color:BLACK')
5558 elif len(args) > 0:
5559 if args[0] in self.cards:
5560 card = args[0]
5561 elif "%s.dat" % args[0] in self.cards:
5562 card = "%s.dat" % args[0]
5563 elif "%s_card.dat" % args[0] in self.cards:
5564 card = "%s_card.dat" % args[0]
5565 elif self.has_ml and args[0].lower() == "madloop":
5566 card = "MadLoopParams.dat"
5567 else:
5568 logger.error("unknow card %s. Please retry." % args[0])
5569 return
5570
5571
5572 if args[1].startswith('--line_position='):
5573
5574 text = open(pjoin(self.me_dir,'Cards',card)).read()
5575 split = text.split('\n')
5576 pos = int(args[1].split('=',1)[1])
5577 newline = line.split(None,2)[2]
5578 split.insert(pos, newline)
5579 ff = open(pjoin(self.me_dir,'Cards',card),'w')
5580 ff.write('\n'.join(split))
5581 logger.info("writting at line %d of the file %s the line: \"%s\"" %(pos, card, line.split(None,1)[1] ))
5582
5583 elif args[1].startswith('--after_line=banner'):
5584
5585 text = open(pjoin(self.me_dir,'Cards',card)).read()
5586 split = text.split('\n')
5587 for posline,l in enumerate(split):
5588 if not l.startswith('#'):
5589 break
5590 split.insert(posline, line.split(None,2)[2])
5591 ff = open(pjoin(self.me_dir,'Cards',card),'w')
5592 ff.write('\n'.join(split))
5593 logger.info("writting at line %d of the file %s the line: \"%s\"" %(posline, card, line.split(None,1)[1] ))
5594
5595 elif args[1].startswith('--before_line='):
5596
5597 text = open(pjoin(self.me_dir,'Cards',card)).read()
5598 split = text.split('\n')
5599 search_pattern=r'''before_line=(?P<quote>["'])(?:(?=(\\?))\2.)*?\1'''
5600 pattern = re.search(search_pattern, line).group()[13:-1]
5601 for posline,l in enumerate(split):
5602 if re.search(pattern, l):
5603 break
5604 else:
5605 raise Exception, 'invalid regular expression: not found in file'
5606 split.insert(posline, re.split(search_pattern,line)[-1])
5607 ff = open(pjoin(self.me_dir,'Cards',card),'w')
5608 ff.write('\n'.join(split))
5609 logger.info("writting at line %d of the file %s the line: \"%s\"" %(posline, card, line.split(None,1)[1] ))
5610
5611
5612
5613 elif args[1].startswith('--after_line='):
5614
5615 text = open(pjoin(self.me_dir,'Cards',card)).read()
5616 split = text.split('\n')
5617 search_pattern = r'''after_line=(?P<quote>["'])(?:(?=(\\?))\2.)*?\1'''
5618 pattern = re.search(search_pattern, line).group()[12:-1]
5619 for posline,l in enumerate(split):
5620 if re.search(pattern, l):
5621 break
5622 else:
5623 posline=len(split)
5624 split.insert(posline+1, re.split(search_pattern,line)[-1])
5625 ff = open(pjoin(self.me_dir,'Cards',card),'w')
5626 ff.write('\n'.join(split))
5627 logger.info("writting at line %d of the file %s the line: \"%s\"" %(posline, card, line.split(None,1)[1] ))
5628 else:
5629 ff = open(pjoin(self.me_dir,'Cards',card),'a')
5630 ff.write("%s \n" % line.split(None,1)[1])
5631 ff.close()
5632 logger.info("adding at the end of the file %s the line: \"%s\"" %(card, line.split(None,1)[1] ))
5633 self.reload_card(pjoin(self.me_dir,'Cards',card))
5634
5635
5636
5638 """Help associated to the asperge command"""
5639 signal.alarm(0)
5640
5641 print '-- syntax: asperge [options]'
5642 print ' Call ASperGe to diagonalize all mass matrices in the model.'
5643 print ' This works only if the ASperGE module is part of the UFO model (a subdirectory).'
5644 print ' If you specify some names after the command (i.e. asperge m1 m2) then ASperGe will only'
5645 print ' diagonalize the associate mass matrices (here m1 and m2).'
5646
5648 prev_timer = signal.alarm(0)
5649 if prev_timer:
5650 nb_back = len(line)
5651 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
5652 self.stdout.write(line)
5653 self.stdout.flush()
5654 blockname = self.pname2block.keys()
5655
5656 wrong = ['decay', 'mass', 'sminput']
5657 valid = [k for k in blockname if 'mix' in k]
5658 potential = [k for k in blockname if k not in valid+wrong]
5659 output = {'Mixing matrices': self.list_completion(text, valid, line),
5660 'Other potential valid input': self.list_completion(text, potential, line)}
5661
5662 return self.deal_multiple_categories(output, formatting)
5663
5664
5666 """Running ASperGe"""
5667 signal.alarm(0)
5668
5669 path = pjoin(self.me_dir,'bin','internal','ufomodel','ASperGE')
5670 if not os.path.exists(path):
5671 logger.error('ASperge has not been detected in the current model, therefore it will not be run.')
5672 return
5673 elif not os.path.exists(pjoin(path,'ASperGe')):
5674 logger.info('ASperGe has been detected but is not compiled. Running the compilation now.')
5675 try:
5676 misc.compile(cwd=path,shell=True)
5677 except MadGraph5Error, error:
5678 logger.error('''ASperGe failed to compile. Note that gsl is needed
5679 for this compilation to go trough. More information on how to install this package on
5680 http://www.gnu.org/software/gsl/
5681 Full compilation log is available at %s''' % pjoin(self.me_dir, 'ASperge_compilation.log'))
5682 open(pjoin(self.me_dir, 'ASperge_compilation.log'),'w').write(str(error))
5683 return
5684
5685 opts = line.split()
5686 card = self.paths['param']
5687 logger.info('running ASperGE')
5688 returncode = misc.call([pjoin(path,'ASperGe'), card, '%s.new' % card] + opts)
5689 if returncode:
5690 logger.error('ASperGE fails with status %s' % returncode)
5691 else:
5692 logger.info('AsPerGe creates the file succesfully')
5693 files.mv(card, '%s.beforeasperge' % card)
5694 files.mv('%s.new' % card, card)
5695
5696
5697
5699 """detect the type of the file and overwritte the current file"""
5700
5701 if path.endswith('.lhco'):
5702
5703
5704 self.do_set('mw_run inputfile %s' % os.path.relpath(path, self.mother_interface.me_dir))
5705 return
5706 elif path.endswith('.lhco.gz'):
5707
5708
5709 self.do_set('mw_run inputfile %s' % os.path.relpath(path, self.mother_interface.me_dir))
5710 return
5711 else:
5712 card_name = CommonRunCmd.detect_card_type(path)
5713
5714 if card_name == 'unknown':
5715 logger.warning('Fail to determine the type of the file. Not copied')
5716 if card_name != 'banner':
5717 logger.info('copy %s as %s' % (path, card_name))
5718 files.cp(path, self.paths[card_name.split('_',1)[0]])
5719 self.reload_card(self.paths[card_name.split('_',1)[0]])
5720 elif card_name == 'banner':
5721 banner_mod.split_banner(path, self.mother_interface.me_dir, proc_card=False)
5722 logger.info('Splitting the banner in it\'s component')
5723 if not self.mode == 'auto':
5724 self.mother_interface.keep_cards(self.cards)
5725 for card_name in self.cards:
5726 self.reload_card(pjoin(self.me_dir, 'Cards', card_name))
5727
5729 """open the file"""
5730 try:
5731 me_dir = self.mother_interface.me_dir
5732 except:
5733 me_dir = None
5734
5735 if answer.isdigit():
5736 if answer == '9':
5737 answer = 'plot'
5738 else:
5739 answer = self.cards[int(answer)-1]
5740
5741 if 'madweight' in answer:
5742 answer = answer.replace('madweight', 'MadWeight')
5743 elif 'MadLoopParams' in answer:
5744 answer = self.paths['ML']
5745 elif 'pythia8_card' in answer:
5746 answer = self.paths['PY8']
5747 if os.path.exists(answer):
5748 path = answer
5749 else:
5750 if not '.dat' in answer and not '.lhco' in answer:
5751 if answer != 'trigger':
5752 path = self.paths[answer]
5753 else:
5754 path = self.paths['delphes']
5755 elif not '.lhco' in answer:
5756 if '_' in answer:
5757 path = self.paths['_'.join(answer.split('_')[:-1])]
5758 else:
5759 path = pjoin(me_dir, 'Cards', answer)
5760 else:
5761 path = pjoin(me_dir, self.mw_card['mw_run']['inputfile'])
5762 if not os.path.exists(path):
5763 logger.info('Path in MW_card not existing')
5764 path = pjoin(me_dir, 'Events', answer)
5765
5766 path = path.replace('_card_card','_card')
5767 try:
5768 self.mother_interface.exec_cmd('open %s' % path)
5769 except InvalidCmd, error:
5770 if str(error) != 'No default path for this file':
5771 raise
5772 if answer == 'transfer_card.dat':
5773 logger.warning('You have to specify a transfer function first!')
5774 elif answer == 'input.lhco':
5775 path = pjoin(me_dir,'Events', 'input.lhco')
5776 ff = open(path,'w')
5777 ff.write('''No LHCO information imported at current time.
5778 To import a lhco file: Close this file and type the path of your file.
5779 You can also copy/paste, your event file here.''')
5780 ff.close()
5781 self.open_file(path)
5782 else:
5783 raise
5784 self.reload_card(path)
5785
5787 """reload object to have it in sync"""
5788
5789 if path == self.paths['param']:
5790 try:
5791 self.param_card = check_param_card.ParamCard(path)
5792 except (check_param_card.InvalidParamCard, ValueError) as e:
5793 logger.error('Current param_card is not valid. We are going to use the default one.')
5794 logger.error('problem detected: %s' % e)
5795 logger.error('Please re-open the file and fix the problem.')
5796 logger.warning('using the \'set\' command without opening the file will discard all your manual change')
5797 elif path == self.paths['run']:
5798 self.run_card = banner_mod.RunCard(path)
5799 elif path == self.paths['ML']:
5800 self.MLcard = banner_mod.MadLoopParam(path)
5801 elif path == self.paths['PY8']:
5802
5803
5804 if not self.PY8Card:
5805 self.PY8Card = banner_mod.PY8Card(self.paths['PY8_default'])
5806
5807 self.PY8Card.read(self.paths['PY8'], setter='user')
5808 self.py8_vars = [k.lower() for k in self.PY8Card.keys()]
5809 elif path == self.paths['MadWeight']:
5810 try:
5811 import madgraph.madweight.Cards as mwcards
5812 except:
5813 import internal.madweight.Cards as mwcards
5814 self.mw_card = mwcards.Card(path)
5815 return path
5816
5818 """a dedicated module for the param"""
5819
5820 special_shortcut ={}
5821
5822 - def __init__(self, question, card=[], mode='auto', *args, **opt):
5823
5824 self.load_default()
5825 cmd.OneLinePathCompletion.__init__(self, question, *args, **opt)
5826 if os.path.isfile(card[0]):
5827 self.param_card = check_param_card.ParamCard(card[0])
5828 self.paths['param'] = card[0]
5829 if os.path.isfile(card[0].replace('.dat', '_default.dat')):
5830 self.paths['param_default'] = card[0].replace('.dat', '_default.dat')
5831 else:
5832 self.paths['param_default'] = card[0]
5833 else:
5834 raise Exception, 'path %s do not exists' % card[0]
5835
5836 self.pname2block, self.restricted_value = self.param_card.analyze_param_card()
5837 self.cards=['param']
5838
5840 "Not available"
5841 logger.warning("asperge not available in this mode")
5842