1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 from __future__ import division
17 import collections
18 import copy
19 import logging
20 import numbers
21 import os
22 import sys
23 import re
24 import math
25 import StringIO
26
27 pjoin = os.path.join
28
29 try:
30 import madgraph
31 except ImportError:
32 MADEVENT = True
33 from internal import MadGraph5Error, InvalidCmd
34 import internal.file_writers as file_writers
35 import internal.files as files
36 import internal.check_param_card as param_card_reader
37 import internal.misc as misc
38 MEDIR = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
39 MEDIR = os.path.split(MEDIR)[0]
40 else:
41 MADEVENT = False
42 import madgraph.various.misc as misc
43 import madgraph.iolibs.file_writers as file_writers
44 import madgraph.iolibs.files as files
45 import models.check_param_card as param_card_reader
46 from madgraph import MG5DIR, MadGraph5Error, InvalidCmd
47
48
49 logger = logging.getLogger('madevent.cards')
54
57 """ """
58
59 ordered_items = ['mgversion', 'mg5proccard', 'mgproccard', 'mgruncard',
60 'slha', 'mggenerationinfo', 'mgpythiacard', 'mgpgscard',
61 'mgdelphescard', 'mgdelphestrigger','mgshowercard',
62 'ma5card_parton','ma5card_hadron','run_settings']
63
64 capitalized_items = {
65 'mgversion': 'MGVersion',
66 'mg5proccard': 'MG5ProcCard',
67 'mgproccard': 'MGProcCard',
68 'mgruncard': 'MGRunCard',
69 'ma5card_parton' : 'MA5Card_parton',
70 'ma5card_hadron' : 'MA5Card_hadron',
71 'mggenerationinfo': 'MGGenerationInfo',
72 'mgpythiacard': 'MGPythiaCard',
73 'mgpgscard': 'MGPGSCard',
74 'mgdelphescard': 'MGDelphesCard',
75 'mgdelphestrigger': 'MGDelphesTrigger',
76 'mgshowercard': 'MGShowerCard' }
77
79 """ """
80
81 if isinstance(banner_path, Banner):
82 dict.__init__(self, banner_path)
83 self.lhe_version = banner_path.lhe_version
84 return
85 else:
86 dict.__init__(self)
87
88
89 if MADEVENT:
90 self['mgversion'] = '#%s\n' % open(pjoin(MEDIR, 'MGMEVersion.txt')).read()
91 else:
92 info = misc.get_pkg_info()
93 self['mgversion'] = info['version']+'\n'
94
95 self.lhe_version = None
96
97
98 if banner_path:
99 self.read_banner(banner_path)
100
101
102
103
104 pat_begin=re.compile('<(?P<name>\w*)>')
105 pat_end=re.compile('</(?P<name>\w*)>')
106
107 tag_to_file={'slha':'param_card.dat',
108 'mgruncard':'run_card.dat',
109 'mgpythiacard':'pythia_card.dat',
110 'mgpgscard' : 'pgs_card.dat',
111 'mgdelphescard':'delphes_card.dat',
112 'mgdelphestrigger':'delphes_trigger.dat',
113 'mg5proccard':'proc_card_mg5.dat',
114 'mgproccard': 'proc_card.dat',
115 'init': '',
116 'mggenerationinfo':'',
117 'scalesfunctionalform':'',
118 'montecarlomasses':'',
119 'initrwgt':'',
120 'madspin':'madspin_card.dat',
121 'mgshowercard':'shower_card.dat',
122 'pythia8':'pythia8_card.dat',
123 'ma5card_parton':'madanalysis5_parton_card.dat',
124 'ma5card_hadron':'madanalysis5_hadron_card.dat',
125 'run_settings':''
126 }
127
129 """read a banner"""
130
131 if isinstance(input_path, str):
132 if input_path.find('\n') ==-1:
133 input_path = open(input_path)
134 else:
135 def split_iter(string):
136 return (x.groups(0)[0] for x in re.finditer(r"([^\n]*\n)", string, re.DOTALL))
137 input_path = split_iter(input_path)
138
139 text = ''
140 store = False
141 for line in input_path:
142 if self.pat_begin.search(line):
143 if self.pat_begin.search(line).group('name').lower() in self.tag_to_file:
144 tag = self.pat_begin.search(line).group('name').lower()
145 store = True
146 continue
147 if store and self.pat_end.search(line):
148 if tag == self.pat_end.search(line).group('name').lower():
149 self[tag] = text
150 text = ''
151 store = False
152 if store:
153 if line.endswith('\n'):
154 text += line
155 else:
156 text += '%s%s' % (line, '\n')
157
158
159 if "</init>" in line:
160 break
161 elif "<event>" in line:
162 break
163
165 """allow auto-build for the run_card/param_card/... """
166 try:
167 return super(Banner, self).__getattribute__(attr)
168 except:
169 if attr not in ['run_card', 'param_card', 'slha', 'mgruncard', 'mg5proccard', 'mgshowercard', 'foanalyse']:
170 raise
171 return self.charge_card(attr)
172
173
174
176 """change the lhe version associate to the banner"""
177
178 version = float(version)
179 if version < 3:
180 version = 1
181 elif version > 3:
182 raise Exception, "Not Supported version"
183 self.lhe_version = version
184
186 """return the cross-section of the file"""
187
188 if "init" not in self:
189 misc.sprint(self.keys())
190 raise Exception
191
192 text = self["init"].split('\n')
193 cross = 0
194 error = 0
195 for line in text:
196 s = line.split()
197 if len(s)==4:
198 cross += float(s[0])
199 if witherror:
200 error += float(s[1])**2
201 if not witherror:
202 return cross
203 else:
204 return cross, math.sqrt(error)
205
206
208 """modify the init information with the associate scale"""
209
210 assert "init" in self
211
212 all_lines = self["init"].split('\n')
213 new_data = []
214 new_data.append(all_lines[0])
215 for i in range(1, len(all_lines)):
216 line = all_lines[i]
217 split = line.split()
218 if len(split) == 4:
219 xsec, xerr, xmax, pid = split
220 else:
221 new_data += all_lines[i:]
222 break
223 pid = int(pid)
224
225 line = " %+13.7e %+13.7e %+13.7e %i" % \
226 (ratio*float(xsec), ratio* float(xerr), ratio*float(xmax), pid)
227 new_data.append(line)
228 self['init'] = '\n'.join(new_data)
229
231 """return the pdg of each beam"""
232
233 assert "init" in self
234
235 all_lines = self["init"].split('\n')
236 pdg1,pdg2,_ = all_lines[0].split(None, 2)
237 return int(pdg1), int(pdg2)
238
240 """ Load the proc_card /param_card and run_card """
241
242 self.add(pjoin(medir,'Cards', 'param_card.dat'))
243 self.add(pjoin(medir,'Cards', 'run_card.dat'))
244 if os.path.exists(pjoin(medir, 'SubProcesses', 'procdef_mg5.dat')):
245 self.add(pjoin(medir,'SubProcesses', 'procdef_mg5.dat'))
246 self.add(pjoin(medir,'Cards', 'proc_card_mg5.dat'))
247 else:
248 self.add(pjoin(medir,'Cards', 'proc_card.dat'))
249
251 """Change the seed value in the banner"""
252
253 p = re.compile(r'''^\s*\d+\s*=\s*iseed''', re.M)
254 new_seed_str = " %s = iseed" % seed
255 self['mgruncard'] = p.sub(new_seed_str, self['mgruncard'])
256
258 """add info on MGGeneration"""
259
260 text = """
261 # Number of Events : %s
262 # Integrated weight (pb) : %s
263 """ % (nb_event, cross)
264 self['MGGenerationInfo'] = text
265
266
267
268
269 - def split(self, me_dir, proc_card=True):
270 """write the banner in the Cards directory.
271 proc_card argument is present to avoid the overwrite of proc_card
272 information"""
273
274 for tag, text in self.items():
275 if tag == 'mgversion':
276 continue
277 if not proc_card and tag in ['mg5proccard','mgproccard']:
278 continue
279 if not self.tag_to_file[tag]:
280 continue
281 ff = open(pjoin(me_dir, 'Cards', self.tag_to_file[tag]), 'w')
282 ff.write(text)
283 ff.close()
284
285
286
287
288
290 """special routine removing width/mass of particles not present in the model
291 This is usefull in case of loop model card, when we want to use the non
292 loop model."""
293
294 if not hasattr(self, 'param_card'):
295 self.charge_card('slha')
296
297 for tag in ['mass', 'decay']:
298 block = self.param_card.get(tag)
299 for data in block:
300 pid = data.lhacode[0]
301 if pid not in pid2label.keys():
302 block.remove((pid,))
303
305 """get the lha_strategy: how the weight have to be handle by the shower"""
306
307 if not self["init"]:
308 raise Exception, "No init block define"
309
310 data = self["init"].split('\n')[0].split()
311 if len(data) != 10:
312 misc.sprint(len(data), self['init'])
313 raise Exception, "init block has a wrong format"
314 return int(float(data[-2]))
315
317 """set the lha_strategy: how the weight have to be handle by the shower"""
318
319 if not (-4 <= int(value) <= 4):
320 raise Exception, "wrong value for lha_strategy", value
321 if not self["init"]:
322 raise Exception, "No init block define"
323
324 all_lines = self["init"].split('\n')
325 data = all_lines[0].split()
326 if len(data) != 10:
327 misc.sprint(len(data), self['init'])
328 raise Exception, "init block has a wrong format"
329 data[-2] = '%s' % value
330 all_lines[0] = ' '.join(data)
331 self['init'] = '\n'.join(all_lines)
332
333
335 """modify the init information with the associate cross-section"""
336
337 assert isinstance(cross, dict)
338
339 assert "init" in self
340
341 all_lines = self["init"].split('\n')
342 new_data = []
343 new_data.append(all_lines[0])
344 for i in range(1, len(all_lines)):
345 line = all_lines[i]
346 split = line.split()
347 if len(split) == 4:
348 xsec, xerr, xmax, pid = split
349 else:
350 new_data += all_lines[i:]
351 break
352 if int(pid) not in cross:
353 raise Exception
354 pid = int(pid)
355 ratio = cross[pid]/float(xsec)
356 line = " %+13.7e %+13.7e %+13.7e %i" % \
357 (float(cross[pid]), ratio* float(xerr), ratio*float(xmax), pid)
358 new_data.append(line)
359 self['init'] = '\n'.join(new_data)
360
361
362
363
364 - def write(self, output_path, close_tag=True, exclude=[]):
365 """write the banner"""
366
367 if isinstance(output_path, str):
368 ff = open(output_path, 'w')
369 else:
370 ff = output_path
371
372 if MADEVENT:
373 header = open(pjoin(MEDIR, 'Source', 'banner_header.txt')).read()
374 else:
375 header = open(pjoin(MG5DIR,'Template', 'LO', 'Source', 'banner_header.txt')).read()
376
377 if not self.lhe_version:
378 self.lhe_version = self.get('run_card', 'lhe_version', default=1.0)
379 if float(self.lhe_version) < 3:
380 self.lhe_version = 1.0
381
382 ff.write(header % { 'version':float(self.lhe_version)})
383
384
385 for tag in [t for t in self.ordered_items if t in self.keys()]:
386 if tag in exclude:
387 continue
388 capitalized_tag = self.capitalized_items[tag] if tag in self.capitalized_items else tag
389 ff.write('<%(tag)s>\n%(text)s\n</%(tag)s>\n' % \
390 {'tag':capitalized_tag, 'text':self[tag].strip()})
391 for tag in [t for t in self.keys() if t not in self.ordered_items]:
392 if tag in ['init'] or tag in exclude:
393 continue
394 capitalized_tag = self.capitalized_items[tag] if tag in self.capitalized_items else tag
395 ff.write('<%(tag)s>\n%(text)s\n</%(tag)s>\n' % \
396 {'tag':capitalized_tag, 'text':self[tag].strip()})
397
398 if not '/header' in exclude:
399 ff.write('</header>\n')
400
401 if 'init' in self and not 'init' in exclude:
402 text = self['init']
403 ff.write('<%(tag)s>\n%(text)s\n</%(tag)s>\n' % \
404 {'tag':'init', 'text':text.strip()})
405 if close_tag:
406 ff.write('</LesHouchesEvents>\n')
407 return ff
408
409
410
411
412
413 - def add(self, path, tag=None):
414 """Add the content of the file to the banner"""
415
416 if not tag:
417 card_name = os.path.basename(path)
418 if 'param_card' in card_name:
419 tag = 'slha'
420 elif 'run_card' in card_name:
421 tag = 'MGRunCard'
422 elif 'pythia_card' in card_name:
423 tag = 'MGPythiaCard'
424 elif 'pythia8_card' in card_name or 'pythia8.cmd' in card_name:
425 tag = 'MGPythiaCard'
426 elif 'pgs_card' in card_name:
427 tag = 'MGPGSCard'
428 elif 'delphes_card' in card_name:
429 tag = 'MGDelphesCard'
430 elif 'delphes_trigger' in card_name:
431 tag = 'MGDelphesTrigger'
432 elif 'proc_card_mg5' in card_name:
433 tag = 'MG5ProcCard'
434 elif 'proc_card' in card_name:
435 tag = 'MGProcCard'
436 elif 'procdef_mg5' in card_name:
437 tag = 'MGProcCard'
438 elif 'shower_card' in card_name:
439 tag = 'MGShowerCard'
440 elif 'madspin_card' in card_name:
441 tag = 'madspin'
442 elif 'FO_analyse_card' in card_name:
443 tag = 'foanalyse'
444 elif 'reweight_card' in card_name:
445 tag='reweight_card'
446 elif 'madanalysis5_parton_card' in card_name:
447 tag='MA5Card_parton'
448 elif 'madanalysis5_hadron_card' in card_name:
449 tag='MA5Card_hadron'
450 else:
451 raise Exception, 'Impossible to know the type of the card'
452
453 self.add_text(tag.lower(), open(path).read())
454
455 - def add_text(self, tag, text):
456 """Add the content of the file to the banner"""
457
458 if tag == 'param_card':
459 tag = 'slha'
460 elif tag == 'run_card':
461 tag = 'mgruncard'
462 elif tag == 'proc_card':
463 tag = 'mg5proccard'
464 elif tag == 'shower_card':
465 tag = 'mgshowercard'
466 elif tag == 'FO_analyse_card':
467 tag = 'foanalyse'
468
469 self[tag.lower()] = text
470
471
521
522
524 """return a specific """
525
526 if tag in ['param_card', 'param']:
527 tag = 'slha'
528 attr_tag = 'param_card'
529 elif tag in ['run_card', 'run']:
530 tag = 'mgruncard'
531 attr_tag = 'run_card'
532 elif tag == 'proc_card':
533 tag = 'mg5proccard'
534 attr_tag = 'proc_card'
535 elif tag == 'model':
536 tag = 'mg5proccard'
537 attr_tag = 'proc_card'
538 arg = ('model',)
539 elif tag == 'generate':
540 tag = 'mg5proccard'
541 attr_tag = 'proc_card'
542 arg = ('generate',)
543 elif tag == 'shower_card':
544 tag = 'mgshowercard'
545 attr_tag = 'shower_card'
546 assert tag in ['slha', 'mgruncard', 'mg5proccard', 'shower_card'], '%s not recognized' % tag
547
548 if not hasattr(self, attr_tag):
549 self.charge_card(attr_tag)
550
551 card = getattr(self, attr_tag)
552 if len(arg) == 0:
553 return card
554 elif len(arg) == 1:
555 if tag == 'mg5proccard':
556 try:
557 return card.get(arg[0])
558 except KeyError, error:
559 if 'default' in opt:
560 return opt['default']
561 else:
562 raise
563 try:
564 return card[arg[0]]
565 except KeyError:
566 if 'default' in opt:
567 return opt['default']
568 else:
569 raise
570 elif len(arg) == 2 and tag == 'slha':
571 try:
572 return card[arg[0]].get(arg[1:])
573 except KeyError:
574 if 'default' in opt:
575 return opt['default']
576 else:
577 raise
578 elif len(arg) == 0:
579 return card
580 else:
581 raise Exception, "Unknow command"
582
583
584 get = get_detail
585
586 - def set(self, card, *args):
587 """modify one of the cards"""
588
589 if tag == 'param_card':
590 tag = 'slha'
591 attr_tag = 'param_card'
592 elif tag == 'run_card':
593 tag = 'mgruncard'
594 attr_tag = 'run_card'
595 elif tag == 'proc_card':
596 tag = 'mg5proccard'
597 attr_tag = 'proc_card'
598 elif tag == 'model':
599 tag = 'mg5proccard'
600 attr_tag = 'proc_card'
601 arg = ('model',)
602 elif tag == 'generate':
603 tag = 'mg5proccard'
604 attr_tag = 'proc_card'
605 arg = ('generate',)
606 elif tag == 'shower_card':
607 tag = 'mgshowercard'
608 attr_tag = 'shower_card'
609 assert tag in ['slha', 'mgruncard', 'mg5proccard', 'shower_card'], 'not recognized'
610
611 if not hasattr(self, attr_tag):
612 self.charge_card(attr_tag)
613
614 card = getattr(self, attr_tag)
615 if len(args) ==2:
616 if tag == 'mg5proccard':
617 card.info[args[0]] = args[-1]
618 else:
619 card[args[0]] = args[1]
620 else:
621 card[args[:-1]] = args[-1]
622
623
624 @misc.multiple_try()
626 """Add the banner to a file and change the associate seed in the banner"""
627
628 if seed is not None:
629 self.set("run_card", "iseed", seed)
630
631 if not out:
632 path_out = "%s.tmp" % path
633 else:
634 path_out = out
635
636 ff = self.write(path_out, close_tag=False,
637 exclude=['MGGenerationInfo', '/header', 'init'])
638 ff.write("## END BANNER##\n")
639 if self.lhe_version >= 3:
640
641 [ff.write(line) if not line.startswith("<generator name='MadGraph5_aMC@NLO'")
642 else ff.write("<generator name='MadGraph5_aMC@NLO' version='%s'>" % self['mgversion'][:-1])
643 for line in open(path)]
644 else:
645 [ff.write(line) for line in open(path)]
646 ff.write("</LesHouchesEvents>\n")
647 ff.close()
648 if out:
649 os.remove(path)
650 else:
651 files.mv(path_out, path)
652
653
654
655 -def split_banner(banner_path, me_dir, proc_card=True):
660
662 """as input we receive a gen_crossxhtml.AllResults object.
663 This define the current banner and load it
664 """
665
666 if not run:
667 try:
668 _run = results_object.current['run_name']
669 _tag = results_object.current['tag']
670 except Exception:
671 return Banner()
672 else:
673 _run = run
674 if not tag:
675 try:
676 _tag = results_object[run].tags[-1]
677 except Exception,error:
678 return Banner()
679 else:
680 _tag = tag
681
682 path = results_object.path
683 banner_path = pjoin(path,'Events',run,'%s_%s_banner.txt' % (run, tag))
684
685 if not os.path.exists(banner_path):
686 if level != "parton" and tag != _tag:
687 return recover_banner(results_object, level, _run, results_object[_run].tags[0])
688 elif level == 'parton':
689 paths = [pjoin(path,'Events',run, 'unweighted_events.lhe.gz'),
690 pjoin(path,'Events',run, 'unweighted_events.lhe'),
691 pjoin(path,'Events',run, 'events.lhe.gz'),
692 pjoin(path,'Events',run, 'events.lhe')]
693 for p in paths:
694 if os.path.exists(p):
695 if MADEVENT:
696 import internal.lhe_parser as lhe_parser
697 else:
698 import madgraph.various.lhe_parser as lhe_parser
699 lhe = lhe_parser.EventFile(p)
700 return Banner(lhe.banner)
701
702
703 return Banner()
704 banner = Banner(banner_path)
705
706
707
708 if level == 'pythia':
709 if 'mgpythiacard' in banner:
710 del banner['mgpythiacard']
711 if level in ['pythia','pgs','delphes']:
712 for tag in ['mgpgscard', 'mgdelphescard', 'mgdelphestrigger']:
713 if tag in banner:
714 del banner[tag]
715 return banner
716
719
721 """Basic Proccard object"""
722
723 history_header = \
724 '#************************************************************\n' + \
725 '#* MadGraph5_aMC@NLO *\n' + \
726 '#* *\n' + \
727 "#* * * *\n" + \
728 "#* * * * * *\n" + \
729 "#* * * * * 5 * * * * *\n" + \
730 "#* * * * * *\n" + \
731 "#* * * *\n" + \
732 "#* *\n" + \
733 "#* *\n" + \
734 "%(info_line)s" +\
735 "#* *\n" + \
736 "#* The MadGraph5_aMC@NLO Development Team - Find us at *\n" + \
737 "#* https://server06.fynu.ucl.ac.be/projects/madgraph *\n" + \
738 '#* *\n' + \
739 '#************************************************************\n' + \
740 '#* *\n' + \
741 '#* Command File for MadGraph5_aMC@NLO *\n' + \
742 '#* *\n' + \
743 '#* run as ./bin/mg5_aMC filename *\n' + \
744 '#* *\n' + \
745 '#************************************************************\n'
746
747
748
749
751 """ initialize a basic proc_card"""
752 self.info = {'model': 'sm', 'generate':None,
753 'full_model_line':'import model sm'}
754 list.__init__(self)
755 if init:
756 self.read(init)
757
758
759 - def read(self, init):
760 """read the proc_card and save the information"""
761
762 if isinstance(init, str):
763 init = file(init, 'r')
764
765 store_line = ''
766 for line in init:
767 line = line.rstrip()
768 if line.endswith('\\'):
769 store_line += line[:-1]
770 else:
771 tmp = store_line + line
772 self.append(tmp.strip())
773 store_line = ""
774 if store_line:
775 raise Exception, "WRONG CARD FORMAT"
776
777
779 """move an element to the last history."""
780 for line in self[:]:
781 if line.startswith(cmd):
782 self.remove(line)
783 list.append(self, line)
784
786 """"add a line in the proc_card perform automatically cleaning"""
787
788 line = line.strip()
789 cmds = line.split()
790 if len(cmds) == 0:
791 return
792
793 list.append(self, line)
794
795
796 cmd = cmds[0]
797
798 if cmd == 'output':
799
800 self.clean(allow_for_removal = ['output'], keep_switch=True,
801 remove_bef_last='output')
802 elif cmd == 'generate':
803
804 self.clean(remove_bef_last='generate', keep_switch=True,
805 allow_for_removal= ['generate', 'add process', 'output'])
806 self.info['generate'] = ' '.join(cmds[1:])
807 elif cmd == 'add' and cmds[1] == 'process' and not self.info['generate']:
808 self.info['generate'] = ' '.join(cmds[2:])
809 elif cmd == 'import':
810 if len(cmds) < 2:
811 return
812 if cmds[1].startswith('model'):
813 self.info['full_model_line'] = line
814 self.clean(remove_bef_last='import', keep_switch=True,
815 allow_for_removal=['generate', 'add process', 'add model', 'output'])
816 if cmds[1] == 'model':
817 self.info['model'] = cmds[2]
818 else:
819 self.info['model'] = None
820 elif cmds[1] == 'proc_v4':
821
822 self[:] = []
823
824
825 - def clean(self, to_keep=['set','add','load'],
826 remove_bef_last=None,
827 to_remove=['open','display','launch', 'check','history'],
828 allow_for_removal=None,
829 keep_switch=False):
830 """Remove command in arguments from history.
831 All command before the last occurrence of 'remove_bef_last'
832 (including it) will be removed (but if another options tells the opposite).
833 'to_keep' is a set of line to always keep.
834 'to_remove' is a set of line to always remove (don't care about remove_bef_
835 status but keep_switch acts.).
836 if 'allow_for_removal' is define only the command in that list can be
837 remove of the history for older command that remove_bef_lb1. all parameter
838 present in to_remove are always remove even if they are not part of this
839 list.
840 keep_switch force to keep the statement remove_bef_??? which changes starts
841 the removal mode.
842 """
843
844
845 if __debug__ and allow_for_removal:
846 for arg in to_keep:
847 assert arg not in allow_for_removal
848
849
850 nline = -1
851 removal = False
852
853 while nline > -len(self):
854 switch = False
855
856
857 if not removal and remove_bef_last:
858 if self[nline].startswith(remove_bef_last):
859 removal = True
860 switch = True
861
862
863 if switch and keep_switch:
864 nline -= 1
865 continue
866
867
868 if any([self[nline].startswith(arg) for arg in to_remove]):
869 self.pop(nline)
870 continue
871
872
873 if removal:
874 if allow_for_removal:
875
876 if any([self[nline].startswith(arg)
877 for arg in allow_for_removal]):
878 self.pop(nline)
879 continue
880 elif not any([self[nline].startswith(arg) for arg in to_keep]):
881
882 self.pop(nline)
883 continue
884
885
886 nline -= 1
887
888 - def get(self, tag, default=None):
889 if isinstance(tag, int):
890 list.__getattr__(self, tag)
891 elif tag == 'info' or tag == "__setstate__":
892 return default
893 elif tag == "multiparticles":
894 out = []
895 for line in self:
896 if line.startswith('define'):
897 name, content = line[7:].split('=',1)
898 out.append((name, content))
899 return out
900 else:
901 return self.info[tag]
902
904 """write the proc_card to a given path"""
905
906 fsock = open(path, 'w')
907 fsock.write(self.history_header)
908 for line in self:
909 while len(line) > 70:
910 sub, line = line[:70]+"\\" , line[70:]
911 fsock.write(sub+"\n")
912 else:
913 fsock.write(line+"\n")
914
917 """ a class for storing/dealing with input file.
918 """
919
920 - def __init__(self, finput=None, **opt):
921 """initialize a new instance. input can be an instance of MadLoopParam,
922 a file, a path to a file, or simply Nothing"""
923
924 if isinstance(finput, self.__class__):
925 dict.__init__(self, finput)
926 assert finput.__dict__.keys()
927 for key in finput.__dict__:
928 setattr(self, key, copy.copy(getattr(finput, key)) )
929 return
930 else:
931 dict.__init__(self)
932
933
934 self.user_set = set()
935 self.auto_set = set()
936 self.system_only = set()
937 self.lower_to_case = {}
938 self.list_parameter = set()
939 self.dict_parameter = {}
940 self.comments = {}
941
942 self.default_setup()
943
944
945
946 if isinstance(finput, (file, str, StringIO.StringIO)):
947 self.read(finput, **opt)
948
951
953 return self.__class__(self)
954
956 """define the sum"""
957 assert isinstance(other, dict)
958 base = self.__class__(self)
959
960 base.update((key.lower(),value) for key, value in other.items())
961 return base
962
964 """define the sum"""
965 new = copy.copy(other)
966 new.update((key, value) for key, value in self.items())
967 return new
968
971
975
978
981
982
983 - def __setitem__(self, name, value, change_userdefine=False):
984 """set the attribute and set correctly the type if the value is a string.
985 change_userdefine on True if we have to add the parameter in user_set
986 """
987 if not len(self):
988
989 self.__init__()
990
991
992 name = name.strip()
993 lower_name = name.lower()
994
995 if change_userdefine and lower_name in self.system_only:
996 logger.critical('%s is a private entry which can not be modify by the user. Keep value at %s' % (name,self[name]))
997 return
998
999
1000 if lower_name in self:
1001 targettype = type(dict.__getitem__(self, lower_name))
1002 if targettype != str and isinstance(value, str) and value.lower() == 'auto':
1003 self.auto_set.add(lower_name)
1004 if lower_name in self.user_set:
1005 self.user_set.remove(lower_name)
1006
1007 return
1008 elif lower_name in self.auto_set:
1009 self.auto_set.remove(lower_name)
1010
1011
1012 if lower_name in self.list_parameter:
1013 if isinstance(self[name], list):
1014 targettype = type(self[name][0])
1015 else:
1016
1017 targettype = type(dict.__getitem__(self,name))
1018 if isinstance(value, str):
1019
1020 value = value.strip()
1021 if value.startswith('[') and value.endswith(']'):
1022 value = value[1:-1]
1023
1024 data = re.split(r"((?<![\\])['\"])((?:.(?!(?<![\\])\1))*.?)\1", str(value))
1025 new_value = []
1026 i = 0
1027 while len(data) > i:
1028 current = filter(None, re.split(r'(?:(?<!\\)\s)|,', data[i], re.VERBOSE))
1029 i+=1
1030 if len(data) > i+1:
1031 if current:
1032 current[-1] += '{0}{1}{0}'.format(data[i], data[i+1])
1033 else:
1034 current = ['{0}{1}{0}'.format(data[i], data[i+1])]
1035 i+=2
1036 new_value += current
1037
1038
1039
1040 value = new_value
1041
1042 elif not hasattr(value, '__iter__'):
1043 value = [value]
1044 elif isinstance(value, dict):
1045 raise Exception, "not being able to handle dictionary in card entry"
1046
1047 values =[self.format_variable(v, targettype, name=name)
1048 for v in value]
1049 dict.__setitem__(self, lower_name, values)
1050 if change_userdefine:
1051 self.user_set.add(lower_name)
1052 return
1053 elif lower_name in self.dict_parameter:
1054 targettype = self.dict_parameter[lower_name]
1055 full_reset = True
1056
1057 if isinstance(value, str):
1058 value = value.strip()
1059
1060
1061
1062
1063
1064
1065
1066 if value.startswith('{') and value.endswith('}'):
1067 new_value = {}
1068 for pair in value[1:-1].split(','):
1069 if not pair.strip():
1070 break
1071 x, y = pair.split(':')
1072 x, y = x.strip(), y.strip()
1073 if x.startswith(('"',"'")) and x.endswith(x[0]):
1074 x = x[1:-1]
1075 new_value[x] = y
1076 value = new_value
1077 elif ',' in value:
1078 x,y = value.split(',')
1079 value = {x.strip():y.strip()}
1080 full_reset = False
1081
1082 elif ':' in value:
1083 x,y = value.split(':')
1084 value = {x.strip():y.strip()}
1085 full_reset = False
1086 else:
1087 x,y = value.split()
1088 value = {x:y}
1089 full_reset = False
1090
1091 if isinstance(value, dict):
1092 for key in value:
1093 value[key] = self.format_variable(value[key], targettype, name=name)
1094 if full_reset:
1095 dict.__setitem__(self, lower_name, value)
1096 else:
1097 dict.__getitem__(self, lower_name).update(value)
1098 else:
1099 raise Exception, '%s should be of dict type'% lower_name
1100 if change_userdefine:
1101 self.user_set.add(lower_name)
1102 return
1103 elif name in self:
1104 targettype = type(self[name])
1105 else:
1106 logger.debug('Trying to add argument %s in %s. ' % (name, self.__class__.__name__) +\
1107 'This argument is not defined by default. Please consider adding it.')
1108 suggestions = [k for k in self.keys() if k.startswith(name[0].lower())]
1109 if len(suggestions)>0:
1110 logger.debug("Did you mean one of the following: %s"%suggestions)
1111 self.add_param(lower_name, self.format_variable(UnknownType(value),
1112 UnknownType, name))
1113 self.lower_to_case[lower_name] = name
1114 if change_userdefine:
1115 self.user_set.add(lower_name)
1116 return
1117
1118 value = self.format_variable(value, targettype, name=name)
1119 dict.__setitem__(self, lower_name, value)
1120 if change_userdefine:
1121 self.user_set.add(lower_name)
1122
1123 - def add_param(self, name, value, system=False, comment=False):
1124 """add a default parameter to the class"""
1125
1126 lower_name = name.lower()
1127 if __debug__:
1128 if lower_name in self:
1129 raise Exception("Duplicate case for %s in %s" % (name,self.__class__))
1130
1131 dict.__setitem__(self, lower_name, value)
1132 self.lower_to_case[lower_name] = name
1133 if isinstance(value, list):
1134 if any([type(value[0]) != type(v) for v in value]):
1135 raise Exception, "All entry should have the same type"
1136 self.list_parameter.add(lower_name)
1137 elif isinstance(value, dict):
1138 allvalues = value.values()
1139 if any([type(allvalues[0]) != type(v) for v in allvalues]):
1140 raise Exception, "All entry should have the same type"
1141 self.dict_parameter[lower_name] = type(allvalues[0])
1142 if '__type__' in value:
1143 del value['__type__']
1144 dict.__setitem__(self, lower_name, value)
1145
1146
1147 if system:
1148 self.system_only.add(lower_name)
1149 if comment:
1150 self.comments[lower_name] = comment
1151
1153 """return a minimal help for the parameter"""
1154
1155 out = "## Information on parameter %s from class %s\n" % (name, self.__class__.__name__)
1156 if name.lower() in self:
1157 out += "## current value: %s (parameter should be of type %s)\n" % (self[name], type(self[name]))
1158 if name.lower() in self.comments:
1159 out += '## %s\n' % self.comments[name.lower()].replace('\n', '\n## ')
1160 else:
1161 out += "## Unknown for this class\n"
1162 if name.lower() in self.user_set:
1163 out += "## This value is considered as been set by the user\n"
1164 else:
1165 out += "## This value is considered as been set by the system\n"
1166 logger.info(out)
1167
1168 @staticmethod
1252
1253
1254
1256
1257 lower_name = name.lower()
1258 if __debug__:
1259 if lower_name not in self:
1260 if lower_name in [key.lower() for key in self] :
1261 raise Exception, "Some key are not lower case %s. Invalid use of the class!"\
1262 % [key for key in self if key.lower() != key]
1263
1264 if lower_name in self.auto_set:
1265 return 'auto'
1266
1267 return dict.__getitem__(self, name.lower())
1268
1269
1270 - def set(self, name, value, changeifuserset=True, user=False):
1271 """convenient way to change attribute.
1272 changeifuserset=False means that the value is NOT change is the value is not on default.
1273 user=True, means that the value will be marked as modified by the user
1274 (potentially preventing future change to the value)
1275 """
1276
1277
1278 if not changeifuserset:
1279 if name.lower() in self.user_set:
1280
1281 return
1282
1283 self.__setitem__(name, value, change_userdefine=user)
1284
1288 """A class to handle information which are passed from MadGraph to the madevent
1289 interface."""
1290
1292 """initialize the directory to the default value"""
1293
1294 self.add_param('loop_induced', False)
1295 self.add_param('has_isr', False)
1296 self.add_param('has_fsr', False)
1297 self.add_param('nb_channel', 0)
1298 self.add_param('nexternal', 0)
1299 self.add_param('ninitial', 0)
1300 self.add_param('grouped_matrix', True)
1301 self.add_param('has_loops', False)
1302 self.add_param('bias_module','None')
1303 self.add_param('max_n_matched_jets', 0)
1304 self.add_param('colored_pdgs', [1,2,3,4,5])
1305 self.add_param('complex_mass_scheme', False)
1306
1307 - def read(self, finput):
1308 """Read the input file, this can be a path to a file,
1309 a file object, a str with the content of the file."""
1310
1311 if isinstance(finput, str):
1312 if "\n" in finput:
1313 finput = finput.split('\n')
1314 elif os.path.isfile(finput):
1315 finput = open(finput)
1316 else:
1317 raise Exception, "No such file %s" % finput
1318
1319 for line in finput:
1320 if '#' in line:
1321 line = line.split('#',1)[0]
1322 if not line:
1323 continue
1324
1325 if '=' in line:
1326 key, value = line.split('=',1)
1327 self[key.strip()] = value
1328
1329 - def write(self, outputpath):
1330 """write the file"""
1331
1332 template ="# Information about the process #\n"
1333 template +="#########################################\n"
1334
1335 fsock = open(outputpath, 'w')
1336 fsock.write(template)
1337
1338 for key, value in self.items():
1339 fsock.write(" %s = %s \n" % (key, value))
1340
1341 fsock.close()
1342
1347 """an object for the GridpackCard"""
1348
1350 """default value for the GridpackCard"""
1351
1352 self.add_param("GridRun", True)
1353 self.add_param("gevents", 2500)
1354 self.add_param("gseed", 1)
1355 self.add_param("ngran", -1)
1356
1357 - def read(self, finput):
1358 """Read the input file, this can be a path to a file,
1359 a file object, a str with the content of the file."""
1360
1361 if isinstance(finput, str):
1362 if "\n" in finput:
1363 finput = finput.split('\n')
1364 elif os.path.isfile(finput):
1365 finput = open(finput)
1366 else:
1367 raise Exception, "No such file %s" % finput
1368
1369 for line in finput:
1370 line = line.split('#')[0]
1371 line = line.split('!')[0]
1372 line = line.split('=',1)
1373 if len(line) != 2:
1374 continue
1375 self[line[1].strip()] = line[0].replace('\'','').strip()
1376
1377 - def write(self, output_file, template=None):
1378 """Write the run_card in output_file according to template
1379 (a path to a valid run_card)"""
1380
1381 if not template:
1382 if not MADEVENT:
1383 template = pjoin(MG5DIR, 'Template', 'LO', 'Cards',
1384 'grid_card_default.dat')
1385 else:
1386 template = pjoin(MEDIR, 'Cards', 'grid_card_default.dat')
1387
1388
1389 text = ""
1390 for line in file(template,'r'):
1391 nline = line.split('#')[0]
1392 nline = nline.split('!')[0]
1393 comment = line[len(nline):]
1394 nline = nline.split('=')
1395 if len(nline) != 2:
1396 text += line
1397 elif nline[1].strip() in self:
1398 text += ' %s\t= %s %s' % (self[nline[1].strip()],nline[1], comment)
1399 else:
1400 logger.info('Adding missing parameter %s to current run_card (with default value)' % nline[1].strip())
1401 text += line
1402
1403 fsock = open(output_file,'w')
1404 fsock.write(text)
1405 fsock.close()
1406
1408 """ Implements the Pythia8 card."""
1409
1411 """ Placeholder function to allow overwriting in the PY8SubRun daughter.
1412 The initialization of the self.subruns attribute should of course not
1413 be performed in PY8SubRun."""
1414 if type == 'parameters':
1415 if "LHEFInputs:nSubruns" not in self:
1416 self.add_param("LHEFInputs:nSubruns", 1,
1417 hidden='ALWAYS_WRITTEN',
1418 comment="""
1419 ====================
1420 Subrun definitions
1421 ====================
1422 """)
1423 if type == 'attributes':
1424 if not(hasattr(self,'subruns')):
1425 first_subrun = PY8SubRun(subrun_id=0)
1426 self.subruns = dict([(first_subrun['Main:subrun'],first_subrun)])
1427
1429 """ Sets up the list of available PY8 parameters."""
1430
1431
1432
1433 self.add_param("Main:numberOfEvents", -1)
1434
1435
1436 self.add_param("JetMatching:qCut", -1.0, always_write_to_card=False)
1437 self.add_param("JetMatching:doShowerKt",False,always_write_to_card=False)
1438
1439 self.add_param("JetMatching:nJetMax", -1, always_write_to_card=False)
1440
1441 self.add_param("Merging:TMS", -1.0, always_write_to_card=False)
1442 self.add_param("Merging:Process", '<set_by_user>', always_write_to_card=False)
1443
1444 self.add_param("Merging:nJetMax", -1, always_write_to_card=False)
1445
1446
1447 self.add_param("SysCalc:fullCutVariation", False)
1448
1449
1450
1451 self.add_param("HEPMCoutput:file", 'auto')
1452
1453
1454
1455 self.add_param("Beams:frameType", 4,
1456 hidden=True,
1457 comment='Tell Pythia8 that an LHEF input is used.')
1458 self.add_param("HEPMCoutput:scaling", 1.0e9,
1459 hidden=True,
1460 comment='1.0 corresponds to HEPMC weight given in [mb]. We choose here the [pb] normalization.')
1461 self.add_param("Check:epTolErr", 1e-2,
1462 hidden=True,
1463 comment='Be more forgiving with momentum mismatches.')
1464
1465
1466 self.add_param("JetMatching:etaJetMax", 1000.0, hidden=True, always_write_to_card=True)
1467
1468
1469
1470 self.add_param("PDF:pSet", 'LHAPDF5:CT10.LHgrid', hidden=True, always_write_to_card=False,
1471 comment='Reminder: Parameter below is shower tune dependent.')
1472 self.add_param("SpaceShower:alphaSvalue", 0.118, hidden=True, always_write_to_card=False,
1473 comment='Reminder: Parameter below is shower tune dependent.')
1474 self.add_param("TimeShower:alphaSvalue", 0.118, hidden=True, always_write_to_card=False,
1475 comment='Reminder: Parameter below is shower tune dependent.')
1476 self.add_param("hadronlevel:all", True, hidden=True, always_write_to_card=False,
1477 comment='This allows to turn on/off hadronization alltogether.')
1478 self.add_param("partonlevel:mpi", True, hidden=True, always_write_to_card=False,
1479 comment='This allows to turn on/off MPI alltogether.')
1480 self.add_param("Beams:setProductionScalesFromLHEF", False, hidden=True,
1481 always_write_to_card=False,
1482 comment='This parameter is automatically set to True by MG5aMC when doing MLM merging with PY8.')
1483
1484
1485 self.add_param("JetMatching:merge", False, hidden=True, always_write_to_card=False,
1486 comment='Specifiy if we are merging sample of different multiplicity.')
1487 self.add_param("SysCalc:qCutList", [10.0,20.0], hidden=True, always_write_to_card=False)
1488 self['SysCalc:qCutList'] = 'auto'
1489 self.add_param("SysCalc:qWeed",-1.0,hidden=True, always_write_to_card=False,
1490 comment='Value of the merging scale below which one does not even write the HepMC event.')
1491 self.add_param("JetMatching:doVeto", False, hidden=True, always_write_to_card=False,
1492 comment='Do veto externally (e.g. in SysCalc).')
1493 self.add_param("JetMatching:scheme", 1, hidden=True, always_write_to_card=False)
1494 self.add_param("JetMatching:setMad", False, hidden=True, always_write_to_card=False,
1495 comment='Specify one must read inputs from the MadGraph banner.')
1496 self.add_param("JetMatching:coneRadius", 1.0, hidden=True, always_write_to_card=False)
1497 self.add_param("JetMatching:nQmatch",4,hidden=True, always_write_to_card=False)
1498
1499 self.add_param("TimeShower:pTmaxMatch", 2, hidden=True, always_write_to_card=False)
1500 self.add_param("SpaceShower:pTmaxMatch", 1, hidden=True, always_write_to_card=False)
1501 self.add_param("SysCalc:tmsList", [10.0,20.0], hidden=True, always_write_to_card=False)
1502 self['SysCalc:tmsList'] = 'auto'
1503 self.add_param("Merging:muFac", 91.188, hidden=True, always_write_to_card=False,
1504 comment='Set factorisation scales of the 2->2 process.')
1505 self.add_param("Merging:applyVeto", False, hidden=True, always_write_to_card=False,
1506 comment='Do veto externally (e.g. in SysCalc).')
1507 self.add_param("Merging:includeWeightInXsection", True, hidden=True, always_write_to_card=False,
1508 comment='If turned off, then the option belows forces PY8 to keep the original weight.')
1509 self.add_param("Merging:muRen", 91.188, hidden=True, always_write_to_card=False,
1510 comment='Set renormalization scales of the 2->2 process.')
1511 self.add_param("Merging:muFacInME", 91.188, hidden=True, always_write_to_card=False,
1512 comment='Set factorisation scales of the 2->2 Matrix Element.')
1513 self.add_param("Merging:muRenInME", 91.188, hidden=True, always_write_to_card=False,
1514 comment='Set renormalization scales of the 2->2 Matrix Element.')
1515 self.add_param("SpaceShower:rapidityOrder", False, hidden=True, always_write_to_card=False)
1516 self.add_param("Merging:nQuarksMerge",4,hidden=True, always_write_to_card=False)
1517
1518 self.add_param("Merging:mayRemoveDecayProducts", False, hidden=True, always_write_to_card=False)
1519 self.add_param("Merging:doKTMerging", False, hidden=True, always_write_to_card=False)
1520 self.add_param("Merging:Dparameter", 0.4, hidden=True, always_write_to_card=False)
1521 self.add_param("Merging:doPTLundMerging", False, hidden=True, always_write_to_card=False)
1522
1523
1524 self.add_param("BeamRemnants:primordialKT", True, hidden=True, always_write_to_card=False, comment="see http://home.thep.lu.se/~torbjorn/pythia82html/BeamRemnants.html")
1525 self.add_param("PartonLevel:Remnants", True, hidden=True, always_write_to_card=False, comment="Master switch for addition of beam remnants. Cannot be used to generate complete events")
1526 self.add_param("Check:event", True, hidden=True, always_write_to_card=False, comment="check physical sanity of the events")
1527 self.add_param("TimeShower:QEDshowerByQ", True, hidden=True, always_write_to_card=False, comment="Allow quarks to radiate photons for FSR, i.e. branchings q -> q gamma")
1528 self.add_param("TimeShower:QEDshowerByL", True, hidden=True, always_write_to_card=False, comment="Allow leptons to radiate photons for FSR, i.e. branchings l -> l gamma")
1529 self.add_param("SpaceShower:QEDshowerByQ", True, hidden=True, always_write_to_card=False, comment="Allow quarks to radiate photons for ISR, i.e. branchings q -> q gamma")
1530 self.add_param("SpaceShower:QEDshowerByL", True, hidden=True, always_write_to_card=False, comment="Allow leptons to radiate photonsfor ISR, i.e. branchings l -> l gamma")
1531 self.add_param("PartonLevel:FSRinResonances", True, hidden=True, always_write_to_card=False, comment="Do not allow shower to run from decay product of unstable particle")
1532 self.add_param("ProcessLevel:resonanceDecays", True, hidden=True, always_write_to_card=False, comment="Do not allow unstable particle to decay.")
1533
1534
1535
1536 self.add_default_subruns('parameters')
1537
1539
1540
1541
1542 self.hidden_param = []
1543 self.hidden_params_to_always_write = set()
1544 self.visible_params_to_always_write = set()
1545
1546 self.params_to_never_write = set()
1547
1548
1549
1550 self.system_set = set()
1551
1552
1553
1554 self.add_default_subruns('attributes')
1555
1556
1557 super(PY8Card, self).__init__(*args, **opts)
1558
1559 - def add_param(self, name, value, hidden=False, always_write_to_card=True,
1560 comment=None):
1561 """ add a parameter to the card. value is the default value and
1562 defines the type (int/float/bool/str) of the input.
1563 The option 'hidden' decides whether the parameter should be visible to the user.
1564 The option 'always_write_to_card' decides whether it should
1565 always be printed or only when it is system_set or user_set.
1566 The option 'comment' can be used to specify a comment to write above
1567 hidden parameters.
1568 """
1569 super(PY8Card, self).add_param(name, value, comment=comment)
1570 name = name.lower()
1571 if hidden:
1572 self.hidden_param.append(name)
1573 if always_write_to_card:
1574 self.hidden_params_to_always_write.add(name)
1575 else:
1576 if always_write_to_card:
1577 self.visible_params_to_always_write.add(name)
1578 if not comment is None:
1579 if not isinstance(comment, str):
1580 raise MadGraph5Error("Option 'comment' must be a string, not"+\
1581 " '%s'."%str(comment))
1582
1584 """Add a subrun to this PY8 Card."""
1585 assert(isinstance(py8_subrun,PY8SubRun))
1586 if py8_subrun['Main:subrun']==-1:
1587 raise MadGraph5Error, "Make sure to correctly set the subrun ID"+\
1588 " 'Main:subrun' *before* adding it to the PY8 Card."
1589 if py8_subrun['Main:subrun'] in self.subruns:
1590 raise MadGraph5Error, "A subrun with ID '%s'"%py8_subrun['Main:subrun']+\
1591 " is already present in this PY8 card. Remove it first, or "+\
1592 " access it directly."
1593 self.subruns[py8_subrun['Main:subrun']] = py8_subrun
1594 if not 'LHEFInputs:nSubruns' in self.user_set:
1595 self['LHEFInputs:nSubruns'] = max(self.subruns.keys())
1596
1597 - def userSet(self, name, value, **opts):
1598 """Set an attribute of this card, following a user_request"""
1599 self.__setitem__(name, value, change_userdefine=True, **opts)
1600 if name.lower() in self.system_set:
1601 self.system_set.remove(name.lower())
1602
1604 """ Forbid the writeout of a specific parameter of this card when the
1605 "write" function will be invoked."""
1606 self.params_to_never_write.add(name.lower())
1607
1609 """Set an attribute of this card, independently of a specific user
1610 request and only if not already user_set."""
1611 if name.lower() not in self.user_set:
1612 self.__setitem__(name, value, change_userdefine=False, **opts)
1613 self.system_set.add(name.lower())
1614
1616 """ Sets a card attribute, but only if it is absent or not already
1617 user_set."""
1618 if name.lower() not in self or name.lower() not in self.user_set:
1619 self.__setitem__(name, value, change_userdefine=False, **opts)
1620 self.system_set.add(name.lower())
1621
1624
1625 @staticmethod
1676
1677
1678 - def write(self, output_file, template, read_subrun=False,
1679 print_only_visible=False, direct_pythia_input=False, add_missing=True):
1680 """ Write the card to output_file using a specific template.
1681 > 'print_only_visible' specifies whether or not the hidden parameters
1682 should be written out if they are in the hidden_params_to_always_write
1683 list and system_set.
1684 > If 'direct_pythia_input' is true, then visible parameters which are not
1685 in the self.visible_params_to_always_write list and are not user_set
1686 or system_set are commented.
1687 > If 'add_missing' is False then parameters that should be written_out but are absent
1688 from the template will not be written out."""
1689
1690
1691 visible_param = [p for p in self if p.lower() not in self.hidden_param
1692 or p.lower() in self.user_set]
1693
1694 visible_param = [p for p in visible_param if p.lower() not in self.params_to_never_write]
1695
1696
1697 if print_only_visible:
1698 hidden_output_param = []
1699 else:
1700 hidden_output_param = [p for p in self if p.lower() in self.hidden_param and
1701 not p.lower() in self.user_set and
1702 (p.lower() in self.hidden_params_to_always_write or
1703 p.lower() in self.system_set)]
1704
1705 hidden_output_param = [p for p in hidden_output_param if p not in self.params_to_never_write]
1706
1707 if print_only_visible:
1708 subruns = []
1709 else:
1710 if not read_subrun:
1711 subruns = sorted(self.subruns.keys())
1712
1713
1714
1715 subruns_to_write = {}
1716
1717
1718
1719 def group_params(params):
1720 if len(params)==0:
1721 return []
1722 groups = {}
1723 for p in params:
1724 try:
1725 groups[':'.join(p.split(':')[:-1])].append(p)
1726 except KeyError:
1727 groups[':'.join(p.split(':')[:-1])] = [p,]
1728 res = sum(groups.values(),[])
1729
1730 if 'Main:subrun' in res:
1731 res.insert(0,res.pop(res.index('Main:subrun')))
1732
1733 if 'LHEFInputs:nSubruns' in res:
1734 res.append(res.pop(res.index('LHEFInputs:nSubruns')))
1735 return res
1736
1737 visible_param = group_params(visible_param)
1738 hidden_output_param = group_params(hidden_output_param)
1739
1740
1741
1742 output = StringIO.StringIO()
1743
1744
1745 if isinstance(template, str):
1746 if os.path.isfile(template):
1747 tmpl = open(template, 'r')
1748 elif '\n' in template:
1749 tmpl = StringIO.StringIO(template)
1750 else:
1751 raise Exception, "File input '%s' not found." % file_input
1752 elif template is None:
1753
1754 tmpl = StringIO.StringIO()
1755 elif isinstance(template, (StringIO.StringIO, file)):
1756 tmpl = template
1757 else:
1758 raise MadGraph5Error("Incorrect type for argument 'template': %s"%
1759 template.__class__.__name__)
1760
1761
1762 last_pos = tmpl.tell()
1763 line = tmpl.readline()
1764 started_subrun_reading = False
1765 while line!='':
1766
1767 if line.strip().startswith('!') or line.strip().startswith('\n'):
1768 output.write(line)
1769
1770 last_pos = tmpl.tell()
1771 line = tmpl.readline()
1772 continue
1773
1774 try:
1775 param_entry, value_entry = line.split('=')
1776 param = param_entry.strip()
1777 value = value_entry.strip()
1778 except ValueError:
1779 line = line.replace('\n','')
1780 raise MadGraph5Error, "Could not read line '%s' of Pythia8 card."%\
1781 line
1782
1783 if param=='Main:subrun':
1784 if read_subrun:
1785 if not started_subrun_reading:
1786
1787 started_subrun_reading = True
1788 else:
1789
1790 tmpl.seek(last_pos)
1791 break
1792 else:
1793
1794 tmpl.seek(last_pos)
1795 subruns_to_write[int(value)] = StringIO.StringIO()
1796 if int(value) in subruns:
1797 self.subruns[int(value)].write(subruns_to_write[int(value)],
1798 tmpl,read_subrun=True)
1799
1800 subruns.pop(subruns.index(int(value)))
1801 else:
1802
1803 DummySubrun=PY8SubRun()
1804
1805 DummySubrun.clear()
1806 DummySubrun.write(subruns_to_write[int(value)],
1807 tmpl, read_subrun=True,
1808 print_only_visible=print_only_visible,
1809 direct_pythia_input=direct_pythia_input)
1810
1811 logger.info('Adding new unknown subrun with ID %d.'%
1812 int(value))
1813
1814 last_pos = tmpl.tell()
1815 line = tmpl.readline()
1816 continue
1817
1818
1819 if param in visible_param:
1820 new_value = PY8Card.pythia8_formatting(self[param])
1821 visible_param.pop(visible_param.index(param))
1822 elif param in hidden_output_param:
1823 new_value = PY8Card.pythia8_formatting(self[param])
1824 hidden_output_param.pop(hidden_output_param.index(param))
1825 else:
1826
1827 if param.lower() not in self.params_to_never_write:
1828 output.write(line)
1829 else:
1830 output.write('! The following parameter was forced to be commented out by MG5aMC.\n')
1831 output.write('! %s'%line)
1832
1833 last_pos = tmpl.tell()
1834 line = tmpl.readline()
1835 continue
1836
1837
1838
1839
1840
1841 if ((not direct_pythia_input) or
1842 (param.lower() in self.visible_params_to_always_write) or
1843 (param.lower() in self.user_set) or
1844 (param.lower() in self.system_set)):
1845 template = '%s=%s'
1846 else:
1847
1848
1849
1850 template = '!%s=%s'
1851
1852 output.write(template%(param_entry,
1853 value_entry.replace(value,new_value)))
1854
1855
1856 last_pos = tmpl.tell()
1857 line = tmpl.readline()
1858
1859
1860 if not add_missing:
1861 visible_param = []
1862 hidden_output_param = []
1863
1864
1865 if len(visible_param)>0 and not template is None:
1866 output.write(
1867 """!
1868 ! Additional general parameters%s.
1869 !
1870 """%(' for subrun %d'%self['Main:subrun'] if 'Main:subrun' in self else ''))
1871 for param in visible_param:
1872 value = PY8Card.pythia8_formatting(self[param])
1873 output.write('%s=%s\n'%(param,value))
1874 if template is None:
1875 if param=='Main:subrun':
1876 output.write(
1877 """!
1878 ! Definition of subrun %d
1879 !
1880 """%self['Main:subrun'])
1881 elif param.lower() not in self.hidden_param:
1882 logger.debug('Adding parameter %s (missing in the template) to current '+\
1883 'pythia8 card (with value %s)',param, value)
1884
1885 if len(hidden_output_param)>0 and not template is None:
1886 output.write(
1887 """!
1888 ! Additional technical parameters%s set by MG5_aMC.
1889 !
1890 """%(' for subrun %d'%self['Main:subrun'] if 'Main:subrun' in self else ''))
1891 for param in hidden_output_param:
1892 if param.lower() in self.comments:
1893 comment = '\n'.join('! %s'%c for c in
1894 self.comments[param.lower()].split('\n'))
1895 output.write(comment+'\n')
1896 output.write('%s=%s\n'%(param,PY8Card.pythia8_formatting(self[param])))
1897
1898
1899
1900 if read_subrun:
1901 output_file.write(output.getvalue())
1902 return
1903
1904
1905 for subrunID in subruns:
1906 new_subrun = StringIO.StringIO()
1907 self.subruns[subrunID].write(new_subrun,None,read_subrun=True)
1908 subruns_to_write[subrunID] = new_subrun
1909
1910
1911 for subrunID in sorted(subruns_to_write):
1912 output.write(subruns_to_write[subrunID].getvalue())
1913
1914
1915
1916 if 'LHEFInputs:nSubruns'.lower() not in self.user_set and \
1917 len(subruns_to_write)>0 and self['LHEFInputs:nSubruns']<\
1918 max(subruns_to_write.keys()):
1919 logger.info("Updating PY8 parameter 'LHEFInputs:nSubruns' to "+
1920 "%d so as to cover all defined subruns."%max(subruns_to_write.keys()))
1921 self['LHEFInputs:nSubruns'] = max(subruns_to_write.keys())
1922 output = StringIO.StringIO()
1923 self.write(output,template,print_only_visible=print_only_visible)
1924
1925
1926 if isinstance(output_file, str):
1927 out = open(output_file,'w')
1928 out.write(output.getvalue())
1929 out.close()
1930 else:
1931 output_file.write(output.getvalue())
1932
1933 - def read(self, file_input, read_subrun=False, setter='default'):
1934 """Read the input file, this can be a path to a file,
1935 a file object, a str with the content of the file.
1936 The setter option choses the authority that sets potential
1937 modified/new parameters. It can be either:
1938 'default' or 'user' or 'system'"""
1939 if isinstance(file_input, str):
1940 if "\n" in file_input:
1941 finput = StringIO.StringIO(file_input)
1942 elif os.path.isfile(file_input):
1943 finput = open(file_input)
1944 else:
1945 raise Exception, "File input '%s' not found." % file_input
1946 elif isinstance(file_input, (StringIO.StringIO, file)):
1947 finput = file_input
1948 else:
1949 raise MadGraph5Error("Incorrect type for argument 'file_input': %s"%
1950 file_inp .__class__.__name__)
1951
1952
1953 last_pos = finput.tell()
1954 line = finput.readline()
1955 started_subrun_reading = False
1956 while line!='':
1957
1958 if line.strip().startswith('!') or line.strip()=='':
1959
1960 last_pos = finput.tell()
1961 line = finput.readline()
1962 continue
1963
1964 try:
1965 param, value = line.split('=',1)
1966 param = param.strip()
1967 value = value.strip()
1968 except ValueError:
1969 line = line.replace('\n','')
1970 raise MadGraph5Error, "Could not read line '%s' of Pythia8 card."%\
1971 line
1972
1973 if param=='Main:subrun':
1974 if read_subrun:
1975 if not started_subrun_reading:
1976
1977 started_subrun_reading = True
1978 else:
1979
1980 finput.seek(last_pos)
1981 return
1982 else:
1983
1984 finput.seek(last_pos)
1985 if int(value) in self.subruns:
1986 self.subruns[int(value)].read(finput,read_subrun=True,
1987 setter=setter)
1988 else:
1989
1990 NewSubrun=PY8SubRun()
1991 NewSubrun.read(finput,read_subrun=True, setter=setter)
1992 self.add_subrun(NewSubrun)
1993
1994
1995 last_pos = finput.tell()
1996 line = finput.readline()
1997 continue
1998
1999
2000
2001
2002
2003 if setter == 'user':
2004 self.userSet(param,value)
2005 elif setter == 'system':
2006 self.systemSet(param,value)
2007 else:
2008 self.defaultSet(param,value)
2009
2010
2011 last_pos = finput.tell()
2012 line = finput.readline()
2013
2015 """ Class to characterize a specific PY8 card subrun section. """
2016
2018 """ Overloading of the homonym function called in the __init__ of PY8Card.
2019 The initialization of the self.subruns attribute should of course not
2020 be performed in PY8SubRun."""
2021 pass
2022
2024 """ Initialize a subrun """
2025
2026
2027 subrunID = -1
2028 if 'subrun_id' in opts:
2029 subrunID = opts.pop('subrun_id')
2030
2031 super(PY8SubRun, self).__init__(*args, **opts)
2032 self['Main:subrun']=subrunID
2033
2035 """Sets up the list of available PY8SubRun parameters."""
2036
2037
2038 super(PY8SubRun, self).default_setup()
2039
2040 self.hidden_param = [k.lower() for k in self.keys()]
2041 self.hidden_params_to_always_write = set()
2042 self.visible_params_to_always_write = set()
2043
2044
2045 self.add_param("Main:subrun", -1)
2046 self.add_param("Beams:LHEF", "events.lhe.gz")
2047
2049
2050 filename = 'run_card'
2051
2052 - def __new__(cls, finput=None, **opt):
2053 if cls is RunCard:
2054 if not finput:
2055 target_class = RunCardLO
2056 elif isinstance(finput, cls):
2057 target_class = finput.__class__
2058 elif isinstance(finput, str):
2059 if '\n' not in finput:
2060 finput = open(finput).read()
2061 if 'req_acc_FO' in finput:
2062 target_class = RunCardNLO
2063 else:
2064 target_class = RunCardLO
2065 else:
2066 return None
2067 return super(RunCard, cls).__new__(target_class, finput, **opt)
2068 else:
2069 return super(RunCard, cls).__new__(cls, finput, **opt)
2070
2072
2073
2074
2075
2076 self.hidden_param = []
2077
2078 self.includepath = collections.defaultdict(list)
2079
2080 self.fortran_name = {}
2081
2082 self.legacy_parameter = {}
2083
2084 self.cuts_parameter = []
2085
2086 self.system_default = {}
2087
2088
2089
2090
2091 super(RunCard, self).__init__(*args, **opts)
2092
2093 - def add_param(self, name, value, fortran_name=None, include=True,
2094 hidden=False, legacy=False, cut=False, system=False, sys_default=None,
2095 **opts):
2096 """ add a parameter to the card. value is the default value and
2097 defines the type (int/float/bool/str) of the input.
2098 fortran_name defines what is the associate name in the f77 code
2099 include defines if we have to put the value in the include file
2100 hidden defines if the parameter is expected to be define by the user.
2101 legacy:Parameter which is not used anymore (raise a warning if not default)
2102 cut: defines the list of cut parameter to allow to set them all to off.
2103 sys_default: default used if the parameter is not in the card
2104 """
2105
2106 super(RunCard, self).add_param(name, value, system=system,**opts)
2107 name = name.lower()
2108 if fortran_name:
2109 self.fortran_name[name] = fortran_name
2110 if legacy:
2111 self.legacy_parameter[name] = value
2112 include = False
2113 if include is True:
2114 self.includepath[True].append(name)
2115 elif include:
2116 self.includepath[include].append(name)
2117 if hidden or system:
2118 self.hidden_param.append(name)
2119 if cut:
2120 self.cuts_parameter.append(name)
2121 if sys_default is not None:
2122 self.system_default[name] = sys_default
2123
2124
2125
2126 - def read(self, finput, consistency=True):
2127 """Read the input file, this can be a path to a file,
2128 a file object, a str with the content of the file."""
2129
2130 if isinstance(finput, str):
2131 if "\n" in finput:
2132 finput = finput.split('\n')
2133 elif os.path.isfile(finput):
2134 finput = open(finput)
2135 else:
2136 raise Exception, "No such file %s" % finput
2137
2138 for line in finput:
2139 line = line.split('#')[0]
2140 line = line.split('!')[0]
2141 line = line.rsplit('=',1)
2142 if len(line) != 2:
2143 continue
2144 value, name = line
2145 name = name.lower().strip()
2146 if name not in self and ('min' in name or 'max' in name):
2147
2148 self.add_param(name, float(value), hidden=True, cut=True)
2149 else:
2150 self.set( name, value, user=True)
2151
2152 if consistency:
2153 try:
2154 self.check_validity()
2155 except InvalidRunCard, error:
2156 if consistency == 'warning':
2157 logger.warning(str(error))
2158 else:
2159 raise
2160
2161
2162 - def write(self, output_file, template=None, python_template=False):
2163 """Write the run_card in output_file according to template
2164 (a path to a valid run_card)"""
2165
2166 to_write = set(self.user_set)
2167 if not template:
2168 raise Exception
2169
2170 if python_template and not to_write:
2171 if not self.list_parameter:
2172 text = file(template,'r').read() % self
2173 else:
2174 data = dict(self)
2175 for name in self.list_parameter:
2176 data[name] = ', '.join(str(v) for v in data[name])
2177 text = file(template,'r').read() % data
2178 else:
2179 text = ""
2180 for line in file(template,'r'):
2181 nline = line.split('#')[0]
2182 nline = nline.split('!')[0]
2183 comment = line[len(nline):]
2184 nline = nline.split('=')
2185 if len(nline) != 2:
2186 text += line
2187 elif nline[1].strip() in self:
2188 name = nline[1].strip().lower()
2189 value = self[name]
2190 if name in self.list_parameter:
2191 value = ', '.join([str(v) for v in value])
2192 if python_template:
2193 text += line % {nline[1].strip():value, name:value}
2194 else:
2195 if not comment or comment[-1]!='\n':
2196 endline = '\n'
2197 else:
2198 endline = ''
2199 text += ' %s\t= %s %s%s' % (value, name, comment, endline)
2200
2201 if name.lower() in to_write:
2202 to_write.remove(nline[1].strip().lower())
2203 else:
2204 logger.info('Adding missing parameter %s to current %s (with default value)',
2205 (name, self.filename))
2206 text += line
2207
2208 if to_write:
2209 text+="""#*********************************************************************
2210 # Additional parameter
2211 #*********************************************************************
2212 """
2213
2214 for key in to_write:
2215 text += ' %s\t= %s # %s\n' % (self[key], key, 'hidden parameter')
2216
2217 if isinstance(output_file, str):
2218 fsock = open(output_file,'w')
2219 fsock.write(text)
2220 fsock.close()
2221 else:
2222 output_file.write(text)
2223
2224
2225 - def get_default(self, name, default=None, log_level=None):
2226 """return self[name] if exist otherwise default. log control if we
2227 put a warning or not if we use the default value"""
2228
2229 lower_name = name.lower()
2230 if lower_name not in self.user_set:
2231 if log_level is None:
2232 if lower_name in self.system_only:
2233 log_level = 5
2234 elif lower_name in self.auto_set:
2235 log_level = 5
2236 elif lower_name in self.hidden_param:
2237 log_level = 10
2238 else:
2239 log_level = 20
2240 if not default:
2241 default = dict.__getitem__(self, name.lower())
2242 logger.log(log_level, '%s missed argument %s. Takes default: %s'
2243 % (self.filename, name, default))
2244 self[name] = default
2245 return default
2246 else:
2247 return self[name]
2248
2249 @staticmethod
2255
2256 @staticmethod
2305
2306
2308 """check that parameter missing in the card are set to the expected value"""
2309
2310 for name, value in self.system_default.items():
2311 self.set(name, value, changeifuserset=False)
2312
2313 default_include_file = 'run_card.inc'
2314
2316 """Write the various include file in output_dir.
2317 The entry True of self.includepath will be written in run_card.inc
2318 The entry False will not be written anywhere"""
2319
2320
2321 self.check_validity()
2322
2323 for incname in self.includepath:
2324 if incname is True:
2325 pathinc = self.default_include_file
2326 else:
2327 pathinc = incname
2328
2329 fsock = file_writers.FortranWriter(pjoin(output_dir,pathinc))
2330 for key in self.includepath[incname]:
2331
2332 if key in self.fortran_name:
2333 fortran_name = self.fortran_name[key]
2334 else:
2335 fortran_name = key
2336
2337
2338 value = self.get_default(key)
2339
2340
2341 if isinstance(value, list):
2342
2343
2344
2345 if isinstance(value[0], bool):
2346 pass
2347 elif isinstance(value[0], int):
2348 line = '%s(%s) = %s \n' % (fortran_name, 0, self.f77_formatting(len(value)))
2349 fsock.writelines(line)
2350 elif isinstance(value[0], float):
2351 line = '%s(%s) = %s \n' % (fortran_name, 0, self.f77_formatting(float(len(value))))
2352 fsock.writelines(line)
2353
2354 for i,v in enumerate(value):
2355 line = '%s(%s) = %s \n' % (fortran_name, i+1, self.f77_formatting(v))
2356 fsock.writelines(line)
2357 elif isinstance(value, dict):
2358 for fortran_name, onevalue in value.items():
2359 line = '%s = %s \n' % (fortran_name, self.f77_formatting(onevalue))
2360 fsock.writelines(line)
2361 else:
2362 line = '%s = %s \n' % (fortran_name, self.f77_formatting(value))
2363 fsock.writelines(line)
2364 fsock.close()
2365
2366
2384
2385
2386 output["idbmup1"] = get_idbmup(self['lpp1'])
2387 output["idbmup2"] = get_idbmup(self['lpp2'])
2388 output["ebmup1"] = self["ebeam1"]
2389 output["ebmup2"] = self["ebeam2"]
2390 output["pdfgup1"] = 0
2391 output["pdfgup2"] = 0
2392 output["pdfsup1"] = self.get_pdf_id(self["pdlabel"])
2393 output["pdfsup2"] = self.get_pdf_id(self["pdlabel"])
2394 return output
2395
2397 if pdf == "lhapdf":
2398 lhaid = self["lhaid"]
2399 if isinstance(lhaid, list):
2400 return lhaid[0]
2401 else:
2402 return lhaid
2403 else:
2404 return {'none': 0, 'mrs02nl':20250, 'mrs02nn':20270, 'cteq4_m': 19150,
2405 'cteq4_l':19170, 'cteq4_d':19160, 'cteq5_m':19050,
2406 'cteq5_d':19060,'cteq5_l':19070,'cteq5m1':19051,
2407 'cteq6_m':10000,'cteq6_l':10041,'cteq6l1':10042,
2408 'nn23lo':246800,'nn23lo1':247000,'nn23nlo':244800
2409 }[pdf]
2410
2413
2415 """remove all the cut"""
2416
2417 for name in self.cuts_parameter:
2418 targettype = type(self[name])
2419 if targettype == bool:
2420 self[name] = False
2421 elif 'min' in name:
2422 self[name] = 0
2423 elif 'max' in name:
2424 self[name] = -1
2425 elif 'eta' in name:
2426 self[name] = -1
2427 else:
2428 self[name] = 0
2429
2431 """an object to handle in a nice way the run_card information"""
2432
2434 """default value for the run_card.dat"""
2435
2436 self.add_param("run_tag", "tag_1", include=False)
2437 self.add_param("gridpack", False)
2438 self.add_param("time_of_flight", -1.0, include=False, hidden=True)
2439 self.add_param("nevents", 10000)
2440 self.add_param("iseed", 0)
2441 self.add_param("lpp1", 1, fortran_name="lpp(1)")
2442 self.add_param("lpp2", 1, fortran_name="lpp(2)")
2443 self.add_param("ebeam1", 6500.0, fortran_name="ebeam(1)")
2444 self.add_param("ebeam2", 6500.0, fortran_name="ebeam(2)")
2445 self.add_param("polbeam1", 0.0, fortran_name="pb1")
2446 self.add_param("polbeam2", 0.0, fortran_name="pb2")
2447 self.add_param("pdlabel", "nn23lo1")
2448 self.add_param("lhaid", 230000, hidden=True)
2449 self.add_param("fixed_ren_scale", False)
2450 self.add_param("fixed_fac_scale", False)
2451 self.add_param("scale", 91.1880)
2452 self.add_param("dsqrt_q2fact1", 91.1880, fortran_name="sf1")
2453 self.add_param("dsqrt_q2fact2", 91.1880, fortran_name="sf2")
2454 self.add_param("dynamical_scale_choice", -1)
2455
2456
2457 self.add_param("bias_module", 'None', include=False)
2458 self.add_param('bias_parameters', {'__type__':1.0}, include='BIAS/bias.inc')
2459
2460
2461 self.add_param("scalefact", 1.0)
2462 self.add_param("ickkw", 0, comment="\'0\' for standard fixed order computation.\n\'1\' for MLM merging activates alphas and pdf re-weighting according to a kt clustering of the QCD radiation.")
2463 self.add_param("highestmult", 1, fortran_name="nhmult", hidden=True)
2464 self.add_param("ktscheme", 1, hidden=True)
2465 self.add_param("alpsfact", 1.0)
2466 self.add_param("chcluster", False, hidden=True)
2467 self.add_param("pdfwgt", True, hidden=True)
2468 self.add_param("asrwgtflavor", 5)
2469 self.add_param("clusinfo", True)
2470 self.add_param("lhe_version", 3.0)
2471 self.add_param("event_norm", "average", include=False, sys_default='sum')
2472
2473 self.add_param("auto_ptj_mjj", False)
2474 self.add_param("bwcutoff", 15.0)
2475 self.add_param("cut_decays", False)
2476 self.add_param("nhel", 0, include=False)
2477
2478 self.add_param("ptj", 20.0, cut=True)
2479 self.add_param("ptb", 0.0, cut=True)
2480 self.add_param("pta", 10.0, cut=True)
2481 self.add_param("ptl", 10.0, cut=True)
2482 self.add_param("misset", 0.0, cut=True)
2483 self.add_param("ptheavy", 0.0, cut=True, comment='this cut apply on particle heavier than 10 GeV')
2484 self.add_param("ptonium", 1.0, legacy=True)
2485 self.add_param("ptjmax", -1.0, cut=True)
2486 self.add_param("ptbmax", -1.0, cut=True)
2487 self.add_param("ptamax", -1.0, cut=True)
2488 self.add_param("ptlmax", -1.0, cut=True)
2489 self.add_param("missetmax", -1.0, cut=True)
2490
2491 self.add_param("ej", 0.0, cut=True)
2492 self.add_param("eb", 0.0, cut=True)
2493 self.add_param("ea", 0.0, cut=True)
2494 self.add_param("el", 0.0, cut=True)
2495 self.add_param("ejmax", -1.0, cut=True)
2496 self.add_param("ebmax", -1.0, cut=True)
2497 self.add_param("eamax", -1.0, cut=True)
2498 self.add_param("elmax", -1.0, cut=True)
2499
2500 self.add_param("etaj", 5.0, cut=True)
2501 self.add_param("etab", -1.0, cut=True)
2502 self.add_param("etaa", 2.5, cut=True)
2503 self.add_param("etal", 2.5, cut=True)
2504 self.add_param("etaonium", 0.6, legacy=True)
2505 self.add_param("etajmin", 0.0, cut=True)
2506 self.add_param("etabmin", 0.0, cut=True)
2507 self.add_param("etaamin", 0.0, cut=True)
2508 self.add_param("etalmin", 0.0, cut=True)
2509
2510 self.add_param("drjj", 0.4, cut=True)
2511 self.add_param("drbb", 0.0, cut=True)
2512 self.add_param("drll", 0.4, cut=True)
2513 self.add_param("draa", 0.4, cut=True)
2514 self.add_param("drbj", 0.0, cut=True)
2515 self.add_param("draj", 0.4, cut=True)
2516 self.add_param("drjl", 0.4, cut=True)
2517 self.add_param("drab", 0.0, cut=True)
2518 self.add_param("drbl", 0.0, cut=True)
2519 self.add_param("dral", 0.4, cut=True)
2520 self.add_param("drjjmax", -1.0, cut=True)
2521 self.add_param("drbbmax", -1.0, cut=True)
2522 self.add_param("drllmax", -1.0, cut=True)
2523 self.add_param("draamax", -1.0, cut=True)
2524 self.add_param("drbjmax", -1.0, cut=True)
2525 self.add_param("drajmax", -1.0, cut=True)
2526 self.add_param("drjlmax", -1.0, cut=True)
2527 self.add_param("drabmax", -1.0, cut=True)
2528 self.add_param("drblmax", -1.0, cut=True)
2529 self.add_param("dralmax", -1.0, cut=True)
2530
2531 self.add_param("mmjj", 0.0, cut=True)
2532 self.add_param("mmbb", 0.0, cut=True)
2533 self.add_param("mmaa", 0.0, cut=True)
2534 self.add_param("mmll", 0.0, cut=True)
2535 self.add_param("mmjjmax", -1.0, cut=True)
2536 self.add_param("mmbbmax", -1.0, cut=True)
2537 self.add_param("mmaamax", -1.0, cut=True)
2538 self.add_param("mmllmax", -1.0, cut=True)
2539 self.add_param("mmnl", 0.0, cut=True)
2540 self.add_param("mmnlmax", -1.0, cut=True)
2541
2542 self.add_param("ptllmin", 0.0, cut=True)
2543 self.add_param("ptllmax", -1.0, cut=True)
2544 self.add_param("xptj", 0.0, cut=True)
2545 self.add_param("xptb", 0.0, cut=True)
2546 self.add_param("xpta", 0.0, cut=True)
2547 self.add_param("xptl", 0.0, cut=True)
2548
2549 self.add_param("ptj1min", 0.0, cut=True)
2550 self.add_param("ptj1max", -1.0, cut=True)
2551 self.add_param("ptj2min", 0.0, cut=True)
2552 self.add_param("ptj2max", -1.0, cut=True)
2553 self.add_param("ptj3min", 0.0, cut=True)
2554 self.add_param("ptj3max", -1.0, cut=True)
2555 self.add_param("ptj4min", 0.0, cut=True)
2556 self.add_param("ptj4max", -1.0, cut=True)
2557 self.add_param("cutuse", 0, cut=True)
2558
2559 self.add_param("ptl1min", 0.0, cut=True)
2560 self.add_param("ptl1max", -1.0, cut=True)
2561 self.add_param("ptl2min", 0.0, cut=True)
2562 self.add_param("ptl2max", -1.0, cut=True)
2563 self.add_param("ptl3min", 0.0, cut=True)
2564 self.add_param("ptl3max", -1.0, cut=True)
2565 self.add_param("ptl4min", 0.0, cut=True)
2566 self.add_param("ptl4max", -1.0, cut=True)
2567
2568 self.add_param("htjmin", 0.0, cut=True)
2569 self.add_param("htjmax", -1.0, cut=True)
2570 self.add_param("ihtmin", 0.0, cut=True)
2571 self.add_param("ihtmax", -1.0, cut=True)
2572 self.add_param("ht2min", 0.0, cut=True)
2573 self.add_param("ht3min", 0.0, cut=True)
2574 self.add_param("ht4min", 0.0, cut=True)
2575 self.add_param("ht2max", -1.0, cut=True)
2576 self.add_param("ht3max", -1.0, cut=True)
2577 self.add_param("ht4max", -1.0, cut=True)
2578
2579 self.add_param("ptgmin", 0.0, cut=True)
2580 self.add_param("r0gamma", 0.4)
2581 self.add_param("xn", 1.0)
2582 self.add_param("epsgamma", 1.0)
2583 self.add_param("isoem", True)
2584 self.add_param("xetamin", 0.0, cut=True)
2585 self.add_param("deltaeta", 0.0, cut=True)
2586 self.add_param("ktdurham", -1.0, fortran_name="kt_durham", cut=True)
2587 self.add_param("dparameter", 0.4, fortran_name="d_parameter", cut=True)
2588 self.add_param("ptlund", -1.0, fortran_name="pt_lund", cut=True)
2589 self.add_param("pdgs_for_merging_cut", [21, 1, 2, 3, 4, 5, 6])
2590 self.add_param("maxjetflavor", 4)
2591 self.add_param("xqcut", 0.0, cut=True)
2592 self.add_param("use_syst", True)
2593 self.add_param('systematics_program', 'auto', include=False, hidden=True, comment='Choose which program to use for systematics computation: none, systematics, syscalc')
2594 self.add_param('systematics_arguments', [''], include=False, hidden=True, comment='Choose the argment to pass to the systematics command. like --mur=0.25,1,4. Look at the help of the systematics function for more details.')
2595
2596 self.add_param("sys_scalefact", "0.5 1 2", include=False)
2597 self.add_param("sys_alpsfact", "None", include=False)
2598 self.add_param("sys_matchscale", "auto", include=False)
2599 self.add_param("sys_pdf", "NNPDF23_lo_as_0130_qed", include=False)
2600 self.add_param("sys_scalecorrelation", -1, include=False)
2601
2602
2603 self.add_param('gridrun', False, hidden=True)
2604 self.add_param('fixed_couplings', True, hidden=True)
2605 self.add_param('mc_grouped_subproc', True, hidden=True)
2606 self.add_param('xmtcentral', 0.0, hidden=True, fortran_name="xmtc")
2607 self.add_param('d', 1.0, hidden=True)
2608 self.add_param('gseed', 0, hidden=True, include=False)
2609 self.add_param('issgridfile', '', hidden=True)
2610
2611 self.add_param('job_strategy', 0, hidden=True, include=False)
2612 self.add_param('survey_splitting', -1, hidden=True, include=False)
2613 self.add_param('refine_evt_by_job', -1, hidden=True, include=False)
2614
2615
2617 """ """
2618
2619 super(RunCardLO, self).check_validity()
2620
2621
2622
2623
2624 if 'nhel' not in self.user_set:
2625 raise InvalidRunCard, "Parameter nhel is not defined in the run_card."
2626 if self['nhel'] not in [1,0]:
2627 raise InvalidRunCard, "Parameter nhel can only be '0' or '1', "+\
2628 "not %s." % self['nhel']
2629 if int(self['maxjetflavor']) > 6:
2630 raise InvalidRunCard, 'maxjetflavor should be lower than 5! (6 is partly supported)'
2631
2632 if len(self['pdgs_for_merging_cut']) > 1000:
2633 raise InvalidRunCard, "The number of elements in "+\
2634 "'pdgs_for_merging_cut' should not exceed 1000."
2635
2636
2637 if self['ptgmin'] > 0:
2638 if self['pta'] > 0:
2639 logger.warning('pta cut discarded since photon isolation is used')
2640 self['pta'] = 0.0
2641 if self['draj'] > 0:
2642 logger.warning('draj cut discarded since photon isolation is used')
2643 self['draj'] = 0.0
2644
2645
2646 if self['gridrun']:
2647 self['iseed'] = self['gseed']
2648
2649
2650 if self['use_syst']:
2651 if self['scalefact'] != 1.0:
2652 logger.warning('Since use_syst=T, We change the value of \'scalefact\' to 1')
2653 self['scalefact'] = 1.0
2654
2655
2656 if self['ickkw'] > 0:
2657 if self['ickkw'] != 1:
2658 logger.critical('ickkw >1 is pure alpha and only partly implemented.')
2659 import madgraph.interface.extended_cmd as basic_cmd
2660 answer = basic_cmd.smart_input('Do you really want to continue', allow_arg=['y','n'], default='n')
2661 if answer !='y':
2662 raise InvalidRunCard, 'ickkw>1 is still in alpha'
2663 if self['use_syst']:
2664
2665 if self['alpsfact'] != 1.0:
2666 logger.warning('Since use_syst=T, We change the value of \'alpsfact\' to 1')
2667 self['alpsfact'] =1.0
2668 if self['maxjetflavor'] == 6:
2669 raise InvalidRunCard, 'maxjetflavor at 6 is NOT supported for matching!'
2670 if self['ickkw'] == 2:
2671
2672 self.get_default('highestmult', log_level=20)
2673 self.get_default('issgridfile', 'issudgrid.dat', log_level=20)
2674 if self['xqcut'] > 0:
2675 if self['ickkw'] == 0:
2676 logger.error('xqcut>0 but ickkw=0. Potentially not fully consistent setup. Be carefull')
2677 import time
2678 time.sleep(5)
2679 if self['drjj'] != 0:
2680 logger.warning('Since icckw>0, We change the value of \'drjj\' to 0')
2681 self['drjj'] = 0
2682 if self['drjl'] != 0:
2683 logger.warning('Since icckw>0, We change the value of \'drjl\' to 0')
2684 self['drjl'] = 0
2685 if not self['auto_ptj_mjj']:
2686 if self['mmjj'] > self['xqcut']:
2687 logger.warning('mmjj > xqcut (and auto_ptj_mjj = F). MMJJ set to 0')
2688 self['mmjj'] = 0.0
2689
2690
2691
2692
2693 possible_set = ['lhapdf', 'mrs02nl','mrs02nn',
2694 'cteq4_m', 'cteq4_l','cteq4_d',
2695 'cteq5_m','cteq5_d','cteq5_l','cteq5m1',
2696 'cteq6_m','cteq6_l', 'cteq6l1',
2697 'nn23lo', 'nn23lo1', 'nn23nlo']
2698
2699
2700 if self['pdlabel'] not in possible_set:
2701 raise InvalidRunCard, 'Invalid PDF set (argument of pdlabel): %s. Possible choice are:\n %s' % (self['pdlabel'], ', '.join(possible_set))
2702 if self['pdlabel'] == 'lhapdf':
2703
2704 self.get_default('lhaid', log_level=20)
2705
2706 for name in self.legacy_parameter:
2707 if self[name] != self.legacy_parameter[name]:
2708 logger.warning("The parameter %s is not supported anymore this parameter will be ignored." % name)
2709
2710
2711
2712
2714 """Rules
2715 process 1->N all cut set on off.
2716 loop_induced -> MC over helicity
2717 e+ e- beam -> lpp:0 ebeam:500
2718 p p beam -> set maxjetflavor automatically
2719 more than one multiplicity: ickkw=1 xqcut=30 use_syst=F
2720 """
2721
2722 if proc_characteristic['loop_induced']:
2723 self['nhel'] = 1
2724 self['pdgs_for_merging_cut'] = proc_characteristic['colored_pdgs']
2725
2726 if proc_characteristic['ninitial'] == 1:
2727
2728 self.remove_all_cut()
2729 self['use_syst'] = False
2730 else:
2731
2732 beam_id = set()
2733 for proc in proc_def:
2734 for oneproc in proc:
2735 for leg in oneproc['legs']:
2736 if not leg['state']:
2737 beam_id.add(leg['id'])
2738 if any(i in beam_id for i in [1,-1,2,-2,3,-3,4,-4,5,-5,21,22]):
2739 maxjetflavor = max([4]+[abs(i) for i in beam_id if -7< i < 7])
2740 self['maxjetflavor'] = maxjetflavor
2741 self['asrwgtflavor'] = maxjetflavor
2742 pass
2743 elif 11 in beam_id or -11 in beam_id:
2744 self['lpp1'] = 0
2745 self['lpp2'] = 0
2746 self['ebeam1'] = 500
2747 self['ebeam2'] = 500
2748 else:
2749 self['lpp1'] = 0
2750 self['lpp2'] = 0
2751
2752
2753 min_particle = 99
2754 max_particle = 0
2755 for proc in proc_def:
2756 min_particle = min(len(proc[0]['legs']), min_particle)
2757 max_particle = max(len(proc[0]['legs']), max_particle)
2758 if min_particle != max_particle:
2759
2760 for procmin in proc_def:
2761 if len(procmin[0]['legs']) != min_particle:
2762 continue
2763 else:
2764 idsmin = [l['id'] for l in procmin[0]['legs']]
2765 break
2766 matching = False
2767 for procmax in proc_def:
2768 if len(procmax[0]['legs']) != max_particle:
2769 continue
2770 idsmax = [l['id'] for l in procmax[0]['legs']]
2771 for i in idsmin:
2772 if i not in idsmax:
2773 continue
2774 else:
2775 idsmax.remove(i)
2776 for j in idsmax:
2777 if j not in [1,-1,2,-2,3,-3,4,-4,5,-5,21]:
2778 break
2779 else:
2780
2781 matching=True
2782 break
2783
2784 if matching:
2785 self['ickkw'] = 1
2786 self['xqcut'] = 30
2787
2788 self['drjj'] = 0
2789 self['drjl'] = 0
2790 self['sys_alpsfact'] = "0.5 1 2"
2791
2792
2793
2794 no_systematics = False
2795 for proc in proc_def:
2796 for oneproc in proc:
2797 if '^2' in oneproc.nice_string():
2798 no_systematics = True
2799 break
2800 else:
2801 continue
2802 break
2803 if no_systematics:
2804 self['use_syst'] = False
2805 self['systematics_program'] = 'none'
2806
2807 - def write(self, output_file, template=None, python_template=False):
2808 """Write the run_card in output_file according to template
2809 (a path to a valid run_card)"""
2810
2811 if not template:
2812 if not MADEVENT:
2813 template = pjoin(MG5DIR, 'Template', 'LO', 'Cards',
2814 'run_card.dat')
2815 python_template = True
2816 else:
2817 template = pjoin(MEDIR, 'Cards', 'run_card_default.dat')
2818 python_template = False
2819
2820 super(RunCardLO, self).write(output_file, template=template,
2821 python_template=python_template)
2822
2826
2828 """ A class to store a MadAnalysis5 card. Very basic since it is basically
2829 free format."""
2830
2831 _MG5aMC_escape_tag = '@MG5aMC'
2832
2833 _default_hadron_inputs = ['*.hepmc', '*.hep', '*.stdhep', '*.lhco','*.root']
2834 _default_parton_inputs = ['*.lhe']
2835 _skip_analysis = False
2836
2837 @classmethod
2839 """ Checks from the type of an event file whether it can be reconstructed or not."""
2840 return not (file_path.endswith('.lhco') or file_path.endswith('.lhco.gz') or \
2841 file_path.endswith('.root') or file_path.endswith('.root.gz'))
2842
2843 @classmethod
2845 """ A method returning the structure of an empty analysis """
2846 return {'commands':[],
2847 'reconstructions':[]}
2848
2849 @classmethod
2851 """ A method returning the structure of an empty reconstruction """
2852 return {'commands':[],
2853 'reco_output':'lhe'}
2854
2856 """define the default value"""
2857 self['mode'] = 'parton'
2858 self['inputs'] = []
2859
2860 self['stdout_lvl'] = None
2861
2862
2863
2864
2865
2866
2867
2868 self['analyses'] = {}
2869
2870
2871 self['recasting'] = {'commands':[],'card':[]}
2872
2873
2874 self['reconstruction'] = {'lhco_input':
2875 MadAnalysis5Card.empty_reconstruction(),
2876 'root_input':
2877 MadAnalysis5Card.empty_reconstruction()}
2878 self['reconstruction']['lhco_input']['reco_output']='lhco'
2879 self['reconstruction']['root_input']['reco_output']='root'
2880
2881
2882 self['order'] = []
2883
2884 - def __init__(self, finput=None,mode=None):
2885 if isinstance(finput, self.__class__):
2886 dict.__init__(self, finput)
2887 assert finput.__dict__.keys()
2888 for key in finput.__dict__:
2889 setattr(self, key, copy.copy(getattr(finput, key)) )
2890 return
2891 else:
2892 dict.__init__(self)
2893
2894
2895 self.default_setup()
2896 if not mode is None:
2897 self['mode']=mode
2898
2899
2900 if isinstance(finput, (file, str, StringIO.StringIO)):
2901 self.read(finput, mode=mode)
2902
2903 - def read(self, input, mode=None):
2904 """ Read an MA5 card"""
2905
2906 if mode not in [None,'parton','hadron']:
2907 raise MadGraph5Error('A MadAnalysis5Card can be read online the modes'+
2908 "'parton' or 'hadron'")
2909 card_mode = mode
2910
2911 if isinstance(input, (file, StringIO.StringIO)):
2912 input_stream = input
2913 elif isinstance(input, str):
2914 if not os.path.isfile(input):
2915 raise InvalidMadAnalysis5Card("Cannot read the MadAnalysis5 card."+\
2916 "File '%s' not found."%input)
2917 if mode is None and 'hadron' in input:
2918 card_mode = 'hadron'
2919 input_stream = open(input,'r')
2920 else:
2921 raise MadGraph5Error('Incorrect input for the read function of'+\
2922 ' the MadAnalysis5Card card. Received argument type is: %s'%str(type(input)))
2923
2924
2925 self.__init__()
2926 current_name = 'default'
2927 current_type = 'analyses'
2928 for line in input_stream:
2929
2930 if line.startswith('#'):
2931 continue
2932 if line.endswith('\n'):
2933 line = line[:-1]
2934 if line.strip()=='':
2935 continue
2936 if line.startswith(self._MG5aMC_escape_tag):
2937 try:
2938 option,value = line[len(self._MG5aMC_escape_tag):].split('=')
2939 value = value.strip()
2940 except ValueError:
2941 option = line[len(self._MG5aMC_escape_tag):]
2942 option = option.strip()
2943
2944 if option=='inputs':
2945 self['inputs'].extend([v.strip() for v in value.split(',')])
2946
2947 elif option == 'skip_analysis':
2948 self._skip_analysis = True
2949
2950 elif option=='stdout_lvl':
2951 try:
2952 self['stdout_lvl']=int(value)
2953 except ValueError:
2954 try:
2955 self['stdout_lvl']=eval(value)
2956 except:
2957 try:
2958 self['stdout_lvl']=eval('logging.%s'%value)
2959 except:
2960 raise InvalidMadAnalysis5Card(
2961 "MA5 output level specification '%s' is incorrect."%str(value))
2962
2963 elif option=='analysis_name':
2964 current_type = 'analyses'
2965 current_name = value
2966 if current_name in self[current_type]:
2967 raise InvalidMadAnalysis5Card(
2968 "Analysis '%s' already defined in MadAnalysis5 card"%current_name)
2969 else:
2970 self[current_type][current_name] = MadAnalysis5Card.empty_analysis()
2971
2972 elif option=='set_reconstructions':
2973 try:
2974 reconstructions = eval(value)
2975 if not isinstance(reconstructions, list):
2976 raise
2977 except:
2978 raise InvalidMadAnalysis5Card("List of reconstructions"+\
2979 " '%s' could not be parsed in MadAnalysis5 card."%value)
2980 if current_type!='analyses' and current_name not in self[current_type]:
2981 raise InvalidMadAnalysis5Card("A list of reconstructions"+\
2982 "can only be defined in the context of an "+\
2983 "analysis in a MadAnalysis5 card.")
2984 self[current_type][current_name]['reconstructions']=reconstructions
2985 continue
2986
2987 elif option=='reconstruction_name':
2988 current_type = 'reconstruction'
2989 current_name = value
2990 if current_name in self[current_type]:
2991 raise InvalidMadAnalysis5Card(
2992 "Reconstruction '%s' already defined in MadAnalysis5 hadron card"%current_name)
2993 else:
2994 self[current_type][current_name] = MadAnalysis5Card.empty_reconstruction()
2995
2996 elif option=='reco_output':
2997 if current_type!='reconstruction' or current_name not in \
2998 self['reconstruction']:
2999 raise InvalidMadAnalysis5Card(
3000 "Option '%s' is only available within the definition of a reconstruction"%option)
3001 if not value.lower() in ['lhe','root']:
3002 raise InvalidMadAnalysis5Card(
3003 "Option '%s' can only take the values 'lhe' or 'root'"%option)
3004 self['reconstruction'][current_name]['reco_output'] = value.lower()
3005
3006 elif option.startswith('recasting'):
3007 current_type = 'recasting'
3008 try:
3009 current_name = option.split('_')[1]
3010 except:
3011 raise InvalidMadAnalysis5Card('Malformed MA5 recasting option %s.'%option)
3012 if len(self['recasting'][current_name])>0:
3013 raise InvalidMadAnalysis5Card(
3014 "Only one recasting can be defined in MadAnalysis5 hadron card")
3015
3016 else:
3017 raise InvalidMadAnalysis5Card(
3018 "Unreckognized MG5aMC instruction in MadAnalysis5 card: '%s'"%option)
3019
3020 if option in ['analysis_name','reconstruction_name'] or \
3021 option.startswith('recasting'):
3022 self['order'].append((current_type,current_name))
3023 continue
3024
3025
3026
3027 if current_name == 'default' and current_type == 'analyses' and\
3028 'default' not in self['analyses']:
3029 self['analyses']['default'] = MadAnalysis5Card.empty_analysis()
3030 self['order'].append(('analyses','default'))
3031
3032 if current_type in ['recasting']:
3033 self[current_type][current_name].append(line)
3034 elif current_type in ['reconstruction']:
3035 self[current_type][current_name]['commands'].append(line)
3036 elif current_type in ['analyses']:
3037 self[current_type][current_name]['commands'].append(line)
3038
3039 if 'reconstruction' in self['analyses'] or len(self['recasting']['card'])>0:
3040 if mode=='parton':
3041 raise InvalidMadAnalysis5Card(
3042 "A parton MadAnalysis5 card cannot specify a recombination or recasting.")
3043 card_mode = 'hadron'
3044 elif mode is None:
3045 card_mode = 'parton'
3046
3047 self['mode'] = card_mode
3048 if self['inputs'] == []:
3049 if self['mode']=='hadron':
3050 self['inputs'] = self._default_hadron_inputs
3051 else:
3052 self['inputs'] = self._default_parton_inputs
3053
3054
3055
3056 if self['mode']=='hadron':
3057 for analysis_name, analysis in self['analyses'].items():
3058 if len(analysis['reconstructions'])==0:
3059 raise InvalidMadAnalysis5Card('Hadron-level analysis '+\
3060 "'%s' is not specified any reconstruction(s)."%analysis_name)
3061 if any(reco not in self['reconstruction'] for reco in \
3062 analysis['reconstructions']):
3063 raise InvalidMadAnalysis5Card('A reconstructions specified in'+\
3064 " analysis '%s' is not defined."%analysis_name)
3065
3066 - def write(self, output):
3067 """ Write an MA5 card."""
3068
3069 if isinstance(output, (file, StringIO.StringIO)):
3070 output_stream = output
3071 elif isinstance(output, str):
3072 output_stream = open(output,'w')
3073 else:
3074 raise MadGraph5Error('Incorrect input for the write function of'+\
3075 ' the MadAnalysis5Card card. Received argument type is: %s'%str(type(output)))
3076
3077 output_lines = []
3078 if self._skip_analysis:
3079 output_lines.append('%s skip_analysis'%self._MG5aMC_escape_tag)
3080 output_lines.append('%s inputs = %s'%(self._MG5aMC_escape_tag,','.join(self['inputs'])))
3081 if not self['stdout_lvl'] is None:
3082 output_lines.append('%s stdout_lvl=%s'%(self._MG5aMC_escape_tag,self['stdout_lvl']))
3083 for definition_type, name in self['order']:
3084
3085 if definition_type=='analyses':
3086 output_lines.append('%s analysis_name = %s'%(self._MG5aMC_escape_tag,name))
3087 output_lines.append('%s set_reconstructions = %s'%(self._MG5aMC_escape_tag,
3088 str(self['analyses'][name]['reconstructions'])))
3089 elif definition_type=='reconstruction':
3090 output_lines.append('%s reconstruction_name = %s'%(self._MG5aMC_escape_tag,name))
3091 elif definition_type=='recasting':
3092 output_lines.append('%s recasting_%s'%(self._MG5aMC_escape_tag,name))
3093
3094 if definition_type in ['recasting']:
3095 output_lines.extend(self[definition_type][name])
3096 elif definition_type in ['reconstruction']:
3097 output_lines.append('%s reco_output = %s'%(self._MG5aMC_escape_tag,
3098 self[definition_type][name]['reco_output']))
3099 output_lines.extend(self[definition_type][name]['commands'])
3100 elif definition_type in ['analyses']:
3101 output_lines.extend(self[definition_type][name]['commands'])
3102
3103 output_stream.write('\n'.join(output_lines))
3104
3105 return
3106
3107 - def get_MA5_cmds(self, inputs_arg, submit_folder, run_dir_path=None,
3108 UFO_model_path=None, run_tag=''):
3109 """ Returns a list of tuples ('AnalysisTag',['commands']) specifying
3110 the commands of the MadAnalysis runs required from this card.
3111 At parton-level, the number of such commands is the number of analysis
3112 asked for. In the future, the idea is that the entire card can be
3113 processed in one go from MA5 directly."""
3114
3115 if isinstance(inputs_arg, list):
3116 inputs = inputs_arg
3117 elif isinstance(inputs_arg, str):
3118 inputs = [inputs_arg]
3119 else:
3120 raise MadGraph5Error("The function 'get_MA5_cmds' can only take "+\
3121 " a string or a list for the argument 'inputs_arg'")
3122
3123 if len(inputs)==0:
3124 raise MadGraph5Error("The function 'get_MA5_cmds' must have "+\
3125 " at least one input specified'")
3126
3127 if run_dir_path is None:
3128 run_dir_path = os.path.dirname(inputs_arg)
3129
3130 cmds_list = []
3131
3132 UFO_load = []
3133
3134 if UFO_model_path:
3135 UFO_load.append('import %s'%UFO_model_path)
3136
3137 def get_import(input, type=None):
3138 """ Generates the MA5 import commands for that event file. """
3139 dataset_name = os.path.basename(input).split('.')[0]
3140 res = ['import %s as %s'%(input, dataset_name)]
3141 if not type is None:
3142 res.append('set %s.type = %s'%(dataset_name, type))
3143 return res
3144
3145 fifo_status = {'warned_fifo':False,'fifo_used_up':False}
3146 def warn_fifo(input):
3147 if not input.endswith('.fifo'):
3148 return False
3149 if not fifo_status['fifo_used_up']:
3150 fifo_status['fifo_used_up'] = True
3151 return False
3152 else:
3153 if not fifo_status['warned_fifo']:
3154 logger.warning('Only the first MA5 analysis/reconstructions can be run on a fifo. Subsequent runs will skip fifo inputs.')
3155 fifo_status['warned_fifo'] = True
3156 return True
3157
3158
3159 inputs_load = []
3160 for input in inputs:
3161 inputs_load.extend(get_import(input))
3162
3163 submit_command = 'submit %s'%submit_folder+'_%s'
3164
3165
3166
3167
3168 reconstruction_outputs = {
3169 'lhco_input':[f for f in inputs if
3170 f.endswith('.lhco') or f.endswith('.lhco.gz')],
3171 'root_input':[f for f in inputs if
3172 f.endswith('.root') or f.endswith('.root.gz')]}
3173
3174
3175 recasting_card_path = pjoin(run_dir_path,
3176 '_'.join([run_tag,os.path.basename(submit_folder),'recasting_card.dat']))
3177
3178
3179 for definition_type, name in self['order']:
3180 if definition_type == 'reconstruction':
3181 analysis_cmds = list(self['reconstruction'][name]['commands'])
3182 reco_outputs = []
3183 for i_input, input in enumerate(inputs):
3184
3185 if not MadAnalysis5Card.events_can_be_reconstructed(input):
3186 continue
3187
3188 if warn_fifo(input):
3189 continue
3190 analysis_cmds.append('import %s as reco_events'%input)
3191 if self['reconstruction'][name]['reco_output']=='lhe':
3192 reco_outputs.append('%s_%s.lhe.gz'%(os.path.basename(
3193 input).replace('_events','').split('.')[0],name))
3194 analysis_cmds.append('set main.outputfile=%s'%reco_outputs[-1])
3195 elif self['reconstruction'][name]['reco_output']=='root':
3196 reco_outputs.append('%s_%s.root'%(os.path.basename(
3197 input).replace('_events','').split('.')[0],name))
3198 analysis_cmds.append('set main.fastsim.rootfile=%s'%reco_outputs[-1])
3199 analysis_cmds.append(
3200 submit_command%('reco_%s_%d'%(name,i_input+1)))
3201 analysis_cmds.append('remove reco_events')
3202
3203 reconstruction_outputs[name]= [pjoin(run_dir_path,rec_out)
3204 for rec_out in reco_outputs]
3205 if len(reco_outputs)>0:
3206 cmds_list.append(('_reco_%s'%name,analysis_cmds))
3207
3208 elif definition_type == 'analyses':
3209 if self['mode']=='parton':
3210 cmds_list.append( (name, UFO_load+inputs_load+
3211 self['analyses'][name]['commands']+[submit_command%name]) )
3212 elif self['mode']=='hadron':
3213
3214 for reco in self['analyses'][name]['reconstructions']+\
3215 ['lhco_input','root_input']:
3216 if len(reconstruction_outputs[reco])==0:
3217 continue
3218 if self['reconstruction'][reco]['reco_output']=='lhe':
3219
3220 analysis_cmds = ['set main.mode = parton']
3221 else:
3222 analysis_cmds = []
3223 analysis_cmds.extend(sum([get_import(rec_out) for
3224 rec_out in reconstruction_outputs[reco]],[]))
3225 analysis_cmds.extend(self['analyses'][name]['commands'])
3226 analysis_cmds.append(submit_command%('%s_%s'%(name,reco)))
3227 cmds_list.append( ('%s_%s'%(name,reco),analysis_cmds) )
3228
3229 elif definition_type == 'recasting':
3230 if len(self['recasting']['card'])==0:
3231 continue
3232 if name == 'card':
3233
3234 open(recasting_card_path,'w').write('\n'.join(self['recasting']['card']))
3235 if name == 'commands':
3236 recasting_cmds = list(self['recasting']['commands'])
3237
3238 n_inputs = 0
3239 for input in inputs:
3240 if not MadAnalysis5Card.events_can_be_reconstructed(input):
3241 continue
3242
3243 if warn_fifo(input):
3244 continue
3245 recasting_cmds.extend(get_import(input,'signal'))
3246 n_inputs += 1
3247
3248 recasting_cmds.append('set main.recast.card_path=%s'%recasting_card_path)
3249 recasting_cmds.append(submit_command%'Recasting')
3250 if n_inputs>0:
3251 cmds_list.append( ('Recasting',recasting_cmds))
3252
3253 return cmds_list
3254
3256 """A class object for the run_card for a (aMC@)NLO pocess"""
3257
3259 """define the default value"""
3260
3261 self.add_param('run_tag', 'tag_1', include=False)
3262 self.add_param('nevents', 10000)
3263 self.add_param('req_acc', -1.0, include=False)
3264 self.add_param('nevt_job', -1, include=False)
3265 self.add_param('event_norm', 'average')
3266
3267 self.add_param('req_acc_fo', 0.01, include=False)
3268 self.add_param('npoints_fo_grid', 5000, include=False)
3269 self.add_param('niters_fo_grid', 4, include=False)
3270 self.add_param('npoints_fo', 10000, include=False)
3271 self.add_param('niters_fo', 6, include=False)
3272
3273 self.add_param('iseed', 0)
3274 self.add_param('lpp1', 1, fortran_name='lpp(1)')
3275 self.add_param('lpp2', 1, fortran_name='lpp(2)')
3276 self.add_param('ebeam1', 6500.0, fortran_name='ebeam(1)')
3277 self.add_param('ebeam2', 6500.0, fortran_name='ebeam(2)')
3278 self.add_param('pdlabel', 'nn23nlo')
3279 self.add_param('lhaid', [244600],fortran_name='lhaPDFid')
3280 self.add_param('lhapdfsetname', ['internal_use_only'], system=True)
3281
3282 self.add_param('parton_shower', 'HERWIG6', fortran_name='shower_mc')
3283 self.add_param('shower_scale_factor',1.0)
3284 self.add_param('fixed_ren_scale', False)
3285 self.add_param('fixed_fac_scale', False)
3286 self.add_param('mur_ref_fixed', 91.118)
3287 self.add_param('muf1_ref_fixed', -1.0, hidden=True)
3288 self.add_param('muf_ref_fixed', 91.118)
3289 self.add_param('muf2_ref_fixed', -1.0, hidden=True)
3290 self.add_param("dynamical_scale_choice", [-1],fortran_name='dyn_scale')
3291 self.add_param('fixed_qes_scale', False, hidden=True)
3292 self.add_param('qes_ref_fixed', -1.0, hidden=True)
3293 self.add_param('mur_over_ref', 1.0)
3294 self.add_param('muf_over_ref', 1.0)
3295 self.add_param('muf1_over_ref', -1.0, hidden=True)
3296 self.add_param('muf2_over_ref', -1.0, hidden=True)
3297 self.add_param('qes_over_ref', -1.0, hidden=True)
3298 self.add_param('reweight_scale', [True], fortran_name='lscalevar')
3299 self.add_param('rw_rscale_down', -1.0, hidden=True)
3300 self.add_param('rw_rscale_up', -1.0, hidden=True)
3301 self.add_param('rw_fscale_down', -1.0, hidden=True)
3302 self.add_param('rw_fscale_up', -1.0, hidden=True)
3303 self.add_param('rw_rscale', [1.0,2.0,0.5], fortran_name='scalevarR')
3304 self.add_param('rw_fscale', [1.0,2.0,0.5], fortran_name='scalevarF')
3305 self.add_param('reweight_pdf', [False], fortran_name='lpdfvar')
3306 self.add_param('pdf_set_min', 244601, hidden=True)
3307 self.add_param('pdf_set_max', 244700, hidden=True)
3308 self.add_param('store_rwgt_info', False)
3309 self.add_param('systematics_program', 'none', include=False, hidden=True, comment='Choose which program to use for systematics computation: none, systematics')
3310 self.add_param('systematics_arguments', [''], include=False, hidden=True, comment='Choose the argment to pass to the systematics command. like --mur=0.25,1,4. Look at the help of the systematics function for more details.')
3311
3312
3313 self.add_param('ickkw', 0)
3314 self.add_param('bwcutoff', 15.0)
3315
3316 self.add_param('jetalgo', 1.0)
3317 self.add_param('jetradius', 0.7)
3318 self.add_param('ptj', 10.0 , cut=True)
3319 self.add_param('etaj', -1.0, cut=True)
3320 self.add_param('ptl', 0.0, cut=True)
3321 self.add_param('etal', -1.0, cut=True)
3322 self.add_param('drll', 0.0, cut=True)
3323 self.add_param('drll_sf', 0.0, cut=True)
3324 self.add_param('mll', 0.0, cut=True)
3325 self.add_param('mll_sf', 30.0, cut=True)
3326 self.add_param('ptgmin', 20.0, cut=True)
3327 self.add_param('etagamma', -1.0)
3328 self.add_param('r0gamma', 0.4)
3329 self.add_param('xn', 1.0)
3330 self.add_param('epsgamma', 1.0)
3331 self.add_param('isoem', True)
3332 self.add_param('maxjetflavor', 4, hidden=True)
3333 self.add_param('iappl', 0)
3334 self.add_param('lhe_version', 3, hidden=True, include=False)
3335
3337 """check the validity of the various input"""
3338
3339 super(RunCardNLO, self).check_validity()
3340
3341
3342 if self['ickkw'] == 3:
3343
3344 scales=['fixed_ren_scale','fixed_fac_scale','fixed_QES_scale']
3345 for scale in scales:
3346 if self[scale]:
3347 logger.warning('''For consistency in the FxFx merging, \'%s\' has been set to false'''
3348 % scale,'$MG:color:BLACK')
3349 self[scale]= False
3350
3351 if len(self["dynamical_scale_choice"]) > 1 or self["dynamical_scale_choice"][0] != -1:
3352 self["dynamical_scale_choice"] = [-1]
3353 self["reweight_scale"]=[self["reweight_scale"][0]]
3354 logger.warning('''For consistency in the FxFx merging, dynamical_scale_choice has been set to -1 (default)'''
3355 ,'$MG:color:BLACK')
3356
3357
3358 jetparams=['jetradius','jetalgo']
3359 for jetparam in jetparams:
3360 if float(self[jetparam]) != 1.0:
3361 logger.info('''For consistency in the FxFx merging, \'%s\' has been set to 1.0'''
3362 % jetparam ,'$MG:color:BLACK')
3363 self[jetparam] = 1.0
3364 elif self['ickkw'] == -1 and (self["dynamical_scale_choice"][0] != -1 or
3365 len(self["dynamical_scale_choice"]) > 1):
3366 self["dynamical_scale_choice"] = [-1]
3367 self["reweight_scale"]=[self["reweight_scale"][0]]
3368 logger.warning('''For consistency with the jet veto, the scale which will be used is ptj. dynamical_scale_choice will be set at -1.'''
3369 ,'$MG:color:BLACK')
3370
3371
3372 if self['iappl'] != 0 and self['pdlabel'].lower() != 'lhapdf':
3373 raise InvalidRunCard('APPLgrid generation only possible with the use of LHAPDF')
3374 if self['iappl'] != 0 and not self['reweight_scale']:
3375 raise InvalidRunCard('APPLgrid generation only possible with including' +\
3376 ' the reweighting to get scale dependence')
3377
3378
3379 possible_set = ['lhapdf','mrs02nl','mrs02nn', 'mrs0119','mrs0117','mrs0121','mrs01_j', 'mrs99_1','mrs99_2','mrs99_3','mrs99_4','mrs99_5','mrs99_6', 'mrs99_7','mrs99_8','mrs99_9','mrs9910','mrs9911','mrs9912', 'mrs98z1','mrs98z2','mrs98z3','mrs98z4','mrs98z5','mrs98ht', 'mrs98l1','mrs98l2','mrs98l3','mrs98l4','mrs98l5', 'cteq3_m','cteq3_l','cteq3_d', 'cteq4_m','cteq4_d','cteq4_l','cteq4a1','cteq4a2', 'cteq4a3','cteq4a4','cteq4a5','cteq4hj','cteq4lq', 'cteq5_m','cteq5_d','cteq5_l','cteq5hj','cteq5hq', 'cteq5f3','cteq5f4','cteq5m1','ctq5hq1','cteq5l1', 'cteq6_m','cteq6_d','cteq6_l','cteq6l1', 'nn23lo','nn23lo1','nn23nlo']
3380 if self['pdlabel'] not in possible_set:
3381 raise InvalidRunCard, 'Invalid PDF set (argument of pdlabel) possible choice are:\n %s' % ','.join(possible_set)
3382
3383
3384 if self['qes_ref_fixed'] == -1.0:
3385 self['qes_ref_fixed']=self['mur_ref_fixed']
3386 if self['qes_over_ref'] == -1.0:
3387 self['qes_over_ref']=self['mur_over_ref']
3388 if self['muf1_over_ref'] != -1.0 and self['muf1_over_ref'] == self['muf2_over_ref']:
3389 self['muf_over_ref']=self['muf1_over_ref']
3390 if self['muf1_over_ref'] == -1.0:
3391 self['muf1_over_ref']=self['muf_over_ref']
3392 if self['muf2_over_ref'] == -1.0:
3393 self['muf2_over_ref']=self['muf_over_ref']
3394 if self['muf1_ref_fixed'] != -1.0 and self['muf1_ref_fixed'] == self['muf2_ref_fixed']:
3395 self['muf_ref_fixed']=self['muf1_ref_fixed']
3396 if self['muf1_ref_fixed'] == -1.0:
3397 self['muf1_ref_fixed']=self['muf_ref_fixed']
3398 if self['muf2_ref_fixed'] == -1.0:
3399 self['muf2_ref_fixed']=self['muf_ref_fixed']
3400
3401 if (self['rw_rscale_down'] != -1.0 and ['rw_rscale_down'] not in self['rw_rscale']) or\
3402 (self['rw_rscale_up'] != -1.0 and ['rw_rscale_up'] not in self['rw_rscale']):
3403 self['rw_rscale']=[1.0,self['rw_rscale_up'],self['rw_rscale_down']]
3404 if (self['rw_fscale_down'] != -1.0 and ['rw_fscale_down'] not in self['rw_fscale']) or\
3405 (self['rw_fscale_up'] != -1.0 and ['rw_fscale_up'] not in self['rw_fscale']):
3406 self['rw_fscale']=[1.0,self['rw_fscale_up'],self['rw_fscale_down']]
3407
3408
3409 if any(self['reweight_pdf']):
3410
3411 if self['pdlabel'] != "lhapdf":
3412 raise InvalidRunCard, 'Reweight PDF option requires to use pdf sets associated to lhapdf. Please either change the pdlabel to use LHAPDF or set reweight_pdf to False.'
3413
3414
3415 if self['pdlabel'] != "lhapdf":
3416 self['reweight_pdf']=[self['reweight_pdf'][0]]
3417 self['lhaid']=[self['lhaid'][0]]
3418
3419
3420 if self['fixed_ren_scale'] and self['fixed_fac_scale']:
3421 self['reweight_scale']=[self['reweight_scale'][0]]
3422 self['dynamical_scale_choice']=[0]
3423
3424
3425
3426
3427 if len(self['reweight_pdf']) == 1 and len(self['lhaid']) != 1:
3428 self['reweight_pdf']=self['reweight_pdf']*len(self['lhaid'])
3429 logger.warning("Setting 'reweight_pdf' for all 'lhaid' to %s" % self['reweight_pdf'][0])
3430 if len(self['reweight_scale']) == 1 and len(self['dynamical_scale_choice']) != 1:
3431 self['reweight_scale']=self['reweight_scale']*len(self['dynamical_scale_choice'])
3432 logger.warning("Setting 'reweight_scale' for all 'dynamical_scale_choice' to %s" % self['reweight_pdf'][0])
3433
3434
3435 if len(self['lhaid']) != len(set(self['lhaid'])):
3436 raise InvalidRunCard, "'lhaid' has two or more identical entries. They have to be all different for the code to work correctly."
3437 if len(self['dynamical_scale_choice']) != len(set(self['dynamical_scale_choice'])):
3438 raise InvalidRunCard, "'dynamical_scale_choice' has two or more identical entries. They have to be all different for the code to work correctly."
3439
3440
3441 if len(self['reweight_pdf']) != len(self['lhaid']):
3442 raise InvalidRunCard, "'reweight_pdf' and 'lhaid' lists should have the same length"
3443 if len(self['reweight_scale']) != len(self['dynamical_scale_choice']):
3444 raise InvalidRunCard, "'reweight_scale' and 'dynamical_scale_choice' lists should have the same length"
3445 if len(self['dynamical_scale_choice']) > 10 :
3446 raise InvalidRunCard, "Length of list for 'dynamical_scale_choice' too long: max is 10."
3447 if len(self['lhaid']) > 25 :
3448 raise InvalidRunCard, "Length of list for 'lhaid' too long: max is 25."
3449 if len(self['rw_rscale']) > 9 :
3450 raise InvalidRunCard, "Length of list for 'rw_rscale' too long: max is 9."
3451 if len(self['rw_fscale']) > 9 :
3452 raise InvalidRunCard, "Length of list for 'rw_fscale' too long: max is 9."
3453
3454 if 1.0 not in self['rw_rscale']:
3455 logger.warning("'1.0' has to be part of 'rw_rscale', adding it")
3456 self['rw_rscale'].insert(0,1.0)
3457 if 1.0 not in self['rw_fscale']:
3458 logger.warning("'1.0' has to be part of 'rw_fscale', adding it")
3459 self['rw_fscale'].insert(0,1.0)
3460 if self['rw_rscale'][0] != 1.0 and 1.0 in self['rw_rscale']:
3461 a=self['rw_rscale'].index(1.0)
3462 self['rw_rscale'][0],self['rw_rscale'][a]=self['rw_rscale'][a],self['rw_rscale'][0]
3463 if self['rw_fscale'][0] != 1.0 and 1.0 in self['rw_fscale']:
3464 a=self['rw_fscale'].index(1.0)
3465 self['rw_fscale'][0],self['rw_fscale'][a]=self['rw_fscale'][a],self['rw_fscale'][0]
3466
3467 if len(self['rw_rscale']) != len(set(self['rw_rscale'])):
3468 raise InvalidRunCard, "'rw_rscale' has two or more identical entries. They have to be all different for the code to work correctly."
3469 if len(self['rw_fscale']) != len(set(self['rw_fscale'])):
3470 raise InvalidRunCard, "'rw_fscale' has two or more identical entries. They have to be all different for the code to work correctly."
3471
3472
3473 - def write(self, output_file, template=None, python_template=False):
3474 """Write the run_card in output_file according to template
3475 (a path to a valid run_card)"""
3476
3477 if not template:
3478 if not MADEVENT:
3479 template = pjoin(MG5DIR, 'Template', 'NLO', 'Cards',
3480 'run_card.dat')
3481 python_template = True
3482 else:
3483 template = pjoin(MEDIR, 'Cards', 'run_card_default.dat')
3484 python_template = False
3485
3486 super(RunCardNLO, self).write(output_file, template=template,
3487 python_template=python_template)
3488
3489
3491 """Rules
3492 e+ e- beam -> lpp:0 ebeam:500
3493 p p beam -> set maxjetflavor automatically
3494 """
3495
3496
3497 beam_id = set()
3498 for proc in proc_def:
3499 for leg in proc['legs']:
3500 if not leg['state']:
3501 beam_id.add(leg['id'])
3502 if any(i in beam_id for i in [1,-1,2,-2,3,-3,4,-4,5,-5,21,22]):
3503 maxjetflavor = max([4]+[abs(i) for i in beam_id if -7< i < 7])
3504 self['maxjetflavor'] = maxjetflavor
3505 pass
3506 elif 11 in beam_id or -11 in beam_id:
3507 self['lpp1'] = 0
3508 self['lpp2'] = 0
3509 self['ebeam1'] = 500
3510 self['ebeam2'] = 500
3511 else:
3512 self['lpp1'] = 0
3513 self['lpp2'] = 0
3514
3515 if proc_characteristic['ninitial'] == 1:
3516
3517 self.remove_all_cut()
3518
3520 """ a class for storing/dealing with the file MadLoopParam.dat
3521 contains a parser to read it, facilities to write a new file,...
3522 """
3523
3524 _ID_reduction_tool_map = {1:'CutTools',
3525 2:'PJFry++',
3526 3:'IREGI',
3527 4:'Golem95',
3528 5:'Samurai',
3529 6:'Ninja',
3530 7:'COLLIER'}
3531
3533 """initialize the directory to the default value"""
3534
3535 self.add_param("MLReductionLib", "6|7|1")
3536 self.add_param("IREGIMODE", 2)
3537 self.add_param("IREGIRECY", True)
3538 self.add_param("CTModeRun", -1)
3539 self.add_param("MLStabThres", 1e-3)
3540 self.add_param("NRotations_DP", 0)
3541 self.add_param("NRotations_QP", 0)
3542 self.add_param("ImprovePSPoint", 2)
3543 self.add_param("CTLoopLibrary", 2)
3544 self.add_param("CTStabThres", 1e-2)
3545 self.add_param("CTModeInit", 1)
3546 self.add_param("CheckCycle", 3)
3547 self.add_param("MaxAttempts", 10)
3548 self.add_param("ZeroThres", 1e-9)
3549 self.add_param("OSThres", 1.0e-8)
3550 self.add_param("DoubleCheckHelicityFilter", True)
3551 self.add_param("WriteOutFilters", True)
3552 self.add_param("UseLoopFilter", False)
3553 self.add_param("HelicityFilterLevel", 2)
3554 self.add_param("LoopInitStartOver", False)
3555 self.add_param("HelInitStartOver", False)
3556 self.add_param("UseQPIntegrandForNinja", True)
3557 self.add_param("UseQPIntegrandForCutTools", True)
3558 self.add_param("COLLIERMode", 1)
3559 self.add_param("COLLIERComputeUVpoles", True)
3560 self.add_param("COLLIERComputeIRpoles", True)
3561 self.add_param("COLLIERRequiredAccuracy", 1.0e-8)
3562 self.add_param("COLLIERCanOutput",False)
3563 self.add_param("COLLIERGlobalCache",-1)
3564 self.add_param("COLLIERUseCacheForPoles",False)
3565 self.add_param("COLLIERUseInternalStabilityTest",True)
3566
3567 - def read(self, finput):
3568 """Read the input file, this can be a path to a file,
3569 a file object, a str with the content of the file."""
3570
3571 if isinstance(finput, str):
3572 if "\n" in finput:
3573 finput = finput.split('\n')
3574 elif os.path.isfile(finput):
3575 finput = open(finput)
3576 else:
3577 raise Exception, "No such file %s" % input
3578
3579 previous_line= ''
3580 for line in finput:
3581 if previous_line.startswith('#'):
3582 name = previous_line[1:].split()[0]
3583 value = line.strip()
3584 if len(value) and value[0] not in ['#', '!']:
3585 self.__setitem__(name, value, change_userdefine=True)
3586 previous_line = line
3587
3588
3589 - def write(self, outputpath, template=None,commentdefault=False):
3590
3591 if not template:
3592 if not MADEVENT:
3593 template = pjoin(MG5DIR, 'Template', 'loop_material', 'StandAlone',
3594 'Cards', 'MadLoopParams.dat')
3595 else:
3596 template = pjoin(MEDIR, 'Cards', 'MadLoopParams_default.dat')
3597 fsock = open(template, 'r')
3598 template = fsock.readlines()
3599 fsock.close()
3600
3601 if isinstance(outputpath, str):
3602 output = open(outputpath, 'w')
3603 else:
3604 output = outputpath
3605
3606 def f77format(value):
3607 if isinstance(value, bool):
3608 if value:
3609 return '.true.'
3610 else:
3611 return '.false.'
3612 elif isinstance(value, int):
3613 return value
3614 elif isinstance(value, float):
3615 tmp ='%e' % value
3616 return tmp.replace('e','d')
3617 elif isinstance(value, str):
3618 return value
3619 else:
3620 raise Exception, "Can not format input %s" % type(value)
3621
3622 name = ''
3623 done = set()
3624 for line in template:
3625 if name:
3626 done.add(name)
3627 if commentdefault and name.lower() not in self.user_set :
3628 output.write('!%s\n' % f77format(self[name]))
3629 else:
3630 output.write('%s\n' % f77format(self[name]))
3631 name=''
3632 continue
3633 elif line.startswith('#'):
3634 name = line[1:].split()[0]
3635 output.write(line)
3636