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 try:
1612 force = opts.pop('force')
1613 except KeyError:
1614 force = False
1615 if force or name.lower() not in self.user_set:
1616 self.__setitem__(name, value, change_userdefine=False, **opts)
1617 self.system_set.add(name.lower())
1618
1620 """ Sets a card attribute, but only if it is absent or not already
1621 user_set."""
1622 try:
1623 force = opts.pop('force')
1624 except KeyError:
1625 force = False
1626 if name.lower() not in self or (force or name.lower() not in self.user_set):
1627 self.__setitem__(name, value, change_userdefine=False, **opts)
1628 self.system_set.add(name.lower())
1629
1632
1633 @staticmethod
1684
1685
1686 - def write(self, output_file, template, read_subrun=False,
1687 print_only_visible=False, direct_pythia_input=False, add_missing=True):
1688 """ Write the card to output_file using a specific template.
1689 > 'print_only_visible' specifies whether or not the hidden parameters
1690 should be written out if they are in the hidden_params_to_always_write
1691 list and system_set.
1692 > If 'direct_pythia_input' is true, then visible parameters which are not
1693 in the self.visible_params_to_always_write list and are not user_set
1694 or system_set are commented.
1695 > If 'add_missing' is False then parameters that should be written_out but are absent
1696 from the template will not be written out."""
1697
1698
1699 visible_param = [p for p in self if p.lower() not in self.hidden_param
1700 or p.lower() in self.user_set]
1701
1702 visible_param = [p for p in visible_param if p.lower() not in self.params_to_never_write]
1703
1704
1705 if print_only_visible:
1706 hidden_output_param = []
1707 else:
1708 hidden_output_param = [p for p in self if p.lower() in self.hidden_param and
1709 not p.lower() in self.user_set and
1710 (p.lower() in self.hidden_params_to_always_write or
1711 p.lower() in self.system_set)]
1712
1713 hidden_output_param = [p for p in hidden_output_param if p not in self.params_to_never_write]
1714
1715 if print_only_visible:
1716 subruns = []
1717 else:
1718 if not read_subrun:
1719 subruns = sorted(self.subruns.keys())
1720
1721
1722
1723 subruns_to_write = {}
1724
1725
1726
1727 def group_params(params):
1728 if len(params)==0:
1729 return []
1730 groups = {}
1731 for p in params:
1732 try:
1733 groups[':'.join(p.split(':')[:-1])].append(p)
1734 except KeyError:
1735 groups[':'.join(p.split(':')[:-1])] = [p,]
1736 res = sum(groups.values(),[])
1737
1738 if 'Main:subrun' in res:
1739 res.insert(0,res.pop(res.index('Main:subrun')))
1740
1741 if 'LHEFInputs:nSubruns' in res:
1742 res.append(res.pop(res.index('LHEFInputs:nSubruns')))
1743 return res
1744
1745 visible_param = group_params(visible_param)
1746 hidden_output_param = group_params(hidden_output_param)
1747
1748
1749
1750 output = StringIO.StringIO()
1751
1752
1753 if isinstance(template, str):
1754 if os.path.isfile(template):
1755 tmpl = open(template, 'r')
1756 elif '\n' in template:
1757 tmpl = StringIO.StringIO(template)
1758 else:
1759 raise Exception, "File input '%s' not found." % file_input
1760 elif template is None:
1761
1762 tmpl = StringIO.StringIO()
1763 elif isinstance(template, (StringIO.StringIO, file)):
1764 tmpl = template
1765 else:
1766 raise MadGraph5Error("Incorrect type for argument 'template': %s"%
1767 template.__class__.__name__)
1768
1769
1770 last_pos = tmpl.tell()
1771 line = tmpl.readline()
1772 started_subrun_reading = False
1773 while line!='':
1774
1775 if line.strip().startswith('!') or line.strip().startswith('\n'):
1776 output.write(line)
1777
1778 last_pos = tmpl.tell()
1779 line = tmpl.readline()
1780 continue
1781
1782 try:
1783 param_entry, value_entry = line.split('=')
1784 param = param_entry.strip()
1785 value = value_entry.strip()
1786 except ValueError:
1787 line = line.replace('\n','')
1788 raise MadGraph5Error, "Could not read line '%s' of Pythia8 card."%\
1789 line
1790
1791 if param=='Main:subrun':
1792 if read_subrun:
1793 if not started_subrun_reading:
1794
1795 started_subrun_reading = True
1796 else:
1797
1798 tmpl.seek(last_pos)
1799 break
1800 else:
1801
1802 tmpl.seek(last_pos)
1803 subruns_to_write[int(value)] = StringIO.StringIO()
1804 if int(value) in subruns:
1805 self.subruns[int(value)].write(subruns_to_write[int(value)],
1806 tmpl,read_subrun=True)
1807
1808 subruns.pop(subruns.index(int(value)))
1809 else:
1810
1811 DummySubrun=PY8SubRun()
1812
1813 DummySubrun.clear()
1814 DummySubrun.write(subruns_to_write[int(value)],
1815 tmpl, read_subrun=True,
1816 print_only_visible=print_only_visible,
1817 direct_pythia_input=direct_pythia_input)
1818
1819 logger.info('Adding new unknown subrun with ID %d.'%
1820 int(value))
1821
1822 last_pos = tmpl.tell()
1823 line = tmpl.readline()
1824 continue
1825
1826
1827 if param in visible_param:
1828 new_value = PY8Card.pythia8_formatting(self[param])
1829 visible_param.pop(visible_param.index(param))
1830 elif param in hidden_output_param:
1831 new_value = PY8Card.pythia8_formatting(self[param])
1832 hidden_output_param.pop(hidden_output_param.index(param))
1833 else:
1834
1835 if param.lower() not in self.params_to_never_write:
1836 output.write(line)
1837 else:
1838 output.write('! The following parameter was forced to be commented out by MG5aMC.\n')
1839 output.write('! %s'%line)
1840
1841 last_pos = tmpl.tell()
1842 line = tmpl.readline()
1843 continue
1844
1845
1846
1847
1848
1849 if ((not direct_pythia_input) or
1850 (param.lower() in self.visible_params_to_always_write) or
1851 (param.lower() in self.user_set) or
1852 (param.lower() in self.system_set)):
1853 template = '%s=%s'
1854 else:
1855
1856
1857
1858 template = '!%s=%s'
1859
1860 output.write(template%(param_entry,
1861 value_entry.replace(value,new_value)))
1862
1863
1864 last_pos = tmpl.tell()
1865 line = tmpl.readline()
1866
1867
1868 if not add_missing:
1869 visible_param = []
1870 hidden_output_param = []
1871
1872
1873 if len(visible_param)>0 and not template is None:
1874 output.write(
1875 """!
1876 ! Additional general parameters%s.
1877 !
1878 """%(' for subrun %d'%self['Main:subrun'] if 'Main:subrun' in self else ''))
1879 for param in visible_param:
1880 value = PY8Card.pythia8_formatting(self[param])
1881 output.write('%s=%s\n'%(param,value))
1882 if template is None:
1883 if param=='Main:subrun':
1884 output.write(
1885 """!
1886 ! Definition of subrun %d
1887 !
1888 """%self['Main:subrun'])
1889 elif param.lower() not in self.hidden_param:
1890 logger.debug('Adding parameter %s (missing in the template) to current '+\
1891 'pythia8 card (with value %s)',param, value)
1892
1893 if len(hidden_output_param)>0 and not template is None:
1894 output.write(
1895 """!
1896 ! Additional technical parameters%s set by MG5_aMC.
1897 !
1898 """%(' for subrun %d'%self['Main:subrun'] if 'Main:subrun' in self else ''))
1899 for param in hidden_output_param:
1900 if param.lower() in self.comments:
1901 comment = '\n'.join('! %s'%c for c in
1902 self.comments[param.lower()].split('\n'))
1903 output.write(comment+'\n')
1904 output.write('%s=%s\n'%(param,PY8Card.pythia8_formatting(self[param])))
1905
1906
1907
1908 if read_subrun:
1909 output_file.write(output.getvalue())
1910 return
1911
1912
1913 for subrunID in subruns:
1914 new_subrun = StringIO.StringIO()
1915 self.subruns[subrunID].write(new_subrun,None,read_subrun=True)
1916 subruns_to_write[subrunID] = new_subrun
1917
1918
1919 for subrunID in sorted(subruns_to_write):
1920 output.write(subruns_to_write[subrunID].getvalue())
1921
1922
1923
1924 if 'LHEFInputs:nSubruns'.lower() not in self.user_set and \
1925 len(subruns_to_write)>0 and self['LHEFInputs:nSubruns']<\
1926 max(subruns_to_write.keys()):
1927 logger.info("Updating PY8 parameter 'LHEFInputs:nSubruns' to "+
1928 "%d so as to cover all defined subruns."%max(subruns_to_write.keys()))
1929 self['LHEFInputs:nSubruns'] = max(subruns_to_write.keys())
1930 output = StringIO.StringIO()
1931 self.write(output,template,print_only_visible=print_only_visible)
1932
1933
1934 if isinstance(output_file, str):
1935 out = open(output_file,'w')
1936 out.write(output.getvalue())
1937 out.close()
1938 else:
1939 output_file.write(output.getvalue())
1940
1941 - def read(self, file_input, read_subrun=False, setter='default'):
1942 """Read the input file, this can be a path to a file,
1943 a file object, a str with the content of the file.
1944 The setter option choses the authority that sets potential
1945 modified/new parameters. It can be either:
1946 'default' or 'user' or 'system'"""
1947 if isinstance(file_input, str):
1948 if "\n" in file_input:
1949 finput = StringIO.StringIO(file_input)
1950 elif os.path.isfile(file_input):
1951 finput = open(file_input)
1952 else:
1953 raise Exception, "File input '%s' not found." % file_input
1954 elif isinstance(file_input, (StringIO.StringIO, file)):
1955 finput = file_input
1956 else:
1957 raise MadGraph5Error("Incorrect type for argument 'file_input': %s"%
1958 file_inp .__class__.__name__)
1959
1960
1961 last_pos = finput.tell()
1962 line = finput.readline()
1963 started_subrun_reading = False
1964 while line!='':
1965
1966 if line.strip().startswith('!') or line.strip()=='':
1967
1968 last_pos = finput.tell()
1969 line = finput.readline()
1970 continue
1971
1972 try:
1973 param, value = line.split('=',1)
1974 param = param.strip()
1975 value = value.strip()
1976 except ValueError:
1977 line = line.replace('\n','')
1978 raise MadGraph5Error, "Could not read line '%s' of Pythia8 card."%\
1979 line
1980
1981 if param=='Main:subrun':
1982 if read_subrun:
1983 if not started_subrun_reading:
1984
1985 started_subrun_reading = True
1986 else:
1987
1988 finput.seek(last_pos)
1989 return
1990 else:
1991
1992 finput.seek(last_pos)
1993 if int(value) in self.subruns:
1994 self.subruns[int(value)].read(finput,read_subrun=True,
1995 setter=setter)
1996 else:
1997
1998 NewSubrun=PY8SubRun()
1999 NewSubrun.read(finput,read_subrun=True, setter=setter)
2000 self.add_subrun(NewSubrun)
2001
2002
2003 last_pos = finput.tell()
2004 line = finput.readline()
2005 continue
2006
2007
2008
2009
2010
2011 if setter == 'user':
2012 self.userSet(param,value)
2013 elif setter == 'system':
2014 self.systemSet(param,value)
2015 else:
2016 self.defaultSet(param,value)
2017
2018
2019 last_pos = finput.tell()
2020 line = finput.readline()
2021
2023 """ Class to characterize a specific PY8 card subrun section. """
2024
2026 """ Overloading of the homonym function called in the __init__ of PY8Card.
2027 The initialization of the self.subruns attribute should of course not
2028 be performed in PY8SubRun."""
2029 pass
2030
2032 """ Initialize a subrun """
2033
2034
2035 subrunID = -1
2036 if 'subrun_id' in opts:
2037 subrunID = opts.pop('subrun_id')
2038
2039 super(PY8SubRun, self).__init__(*args, **opts)
2040 self['Main:subrun']=subrunID
2041
2043 """Sets up the list of available PY8SubRun parameters."""
2044
2045
2046 super(PY8SubRun, self).default_setup()
2047
2048 self.hidden_param = [k.lower() for k in self.keys()]
2049 self.hidden_params_to_always_write = set()
2050 self.visible_params_to_always_write = set()
2051
2052
2053 self.add_param("Main:subrun", -1)
2054 self.add_param("Beams:LHEF", "events.lhe.gz")
2055
2057
2058 filename = 'run_card'
2059
2060 - def __new__(cls, finput=None, **opt):
2061 if cls is RunCard:
2062 if not finput:
2063 target_class = RunCardLO
2064 elif isinstance(finput, cls):
2065 target_class = finput.__class__
2066 elif isinstance(finput, str):
2067 if '\n' not in finput:
2068 finput = open(finput).read()
2069 if 'req_acc_FO' in finput:
2070 target_class = RunCardNLO
2071 else:
2072 target_class = RunCardLO
2073 else:
2074 return None
2075 return super(RunCard, cls).__new__(target_class, finput, **opt)
2076 else:
2077 return super(RunCard, cls).__new__(cls, finput, **opt)
2078
2080
2081
2082
2083
2084 self.hidden_param = []
2085
2086 self.includepath = collections.defaultdict(list)
2087
2088 self.fortran_name = {}
2089
2090 self.legacy_parameter = {}
2091
2092 self.cuts_parameter = []
2093
2094 self.system_default = {}
2095
2096
2097
2098
2099 super(RunCard, self).__init__(*args, **opts)
2100
2101 - def add_param(self, name, value, fortran_name=None, include=True,
2102 hidden=False, legacy=False, cut=False, system=False, sys_default=None,
2103 **opts):
2104 """ add a parameter to the card. value is the default value and
2105 defines the type (int/float/bool/str) of the input.
2106 fortran_name defines what is the associate name in the f77 code
2107 include defines if we have to put the value in the include file
2108 hidden defines if the parameter is expected to be define by the user.
2109 legacy:Parameter which is not used anymore (raise a warning if not default)
2110 cut: defines the list of cut parameter to allow to set them all to off.
2111 sys_default: default used if the parameter is not in the card
2112 """
2113
2114 super(RunCard, self).add_param(name, value, system=system,**opts)
2115 name = name.lower()
2116 if fortran_name:
2117 self.fortran_name[name] = fortran_name
2118 if legacy:
2119 self.legacy_parameter[name] = value
2120 include = False
2121 if include is True:
2122 self.includepath[True].append(name)
2123 elif include:
2124 self.includepath[include].append(name)
2125 if hidden or system:
2126 self.hidden_param.append(name)
2127 if cut:
2128 self.cuts_parameter.append(name)
2129 if sys_default is not None:
2130 self.system_default[name] = sys_default
2131
2132
2133
2134 - def read(self, finput, consistency=True):
2135 """Read the input file, this can be a path to a file,
2136 a file object, a str with the content of the file."""
2137
2138 if isinstance(finput, str):
2139 if "\n" in finput:
2140 finput = finput.split('\n')
2141 elif os.path.isfile(finput):
2142 finput = open(finput)
2143 else:
2144 raise Exception, "No such file %s" % finput
2145
2146 for line in finput:
2147 line = line.split('#')[0]
2148 line = line.split('!')[0]
2149 line = line.rsplit('=',1)
2150 if len(line) != 2:
2151 continue
2152 value, name = line
2153 name = name.lower().strip()
2154 if name not in self and ('min' in name or 'max' in name):
2155
2156 self.add_param(name, float(value), hidden=True, cut=True)
2157 else:
2158 self.set( name, value, user=True)
2159
2160 if consistency:
2161 try:
2162 self.check_validity()
2163 except InvalidRunCard, error:
2164 if consistency == 'warning':
2165 logger.warning(str(error))
2166 else:
2167 raise
2168
2169
2170 - def write(self, output_file, template=None, python_template=False):
2171 """Write the run_card in output_file according to template
2172 (a path to a valid run_card)"""
2173
2174 to_write = set(self.user_set)
2175 if not template:
2176 raise Exception
2177
2178 if python_template and not to_write:
2179 if not self.list_parameter:
2180 text = file(template,'r').read() % self
2181 else:
2182 data = dict(self)
2183 for name in self.list_parameter:
2184 data[name] = ', '.join(str(v) for v in data[name])
2185 text = file(template,'r').read() % data
2186 else:
2187 text = ""
2188 for line in file(template,'r'):
2189 nline = line.split('#')[0]
2190 nline = nline.split('!')[0]
2191 comment = line[len(nline):]
2192 nline = nline.split('=')
2193 if len(nline) != 2:
2194 text += line
2195 elif nline[1].strip() in self:
2196 name = nline[1].strip().lower()
2197 value = self[name]
2198 if name in self.list_parameter:
2199 value = ', '.join([str(v) for v in value])
2200 if python_template:
2201 text += line % {nline[1].strip():value, name:value}
2202 else:
2203 if not comment or comment[-1]!='\n':
2204 endline = '\n'
2205 else:
2206 endline = ''
2207 text += ' %s\t= %s %s%s' % (value, name, comment, endline)
2208
2209 if name.lower() in to_write:
2210 to_write.remove(nline[1].strip().lower())
2211 else:
2212 logger.info('Adding missing parameter %s to current %s (with default value)',
2213 (name, self.filename))
2214 text += line
2215
2216 if to_write:
2217 text+="""#*********************************************************************
2218 # Additional parameter
2219 #*********************************************************************
2220 """
2221
2222 for key in to_write:
2223 text += ' %s\t= %s # %s\n' % (self[key], key, 'hidden parameter')
2224
2225 if isinstance(output_file, str):
2226 fsock = open(output_file,'w')
2227 fsock.write(text)
2228 fsock.close()
2229 else:
2230 output_file.write(text)
2231
2232
2233 - def get_default(self, name, default=None, log_level=None):
2234 """return self[name] if exist otherwise default. log control if we
2235 put a warning or not if we use the default value"""
2236
2237 lower_name = name.lower()
2238 if lower_name not in self.user_set:
2239 if log_level is None:
2240 if lower_name in self.system_only:
2241 log_level = 5
2242 elif lower_name in self.auto_set:
2243 log_level = 5
2244 elif lower_name in self.hidden_param:
2245 log_level = 10
2246 else:
2247 log_level = 20
2248 if not default:
2249 default = dict.__getitem__(self, name.lower())
2250 logger.log(log_level, '%s missed argument %s. Takes default: %s'
2251 % (self.filename, name, default))
2252 self[name] = default
2253 return default
2254 else:
2255 return self[name]
2256
2257 @staticmethod
2263
2264 @staticmethod
2313
2314
2316 """check that parameter missing in the card are set to the expected value"""
2317
2318 for name, value in self.system_default.items():
2319 self.set(name, value, changeifuserset=False)
2320
2321 default_include_file = 'run_card.inc'
2322
2324 """Write the various include file in output_dir.
2325 The entry True of self.includepath will be written in run_card.inc
2326 The entry False will not be written anywhere"""
2327
2328
2329 self.check_validity()
2330
2331 for incname in self.includepath:
2332 if incname is True:
2333 pathinc = self.default_include_file
2334 else:
2335 pathinc = incname
2336
2337 fsock = file_writers.FortranWriter(pjoin(output_dir,pathinc))
2338 for key in self.includepath[incname]:
2339
2340 if key in self.fortran_name:
2341 fortran_name = self.fortran_name[key]
2342 else:
2343 fortran_name = key
2344
2345
2346 value = self.get_default(key)
2347
2348
2349 if isinstance(value, list):
2350
2351
2352
2353 if isinstance(value[0], bool):
2354 pass
2355 elif isinstance(value[0], int):
2356 line = '%s(%s) = %s \n' % (fortran_name, 0, self.f77_formatting(len(value)))
2357 fsock.writelines(line)
2358 elif isinstance(value[0], float):
2359 line = '%s(%s) = %s \n' % (fortran_name, 0, self.f77_formatting(float(len(value))))
2360 fsock.writelines(line)
2361
2362 for i,v in enumerate(value):
2363 line = '%s(%s) = %s \n' % (fortran_name, i+1, self.f77_formatting(v))
2364 fsock.writelines(line)
2365 elif isinstance(value, dict):
2366 for fortran_name, onevalue in value.items():
2367 line = '%s = %s \n' % (fortran_name, self.f77_formatting(onevalue))
2368 fsock.writelines(line)
2369 else:
2370 line = '%s = %s \n' % (fortran_name, self.f77_formatting(value))
2371 fsock.writelines(line)
2372 fsock.close()
2373
2374
2392
2393
2394 output["idbmup1"] = get_idbmup(self['lpp1'])
2395 output["idbmup2"] = get_idbmup(self['lpp2'])
2396 output["ebmup1"] = self["ebeam1"]
2397 output["ebmup2"] = self["ebeam2"]
2398 output["pdfgup1"] = 0
2399 output["pdfgup2"] = 0
2400 output["pdfsup1"] = self.get_pdf_id(self["pdlabel"])
2401 output["pdfsup2"] = self.get_pdf_id(self["pdlabel"])
2402 return output
2403
2405 if pdf == "lhapdf":
2406 lhaid = self["lhaid"]
2407 if isinstance(lhaid, list):
2408 return lhaid[0]
2409 else:
2410 return lhaid
2411 else:
2412 return {'none': 0, 'mrs02nl':20250, 'mrs02nn':20270, 'cteq4_m': 19150,
2413 'cteq4_l':19170, 'cteq4_d':19160, 'cteq5_m':19050,
2414 'cteq5_d':19060,'cteq5_l':19070,'cteq5m1':19051,
2415 'cteq6_m':10000,'cteq6_l':10041,'cteq6l1':10042,
2416 'nn23lo':246800,'nn23lo1':247000,'nn23nlo':244800
2417 }[pdf]
2418
2421
2423 """remove all the cut"""
2424
2425 for name in self.cuts_parameter:
2426 targettype = type(self[name])
2427 if targettype == bool:
2428 self[name] = False
2429 elif 'min' in name:
2430 self[name] = 0
2431 elif 'max' in name:
2432 self[name] = -1
2433 elif 'eta' in name:
2434 self[name] = -1
2435 else:
2436 self[name] = 0
2437
2439 """an object to handle in a nice way the run_card information"""
2440
2442 """default value for the run_card.dat"""
2443
2444 self.add_param("run_tag", "tag_1", include=False)
2445 self.add_param("gridpack", False)
2446 self.add_param("time_of_flight", -1.0, include=False, hidden=True)
2447 self.add_param("nevents", 10000)
2448 self.add_param("iseed", 0)
2449 self.add_param("lpp1", 1, fortran_name="lpp(1)")
2450 self.add_param("lpp2", 1, fortran_name="lpp(2)")
2451 self.add_param("ebeam1", 6500.0, fortran_name="ebeam(1)")
2452 self.add_param("ebeam2", 6500.0, fortran_name="ebeam(2)")
2453 self.add_param("polbeam1", 0.0, fortran_name="pb1")
2454 self.add_param("polbeam2", 0.0, fortran_name="pb2")
2455 self.add_param("pdlabel", "nn23lo1")
2456 self.add_param("lhaid", 230000, hidden=True)
2457 self.add_param("fixed_ren_scale", False)
2458 self.add_param("fixed_fac_scale", False)
2459 self.add_param("scale", 91.1880)
2460 self.add_param("dsqrt_q2fact1", 91.1880, fortran_name="sf1")
2461 self.add_param("dsqrt_q2fact2", 91.1880, fortran_name="sf2")
2462 self.add_param("dynamical_scale_choice", -1, comment="\'-1\' is based on CKKW back clustering (following feynman diagram).\n \'1\' is the sum of transverse energy.\n '2' is HT (sum of the transverse mass)\n '3' is HT/2\n '4' is the center of mass energy")
2463
2464
2465 self.add_param("bias_module", 'None', include=False)
2466 self.add_param('bias_parameters', {'__type__':1.0}, include='BIAS/bias.inc')
2467
2468
2469 self.add_param("scalefact", 1.0)
2470 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.")
2471 self.add_param("highestmult", 1, fortran_name="nhmult", hidden=True)
2472 self.add_param("ktscheme", 1, hidden=True)
2473 self.add_param("alpsfact", 1.0)
2474 self.add_param("chcluster", False, hidden=True)
2475 self.add_param("pdfwgt", True, hidden=True)
2476 self.add_param("asrwgtflavor", 5)
2477 self.add_param("clusinfo", True)
2478 self.add_param("lhe_version", 3.0)
2479 self.add_param("event_norm", "average", include=False, sys_default='sum')
2480
2481 self.add_param("auto_ptj_mjj", False)
2482 self.add_param("bwcutoff", 15.0)
2483 self.add_param("cut_decays", False)
2484 self.add_param("nhel", 0, include=False)
2485
2486 self.add_param("ptj", 20.0, cut=True)
2487 self.add_param("ptb", 0.0, cut=True)
2488 self.add_param("pta", 10.0, cut=True)
2489 self.add_param("ptl", 10.0, cut=True)
2490 self.add_param("misset", 0.0, cut=True)
2491 self.add_param("ptheavy", 0.0, cut=True, comment='this cut apply on particle heavier than 10 GeV')
2492 self.add_param("ptonium", 1.0, legacy=True)
2493 self.add_param("ptjmax", -1.0, cut=True)
2494 self.add_param("ptbmax", -1.0, cut=True)
2495 self.add_param("ptamax", -1.0, cut=True)
2496 self.add_param("ptlmax", -1.0, cut=True)
2497 self.add_param("missetmax", -1.0, cut=True)
2498
2499 self.add_param("ej", 0.0, cut=True)
2500 self.add_param("eb", 0.0, cut=True)
2501 self.add_param("ea", 0.0, cut=True)
2502 self.add_param("el", 0.0, cut=True)
2503 self.add_param("ejmax", -1.0, cut=True)
2504 self.add_param("ebmax", -1.0, cut=True)
2505 self.add_param("eamax", -1.0, cut=True)
2506 self.add_param("elmax", -1.0, cut=True)
2507
2508 self.add_param("etaj", 5.0, cut=True)
2509 self.add_param("etab", -1.0, cut=True)
2510 self.add_param("etaa", 2.5, cut=True)
2511 self.add_param("etal", 2.5, cut=True)
2512 self.add_param("etaonium", 0.6, legacy=True)
2513 self.add_param("etajmin", 0.0, cut=True)
2514 self.add_param("etabmin", 0.0, cut=True)
2515 self.add_param("etaamin", 0.0, cut=True)
2516 self.add_param("etalmin", 0.0, cut=True)
2517
2518 self.add_param("drjj", 0.4, cut=True)
2519 self.add_param("drbb", 0.0, cut=True)
2520 self.add_param("drll", 0.4, cut=True)
2521 self.add_param("draa", 0.4, cut=True)
2522 self.add_param("drbj", 0.0, cut=True)
2523 self.add_param("draj", 0.4, cut=True)
2524 self.add_param("drjl", 0.4, cut=True)
2525 self.add_param("drab", 0.0, cut=True)
2526 self.add_param("drbl", 0.0, cut=True)
2527 self.add_param("dral", 0.4, cut=True)
2528 self.add_param("drjjmax", -1.0, cut=True)
2529 self.add_param("drbbmax", -1.0, cut=True)
2530 self.add_param("drllmax", -1.0, cut=True)
2531 self.add_param("draamax", -1.0, cut=True)
2532 self.add_param("drbjmax", -1.0, cut=True)
2533 self.add_param("drajmax", -1.0, cut=True)
2534 self.add_param("drjlmax", -1.0, cut=True)
2535 self.add_param("drabmax", -1.0, cut=True)
2536 self.add_param("drblmax", -1.0, cut=True)
2537 self.add_param("dralmax", -1.0, cut=True)
2538
2539 self.add_param("mmjj", 0.0, cut=True)
2540 self.add_param("mmbb", 0.0, cut=True)
2541 self.add_param("mmaa", 0.0, cut=True)
2542 self.add_param("mmll", 0.0, cut=True)
2543 self.add_param("mmjjmax", -1.0, cut=True)
2544 self.add_param("mmbbmax", -1.0, cut=True)
2545 self.add_param("mmaamax", -1.0, cut=True)
2546 self.add_param("mmllmax", -1.0, cut=True)
2547 self.add_param("mmnl", 0.0, cut=True)
2548 self.add_param("mmnlmax", -1.0, cut=True)
2549
2550 self.add_param("ptllmin", 0.0, cut=True)
2551 self.add_param("ptllmax", -1.0, cut=True)
2552 self.add_param("xptj", 0.0, cut=True)
2553 self.add_param("xptb", 0.0, cut=True)
2554 self.add_param("xpta", 0.0, cut=True)
2555 self.add_param("xptl", 0.0, cut=True)
2556
2557 self.add_param("ptj1min", 0.0, cut=True)
2558 self.add_param("ptj1max", -1.0, cut=True)
2559 self.add_param("ptj2min", 0.0, cut=True)
2560 self.add_param("ptj2max", -1.0, cut=True)
2561 self.add_param("ptj3min", 0.0, cut=True)
2562 self.add_param("ptj3max", -1.0, cut=True)
2563 self.add_param("ptj4min", 0.0, cut=True)
2564 self.add_param("ptj4max", -1.0, cut=True)
2565 self.add_param("cutuse", 0, cut=True)
2566
2567 self.add_param("ptl1min", 0.0, cut=True)
2568 self.add_param("ptl1max", -1.0, cut=True)
2569 self.add_param("ptl2min", 0.0, cut=True)
2570 self.add_param("ptl2max", -1.0, cut=True)
2571 self.add_param("ptl3min", 0.0, cut=True)
2572 self.add_param("ptl3max", -1.0, cut=True)
2573 self.add_param("ptl4min", 0.0, cut=True)
2574 self.add_param("ptl4max", -1.0, cut=True)
2575
2576 self.add_param("htjmin", 0.0, cut=True)
2577 self.add_param("htjmax", -1.0, cut=True)
2578 self.add_param("ihtmin", 0.0, cut=True)
2579 self.add_param("ihtmax", -1.0, cut=True)
2580 self.add_param("ht2min", 0.0, cut=True)
2581 self.add_param("ht3min", 0.0, cut=True)
2582 self.add_param("ht4min", 0.0, cut=True)
2583 self.add_param("ht2max", -1.0, cut=True)
2584 self.add_param("ht3max", -1.0, cut=True)
2585 self.add_param("ht4max", -1.0, cut=True)
2586
2587 self.add_param("ptgmin", 0.0, cut=True)
2588 self.add_param("r0gamma", 0.4)
2589 self.add_param("xn", 1.0)
2590 self.add_param("epsgamma", 1.0)
2591 self.add_param("isoem", True)
2592 self.add_param("xetamin", 0.0, cut=True)
2593 self.add_param("deltaeta", 0.0, cut=True)
2594 self.add_param("ktdurham", -1.0, fortran_name="kt_durham", cut=True)
2595 self.add_param("dparameter", 0.4, fortran_name="d_parameter", cut=True)
2596 self.add_param("ptlund", -1.0, fortran_name="pt_lund", cut=True)
2597 self.add_param("pdgs_for_merging_cut", [21, 1, 2, 3, 4, 5, 6])
2598 self.add_param("maxjetflavor", 4)
2599 self.add_param("xqcut", 0.0, cut=True)
2600 self.add_param("use_syst", True)
2601 self.add_param('systematics_program', 'auto', include=False, hidden=True, comment='Choose which program to use for systematics computation: none, systematics, syscalc')
2602 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.')
2603
2604 self.add_param("sys_scalefact", "0.5 1 2", include=False)
2605 self.add_param("sys_alpsfact", "None", include=False)
2606 self.add_param("sys_matchscale", "auto", include=False)
2607 self.add_param("sys_pdf", "NNPDF23_lo_as_0130_qed", include=False)
2608 self.add_param("sys_scalecorrelation", -1, include=False)
2609
2610
2611 self.add_param('gridrun', False, hidden=True)
2612 self.add_param('fixed_couplings', True, hidden=True)
2613 self.add_param('mc_grouped_subproc', True, hidden=True)
2614 self.add_param('xmtcentral', 0.0, hidden=True, fortran_name="xmtc")
2615 self.add_param('d', 1.0, hidden=True)
2616 self.add_param('gseed', 0, hidden=True, include=False)
2617 self.add_param('issgridfile', '', hidden=True)
2618
2619 self.add_param('job_strategy', 0, hidden=True, include=False)
2620 self.add_param('survey_splitting', -1, hidden=True, include=False)
2621 self.add_param('refine_evt_by_job', -1, hidden=True, include=False)
2622
2623
2625 """ """
2626
2627 super(RunCardLO, self).check_validity()
2628
2629
2630
2631
2632 if 'nhel' not in self.user_set:
2633 raise InvalidRunCard, "Parameter nhel is not defined in the run_card."
2634 if self['nhel'] not in [1,0]:
2635 raise InvalidRunCard, "Parameter nhel can only be '0' or '1', "+\
2636 "not %s." % self['nhel']
2637 if int(self['maxjetflavor']) > 6:
2638 raise InvalidRunCard, 'maxjetflavor should be lower than 5! (6 is partly supported)'
2639
2640 if len(self['pdgs_for_merging_cut']) > 1000:
2641 raise InvalidRunCard, "The number of elements in "+\
2642 "'pdgs_for_merging_cut' should not exceed 1000."
2643
2644
2645 if self['ptgmin'] > 0:
2646 if self['pta'] > 0:
2647 logger.warning('pta cut discarded since photon isolation is used')
2648 self['pta'] = 0.0
2649 if self['draj'] > 0:
2650 logger.warning('draj cut discarded since photon isolation is used')
2651 self['draj'] = 0.0
2652
2653
2654 if self['gridrun']:
2655 self['iseed'] = self['gseed']
2656
2657
2658 if self['use_syst']:
2659 if self['scalefact'] != 1.0:
2660 logger.warning('Since use_syst=T, We change the value of \'scalefact\' to 1')
2661 self['scalefact'] = 1.0
2662
2663
2664 if self['ickkw'] > 0:
2665 if self['ickkw'] != 1:
2666 logger.critical('ickkw >1 is pure alpha and only partly implemented.')
2667 import madgraph.interface.extended_cmd as basic_cmd
2668 answer = basic_cmd.smart_input('Do you really want to continue', allow_arg=['y','n'], default='n')
2669 if answer !='y':
2670 raise InvalidRunCard, 'ickkw>1 is still in alpha'
2671 if self['use_syst']:
2672
2673 if self['alpsfact'] != 1.0:
2674 logger.warning('Since use_syst=T, We change the value of \'alpsfact\' to 1')
2675 self['alpsfact'] =1.0
2676 if self['maxjetflavor'] == 6:
2677 raise InvalidRunCard, 'maxjetflavor at 6 is NOT supported for matching!'
2678 if self['ickkw'] == 2:
2679
2680 self.get_default('highestmult', log_level=20)
2681 self.get_default('issgridfile', 'issudgrid.dat', log_level=20)
2682 if self['xqcut'] > 0:
2683 if self['ickkw'] == 0:
2684 logger.error('xqcut>0 but ickkw=0. Potentially not fully consistent setup. Be carefull')
2685 import time
2686 time.sleep(5)
2687 if self['drjj'] != 0:
2688 logger.warning('Since icckw>0, We change the value of \'drjj\' to 0')
2689 self['drjj'] = 0
2690 if self['drjl'] != 0:
2691 logger.warning('Since icckw>0, We change the value of \'drjl\' to 0')
2692 self['drjl'] = 0
2693 if not self['auto_ptj_mjj']:
2694 if self['mmjj'] > self['xqcut']:
2695 logger.warning('mmjj > xqcut (and auto_ptj_mjj = F). MMJJ set to 0')
2696 self['mmjj'] = 0.0
2697
2698
2699
2700
2701 possible_set = ['lhapdf', 'mrs02nl','mrs02nn',
2702 'cteq4_m', 'cteq4_l','cteq4_d',
2703 'cteq5_m','cteq5_d','cteq5_l','cteq5m1',
2704 'cteq6_m','cteq6_l', 'cteq6l1',
2705 'nn23lo', 'nn23lo1', 'nn23nlo']
2706
2707
2708 if self['pdlabel'] not in possible_set:
2709 raise InvalidRunCard, 'Invalid PDF set (argument of pdlabel): %s. Possible choice are:\n %s' % (self['pdlabel'], ', '.join(possible_set))
2710 if self['pdlabel'] == 'lhapdf':
2711
2712 self.get_default('lhaid', log_level=20)
2713
2714 for name in self.legacy_parameter:
2715 if self[name] != self.legacy_parameter[name]:
2716 logger.warning("The parameter %s is not supported anymore this parameter will be ignored." % name)
2717
2718
2719
2720
2722 """Rules
2723 process 1->N all cut set on off.
2724 loop_induced -> MC over helicity
2725 e+ e- beam -> lpp:0 ebeam:500
2726 p p beam -> set maxjetflavor automatically
2727 more than one multiplicity: ickkw=1 xqcut=30 use_syst=F
2728 """
2729
2730 if proc_characteristic['loop_induced']:
2731 self['nhel'] = 1
2732 self['pdgs_for_merging_cut'] = proc_characteristic['colored_pdgs']
2733
2734 if proc_characteristic['ninitial'] == 1:
2735
2736 self.remove_all_cut()
2737 self['use_syst'] = False
2738 else:
2739
2740 beam_id = set()
2741 for proc in proc_def:
2742 for oneproc in proc:
2743 for leg in oneproc['legs']:
2744 if not leg['state']:
2745 beam_id.add(leg['id'])
2746 if any(i in beam_id for i in [1,-1,2,-2,3,-3,4,-4,5,-5,21,22]):
2747 maxjetflavor = max([4]+[abs(i) for i in beam_id if -7< i < 7])
2748 self['maxjetflavor'] = maxjetflavor
2749 self['asrwgtflavor'] = maxjetflavor
2750 pass
2751 elif 11 in beam_id or -11 in beam_id:
2752 self['lpp1'] = 0
2753 self['lpp2'] = 0
2754 self['ebeam1'] = 500
2755 self['ebeam2'] = 500
2756 else:
2757 self['lpp1'] = 0
2758 self['lpp2'] = 0
2759
2760
2761 min_particle = 99
2762 max_particle = 0
2763 for proc in proc_def:
2764 min_particle = min(len(proc[0]['legs']), min_particle)
2765 max_particle = max(len(proc[0]['legs']), max_particle)
2766 if min_particle != max_particle:
2767
2768 for procmin in proc_def:
2769 if len(procmin[0]['legs']) != min_particle:
2770 continue
2771 else:
2772 idsmin = [l['id'] for l in procmin[0]['legs']]
2773 break
2774 matching = False
2775 for procmax in proc_def:
2776 if len(procmax[0]['legs']) != max_particle:
2777 continue
2778 idsmax = [l['id'] for l in procmax[0]['legs']]
2779 for i in idsmin:
2780 if i not in idsmax:
2781 continue
2782 else:
2783 idsmax.remove(i)
2784 for j in idsmax:
2785 if j not in [1,-1,2,-2,3,-3,4,-4,5,-5,21]:
2786 break
2787 else:
2788
2789 matching=True
2790 break
2791
2792 if matching:
2793 self['ickkw'] = 1
2794 self['xqcut'] = 30
2795
2796 self['drjj'] = 0
2797 self['drjl'] = 0
2798 self['sys_alpsfact'] = "0.5 1 2"
2799
2800
2801
2802 no_systematics = False
2803 for proc in proc_def:
2804 for oneproc in proc:
2805 if '^2' in oneproc.nice_string():
2806 no_systematics = True
2807 break
2808 else:
2809 continue
2810 break
2811 if no_systematics:
2812 self['use_syst'] = False
2813 self['systematics_program'] = 'none'
2814
2815 - def write(self, output_file, template=None, python_template=False):
2816 """Write the run_card in output_file according to template
2817 (a path to a valid run_card)"""
2818
2819 if not template:
2820 if not MADEVENT:
2821 template = pjoin(MG5DIR, 'Template', 'LO', 'Cards',
2822 'run_card.dat')
2823 python_template = True
2824 else:
2825 template = pjoin(MEDIR, 'Cards', 'run_card_default.dat')
2826 python_template = False
2827
2828 super(RunCardLO, self).write(output_file, template=template,
2829 python_template=python_template)
2830
2834
2836 """ A class to store a MadAnalysis5 card. Very basic since it is basically
2837 free format."""
2838
2839 _MG5aMC_escape_tag = '@MG5aMC'
2840
2841 _default_hadron_inputs = ['*.hepmc', '*.hep', '*.stdhep', '*.lhco','*.root']
2842 _default_parton_inputs = ['*.lhe']
2843 _skip_analysis = False
2844
2845 @classmethod
2847 """ Checks from the type of an event file whether it can be reconstructed or not."""
2848 return not (file_path.endswith('.lhco') or file_path.endswith('.lhco.gz') or \
2849 file_path.endswith('.root') or file_path.endswith('.root.gz'))
2850
2851 @classmethod
2853 """ A method returning the structure of an empty analysis """
2854 return {'commands':[],
2855 'reconstructions':[]}
2856
2857 @classmethod
2859 """ A method returning the structure of an empty reconstruction """
2860 return {'commands':[],
2861 'reco_output':'lhe'}
2862
2864 """define the default value"""
2865 self['mode'] = 'parton'
2866 self['inputs'] = []
2867
2868 self['stdout_lvl'] = None
2869
2870
2871
2872
2873
2874
2875
2876 self['analyses'] = {}
2877
2878
2879 self['recasting'] = {'commands':[],'card':[]}
2880
2881
2882 self['reconstruction'] = {'lhco_input':
2883 MadAnalysis5Card.empty_reconstruction(),
2884 'root_input':
2885 MadAnalysis5Card.empty_reconstruction()}
2886 self['reconstruction']['lhco_input']['reco_output']='lhco'
2887 self['reconstruction']['root_input']['reco_output']='root'
2888
2889
2890 self['order'] = []
2891
2892 - def __init__(self, finput=None,mode=None):
2893 if isinstance(finput, self.__class__):
2894 dict.__init__(self, finput)
2895 assert finput.__dict__.keys()
2896 for key in finput.__dict__:
2897 setattr(self, key, copy.copy(getattr(finput, key)) )
2898 return
2899 else:
2900 dict.__init__(self)
2901
2902
2903 self.default_setup()
2904 if not mode is None:
2905 self['mode']=mode
2906
2907
2908 if isinstance(finput, (file, str, StringIO.StringIO)):
2909 self.read(finput, mode=mode)
2910
2911 - def read(self, input, mode=None):
2912 """ Read an MA5 card"""
2913
2914 if mode not in [None,'parton','hadron']:
2915 raise MadGraph5Error('A MadAnalysis5Card can be read online the modes'+
2916 "'parton' or 'hadron'")
2917 card_mode = mode
2918
2919 if isinstance(input, (file, StringIO.StringIO)):
2920 input_stream = input
2921 elif isinstance(input, str):
2922 if not os.path.isfile(input):
2923 raise InvalidMadAnalysis5Card("Cannot read the MadAnalysis5 card."+\
2924 "File '%s' not found."%input)
2925 if mode is None and 'hadron' in input:
2926 card_mode = 'hadron'
2927 input_stream = open(input,'r')
2928 else:
2929 raise MadGraph5Error('Incorrect input for the read function of'+\
2930 ' the MadAnalysis5Card card. Received argument type is: %s'%str(type(input)))
2931
2932
2933 self.__init__()
2934 current_name = 'default'
2935 current_type = 'analyses'
2936 for line in input_stream:
2937
2938 if line.startswith('#'):
2939 continue
2940 if line.endswith('\n'):
2941 line = line[:-1]
2942 if line.strip()=='':
2943 continue
2944 if line.startswith(self._MG5aMC_escape_tag):
2945 try:
2946 option,value = line[len(self._MG5aMC_escape_tag):].split('=')
2947 value = value.strip()
2948 except ValueError:
2949 option = line[len(self._MG5aMC_escape_tag):]
2950 option = option.strip()
2951
2952 if option=='inputs':
2953 self['inputs'].extend([v.strip() for v in value.split(',')])
2954
2955 elif option == 'skip_analysis':
2956 self._skip_analysis = True
2957
2958 elif option=='stdout_lvl':
2959 try:
2960 self['stdout_lvl']=int(value)
2961 except ValueError:
2962 try:
2963 self['stdout_lvl']=eval(value)
2964 except:
2965 try:
2966 self['stdout_lvl']=eval('logging.%s'%value)
2967 except:
2968 raise InvalidMadAnalysis5Card(
2969 "MA5 output level specification '%s' is incorrect."%str(value))
2970
2971 elif option=='analysis_name':
2972 current_type = 'analyses'
2973 current_name = value
2974 if current_name in self[current_type]:
2975 raise InvalidMadAnalysis5Card(
2976 "Analysis '%s' already defined in MadAnalysis5 card"%current_name)
2977 else:
2978 self[current_type][current_name] = MadAnalysis5Card.empty_analysis()
2979
2980 elif option=='set_reconstructions':
2981 try:
2982 reconstructions = eval(value)
2983 if not isinstance(reconstructions, list):
2984 raise
2985 except:
2986 raise InvalidMadAnalysis5Card("List of reconstructions"+\
2987 " '%s' could not be parsed in MadAnalysis5 card."%value)
2988 if current_type!='analyses' and current_name not in self[current_type]:
2989 raise InvalidMadAnalysis5Card("A list of reconstructions"+\
2990 "can only be defined in the context of an "+\
2991 "analysis in a MadAnalysis5 card.")
2992 self[current_type][current_name]['reconstructions']=reconstructions
2993 continue
2994
2995 elif option=='reconstruction_name':
2996 current_type = 'reconstruction'
2997 current_name = value
2998 if current_name in self[current_type]:
2999 raise InvalidMadAnalysis5Card(
3000 "Reconstruction '%s' already defined in MadAnalysis5 hadron card"%current_name)
3001 else:
3002 self[current_type][current_name] = MadAnalysis5Card.empty_reconstruction()
3003
3004 elif option=='reco_output':
3005 if current_type!='reconstruction' or current_name not in \
3006 self['reconstruction']:
3007 raise InvalidMadAnalysis5Card(
3008 "Option '%s' is only available within the definition of a reconstruction"%option)
3009 if not value.lower() in ['lhe','root']:
3010 raise InvalidMadAnalysis5Card(
3011 "Option '%s' can only take the values 'lhe' or 'root'"%option)
3012 self['reconstruction'][current_name]['reco_output'] = value.lower()
3013
3014 elif option.startswith('recasting'):
3015 current_type = 'recasting'
3016 try:
3017 current_name = option.split('_')[1]
3018 except:
3019 raise InvalidMadAnalysis5Card('Malformed MA5 recasting option %s.'%option)
3020 if len(self['recasting'][current_name])>0:
3021 raise InvalidMadAnalysis5Card(
3022 "Only one recasting can be defined in MadAnalysis5 hadron card")
3023
3024 else:
3025 raise InvalidMadAnalysis5Card(
3026 "Unreckognized MG5aMC instruction in MadAnalysis5 card: '%s'"%option)
3027
3028 if option in ['analysis_name','reconstruction_name'] or \
3029 option.startswith('recasting'):
3030 self['order'].append((current_type,current_name))
3031 continue
3032
3033
3034
3035 if current_name == 'default' and current_type == 'analyses' and\
3036 'default' not in self['analyses']:
3037 self['analyses']['default'] = MadAnalysis5Card.empty_analysis()
3038 self['order'].append(('analyses','default'))
3039
3040 if current_type in ['recasting']:
3041 self[current_type][current_name].append(line)
3042 elif current_type in ['reconstruction']:
3043 self[current_type][current_name]['commands'].append(line)
3044 elif current_type in ['analyses']:
3045 self[current_type][current_name]['commands'].append(line)
3046
3047 if 'reconstruction' in self['analyses'] or len(self['recasting']['card'])>0:
3048 if mode=='parton':
3049 raise InvalidMadAnalysis5Card(
3050 "A parton MadAnalysis5 card cannot specify a recombination or recasting.")
3051 card_mode = 'hadron'
3052 elif mode is None:
3053 card_mode = 'parton'
3054
3055 self['mode'] = card_mode
3056 if self['inputs'] == []:
3057 if self['mode']=='hadron':
3058 self['inputs'] = self._default_hadron_inputs
3059 else:
3060 self['inputs'] = self._default_parton_inputs
3061
3062
3063
3064 if self['mode']=='hadron':
3065 for analysis_name, analysis in self['analyses'].items():
3066 if len(analysis['reconstructions'])==0:
3067 raise InvalidMadAnalysis5Card('Hadron-level analysis '+\
3068 "'%s' is not specified any reconstruction(s)."%analysis_name)
3069 if any(reco not in self['reconstruction'] for reco in \
3070 analysis['reconstructions']):
3071 raise InvalidMadAnalysis5Card('A reconstructions specified in'+\
3072 " analysis '%s' is not defined."%analysis_name)
3073
3074 - def write(self, output):
3075 """ Write an MA5 card."""
3076
3077 if isinstance(output, (file, StringIO.StringIO)):
3078 output_stream = output
3079 elif isinstance(output, str):
3080 output_stream = open(output,'w')
3081 else:
3082 raise MadGraph5Error('Incorrect input for the write function of'+\
3083 ' the MadAnalysis5Card card. Received argument type is: %s'%str(type(output)))
3084
3085 output_lines = []
3086 if self._skip_analysis:
3087 output_lines.append('%s skip_analysis'%self._MG5aMC_escape_tag)
3088 output_lines.append('%s inputs = %s'%(self._MG5aMC_escape_tag,','.join(self['inputs'])))
3089 if not self['stdout_lvl'] is None:
3090 output_lines.append('%s stdout_lvl=%s'%(self._MG5aMC_escape_tag,self['stdout_lvl']))
3091 for definition_type, name in self['order']:
3092
3093 if definition_type=='analyses':
3094 output_lines.append('%s analysis_name = %s'%(self._MG5aMC_escape_tag,name))
3095 output_lines.append('%s set_reconstructions = %s'%(self._MG5aMC_escape_tag,
3096 str(self['analyses'][name]['reconstructions'])))
3097 elif definition_type=='reconstruction':
3098 output_lines.append('%s reconstruction_name = %s'%(self._MG5aMC_escape_tag,name))
3099 elif definition_type=='recasting':
3100 output_lines.append('%s recasting_%s'%(self._MG5aMC_escape_tag,name))
3101
3102 if definition_type in ['recasting']:
3103 output_lines.extend(self[definition_type][name])
3104 elif definition_type in ['reconstruction']:
3105 output_lines.append('%s reco_output = %s'%(self._MG5aMC_escape_tag,
3106 self[definition_type][name]['reco_output']))
3107 output_lines.extend(self[definition_type][name]['commands'])
3108 elif definition_type in ['analyses']:
3109 output_lines.extend(self[definition_type][name]['commands'])
3110
3111 output_stream.write('\n'.join(output_lines))
3112
3113 return
3114
3115 - def get_MA5_cmds(self, inputs_arg, submit_folder, run_dir_path=None,
3116 UFO_model_path=None, run_tag=''):
3117 """ Returns a list of tuples ('AnalysisTag',['commands']) specifying
3118 the commands of the MadAnalysis runs required from this card.
3119 At parton-level, the number of such commands is the number of analysis
3120 asked for. In the future, the idea is that the entire card can be
3121 processed in one go from MA5 directly."""
3122
3123 if isinstance(inputs_arg, list):
3124 inputs = inputs_arg
3125 elif isinstance(inputs_arg, str):
3126 inputs = [inputs_arg]
3127 else:
3128 raise MadGraph5Error("The function 'get_MA5_cmds' can only take "+\
3129 " a string or a list for the argument 'inputs_arg'")
3130
3131 if len(inputs)==0:
3132 raise MadGraph5Error("The function 'get_MA5_cmds' must have "+\
3133 " at least one input specified'")
3134
3135 if run_dir_path is None:
3136 run_dir_path = os.path.dirname(inputs_arg)
3137
3138 cmds_list = []
3139
3140 UFO_load = []
3141
3142 if UFO_model_path:
3143 UFO_load.append('import %s'%UFO_model_path)
3144
3145 def get_import(input, type=None):
3146 """ Generates the MA5 import commands for that event file. """
3147 dataset_name = os.path.basename(input).split('.')[0]
3148 res = ['import %s as %s'%(input, dataset_name)]
3149 if not type is None:
3150 res.append('set %s.type = %s'%(dataset_name, type))
3151 return res
3152
3153 fifo_status = {'warned_fifo':False,'fifo_used_up':False}
3154 def warn_fifo(input):
3155 if not input.endswith('.fifo'):
3156 return False
3157 if not fifo_status['fifo_used_up']:
3158 fifo_status['fifo_used_up'] = True
3159 return False
3160 else:
3161 if not fifo_status['warned_fifo']:
3162 logger.warning('Only the first MA5 analysis/reconstructions can be run on a fifo. Subsequent runs will skip fifo inputs.')
3163 fifo_status['warned_fifo'] = True
3164 return True
3165
3166
3167 inputs_load = []
3168 for input in inputs:
3169 inputs_load.extend(get_import(input))
3170
3171 submit_command = 'submit %s'%submit_folder+'_%s'
3172
3173
3174
3175
3176 reconstruction_outputs = {
3177 'lhco_input':[f for f in inputs if
3178 f.endswith('.lhco') or f.endswith('.lhco.gz')],
3179 'root_input':[f for f in inputs if
3180 f.endswith('.root') or f.endswith('.root.gz')]}
3181
3182
3183 recasting_card_path = pjoin(run_dir_path,
3184 '_'.join([run_tag,os.path.basename(submit_folder),'recasting_card.dat']))
3185
3186
3187 for definition_type, name in self['order']:
3188 if definition_type == 'reconstruction':
3189 analysis_cmds = list(self['reconstruction'][name]['commands'])
3190 reco_outputs = []
3191 for i_input, input in enumerate(inputs):
3192
3193 if not MadAnalysis5Card.events_can_be_reconstructed(input):
3194 continue
3195
3196 if warn_fifo(input):
3197 continue
3198 analysis_cmds.append('import %s as reco_events'%input)
3199 if self['reconstruction'][name]['reco_output']=='lhe':
3200 reco_outputs.append('%s_%s.lhe.gz'%(os.path.basename(
3201 input).replace('_events','').split('.')[0],name))
3202 analysis_cmds.append('set main.outputfile=%s'%reco_outputs[-1])
3203 elif self['reconstruction'][name]['reco_output']=='root':
3204 reco_outputs.append('%s_%s.root'%(os.path.basename(
3205 input).replace('_events','').split('.')[0],name))
3206 analysis_cmds.append('set main.fastsim.rootfile=%s'%reco_outputs[-1])
3207 analysis_cmds.append(
3208 submit_command%('reco_%s_%d'%(name,i_input+1)))
3209 analysis_cmds.append('remove reco_events')
3210
3211 reconstruction_outputs[name]= [pjoin(run_dir_path,rec_out)
3212 for rec_out in reco_outputs]
3213 if len(reco_outputs)>0:
3214 cmds_list.append(('_reco_%s'%name,analysis_cmds))
3215
3216 elif definition_type == 'analyses':
3217 if self['mode']=='parton':
3218 cmds_list.append( (name, UFO_load+inputs_load+
3219 self['analyses'][name]['commands']+[submit_command%name]) )
3220 elif self['mode']=='hadron':
3221
3222 for reco in self['analyses'][name]['reconstructions']+\
3223 ['lhco_input','root_input']:
3224 if len(reconstruction_outputs[reco])==0:
3225 continue
3226 if self['reconstruction'][reco]['reco_output']=='lhe':
3227
3228 analysis_cmds = ['set main.mode = parton']
3229 else:
3230 analysis_cmds = []
3231 analysis_cmds.extend(sum([get_import(rec_out) for
3232 rec_out in reconstruction_outputs[reco]],[]))
3233 analysis_cmds.extend(self['analyses'][name]['commands'])
3234 analysis_cmds.append(submit_command%('%s_%s'%(name,reco)))
3235 cmds_list.append( ('%s_%s'%(name,reco),analysis_cmds) )
3236
3237 elif definition_type == 'recasting':
3238 if len(self['recasting']['card'])==0:
3239 continue
3240 if name == 'card':
3241
3242 open(recasting_card_path,'w').write('\n'.join(self['recasting']['card']))
3243 if name == 'commands':
3244 recasting_cmds = list(self['recasting']['commands'])
3245
3246 n_inputs = 0
3247 for input in inputs:
3248 if not MadAnalysis5Card.events_can_be_reconstructed(input):
3249 continue
3250
3251 if warn_fifo(input):
3252 continue
3253 recasting_cmds.extend(get_import(input,'signal'))
3254 n_inputs += 1
3255
3256 recasting_cmds.append('set main.recast.card_path=%s'%recasting_card_path)
3257 recasting_cmds.append(submit_command%'Recasting')
3258 if n_inputs>0:
3259 cmds_list.append( ('Recasting',recasting_cmds))
3260
3261 return cmds_list
3262
3264 """A class object for the run_card for a (aMC@)NLO pocess"""
3265
3267 """define the default value"""
3268
3269 self.add_param('run_tag', 'tag_1', include=False)
3270 self.add_param('nevents', 10000)
3271 self.add_param('req_acc', -1.0, include=False)
3272 self.add_param('nevt_job', -1, include=False)
3273 self.add_param('event_norm', 'average')
3274
3275 self.add_param('req_acc_fo', 0.01, include=False)
3276 self.add_param('npoints_fo_grid', 5000, include=False)
3277 self.add_param('niters_fo_grid', 4, include=False)
3278 self.add_param('npoints_fo', 10000, include=False)
3279 self.add_param('niters_fo', 6, include=False)
3280
3281 self.add_param('iseed', 0)
3282 self.add_param('lpp1', 1, fortran_name='lpp(1)')
3283 self.add_param('lpp2', 1, fortran_name='lpp(2)')
3284 self.add_param('ebeam1', 6500.0, fortran_name='ebeam(1)')
3285 self.add_param('ebeam2', 6500.0, fortran_name='ebeam(2)')
3286 self.add_param('pdlabel', 'nn23nlo')
3287 self.add_param('lhaid', [244600],fortran_name='lhaPDFid')
3288 self.add_param('lhapdfsetname', ['internal_use_only'], system=True)
3289
3290 self.add_param('parton_shower', 'HERWIG6', fortran_name='shower_mc')
3291 self.add_param('shower_scale_factor',1.0)
3292 self.add_param('fixed_ren_scale', False)
3293 self.add_param('fixed_fac_scale', False)
3294 self.add_param('mur_ref_fixed', 91.118)
3295 self.add_param('muf1_ref_fixed', -1.0, hidden=True)
3296 self.add_param('muf_ref_fixed', 91.118)
3297 self.add_param('muf2_ref_fixed', -1.0, hidden=True)
3298 self.add_param("dynamical_scale_choice", [-1],fortran_name='dyn_scale', comment="\'-1\' is based on CKKW back clustering (following feynman diagram).\n \'1\' is the sum of transverse energy.\n '2' is HT (sum of the transverse mass)\n '3' is HT/2\n '4' is the center of mass energy")
3299 self.add_param('fixed_qes_scale', False, hidden=True)
3300 self.add_param('qes_ref_fixed', -1.0, hidden=True)
3301 self.add_param('mur_over_ref', 1.0)
3302 self.add_param('muf_over_ref', 1.0)
3303 self.add_param('muf1_over_ref', -1.0, hidden=True)
3304 self.add_param('muf2_over_ref', -1.0, hidden=True)
3305 self.add_param('qes_over_ref', -1.0, hidden=True)
3306 self.add_param('reweight_scale', [True], fortran_name='lscalevar')
3307 self.add_param('rw_rscale_down', -1.0, hidden=True)
3308 self.add_param('rw_rscale_up', -1.0, hidden=True)
3309 self.add_param('rw_fscale_down', -1.0, hidden=True)
3310 self.add_param('rw_fscale_up', -1.0, hidden=True)
3311 self.add_param('rw_rscale', [1.0,2.0,0.5], fortran_name='scalevarR')
3312 self.add_param('rw_fscale', [1.0,2.0,0.5], fortran_name='scalevarF')
3313 self.add_param('reweight_pdf', [False], fortran_name='lpdfvar')
3314 self.add_param('pdf_set_min', 244601, hidden=True)
3315 self.add_param('pdf_set_max', 244700, hidden=True)
3316 self.add_param('store_rwgt_info', False)
3317 self.add_param('systematics_program', 'none', include=False, hidden=True, comment='Choose which program to use for systematics computation: none, systematics')
3318 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.')
3319
3320
3321 self.add_param('ickkw', 0)
3322 self.add_param('bwcutoff', 15.0)
3323
3324 self.add_param('jetalgo', 1.0)
3325 self.add_param('jetradius', 0.7)
3326 self.add_param('ptj', 10.0 , cut=True)
3327 self.add_param('etaj', -1.0, cut=True)
3328 self.add_param('ptl', 0.0, cut=True)
3329 self.add_param('etal', -1.0, cut=True)
3330 self.add_param('drll', 0.0, cut=True)
3331 self.add_param('drll_sf', 0.0, cut=True)
3332 self.add_param('mll', 0.0, cut=True)
3333 self.add_param('mll_sf', 30.0, cut=True)
3334 self.add_param('ptgmin', 20.0, cut=True)
3335 self.add_param('etagamma', -1.0)
3336 self.add_param('r0gamma', 0.4)
3337 self.add_param('xn', 1.0)
3338 self.add_param('epsgamma', 1.0)
3339 self.add_param('isoem', True)
3340 self.add_param('maxjetflavor', 4, hidden=True)
3341 self.add_param('iappl', 0)
3342 self.add_param('lhe_version', 3, hidden=True, include=False)
3343
3344
3345 self.add_param('FO_LHE_weight_ratio',1e-3, hidden=True, system=True)
3346 self.add_param('FO_LHE_postprocessing',['grouping','random'],
3347 hidden=True, system=True, include=False)
3348
3350 """check the validity of the various input"""
3351
3352 super(RunCardNLO, self).check_validity()
3353
3354
3355 if self['ickkw'] == 3:
3356
3357 scales=['fixed_ren_scale','fixed_fac_scale','fixed_QES_scale']
3358 for scale in scales:
3359 if self[scale]:
3360 logger.warning('''For consistency in the FxFx merging, \'%s\' has been set to false'''
3361 % scale,'$MG:color:BLACK')
3362 self[scale]= False
3363
3364 if len(self["dynamical_scale_choice"]) > 1 or self["dynamical_scale_choice"][0] != -1:
3365 self["dynamical_scale_choice"] = [-1]
3366 self["reweight_scale"]=[self["reweight_scale"][0]]
3367 logger.warning('''For consistency in the FxFx merging, dynamical_scale_choice has been set to -1 (default)'''
3368 ,'$MG:color:BLACK')
3369
3370
3371 jetparams=['jetradius','jetalgo']
3372 for jetparam in jetparams:
3373 if float(self[jetparam]) != 1.0:
3374 logger.info('''For consistency in the FxFx merging, \'%s\' has been set to 1.0'''
3375 % jetparam ,'$MG:color:BLACK')
3376 self[jetparam] = 1.0
3377 elif self['ickkw'] == -1 and (self["dynamical_scale_choice"][0] != -1 or
3378 len(self["dynamical_scale_choice"]) > 1):
3379 self["dynamical_scale_choice"] = [-1]
3380 self["reweight_scale"]=[self["reweight_scale"][0]]
3381 logger.warning('''For consistency with the jet veto, the scale which will be used is ptj. dynamical_scale_choice will be set at -1.'''
3382 ,'$MG:color:BLACK')
3383
3384
3385 if self['iappl'] != 0 and self['pdlabel'].lower() != 'lhapdf':
3386 raise InvalidRunCard('APPLgrid generation only possible with the use of LHAPDF')
3387 if self['iappl'] != 0 and not self['reweight_scale']:
3388 raise InvalidRunCard('APPLgrid generation only possible with including' +\
3389 ' the reweighting to get scale dependence')
3390
3391
3392 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']
3393 if self['pdlabel'] not in possible_set:
3394 raise InvalidRunCard, 'Invalid PDF set (argument of pdlabel) possible choice are:\n %s' % ','.join(possible_set)
3395
3396
3397 if self['qes_ref_fixed'] == -1.0:
3398 self['qes_ref_fixed']=self['mur_ref_fixed']
3399 if self['qes_over_ref'] == -1.0:
3400 self['qes_over_ref']=self['mur_over_ref']
3401 if self['muf1_over_ref'] != -1.0 and self['muf1_over_ref'] == self['muf2_over_ref']:
3402 self['muf_over_ref']=self['muf1_over_ref']
3403 if self['muf1_over_ref'] == -1.0:
3404 self['muf1_over_ref']=self['muf_over_ref']
3405 if self['muf2_over_ref'] == -1.0:
3406 self['muf2_over_ref']=self['muf_over_ref']
3407 if self['muf1_ref_fixed'] != -1.0 and self['muf1_ref_fixed'] == self['muf2_ref_fixed']:
3408 self['muf_ref_fixed']=self['muf1_ref_fixed']
3409 if self['muf1_ref_fixed'] == -1.0:
3410 self['muf1_ref_fixed']=self['muf_ref_fixed']
3411 if self['muf2_ref_fixed'] == -1.0:
3412 self['muf2_ref_fixed']=self['muf_ref_fixed']
3413
3414 if (self['rw_rscale_down'] != -1.0 and ['rw_rscale_down'] not in self['rw_rscale']) or\
3415 (self['rw_rscale_up'] != -1.0 and ['rw_rscale_up'] not in self['rw_rscale']):
3416 self['rw_rscale']=[1.0,self['rw_rscale_up'],self['rw_rscale_down']]
3417 if (self['rw_fscale_down'] != -1.0 and ['rw_fscale_down'] not in self['rw_fscale']) or\
3418 (self['rw_fscale_up'] != -1.0 and ['rw_fscale_up'] not in self['rw_fscale']):
3419 self['rw_fscale']=[1.0,self['rw_fscale_up'],self['rw_fscale_down']]
3420
3421
3422 if any(self['reweight_pdf']):
3423
3424 if self['pdlabel'] != "lhapdf":
3425 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.'
3426
3427
3428 if self['pdlabel'] != "lhapdf":
3429 self['reweight_pdf']=[self['reweight_pdf'][0]]
3430 self['lhaid']=[self['lhaid'][0]]
3431
3432
3433 if self['fixed_ren_scale'] and self['fixed_fac_scale']:
3434 self['reweight_scale']=[self['reweight_scale'][0]]
3435 self['dynamical_scale_choice']=[0]
3436
3437
3438
3439
3440 if len(self['reweight_pdf']) == 1 and len(self['lhaid']) != 1:
3441 self['reweight_pdf']=self['reweight_pdf']*len(self['lhaid'])
3442 logger.warning("Setting 'reweight_pdf' for all 'lhaid' to %s" % self['reweight_pdf'][0])
3443 if len(self['reweight_scale']) == 1 and len(self['dynamical_scale_choice']) != 1:
3444 self['reweight_scale']=self['reweight_scale']*len(self['dynamical_scale_choice'])
3445 logger.warning("Setting 'reweight_scale' for all 'dynamical_scale_choice' to %s" % self['reweight_pdf'][0])
3446
3447
3448 if len(self['lhaid']) != len(set(self['lhaid'])):
3449 raise InvalidRunCard, "'lhaid' has two or more identical entries. They have to be all different for the code to work correctly."
3450 if len(self['dynamical_scale_choice']) != len(set(self['dynamical_scale_choice'])):
3451 raise InvalidRunCard, "'dynamical_scale_choice' has two or more identical entries. They have to be all different for the code to work correctly."
3452
3453
3454 if len(self['reweight_pdf']) != len(self['lhaid']):
3455 raise InvalidRunCard, "'reweight_pdf' and 'lhaid' lists should have the same length"
3456 if len(self['reweight_scale']) != len(self['dynamical_scale_choice']):
3457 raise InvalidRunCard, "'reweight_scale' and 'dynamical_scale_choice' lists should have the same length"
3458 if len(self['dynamical_scale_choice']) > 10 :
3459 raise InvalidRunCard, "Length of list for 'dynamical_scale_choice' too long: max is 10."
3460 if len(self['lhaid']) > 25 :
3461 raise InvalidRunCard, "Length of list for 'lhaid' too long: max is 25."
3462 if len(self['rw_rscale']) > 9 :
3463 raise InvalidRunCard, "Length of list for 'rw_rscale' too long: max is 9."
3464 if len(self['rw_fscale']) > 9 :
3465 raise InvalidRunCard, "Length of list for 'rw_fscale' too long: max is 9."
3466
3467 if 1.0 not in self['rw_rscale']:
3468 logger.warning("'1.0' has to be part of 'rw_rscale', adding it")
3469 self['rw_rscale'].insert(0,1.0)
3470 if 1.0 not in self['rw_fscale']:
3471 logger.warning("'1.0' has to be part of 'rw_fscale', adding it")
3472 self['rw_fscale'].insert(0,1.0)
3473 if self['rw_rscale'][0] != 1.0 and 1.0 in self['rw_rscale']:
3474 a=self['rw_rscale'].index(1.0)
3475 self['rw_rscale'][0],self['rw_rscale'][a]=self['rw_rscale'][a],self['rw_rscale'][0]
3476 if self['rw_fscale'][0] != 1.0 and 1.0 in self['rw_fscale']:
3477 a=self['rw_fscale'].index(1.0)
3478 self['rw_fscale'][0],self['rw_fscale'][a]=self['rw_fscale'][a],self['rw_fscale'][0]
3479
3480 if len(self['rw_rscale']) != len(set(self['rw_rscale'])):
3481 raise InvalidRunCard, "'rw_rscale' has two or more identical entries. They have to be all different for the code to work correctly."
3482 if len(self['rw_fscale']) != len(set(self['rw_fscale'])):
3483 raise InvalidRunCard, "'rw_fscale' has two or more identical entries. They have to be all different for the code to work correctly."
3484
3485
3486 - def write(self, output_file, template=None, python_template=False):
3487 """Write the run_card in output_file according to template
3488 (a path to a valid run_card)"""
3489
3490 if not template:
3491 if not MADEVENT:
3492 template = pjoin(MG5DIR, 'Template', 'NLO', 'Cards',
3493 'run_card.dat')
3494 python_template = True
3495 else:
3496 template = pjoin(MEDIR, 'Cards', 'run_card_default.dat')
3497 python_template = False
3498
3499 super(RunCardNLO, self).write(output_file, template=template,
3500 python_template=python_template)
3501
3502
3504 """Rules
3505 e+ e- beam -> lpp:0 ebeam:500
3506 p p beam -> set maxjetflavor automatically
3507 """
3508
3509
3510 beam_id = set()
3511 for proc in proc_def:
3512 for leg in proc['legs']:
3513 if not leg['state']:
3514 beam_id.add(leg['id'])
3515 if any(i in beam_id for i in [1,-1,2,-2,3,-3,4,-4,5,-5,21,22]):
3516 maxjetflavor = max([4]+[abs(i) for i in beam_id if -7< i < 7])
3517 self['maxjetflavor'] = maxjetflavor
3518 pass
3519 elif 11 in beam_id or -11 in beam_id:
3520 self['lpp1'] = 0
3521 self['lpp2'] = 0
3522 self['ebeam1'] = 500
3523 self['ebeam2'] = 500
3524 else:
3525 self['lpp1'] = 0
3526 self['lpp2'] = 0
3527
3528 if proc_characteristic['ninitial'] == 1:
3529
3530 self.remove_all_cut()
3531
3535 """ a class for storing/dealing with the file MadLoopParam.dat
3536 contains a parser to read it, facilities to write a new file,...
3537 """
3538
3539 _ID_reduction_tool_map = {1:'CutTools',
3540 2:'PJFry++',
3541 3:'IREGI',
3542 4:'Golem95',
3543 5:'Samurai',
3544 6:'Ninja',
3545 7:'COLLIER'}
3546
3548 """initialize the directory to the default value"""
3549
3550 self.add_param("MLReductionLib", "6|7|1")
3551 self.add_param("IREGIMODE", 2)
3552 self.add_param("IREGIRECY", True)
3553 self.add_param("CTModeRun", -1)
3554 self.add_param("MLStabThres", 1e-3)
3555 self.add_param("NRotations_DP", 0)
3556 self.add_param("NRotations_QP", 0)
3557 self.add_param("ImprovePSPoint", 2)
3558 self.add_param("CTLoopLibrary", 2)
3559 self.add_param("CTStabThres", 1e-2)
3560 self.add_param("CTModeInit", 1)
3561 self.add_param("CheckCycle", 3)
3562 self.add_param("MaxAttempts", 10)
3563 self.add_param("ZeroThres", 1e-9)
3564 self.add_param("OSThres", 1.0e-8)
3565 self.add_param("DoubleCheckHelicityFilter", True)
3566 self.add_param("WriteOutFilters", True)
3567 self.add_param("UseLoopFilter", False)
3568 self.add_param("HelicityFilterLevel", 2)
3569 self.add_param("LoopInitStartOver", False)
3570 self.add_param("HelInitStartOver", False)
3571 self.add_param("UseQPIntegrandForNinja", True)
3572 self.add_param("UseQPIntegrandForCutTools", True)
3573 self.add_param("COLLIERMode", 1)
3574 self.add_param("COLLIERComputeUVpoles", True)
3575 self.add_param("COLLIERComputeIRpoles", True)
3576 self.add_param("COLLIERRequiredAccuracy", 1.0e-8)
3577 self.add_param("COLLIERCanOutput",False)
3578 self.add_param("COLLIERGlobalCache",-1)
3579 self.add_param("COLLIERUseCacheForPoles",False)
3580 self.add_param("COLLIERUseInternalStabilityTest",True)
3581
3582 - def read(self, finput):
3583 """Read the input file, this can be a path to a file,
3584 a file object, a str with the content of the file."""
3585
3586 if isinstance(finput, str):
3587 if "\n" in finput:
3588 finput = finput.split('\n')
3589 elif os.path.isfile(finput):
3590 finput = open(finput)
3591 else:
3592 raise Exception, "No such file %s" % input
3593
3594 previous_line= ''
3595 for line in finput:
3596 if previous_line.startswith('#'):
3597 name = previous_line[1:].split()[0]
3598 value = line.strip()
3599 if len(value) and value[0] not in ['#', '!']:
3600 self.__setitem__(name, value, change_userdefine=True)
3601 previous_line = line
3602
3603
3604 - def write(self, outputpath, template=None,commentdefault=False):
3605
3606 if not template:
3607 if not MADEVENT:
3608 template = pjoin(MG5DIR, 'Template', 'loop_material', 'StandAlone',
3609 'Cards', 'MadLoopParams.dat')
3610 else:
3611 template = pjoin(MEDIR, 'Cards', 'MadLoopParams_default.dat')
3612 fsock = open(template, 'r')
3613 template = fsock.readlines()
3614 fsock.close()
3615
3616 if isinstance(outputpath, str):
3617 output = open(outputpath, 'w')
3618 else:
3619 output = outputpath
3620
3621 def f77format(value):
3622 if isinstance(value, bool):
3623 if value:
3624 return '.true.'
3625 else:
3626 return '.false.'
3627 elif isinstance(value, int):
3628 return value
3629 elif isinstance(value, float):
3630 tmp ='%e' % value
3631 return tmp.replace('e','d')
3632 elif isinstance(value, str):
3633 return value
3634 else:
3635 raise Exception, "Can not format input %s" % type(value)
3636
3637 name = ''
3638 done = set()
3639 for line in template:
3640 if name:
3641 done.add(name)
3642 if commentdefault and name.lower() not in self.user_set :
3643 output.write('!%s\n' % f77format(self[name]))
3644 else:
3645 output.write('%s\n' % f77format(self[name]))
3646 name=''
3647 continue
3648 elif line.startswith('#'):
3649 name = line[1:].split()[0]
3650 output.write(line)
3651