~maddevelopers/mg5amcnlo/3.0.2

« back to all changes in this revision

Viewing changes to madgraph/various/misc.py

  • Committer: Marco Zaro
  • Date: 2014-01-27 16:54:10 UTC
  • mfrom: (78.124.55 MG5_aMC_2.1)
  • Revision ID: marco.zaro@gmail.com-20140127165410-5lma8c2hzbzm426j
merged with lp:~maddevelopers/madgraph5/MG5_aMC_2.1 r 267

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
################################################################################
2
2
#
3
 
# Copyright (c) 2009 The MadGraph Development team and Contributors
 
3
# Copyright (c) 2009 The MadGraph5_aMC@NLO Development team and Contributors
4
4
#
5
 
# This file is a part of the MadGraph 5 project, an application which 
 
5
# This file is a part of the MadGraph5_aMC@NLO project, an application which 
6
6
# automatically generates Feynman diagrams and matrix elements for arbitrary
7
7
# high-energy processes in the Standard Model and beyond.
8
8
#
9
 
# It is subject to the MadGraph license which should accompany this 
 
9
# It is subject to the MadGraph5_aMC@NLO license which should accompany this 
10
10
# distribution.
11
11
#
12
 
# For more information, please visit: http://madgraph.phys.ucl.ac.be
 
12
# For more information, visit madgraph.phys.ucl.ac.be and amcatnlo.web.cern.ch
13
13
#
14
14
################################################################################
15
15
 
25
25
import sys
26
26
import optparse
27
27
import time
 
28
import shutil
28
29
 
29
30
try:
30
31
    # Use in MadGraph
66
67
 
67
68
 
68
69
#===============================================================================
 
70
# mute_logger (designed to be a decorator)
 
71
#===============================================================================
 
72
def mute_logger(names=['madgraph','ALOHA','cmdprint','madevent'], levels=[50,50,50,50]):
 
73
    """change the logger level and restore those at their initial value at the
 
74
    end of the function decorated."""
 
75
    def control_logger(f):
 
76
        def restore_old_levels(names, levels):
 
77
            for name, level in zip(names, levels):
 
78
                log_module = logging.getLogger(name)
 
79
                log_module.setLevel(level)            
 
80
        
 
81
        def f_with_no_logger(self, *args, **opt):
 
82
            old_levels = []
 
83
            for name, level in zip(names, levels):
 
84
                log_module = logging.getLogger(name)
 
85
                old_levels.append(log_module.level)
 
86
                log_module.setLevel(level)
 
87
            try:
 
88
                out = f(self, *args, **opt)
 
89
                restore_old_levels(names, old_levels)
 
90
                return out
 
91
            except:
 
92
                restore_old_levels(names, old_levels)
 
93
                raise
 
94
            
 
95
        return f_with_no_logger
 
96
    return control_logger
 
97
 
 
98
#===============================================================================
69
99
# get_pkg_info
70
100
#===============================================================================
71
101
def get_pkg_info(info_str=None):
72
 
    """Returns the current version information of the MadGraph package, 
 
102
    """Returns the current version information of the MadGraph5_aMC@NLO package, 
73
103
    as written in the VERSION text file. If the file cannot be found, 
74
104
    a dictionary with empty values is returned. As an option, an info
75
105
    string can be passed to be read instead of the file content.
103
133
#===============================================================================
104
134
def which(program):
105
135
    def is_exe(fpath):
106
 
        return os.path.exists(fpath) and os.access(fpath, os.X_OK)
 
136
        return os.path.exists(fpath) and os.access(\
 
137
                                               os.path.realpath(fpath), os.X_OK)
107
138
 
108
139
    if not program:
109
140
        return None
118
149
            if is_exe(exe_file):
119
150
                return exe_file
120
151
    return None
 
152
#===============================================================================
 
153
# find a library
 
154
#===============================================================================
 
155
def which_lib(program):
 
156
    def is_lib(fpath):
 
157
        return os.path.exists(fpath) and os.access(fpath, os.R_OK)
 
158
 
 
159
    if not program:
 
160
        return None
 
161
 
 
162
    fpath, fname = os.path.split(program)
 
163
    if fpath:
 
164
        if is_lib(program):
 
165
            return program
 
166
    else:
 
167
        if "LD_LIBRARY_PATH" in os.environ:
 
168
            ev_path="LD_LIBRARY_PATH"
 
169
        elif "PATH" in os.environ:
 
170
            ev_path="PATH"
 
171
        else:
 
172
            ev_path=None
 
173
        if ev_path !=None:
 
174
            for path in os.environ[ev_path].split(os.pathsep):
 
175
                lib_file = os.path.join(path, program)
 
176
                if is_lib(lib_file):
 
177
                    return lib_file
 
178
    return None
 
179
 
121
180
 
122
181
#===============================================================================
123
182
# Return Nice display for a random variable
158
217
                except Exception, error:
159
218
                    global wait_once
160
219
                    if not wait_once:
161
 
                        text = """Start waiting for update on filesystem. (more info in debug mode)"""
 
220
                        text = """Start waiting for update. (more info in debug mode)"""
162
221
                        logger.info(text)
163
222
                        logger_stderr.debug('fail to do %s function with %s args. %s try on a max of %s (%s waiting time)' %
164
223
                                 (str(f), ', '.join([str(a) for a in args]), i+1, nb_try, sleep * (i+1)))
165
224
                        logger_stderr.debug('error is %s' % str(error))
166
225
                    wait_once = True
167
226
                    time.sleep(sleep * (i+1))
 
227
 
168
228
            raise error.__class__, '[Fail %i times] \n %s ' % (i+1, error)
169
229
        return deco_f_retry
170
230
    return deco_retry
222
282
                  'is required to compile %s.\nPlease install it and retry.'%cwd
223
283
            else:
224
284
                logger_stderr.error('ERROR, you could not compile %s because'%cwd+\
225
 
             ' your version of gfortran is older than 4.6. MadGraph will carry on,'+\
 
285
             ' your version of gfortran is older than 4.6. MadGraph5_aMC@NLO will carry on,'+\
226
286
                              ' but will not be able to compile an executable.')
227
287
                return p.returncode
228
288
        # Other reason
234
294
        error_text += 'Please try to fix this compilations issue and retry.\n'
235
295
        error_text += 'Help might be found at https://answers.launchpad.net/madgraph5.\n'
236
296
        error_text += 'If you think that this is a bug, you can report this at https://bugs.launchpad.net/madgraph5'
237
 
 
238
297
        raise MadGraph5Error, error_text
239
298
    return p.returncode
240
299
 
242
301
    """ Returns the gfortran version as a string.
243
302
        Returns '0' if it failed."""
244
303
    try:    
245
 
        p = Popen(compiler+' -dumpversion', stdout=subprocess.PIPE, 
246
 
                    stderr=subprocess.PIPE, shell=True)
 
304
        p = Popen([compiler, '-dumpversion'], stdout=subprocess.PIPE, 
 
305
                    stderr=subprocess.PIPE)
247
306
        output, error = p.communicate()
248
307
        version_finder=re.compile(r"(?P<version>(\d.)*\d)")
249
308
        version = version_finder.search(output).group('version')
270
329
        text= pattern.sub(new, text)
271
330
        open(name,'w').write(text)
272
331
 
273
 
 
274
 
#===============================================================================
275
 
# mute_logger (designed to be a decorator)
276
 
#===============================================================================
277
 
def mute_logger(names=['madgraph','ALOHA','cmdprint','madevent'], levels=[50,50,50,50]):
278
 
    """change the logger level and restore those at their initial value at the
279
 
    end of the function decorated."""
280
 
    def control_logger(f):
281
 
        def restore_old_levels(names, levels):
282
 
            for name, level in zip(names, levels):
283
 
                log_module = logging.getLogger(name)
284
 
                log_module.setLevel(level)            
285
 
        
286
 
        def f_with_no_logger(self, *args, **opt):
287
 
            old_levels = []
288
 
            for name, level in zip(names, levels):
289
 
                log_module = logging.getLogger(name)
290
 
                old_levels.append(log_module.level)
291
 
                log_module.setLevel(level)
292
 
            try:
293
 
                out = f(self, *args, **opt)
294
 
                restore_old_levels(names, old_levels)
295
 
                return out
296
 
            except:
297
 
                restore_old_levels(names, old_levels)
298
 
                raise
299
 
            
300
 
        return f_with_no_logger
301
 
    return control_logger
302
 
 
303
332
#===============================================================================
304
333
# mute_logger (designed to work as with statement)
305
334
#===============================================================================
314
343
        
315
344
        self.names = names
316
345
        self.levels = levels
317
 
        if files:
 
346
        if isinstance(files, list):
318
347
            self.files = files
319
348
        else:
320
 
            self.files = [None] * len(names)
 
349
            self.files = [files] * len(names)
321
350
        self.logger_saved_info = {}
322
351
        self.opts = opt
323
352
 
333
362
        self.levels = old_levels
334
363
        
335
364
    def __exit__(self, ctype, value, traceback ):
336
 
        for name, level, path in zip(self.names, self.levels, self.files):
 
365
        for name, level, path, level in zip(self.names, self.levels, self.files, self.levels):
337
366
            if 'keep' in self.opts and not self.opts['keep']:
338
 
                self.restore_logFile_for_logger(name, path=path)
 
367
                self.restore_logFile_for_logger(name, level, path=path)
339
368
            else:
340
 
                self.restore_logFile_for_logger(name)
 
369
                self.restore_logFile_for_logger(name, level)
341
370
            
342
371
            log_module = logging.getLogger(name)
343
372
            log_module.setLevel(level)         
360
389
            self.logger_saved_info[logname] = [hdlr, my_logger.handlers]
361
390
            #for h in my_logger.handlers:
362
391
            #    h.setLevel(logging.CRITICAL)
363
 
            for old_hdlr in my_logger.handlers:
 
392
            for old_hdlr in list(my_logger.handlers):
364
393
                my_logger.removeHandler(old_hdlr)
365
394
            my_logger.addHandler(hdlr)
366
395
            #my_logger.setLevel(level)
367
396
            my_logger.debug('Log of %s' % logname)
368
397
 
369
 
    def restore_logFile_for_logger(self, full_logname, path=None, **opts):
 
398
    def restore_logFile_for_logger(self, full_logname, level, path=None, **opts):
370
399
        """ Setup the logger by redirecting them all to logfiles in tmp """
371
400
        
372
401
        logs = full_logname.split('.')
379
408
                except Exception, error:
380
409
                    pass
381
410
            my_logger = logging.getLogger(logname)
382
 
            my_logger.removeHandler(self.logger_saved_info[logname][0])
383
 
            for old_hdlr in self.logger_saved_info[logname][1]:
384
 
                my_logger.addHandler(old_hdlr)
385
 
            #my_logger.setLevel(cls.logger_saved_info[logname][1])
 
411
            if logname in self.logger_saved_info:
 
412
                my_logger.removeHandler(self.logger_saved_info[logname][0])
 
413
                for old_hdlr in self.logger_saved_info[logname][1]:
 
414
                    my_logger.addHandler(old_hdlr)
 
415
            else:
 
416
                my_logger.setLevel(level)
 
417
        
386
418
            #for i, h in enumerate(my_logger.handlers):
387
419
            #    h.setLevel(cls.logger_saved_info[logname][2][i])
388
420
 
389
421
 
390
 
 
391
422
def detect_current_compiler(path):
392
423
    """find the current compiler for the current directory"""
393
424
    
572
603
        else:
573
604
            raise StopIteration
574
605
 
 
606
 
575
607
def write_PS_input(filePath, PS):
576
608
    """ Write out in file filePath the PS point to be read by the MadLoop."""
577
609
    try:
602
634
    return running_time
603
635
    
604
636
 
 
637
#===============================================================================
 
638
# TMP_directory (designed to work as with statement)
 
639
#===============================================================================
 
640
class TMP_directory(object):
 
641
    """create a temporary directory and ensure this one to be cleaned.
 
642
    """
 
643
 
 
644
    def __init__(self, suffix='', prefix='tmp', dir=None):
 
645
        import tempfile   
 
646
        self.path = tempfile.mkdtemp(suffix, prefix, dir)
 
647
 
 
648
 
 
649
    def __exit__(self, ctype, value, traceback ):
 
650
        shutil.rmtree(self.path)
 
651
        
 
652
    def __enter__(self):
 
653
        return self.path
605
654
 
606
655
#
607
656
# Global function to open supported file types
652
701
        
653
702
        # first for eps_viewer
654
703
        if not cls.eps_viewer:
655
 
           cls.eps_viewer = cls.find_valid(['gv', 'ggv', 'evince'], 'eps viewer') 
 
704
           cls.eps_viewer = cls.find_valid(['evince','gv', 'ggv'], 'eps viewer') 
656
705
            
657
706
        # Second for web browser
658
707
        if not cls.web_browser:
794
843
################################################################################
795
844
# function to check if two float are approximatively equal
796
845
################################################################################
797
 
def equal(a,b,sig_fig=6):
 
846
def equal(a,b,sig_fig=6, zero_limit=True):
798
847
    """function to check if two float are approximatively equal"""
799
848
    import math
800
849
 
801
 
    if a:
 
850
    if not a or not b:
 
851
        if zero_limit:
 
852
            power = sig_fig + 1
 
853
        else:
 
854
            return a == b  
 
855
    else:
802
856
        power = sig_fig - int(math.log10(abs(a))) + 1
803
 
    else:
804
 
        power = sig_fig + 1
 
857
 
805
858
    return ( a==b or abs(int(a*10**power) - int(b*10**power)) < 10)
806
859
 
807
860
################################################################################