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