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