~maddevelopers/mg5amcnlo/WWW5_caching

« back to all changes in this revision

Viewing changes to users/mardelcourt/PROC_407857/PROC_407857/bin/internal/banner.py

  • Committer: John Doe
  • Date: 2013-03-25 20:27:02 UTC
  • Revision ID: john.doe@gmail.com-20130325202702-5sk3t1r8h33ca4p4
first clean version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
################################################################################
 
2
#
 
3
# Copyright (c) 2011 The MadGraph Development team and Contributors
 
4
#
 
5
# This file is a part of the MadGraph 5 project, an application which 
 
6
# automatically generates Feynman diagrams and matrix elements for arbitrary
 
7
# high-energy processes in the Standard Model and beyond.
 
8
#
 
9
# It is subject to the MadGraph license which should accompany this 
 
10
# distribution.
 
11
#
 
12
# For more information, please visit: http://madgraph.phys.ucl.ac.be
 
13
#
 
14
################################################################################
 
15
"""A File for splitting"""
 
16
 
 
17
import sys
 
18
import re
 
19
import os
 
20
 
 
21
pjoin = os.path.join
 
22
 
 
23
try:
 
24
    import madgraph.various.misc as misc
 
25
    import madgraph.iolibs.file_writers as file_writers
 
26
    import models.check_param_card as param_card_reader
 
27
    from madgraph import MG5DIR
 
28
    MADEVENT = False
 
29
except ImportError:
 
30
    MADEVENT = True
 
31
    import internal.file_writers as file_writers
 
32
    import internal.check_param_card as param_card_reader
 
33
    MEDIR = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
 
34
    MEDIR = os.path.split(MEDIR)[0]
 
35
 
 
36
import logging
 
37
 
 
38
logger = logging.getLogger('madevent.cards')
 
39
 
 
40
#dict
 
41
class Banner(dict):
 
42
    """ """
 
43
 
 
44
    ordered_items = ['mgversion', 'mg5proccard', 'mgproccard', 'mgruncard',
 
45
                     'slha', 'MGGenerationInfo', 'mgpythiacard', 'mgpgscard',
 
46
                     'mgdelphescard', 'mgdelphestrigger']
 
47
    
 
48
    def __init__(self, banner_path=None):
 
49
        """ """
 
50
        dict.__init__(self)
 
51
        
 
52
        #Look at the version
 
53
        if MADEVENT:
 
54
            self['mgversion'] = '#%s\n' % open(pjoin(MEDIR, 'MGMEVersion.txt')).read()
 
55
        else:
 
56
            info = misc.get_pkg_info()
 
57
            self['mgversion'] = info['version']+'\n'
 
58
            
 
59
        if banner_path:
 
60
            self.read_banner(banner_path)
 
61
 
 
62
    ############################################################################
 
63
    #  READ BANNER
 
64
    ############################################################################
 
65
    pat_begin=re.compile('<(?P<name>\w*)>')
 
66
    pat_end=re.compile('</(?P<name>\w*)>')
 
67
 
 
68
    tag_to_file={'slha':'param_card.dat',
 
69
      'mgruncard':'run_card.dat',
 
70
      'mgpythiacard':'pythia_card.dat',
 
71
      'mgpgscard' : 'pgs_card.dat',
 
72
      'mgdelphescard':'delphes_card.dat',      
 
73
      'mgdelphestrigger':'delphes_trigger.dat',
 
74
      'mg5proccard':'proc_card_mg5.dat',
 
75
      'mgproccard': 'proc_card.dat',
 
76
      'init': '',
 
77
      'mggenerationinfo':'',
 
78
      'montecarlomasses':'',
 
79
      'madspin':'madspin_card.dat' 
 
80
      }
 
81
    
 
82
    def read_banner(self, input_path):
 
83
        """read a banner"""
 
84
 
 
85
        if isinstance(input_path, str):
 
86
            input_path = open(input_path)
 
87
 
 
88
        text = ''
 
89
        store = False
 
90
        for line in input_path:
 
91
            if self.pat_begin.search(line):
 
92
                tag = self.pat_begin.search(line).group('name').lower()
 
93
                if tag in self.tag_to_file:
 
94
                    store = True
 
95
                    continue
 
96
            if store and self.pat_end.search(line):
 
97
                if tag == self.pat_end.search(line).group('name').lower():
 
98
                    self[tag] = text
 
99
                    text = ''
 
100
                    store = False
 
101
            if store:
 
102
                text += line
 
103
                
 
104
            #reaching end of the banner in a event file avoid to read full file 
 
105
            if "</init>" in line:
 
106
                break
 
107
            elif "<event>" in line:
 
108
                break
 
109
                
 
110
    def load_basic(self, medir):
 
111
        """ Load the proc_card /param_card and run_card """
 
112
        
 
113
        self.add(pjoin(medir,'Cards', 'param_card.dat'))
 
114
        self.add(pjoin(medir,'Cards', 'run_card.dat'))
 
115
        if os.path.exists(pjoin(medir, 'SubProcesses', 'procdef_mg5.dat')):
 
116
            self.add(pjoin(medir,'SubProcesses', 'procdef_mg5.dat'))
 
117
            self.add(pjoin(medir,'Cards', 'proc_card_mg5.dat'))
 
118
        else:
 
119
            self.add(pjoin(medir,'Cards', 'proc_card.dat'))
 
120
    
 
121
    
 
122
    def change_seed(self, seed):
 
123
        """Change the seed value in the banner"""
 
124
        #      0       = iseed
 
125
        p = re.compile(r'''^\s*\d+\s*=\s*iseed''', re.M)
 
126
        new_seed_str = " %s = iseed" % seed
 
127
        self['mgruncard'] = p.sub(new_seed_str, self['mgruncard'])
 
128
    
 
129
    def add_generation_info(self, cross, nb_event):
 
130
        """add info on MGGeneration"""
 
131
        
 
132
        text = """
 
133
#  Number of Events        :       %s
 
134
#  Integrated weight (pb)  :       %s
 
135
""" % (nb_event, cross)
 
136
        self['MGGenerationInfo'] = text
 
137
    
 
138
    ############################################################################
 
139
    #  SPLIT BANNER
 
140
    ############################################################################
 
141
    def split(self, me_dir, proc_card=True):
 
142
        """write the banner in the Cards directory.
 
143
        proc_card argument is present to avoid the overwrite of proc_card 
 
144
        information"""
 
145
 
 
146
        for tag, text in self.items():
 
147
            if tag == 'mgversion':
 
148
                continue
 
149
            if not proc_card and tag in ['mg5proccard','mgproccard']:
 
150
                continue
 
151
            if not self.tag_to_file[tag]:
 
152
                continue
 
153
            ff = open(pjoin(me_dir, 'Cards', self.tag_to_file[tag]), 'w')
 
154
            ff.write(text)
 
155
            ff.close()
 
156
 
 
157
    ############################################################################
 
158
    #  WRITE BANNER
 
159
    ############################################################################
 
160
    def check_pid(self, pid2label):
 
161
        """special routine removing width/mass of particles not present in the model
 
162
        This is usefull in case of loop model card, when we want to use the non
 
163
        loop model."""
 
164
        
 
165
        if not hasattr(self, 'param_card'):
 
166
            self.charge_card('slha')
 
167
            
 
168
        for tag in ['mass', 'decay']:
 
169
            block = self.param_card.get(tag)
 
170
            for data in block:
 
171
                pid = data.lhacode[0]
 
172
                if pid not in pid2label.keys(): 
 
173
                    block.remove((pid,))
 
174
 
 
175
    ############################################################################
 
176
    #  WRITE BANNER
 
177
    ############################################################################
 
178
    def write(self, output_path, close_tag=True):
 
179
        """write the banner"""
 
180
        
 
181
        if isinstance(output_path, str):
 
182
            ff = open(output_path, 'w')
 
183
        else:
 
184
            ff = output_path
 
185
            
 
186
        if MADEVENT:
 
187
            header = open(pjoin(MEDIR, 'Source', 'banner_header.txt')).read()
 
188
        else:
 
189
            header = open(pjoin(MG5DIR,'Template', 'LO', 'Source', 'banner_header.txt')).read()
 
190
        
 
191
        ff.write(header)
 
192
 
 
193
 
 
194
        for tag in [t for t in self.ordered_items if t in self.keys()]:
 
195
            ff.write('<%(tag)s>\n%(text)s\n</%(tag)s>\n' % \
 
196
                     {'tag':tag, 'text':self[tag].strip()})
 
197
        for tag in [t for t in self.keys() if t not in self.ordered_items]:
 
198
            if tag in ['init']:
 
199
                continue
 
200
            ff.write('<%(tag)s>\n%(text)s\n</%(tag)s>\n' % \
 
201
                     {'tag':tag, 'text':self[tag].strip()})
 
202
 
 
203
        ff.write('</header>\n')    
 
204
 
 
205
        if 'init' in self:
 
206
            text = self['init']
 
207
            ff.write('<%(tag)s>\n%(text)s\n</%(tag)s>\n' % \
 
208
                     {'tag':'init', 'text':text.strip()})  
 
209
        if close_tag:          
 
210
            ff.write('</LesHouchesEvents>\n')
 
211
        
 
212
        
 
213
    ############################################################################
 
214
    # BANNER
 
215
    ############################################################################
 
216
    def add(self, path, tag=None):
 
217
        """Add the content of the file to the banner"""
 
218
        
 
219
        if not tag:
 
220
            card_name = os.path.basename(path)
 
221
            if 'param_card' in card_name:
 
222
                tag = 'slha'
 
223
            elif 'run_card' in card_name:
 
224
                tag = 'MGRunCard'
 
225
            elif 'pythia_card' in card_name:
 
226
                tag = 'MGPythiaCard'
 
227
            elif 'pgs_card' in card_name:
 
228
                tag = 'MGPGSCard'
 
229
            elif 'delphes_card' in card_name:
 
230
                tag = 'MGDelphesCard'
 
231
            elif 'delphes_trigger' in card_name:
 
232
                tag = 'MGDelphesTrigger'
 
233
            elif 'proc_card_mg5' in card_name:
 
234
                tag = 'MG5ProcCard'
 
235
            elif 'proc_card' in card_name:
 
236
                tag = 'MGProcCard'
 
237
            elif 'procdef_mg5' in card_name:
 
238
                tag = 'MGProcCard'
 
239
            else:
 
240
                raise Exception, 'Impossible to know the type of the card'
 
241
 
 
242
            self.add_text(tag.lower(), open(path).read())
 
243
 
 
244
    def add_text(self, tag, text):
 
245
        """Add the content of the file to the banner"""
 
246
        
 
247
        self[tag.lower()] = text
 
248
    
 
249
    
 
250
    def charge_card(self, tag):
 
251
        """Build the python object associated to the card"""
 
252
        
 
253
        if tag == 'param_card':
 
254
            tag = 'slha'
 
255
        elif tag == 'run_card':
 
256
            tag = 'mgruncard' 
 
257
        elif tag == 'proc_card':
 
258
            tag = 'mg5proccard' 
 
259
        
 
260
        assert tag in ['slha', 'mgruncard', 'mg5proccard'], 'invalid card %s' % tag
 
261
        
 
262
        if tag == 'slha':
 
263
            param_card = self[tag].split('\n')
 
264
            self.param_card = param_card_reader.ParamCard(param_card)
 
265
            return self.param_card
 
266
        elif tag == 'mgruncard':
 
267
            run_card = self[tag].split('\n') 
 
268
            if 'parton_shower' in self[tag]:
 
269
                self.run_card = RunCardNLO(run_card)
 
270
            else:
 
271
                self.run_card = RunCard(run_card)
 
272
            return self.run_card
 
273
        elif tag == 'mg5proccard':
 
274
            proc_card = self[tag].split('\n')
 
275
            self.proc_card = ProcCard(proc_card)
 
276
            return self.proc_card
 
277
 
 
278
        
 
279
    def get_detail(self, tag, *arg):
 
280
        """return a specific """
 
281
                
 
282
        if tag == 'param_card':
 
283
            tag = 'slha'
 
284
            attr_tag = 'param_card'
 
285
        elif tag == 'run_card':
 
286
            tag = 'mgruncard' 
 
287
            attr_tag = 'run_card'
 
288
        elif tag == 'proc_card':
 
289
            tag = 'mg5proccard' 
 
290
            attr_tag = 'proc_card'
 
291
        elif tag == 'model':
 
292
            tag = 'mg5proccard' 
 
293
            attr_tag = 'proc_card'
 
294
            arg = ('model',)
 
295
        elif tag == 'generate':
 
296
            tag = 'mg5proccard' 
 
297
            attr_tag = 'proc_card'
 
298
            arg = ('generate',)
 
299
        assert tag in ['slha', 'mgruncard', 'mg5proccard'], 'not recognized'
 
300
        
 
301
        if not hasattr(self, attr_tag):
 
302
            self.charge_card(attr_tag) 
 
303
            
 
304
        card = getattr(self, attr_tag)
 
305
        if len(arg) == 1:
 
306
            if tag == 'mg5proccard':
 
307
                return card.info[arg[0]]
 
308
            return card[arg[0]]
 
309
        elif len(arg) == 2 and tag == 'slha':
 
310
            return card[arg[0]].get(arg[1:])
 
311
        else:
 
312
            raise Exception, "Unknow command"
 
313
    
 
314
    #convenient alias
 
315
    get = get_detail
 
316
        
 
317
def split_banner(banner_path, me_dir, proc_card=True):
 
318
    """a simple way to split a banner"""
 
319
    
 
320
    banner = Banner(banner_path)
 
321
    banner.split(me_dir, proc_card)
 
322
    
 
323
def recover_banner(results_object, level):
 
324
    """as input we receive a gen_crossxhtml.AllResults object.
 
325
       This define the current banner and load it
 
326
    """
 
327
    try:  
 
328
        run = results_object.current['run_name']    
 
329
        tag = results_object.current['tag'] 
 
330
    except Exception:
 
331
        return Banner()                                  
 
332
    path = results_object.path
 
333
    banner_path = pjoin(path,'Events',run,'%s_%s_banner.txt' % (run, tag))
 
334
    
 
335
    if not os.path.exists(banner_path):
 
336
        # security if the banner was remove (or program canceled before created it)
 
337
        return Banner()  
 
338
    
 
339
    banner = Banner(banner_path)
 
340
    
 
341
    
 
342
    
 
343
    if level == 'pythia':
 
344
        if 'mgpythiacard' in banner:
 
345
            del banner['mgpythiacard']
 
346
    if level in ['pythia','pgs','delphes']:
 
347
        for tag in ['mgpgscard', 'mgdelphescard', 'mgdelphestrigger']:
 
348
            if tag in banner:
 
349
                del banner[tag]
 
350
    return banner
 
351
    
 
352
 
 
353
class RunCard(dict):
 
354
    """A class object for the run_card"""
 
355
 
 
356
    def __init__(self, run_card):
 
357
        """ """
 
358
        
 
359
        if isinstance(run_card, str):
 
360
            run_card = file(run_card,'r')
 
361
        else:
 
362
            pass # use in banner loading
 
363
 
 
364
        for line in run_card:
 
365
            line = line.split('#')[0]
 
366
            line = line.split('!')[0]
 
367
            line = line.split('=')
 
368
            if len(line) != 2:
 
369
                continue
 
370
            self[line[1].strip()] = line[0].replace('\'','').strip()
 
371
 
 
372
    def get_default(self, name, default, log_level):
 
373
        """return self[name] if exist otherwise default. log control if we 
 
374
        put a warning or not if we use the default value"""
 
375
 
 
376
        try:
 
377
            return self[name]
 
378
        except KeyError:
 
379
            if log_level:
 
380
                logger.log(log_level, 'run_card missed argument %s. Takes default: %s'
 
381
                                   % (name, default))
 
382
                self[name] = default
 
383
                return default
 
384
        
 
385
    @staticmethod
 
386
    def format(format, value):
 
387
        """format the value"""
 
388
        
 
389
        if format == 'bool':
 
390
            if str(value) in ['1','T','.true.','True']:
 
391
                return '.true.'
 
392
            else:
 
393
                return '.false.'
 
394
            
 
395
        elif format == 'int':
 
396
            return str(int(value))
 
397
        
 
398
        elif format == 'float':
 
399
            if isinstance(value, str):
 
400
                value = value.replace('d','e')
 
401
            return ('%.10e' % float(value)).replace('e','d')
 
402
        
 
403
        elif format == 'str':
 
404
            return "'%s'" % value
 
405
    
 
406
 
 
407
        
 
408
    def write(self, output_file, template=None):
 
409
        """Write the run_card in output_file according to template 
 
410
           (a path to a valid run_card)"""
 
411
        
 
412
        if not template:
 
413
            template = output_file
 
414
        
 
415
        text = ""
 
416
        for line in file(template,'r'):
 
417
            nline = line.split('#')[0]
 
418
            nline = nline.split('!')[0]
 
419
            comment = line[len(nline):]
 
420
            nline = nline.split('=')
 
421
            if len(nline) != 2:
 
422
                text += line
 
423
            else:
 
424
                text += '  %s\t= %s %s' % (self[nline[1].strip()],nline[1], comment)        
 
425
        
 
426
        fsock = open(output_file,'w')
 
427
        fsock.write(text)
 
428
        fsock.close()
 
429
 
 
430
 
 
431
    def write_include_file(self, output_path):
 
432
        """writing the run_card.inc file""" 
 
433
        
 
434
        self.fsock = file_writers.FortranWriter(output_path)    
 
435
################################################################################
 
436
#      Writing the lines corresponding to the cuts
 
437
################################################################################
 
438
    
 
439
        self.add_line('maxjetflavor', 'int', 4)
 
440
        self.add_line('auto_ptj_mjj', 'bool', True)
 
441
        self.add_line('cut_decays', 'bool', True)
 
442
        # minimum pt
 
443
        self.add_line('ptj', 'float', 20)
 
444
        self.add_line('ptb', 'float', 20)
 
445
        self.add_line('pta', 'float', 20)
 
446
        self.add_line('ptl', 'float', 20)
 
447
        self.add_line('misset', 'float', 0)
 
448
        self.add_line('ptonium', 'float', 0.0)
 
449
        # maximal pt
 
450
        self.add_line('ptjmax', 'float', -1)
 
451
        self.add_line('ptbmax', 'float', -1)
 
452
        self.add_line('ptamax', 'float', -1)
 
453
        self.add_line('ptlmax', 'float', -1)
 
454
        self.add_line('missetmax', 'float', -1)
 
455
        # maximal rapidity (absolute value)
 
456
        self.add_line('etaj', 'float', 4.0)
 
457
        self.add_line('etab', 'float', 4.0)
 
458
        self.add_line('etaa', 'float', 4.0)
 
459
        self.add_line('etal', 'float', 4.0)
 
460
        # minimal rapidity (absolute value)
 
461
        self.add_line('etajmin', 'float', 0.0)
 
462
        self.add_line('etabmin', 'float', 0.0)
 
463
        self.add_line('etaamin', 'float', 0.0)
 
464
        self.add_line('etalmin', 'float', 0.0)
 
465
        self.add_line('etaonium', 'float', 100.0)
 
466
        # Minimul E's
 
467
        self.add_line('ej', 'float', 0.0)
 
468
        self.add_line('eb', 'float', 0.0)
 
469
        self.add_line('ea', 'float', 0.0)
 
470
        self.add_line('el', 'float', 0.0)
 
471
        # Maximum E's
 
472
        self.add_line('ejmax', 'float', -1)
 
473
        self.add_line('ebmax', 'float', -1)
 
474
        self.add_line('eamax', 'float', -1)
 
475
        self.add_line('elmax', 'float', -1)     
 
476
        # minimum delta_r
 
477
        self.add_line('drjj', 'float', 0.4)     
 
478
        self.add_line('drbb', 'float', 0.4)     
 
479
        self.add_line('drll', 'float', 0.4)     
 
480
        self.add_line('draa', 'float', 0.4)     
 
481
        self.add_line('drbj', 'float', 0.4)     
 
482
        self.add_line('draj', 'float', 0.4)     
 
483
        self.add_line('drjl', 'float', 0.4)     
 
484
        self.add_line('drab', 'float', 0.4)     
 
485
        self.add_line('drbl', 'float', 0.4)     
 
486
        self.add_line('dral', 'float', 0.4)     
 
487
        # maximum delta_r
 
488
        self.add_line('drjjmax', 'float', -1)
 
489
        self.add_line('drbbmax', 'float', -1)
 
490
        self.add_line('drllmax', 'float', -1)
 
491
        self.add_line('draamax', 'float', -1)
 
492
        self.add_line('drbjmax', 'float', -1)
 
493
        self.add_line('drajmax', 'float', -1)
 
494
        self.add_line('drjlmax', 'float', -1)
 
495
        self.add_line('drabmax', 'float', -1)
 
496
        self.add_line('drblmax', 'float', -1)
 
497
        self.add_line('dralmax', 'float', -1)
 
498
        # minimum invariant mass for pairs
 
499
        self.add_line('mmjj', 'float', 0.0)
 
500
        self.add_line('mmbb', 'float', 0.0)
 
501
        self.add_line('mmaa', 'float', 0.0)
 
502
        self.add_line('mmll', 'float', 0.0)
 
503
        # maximum invariant mall for pairs
 
504
        self.add_line('mmjjmax', 'float', -1)
 
505
        self.add_line('mmbbmax', 'float', -1)
 
506
        self.add_line('mmaamax', 'float', -1)
 
507
        self.add_line('mmllmax', 'float', -1)
 
508
        #Min Maxi invariant mass for all leptons 
 
509
        self.add_line("mmnl", 'float', 0.0)
 
510
        self.add_line("mmnlmax", 'float', -1)
 
511
        #inclusive cuts
 
512
        self.add_line("xptj", 'float', 0.0)
 
513
        self.add_line("xptb", 'float', 0.0)
 
514
        self.add_line("xpta", 'float', 0.0)
 
515
        self.add_line("xptl", 'float', 0.0)
 
516
        self.add_line("xmtcentral", 'float', 0.0, fortran_name='xmtc', log=10)
 
517
        # WBT cuts
 
518
        self.add_line("xetamin", 'float', 0.0)
 
519
        self.add_line("deltaeta", 'float', 0.0)
 
520
        # Jet measure cuts 
 
521
        self.add_line("xqcut", 'float', 0.0)
 
522
        self.add_line("d", 'float', 1.0, log=10)
 
523
        # Set min pt of one heavy particle 
 
524
        self.add_line("ptheavy", 'float', 0.0)
 
525
        # Pt of pairs of leptons (CHARGED AND NEUTRALS)
 
526
        self.add_line("ptllmin", "float", 0.0)
 
527
        self.add_line("ptllmax", "float", -1)
 
528
        # Check   the pt's of the jets sorted by pt
 
529
        self.add_line("ptj1min", "float", 0.0)
 
530
        self.add_line("ptj1max", "float", -1)
 
531
        self.add_line("ptj2min", "float", 0.0)
 
532
        self.add_line("ptj2max", "float", -1)
 
533
        self.add_line("ptj3min", "float", 0.0)
 
534
        self.add_line("ptj3max", "float", -1)
 
535
        self.add_line("ptj4min", "float", 0.0)
 
536
        self.add_line("ptj4max", "float", -1)
 
537
        self.add_line("cutuse", "float", 0.0)
 
538
        # Check   the pt's of leptons sorted by pt
 
539
        self.add_line("ptl1min", "float", 0.0)
 
540
        self.add_line("ptl1max", "float", -1)
 
541
        self.add_line("ptl2min", "float", 0.0)
 
542
        self.add_line("ptl2max", "float", -1)
 
543
        self.add_line("ptl3min", "float", 0.0)
 
544
        self.add_line("ptl3max", "float", -1)
 
545
        self.add_line("ptl4min", "float", 0.0)
 
546
        self.add_line("ptl4max", "float", -1)
 
547
        # Check  Ht
 
548
        self.add_line("ht2min", 'float', 0.0)
 
549
        self.add_line("ht3min", 'float', 0.0)
 
550
        self.add_line("ht4min", 'float', 0.0)
 
551
        self.add_line("ht2max", 'float', -1)
 
552
        self.add_line("ht3max", 'float', -1)
 
553
        self.add_line("ht4max", 'float', -1)        
 
554
        self.add_line("htjmin", 'float', 0.0)
 
555
        self.add_line("htjmax", 'float', -1)        
 
556
        self.add_line("ihtmin", 'float', 0.0)
 
557
        self.add_line("ihtmax", 'float', -1)
 
558
 
 
559
################################################################################
 
560
#      Writing the lines corresponding to anything but cuts
 
561
################################################################################
 
562
        # seed
 
563
        self.add_line("gridpack","bool", False)
 
564
        self.add_line("gridrun",'bool', False, log=10)
 
565
        if str(self['gridrun']) in ['1','T','.true','True'] and \
 
566
           str(self['gridpack']) in ['1','T','.true','True']:
 
567
            self.add_line('gseed', 'int', 0, fortran_name='iseed')
 
568
        else:
 
569
            self.add_line('iseed', 'int', 0, fortran_name='iseed')
 
570
        # Renormalizrion and factorization scales
 
571
        self.add_line('fixed_ren_scale', 'bool', True)
 
572
        self.add_line('fixed_fac_scale', 'bool', True)
 
573
        self.add_line('scale', 'float', 'float', 91.188)
 
574
        self.add_line('dsqrt_q2fact1','float', 91.188, fortran_name='sf1')
 
575
        self.add_line('dsqrt_q2fact2', 'float', 91.188, fortran_name='sf2')
 
576
        self.add_line('scalefact', 'float', 1.0)
 
577
        self.add_line('fixed_couplings', 'bool', True, log=10)
 
578
        self.add_line('ickkw', 'int', 0)
 
579
        self.add_line('chcluster', 'bool', False)
 
580
        self.add_line('ktscheme', 'int', 1)
 
581
        self.add_line('asrwgtflavor', 'int', 5)
 
582
        if int(self['ickkw'])>0:
 
583
            self.add_line('alpsfact', 'float', 1.0)
 
584
            self.add_line('pdfwgt', 'bool', True)
 
585
        if int(self['ickkw'])==2:
 
586
            self.add_line('highestmult','int', 0, fortran_name='nhmult')
 
587
            self.add_line('issgridfile','str','issudgrid.dat')
 
588
        # Collider energy and type
 
589
        self.add_line('lpp1', 'int', 1, fortran_name='lpp(1)')
 
590
        self.add_line('lpp2', 'int', 1, fortran_name='lpp(2)')
 
591
        self.add_line('ebeam1', 'float', 7000, fortran_name='ebeam(1)')
 
592
        self.add_line('ebeam2', 'float', 7000, fortran_name='ebeam(2)')
 
593
        # Beam polarization
 
594
        self.add_line('polbeam1', 'float', 0.0, fortran_name='pb1')
 
595
        self.add_line('polbeam2', 'float', 0.0, fortran_name='pb2')
 
596
        # BW cutoff (M+/-bwcutoff*Gamma)
 
597
        self.add_line('bwcutoff', 'float', 15.0)
 
598
        #  Collider pdf
 
599
        self.add_line('pdlabel','str','cteq6l1')
 
600
        if self['pdlabel'] == 'lhapdf':
 
601
            self.add_line('lhaid', 'int', 10042)
 
602
        else:
 
603
            self.add_line('lhaid', 'int', 10042, log=10)
 
604
        
 
605
        self.fsock.close()
 
606
 
 
607
 
 
608
 
 
609
        
 
610
    def add_line(self, card_name, type, default, log=30, fortran_name=None):
 
611
        """get the line for the .inc file""" 
 
612
         
 
613
        value = self.get_default(card_name, default, log)
 
614
        if not fortran_name:
 
615
            fortran_name = card_name
 
616
        self.fsock.writelines(' %s = %s \n' % (fortran_name, self.format(type, value)))
 
617
 
 
618
 
 
619
class RunCardNLO(RunCard):
 
620
    """A class object for the run_card for a (aMC@)NLO pocess"""
 
621
 
 
622
        
 
623
    def write_include_file(self, output_path):
 
624
        """writing the run_card.inc file""" 
 
625
        
 
626
        self.fsock = file_writers.FortranWriter(output_path)    
 
627
################################################################################
 
628
#      Writing the lines corresponding to the cuts
 
629
################################################################################
 
630
    
 
631
        self.add_line('maxjetflavor', 'int', 5)
 
632
        # minimum pt
 
633
        self.add_line('ptj', 'float', 20)
 
634
        self.add_line('etaj', 'float', -1.0)
 
635
        self.add_line('ptl', 'float', 20)
 
636
        self.add_line('etal', 'float', -1.0)
 
637
        # minimum delta_r
 
638
        self.add_line('drll', 'float', 0.4)     
 
639
        # minimum invariant mass for pairs
 
640
        self.add_line('mll', 'float', 0.0)
 
641
        #inclusive cuts
 
642
        # Jet measure cuts 
 
643
        self.add_line("jetradius", 'float', 0.7, log=10)
 
644
 
 
645
################################################################################
 
646
#      Writing the lines corresponding to anything but cuts
 
647
################################################################################
 
648
        # seed
 
649
        self.add_line('iseed', 'int', 0)
 
650
        self.add_line('parton_shower', 'str', 'HERWIG6', fortran_name='shower_mc')
 
651
        self.add_line('nevents', 'int', 10000)
 
652
        self.add_line('event_norm', 'str', 'average', fortran_name='event_norm')
 
653
        # Renormalizrion and factorization scales
 
654
        self.add_line('fixed_ren_scale', 'bool', True)
 
655
        self.add_line('fixed_fac_scale', 'bool', True)
 
656
        self.add_line('fixed_QES_scale', 'bool', True)
 
657
        self.add_line('muR_ref_fixed', 'float', 91.188)
 
658
        self.add_line('muF1_ref_fixed','float', 91.188)
 
659
        self.add_line('muF2_ref_fixed', 'float', 91.188)
 
660
        self.add_line('QES_ref_fixed', 'float', 91.188)
 
661
        self.add_line('muR_over_ref', 'float', 1.0)
 
662
        self.add_line('muF1_over_ref', 'float', 1.0)
 
663
        self.add_line('muF2_over_ref', 'float', 1.0)
 
664
        self.add_line('QES_over_ref', 'float', 1.0)
 
665
        #reweight block
 
666
        self.add_line('reweight_scale', 'bool', True, fortran_name='do_rwgt_scale')
 
667
        self.add_line('rw_Rscale_up', 'float', 2.0)
 
668
        self.add_line('rw_Rscale_down', 'float', 0.5)
 
669
        self.add_line('rw_Fscale_up', 'float', 2.0)
 
670
        self.add_line('rw_Fscale_down', 'float', 0.5)
 
671
        self.add_line('reweight_PDF', 'bool', True, fortran_name='do_rwgt_pdf')
 
672
        self.add_line('PDF_set_min', 'int', 21101)
 
673
        self.add_line('PDF_set_max', 'int', 21140)
 
674
 
 
675
       # self.add_line('fixed_couplings', 'bool', True, log=10)
 
676
        self.add_line('jetalgo', 'int', 1)
 
677
        # Collider energy and type
 
678
        self.add_line('lpp1', 'int', 1, fortran_name='lpp(1)')
 
679
        self.add_line('lpp2', 'int', 1, fortran_name='lpp(2)')
 
680
        self.add_line('ebeam1', 'float', 4000, fortran_name='ebeam(1)')
 
681
        self.add_line('ebeam2', 'float', 4000, fortran_name='ebeam(2)')
 
682
        # BW cutoff (M+/-bwcutoff*Gamma)
 
683
        self.add_line('bwcutoff', 'float', 15.0)
 
684
        #  Collider pdf
 
685
        self.add_line('pdlabel','str','cteq6_m')
 
686
        if self['pdlabel'] == 'lhapdf':
 
687
            self.add_line('lhaid', 'int', 10042)
 
688
        else:
 
689
            self.add_line('lhaid', 'int', 10042, log=10)
 
690
        
 
691
        self.fsock.close()
 
692
 
 
693
class ProcCard(list):
 
694
    """Basic Proccard object"""
 
695
    
 
696
    def __init__(self, init=None):
 
697
        """ initialize a basic proc_card"""
 
698
        self.info = {'model': 'sm', 'generate':None,
 
699
                     'full_model_line':'import model sm'}
 
700
        list.__init__(self)
 
701
        if init:
 
702
            self.read(init)
 
703
 
 
704
            
 
705
    def read(self, init):
 
706
        """read the proc_card and save the information"""
 
707
        
 
708
        if isinstance(init, str): #path to file
 
709
            init = file(init, 'r')
 
710
        
 
711
        for line in init:
 
712
            self.append(line)
 
713
            
 
714
    def move_to_last(self, cmd):
 
715
        """move an element to the last history."""
 
716
        for line in self[:]:
 
717
            if line.startswith(cmd):
 
718
                self.remove(line)
 
719
                list.append(self, line)
 
720
    
 
721
    def append(self, line):
 
722
        """"add a line in the proc_card perform automatically cleaning"""
 
723
        
 
724
        line = line.strip()
 
725
        cmds = line.split()
 
726
        if len(cmds) == 0:
 
727
            return
 
728
        
 
729
        list.append(self, line)
 
730
        
 
731
        # command type:
 
732
        cmd = cmds[0]
 
733
        
 
734
        if cmd == 'output':
 
735
            # Remove previous outputs from history
 
736
            self.clean(allow_for_removal = ['output'], keep_switch=True,
 
737
                           remove_bef_last='output')
 
738
        elif cmd == 'generate':
 
739
            # Remove previous generations from history
 
740
            self.clean(remove_bef_last='generate', keep_switch=True,
 
741
                     allow_for_removal= ['generate', 'add process', 'output'])
 
742
            self.info['generate'] = ' '.join(cmds[1:])
 
743
        elif cmd == 'import':
 
744
            if len(cmds) < 2:
 
745
                return
 
746
            if cmds[1].startswith('model'):
 
747
                self.info['full_model_line'] = line
 
748
                self.clean(remove_bef_last='import', keep_switch=True,
 
749
                        allow_for_removal=['generate', 'add process', 'output'])
 
750
                if cmds[1] == 'model':
 
751
                    self.info['model'] = cmds[2]
 
752
                else:
 
753
                    self.info['model'] = None # not UFO model
 
754
            elif cmds[1] == 'proc_v4':
 
755
                #full cleaning
 
756
                self[:] = []
 
757
                
 
758
 
 
759
    def clean(self, to_keep=['set','add','load'],
 
760
                            remove_bef_last=None,
 
761
                            to_remove=['open','display','launch', 'check','history'],
 
762
                            allow_for_removal=None,
 
763
                            keep_switch=False):
 
764
        """Remove command in arguments from history.
 
765
        All command before the last occurrence of  'remove_bef_last'
 
766
        (including it) will be removed (but if another options tells the opposite).                
 
767
        'to_keep' is a set of line to always keep.
 
768
        'to_remove' is a set of line to always remove (don't care about remove_bef_ 
 
769
        status but keep_switch acts.).
 
770
        if 'allow_for_removal' is define only the command in that list can be 
 
771
        remove of the history for older command that remove_bef_lb1. all parameter
 
772
        present in to_remove are always remove even if they are not part of this 
 
773
        list.
 
774
        keep_switch force to keep the statement remove_bef_??? which changes starts
 
775
        the removal mode.
 
776
        """
 
777
        
 
778
        #check consistency
 
779
        if __debug__ and allow_for_removal:
 
780
            for arg in to_keep:
 
781
                assert arg not in allow_for_removal
 
782
            
 
783
    
 
784
        nline = -1
 
785
        removal = False
 
786
        #looping backward
 
787
        while nline > -len(self):
 
788
            switch  = False # set in True when removal pass in True
 
789
 
 
790
            #check if we need to pass in removal mode
 
791
            if not removal and remove_bef_last:
 
792
                    if self[nline].startswith(remove_bef_last):
 
793
                        removal = True
 
794
                        switch = True  
 
795
 
 
796
            # if this is the switch and is protected pass to the next element
 
797
            if switch and keep_switch:
 
798
                nline -= 1
 
799
                continue
 
800
 
 
801
            # remove command in to_remove (whatever the status of removal)
 
802
            if any([self[nline].startswith(arg) for arg in to_remove]):
 
803
                self.pop(nline)
 
804
                continue
 
805
            
 
806
            # Only if removal mode is active!
 
807
            if removal:
 
808
                if allow_for_removal:
 
809
                    # Only a subset of command can be removed
 
810
                    if any([self[nline].startswith(arg) 
 
811
                                                 for arg in allow_for_removal]):
 
812
                        self.pop(nline)
 
813
                        continue
 
814
                elif not any([self[nline].startswith(arg) for arg in to_keep]):
 
815
                    # All command have to be remove but protected
 
816
                    self.pop(nline)
 
817
                    continue
 
818
            
 
819
            # update the counter to pass to the next element
 
820
            nline -= 1
 
821
        
 
822
        def __getattr__(self, tag):
 
823
            if isinstance(tag, int):
 
824
                list.__getattr__(self, tag)
 
825
            else:
 
826
                return self.info[tag]
 
827
            
 
828
                
 
829
            
 
830
        
 
831
    
 
832
            
 
833
            
 
834
        
 
835
        
 
836
        
 
837
        
 
838
        
 
839
        
 
840
        
 
841