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