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': None,
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.isfile(args[0]) and 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[0])
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 if '&&' in self.run_card['sys_pdf']:
1594 line = ' '.join(self.run_card['sys_pdf'])
1595 sys_pdf = line.split('&&')
1596 lhaid += [l.split()[0] for l in sys_pdf]
1597 else:
1598 lhaid += [l for l in self.run_card['sys_pdf'].split() if not l.isdigit() or int(l) > 500]
1599
1600 else:
1601
1602 pdf = [a[6:] for a in opts if a.startswith('--pdf=')]
1603 lhaid += [t.split('@')[0] for p in pdf for t in p.split(',')
1604 if t not in ['errorset', 'central']]
1605
1606
1607 [self.copy_lhapdf_set([onelha], pdfsets_dir) for onelha in lhaid]
1608
1609
1610 if self.options['run_mode'] ==2:
1611 nb_submit = min(self.options['nb_core'], nb_event//2500)
1612 elif self.options['run_mode'] ==1:
1613 nb_submit = min(self.options['cluster_size'], nb_event//25000)
1614 else:
1615 nb_submit =1
1616
1617 if MADEVENT:
1618 import internal.systematics as systematics
1619 else:
1620 import madgraph.various.systematics as systematics
1621
1622
1623 if nb_submit in [0,1]:
1624 systematics.call_systematics([input, output] + opts,
1625 log=lambda x: logger.info(str(x)),
1626 result=result_file
1627 )
1628
1629 elif self.options['run_mode'] in [1,2]:
1630 event_per_job = nb_event // nb_submit
1631 nb_job_with_plus_one = nb_event % nb_submit
1632 start_event, stop_event = 0,0
1633 for i in range(nb_submit):
1634
1635 event_requested = event_per_job
1636 if i < nb_job_with_plus_one:
1637 event_requested += 1
1638 start_event = stop_event
1639 stop_event = start_event + event_requested
1640
1641 prog = sys.executable
1642 input_files = [os.path.basename(input)]
1643 output_files = ['./tmp_%s_%s' % (i, os.path.basename(output)),
1644 './log_sys_%s.txt' % (i)]
1645 argument = []
1646 if not __debug__:
1647 argument.append('-O')
1648 argument += [pjoin(self.me_dir, 'bin', 'internal', 'systematics.py'),
1649 input_files[0], output_files[0]] + opts +\
1650 ['--start_event=%i' % start_event,
1651 '--stop_event=%i' %stop_event,
1652 '--result=./log_sys_%s.txt' %i,
1653 '--lhapdf_config=%s' % self.options['lhapdf']]
1654 required_output = output_files
1655 self.cluster.cluster_submit(prog, argument,
1656 input_files=input_files,
1657 output_files=output_files,
1658 cwd=os.path.dirname(output),
1659 required_output=required_output,
1660 stdout='/dev/null'
1661 )
1662 starttime = time.time()
1663 update_status = lambda idle, run, finish: \
1664 self.update_status((idle, run, finish, 'running systematics'), level=None,
1665 force=False, starttime=starttime)
1666
1667 try:
1668 self.cluster.wait(os.path.dirname(output), update_status, update_first=update_status)
1669 except Exception:
1670 self.cluster.remove()
1671 old_run_mode = self.options['run_mode']
1672 self.options['run_mode'] =0
1673 try:
1674 out = self.do_systematics(line)
1675 finally:
1676 self.options['run_mode'] = old_run_mode
1677
1678 all_cross = []
1679 for i in range(nb_submit):
1680 pos=0
1681 for line in open(pjoin(os.path.dirname(output), 'log_sys_%s.txt'%i)):
1682 if line.startswith('#'):
1683 continue
1684 split = line.split()
1685 if len(split) in [0,1]:
1686 continue
1687 key = tuple(float(x) for x in split[:-1])
1688 cross= float(split[-1])
1689 if 'event_norm' in self.run_card and \
1690 self.run_card['event_norm'] in ['average', 'unity']:
1691 cross *= (event_per_job+1 if i <nb_job_with_plus_one else event_per_job)
1692 if len(all_cross) > pos:
1693 all_cross[pos] += cross
1694 else:
1695 all_cross.append(cross)
1696 pos+=1
1697
1698 if 'event_norm' in self.run_card and \
1699 self.run_card['event_norm'] in ['unity']:
1700 all_cross= [cross/nb_event for cross in all_cross]
1701
1702 sys_obj = systematics.call_systematics([input, None] + opts,
1703 log=lambda x: logger.info(str(x)),
1704 result=result_file,
1705 running=False
1706 )
1707 sys_obj.print_cross_sections(all_cross, nb_event, result_file)
1708
1709
1710 subprocess.call(['cat']+\
1711 ['./tmp_%s_%s' % (i, os.path.basename(output)) for i in range(nb_submit)],
1712 stdout=open(output,'w'),
1713 cwd=os.path.dirname(output))
1714 for i in range(nb_submit):
1715 os.remove('%s/tmp_%s_%s' %(os.path.dirname(output),i,os.path.basename(output)))
1716
1717
1718
1719
1720
1721
1722 self.update_status('End of systematics computation', level='parton', makehtml=False)
1723
1724
1725
1727 """ syntax is "reweight RUN_NAME"
1728 Allow to reweight the events generated with a new choices of model
1729 parameter. Description of the methods are available here
1730 cp3.irmp.ucl.ac.be/projects/madgraph/wiki/Reweight
1731 """
1732
1733
1734 def check_multicore(self):
1735 """ determine if the cards are save for multicore use"""
1736 card = pjoin(self.me_dir, 'Cards', 'reweight_card.dat')
1737
1738 multicore = True
1739 if self.options['run_mode'] in [0,1]:
1740 multicore = False
1741
1742 lines = [l.strip() for l in open(card) if not l.strip().startswith('#')]
1743 while lines and not lines[0].startswith('launch'):
1744 line = lines.pop(0)
1745
1746 if line.startswith('change') and line[6:].strip().startswith('output'):
1747 return False
1748 if line.startswith('change') and line[6:].strip().startswith('multicore'):
1749 split_line = line.split()
1750 if len(split_line) > 2:
1751 multicore = bool(split_line[2])
1752
1753
1754 lines = [line[6:].strip() for line in lines if line.startswith('change')]
1755 for line in lines:
1756 if line.startswith(('process','model','output', 'rwgt_dir')):
1757 return False
1758 elif line.startswith('multicore'):
1759 split_line = line.split()
1760 if len(split_line) > 1:
1761 multicore = bool(split_line[1])
1762
1763 return multicore
1764
1765
1766
1767 if '-from_cards' in line and not os.path.exists(pjoin(self.me_dir, 'Cards', 'reweight_card.dat')):
1768 return
1769
1770 if '--multicore=create' in line:
1771 multicore='create'
1772 elif '--multicore=wait' in line:
1773 multicore='wait'
1774 else:
1775 multicore=False
1776
1777
1778 if MADEVENT and not self.options['mg5_path']:
1779 raise self.InvalidCmd, '''The module reweight requires that MG5 is installed on the system.
1780 You can install it and set its path in ./Cards/me5_configuration.txt'''
1781 elif MADEVENT:
1782 sys.path.append(self.options['mg5_path'])
1783 try:
1784 import madgraph.interface.reweight_interface as reweight_interface
1785 except ImportError:
1786 raise self.ConfigurationError, '''Can\'t load Reweight module.
1787 The variable mg5_path might not be correctly configured.'''
1788
1789
1790
1791 if not '-from_cards' in line:
1792 self.keep_cards(['reweight_card.dat'], ignore=['*'])
1793 self.ask_edit_cards(['reweight_card.dat'], 'fixed', plot=False)
1794
1795
1796 args = self.split_arg(line)
1797
1798 if not self.force_run:
1799
1800 if self.run_name and self.results.current and self.results.current['cross'] == 0:
1801 self.results.delete_run(self.run_name, self.run_tag)
1802 self.results.save()
1803
1804 if not hasattr(self, 'run_card'):
1805 self.run_card = banner_mod.RunCard(pjoin(self.me_dir, 'Cards', 'run_card.dat'))
1806
1807
1808 command = [sys.executable]
1809 if os.path.exists(pjoin(self.me_dir, 'bin', 'madevent')):
1810 command.append(pjoin(self.me_dir, 'bin', 'internal','madevent_interface.py'))
1811 else:
1812 command.append(pjoin(self.me_dir, 'bin', 'internal', 'amcatnlo_run_interface.py'))
1813 if not isinstance(self, cmd.CmdShell):
1814 command.append('--web')
1815 command.append('reweight')
1816
1817
1818 if self.options['nb_core']==1 or self.run_card['nevents'] < 101 or not check_multicore(self):
1819 if self.run_name:
1820 command.append(self.run_name)
1821 else:
1822 command += args
1823 if '-from_cards' not in command:
1824 command.append('-from_cards')
1825 p = misc.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, cwd=os.getcwd())
1826 while p.poll() is None:
1827 line = p.stdout.readline()
1828 if any(t in line for t in ['INFO:', 'WARNING:', 'CRITICAL:', 'ERROR:', 'root:','KEEP:']) and \
1829 not '***********' in line:
1830 print line[:-1].replace('INFO', 'REWEIGHT').replace('KEEP:','')
1831 elif __debug__ and line:
1832 logger.debug(line[:-1])
1833 if p.returncode !=0:
1834 logger.error("Reweighting failed")
1835 return
1836 self.results = self.load_results_db()
1837
1838 try:
1839 if self.results[self.run_name][-2]['cross']==0:
1840 self.results.delete_run(self.run_name,self.results[self.run_name][-2]['tag'])
1841 except:
1842 pass
1843 try:
1844 if self.results.current['cross'] == 0 and self.run_name:
1845 self.results.delete_run(self.run_name, self.run_tag)
1846 except:
1847 pass
1848
1849 try:
1850 self.results.def_current(self.run_name, self.run_tag)
1851 except Exception:
1852 pass
1853 return
1854
1855 else:
1856
1857 if not isinstance(self.cluster, cluster.MultiCore):
1858 mycluster = cluster.MultiCore(nb_core=self.options['nb_core'])
1859 else:
1860 mycluster = self.cluster
1861
1862 new_args=list(args)
1863 self.check_decay_events(new_args)
1864 try:
1865 os.remove(pjoin(self.me_dir,'rw_me','rwgt.pkl'))
1866 except Exception, error:
1867 pass
1868
1869 import madgraph.various.lhe_parser as lhe_parser
1870
1871 if 'nevt_job' in self.run_card and self.run_card['nevt_job'] !=-1:
1872 nevt_job = self.run_card['nevt_job']
1873 else:
1874 nevt_job = max(5000, self.run_card['nevents']/50)
1875 logger.info("split the event file in bunch of %s events" % nevt_job)
1876 nb_file = lhe_parser.EventFile(new_args[0]).split(nevt_job)
1877 starttime = time.time()
1878 update_status = lambda idle, run, finish: \
1879 self.update_status((idle, run, finish, 'reweight'), level=None,
1880 force=False, starttime=starttime)
1881
1882 all_lhe = []
1883 devnull= open(os.devnull)
1884 for i in range(nb_file):
1885 new_command = list(command)
1886 new_command.append('%s_%s.lhe' % (new_args[0],i))
1887 all_lhe.append('%s_%s.lhe' % (new_args[0],i))
1888 if '-from_cards' not in command:
1889 new_command.append('-from_cards')
1890 if i==0:
1891 if __debug__:
1892 stdout = None
1893 else:
1894 stdout = open(pjoin(self.me_dir,'Events', self.run_name, 'reweight.log'),'w')
1895 new_command.append('--multicore=create')
1896 else:
1897 stdout = devnull
1898
1899 new_command.append('--multicore=wait')
1900 mycluster.submit(prog=command[0], argument=new_command[1:], stdout=stdout, cwd=os.getcwd())
1901 mycluster.wait(self.me_dir,update_status)
1902 devnull.close()
1903 logger.info("Collect and combine the various output file.")
1904 lhe = lhe_parser.MultiEventFile(all_lhe, parse=False)
1905 nb_event, cross_sections = lhe.write(new_args[0], get_info=True)
1906 if any(os.path.exists('%s_%s_debug.log' % (f, self.run_tag)) for f in all_lhe):
1907 for f in all_lhe:
1908 if os.path.exists('%s_%s_debug.log' % (f, self.run_tag)):
1909 raise Exception, "Some of the run failed: Please read %s_%s_debug.log" % (f, self.run_tag)
1910
1911
1912 if 'event_norm' in self.run_card and self.run_card['event_norm'] == 'average':
1913 for key, value in cross_sections.items():
1914 cross_sections[key] = value / (nb_event+1)
1915 lhe.remove()
1916 for key in cross_sections:
1917 if key == 'orig' or key.isdigit():
1918 continue
1919 logger.info('%s : %s pb' % (key, cross_sections[key]))
1920 return
1921
1922
1923
1924 self.to_store.append('event')
1925
1926 if self.results.current['cross'] == 0 and self.run_name:
1927 self.results.delete_run(self.run_name, self.run_tag)
1928
1929 self.check_decay_events(args)
1930
1931 reweight_cmd = reweight_interface.ReweightInterface(args[0], mother=self)
1932
1933
1934 wgt_names = reweight_cmd.get_weight_names()
1935 if wgt_names == [''] and reweight_cmd.has_nlo:
1936 self.update_status('Running Reweighting (LO approximate)', level='madspin')
1937 else:
1938 self.update_status('Running Reweighting', level='madspin')
1939
1940 path = pjoin(self.me_dir, 'Cards', 'reweight_card.dat')
1941 reweight_cmd.raw_input=False
1942 reweight_cmd.me_dir = self.me_dir
1943 reweight_cmd.multicore = multicore
1944 print "We are in mode", multicore
1945 reweight_cmd.import_command_file(path)
1946 reweight_cmd.do_quit('')
1947
1948 logger.info("quit rwgt")
1949
1950
1951
1952
1953 try:
1954 self.results.def_current(self.run_name, self.run_tag)
1955 except Exception:
1956 pass
1957
1958
1960 """launch pgs"""
1961
1962 args = self.split_arg(line)
1963
1964 if '--no_default' in args:
1965 no_default = True
1966 args.remove('--no_default')
1967 else:
1968 no_default = False
1969
1970 if no_default and not os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')):
1971 logger.info('No pgs_card detected, so not run pgs')
1972 return
1973
1974
1975
1976
1977
1978
1979 lock = self.check_pgs(args, no_default=no_default)
1980
1981
1982 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')):
1983 files.cp(pjoin(self.me_dir, 'Cards', 'pgs_card_default.dat'),
1984 pjoin(self.me_dir, 'Cards', 'pgs_card.dat'))
1985 logger.info('No pgs card found. Take the default one.')
1986
1987 if not (no_default or self.force):
1988 self.ask_edit_cards(['pgs_card.dat'])
1989
1990 self.update_status('prepare PGS run', level=None)
1991
1992 pgsdir = pjoin(self.options['pythia-pgs_path'], 'src')
1993 eradir = self.options['exrootanalysis_path']
1994 madir = self.options['madanalysis_path']
1995 td = self.options['td_path']
1996
1997
1998 if not misc.is_executable(pjoin(pgsdir, 'pgs')):
1999 logger.info('No PGS executable -- running make')
2000 misc.compile(cwd=pgsdir)
2001
2002 self.update_status('Running PGS', level='pgs')
2003
2004 tag = self.run_tag
2005
2006 banner_path = pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, self.run_tag))
2007 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')):
2008 self.banner.add(pjoin(self.me_dir, 'Cards','pgs_card.dat'))
2009 self.banner.write(banner_path)
2010 else:
2011 open(banner_path, 'w').close()
2012
2013
2014
2015
2016 if lock:
2017 lock.wait()
2018
2019 ff = open(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'), 'w')
2020 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')):
2021 text = open(banner_path).read()
2022 text = '#%s' % text.replace('\n','\n#')
2023 dico = self.results[self.run_name].get_current_info()
2024 text +='\n## Integrated weight (pb) : %.4g' % dico['cross']
2025 text +='\n## Number of Event : %s\n' % dico['nb_event']
2026 ff.writelines(text)
2027 ff.close()
2028
2029 try:
2030 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done'))
2031 except Exception:
2032 pass
2033
2034 pgs_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_pgs.log" % tag)
2035 self.cluster.launch_and_wait('../bin/internal/run_pgs',
2036 argument=[pgsdir], cwd=pjoin(self.me_dir,'Events'),
2037 stdout=pgs_log, stderr=subprocess.STDOUT)
2038
2039 if not os.path.exists(pjoin(self.me_dir, 'Events', 'pgs.done')):
2040 logger.error('Fail to create LHCO events')
2041 return
2042 else:
2043 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done'))
2044
2045 if os.path.getsize(banner_path) == os.path.getsize(pjoin(self.me_dir, 'Events','pgs_events.lhco')):
2046 misc.call(['cat pgs_uncleaned_events.lhco >> pgs_events.lhco'],
2047 cwd=pjoin(self.me_dir, 'Events'))
2048 os.remove(pjoin(self.me_dir, 'Events', 'pgs_uncleaned_events.lhco '))
2049
2050
2051 if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHCOlympicsConverter')):
2052 self.update_status('Creating PGS Root File', level='pgs')
2053 try:
2054 misc.call([eradir+'/ExRootLHCOlympicsConverter',
2055 'pgs_events.lhco',pjoin('%s/%s_pgs_events.root' % (self.run_name, tag))],
2056 cwd=pjoin(self.me_dir, 'Events'))
2057 except Exception:
2058 logger.warning('fail to produce Root output [problem with ExRootAnalysis')
2059 if os.path.exists(pjoin(self.me_dir, 'Events', 'pgs_events.lhco')):
2060
2061 files.mv(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'),
2062 pjoin(self.me_dir, 'Events', self.run_name, '%s_pgs_events.lhco' % tag))
2063 self.create_plot('PGS')
2064 misc.gzip(pjoin(self.me_dir, 'Events', self.run_name, '%s_pgs_events.lhco' % tag))
2065
2066 self.update_status('finish', level='pgs', makehtml=False)
2067
2068
2070 """Require MG5 directory: Compute automatically the widths of a set
2071 of particles"""
2072
2073
2074
2075 args = self.split_arg(line)
2076 opts = self.check_compute_widths(args)
2077
2078 from madgraph.interface.master_interface import MasterCmd
2079 cmd = MasterCmd()
2080 self.define_child_cmd_interface(cmd, interface=False)
2081 cmd.exec_cmd('set automatic_html_opening False --no_save')
2082 if not opts['path']:
2083 opts['path'] = pjoin(self.me_dir, 'Cards', 'param_card.dat')
2084 if not opts['force'] :
2085 self.ask_edit_cards(['param_card'],[], plot=False)
2086
2087
2088 line = 'compute_widths %s %s' % \
2089 (' '.join([str(i) for i in opts['particles']]),
2090 ' '.join('--%s=%s' % (key,value) for (key,value) in opts.items()
2091 if key not in ['model', 'force', 'particles'] and value))
2092 cmd.exec_cmd(line, model=opts['model'])
2093 self.child = None
2094 del cmd
2095
2096
2098 """Not in help:Print the cross-section/ number of events for a given run"""
2099
2100 args = self.split_arg(line)
2101 options={'path':None, 'mode':'w', 'format':'full'}
2102 for arg in list(args):
2103 if arg.startswith('--') and '=' in arg:
2104 name,value=arg.split('=',1)
2105 name = name [2:]
2106 options[name] = value
2107 args.remove(arg)
2108
2109
2110 if len(args) > 0:
2111 run_name = args[0]
2112 else:
2113 for i, run_name in enumerate(self.results.order):
2114 for j, one_result in enumerate(self.results[run_name]):
2115 if i or j:
2116 options['mode'] = "a"
2117 if options['path']:
2118 self.print_results_in_file(one_result, options['path'], options['mode'], options['format'])
2119 else:
2120 self.print_results_in_shell(one_result)
2121 return
2122
2123 if run_name not in self.results:
2124 raise self.InvalidCmd('%s is not a valid run_name or it doesn\'t have any information' \
2125 % run_name)
2126
2127
2128 if len(args) == 2:
2129 tag = args[1]
2130 if tag.isdigit():
2131 tag = int(tag) - 1
2132 if len(self.results[run_name]) < tag:
2133 raise self.InvalidCmd('Only %s different tag available' % \
2134 len(self.results[run_name]))
2135 data = self.results[run_name][tag]
2136 else:
2137 data = self.results[run_name].return_tag(tag)
2138 else:
2139 data = self.results[run_name].return_tag(None)
2140
2141 if options['path']:
2142 self.print_results_in_file(data, options['path'], options['mode'], options['format'])
2143 else:
2144 self.print_results_in_shell(data)
2145
2150
2151
2152
2153
2154
2155 @staticmethod
2156 - def runMA5(MA5_interpreter, MA5_cmds, MA5_runtag, logfile_path, advertise_log=True):
2157 """ Run MA5 in a controlled environnment."""
2158 successfull_MA5_run = True
2159
2160 try:
2161
2162 MA5_logger = None
2163 MA5_logger = logging.getLogger('MA5')
2164 BackUp_MA5_handlers = MA5_logger.handlers
2165 for handler in BackUp_MA5_handlers:
2166 MA5_logger.removeHandler(handler)
2167 file_handler = logging.FileHandler(logfile_path)
2168 MA5_logger.addHandler(file_handler)
2169 if advertise_log:
2170 logger.info("Follow Madanalysis5 run with the following command in a separate terminal:")
2171 logger.info(' tail -f %s'%logfile_path)
2172
2173 with misc.stdchannel_redirected(sys.stdout, os.devnull):
2174 with misc.stdchannel_redirected(sys.stderr, os.devnull):
2175 MA5_interpreter.print_banner()
2176 MA5_interpreter.load(MA5_cmds)
2177 except Exception as e:
2178 logger.warning("MadAnalysis5 failed to run the commands for task "+
2179 "'%s'. Madanalys5 analysis will be skipped."%MA5_runtag)
2180 error=StringIO.StringIO()
2181 traceback.print_exc(file=error)
2182 logger.debug('MadAnalysis5 error was:')
2183 logger.debug('-'*60)
2184 logger.debug(error.getvalue()[:-1])
2185 logger.debug('-'*60)
2186 successfull_MA5_run = False
2187 finally:
2188 if not MA5_logger is None:
2189 for handler in MA5_logger.handlers:
2190 MA5_logger.removeHandler(handler)
2191 for handler in BackUp_MA5_handlers:
2192 MA5_logger.addHandler(handler)
2193
2194 return successfull_MA5_run
2195
2196
2197
2198
2199 @staticmethod
2202 """ Makes sure to correctly setup paths and constructs and return an MA5 path"""
2203
2204 MA5path = os.path.normpath(pjoin(mg5_path,ma5_path))
2205
2206 if MA5path is None or not os.path.isfile(pjoin(MA5path,'bin','ma5')):
2207 return None
2208 if MA5path not in sys.path:
2209 sys.path.insert(0, MA5path)
2210
2211 try:
2212
2213
2214 import readline
2215 old_completer = readline.get_completer()
2216 old_delims = readline.get_completer_delims()
2217 old_history = [readline.get_history_item(i) for i in range(1,readline.get_current_history_length()+1)]
2218 except ImportError:
2219 old_completer, old_delims, old_history = None, None, None
2220 try:
2221 from madanalysis.interpreter.ma5_interpreter import MA5Interpreter
2222 with misc.stdchannel_redirected(sys.stdout, os.devnull):
2223 with misc.stdchannel_redirected(sys.stderr, os.devnull):
2224 MA5_interpreter = MA5Interpreter(MA5path, LoggerLevel=loglevel,
2225 LoggerStream=logstream,forced=forced)
2226 except Exception as e:
2227 logger.warning('MadAnalysis5 failed to start so that MA5 analysis will be skipped.')
2228 error=StringIO.StringIO()
2229 traceback.print_exc(file=error)
2230 logger.debug('MadAnalysis5 error was:')
2231 logger.debug('-'*60)
2232 logger.debug(error.getvalue()[:-1])
2233 logger.debug('-'*60)
2234 MA5_interpreter = None
2235 finally:
2236
2237 if not old_history is None:
2238 readline.clear_history()
2239 for line in old_history:
2240 readline.add_history(line)
2241 if not old_completer is None:
2242 readline.set_completer(old_completer)
2243 if not old_delims is None:
2244 readline.set_completer_delims(old_delims)
2245
2246
2247 if not mg5_interface is None and any(not elem is None for elem in [old_completer, old_delims, old_history]):
2248 mg5_interface.set_readline_completion_display_matches_hook()
2249
2250 return MA5_interpreter
2251
2253 """Check the argument for the madanalysis5 command
2254 syntax: madanalysis5_parton [NAME]
2255 """
2256
2257 MA5_options = {'MA5_stdout_lvl':'default'}
2258
2259 stdout_level_tags = [a for a in args if a.startswith('--MA5_stdout_lvl=')]
2260 for slt in stdout_level_tags:
2261 lvl = slt.split('=')[1].strip()
2262 try:
2263
2264 MA5_options['MA5_stdout_lvl']=int(lvl)
2265 except ValueError:
2266 if lvl.startswith('logging.'):
2267 lvl = lvl[8:]
2268 try:
2269 MA5_options['MA5_stdout_lvl'] = getattr(logging, lvl)
2270 except:
2271 raise InvalidCmd("MA5 output level specification"+\
2272 " '%s' is incorrect." % str(lvl))
2273 args.remove(slt)
2274
2275 if mode=='parton':
2276
2277
2278 MA5_options['inputs'] = '*.lhe'
2279 elif mode=='hadron':
2280
2281
2282
2283 MA5_options['inputs'] = ['fromCard']
2284 else:
2285 raise MadGraph5Error('Mode %s not reckognized'%mode+
2286 ' in function check_madanalysis5.')
2287
2288 if not self.options['madanalysis5_path']:
2289 logger.info('Now trying to read the configuration file again'+
2290 ' to find MadAnalysis5 path')
2291 self.set_configuration()
2292
2293 if not self.options['madanalysis5_path'] or not \
2294 os.path.exists(pjoin(self.options['madanalysis5_path'],'bin','ma5')):
2295 error_msg = 'No valid MadAnalysis5 path set.\n'
2296 error_msg += 'Please use the set command to define the path and retry.\n'
2297 error_msg += 'You can also define it in the configuration file.\n'
2298 error_msg += 'Finally, it can be installed automatically using the'
2299 error_msg += ' install command.\n'
2300 raise self.InvalidCmd(error_msg)
2301
2302
2303 if not os.path.isfile(pjoin(self.me_dir,
2304 'Cards','madanalysis5_%s_card.dat'%mode)):
2305 raise self.InvalidCmd('Your installed version of MadAnalysis5 and/or'+\
2306 ' MadGraph5_aMCatNLO does not seem to support analysis at'+
2307 '%s level.'%mode)
2308
2309 tag = [a for a in args if a.startswith('--tag=')]
2310 if tag:
2311 args.remove(tag[0])
2312 tag = tag[0][6:]
2313
2314 if len(args) == 0 and not self.run_name:
2315 if self.results.lastrun:
2316 args.insert(0, self.results.lastrun)
2317 else:
2318 raise self.InvalidCmd('No run name currently defined. '+
2319 'Please add this information.')
2320
2321 if len(args) >= 1:
2322 if mode=='parton' and args[0] != self.run_name and \
2323 not os.path.exists(pjoin(self.me_dir,'Events',args[0],
2324 'unweighted_events.lhe.gz')) and not os.path.exists(
2325 pjoin(self.me_dir,'Events',args[0])):
2326 raise self.InvalidCmd('No events file in the %s run.'%args[0])
2327 self.set_run_name(args[0], tag, level='madanalysis5_%s'%mode)
2328 else:
2329 if tag:
2330 self.run_card['run_tag'] = args[0]
2331 self.set_run_name(self.run_name, tag, level='madanalysis5_%s'%mode)
2332
2333 if mode=='parton':
2334 if any(t for t in args if t.startswith('--input=')):
2335 raise InvalidCmd('The option --input=<input_file> is not'+
2336 ' available when running partonic MadAnalysis5 analysis. The'+
2337 ' .lhe output of the selected run is used automatically.')
2338 input_file = pjoin(self.me_dir,'Events',self.run_name, 'unweighted_events.lhe')
2339 MA5_options['inputs'] = '%s.gz'%input_file
2340 if not os.path.exists('%s.gz'%input_file):
2341 if os.path.exists(input_file):
2342 misc.gzip(input_file, keep=True, stdout=output_file)
2343 else:
2344 logger.warning("LHE event file not found in \n%s\ns"%input_file+
2345 "Parton-level MA5 analysis will be skipped.")
2346
2347 if mode=='hadron':
2348
2349
2350 self.store_result()
2351
2352 hadron_tag = [t for t in args if t.startswith('--input=')]
2353 if hadron_tag and hadron_tag[0][8:]:
2354 hadron_inputs = hadron_tag[0][8:].split(',')
2355
2356
2357 elif MA5_options['inputs'] == ['fromCard']:
2358 hadron_inputs = banner_mod.MadAnalysis5Card(pjoin(self.me_dir,
2359 'Cards','madanalysis5_hadron_card.dat'),mode='hadron')['inputs']
2360
2361
2362
2363 MA5_options['inputs'] = []
2364 special_source_tags = []
2365 for htag in hadron_inputs:
2366
2367 if htag in special_source_tags:
2368
2369 continue
2370
2371 if os.path.isfile(htag) or (os.path.exists(htag) and
2372 stat.S_ISFIFO(os.stat(htag).st_mode)):
2373 MA5_options['inputs'].append(htag)
2374 continue
2375
2376
2377
2378 file_candidates = misc.glob(htag, pjoin(self.me_dir,'Events',self.run_name))+\
2379 misc.glob('%s.gz'%htag, pjoin(self.me_dir,'Events',self.run_name))
2380 priority_files = [f for f in file_candidates if
2381 self.run_card['run_tag'] in os.path.basename(f)]
2382 priority_files = [f for f in priority_files if
2383 'EVENTS' in os.path.basename(f).upper()]
2384
2385 for f in file_candidates:
2386 if os.path.basename(f).startswith('unweighted_events.lhe'):
2387 priority_files.append(f)
2388 if priority_files:
2389 MA5_options['inputs'].append(priority_files[-1])
2390 continue
2391 if file_candidates:
2392 MA5_options['inputs'].append(file_candidates[-1])
2393 continue
2394
2395 return MA5_options
2396
2398 """Ask the question when launching madanalysis5.
2399 In the future we can ask here further question about the MA5 run, but
2400 for now we just edit the cards"""
2401
2402 cards = ['madanalysis5_%s_card.dat'%runtype]
2403 self.keep_cards(cards)
2404
2405 if self.force:
2406 return runtype
2407
2408
2409
2410 auto=False
2411 if mode=='auto':
2412 auto=True
2413 if auto:
2414 self.ask_edit_cards(cards, mode='auto', plot=False)
2415 else:
2416 self.ask_edit_cards(cards, plot=False)
2417
2418
2419
2420 mode = runtype
2421 return mode
2422
2424 "Complete the madanalysis5 command"
2425 args = self.split_arg(line[0:begidx], error=False)
2426 if len(args) == 1:
2427
2428 data = []
2429 for name in banner_mod.MadAnalysis5Card._default_hadron_inputs:
2430 data += misc.glob(pjoin('*','%s'%name), pjoin(self.me_dir, 'Events'))
2431 data += misc.glob(pjoin('*','%s.gz'%name), pjoin(self.me_dir, 'Events'))
2432 data = [n.rsplit('/',2)[1] for n in data]
2433 tmp1 = self.list_completion(text, data)
2434 if not self.run_name:
2435 return tmp1
2436 else:
2437 tmp2 = self.list_completion(text, ['-f',
2438 '--MA5_stdout_lvl=','--input=','--no_default', '--tag='], line)
2439 return tmp1 + tmp2
2440
2441 elif '--MA5_stdout_lvl=' in line and not any(arg.startswith(
2442 '--MA5_stdout_lvl=') for arg in args):
2443 return self.list_completion(text,
2444 ['--MA5_stdout_lvl=%s'%opt for opt in
2445 ['logging.INFO','logging.DEBUG','logging.WARNING',
2446 'logging.CRITICAL','90']], line)
2447 elif '--input=' in line and not any(arg.startswith(
2448 '--input=') for arg in args):
2449 return self.list_completion(text, ['--input=%s'%opt for opt in
2450 (banner_mod.MadAnalysis5Card._default_hadron_inputs +['path'])], line)
2451 else:
2452 return self.list_completion(text, ['-f',
2453 '--MA5_stdout_lvl=','--input=','--no_default', '--tag='], line)
2454
2456 """launch MadAnalysis5 at the hadron level."""
2457 return self.run_madanalysis5(line,mode='hadron')
2458
2460 """launch MadAnalysis5 at the parton level or at the hadron level with
2461 a specific command line."""
2462
2463
2464 args = self.split_arg(line)
2465
2466 if '--no_default' in args:
2467 no_default = True
2468 args.remove('--no_default')
2469 else:
2470 no_default = False
2471
2472 if no_default:
2473
2474 if mode=='parton' and not os.path.exists(pjoin(self.me_dir, 'Cards',
2475 'madanalysis5_parton_card.dat')):
2476 return
2477 if mode=='hadron' and not os.path.exists(pjoin(self.me_dir, 'Cards',
2478 'madanalysis5_hadron_card.dat')):
2479 return
2480 else:
2481
2482
2483 self.ask_madanalysis5_run_configuration(runtype=mode)
2484
2485 if not self.options['madanalysis5_path'] or \
2486 all(not os.path.exists(pjoin(self.me_dir, 'Cards',card)) for card in
2487 ['madanalysis5_parton_card.dat','madanalysis5_hadron_card.dat']):
2488 if no_default:
2489 return
2490 else:
2491 raise InvalidCmd('You must have MadAnalysis5 available to run'+
2492 " this command. Consider installing it with the 'install' function.")
2493
2494 if not self.run_name:
2495 MA5_opts = self.check_madanalysis5(args, mode=mode)
2496 self.configure_directory(html_opening =False)
2497 else:
2498
2499 self.configure_directory(html_opening =False)
2500 MA5_opts = self.check_madanalysis5(args, mode=mode)
2501
2502
2503 if MA5_opts['inputs']==[]:
2504 if no_default:
2505 logger.warning('No hadron level input found to run MadAnalysis5 on.'+
2506 ' Skipping its hadron-level analysis.')
2507 return
2508 else:
2509 raise self.InvalidCmd('\nNo input files specified or availabled for'+
2510 ' this MadAnalysis5 hadron-level run.\nPlease double-check the options of this'+
2511 ' MA5 command (or card) and which output files\nare currently in the chosen'+
2512 " run directory '%s'."%self.run_name)
2513
2514 MA5_card = banner_mod.MadAnalysis5Card(pjoin(self.me_dir, 'Cards',
2515 'madanalysis5_%s_card.dat'%mode), mode=mode)
2516
2517 if MA5_card._skip_analysis:
2518 logger.info('Madanalysis5 %s-level analysis was skipped following user request.'%mode)
2519 logger.info("To run the analysis, remove or comment the tag '%s skip_analysis' "
2520 %banner_mod.MadAnalysis5Card._MG5aMC_escape_tag+
2521 "in\n '%s'."%pjoin(self.me_dir, 'Cards','madanalysis5_%s_card.dat'%mode))
2522 return
2523
2524 MA5_cmds_list = MA5_card.get_MA5_cmds(MA5_opts['inputs'],
2525 pjoin(self.me_dir,'MA5_%s_ANALYSIS'%mode.upper()),
2526 run_dir_path = pjoin(self.me_dir,'Events', self.run_name),
2527 UFO_model_path=pjoin(self.me_dir,'bin','internal','ufomodel'),
2528 run_tag = self.run_tag)
2529
2530
2531
2532
2533
2534
2535
2536
2537 self.update_status('\033[92mRunning MadAnalysis5 [arXiv:1206.1599]\033[0m',
2538 level='madanalysis5_%s'%mode)
2539 if mode=='hadron':
2540 logger.info('Hadron input files considered:')
2541 for input in MA5_opts['inputs']:
2542 logger.info(' --> %s'%input)
2543 elif mode=='parton':
2544 logger.info('Parton input file considered:')
2545 logger.info(' --> %s'%MA5_opts['inputs'])
2546
2547
2548
2549
2550 if MA5_opts['MA5_stdout_lvl']=='default':
2551 if MA5_card['stdout_lvl'] is None:
2552 MA5_lvl = self.options['stdout_level']
2553 else:
2554 MA5_lvl = MA5_card['stdout_lvl']
2555 else:
2556 MA5_lvl = MA5_opts['MA5_stdout_lvl']
2557
2558
2559 MA5_interpreter = CommonRunCmd.get_MadAnalysis5_interpreter(
2560 self.options['mg5_path'],
2561 self.options['madanalysis5_path'],
2562 logstream=sys.stdout,
2563 loglevel=100,
2564 forced=True)
2565
2566
2567
2568 if MA5_interpreter is None:
2569 return
2570
2571
2572 used_up_fifos = []
2573
2574 for MA5_runtag, MA5_cmds in MA5_cmds_list:
2575
2576
2577 MA5_interpreter.setLogLevel(100)
2578
2579 if mode=='hadron':
2580 MA5_interpreter.init_reco()
2581 else:
2582 MA5_interpreter.init_parton()
2583 MA5_interpreter.setLogLevel(MA5_lvl)
2584
2585 if MA5_runtag!='default':
2586 if MA5_runtag.startswith('_reco_'):
2587 logger.info("MadAnalysis5 now running the reconstruction '%s'..."%
2588 MA5_runtag[6:],'$MG:color:GREEN')
2589 elif MA5_runtag=='Recasting':
2590 logger.info("MadAnalysis5 now running the recasting...",
2591 '$MG:color:GREEN')
2592 else:
2593 logger.info("MadAnalysis5 now running the '%s' analysis..."%
2594 MA5_runtag,'$MG:color:GREEN')
2595
2596
2597
2598 if not CommonRunCmd.runMA5(MA5_interpreter, MA5_cmds, MA5_runtag,
2599 pjoin(self.me_dir,'Events',self.run_name,'%s_MA5_%s.log'%(self.run_tag,MA5_runtag))):
2600
2601 return
2602
2603 if MA5_runtag.startswith('_reco_'):
2604
2605
2606
2607
2608 links_created=[]
2609 for i, input in enumerate(MA5_opts['inputs']):
2610
2611
2612 if not banner_mod.MadAnalysis5Card.events_can_be_reconstructed(input):
2613 continue
2614
2615 if input.endswith('.fifo'):
2616 if input in used_up_fifos:
2617
2618 continue
2619 else:
2620 used_up_fifos.append(input)
2621
2622 reco_output = pjoin(self.me_dir,
2623 'MA5_%s_ANALYSIS%s_%d'%(mode.upper(),MA5_runtag,i+1))
2624
2625 reco_event_file = misc.glob('*.lhe.gz',pjoin(reco_output,'Output','_reco_events'))+\
2626 misc.glob('*.root',pjoin(reco_output,'Output','_reco_events'))
2627 if len(reco_event_file)==0:
2628 raise MadGraph5Error, "MadAnalysis5 failed to produce the "+\
2629 "reconstructed event file for reconstruction '%s'."%MA5_runtag[6:]
2630 reco_event_file = reco_event_file[0]
2631
2632 shutil.move(reco_output,pjoin(self.me_dir,'HTML',
2633 self.run_name,'%s_MA5_%s_ANALYSIS%s_%d'%
2634 (self.run_tag,mode.upper(),MA5_runtag,i+1)))
2635
2636 links_created.append(os.path.basename(reco_event_file))
2637 files.ln(pjoin(self.me_dir,'HTML',self.run_name,
2638 '%s_MA5_%s_ANALYSIS%s_%d'%(self.run_tag,mode.upper(),
2639 MA5_runtag,i+1),'Output','_reco_events',links_created[-1]),
2640 pjoin(self.me_dir,'Events',self.run_name))
2641
2642 logger.info("MadAnalysis5 successfully completed the reconstruction "+
2643 "'%s'. Links to the reconstructed event files are:"%MA5_runtag[6:])
2644 for link in links_created:
2645 logger.info(' --> %s'%pjoin(self.me_dir,'Events',self.run_name,link))
2646 continue
2647
2648 if MA5_runtag.upper()=='RECASTING':
2649 target = pjoin(self.me_dir,'MA5_%s_ANALYSIS_%s'\
2650 %(mode.upper(),MA5_runtag),'Output','CLs_output_summary.dat')
2651 else:
2652 target = pjoin(self.me_dir,'MA5_%s_ANALYSIS_%s'\
2653 %(mode.upper(),MA5_runtag),'PDF','main.pdf')
2654 if not os.path.isfile(target):
2655 raise MadGraph5Error, "MadAnalysis5 failed to produced "+\
2656 "an output for the analysis '%s' in\n %s"%(MA5_runtag,target)
2657
2658
2659 if MA5_runtag.upper()=='RECASTING':
2660 carboncopy_name = '%s_MA5_CLs.dat'%(self.run_tag)
2661 else:
2662 carboncopy_name = '%s_MA5_%s_analysis_%s.pdf'%(
2663 self.run_tag,mode,MA5_runtag)
2664 shutil.copy(target, pjoin(self.me_dir,'Events',self.run_name,carboncopy_name))
2665 if MA5_runtag!='default':
2666 logger.info("MadAnalysis5 successfully completed the "+
2667 "%s. Reported results are placed in:"%("analysis '%s'"%MA5_runtag
2668 if MA5_runtag.upper()!='RECASTING' else "recasting"))
2669 else:
2670 logger.info("MadAnalysis5 successfully completed the analysis."+
2671 " Reported results are placed in:")
2672 logger.info(' --> %s'%pjoin(self.me_dir,'Events',self.run_name,carboncopy_name))
2673
2674
2675 shutil.move(pjoin(self.me_dir,'MA5_%s_ANALYSIS_%s'\
2676 %(mode.upper(),MA5_runtag)), pjoin(self.me_dir,'HTML',self.run_name,
2677 '%s_MA5_%s_ANALYSIS_%s'%(self.run_tag,mode.upper(),MA5_runtag)))
2678
2679
2680
2681 new_details={}
2682 for detail in ['nb_event','cross','error']:
2683 new_details[detail] = \
2684 self.results[self.run_name].get_current_info()[detail]
2685 for detail in new_details:
2686 self.results.add_detail(detail,new_details[detail])
2687
2688 self.update_status('Finished MA5 analyses.', level='madanalysis5_%s'%mode,
2689 makehtml=False)
2690
2691
2692 self.banner.add(pjoin(self.me_dir, 'Cards',
2693 'madanalysis5_%s_card.dat'%mode))
2694 banner_path = pjoin(self.me_dir,'Events', self.run_name,
2695 '%s_%s_banner.txt'%(self.run_name, self.run_tag))
2696 self.banner.write(banner_path)
2697
2698 if not no_default:
2699 logger.info('Find more information about this run on the HTML local page')
2700 logger.info(' --> %s'%pjoin(self.me_dir,'index.html'))
2701
2702
2703
2704
2705
2707 """ run delphes and make associate root file/plot """
2708
2709 args = self.split_arg(line)
2710
2711 if '--no_default' in args:
2712 no_default = True
2713 args.remove('--no_default')
2714 else:
2715 no_default = False
2716
2717 if no_default and not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
2718 logger.info('No delphes_card detected, so not run Delphes')
2719 return
2720
2721
2722 filepath = self.check_delphes(args, nodefault=no_default)
2723 if no_default and not filepath:
2724 return
2725
2726 self.update_status('prepare delphes run', level=None)
2727
2728 if os.path.exists(pjoin(self.options['delphes_path'], 'data')):
2729 delphes3 = False
2730 prog = '../bin/internal/run_delphes'
2731 if filepath and '.hepmc' in filepath[:-10]:
2732 raise self.InvalidCmd, 'delphes2 do not support hepmc'
2733 else:
2734 delphes3 = True
2735 prog = '../bin/internal/run_delphes3'
2736
2737
2738
2739 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')):
2740 if no_default:
2741 logger.info('No delphes_card detected, so not running Delphes')
2742 return
2743 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_card_default.dat'),
2744 pjoin(self.me_dir, 'Cards', 'delphes_card.dat'))
2745 logger.info('No delphes card found. Take the default one.')
2746 if not delphes3 and not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat')):
2747 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_trigger_default.dat'),
2748 pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat'))
2749 if not (no_default or self.force):
2750 if delphes3:
2751 self.ask_edit_cards(['delphes_card.dat'], args)
2752 else:
2753 self.ask_edit_cards(['delphes_card.dat', 'delphes_trigger.dat'], args)
2754
2755 self.update_status('Running Delphes', level=None)
2756
2757 delphes_dir = self.options['delphes_path']
2758 tag = self.run_tag
2759 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')):
2760 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_card.dat'))
2761 if not delphes3:
2762 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_trigger.dat'))
2763 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, tag)))
2764
2765 cross = self.results[self.run_name].get_current_info()['cross']
2766
2767 delphes_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_delphes.log" % tag)
2768 self.cluster.launch_and_wait(prog,
2769 argument= [delphes_dir, self.run_name, tag, str(cross), filepath],
2770 stdout=delphes_log, stderr=subprocess.STDOUT,
2771 cwd=pjoin(self.me_dir,'Events'))
2772
2773 if not os.path.exists(pjoin(self.me_dir, 'Events',
2774 self.run_name, '%s_delphes_events.lhco.gz' % tag))\
2775 and not os.path.exists(pjoin(self.me_dir, 'Events',
2776 self.run_name, '%s_delphes_events.lhco' % tag)):
2777 logger.info('If you are interested in lhco output. please run root2lhco converter.')
2778 logger.info(' or edit bin/internal/run_delphes3 to run the converter automatically.')
2779
2780
2781
2782 madir = self.options['madanalysis_path']
2783 td = self.options['td_path']
2784
2785 if os.path.exists(pjoin(self.me_dir, 'Events',
2786 self.run_name, '%s_delphes_events.lhco' % tag)):
2787
2788 self.create_plot('Delphes')
2789
2790 if os.path.exists(pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag)):
2791 misc.gzip(pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag))
2792
2793 self.update_status('delphes done', level='delphes', makehtml=False)
2794
2795
2796
2798 """Find the pid of all particles in the final and initial states"""
2799 pids = set()
2800 subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses',
2801 'subproc.mg'))]
2802 nb_init = self.ninitial
2803 pat = re.compile(r'''DATA \(IDUP\(I,\d+\),I=1,\d+\)/([\+\-\d,\s]*)/''', re.I)
2804 for Pdir in subproc:
2805 text = open(pjoin(self.me_dir, 'SubProcesses', Pdir, 'born_leshouche.inc')).read()
2806 group = pat.findall(text)
2807 for particles in group:
2808 particles = particles.split(',')
2809 pids.update(set(particles))
2810
2811 return pids
2812
2813
2838
2839
2840 if hasattr(self, 'pdffile') and self.pdffile:
2841 return self.pdffile
2842 else:
2843 for line in open(pjoin(self.me_dir,'Source','PDF','pdf_list.txt')):
2844 data = line.split()
2845 if len(data) < 4:
2846 continue
2847 if data[1].lower() == self.run_card['pdlabel'].lower():
2848 self.pdffile = check_cluster(pjoin(self.me_dir, 'lib', 'Pdfdata', data[2]))
2849 return self.pdffile
2850 else:
2851
2852 path = pjoin(self.me_dir, 'lib', 'PDFsets')
2853 if os.path.exists(path):
2854 self.pdffile = path
2855 else:
2856 self.pdffile = " "
2857 return self.pdffile
2858
2859
2869
2870
2871 - def do_set(self, line, log=True):
2872 """Set an option, which will be default for coming generations/outputs
2873 """
2874
2875
2876
2877 args = self.split_arg(line)
2878
2879 self.check_set(args)
2880
2881 if args[0] in self.options_configuration and '--no_save' not in args:
2882 self.do_save('options --auto')
2883
2884 if args[0] == "stdout_level":
2885 if args[1].isdigit():
2886 logging.root.setLevel(int(args[1]))
2887 logging.getLogger('madgraph').setLevel(int(args[1]))
2888 else:
2889 logging.root.setLevel(eval('logging.' + args[1]))
2890 logging.getLogger('madgraph').setLevel(eval('logging.' + args[1]))
2891 if log: logger.info('set output information to level: %s' % args[1])
2892 elif args[0] == "fortran_compiler":
2893 if args[1] == 'None':
2894 args[1] = None
2895 self.options['fortran_compiler'] = args[1]
2896 current = misc.detect_current_compiler(pjoin(self.me_dir,'Source','make_opts'), 'fortran')
2897 if current != args[1] and args[1] != None:
2898 misc.mod_compilator(self.me_dir, args[1], current, 'gfortran')
2899 elif args[0] == "cpp_compiler":
2900 if args[1] == 'None':
2901 args[1] = None
2902 self.options['cpp_compiler'] = args[1]
2903 current = misc.detect_current_compiler(pjoin(self.me_dir,'Source','make_opts'), 'cpp')
2904 if current != args[1] and args[1] != None:
2905 misc.mod_compilator(self.me_dir, args[1], current, 'cpp')
2906 elif args[0] == "run_mode":
2907 if not args[1] in [0,1,2,'0','1','2']:
2908 raise self.InvalidCmd, 'run_mode should be 0, 1 or 2.'
2909 self.cluster_mode = int(args[1])
2910 self.options['run_mode'] = self.cluster_mode
2911 elif args[0] in ['cluster_type', 'cluster_queue', 'cluster_temp_path']:
2912 if args[1] == 'None':
2913 args[1] = None
2914 self.options[args[0]] = args[1]
2915
2916
2917 elif args[0] in ['cluster_nb_retry', 'cluster_retry_wait', 'cluster_size']:
2918 self.options[args[0]] = int(args[1])
2919
2920 elif args[0] == 'nb_core':
2921 if args[1] == 'None':
2922 import multiprocessing
2923 self.nb_core = multiprocessing.cpu_count()
2924 self.options['nb_core'] = self.nb_core
2925 return
2926 if not args[1].isdigit():
2927 raise self.InvalidCmd('nb_core should be a positive number')
2928 self.nb_core = int(args[1])
2929 self.options['nb_core'] = self.nb_core
2930 elif args[0] == 'timeout':
2931 self.options[args[0]] = int(args[1])
2932 elif args[0] == 'cluster_status_update':
2933 if '(' in args[1]:
2934 data = ' '.join([a for a in args[1:] if not a.startswith('-')])
2935 data = data.replace('(','').replace(')','').replace(',',' ').split()
2936 first, second = data[:2]
2937 else:
2938 first, second = args[1:3]
2939
2940 self.options[args[0]] = (int(first), int(second))
2941 elif args[0] == 'notification_center':
2942 if args[1] in ['None','True','False']:
2943 self.allow_notification_center = eval(args[1])
2944 self.options[args[0]] = eval(args[1])
2945 else:
2946 raise self.InvalidCmd('Not a valid value for notification_center')
2947 elif args[0] in self.options:
2948 if args[1] in ['None','True','False']:
2949 self.options[args[0]] = ast.literal_eval(args[1])
2950 elif args[0].endswith('path'):
2951 if os.path.exists(args[1]):
2952 self.options[args[0]] = args[1]
2953 elif os.path.exists(pjoin(self.me_dir, args[1])):
2954 self.options[args[0]] = pjoin(self.me_dir, args[1])
2955 else:
2956 raise self.InvalidCmd('Not a valid path: keep previous value: \'%s\'' % self.options[args[0]])
2957 else:
2958 self.options[args[0]] = args[1]
2959
2960 - def post_set(self, stop, line):
2961 """Check if we need to save this in the option file"""
2962 try:
2963 args = self.split_arg(line)
2964 if 'cluster' in args[0] or args[0] == 'run_mode':
2965 self.configure_run_mode(self.options['run_mode'])
2966
2967
2968
2969 self.check_set(args)
2970
2971 if args[0] in self.options_configuration and '--no_save' not in args:
2972 self.exec_cmd('save options --auto')
2973 elif args[0] in self.options_madevent:
2974 logger.info('This option will be the default in any output that you are going to create in this session.')
2975 logger.info('In order to keep this changes permanent please run \'save options\'')
2976 return stop
2977 except self.InvalidCmd:
2978 return stop
2979
3045
3046
3048 """
3049 1) Check that no scan parameter are present
3050 2) Check that all the width are define in the param_card.
3051 - If a scan parameter is define. create the iterator and recall this fonction
3052 on the first element.
3053 - If some width are set on 'Auto', call the computation tools.
3054 3) if dependent is on True check for dependent parameter (automatic for scan)"""
3055
3056 pattern_scan = re.compile(r'''^(decay)?[\s\d]*scan''', re.I+re.M)
3057 pattern_width = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto(@NLO|)''',re.I)
3058 text = open(path).read()
3059
3060 if pattern_scan.search(text):
3061 if not isinstance(self, cmd.CmdShell):
3062
3063 raise Exception, "Scan are not allowed in web mode"
3064
3065 main_card = check_param_card.ParamCardIterator(text)
3066 self.param_card_iterator = main_card
3067 first_card = main_card.next(autostart=True)
3068 first_card.write(path)
3069 return self.check_param_card(path, run, dependent=True)
3070
3071 pdg_info = pattern_width.findall(text)
3072 if pdg_info:
3073 if run:
3074 logger.info('Computing the width set on auto in the param_card.dat')
3075 has_nlo = any(nlo.lower()=="@nlo" for _,nlo in pdg_info)
3076 pdg = [pdg for pdg,nlo in pdg_info]
3077 if not has_nlo:
3078 self.do_compute_widths('%s %s' % (' '.join(pdg), path))
3079 else:
3080 self.do_compute_widths('%s %s --nlo' % (' '.join(pdg), path))
3081 else:
3082 logger.info('''Some width are on Auto in the card.
3083 Those will be computed as soon as you have finish the edition of the cards.
3084 If you want to force the computation right now and being able to re-edit
3085 the cards afterwards, you can type \"compute_wdiths\".''')
3086
3087 if dependent:
3088 card = check_param_card.ParamCard(path)
3089 AskforEditCard.update_dependent(self, self.me_dir, card, path, timer=20)
3090
3091 return
3092
3094 """If a ME run is currently running add a link in the html output"""
3095
3096
3097
3098 if hasattr(self, 'results') and hasattr(self.results, 'current') and\
3099 self.results.current and 'run_name' in self.results.current and \
3100 hasattr(self, 'me_dir'):
3101 name = self.results.current['run_name']
3102 tag = self.results.current['tag']
3103 self.debug_output = pjoin(self.me_dir, '%s_%s_debug.log' % (name,tag))
3104 if errortype:
3105 self.results.current.debug = errortype
3106 else:
3107 self.results.current.debug = self.debug_output
3108
3109 else:
3110
3111 self.debug_output = CommonRunCmd.debug_output
3112 if os.path.exists('ME5_debug') and not 'ME5_debug' in self.debug_output:
3113 os.remove('ME5_debug')
3114 if not 'ME5_debug' in self.debug_output:
3115 os.system('ln -s %s ME5_debug &> /dev/null' % self.debug_output)
3116
3117
3119 """Not in help: exit """
3120
3121 if not self.force_run:
3122 try:
3123 os.remove(pjoin(self.me_dir,'RunWeb'))
3124 except Exception:
3125 pass
3126 try:
3127 self.store_result()
3128 except Exception:
3129
3130 pass
3131
3132 try:
3133 self.update_status('', level=None)
3134 except Exception, error:
3135 pass
3136 devnull = open(os.devnull, 'w')
3137 try:
3138 misc.call(['./bin/internal/gen_cardhtml-pl'], cwd=self.me_dir,
3139 stdout=devnull, stderr=devnull)
3140 except Exception:
3141 pass
3142 devnull.close()
3143
3144 return super(CommonRunCmd, self).do_quit(line)
3145
3146
3147 do_EOF = do_quit
3148 do_exit = do_quit
3149
3150
3151 - def update_status(self, status, level, makehtml=True, force=True,
3152 error=False, starttime = None, update_results=True,
3153 print_log=True):
3154 """ update the index status """
3155
3156 if makehtml and not force:
3157 if hasattr(self, 'next_update') and time.time() < self.next_update:
3158 return
3159 else:
3160 self.next_update = time.time() + 3
3161
3162 if print_log:
3163 if isinstance(status, str):
3164 if '<br>' not in status:
3165 logger.info(status)
3166 elif starttime:
3167 running_time = misc.format_timer(time.time()-starttime)
3168 logger.info(' Idle: %s, Running: %s, Completed: %s [ %s ]' % \
3169 (status[0], status[1], status[2], running_time))
3170 else:
3171 logger.info(' Idle: %s, Running: %s, Completed: %s' % status[:3])
3172
3173 if isinstance(status, str) and status.startswith('\x1b['):
3174 status = status[status.index('m')+1:-7]
3175 if 'arXiv' in status:
3176 if '[' in status:
3177 status = status.split('[',1)[0]
3178 else:
3179 status = status.split('arXiv',1)[0]
3180
3181 if update_results:
3182 self.results.update(status, level, makehtml=makehtml, error=error)
3183
3184
3186 """Ask the question when launching generate_events/multi_run"""
3187
3188 check_card = ['pythia_card.dat', 'pgs_card.dat','delphes_card.dat',
3189 'delphes_trigger.dat', 'madspin_card.dat', 'shower_card.dat',
3190 'reweight_card.dat','pythia8_card.dat',
3191 'madanalysis5_parton_card.dat','madanalysis5_hadron_card.dat',
3192 'plot_card.dat']
3193
3194 cards_path = pjoin(self.me_dir,'Cards')
3195 for card in check_card:
3196 if card in ignore or (ignore == ['*'] and card not in need_card):
3197 continue
3198 if card not in need_card:
3199 if os.path.exists(pjoin(cards_path, card)):
3200 files.mv(pjoin(cards_path, card), pjoin(cards_path, '.%s' % card))
3201 else:
3202 if not os.path.exists(pjoin(cards_path, card)):
3203 if os.path.exists(pjoin(cards_path, '.%s' % card)):
3204 files.mv(pjoin(cards_path, '.%s' % card), pjoin(cards_path, card))
3205 else:
3206 default = card.replace('.dat', '_default.dat')
3207 files.cp(pjoin(cards_path, default),pjoin(cards_path, card))
3208
3209
3210 - def set_configuration(self, config_path=None, final=True, initdir=None, amcatnlo=False):
3211 """ assign all configuration variable from file
3212 ./Cards/mg5_configuration.txt. assign to default if not define """
3213
3214 if not hasattr(self, 'options') or not self.options:
3215 self.options = dict(self.options_configuration)
3216 self.options.update(self.options_madgraph)
3217 self.options.update(self.options_madevent)
3218
3219 if not config_path:
3220 if os.environ.has_key('MADGRAPH_BASE'):
3221 config_path = pjoin(os.environ['MADGRAPH_BASE'],'mg5_configuration.txt')
3222 self.set_configuration(config_path=config_path, final=False)
3223 if 'HOME' in os.environ:
3224 config_path = pjoin(os.environ['HOME'],'.mg5',
3225 'mg5_configuration.txt')
3226 if os.path.exists(config_path):
3227 self.set_configuration(config_path=config_path, final=False)
3228 if amcatnlo:
3229 me5_config = pjoin(self.me_dir, 'Cards', 'amcatnlo_configuration.txt')
3230 else:
3231 me5_config = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
3232 self.set_configuration(config_path=me5_config, final=False, initdir=self.me_dir)
3233
3234 if self.options.has_key('mg5_path') and self.options['mg5_path']:
3235 MG5DIR = self.options['mg5_path']
3236 config_file = pjoin(MG5DIR, 'input', 'mg5_configuration.txt')
3237 self.set_configuration(config_path=config_file, final=False,initdir=MG5DIR)
3238 else:
3239 self.options['mg5_path'] = None
3240 return self.set_configuration(config_path=me5_config, final=final,initdir=self.me_dir)
3241
3242 config_file = open(config_path)
3243
3244
3245 logger.info('load configuration from %s ' % config_file.name)
3246 for line in config_file:
3247
3248 if '#' in line:
3249 line = line.split('#',1)[0]
3250 line = line.replace('\n','').replace('\r\n','')
3251 try:
3252 name, value = line.split('=')
3253 except ValueError:
3254 pass
3255 else:
3256 name = name.strip()
3257 value = value.strip()
3258 if name.endswith('_path') and not name.startswith('cluster'):
3259 path = value
3260 if os.path.isdir(path):
3261 self.options[name] = os.path.realpath(path)
3262 continue
3263 if not initdir:
3264 continue
3265 path = pjoin(initdir, value)
3266 if os.path.isdir(path):
3267 self.options[name] = os.path.realpath(path)
3268 continue
3269 else:
3270 self.options[name] = value
3271 if value.lower() == "none":
3272 self.options[name] = None
3273
3274 if not final:
3275 return self.options
3276
3277
3278
3279 for key in self.options:
3280
3281 if key.endswith('path') and not key.startswith("cluster"):
3282 path = self.options[key]
3283 if path is None:
3284 continue
3285 if os.path.isdir(path):
3286 self.options[key] = os.path.realpath(path)
3287 continue
3288 path = pjoin(self.me_dir, self.options[key])
3289 if os.path.isdir(path):
3290 self.options[key] = os.path.realpath(path)
3291 continue
3292 elif self.options.has_key('mg5_path') and self.options['mg5_path']:
3293 path = pjoin(self.options['mg5_path'], self.options[key])
3294 if os.path.isdir(path):
3295 self.options[key] = os.path.realpath(path)
3296 continue
3297 self.options[key] = None
3298 elif key.startswith('cluster') and key != 'cluster_status_update':
3299 if key in ('cluster_nb_retry','cluster_wait_retry'):
3300 self.options[key] = int(self.options[key])
3301 if hasattr(self,'cluster'):
3302 del self.cluster
3303 pass
3304 elif key == 'automatic_html_opening':
3305 if self.options[key] in ['False', 'True']:
3306 self.options[key] =ast.literal_eval(self.options[key])
3307 elif key == "notification_center":
3308 if self.options[key] in ['False', 'True']:
3309 self.allow_notification_center =ast.literal_eval(self.options[key])
3310 self.options[key] =ast.literal_eval(self.options[key])
3311 elif key not in ['text_editor','eps_viewer','web_browser','stdout_level',
3312 'complex_mass_scheme', 'gauge', 'group_subprocesses']:
3313
3314 try:
3315 self.do_set("%s %s --no_save" % (key, self.options[key]), log=False)
3316 except self.InvalidCmd:
3317 logger.warning("Option %s from config file not understood" \
3318 % key)
3319
3320
3321 misc.open_file.configure(self.options)
3322 self.configure_run_mode(self.options['run_mode'])
3323 return self.options
3324
3325 @staticmethod
3327 """ find a valid run_name for the current job """
3328
3329 name = 'run_%02d'
3330 data = [int(s[4:j]) for s in os.listdir(pjoin(me_dir,'Events')) for
3331 j in range(4,len(s)+1) if \
3332 s.startswith('run_') and s[4:j].isdigit()]
3333 return name % (max(data+[0])+1)
3334
3335
3336
3338 """Require MG5 directory: decay events with spin correlations
3339 """
3340
3341 if '-from_cards' in line and not os.path.exists(pjoin(self.me_dir, 'Cards', 'madspin_card.dat')):
3342 return
3343
3344
3345
3346
3347 if MADEVENT and not self.options['mg5_path']:
3348 raise self.InvalidCmd, '''The module decay_events requires that MG5 is installed on the system.
3349 You can install it and set its path in ./Cards/me5_configuration.txt'''
3350 elif MADEVENT:
3351 sys.path.append(self.options['mg5_path'])
3352 try:
3353 import MadSpin.decay as decay
3354 import MadSpin.interface_madspin as interface_madspin
3355 except ImportError:
3356 if __debug__:
3357 raise
3358 else:
3359 raise self.ConfigurationError, '''Can\'t load MadSpin
3360 The variable mg5_path might not be correctly configured.'''
3361
3362 self.update_status('Running MadSpin', level='madspin')
3363 if not '-from_cards' in line:
3364 self.keep_cards(['madspin_card.dat'], ignore=['*'])
3365 self.ask_edit_cards(['madspin_card.dat'], 'fixed', plot=False)
3366 self.help_decay_events(skip_syntax=True)
3367
3368
3369 args = self.split_arg(line)
3370 self.check_decay_events(args)
3371
3372 madspin_cmd = interface_madspin.MadSpinInterface(args[0])
3373 madspin_cmd.update_status = lambda *x,**opt: self.update_status(*x, level='madspin',**opt)
3374
3375 path = pjoin(self.me_dir, 'Cards', 'madspin_card.dat')
3376
3377 madspin_cmd.import_command_file(path)
3378
3379
3380 i = 1
3381 while os.path.exists(pjoin(self.me_dir,'Events', '%s_decayed_%i' % (self.run_name,i))):
3382 i+=1
3383 new_run = '%s_decayed_%i' % (self.run_name,i)
3384 evt_dir = pjoin(self.me_dir, 'Events')
3385
3386 os.mkdir(pjoin(evt_dir, new_run))
3387 current_file = args[0].replace('.lhe', '_decayed.lhe')
3388 new_file = pjoin(evt_dir, new_run, os.path.basename(args[0]))
3389 if not os.path.exists(current_file):
3390 if os.path.exists(current_file+'.gz'):
3391 current_file += '.gz'
3392 new_file += '.gz'
3393 else:
3394 logger.error('MadSpin fails to create any decayed file.')
3395 return
3396
3397 files.mv(current_file, new_file)
3398 logger.info("The decayed event file has been moved to the following location: ")
3399 logger.info(new_file)
3400
3401 if hasattr(self, 'results'):
3402 current = self.results.current
3403 nb_event = self.results.current['nb_event']
3404 if not nb_event:
3405 current = self.results[self.run_name][0]
3406 nb_event = current['nb_event']
3407
3408 cross = current['cross']
3409 error = current['error']
3410 self.results.add_run( new_run, self.run_card)
3411 self.results.add_detail('nb_event', int(nb_event*madspin_cmd.efficiency))
3412 self.results.add_detail('cross', madspin_cmd.cross)
3413 self.results.add_detail('error', madspin_cmd.error+ cross * madspin_cmd.err_branching_ratio)
3414 self.results.add_detail('run_mode', current['run_mode'])
3415
3416 self.run_name = new_run
3417 self.banner = madspin_cmd.banner
3418 self.banner.add(path)
3419 self.banner.write(pjoin(self.me_dir,'Events',self.run_name, '%s_%s_banner.txt' %
3420 (self.run_name, self.run_tag)))
3421 self.update_status('MadSpin Done', level='parton', makehtml=False)
3422 if 'unweighted' in os.path.basename(args[0]):
3423 self.create_plot('parton')
3424
3431
3433 "Complete the print results command"
3434 args = self.split_arg(line[0:begidx], error=False)
3435 if len(args) == 1:
3436
3437 data = misc.glob(pjoin('*','unweighted_events.lhe.gz'),
3438 pjoin(self.me_dir, 'Events'))
3439
3440 data = [n.rsplit('/',2)[1] for n in data]
3441 tmp1 = self.list_completion(text, data)
3442 return tmp1
3443 else:
3444 data = misc.glob('*_pythia_events.hep.gz', pjoin(self.me_dir, 'Events', args[0]))
3445 data = [os.path.basename(p).rsplit('_',1)[0] for p in data]
3446 data += ["--mode=a", "--mode=w", "--path=", "--format=short"]
3447 tmp1 = self.list_completion(text, data)
3448 return tmp1
3449
3451 logger.info("syntax: print_result [RUN] [TAG] [options]")
3452 logger.info("-- show in text format the status of the run (cross-section/nb-event/...)")
3453 logger.info("--path= defines the path of the output file.")
3454 logger.info("--mode=a allow to add the information at the end of the file.")
3455 logger.info("--format=short (only if --path is define)")
3456 logger.info(" allows to have a multi-column output easy to parse")
3457
3458
3484
3485
3487 args = self.split_arg(line[0:begidx], error=False)
3488
3489 if len(args) == 1 and os.path.sep not in text:
3490
3491 data = misc.glob(pjoin('*','*events.lhe*'), pjoin(self.me_dir, 'Events'))
3492 data = [n.rsplit('/',2)[1] for n in data]
3493 return self.list_completion(text, data, line)
3494 else:
3495 return self.path_completion(text,
3496 os.path.join('.',*[a for a in args \
3497 if a.endswith(os.path.sep)]))
3498
3510
3511
3512
3514 "Complete the compute_widths command"
3515
3516 args = self.split_arg(line[0:begidx])
3517
3518 if args[-1] in ['--path=', '--output=']:
3519 completion = {'path': self.path_completion(text)}
3520 elif line[begidx-1] == os.path.sep:
3521 current_dir = pjoin(*[a for a in args if a.endswith(os.path.sep)])
3522 if current_dir.startswith('--path='):
3523 current_dir = current_dir[7:]
3524 if current_dir.startswith('--output='):
3525 current_dir = current_dir[9:]
3526 completion = {'path': self.path_completion(text, current_dir)}
3527 else:
3528 completion = {}
3529 completion['options'] = self.list_completion(text,
3530 ['--path=', '--output=', '--min_br=0.\$', '--nlo',
3531 '--precision_channel=0.\$', '--body_decay='])
3532
3533 return self.deal_multiple_categories(completion, formatting)
3534
3535
3537 """update the make_opts file writing the environmental variables
3538 stored in make_opts_var"""
3539 make_opts = os.path.join(self.me_dir, 'Source', 'make_opts')
3540
3541
3542 if not hasattr(self,'options') or not 'pythia8_path' in self.options or \
3543 not self.options['pythia8_path'] or \
3544 not os.path.isfile(pjoin(self.options['pythia8_path'],'bin','pythia8-config')):
3545 self.make_opts_var['PYTHIA8_PATH']='NotInstalled'
3546 else:
3547 self.make_opts_var['PYTHIA8_PATH']=self.options['pythia8_path']
3548
3549 self.make_opts_var['MG5AMC_VERSION'] = misc.get_pkg_info()['version']
3550
3551 return self.update_make_opts_full(make_opts, self.make_opts_var)
3552
3553 @staticmethod
3555 """update the make_opts file writing the environmental variables
3556 of def_variables.
3557 if a value of the dictionary is None then it is not written.
3558 """
3559 make_opts = path
3560 pattern = re.compile(r'^(\w+)\s*=\s*(.*)$',re.DOTALL)
3561 diff = False
3562
3563
3564 tag = '#end_of_make_opts_variables\n'
3565 make_opts_variable = True
3566 content = []
3567 variables = dict(def_variables)
3568 need_keys = variables.keys()
3569 for line in open(make_opts):
3570 line = line.strip()
3571 if make_opts_variable:
3572 if line.startswith('#') or not line:
3573 if line.startswith('#end_of_make_opts_variables'):
3574 make_opts_variable = False
3575 continue
3576 elif pattern.search(line):
3577 key, value = pattern.search(line).groups()
3578 if key not in variables:
3579 variables[key] = value
3580 elif value != variables[key]:
3581 diff=True
3582 else:
3583 need_keys.remove(key)
3584 else:
3585 make_opts_variable = False
3586 content.append(line)
3587 else:
3588 content.append(line)
3589
3590 if need_keys:
3591 diff=True
3592
3593 content_variables = '\n'.join('%s=%s' % (k,v) for k, v in variables.items() if v is not None)
3594 content_variables += '\n%s' % tag
3595
3596 if diff:
3597 with open(make_opts, 'w') as fsock:
3598 fsock.write(content_variables + '\n'.join(content))
3599 return
3600
3601
3602
3604 """links lhapdf into libdir"""
3605
3606 lhapdf_version = self.get_lhapdf_version()
3607 logger.info('Using LHAPDF v%s interface for PDFs' % lhapdf_version)
3608 lhalibdir = subprocess.Popen([self.options['lhapdf'], '--libdir'],
3609 stdout = subprocess.PIPE).stdout.read().strip()
3610
3611 if lhapdf_version.startswith('5.'):
3612 pdfsetsdir = subprocess.Popen([self.options['lhapdf'], '--pdfsets-path'],
3613 stdout = subprocess.PIPE).stdout.read().strip()
3614 else:
3615 pdfsetsdir = subprocess.Popen([self.options['lhapdf'], '--datadir'],
3616 stdout = subprocess.PIPE).stdout.read().strip()
3617
3618 self.lhapdf_pdfsets = self.get_lhapdf_pdfsets_list(pdfsetsdir)
3619
3620 lhalib = 'libLHAPDF.a'
3621
3622 if os.path.exists(pjoin(libdir, lhalib)):
3623 files.rm(pjoin(libdir, lhalib))
3624 files.ln(pjoin(lhalibdir, lhalib), libdir)
3625
3626 if not os.path.isdir(pjoin(libdir, 'PDFsets')):
3627 os.mkdir(pjoin(libdir, 'PDFsets'))
3628 self.make_opts_var['lhapdf'] = self.options['lhapdf']
3629 self.make_opts_var['lhapdfversion'] = lhapdf_version[0]
3630 self.make_opts_var['lhapdf_config'] = self.options['lhapdf']
3631
3632
3634 """reads the proc_characteristics file and initialises the correspondant
3635 dictionary"""
3636
3637 if not path:
3638 path = os.path.join(self.me_dir, 'SubProcesses', 'proc_characteristics')
3639
3640 self.proc_characteristics = banner_mod.ProcCharacteristic(path)
3641 return self.proc_characteristics
3642
3643
3645 """copy (if needed) the lhapdf set corresponding to the lhaid in lhaid_list
3646 into lib/PDFsets"""
3647
3648 if not hasattr(self, 'lhapdf_pdfsets'):
3649 self.lhapdf_pdfsets = self.get_lhapdf_pdfsets_list(pdfsets_dir)
3650
3651 pdfsetname=set()
3652 for lhaid in lhaid_list:
3653 if isinstance(lhaid, str) and lhaid.isdigit():
3654 lhaid = int(lhaid)
3655 if isinstance(lhaid, (int,float)):
3656 try:
3657 if lhaid in self.lhapdf_pdfsets:
3658 pdfsetname.add(self.lhapdf_pdfsets[lhaid]['filename'])
3659 else:
3660 raise MadGraph5Error('lhaid %s not valid input number for the current lhapdf' % lhaid )
3661 except KeyError:
3662 if self.lhapdf_version.startswith('5'):
3663 raise MadGraph5Error(\
3664 ('invalid lhaid set in th run_card: %d .\nPlease note that some sets' % lhaid) + \
3665 '(eg MSTW 90%CL error sets) \nare not available in aMC@NLO + LHAPDF 5.x.x')
3666 else:
3667 logger.debug('%d not found in pdfsets.index' % lhaid)
3668 else:
3669 pdfsetname.add(lhaid)
3670
3671
3672
3673
3674 if not os.path.isdir(pdfsets_dir):
3675 try:
3676 os.mkdir(pdfsets_dir)
3677 except OSError:
3678 pdfsets_dir = pjoin(self.me_dir, 'lib', 'PDFsets')
3679 elif os.path.exists(pjoin(self.me_dir, 'lib', 'PDFsets')):
3680
3681 for name in os.listdir(pjoin(self.me_dir, 'lib', 'PDFsets')):
3682 if name not in pdfsetname:
3683 try:
3684 if os.path.isdir(pjoin(self.me_dir, 'lib', 'PDFsets', name)):
3685 shutil.rmtree(pjoin(self.me_dir, 'lib', 'PDFsets', name))
3686 else:
3687 os.remove(pjoin(self.me_dir, 'lib', 'PDFsets', name))
3688 except Exception, error:
3689 logger.debug('%s', error)
3690
3691 if self.options["cluster_local_path"]:
3692 lhapdf_cluster_possibilities = [self.options["cluster_local_path"],
3693 pjoin(self.options["cluster_local_path"], "lhapdf"),
3694 pjoin(self.options["cluster_local_path"], "lhapdf", "pdfsets"),
3695 pjoin(self.options["cluster_local_path"], "..", "lhapdf"),
3696 pjoin(self.options["cluster_local_path"], "..", "lhapdf", "pdfsets"),
3697 pjoin(self.options["cluster_local_path"], "..", "lhapdf","pdfsets", "6.1")
3698 ]
3699 else:
3700 lhapdf_cluster_possibilities = []
3701
3702 for pdfset in pdfsetname:
3703
3704 if self.options["cluster_local_path"] and self.options["run_mode"] == 1 and \
3705 any((os.path.exists(pjoin(d, pdfset)) for d in lhapdf_cluster_possibilities)):
3706
3707 os.environ["LHAPATH"] = [d for d in lhapdf_cluster_possibilities if os.path.exists(pjoin(d, pdfset))][0]
3708 os.environ["CLUSTER_LHAPATH"] = os.environ["LHAPATH"]
3709
3710 if os.path.exists(pjoin(pdfsets_dir, pdfset)):
3711 try:
3712 if os.path.isdir(pjoin(pdfsets_dir, name)):
3713 shutil.rmtree(pjoin(pdfsets_dir, name))
3714 else:
3715 os.remove(pjoin(pdfsets_dir, name))
3716 except Exception, error:
3717 logger.debug('%s', error)
3718
3719
3720 elif not os.path.exists(pjoin(self.me_dir, 'lib', 'PDFsets', pdfset)) and \
3721 not os.path.isdir(pjoin(self.me_dir, 'lib', 'PDFsets', pdfset)):
3722
3723 if pdfset and not os.path.exists(pjoin(pdfsets_dir, pdfset)):
3724 self.install_lhapdf_pdfset(pdfsets_dir, pdfset)
3725
3726 if os.path.exists(pjoin(pdfsets_dir, pdfset)):
3727 files.cp(pjoin(pdfsets_dir, pdfset), pjoin(self.me_dir, 'lib', 'PDFsets'))
3728 elif os.path.exists(pjoin(os.path.dirname(pdfsets_dir), pdfset)):
3729 files.cp(pjoin(os.path.dirname(pdfsets_dir), pdfset), pjoin(self.me_dir, 'lib', 'PDFsets'))
3730
3732 """idownloads and install the pdfset filename in the pdfsets_dir"""
3733 lhapdf_version = self.get_lhapdf_version()
3734 local_path = pjoin(self.me_dir, 'lib', 'PDFsets')
3735 return self.install_lhapdf_pdfset_static(self.options['lhapdf'],
3736 pdfsets_dir, filename,
3737 lhapdf_version=lhapdf_version,
3738 alternate_path=local_path)
3739
3740
3741 @staticmethod
3744 """idownloads and install the pdfset filename in the pdfsets_dir.
3745 Version which can be used independently of the class.
3746 local path is used if the global installation fails.
3747 """
3748
3749 if not lhapdf_version:
3750 lhapdf_version = subprocess.Popen([lhapdf_config, '--version'],
3751 stdout = subprocess.PIPE).stdout.read().strip()
3752 if not pdfsets_dir:
3753 pdfsets_dir = subprocess.Popen([lhapdf_config, '--datadir'],
3754 stdout = subprocess.PIPE).stdout.read().strip()
3755
3756 if isinstance(filename, int):
3757 pdf_info = CommonRunCmd.get_lhapdf_pdfsets_list_static(pdfsets_dir, lhapdf_version)
3758 filename = pdf_info[filename]['filename']
3759
3760 if os.path.exists(pjoin(pdfsets_dir, filename)):
3761 logger.debug('%s is already present in %s', filename, pdfsets_dir)
3762 return
3763
3764 logger.info('Trying to download %s' % filename)
3765
3766 if lhapdf_version.startswith('5.'):
3767
3768
3769
3770 getdata = lhapdf_config.replace('lhapdf-config', ('lhapdf-getdata'))
3771 misc.call([getdata, filename], cwd = pdfsets_dir)
3772
3773 elif lhapdf_version.startswith('6.'):
3774
3775
3776 getdata = lhapdf_config.replace('lhapdf-config', ('lhapdf'))
3777
3778 misc.call([getdata, 'install', filename], cwd = pdfsets_dir)
3779
3780 else:
3781 raise MadGraph5Error('Not valid LHAPDF version: %s' % lhapdf_version)
3782
3783
3784 if os.path.exists(pjoin(pdfsets_dir, filename)) or \
3785 os.path.isdir(pjoin(pdfsets_dir, filename)):
3786 logger.info('%s successfully downloaded and stored in %s' \
3787 % (filename, pdfsets_dir))
3788
3789 elif lhapdf_version.startswith('5.'):
3790 logger.warning('Could not download %s into %s. Trying to save it locally' \
3791 % (filename, pdfsets_dir))
3792 CommonRunCmd.install_lhapdf_pdfset_static(lhapdf_config, alternate_path, filename,
3793 lhapdf_version=lhapdf_version)
3794 elif lhapdf_version.startswith('6.') and '.LHgrid' in filename:
3795 logger.info('Could not download %s: Try %s', filename, filename.replace('.LHgrid',''))
3796 return CommonRunCmd.install_lhapdf_pdfset_static(lhapdf_config, pdfsets_dir,
3797 filename.replace('.LHgrid',''),
3798 lhapdf_version, alternate_path)
3799
3800 else:
3801 raise MadGraph5Error, \
3802 'Could not download %s into %s. Please try to install it manually.' \
3803 % (filename, pdfsets_dir)
3804
3805
3806
3808 """read the PDFsets.index file, which should be located in the same
3809 place as pdfsets_dir, and return a list of dictionaries with the information
3810 about each pdf set"""
3811 lhapdf_version = self.get_lhapdf_version()
3812 return self.get_lhapdf_pdfsets_list_static(pdfsets_dir, lhapdf_version)
3813
3814 @staticmethod
3816
3817 if lhapdf_version.startswith('5.'):
3818 if os.path.exists('%s.index' % pdfsets_dir):
3819 indexfile = '%s.index' % pdfsets_dir
3820 else:
3821 raise MadGraph5Error, 'index of lhapdf file not found'
3822 pdfsets_lines = \
3823 [l for l in open(indexfile).read().split('\n') if l.strip() and \
3824 not '90cl' in l]
3825 lhapdf_pdfsets = dict( (int(l.split()[0]), {'lhaid': int(l.split()[0]),
3826 'pdflib_ntype': int(l.split()[1]),
3827 'pdflib_ngroup': int(l.split()[2]),
3828 'pdflib_nset': int(l.split()[3]),
3829 'filename': l.split()[4],
3830 'lhapdf_nmem': int(l.split()[5]),
3831 'q2min': float(l.split()[6]),
3832 'q2max': float(l.split()[7]),
3833 'xmin': float(l.split()[8]),
3834 'xmax': float(l.split()[9]),
3835 'description': l.split()[10]}) \
3836 for l in pdfsets_lines)
3837
3838 elif lhapdf_version.startswith('6.'):
3839 pdfsets_lines = \
3840 [l for l in open(pjoin(pdfsets_dir, 'pdfsets.index')).read().split('\n') if l.strip()]
3841 lhapdf_pdfsets = dict( (int(l.split()[0]),
3842 {'lhaid': int(l.split()[0]),
3843 'filename': l.split()[1]}) \
3844 for l in pdfsets_lines)
3845
3846 else:
3847 raise MadGraph5Error('Not valid LHAPDF version: %s' % lhapdf_version)
3848
3849 return lhapdf_pdfsets
3850
3851
3853 """returns the lhapdf version number"""
3854 if not hasattr(self, 'lhapdfversion'):
3855 try:
3856 self.lhapdf_version = \
3857 subprocess.Popen([self.options['lhapdf'], '--version'],
3858 stdout = subprocess.PIPE).stdout.read().strip()
3859 except OSError, error:
3860 if error.errno == 2:
3861 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']
3862 else:
3863 raise
3864
3865
3866 if self.lhapdf_version.startswith('6.0'):
3867 raise MadGraph5Error('LHAPDF 6.0.x not supported. Please use v6.1 or later')
3868
3869 return self.lhapdf_version
3870
3871
3873 lhapdf_version = self.get_lhapdf_version()
3874
3875
3876 if 'LHAPDF_DATA_PATH' in os.environ.keys() and os.environ['LHAPDF_DATA_PATH']:
3877 datadir = os.environ['LHAPDF_DATA_PATH']
3878
3879 elif lhapdf_version.startswith('5.'):
3880 datadir = subprocess.Popen([self.options['lhapdf'], '--pdfsets-path'],
3881 stdout = subprocess.PIPE).stdout.read().strip()
3882
3883 elif lhapdf_version.startswith('6.'):
3884 datadir = subprocess.Popen([self.options['lhapdf'], '--datadir'],
3885 stdout = subprocess.PIPE).stdout.read().strip()
3886
3887 return datadir
3888
3890 lhapdf_version = self.get_lhapdf_version()
3891
3892 if lhapdf_version.startswith('5.'):
3893 libdir = subprocess.Popen([self.options['lhapdf-config'], '--libdir'],
3894 stdout = subprocess.PIPE).stdout.read().strip()
3895
3896 elif lhapdf_version.startswith('6.'):
3897 libdir = subprocess.Popen([self.options['lhapdf'], '--libs'],
3898 stdout = subprocess.PIPE).stdout.read().strip()
3899
3900 return libdir
3901
3903 """A class for asking a question where in addition you can have the
3904 set command define and modifying the param_card/run_card correctly"""
3905
3906 all_card_name = ['param_card', 'run_card', 'pythia_card', 'pythia8_card',
3907 'madweight_card', 'MadLoopParams', 'shower_card']
3908
3909 special_shortcut = {'ebeam':([float],['run_card ebeam1 %(0)s', 'run_card ebeam2 %(0)s']),
3910 'lpp': ([int],['run_card lpp1 %(0)s', 'run_card lpp2 %(0)s' ]),
3911 'lhc': ([int],['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2']),
3912 'lep': ([int],['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2']),
3913 'ilc': ([int],['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2']),
3914 'lcc': ([int],['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2']),
3915 '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']),
3916 'simplepy8':([],['pythia8_card hadronlevel:all False',
3917 'pythia8_card partonlevel:mpi False',
3918 'pythia8_card BeamRemnants:primordialKT False',
3919 'pythia8_card PartonLevel:Remnants False',
3920 'pythia8_card Check:event False',
3921 'pythia8_card TimeShower:QEDshowerByQ False',
3922 'pythia8_card TimeShower:QEDshowerByL False',
3923 'pythia8_card SpaceShower:QEDshowerByQ False',
3924 'pythia8_card SpaceShower:QEDshowerByL False',
3925 'pythia8_card PartonLevel:FSRinResonances False',
3926 'pythia8_card ProcessLevel:resonanceDecays False',
3927 ]),
3928 'mpi':([bool],['pythia8_card partonlevel:mpi %(0)s']),
3929 'no_parton_cut':([],['run_card nocut T'])
3930 }
3931
3932 special_shortcut_help = {
3933 'ebeam' : 'syntax: set ebeam VALUE:\n This parameter sets the energy to both beam to the value in GeV',
3934 'lpp' : 'syntax: set ebeam VALUE:\n'+\
3935 ' Set the type of beam to a given value for both beam\n'+\
3936 ' 0 : means no PDF\n'+\
3937 ' 1 : means proton PDF\n'+\
3938 ' -1 : means antiproton PDF\n'+\
3939 ' 2 : means PDF for elastic photon emited from a proton\n'+\
3940 ' 3 : means PDF for elastic photon emited from an electron',
3941 'lhc' : 'syntax: set lhc VALUE:\n Set for a proton-proton collision with that given center of mass energy (in TeV)',
3942 'lep' : 'syntax: set lep VALUE:\n Set for a electron-positron collision with that given center of mass energy (in GeV)',
3943 'fixed_scale' : 'syntax: set fixed_scale VALUE:\n Set all scales to the give value (in GeV)',
3944 'simplepy8' : 'Turn off non-perturbative slow features of Pythia8.',
3945 'mpi' : 'syntax: set mpi value: allow to turn mpi in Pythia8 on/off'
3946 }
3947
3949 """ define all default variable. No load of card here.
3950 This allow to subclass this class and just change init and still have
3951 all variables defined."""
3952
3953 self.me_dir = None
3954 self.param_card = None
3955 self.run_card = {}
3956 self.pname2block = {}
3957 self.conflict = []
3958 self.restricted_value = {}
3959 self.mode = ''
3960 self.cards = []
3961 self.run_set = []
3962 self.has_mw = False
3963 self.has_ml = False
3964 self.has_shower = False
3965 self.has_PY8 = False
3966 self.paths = {}
3967
3968
3970
3971 if 'pwd' in opt:
3972 self.me_dir = opt['pwd']
3973 elif 'mother_interface' in opt:
3974 self.mother_interface = opt['mother_interface']
3975 if not hasattr(self, 'me_dir') or not self.me_dir:
3976 self.me_dir = self.mother_interface.me_dir
3977
3978
3979 self.paths['param'] = pjoin(self.me_dir,'Cards','param_card.dat')
3980 self.paths['param_default'] = pjoin(self.me_dir,'Cards','param_card_default.dat')
3981 self.paths['run'] = pjoin(self.me_dir,'Cards','run_card.dat')
3982 self.paths['run_default'] = pjoin(self.me_dir,'Cards','run_card_default.dat')
3983 self.paths['transfer'] =pjoin(self.me_dir,'Cards','transfer_card.dat')
3984 self.paths['MadWeight'] =pjoin(self.me_dir,'Cards','MadWeight_card.dat')
3985 self.paths['MadWeight_default'] =pjoin(self.me_dir,'Cards','MadWeight_card_default.dat')
3986 self.paths['ML'] =pjoin(self.me_dir,'Cards','MadLoopParams.dat')
3987 self.paths['shower'] = pjoin(self.me_dir,'Cards','shower_card.dat')
3988 self.paths['shower_default'] = pjoin(self.me_dir,'Cards','shower_card_default.dat')
3989 self.paths['pythia'] =pjoin(self.me_dir, 'Cards','pythia_card.dat')
3990 self.paths['PY8'] = pjoin(self.me_dir, 'Cards','pythia8_card.dat')
3991 self.paths['PY8_default'] = pjoin(self.me_dir, 'Cards','pythia8_card_default.dat')
3992 self.paths['madspin_default'] = pjoin(self.me_dir,'Cards/madspin_card_default.dat')
3993 self.paths['madspin'] = pjoin(self.me_dir,'Cards/madspin_card.dat')
3994 self.paths['reweight'] = pjoin(self.me_dir,'Cards','reweight_card.dat')
3995 self.paths['delphes'] = pjoin(self.me_dir,'Cards','delphes_card.dat')
3996 self.paths['plot'] = pjoin(self.me_dir,'Cards','plot_card.dat')
3997 self.paths['plot_default'] = pjoin(self.me_dir,'Cards','plot_card_default.dat')
3998 self.paths['madanalysis5_parton'] = pjoin(self.me_dir,'Cards','madanalysis5_parton_card.dat')
3999 self.paths['madanalysis5_hadron'] = pjoin(self.me_dir,'Cards','madanalysis5_hadron_card.dat')
4000 self.paths['madanalysis5_parton_default'] = pjoin(self.me_dir,'Cards','madanalysis5_parton_card_default.dat')
4001 self.paths['madanalysis5_hadron_default'] = pjoin(self.me_dir,'Cards','madanalysis5_hadron_card_default.dat')
4002
4003 - def __init__(self, question, cards=[], mode='auto', *args, **opt):
4004
4005 self.load_default()
4006 self.define_paths(**opt)
4007 cmd.OneLinePathCompletion.__init__(self, question, *args, **opt)
4008
4009
4010 try:
4011 self.param_card = check_param_card.ParamCard(self.paths['param'])
4012 except (check_param_card.InvalidParamCard, ValueError) as e:
4013 logger.error('Current param_card is not valid. We are going to use the default one.')
4014 logger.error('problem detected: %s' % e)
4015 files.cp(self.paths['param_default'], self.paths['param'])
4016 self.param_card = check_param_card.ParamCard(self.paths['param'])
4017 default_param = check_param_card.ParamCard(self.paths['param_default'])
4018 self.param_card_default = default_param
4019
4020 try:
4021 self.run_card = banner_mod.RunCard(self.paths['run'], consistency='warning')
4022 except IOError:
4023 self.run_card = {}
4024 try:
4025 run_card_def = banner_mod.RunCard(self.paths['run_default'])
4026 except IOError:
4027 run_card_def = {}
4028
4029 self.pname2block = {}
4030 self.conflict = []
4031 self.restricted_value = {}
4032 self.mode = mode
4033 self.cards = cards
4034
4035
4036
4037
4038 self.pname2block, self.restricted_value = \
4039 default_param.analyze_param_card()
4040
4041 if run_card_def:
4042 self.run_set = run_card_def.keys() + self.run_card.hidden_param
4043 elif self.run_card:
4044 self.run_set = self.run_card.keys()
4045 else:
4046 self.run_set = []
4047
4048 for var in self.pname2block:
4049 if var in self.run_set:
4050 self.conflict.append(var)
4051
4052
4053 self.has_delphes = False
4054 if 'delphes_card.dat' in cards:
4055 self.has_delphes = True
4056
4057
4058 self.has_mw = False
4059 if 'madweight_card.dat' in cards:
4060
4061 self.do_change_tf = self.mother_interface.do_define_transfer_fct
4062 self.complete_change_tf = self.mother_interface.complete_define_transfer_fct
4063 self.help_change_tf = self.mother_interface.help_define_transfer_fct
4064 if not os.path.exists(self.paths['transfer']):
4065 logger.warning('No transfer function currently define. Please use the change_tf command to define one.')
4066
4067
4068 self.has_mw = True
4069 try:
4070 import madgraph.madweight.Cards as mwcards
4071 except:
4072 import internal.madweight.Cards as mwcards
4073 self.mw_card = mwcards.Card(self.paths['MadWeight'])
4074 self.mw_card = self.mw_card.info
4075 self.mw_vars = []
4076 for key in self.mw_card:
4077 if key == 'comment':
4078 continue
4079 for key2 in self.mw_card.info[key]:
4080 if isinstance(key2, str) and not key2.isdigit():
4081 self.mw_vars.append(key2)
4082
4083
4084 for var in self.pname2block:
4085 if var in self.mw_vars:
4086 self.conflict.append(var)
4087 for var in self.mw_vars:
4088 if var in self.run_card:
4089 self.conflict.append(var)
4090
4091
4092 self.has_ml = False
4093 if os.path.isfile(self.paths['ML']):
4094 self.has_ml = True
4095 self.MLcard = banner_mod.MadLoopParam(self.paths['ML'])
4096 self.MLcardDefault = banner_mod.MadLoopParam()
4097
4098 self.ml_vars = [k.lower() for k in self.MLcard.keys()]
4099
4100 for var in self.ml_vars:
4101 if var in self.run_card:
4102 self.conflict.append(var)
4103 if var in self.pname2block:
4104 self.conflict.append(var)
4105 if self.has_mw and var in self.mw_vars:
4106 self.conflict.append(var)
4107
4108
4109 self.has_shower = False
4110 if 'shower_card.dat' in cards:
4111 self.has_shower = True
4112 try:
4113 import madgraph.various.shower_card as showercards
4114 except:
4115 import internal.shower_card as showercards
4116 self.shower_card = showercards.ShowerCard(self.paths['shower'])
4117 self.shower_vars = self.shower_card.keys()
4118
4119
4120 for var in self.pname2block:
4121 if var in self.shower_vars:
4122 self.conflict.append(var)
4123 for var in self.shower_vars:
4124 if var in self.run_card:
4125 self.conflict.append(var)
4126
4127
4128 self.has_PY8 = False
4129 if 'pythia8_card.dat' in cards:
4130 self.has_PY8 = True
4131 self.PY8Card = banner_mod.PY8Card(self.paths['PY8'])
4132 self.PY8CardDefault = banner_mod.PY8Card()
4133
4134 self.py8_vars = [k.lower() for k in self.PY8Card.keys()]
4135
4136 for var in self.py8_vars:
4137 if var in self.run_card:
4138 self.conflict.append(var)
4139 if var in self.pname2block:
4140 self.conflict.append(var)
4141 if self.has_mw and var in self.mw_vars:
4142 self.conflict.append(var)
4143 if self.has_ml and var in self.ml_vars:
4144 self.conflict.append(var)
4145
4146 - def do_help(self, line, conflict_raise=False, banner=True):
4147
4148 if banner:
4149 logger.info('*** HELP MESSAGE ***', '$MG:color:BLACK')
4150
4151 args = self.split_arg(line)
4152
4153 if len(args)==0 or (len(args) == 1 and hasattr(self, 'do_%s' % args[0])):
4154 out = cmd.BasicCmd.do_help(self, line)
4155 if len(args)==0:
4156 print 'Allowed Argument'
4157 print '================'
4158 print '\t'.join(self.allow_arg)
4159 print
4160 print 'Special shortcut: (type help <name>)'
4161 print '===================================='
4162 print ' syntax: set <name> <value>'
4163 print '\t'.join(self.special_shortcut)
4164 print
4165 if banner:
4166 logger.info('*** END HELP ***', '$MG:color:BLACK')
4167 return out
4168
4169
4170 if args[0] in self.special_shortcut:
4171 if args[0] in self.special_shortcut_help:
4172 print self.special_shortcut_help[args[0]]
4173 if banner:
4174 logger.info('*** END HELP ***', '$MG:color:BLACK')
4175 return
4176
4177 start = 0
4178 card = ''
4179 if args[0]+'_card' in self.all_card_name+ self.cards:
4180 args[0] += '_card'
4181 elif args[0]+'.dat' in self.all_card_name+ self.cards:
4182 args[0] += '.dat'
4183 elif args[0]+'_card.dat' in self.all_card_name+ self.cards:
4184 args[0] += '_card.dat'
4185 if args[0] in self.all_card_name + self.cards:
4186 start += 1
4187 card = args[0]
4188 if len(args) == 1:
4189 if args[0] == 'pythia8_card':
4190 args[0] = 'PY8Card'
4191 if args[0] == 'param_card':
4192 logger.info("Param_card information: ", '$MG:color:BLUE')
4193 print "File to define the various model parameter"
4194 logger.info("List of the Block defined:",'$MG:color:BLUE')
4195 print "\t".join(self.param_card.keys())
4196 elif args[0].startswith('madanalysis5'):
4197 print 'This card allow to make plot with the madanalysis5 package'
4198 print 'An example card is provided. For more information about the '
4199 print 'syntax please refer to: https://madanalysis.irmp.ucl.ac.be/'
4200 print 'or to the user manual [arXiv:1206.1599]'
4201 if args[0].startswith('madanalysis5_hadron'):
4202 print
4203 print 'This card also allow to make recasting analysis'
4204 print 'For more detail, see: arXiv:1407.3278'
4205 elif hasattr(self, args[0]):
4206 logger.info("%s information: " % args[0], '$MG:color:BLUE')
4207 print(eval('self.%s' % args[0]).__doc__)
4208 logger.info("List of parameter associated", '$MG:color:BLUE')
4209 print "\t".join(eval('self.%s' % args[0]).keys())
4210 if banner:
4211 logger.info('*** END HELP ***', '$MG:color:BLACK')
4212 return
4213
4214
4215 if args[start] in [l.lower() for l in self.run_card.keys()] and card in ['', 'run_card']:
4216 if args[start] not in self.run_set:
4217 args[start] = [l for l in self.run_set if l.lower() == args[start]][0]
4218
4219 if args[start] in self.conflict and not conflict_raise:
4220 conflict_raise = True
4221 logger.info('** AMBIGUOUS NAME: %s **', args[start], '$MG:color:BLACK')
4222 if card == '':
4223 logger.info('** If not explicitely speficy this parameter will modif the run_card file', '$MG:color:BLACK')
4224
4225 self.run_card.do_help(args[start])
4226
4227 elif (args[start] in self.param_card or args[start] == 'width') \
4228 and card in ['','param_card']:
4229 if args[start] in self.conflict and not conflict_raise:
4230 conflict_raise = True
4231 logger.info('** AMBIGUOUS NAME: %s **', args[start], '$MG:color:BLACK')
4232 if card == '':
4233 logger.info('** If not explicitely speficy this parameter will modif the param_card file', '$MG:color:BLACK')
4234
4235 if args[start] == 'width':
4236 args[start] = 'decay'
4237
4238 if len(args) == start+1:
4239 self.param_card.do_help(args[start], tuple())
4240 key = None
4241 elif args[start+1] in self.pname2block:
4242 all_var = self.pname2block[args[start+1]]
4243 key = None
4244 for bname, lhaid in all_var:
4245 if bname == args[start]:
4246 key = lhaid
4247 break
4248 else:
4249 logger.warning('%s is not part of block "%s" but "%s". please correct.' %
4250 (args[start+1], args[start], bname))
4251 else:
4252 try:
4253 key = tuple([int(i) for i in args[start+1:]])
4254 except ValueError:
4255 logger.warning('Failed to identify LHA information')
4256 return
4257
4258 if key in self.param_card[args[start]].param_dict:
4259 self.param_card.do_help(args[start], key, default=self.param_card_default)
4260 elif key:
4261 logger.warning('invalid information: %s not defined in the param_card' % (key,))
4262
4263 elif args[start] in self.pname2block and card in ['','param_card']:
4264 if args[start] in self.conflict and not conflict_raise:
4265 conflict_raise = True
4266 logger.info('** AMBIGUOUS NAME: %s **', args[start], '$MG:color:BLACK')
4267 if card == '':
4268 logger.info('** If not explicitely speficy this parameter will modif the param_card file', '$MG:color:BLACK')
4269
4270 all_var = self.pname2block[args[start]]
4271 for bname, lhaid in all_var:
4272 new_line = 'param_card %s %s %s' % (bname,
4273 ' '.join([ str(i) for i in lhaid]), ' '.join(args[start+1:]))
4274 self.do_help(new_line, conflict_raise=True, banner=False)
4275
4276
4277 elif self.has_ml and args[start] in self.ml_vars \
4278 and card in ['', 'MadLoop_card']:
4279
4280 if args[start] in self.conflict and not conflict_raise:
4281 conflict_raise = True
4282 logger.info('** AMBIGUOUS NAME: %s **', args[start], '$MG:color:BLACK')
4283 if card == '':
4284 logger.info('** If not explicitely speficy this parameter will modif the madloop_card file', '$MG:color:BLACK')
4285
4286 self.MLcard.do_help(args[start])
4287
4288
4289 elif self.has_PY8 and args[start] in self.PY8Card:
4290 if args[start] in self.conflict and not conflict_raise:
4291 conflict_raise = True
4292 logger.info('** AMBIGUOUS NAME: %s **', args[start], '$MG:color:BLACK')
4293 if card == '':
4294 logger.info('** If not explicitely speficy this parameter will modif the pythia8_card file', '$MG:color:BLACK')
4295
4296 self.PY8Card.do_help(args[start])
4297 elif card.startswith('madanalysis5'):
4298 print 'MA5'
4299
4300
4301 else:
4302 print "no help available"
4303
4304 if banner:
4305 logger.info('*** END HELP ***', '$MG:color:BLACK')
4306
4307 return
4308
4309
4310
4311
4312
4313
4315 prev_timer = signal.alarm(0)
4316 if prev_timer:
4317 nb_back = len(line)
4318 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
4319 self.stdout.write(line)
4320 self.stdout.flush()
4321
4322 possibilities = self.complete_set(text, line, begidx, endidx,formatting=False)
4323 if line[:begidx].strip() == 'help':
4324 possibilities['Defined command'] = cmd.BasicCmd.completenames(self, text, line)
4325 possibilities.update(self.complete_add(text, line, begidx, endidx,formatting=False))
4326 return self.deal_multiple_categories(possibilities)
4327
4328
4329
4330
4331
4333 prev_timer = signal.alarm(0)
4334 if prev_timer:
4335 nb_back = len(line)
4336 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
4337 self.stdout.write(line)
4338 self.stdout.flush()
4339
4340 arg = line[:begidx].split()
4341 if len(arg) <=1:
4342 return self.list_completion(text, ['dependent', 'missing'], line)
4343
4344
4345 - def complete_set(self, text, line, begidx, endidx, formatting=True):
4346 """ Complete the set command"""
4347
4348 prev_timer = signal.alarm(0)
4349 if prev_timer:
4350 nb_back = len(line)
4351 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
4352 self.stdout.write(line)
4353 self.stdout.flush()
4354
4355 possibilities = {}
4356 allowed = {}
4357 args = self.split_arg(line[0:begidx])
4358 if args[-1] in ['Auto', 'default']:
4359 return
4360 if len(args) == 1:
4361 allowed = {'category':'', 'run_card':'', 'block':'all', 'param_card':'','shortcut':''}
4362 if self.has_mw:
4363 allowed['madweight_card'] = ''
4364 allowed['mw_block'] = 'all'
4365 if self.has_shower:
4366 allowed['shower_card'] = ''
4367 if self.has_ml:
4368 allowed['madloop_card'] = ''
4369 if self.has_PY8:
4370 allowed['pythia8_card'] = ''
4371 if self.has_delphes:
4372 allowed['delphes_card'] = ''
4373
4374 elif len(args) == 2:
4375 if args[1] == 'run_card':
4376 allowed = {'run_card':'default'}
4377 elif args[1] == 'param_card':
4378 allowed = {'block':'all', 'param_card':'default'}
4379 elif args[1] in self.param_card.keys():
4380 allowed = {'block':args[1]}
4381 elif args[1] == 'width':
4382 allowed = {'block': 'decay'}
4383 elif args[1] == 'MadWeight_card':
4384 allowed = {'madweight_card':'default', 'mw_block': 'all'}
4385 elif args[1] == 'MadLoop_card':
4386 allowed = {'madloop_card':'default'}
4387 elif args[1] == 'pythia8_card':
4388 allowed = {'pythia8_card':'default'}
4389 elif self.has_mw and args[1] in self.mw_card.keys():
4390 allowed = {'mw_block':args[1]}
4391 elif args[1] == 'shower_card':
4392 allowed = {'shower_card':'default'}
4393 elif args[1] == 'delphes_card':
4394 allowed = {'delphes_card':'default'}
4395 else:
4396 allowed = {'value':''}
4397 else:
4398 start = 1
4399 if args[1] in ['run_card', 'param_card', 'MadWeight_card', 'shower_card',
4400 'MadLoop_card','pythia8_card','delphes_card','plot_card',
4401 'madanalysis5_parton_card','madanalysis5_hadron_card']:
4402 start = 2
4403 if args[-1] in self.pname2block.keys():
4404 allowed['value'] = 'default'
4405 elif args[start] in self.param_card.keys() or args[start] == 'width':
4406 if args[start] == 'width':
4407 args[start] = 'decay'
4408
4409 if args[start+1:]:
4410 allowed = {'block':(args[start], args[start+1:])}
4411 else:
4412 allowed = {'block':args[start]}
4413 elif self.has_mw and args[start] in self.mw_card.keys():
4414 if args[start+1:]:
4415 allowed = {'mw_block':(args[start], args[start+1:])}
4416 else:
4417 allowed = {'mw_block':args[start]}
4418
4419
4420 else:
4421 allowed['value'] = ''
4422
4423 if 'category' in allowed.keys():
4424 categories = ['run_card', 'param_card']
4425 if self.has_mw:
4426 categories.append('MadWeight_card')
4427 if self.has_shower:
4428 categories.append('shower_card')
4429 if self.has_ml:
4430 categories.append('MadLoop_card')
4431 if self.has_PY8:
4432 categories.append('pythia8_card')
4433 if self.has_delphes:
4434 categories.append('delphes_card')
4435
4436 possibilities['category of parameter (optional)'] = \
4437 self.list_completion(text, categories)
4438
4439 if 'shortcut' in allowed.keys():
4440 possibilities['special values'] = self.list_completion(text, self.special_shortcut.keys()+['qcut', 'showerkt'])
4441
4442 if 'run_card' in allowed.keys():
4443 opts = self.run_set
4444 if allowed['run_card'] == 'default':
4445 opts.append('default')
4446
4447 possibilities['Run Card'] = self.list_completion(text, opts)
4448
4449 if 'param_card' in allowed.keys():
4450 opts = self.pname2block.keys()
4451 if allowed['param_card'] == 'default':
4452 opts.append('default')
4453 possibilities['Param Card'] = self.list_completion(text, opts)
4454
4455 if 'madweight_card' in allowed.keys():
4456 opts = self.mw_vars + [k for k in self.mw_card.keys() if k !='comment']
4457 if allowed['madweight_card'] == 'default':
4458 opts.append('default')
4459 possibilities['MadWeight Card'] = self.list_completion(text, opts)
4460
4461 if 'madloop_card' in allowed.keys():
4462 opts = self.ml_vars
4463 if allowed['madloop_card'] == 'default':
4464 opts.append('default')
4465 possibilities['MadLoop Parameter'] = self.list_completion(text, opts)
4466
4467 if 'pythia8_card' in allowed.keys():
4468 opts = self.py8_vars
4469 if allowed['pythia8_card'] == 'default':
4470 opts.append('default')
4471 possibilities['Pythia8 Parameter'] = self.list_completion(text, opts)
4472
4473 if 'shower_card' in allowed.keys():
4474 opts = self.shower_vars + [k for k in self.shower_card.keys() if k !='comment']
4475 if allowed['shower_card'] == 'default':
4476 opts.append('default')
4477 possibilities['Shower Card'] = self.list_completion(text, opts)
4478
4479 if 'delphes_card' in allowed:
4480 if allowed['delphes_card'] == 'default':
4481 opts = ['default', 'atlas', 'cms']
4482 possibilities['Delphes Card'] = self.list_completion(text, opts)
4483
4484 if 'value' in allowed.keys():
4485 opts = ['default']
4486 if 'decay' in args:
4487 opts.append('Auto')
4488 opts.append('Auto@NLO')
4489 elif args[-1] in self.pname2block and self.pname2block[args[-1]][0][0] == 'decay':
4490 opts.append('Auto')
4491 opts.append('Auto@NLO')
4492 possibilities['Special Value'] = self.list_completion(text, opts)
4493
4494 if 'block' in allowed.keys():
4495 if allowed['block'] == 'all':
4496 allowed_block = [i for i in self.param_card.keys() if 'qnumbers' not in i]
4497 allowed_block.append('width')
4498 possibilities['Param Card Block' ] = \
4499 self.list_completion(text, allowed_block)
4500 elif isinstance(allowed['block'], basestring):
4501 block = self.param_card[allowed['block']].param_dict
4502 ids = [str(i[0]) for i in block
4503 if (allowed['block'], i) not in self.restricted_value]
4504 possibilities['Param Card id' ] = self.list_completion(text, ids)
4505 varname = [name for name, all_var in self.pname2block.items()
4506 if any((bname == allowed['block']
4507 for bname,lhaid in all_var))]
4508 possibilities['Param card variable'] = self.list_completion(text,
4509 varname)
4510 else:
4511 block = self.param_card[allowed['block'][0]].param_dict
4512 nb = len(allowed['block'][1])
4513 ids = [str(i[nb]) for i in block if len(i) > nb and \
4514 [str(a) for a in i[:nb]] == allowed['block'][1]]
4515
4516 if not ids:
4517 if tuple([int(i) for i in allowed['block'][1]]) in block:
4518 opts = ['default']
4519 if allowed['block'][0] == 'decay':
4520 opts.append('Auto')
4521 opts.append('Auto@NLO')
4522 possibilities['Special value'] = self.list_completion(text, opts)
4523 possibilities['Param Card id' ] = self.list_completion(text, ids)
4524
4525 if 'mw_block' in allowed.keys():
4526 if allowed['mw_block'] == 'all':
4527 allowed_block = [i for i in self.mw_card.keys() if 'comment' not in i]
4528 possibilities['MadWeight Block' ] = \
4529 self.list_completion(text, allowed_block)
4530 elif isinstance(allowed['mw_block'], basestring):
4531 block = self.mw_card[allowed['mw_block']]
4532 ids = [str(i[0]) if isinstance(i, tuple) else str(i) for i in block]
4533 possibilities['MadWeight Card id' ] = self.list_completion(text, ids)
4534 else:
4535 block = self.mw_card[allowed['mw_block'][0]]
4536 nb = len(allowed['mw_block'][1])
4537 ids = [str(i[nb]) for i in block if isinstance(i, tuple) and\
4538 len(i) > nb and \
4539 [str(a) for a in i[:nb]] == allowed['mw_block'][1]]
4540
4541 if not ids:
4542 if tuple([i for i in allowed['mw_block'][1]]) in block or \
4543 allowed['mw_block'][1][0] in block.keys():
4544 opts = ['default']
4545 possibilities['Special value'] = self.list_completion(text, opts)
4546 possibilities['MadWeight Card id' ] = self.list_completion(text, ids)
4547
4548 return self.deal_multiple_categories(possibilities, formatting)
4549
4551 """ edit the value of one parameter in the card"""
4552
4553
4554 args = self.split_arg(line)
4555 if len(args) == 0:
4556 logger.warning("No argument. For help type 'help set'.")
4557
4558 if len(args)==1 and '=' in args[-1]:
4559 arg1, arg2 = args.pop(-1).split('=',1)
4560 args += [arg1, arg2]
4561 if '=' in args:
4562 args.remove('=')
4563
4564 args[:-1] = [ a.lower() for a in args[:-1]]
4565
4566 if args[0] in self.special_shortcut:
4567 targettypes , cmd = self.special_shortcut[args[0]]
4568 if len(args) != len(targettypes) +1:
4569 logger.warning('shortcut %s requires %s argument' % (args[0], len(targettypes)))
4570 if len(args) < len(targettypes) +1:
4571 return
4572 else:
4573 logger.warning('additional argument will be ignored')
4574 values ={}
4575 for i, argtype in enumerate(targettypes):
4576 try:
4577 values = {str(i): banner_mod.ConfigFile.format_variable(args[i+1], argtype, args[0])}
4578 except ValueError as e:
4579 logger.warning("Wrong argument: The entry #%s should be of type %s.", i+1, argtype)
4580 return
4581
4582
4583
4584 for arg in cmd:
4585 try:
4586 text = arg % values
4587 except KeyError:
4588 logger.warning("This command requires one argument")
4589 return
4590 except Exception as e:
4591 logger.warning(str(e))
4592 return
4593 else:
4594 self.do_set(arg % values)
4595 return
4596
4597
4598 start = 0
4599 if len(args) < 2:
4600 logger.warning('Invalid set command %s (need two arguments)' % line)
4601 return
4602
4603
4604 if args[0].lower() == 'qcut':
4605 pythia_path = self.paths['pythia']
4606 if os.path.exists(pythia_path):
4607 logger.info('add line QCUT = %s in pythia_card.dat' % args[1])
4608 p_card = open(pythia_path,'r').read()
4609 p_card, n = re.subn('''^\s*QCUT\s*=\s*[\de\+\-\.]*\s*$''',
4610 ''' QCUT = %s ''' % args[1], \
4611 p_card, flags=(re.M+re.I))
4612 if n==0:
4613 p_card = '%s \n QCUT= %s' % (p_card, args[1])
4614 with open(pythia_path, 'w') as fsock:
4615 fsock.write(p_card)
4616 return
4617
4618 if args[0].lower() == 'showerkt':
4619 pythia_path = self.paths['pythia']
4620 if os.path.exists(pythia_path):
4621 logger.info('add line SHOWERKT = %s in pythia_card.dat' % args[1].upper())
4622 p_card = open(pythia_path,'r').read()
4623 p_card, n = re.subn('''^\s*SHOWERKT\s*=\s*[default\de\+\-\.]*\s*$''',
4624 ''' SHOWERKT = %s ''' % args[1].upper(), \
4625 p_card, flags=(re.M+re.I))
4626 if n==0:
4627 p_card = '%s \n SHOWERKT= %s' % (p_card, args[1].upper())
4628 with open(pythia_path, 'w') as fsock:
4629 fsock.write(p_card)
4630 return
4631
4632 card = ''
4633 if args[0] == 'madweight_card':
4634 if not self.mw_card:
4635 logger.warning('Invalid Command: No MadWeight card defined.')
4636 return
4637 args[0] = 'MadWeight_card'
4638
4639 if args[0] == 'shower_card':
4640 if not self.shower_card:
4641 logger.warning('Invalid Command: No Shower card defined.')
4642 return
4643 args[0] = 'shower_card'
4644
4645 if args[0] == "madloop_card":
4646 if not self.has_ml:
4647 logger.warning('Invalid Command: No MadLoopParam card defined.')
4648 return
4649 args[0] = 'MadLoop_card'
4650
4651 if args[0] == "pythia8_card":
4652 if not self.has_PY8:
4653 logger.warning('Invalid Command: No Pythia8 card defined.')
4654 return
4655 args[0] = 'pythia8_card'
4656
4657 if args[0] == 'delphes_card':
4658 if not self.has_delphes:
4659 logger.warning('Invalid Command: No Delphes card defined.')
4660 return
4661 if args[1] == 'atlas':
4662 logger.info("set default ATLAS configuration for Delphes", '$MG:color:BLACK')
4663 files.cp(pjoin(self.me_dir,'Cards', 'delphes_card_ATLAS.dat'),
4664 pjoin(self.me_dir,'Cards', 'delphes_card.dat'))
4665 return
4666 elif args[1] == 'cms':
4667 logger.info("set default CMS configuration for Delphes",'$MG:color:BLACK')
4668 files.cp(pjoin(self.me_dir,'Cards', 'delphes_card_CMS.dat'),
4669 pjoin(self.me_dir,'Cards', 'delphes_card.dat'))
4670 return
4671
4672 if args[0] in ['run_card', 'param_card', 'MadWeight_card', 'shower_card',
4673 'delphes_card','madanalysis5_hadron_card','madanalysis5_parton_card']:
4674 if args[1] == 'default':
4675 logger.info('replace %s by the default card' % args[0],'$MG:color:BLACK')
4676 files.cp(self.paths['%s_default' %args[0][:-5]], self.paths[args[0][:-5]])
4677 if args[0] == 'param_card':
4678 self.param_card = check_param_card.ParamCard(self.paths['param'])
4679 elif args[0] == 'run_card':
4680 self.run_card = banner_mod.RunCard(self.paths['run'])
4681 elif args[0] == 'shower_card':
4682 self.shower_card = shower_card_mod.ShowerCard(self.paths['shower'])
4683 return
4684 else:
4685 card = args[0]
4686 start=1
4687 if len(args) < 3:
4688 logger.warning('Invalid set command: %s (not enough arguments)' % line)
4689 return
4690
4691 elif args[0] in ['MadLoop_card']:
4692 if args[1] == 'default':
4693 logger.info('replace MadLoopParams.dat by the default card','$MG:color:BLACK')
4694 self.MLcard = banner_mod.MadLoopParam(self.MLcardDefault)
4695 self.MLcard.write(self.paths['ML'],
4696 commentdefault=True)
4697 return
4698 else:
4699 card = args[0]
4700 start=1
4701 if len(args) < 3:
4702 logger.warning('Invalid set command: %s (not enough arguments)' % line)
4703 return
4704 elif args[0] in ['pythia8_card']:
4705 if args[1] == 'default':
4706 logger.info('replace pythia8_card.dat by the default card','$MG:color:BLACK')
4707 self.PY8Card = banner_mod.PY8Card(self.PY8CardDefault)
4708 self.PY8Card.write(pjoin(self.me_dir,'Cards','pythia8_card.dat'),
4709 pjoin(self.me_dir,'Cards','pythia8_card_default.dat'),
4710 print_only_visible=True)
4711 return
4712 else:
4713 card = args[0]
4714 start=1
4715 if len(args) < 3:
4716 logger.warning('Invalid set command: %s (not enough arguments)' % line)
4717 return
4718 elif args[0] in ['madspin_card']:
4719 if args[1] == 'default':
4720 logger.info('replace madspin_card.dat by the default card','$MG:color:BLACK')
4721 files.cp(self.paths['MS_default'], self.paths['madspin'])
4722 return
4723 else:
4724 logger.warning("""Command set not allowed for modifying the madspin_card.
4725 Check the command \"decay\" instead.""")
4726 return
4727
4728
4729 if args[start] in [l.lower() for l in self.run_card.keys()] and card in ['', 'run_card']:
4730 if args[start] not in self.run_set:
4731 args[start] = [l for l in self.run_set if l.lower() == args[start]][0]
4732
4733 if args[start] in self.conflict and card == '':
4734 text = 'Ambiguous name (present in more than one card). Will assume it to be referred to run_card.\n'
4735 text += 'If this is not intended, please reset it in the run_card and specify the relevant card to \n'
4736 text += 'edit, in the format < set card parameter value >'
4737 logger.warning(text)
4738
4739 if args[start+1] == 'default':
4740 default = banner_mod.RunCard(self.paths['run_default'])
4741 if args[start] in default.keys():
4742 self.setR(args[start],default[args[start]])
4743 else:
4744 logger.info('remove information %s from the run_card' % args[start],'$MG:color:BLACK')
4745 del self.run_card[args[start]]
4746 else:
4747 if args[0].startswith('sys_') or \
4748 args[0] in self.run_card.list_parameter or \
4749 args[0] in self.run_card.dict_parameter:
4750 val = ' '.join(args[start+1:])
4751 val = val.split('#')[0]
4752 else:
4753 val = args[start+1]
4754 self.setR(args[start], val)
4755 self.run_card.write(self.paths['run'], self.paths['run_default'])
4756
4757 elif card == 'run_card' and args[start] in ['nocut', 'no_cut']:
4758 logger.info("Going to remove all cuts from the run_card", '$MG:color:BLACK')
4759 self.run_card.remove_all_cut()
4760 self.run_card.write(self.paths['run'], self.paths['run_default'])
4761
4762 elif (args[start] in self.param_card or args[start] == 'width') \
4763 and card in ['','param_card']:
4764
4765 if any(t.startswith('scan') for t in args):
4766 index = [i for i,t in enumerate(args) if t.startswith('scan')][0]
4767 args = args[:index] + [' '.join(args[index:])]
4768
4769 if args[start] in self.conflict and card == '':
4770 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4771 text += ' in the format < set card parameter value>'
4772 logger.warning(text)
4773 return
4774
4775 if args[start] == 'width':
4776 args[start] = 'decay'
4777
4778 if args[start+1] in self.pname2block:
4779 all_var = self.pname2block[args[start+1]]
4780 key = None
4781 for bname, lhaid in all_var:
4782 if bname == args[start]:
4783 key = lhaid
4784 break
4785 else:
4786 logger.warning('%s is not part of block "%s" but "%s". please correct.' %
4787 (args[start+1], args[start], bname))
4788 return
4789 else:
4790 try:
4791 key = tuple([int(i) for i in args[start+1:-1]])
4792 except ValueError:
4793 if args[start] == 'decay' and args[start+1:-1] == ['all']:
4794 for key in self.param_card[args[start]].param_dict:
4795 if (args[start], key) in self.restricted_value:
4796 continue
4797 else:
4798 self.setP(args[start], key, args[-1])
4799 self.param_card.write(self.paths['param'])
4800 return
4801 logger.warning('invalid set command %s (failed to identify LHA information)' % line)
4802 return
4803
4804 if key in self.param_card[args[start]].param_dict:
4805 if (args[start], key) in self.restricted_value:
4806 text = "Note that this parameter seems to be ignore by MG.\n"
4807 text += "MG will use instead the expression: %s\n" % \
4808 self.restricted_value[(args[start], key)]
4809 text += "You need to match this expression for external program (such pythia)."
4810 logger.warning(text)
4811
4812 if args[-1].lower() in ['default', 'auto', 'auto@nlo'] or args[-1].startswith('scan'):
4813 self.setP(args[start], key, args[-1])
4814 else:
4815 try:
4816 value = float(args[-1])
4817 except Exception:
4818 logger.warning('Invalid input: Expected number and not \'%s\'' \
4819 % args[-1])
4820 return
4821 self.setP(args[start], key, value)
4822 else:
4823 logger.warning('invalid set command %s' % line)
4824 return
4825 self.param_card.write(self.paths['param'])
4826
4827
4828 elif args[start] in self.pname2block and card in ['','param_card']:
4829 if args[start] in self.conflict and card == '':
4830 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4831 text += ' in the format < set card parameter value>'
4832 logger.warning(text)
4833 return
4834
4835 all_var = self.pname2block[args[start]]
4836 for bname, lhaid in all_var:
4837 new_line = 'param_card %s %s %s' % (bname,
4838 ' '.join([ str(i) for i in lhaid]), ' '.join(args[start+1:]))
4839 self.do_set(new_line)
4840 if len(all_var) > 1:
4841 logger.warning('This variable correspond to more than one parameter in the param_card.')
4842 for bname, lhaid in all_var:
4843 logger.warning(' %s %s' % (bname, ' '.join([str(i) for i in lhaid])))
4844 logger.warning('all listed variables have been modified')
4845
4846
4847 elif self.has_mw and (args[start] in self.mw_card and args[start] != 'comment') \
4848 and card in ['','MadWeight_card']:
4849
4850 if args[start] in self.conflict and card == '':
4851 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4852 text += ' in the format < set card parameter value>'
4853 logger.warning(text)
4854 return
4855
4856 block = args[start]
4857 name = args[start+1]
4858 value = args[start+2:]
4859 self.setM(block, name, value)
4860 self.mw_card.write(self.paths['MadWeight'])
4861
4862
4863 elif self.has_mw and args[start] in self.mw_vars \
4864 and card in ['', 'MadWeight_card']:
4865
4866 if args[start] in self.conflict and card == '':
4867 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4868 text += ' in the format < set card parameter value>'
4869 logger.warning(text)
4870 return
4871
4872 block = [b for b, data in self.mw_card.items() if args[start] in data]
4873 if len(block) > 1:
4874 logger.warning('%s is define in more than one block: %s.Please specify.'
4875 % (args[start], ','.join(block)))
4876 return
4877
4878 block = block[0]
4879 name = args[start]
4880 value = args[start+1:]
4881 self.setM(block, name, value)
4882 self.mw_card.write(self.paths['MadWeight'])
4883
4884
4885 elif self.has_mw and args[start].startswith('mw_') and len(args[start:]) == 3\
4886 and card == 'MadWeight_card':
4887 block = args[start]
4888 name = args[start+1]
4889 value = args[start+2]
4890 self.setM(block, name, value)
4891 self.mw_card.write(self.paths['MadWeight'])
4892
4893
4894 elif self.has_shower and args[start].lower() in [l.lower() for l in \
4895 self.shower_card.keys()] and card in ['', 'shower_card']:
4896 if args[start] not in self.shower_card:
4897 args[start] = [l for l in self.shower_card if l.lower() == args[start].lower()][0]
4898
4899 if args[start] in self.conflict and card == '':
4900 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4901 text += ' in the format < set card parameter value>'
4902 logger.warning(text)
4903 return
4904
4905 if args[start+1].lower() == 'default':
4906 default = shower_card_mod.ShowerCard(self.paths['shower_default'])
4907 if args[start] in default.keys():
4908 self.shower_card.set_param(args[start],default[args[start]], self.paths['shower'])
4909 else:
4910 logger.info('remove information %s from the shower_card' % args[start],'$MG:color:BLACK')
4911 del self.shower_card[args[start]]
4912 elif args[start+1].lower() in ['t','.true.','true']:
4913 self.shower_card.set_param(args[start],'.true.',self.paths['shower'])
4914 elif args[start+1].lower() in ['f','.false.','false']:
4915 self.shower_card.set_param(args[start],'.false.',self.paths['shower'])
4916 elif args[start] in ['analyse', 'extralibs', 'extrapaths', 'includepaths'] or\
4917 args[start].startswith('dm_'):
4918
4919 args = line.split()
4920 args_str = ' '.join(str(a) for a in args[start+1:len(args)])
4921 self.shower_card.set_param(args[start],args_str,pjoin(self.me_dir,'Cards','shower_card.dat'))
4922 else:
4923 args_str = ' '.join(str(a) for a in args[start+1:len(args)])
4924 self.shower_card.set_param(args[start],args_str,self.paths['shower'])
4925
4926
4927 elif self.has_ml and args[start] in self.ml_vars \
4928 and card in ['', 'MadLoop_card']:
4929
4930 if args[start] in self.conflict and card == '':
4931 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4932 logger.warning(text)
4933 return
4934
4935 if args[start+1] == 'default':
4936 value = self.MLcardDefault[args[start]]
4937 default = True
4938 else:
4939 value = args[start+1]
4940 default = False
4941 self.setML(args[start], value, default=default)
4942 self.MLcard.write(self.paths['ML'],
4943 commentdefault=True)
4944
4945
4946 elif self.has_PY8 and (card == 'pythia8_card' or (card == '' and \
4947 args[start] in self.PY8Card)):
4948
4949 if args[start] in self.conflict and card == '':
4950 text = 'ambiguous name (present in more than one card). Please specify which card to edit'
4951 logger.warning(text)
4952 return
4953
4954 if args[start+1] == 'default':
4955 value = self.PY8CardDefault[args[start]]
4956 default = True
4957 else:
4958 value = ' '.join(args[start+1:])
4959 default = False
4960 self.setPY8(args[start], value, default=default)
4961 self.PY8Card.write(pjoin(self.me_dir,'Cards','pythia8_card.dat'),
4962 pjoin(self.me_dir,'Cards','pythia8_card_default.dat'),
4963 print_only_visible=True)
4964
4965
4966 else:
4967 logger.warning('invalid set command %s ' % line)
4968 arg = args[start].lower()
4969 if self.has_PY8:
4970 close_opts = [name for name in self.PY8Card if name.lower().startswith(arg[:3]) or arg in name.lower()]
4971 if close_opts:
4972 logger.info('Did you mean one of the following PY8 options:\n%s' % '\t'.join(close_opts))
4973 if self.run_card:
4974 close_opts = [name for name in self.run_card if name.lower().startswith(arg[:3]) or arg in name.lower()]
4975 if close_opts:
4976 logger.info('Did you mean one of the following run_card options:\n%s' % '\t'.join(close_opts))
4977
4978 return
4979
4980 - def setM(self, block, name, value):
4981
4982 if isinstance(value, list) and len(value) == 1:
4983 value = value[0]
4984
4985 if block not in self.mw_card:
4986 logger.warning('block %s was not present in the current MadWeight card. We are adding it' % block)
4987 self.mw_card[block] = {}
4988 elif name not in self.mw_card[block]:
4989 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')
4990 if value == 'default':
4991 import madgraph.madweight.Cards as mwcards
4992 mw_default = mwcards.Card(self.paths['MadWeight_default'])
4993 try:
4994 value = mw_default[block][name]
4995 except KeyError:
4996 logger.info('removing id "%s" from Block "%s" '% (name, block),'$MG:color:BLACK')
4997 if name in self.mw_card[block]:
4998 del self.mw_card[block][name]
4999 return
5000 if value:
5001 logger.info('modify madweight_card information BLOCK "%s" with id "%s" set to %s',
5002 block, name, value, '$MG:color:BLACK')
5003 else:
5004 logger.warning("Invalid command: No value. To set default value. Use \"default\" as value")
5005 return
5006
5007 self.mw_card[block][name] = value
5008
5009 - def setR(self, name, value):
5010 logger.info('modify parameter %s of the run_card.dat to %s' % (name, value),'$MG:color:BLACK')
5011 self.run_card.set(name, value, user=True)
5012
5013 - def setML(self, name, value, default=False):
5014
5015 try:
5016 self.MLcard.set(name, value, user=True)
5017 except Exception, error:
5018 logger.warning("Fail to change parameter. Please Retry. Reason: %s." % error)
5019 return
5020 logger.info('modify parameter %s of the MadLoopParam.dat to %s' % (name, value),'$MG:color:BLACK')
5021 if default and name.lower() in self.MLcard.user_set:
5022 self.MLcard.user_set.remove(name.lower())
5023
5024 - def setPY8(self, name, value, default=False):
5033
5034 - def setP(self, block, lhaid, value):
5035 if isinstance(value, str):
5036 value = value.lower()
5037 if value == 'default':
5038 default = check_param_card.ParamCard(self.paths['param_default'])
5039 value = default[block].param_dict[lhaid].value
5040
5041 elif value in ['auto', 'auto@nlo']:
5042 if 'nlo' in value:
5043 value = 'Auto@NLO'
5044 else:
5045 value = 'Auto'
5046 if block != 'decay':
5047 logger.warning('Invalid input: \'Auto\' value only valid for DECAY')
5048 return
5049 elif value.startswith('scan'):
5050 if ':' not in value:
5051 logger.warning('Invalid input: \'scan\' mode requires a \':\' before the definition.')
5052 return
5053 tag = value.split(':')[0]
5054 tag = tag[4:].strip()
5055 if tag and not tag.isdigit():
5056 logger.warning('Invalid input: scan tag need to be integer and not "%s"' % tag)
5057 return
5058
5059
5060 pass
5061 else:
5062 try:
5063 value = float(value)
5064 except ValueError:
5065 logger.warning('Invalid input: \'%s\' not valid intput.'% value)
5066
5067 logger.info('modify param_card information BLOCK %s with id %s set to %s' %\
5068 (block, lhaid, value), '$MG:color:BLACK')
5069 self.param_card[block].param_dict[lhaid].value = value
5070
5072 """This is run on quitting the class. Apply here all the self-consistency
5073 rule that you want. Do the modification via the set command."""
5074
5075
5076 if 'reweight' in self.allow_arg and 'run' in self.allow_arg and \
5077 isinstance(self.run_card,banner_mod.RunCardNLO) and \
5078 not self.run_card['store_rwgt_info']:
5079
5080 re_pattern = re.compile(r'''^\s*change\s*mode\s* (LO\+NLO|LO|NLO)\s*(?:#|$)''', re.M+re.I)
5081 text = open(self.paths['reweight']).read()
5082 options = re_pattern.findall(text)
5083 if any(o in ['NLO', 'LO+NLO'] for o in options):
5084 logger.info('NLO reweighting is on ON. Automatically set store_rwgt_info to True', '$MG:color:BLACK' )
5085 self.do_set('run_card store_rwgt_info True')
5086
5087
5088
5089 if 'run' in self.allow_arg and \
5090 self.run_card['systematics_program'] == 'systematics' and \
5091 isinstance(self.run_card,banner_mod.RunCardNLO) and \
5092 not self.run_card['store_rwgt_info']:
5093 logger.warning('To be able to run systematics program, we set store_rwgt_info to True')
5094 self.do_set('run_card store_rwgt_info True')
5095
5096
5097 if 'pythia_card.dat' in self.cards:
5098 if self.run_card['event_norm'] != 'sum':
5099 logger.info('Pythia6 needs a specific normalisation of the events. We will change it accordingly.', '$MG:color:BLACK' )
5100 self.do_set('run_card event_norm sum')
5101
5102 elif 'pythia8_card.dat' in self.cards:
5103 if self.run_card['event_norm'] == 'sum':
5104 logger.info('Pythia8 needs a specific normalisation of the events. We will change it accordingly.', '$MG:color:BLACK' )
5105 self.do_set('run_card event_norm average')
5106
5107
5108 if self.has_shower and isinstance(self.run_card, banner_mod.RunCardNLO):
5109 modify_extralibs, modify_extrapaths = False,False
5110 extralibs = self.shower_card['extralibs'].split()
5111 extrapaths = self.shower_card['extrapaths'].split()
5112
5113 if self.run_card['parton_shower'] in ['PYTHIA8', 'HERWIGPP', 'HW7']:
5114 if 'stdhep' in self.shower_card['extralibs']:
5115 extralibs.remove('stdhep')
5116 modify_extralibs = True
5117 if 'Fmcfio' in self.shower_card['extralibs']:
5118 extralibs.remove('Fmcfio')
5119 modify_extralibs = True
5120 if self.run_card['parton_shower'] == 'PYTHIA8':
5121
5122 if not self.mother_interface.options['pythia8_path']:
5123 raise self.mother.InvalidCmd, 'Pythia8 is not correctly specified to MadGraph5_aMC@NLO'
5124 executable = pjoin(self.mother_interface.options['pythia8_path'], 'bin', 'pythia8-config')
5125 if not os.path.exists(executable):
5126 raise self.mother.InvalidCmd, 'Pythia8 is not correctly specified to MadGraph5_aMC@NLO'
5127
5128
5129 libs , paths = [], []
5130 p = misc.subprocess.Popen([executable, '--libs'], stdout=subprocess.PIPE)
5131 stdout, _ = p. communicate()
5132 libs = [x[2:] for x in stdout.split() if x.startswith('-l') or paths.append(x[2:])]
5133
5134
5135 p = misc.subprocess.Popen([executable, '--config'], stdout=subprocess.PIPE)
5136 stdout, _ = p. communicate()
5137 for lib in ['-ldl','-lstdc++','-lc++']:
5138 if lib in stdout:
5139 libs.append(lib[2:])
5140
5141
5142
5143 supports_HEPMCHACK = '-DHEPMC2HACK' in stdout
5144
5145
5146 for l in libs:
5147 if l not in extralibs:
5148 modify_extralibs = True
5149 extralibs.append(l)
5150 for L in paths:
5151 if L not in extrapaths:
5152 modify_extrapaths = True
5153 extrapaths.append(L)
5154
5155
5156 if modify_extralibs:
5157 if extralibs:
5158 self.do_set('shower_card extralibs %s ' % ' '.join(extralibs))
5159 else:
5160 self.do_set('shower_card extralibs None ')
5161 if modify_extrapaths:
5162 if extrapaths:
5163 self.do_set('shower_card extrapaths %s ' % ' '.join(extrapaths))
5164 else:
5165 self.do_set('shower_card extrapaths None ')
5166
5167 - def reask(self, *args, **opt):
5168
5169 cmd.OneLinePathCompletion.reask(self,*args, **opt)
5170 if self.has_mw and not os.path.exists(pjoin(self.me_dir,'Cards','transfer_card.dat')):
5171 logger.warning('No transfer function currently define. Please use the change_tf command to define one.')
5172
5173 fail_due_to_format = 0
5174 - def postcmd(self, stop, line):
5175 ending_question = cmd.OneLinePathCompletion.postcmd(self,stop,line)
5176
5177 if ending_question:
5178 self.check_card_consistency()
5179 try:
5180 self.do_update('dependent', timer=20)
5181 except MadGraph5Error, error:
5182 if 'Missing block:' in str(error):
5183 self.fail_due_to_format +=1
5184 if self.fail_due_to_format == 10:
5185 missing, unknow = str(error).split('\n')[-2:]
5186 logger.warning("Invalid param_card:\n%s\n%s\n" % (missing, unknow))
5187 logger.info("Type \"update missing\" to use default value.\n ", '$MG:color:BLACK')
5188 self.value = False
5189 return self.reask(True)
5190 else:
5191 raise
5192
5193 return ending_question
5194
5195
5196
5197
5198
5200 """ syntax: update dependent: Change the mass/width of particles which are not free parameter for the model.
5201 update missing: add to the current param_card missing blocks/parameters."""
5202
5203 args = self.split_arg(line)
5204 if len(args)==0:
5205 logger.warning('miss an argument (dependent or missing). Please retry')
5206 return
5207
5208 if args[0] == 'dependent':
5209 if not self.mother_interface:
5210 logger.warning('Failed to update dependent parameter. This might create trouble for external program (like MadSpin/shower/...)')
5211
5212 pattern_width = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto(@NLO|)''',re.I)
5213 pattern_scan = re.compile(r'''^(decay)?[\s\d]*scan''', re.I+re.M)
5214 param_text= open(self.paths['param']).read()
5215
5216 if pattern_scan.search(param_text):
5217
5218
5219
5220 return
5221 elif pattern_width.search(param_text):
5222 self.do_compute_widths('')
5223 self.param_card = check_param_card.ParamCard(self.paths['param'])
5224
5225
5226 self.update_dependent(self.mother_interface, self.me_dir, self.param_card,
5227 self.paths['param'], timer)
5228
5229 elif args[0] == 'missing':
5230 self.update_missing()
5231 return
5232
5233
5234
5235 @staticmethod
5237 """static method which can also be called from outside the class
5238 usefull in presence of scan.
5239 return if the param_card was updated or not
5240 """
5241 logger.info('Update the dependent parameter of the param_card.dat')
5242 modify = True
5243 class TimeOutError(Exception):
5244 pass
5245 def handle_alarm(signum, frame):
5246 raise TimeOutError
5247 signal.signal(signal.SIGALRM, handle_alarm)
5248 if timer:
5249 signal.alarm(timer)
5250 log_level=30
5251 else:
5252 log_level=20
5253
5254 try:
5255 model = mecmd.get_model()
5256 signal.alarm(0)
5257 except TimeOutError:
5258 logger.warning('The model takes too long to load so we bypass the updating of dependent parameter.\n'+\
5259 'This might create trouble for external program (like MadSpin/shower/...)\n'+\
5260 'The update can be forced without timer by typing \'update dependent\' at the time of the card edition')
5261 modify =False
5262 except Exception,error:
5263 logger.debug(str(error))
5264 logger.warning('Failed to update dependent parameter. This might create trouble for external program (like MadSpin/shower/...)')
5265 signal.alarm(0)
5266 else:
5267 restrict_card = pjoin(me_dir,'Source','MODEL','param_card_rule.dat')
5268 if not os.path.exists(restrict_card):
5269 restrict_card = None
5270
5271 if model:
5272 modify = param_card.update_dependent(model, restrict_card, log_level)
5273 if modify and path:
5274 param_card.write(path)
5275 else:
5276 logger.warning('missing MG5aMC code. Fail to update dependent parameter. This might create trouble for program like MadSpin/shower/...')
5277
5278 if log_level==20:
5279 logger.info('param_card up to date.')
5280
5281 return modify
5282
5283
5284
5286
5287 def check_block(self, blockname):
5288 add_entry = 0
5289 if blockname.lower() not in self.param_card_default:
5290 logger.info('unknow block %s: block will be ignored', blockname)
5291 return add_entry
5292 block = self.param_card_default[blockname]
5293 for key in block.keys():
5294 if key not in input_in_block:
5295 param = block.get(key)
5296 if blockname != 'decay':
5297 text.append('\t%s\t%s # %s\n' % (' \t'.join([`i` for i in param.lhacode]), param.value, param.comment))
5298 else:
5299 text.append('DECAY \t%s\t%s # %s\n' % (' \t'.join([`i` for i in param.lhacode]), param.value, param.comment))
5300 add_entry += 1
5301 if add_entry:
5302 text.append('\n')
5303 if add_entry:
5304 logger.info("Adding %s parameter(s) to block %s", add_entry, blockname)
5305 return add_entry
5306
5307
5308 current_block = ''
5309 input_in_block = set()
5310 defined_blocks = set()
5311 decay = set()
5312 text = []
5313 add_entry = 0
5314 for line in open(self.paths['param']):
5315
5316 new_block = re.findall(r'^\s*(block|decay)\s*(\w*)', line, re.I)
5317 if new_block:
5318 new_block = new_block[0]
5319 defined_blocks.add(new_block[1].lower())
5320 if current_block:
5321 add_entry += check_block(self, current_block)
5322
5323 current_block= new_block[1]
5324 input_in_block = set()
5325 if new_block[0].lower() == 'decay':
5326 decay.add((int(new_block[1]),))
5327 current_block = ''
5328 if new_block[1].lower() == 'qnumbers':
5329 current_block = ''
5330
5331 text.append(line)
5332 if not current_block:
5333 continue
5334
5335
5336
5337 line = line.split('#',1)[0]
5338 split = line.split()
5339 if not split:
5340 continue
5341 else:
5342 try:
5343 lhacode = [int(i) for i in split[:-1]]
5344 except:
5345 continue
5346 input_in_block.add(tuple(lhacode))
5347
5348 if current_block:
5349 add_entry += check_block(self, current_block)
5350
5351
5352 for block in self.param_card_default:
5353
5354 if block.startswith(('qnumbers', 'decay')):
5355 continue
5356
5357 if block not in defined_blocks:
5358 nb_entry = len(self.param_card_default[block])
5359 logger.info("Block %s was missing. Adding the %s associated parameter(s)", block,nb_entry)
5360 add_entry += nb_entry
5361 text.append(str(self.param_card_default[block]))
5362
5363
5364 input_in_block = decay
5365 add_entry += check_block(self, 'decay')
5366
5367 if add_entry:
5368 logger.info('write new param_card with %s new parameter(s).', add_entry, '$MG:color:BLACK')
5369 open(self.paths['param'],'w').write(''.join(text))
5370 self.reload_card(self.paths['param'])
5371 else:
5372 logger.info('No missing parameter detected.', '$MG:color:BLACK')
5373
5374
5379
5407
5408
5410 """Default action if line is not recognized"""
5411
5412 line = line.strip()
5413 args = line.split()
5414 if line == '' and self.default_value is not None:
5415 self.value = self.default_value
5416
5417 elif hasattr(self, 'do_%s' % args[0]):
5418 self.do_set(' '.join(args[1:]))
5419 elif os.path.isfile(line):
5420 self.copy_file(line)
5421 self.value = 'repeat'
5422 elif self.me_dir and os.path.exists(pjoin(self.me_dir, line)):
5423 self.copy_file(pjoin(self.me_dir,line))
5424 self.value = 'repeat'
5425 elif line.strip() != '0' and line.strip() != 'done' and \
5426 str(line) != 'EOF' and line.strip() in self.allow_arg:
5427 self.open_file(line)
5428 self.value = 'repeat'
5429 else:
5430 self.value = line
5431
5432 return line
5433
5435 """edit the madspin_card to define the decay of the associate particle"""
5436 signal.alarm(0)
5437 path = self.paths['madspin']
5438
5439 if 'madspin_card.dat' not in self.cards or not os.path.exists(path):
5440 logger.warning("Command decay not valid. Since MadSpin is not available.")
5441 return
5442
5443 if ">" not in line:
5444 logger.warning("invalid command for decay. Line ignored")
5445 return
5446
5447 if "-add" in line:
5448
5449 particle = line.split('>')[0].strip()
5450 text = open(path).read()
5451 line = line.replace('--add', '').replace('-add','')
5452 logger.info("change madspin_card to add one decay to %s: %s" %(particle, line.strip()), '$MG:color:BLACK')
5453
5454 text = text.replace('launch', "\ndecay %s\nlaunch\n" % line,1)
5455 else:
5456
5457
5458 particle = line.split('>')[0].strip()
5459 logger.info("change madspin_card to define the decay of %s: %s" %(particle, line.strip()), '$MG:color:BLACK')
5460 particle = particle.replace('+','\+').replace('-','\-')
5461 decay_pattern = re.compile(r"^\s*decay\s+%s\s*>[\s\w+-~]*?$" % particle, re.I+re.M)
5462 text= open(path).read()
5463 text = decay_pattern.sub('', text)
5464 text = text.replace('launch', "\ndecay %s\nlaunch\n" % line,1)
5465
5466 with open(path,'w') as fsock:
5467 fsock.write(text)
5468
5469
5470
5472 signal.alarm(0)
5473 path = self.paths['param']
5474 pattern = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto(@NLO|)''',re.I)
5475 text = open(path).read()
5476 pdg_info = pattern.findall(text)
5477 has_nlo = any("@nlo"==nlo.lower() for _, nlo in pdg_info)
5478 pdg = [p for p,_ in pdg_info]
5479
5480
5481 line = '%s %s' % (line, ' '.join(pdg))
5482 if not '--path' in line:
5483 line += ' --path=%s' % path
5484 if has_nlo:
5485 line += ' --nlo'
5486
5487 try:
5488 return self.mother_interface.do_compute_widths(line)
5489 except InvalidCmd, error:
5490 logger.error("Invalid command: %s " % error)
5491
5495
5497 """help for command decay which modifies MadSpin_card"""
5498
5499 signal.alarm(0)
5500 print '--syntax: decay PROC [--add]'
5501 print ' '
5502 print ' modify the madspin_card to modify the decay of the associate particle.'
5503 print ' and define it to PROC.'
5504 print ' if --add is present, just add a new decay for the associate particle.'
5505
5507 prev_timer = signal.alarm(0)
5508 if prev_timer:
5509 nb_back = len(line)
5510 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
5511 self.stdout.write(line)
5512 self.stdout.flush()
5513 return self.mother_interface.complete_compute_widths(*args,**opts)
5514
5515
5517 """help for add command"""
5518
5519 logger.info('********************* HELP ADD ***************************')
5520 logger.info( '-- syntax: add pythia8_card NAME VALUE')
5521 logger.info( " add a definition of name in the pythia8_card with the given value")
5522 logger.info( " Do not work for the param_card" )
5523 logger.info( '-- syntax: add filename [OPTION] line')
5524 logger.info( ' add the given LINE to the end of the associate file (all file supportedd).')
5525 logger.info( ' OPTION parameter allows to change the position where to write in the file')
5526 logger.info( ' --after_line=banner : write the line at the end of the banner')
5527 logger.info( ' --line_position=X : insert the line before line X (starts at 0)')
5528 logger.info( ' --after_line="<regular-expression>" write the line after the first line matching the regular expression')
5529 logger.info( ' --before_line="<regular-expression>" write the line before the first line matching the regular expression')
5530 logger.info( ' example: change reweight --after_line="^\s*change mode" change model heft')
5531 logger.info('********************* HELP ADD ***************************')
5532
5533 - def complete_add(self, text, line, begidx, endidx, formatting=True):
5534 """ auto-completion for add command"""
5535
5536 prev_timer = signal.alarm(0)
5537 if prev_timer:
5538 nb_back = len(line)
5539 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
5540 self.stdout.write(line)
5541 self.stdout.flush()
5542
5543 split = line[:begidx].split()
5544 if len(split)==1:
5545 possibilities = {}
5546 cards = [c.rsplit('.',1)[0] for c in self.cards]
5547 possibilities['category of parameter (optional)'] = \
5548 self.list_completion(text, cards)
5549 elif len(split) == 2:
5550 possibilities = {}
5551 options = ['--line_position=','--after_line=banner', '--after_line="','--before_line="']
5552 possibilities['category of parameter (optional)'] = \
5553 self.list_completion(text, options, line)
5554 else:
5555 return
5556 return self.deal_multiple_categories(possibilities, formatting)
5557
5559 """ syntax: add filename NAME VALUE
5560 syntax: add filename LINE"""
5561
5562 args = self.split_arg(line)
5563 if len(args) == 3 and args[0] in ['pythia8_card', 'pythia8_card.dat'] and self.has_PY8:
5564 name= args[1]
5565 value = args[2]
5566 self.PY8Card.userSet(name, value)
5567 self.PY8Card.write(pjoin(self.me_dir,'Cards','pythia8_card.dat'),
5568 pjoin(self.me_dir,'Cards','pythia8_card_default.dat'),
5569 print_only_visible=True)
5570 logger.info("add in the pythia8_card the parameter \"%s\" with value \"%s\"" % (name, value), '$MG:color:BLACK')
5571 elif len(args) > 0:
5572 if args[0] in self.cards:
5573 card = args[0]
5574 elif "%s.dat" % args[0] in self.cards:
5575 card = "%s.dat" % args[0]
5576 elif "%s_card.dat" % args[0] in self.cards:
5577 card = "%s_card.dat" % args[0]
5578 elif self.has_ml and args[0].lower() == "madloop":
5579 card = "MadLoopParams.dat"
5580 else:
5581 logger.error("unknow card %s. Please retry." % args[0])
5582 return
5583
5584
5585 if args[1].startswith('--line_position='):
5586
5587 text = open(pjoin(self.me_dir,'Cards',card)).read()
5588 split = text.split('\n')
5589 pos = int(args[1].split('=',1)[1])
5590 newline = line.split(None,2)[2]
5591 split.insert(pos, newline)
5592 ff = open(pjoin(self.me_dir,'Cards',card),'w')
5593 ff.write('\n'.join(split))
5594 logger.info("writting at line %d of the file %s the line: \"%s\"" %(pos, card, line.split(None,1)[1] ))
5595
5596 elif args[1].startswith('--after_line=banner'):
5597
5598 text = open(pjoin(self.me_dir,'Cards',card)).read()
5599 split = text.split('\n')
5600 for posline,l in enumerate(split):
5601 if not l.startswith('#'):
5602 break
5603 split.insert(posline, line.split(None,2)[2])
5604 ff = open(pjoin(self.me_dir,'Cards',card),'w')
5605 ff.write('\n'.join(split))
5606 logger.info("writting at line %d of the file %s the line: \"%s\"" %(posline, card, line.split(None,1)[1] ))
5607
5608 elif args[1].startswith('--before_line='):
5609
5610 text = open(pjoin(self.me_dir,'Cards',card)).read()
5611 split = text.split('\n')
5612 search_pattern=r'''before_line=(?P<quote>["'])(?:(?=(\\?))\2.)*?\1'''
5613 pattern = re.search(search_pattern, line).group()[13:-1]
5614 for posline,l in enumerate(split):
5615 if re.search(pattern, l):
5616 break
5617 else:
5618 raise Exception, 'invalid regular expression: not found in file'
5619 split.insert(posline, re.split(search_pattern,line)[-1])
5620 ff = open(pjoin(self.me_dir,'Cards',card),'w')
5621 ff.write('\n'.join(split))
5622 logger.info("writting at line %d of the file %s the line: \"%s\"" %(posline, card, line.split(None,1)[1] ))
5623
5624
5625
5626 elif args[1].startswith('--after_line='):
5627
5628 text = open(pjoin(self.me_dir,'Cards',card)).read()
5629 split = text.split('\n')
5630 search_pattern = r'''after_line=(?P<quote>["'])(?:(?=(\\?))\2.)*?\1'''
5631 pattern = re.search(search_pattern, line).group()[12:-1]
5632 for posline,l in enumerate(split):
5633 if re.search(pattern, l):
5634 break
5635 else:
5636 posline=len(split)
5637 split.insert(posline+1, re.split(search_pattern,line)[-1])
5638 ff = open(pjoin(self.me_dir,'Cards',card),'w')
5639 ff.write('\n'.join(split))
5640 logger.info("writting at line %d of the file %s the line: \"%s\"" %(posline, card, line.split(None,1)[1] ))
5641 else:
5642 ff = open(pjoin(self.me_dir,'Cards',card),'a')
5643 ff.write("%s \n" % line.split(None,1)[1])
5644 ff.close()
5645 logger.info("adding at the end of the file %s the line: \"%s\"" %(card, line.split(None,1)[1] ))
5646 self.reload_card(pjoin(self.me_dir,'Cards',card))
5647
5648
5649
5651 """Help associated to the asperge command"""
5652 signal.alarm(0)
5653
5654 print '-- syntax: asperge [options]'
5655 print ' Call ASperGe to diagonalize all mass matrices in the model.'
5656 print ' This works only if the ASperGE module is part of the UFO model (a subdirectory).'
5657 print ' If you specify some names after the command (i.e. asperge m1 m2) then ASperGe will only'
5658 print ' diagonalize the associate mass matrices (here m1 and m2).'
5659
5661 prev_timer = signal.alarm(0)
5662 if prev_timer:
5663 nb_back = len(line)
5664 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
5665 self.stdout.write(line)
5666 self.stdout.flush()
5667 blockname = self.pname2block.keys()
5668
5669 wrong = ['decay', 'mass', 'sminput']
5670 valid = [k for k in blockname if 'mix' in k]
5671 potential = [k for k in blockname if k not in valid+wrong]
5672 output = {'Mixing matrices': self.list_completion(text, valid, line),
5673 'Other potential valid input': self.list_completion(text, potential, line)}
5674
5675 return self.deal_multiple_categories(output, formatting)
5676
5677
5679 """Running ASperGe"""
5680 signal.alarm(0)
5681
5682 path = pjoin(self.me_dir,'bin','internal','ufomodel','ASperGE')
5683 if not os.path.exists(path):
5684 logger.error('ASperge has not been detected in the current model, therefore it will not be run.')
5685 return
5686 elif not os.path.exists(pjoin(path,'ASperGe')):
5687 logger.info('ASperGe has been detected but is not compiled. Running the compilation now.')
5688 try:
5689 misc.compile(cwd=path,shell=True)
5690 except MadGraph5Error, error:
5691 logger.error('''ASperGe failed to compile. Note that gsl is needed
5692 for this compilation to go trough. More information on how to install this package on
5693 http://www.gnu.org/software/gsl/
5694 Full compilation log is available at %s''' % pjoin(self.me_dir, 'ASperge_compilation.log'))
5695 open(pjoin(self.me_dir, 'ASperge_compilation.log'),'w').write(str(error))
5696 return
5697
5698 opts = line.split()
5699 card = self.paths['param']
5700 logger.info('running ASperGE')
5701 returncode = misc.call([pjoin(path,'ASperGe'), card, '%s.new' % card] + opts)
5702 if returncode:
5703 logger.error('ASperGE fails with status %s' % returncode)
5704 else:
5705 logger.info('AsPerGe creates the file succesfully')
5706 files.mv(card, '%s.beforeasperge' % card)
5707 files.mv('%s.new' % card, card)
5708
5709
5710
5712 """detect the type of the file and overwritte the current file"""
5713
5714 if path.endswith('.lhco'):
5715
5716
5717 self.do_set('mw_run inputfile %s' % os.path.relpath(path, self.mother_interface.me_dir))
5718 return
5719 elif path.endswith('.lhco.gz'):
5720
5721
5722 self.do_set('mw_run inputfile %s' % os.path.relpath(path, self.mother_interface.me_dir))
5723 return
5724 else:
5725 card_name = CommonRunCmd.detect_card_type(path)
5726
5727 if card_name == 'unknown':
5728 logger.warning('Fail to determine the type of the file. Not copied')
5729 if card_name != 'banner':
5730 logger.info('copy %s as %s' % (path, card_name))
5731 files.cp(path, self.paths[card_name.split('_',1)[0]])
5732 self.reload_card(self.paths[card_name.split('_',1)[0]])
5733 elif card_name == 'banner':
5734 banner_mod.split_banner(path, self.mother_interface.me_dir, proc_card=False)
5735 logger.info('Splitting the banner in it\'s component')
5736 if not self.mode == 'auto':
5737 self.mother_interface.keep_cards(self.cards)
5738 for card_name in self.cards:
5739 self.reload_card(pjoin(self.me_dir, 'Cards', card_name))
5740
5742 """open the file"""
5743 try:
5744 me_dir = self.mother_interface.me_dir
5745 except:
5746 me_dir = None
5747
5748 if answer.isdigit():
5749 if answer == '9':
5750 answer = 'plot'
5751 else:
5752 answer = self.cards[int(answer)-1]
5753
5754 if 'madweight' in answer:
5755 answer = answer.replace('madweight', 'MadWeight')
5756 elif 'MadLoopParams' in answer:
5757 answer = self.paths['ML']
5758 elif 'pythia8_card' in answer:
5759 answer = self.paths['PY8']
5760 if os.path.exists(answer):
5761 path = answer
5762 else:
5763 if not '.dat' in answer and not '.lhco' in answer:
5764 if answer != 'trigger':
5765 path = self.paths[answer]
5766 else:
5767 path = self.paths['delphes']
5768 elif not '.lhco' in answer:
5769 if '_' in answer:
5770 path = self.paths['_'.join(answer.split('_')[:-1])]
5771 else:
5772 path = pjoin(me_dir, 'Cards', answer)
5773 else:
5774 path = pjoin(me_dir, self.mw_card['mw_run']['inputfile'])
5775 if not os.path.exists(path):
5776 logger.info('Path in MW_card not existing')
5777 path = pjoin(me_dir, 'Events', answer)
5778
5779 path = path.replace('_card_card','_card')
5780 try:
5781 self.mother_interface.exec_cmd('open %s' % path)
5782 except InvalidCmd, error:
5783 if str(error) != 'No default path for this file':
5784 raise
5785 if answer == 'transfer_card.dat':
5786 logger.warning('You have to specify a transfer function first!')
5787 elif answer == 'input.lhco':
5788 path = pjoin(me_dir,'Events', 'input.lhco')
5789 ff = open(path,'w')
5790 ff.write('''No LHCO information imported at current time.
5791 To import a lhco file: Close this file and type the path of your file.
5792 You can also copy/paste, your event file here.''')
5793 ff.close()
5794 self.open_file(path)
5795 else:
5796 raise
5797 self.reload_card(path)
5798
5800 """reload object to have it in sync"""
5801
5802 if path == self.paths['param']:
5803 try:
5804 self.param_card = check_param_card.ParamCard(path)
5805 except (check_param_card.InvalidParamCard, ValueError) as e:
5806 logger.error('Current param_card is not valid. We are going to use the default one.')
5807 logger.error('problem detected: %s' % e)
5808 logger.error('Please re-open the file and fix the problem.')
5809 logger.warning('using the \'set\' command without opening the file will discard all your manual change')
5810 elif path == self.paths['run']:
5811 self.run_card = banner_mod.RunCard(path)
5812 elif path == self.paths['ML']:
5813 self.MLcard = banner_mod.MadLoopParam(path)
5814 elif path == self.paths['PY8']:
5815
5816
5817 if not self.PY8Card:
5818 self.PY8Card = banner_mod.PY8Card(self.paths['PY8_default'])
5819
5820 self.PY8Card.read(self.paths['PY8'], setter='user')
5821 self.py8_vars = [k.lower() for k in self.PY8Card.keys()]
5822 elif path == self.paths['MadWeight']:
5823 try:
5824 import madgraph.madweight.Cards as mwcards
5825 except:
5826 import internal.madweight.Cards as mwcards
5827 self.mw_card = mwcards.Card(path)
5828 return path
5829
5831 """a dedicated module for the param"""
5832
5833 special_shortcut ={}
5834
5835 - def __init__(self, question, card=[], mode='auto', *args, **opt):
5836
5837 self.load_default()
5838 cmd.OneLinePathCompletion.__init__(self, question, *args, **opt)
5839 if os.path.isfile(card[0]):
5840 self.param_card = check_param_card.ParamCard(card[0])
5841 self.paths['param'] = card[0]
5842 if os.path.isfile(card[0].replace('.dat', '_default.dat')):
5843 self.paths['param_default'] = card[0].replace('.dat', '_default.dat')
5844 else:
5845 self.paths['param_default'] = card[0]
5846 else:
5847 raise Exception, 'path %s do not exists' % card[0]
5848
5849 self.pname2block, self.restricted_value = self.param_card.analyze_param_card()
5850 self.cards=['param']
5851
5853 "Not available"
5854 logger.warning("asperge not available in this mode")
5855