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