1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """A set of functions performing routine administrative I/O tasks."""
16
17 import contextlib
18 import itertools
19 import logging
20 import os
21 import re
22 import signal
23 import subprocess
24 import sys
25 import StringIO
26 import sys
27 import optparse
28 import time
29 import shutil
30 import traceback
31 import gzip as ziplib
32 from distutils.version import LooseVersion, StrictVersion
33
34 try:
35
36 import madgraph
37 except Exception, error:
38
39 import internal
40 from internal import MadGraph5Error, InvalidCmd
41 import internal.files as files
42 MADEVENT = True
43 else:
44 from madgraph import MadGraph5Error, InvalidCmd
45 import madgraph.iolibs.files as files
46 MADEVENT = False
47
48
49 logger = logging.getLogger('cmdprint.ext_program')
50 logger_stderr = logging.getLogger('madevent.misc')
51 pjoin = os.path.join
57 """Parse a newline separated list of "param=value" as a dictionnary
58 """
59
60 info_dict = {}
61 pattern = re.compile("(?P<name>\w*)\s*=\s*(?P<value>.*)",
62 re.IGNORECASE | re.VERBOSE)
63 for entry in fsock:
64 entry = entry.strip()
65 if len(entry) == 0: continue
66 m = pattern.match(entry)
67 if m is not None:
68 info_dict[m.group('name')] = m.group('value')
69 else:
70 raise IOError, "String %s is not a valid info string" % entry
71
72 return info_dict
73
74
75 -def glob(name, path=''):
76 """call to glob.glob with automatic security on path"""
77 import glob as glob_module
78 path = re.sub('(?P<name>\?|\*|\[|\])', '[\g<name>]', path)
79 return glob_module.glob(pjoin(path, name))
80
81
82
83
84 -def mute_logger(names=['madgraph','ALOHA','cmdprint','madevent'], levels=[50,50,50,50]):
85 """change the logger level and restore those at their initial value at the
86 end of the function decorated."""
87 def control_logger(f):
88 def restore_old_levels(names, levels):
89 for name, level in zip(names, levels):
90 log_module = logging.getLogger(name)
91 log_module.setLevel(level)
92
93 def f_with_no_logger(self, *args, **opt):
94 old_levels = []
95 for name, level in zip(names, levels):
96 log_module = logging.getLogger(name)
97 old_levels.append(log_module.level)
98 log_module.setLevel(level)
99 try:
100 out = f(self, *args, **opt)
101 restore_old_levels(names, old_levels)
102 return out
103 except:
104 restore_old_levels(names, old_levels)
105 raise
106
107 return f_with_no_logger
108 return control_logger
109
110 PACKAGE_INFO = {}
115 """Returns the current version information of the MadGraph5_aMC@NLO package,
116 as written in the VERSION text file. If the file cannot be found,
117 a dictionary with empty values is returned. As an option, an info
118 string can be passed to be read instead of the file content.
119 """
120 global PACKAGE_INFO
121
122 if info_str:
123 info_dict = parse_info_str(StringIO.StringIO(info_str))
124
125 elif MADEVENT:
126 info_dict ={}
127 info_dict['version'] = open(pjoin(internal.__path__[0],'..','..','MGMEVersion.txt')).read().strip()
128 info_dict['date'] = '20xx-xx-xx'
129 else:
130 if PACKAGE_INFO:
131 return PACKAGE_INFO
132 info_dict = files.read_from_file(os.path.join(madgraph.__path__[0],
133 "VERSION"),
134 parse_info_str,
135 print_error=False)
136 PACKAGE_INFO = info_dict
137
138 return info_dict
139
144 """Returns the present time info for use in MG5 command history header.
145 """
146
147 creation_time = time.asctime()
148 time_info = {'time': creation_time,
149 'fill': ' ' * (26 - len(creation_time))}
150
151 return time_info
152
158 """ Returns None if compatible or, it not compatible, a string explaining
159 why it is so."""
160
161 ma5_version = None
162 try:
163 for line in open(pjoin(ma5path,'version.txt'),'r').read().split('\n'):
164 if line.startswith('MA5 version :'):
165 ma5_version=LooseVersion(line[13:].strip())
166 break
167 except:
168 ma5_version = None
169
170 if ma5_version is None:
171 reason = "No MadAnalysis5 version number could be read from the path supplied '%s'."%ma5path
172 reason += "\nThe specified version of MadAnalysis5 will not be active in your session."
173 return reason
174
175 mg5_version = None
176 try:
177 info = get_pkg_info()
178 mg5_version = LooseVersion(info['version'])
179 except:
180 mg5_version = None
181
182
183 if not mg5_version:
184 return None
185
186 if mg5_version < LooseVersion("2.6.1") and ma5_version >= LooseVersion("1.6.32"):
187 reason = "This active MG5aMC version is too old (v%s) for your selected version of MadAnalysis5 (v%s)"%(mg5_version,ma5_version)
188 reason += "\nUpgrade MG5aMC or re-install MA5 from within MG5aMC to fix this compatibility issue."
189 reason += "\nThe specified version of MadAnalysis5 will not be active in your session."
190 return reason
191
192 if mg5_version >= LooseVersion("2.6.1") and ma5_version < LooseVersion("1.6.32"):
193 reason = "Your selected version of MadAnalysis5 (v%s) is too old for this active version of MG5aMC (v%s)."%(ma5_version,mg5_version)
194 reason += "\nRe-install MA5 from within MG5aMC to fix this compatibility issue."
195 reason += "\nThe specified version of MadAnalysis5 will not be active in your session."
196 return reason
197
198 return None
199
204 """Browse the subdirectories of the path 'start_path' and returns the first
205 one found which contains at least one file ending with the string extension
206 given in argument."""
207
208 if not os.path.isdir(start_path):
209 return None
210 subdirs=[pjoin(start_path,dir) for dir in os.listdir(start_path)]
211 for subdir in subdirs:
212 if os.path.isfile(subdir):
213 if os.path.basename(subdir).endswith(extension):
214 return start_path
215 elif os.path.isdir(subdir):
216 path = find_includes_path(subdir, extension)
217 if path:
218 return path
219 return None
220
226 """ Get whether ninja supports quad prec in different ways"""
227
228
229 ninja_config = os.path.abspath(pjoin(
230 ninja_lib_path,os.pardir,'bin','ninja-config'))
231 if os.path.exists(ninja_config):
232 try:
233 p = Popen([ninja_config, '-quadsupport'], stdout=subprocess.PIPE,
234 stderr=subprocess.PIPE)
235 output, error = p.communicate()
236 return 'TRUE' in output.upper()
237 except Exception:
238 pass
239
240
241
242 return False
243
244
245
246
247 -def which(program):
248 def is_exe(fpath):
249 return os.path.exists(fpath) and os.access(\
250 os.path.realpath(fpath), os.X_OK)
251
252 if not program:
253 return None
254
255 fpath, fname = os.path.split(program)
256 if fpath:
257 if is_exe(program):
258 return program
259 else:
260 for path in os.environ["PATH"].split(os.pathsep):
261 exe_file = os.path.join(path, program)
262 if is_exe(exe_file):
263 return exe_file
264 return None
265
281
287 """ Make sure to turn off some dependency of MG5aMC. """
288
289 def tell(msg):
290 if log == 'stdout':
291 print msg
292 elif callable(log):
293 log(msg)
294
295
296 if dependency in ['pjfry','golem','samurai','ninja','collier']:
297 if cmd.options[dependency] not in ['None',None,'']:
298 tell("Deactivating MG5_aMC dependency '%s'"%dependency)
299 cmd.options[dependency] = None
300
302 """ Checks whether the specfieid MG dependency can be activated if it was
303 not turned off in MG5 options."""
304
305 def tell(msg):
306 if log == 'stdout':
307 print msg
308 elif callable(log):
309 log(msg)
310
311 if cmd is None:
312 cmd = MGCmd.MasterCmd()
313
314 if dependency=='pjfry':
315 if cmd.options['pjfry'] in ['None',None,''] or \
316 (cmd.options['pjfry'] == 'auto' and which_lib('libpjfry.a') is None) or\
317 which_lib(pjoin(cmd.options['pjfry'],'libpjfry.a')) is None:
318 tell("Installing PJFry...")
319 cmd.do_install('PJFry')
320
321 if dependency=='golem':
322 if cmd.options['golem'] in ['None',None,''] or\
323 (cmd.options['golem'] == 'auto' and which_lib('libgolem.a') is None) or\
324 which_lib(pjoin(cmd.options['golem'],'libgolem.a')) is None:
325 tell("Installing Golem95...")
326 cmd.do_install('Golem95')
327
328 if dependency=='samurai':
329 raise MadGraph5Error, 'Samurai cannot yet be automatically installed.'
330
331 if dependency=='ninja':
332 if cmd.options['ninja'] in ['None',None,''] or\
333 (cmd.options['ninja'] == './HEPTools/lib' and not MG5dir is None and\
334 which_lib(pjoin(MG5dir,cmd.options['ninja'],'libninja.a')) is None):
335 tell("Installing ninja...")
336 cmd.do_install('ninja')
337
338 if dependency=='collier':
339 if cmd.options['collier'] in ['None',None,''] or\
340 (cmd.options['collier'] == 'auto' and which_lib('libcollier.a') is None) or\
341 which_lib(pjoin(cmd.options['collier'],'libcollier.a')) is None:
342 tell("Installing COLLIER...")
343 cmd.do_install('collier')
344
349 def is_lib(fpath):
350 return os.path.exists(fpath) and os.access(fpath, os.R_OK)
351
352 if not lib:
353 return None
354
355 fpath, fname = os.path.split(lib)
356 if fpath:
357 if is_lib(lib):
358 return lib
359 else:
360 locations = sum([os.environ[env_path].split(os.pathsep) for env_path in
361 ["DYLD_LIBRARY_PATH","LD_LIBRARY_PATH","LIBRARY_PATH","PATH"]
362 if env_path in os.environ],[])
363 for path in locations:
364 lib_file = os.path.join(path, lib)
365 if is_lib(lib_file):
366 return lib_file
367 return None
368
373 """ Return nice information on the current variable """
374
375
376 info = [('type',type(var)),('str', var)]
377 if hasattr(var, 'func_doc'):
378 info.append( ('DOC', var.func_doc) )
379 if hasattr(var, '__doc__'):
380 info.append( ('DOC', var.__doc__) )
381 if hasattr(var, '__dict__'):
382 info.append( ('ATTRIBUTE', var.__dict__.keys() ))
383
384 spaces = ' ' * nb_space
385
386 outstr=''
387 for name, value in info:
388 outstr += '%s%3s : %s\n' % (spaces,name, value)
389
390 return outstr
391
392
393
394
395 wait_once = False
397
398 def deco_retry(f):
399 def deco_f_retry(*args, **opt):
400 for i in range(nb_try):
401 try:
402 return f(*args, **opt)
403 except KeyboardInterrupt:
404 raise
405 except Exception, error:
406 global wait_once
407 if not wait_once:
408 text = """Start waiting for update. (more info in debug mode)"""
409 logger.info(text)
410 logger_stderr.debug('fail to do %s function with %s args. %s try on a max of %s (%s waiting time)' %
411 (str(f), ', '.join([str(a) for a in args]), i+1, nb_try, sleep * (i+1)))
412 logger_stderr.debug('error is %s' % str(error))
413 if __debug__: logger_stderr.debug('and occurred at :'+traceback.format_exc())
414 wait_once = True
415 time.sleep(sleep * (i+1))
416
417 if __debug__:
418 raise
419 raise error.__class__, '[Fail %i times] \n %s ' % (i+1, error)
420 return deco_f_retry
421 return deco_retry
422
427 """return a name of the type xxxx[A-B]yyy
428 where xxx and yyy are the common part between the two names.
429 """
430
431
432 base = [first[i] for i in range(len(first)) if first[:i+1] == last[:i+1]]
433
434 while base and base[0].isdigit():
435 base = base[1:]
436
437 end = [first[-(i+1)] for i in range(len(first)) if first[-(i+1):] == last[-(i+1):]]
438
439 while end and end[-1].isdigit():
440 end = end[:-1]
441 end.reverse()
442
443 base, end = ''.join(base), ''.join(end)
444 if end:
445 name = "%s[%s-%s]%s" % (base, first[len(base):-len(end)], last[len(base):-len(end)],end)
446 else:
447 name = "%s[%s-%s]%s" % (base, first[len(base):], last[len(base):],end)
448 return name
449
450
451
452
453 -def compile(arg=[], cwd=None, mode='fortran', job_specs = True, nb_core=1 ,**opt):
454 """compile a given directory"""
455
456 if 'nocompile' in opt:
457 if opt['nocompile'] == True:
458 if not arg:
459 return
460 if cwd:
461 executable = pjoin(cwd, arg[0])
462 else:
463 executable = arg[0]
464 if os.path.exists(executable):
465 return
466 del opt['nocompile']
467
468 cmd = ['make']
469 try:
470 if nb_core > 1:
471 cmd.append('-j%s' % nb_core)
472 cmd += arg
473 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
474 stderr=subprocess.STDOUT, cwd=cwd, **opt)
475 (out, err) = p.communicate()
476 except OSError, error:
477 if cwd and not os.path.exists(cwd):
478 raise OSError, 'Directory %s doesn\'t exists. Impossible to run make' % cwd
479 else:
480 error_text = "Impossible to compile %s directory\n" % cwd
481 error_text += "Trying to launch make command returns:\n"
482 error_text += " " + str(error) + "\n"
483 error_text += "In general this means that your computer is not able to compile."
484 if sys.platform == "darwin":
485 error_text += "Note that MacOSX doesn\'t have gmake/gfortan install by default.\n"
486 error_text += "Xcode3 contains those required programs"
487 raise MadGraph5Error, error_text
488
489 if p.returncode:
490
491 if not cwd:
492 cwd = os.getcwd()
493 all_file = [f.lower() for f in os.listdir(cwd)]
494 if 'makefile' not in all_file and '-f' not in arg:
495 raise OSError, 'no makefile present in %s' % os.path.realpath(cwd)
496
497 if mode == 'fortran' and not (which('g77') or which('gfortran')):
498 error_msg = 'A fortran compiler (g77 or gfortran) is required to create this output.\n'
499 error_msg += 'Please install g77 or gfortran on your computer and retry.'
500 raise MadGraph5Error, error_msg
501 elif mode == 'cpp' and not which('g++'):
502 error_msg ='A C++ compiler (g++) is required to create this output.\n'
503 error_msg += 'Please install g++ (which is part of the gcc package) on your computer and retry.'
504 raise MadGraph5Error, error_msg
505
506
507 if any(tag.upper() in out.upper() for tag in ['real(kind=16)','real*16',
508 'complex*32']) and mode == 'fortran' and not \
509 ''.join(get_gfortran_version().split('.')) >= '46':
510 if not which('gfortran'):
511 raise MadGraph5Error, 'The fortran compiler gfortran v4.6 or later '+\
512 'is required to compile %s.\nPlease install it and retry.'%cwd
513 else:
514 logger_stderr.error('ERROR, you could not compile %s because'%cwd+\
515 ' your version of gfortran is older than 4.6. MadGraph5_aMC@NLO will carry on,'+\
516 ' but will not be able to compile an executable.')
517 return p.returncode
518
519 error_text = 'A compilation Error occurs '
520 if cwd:
521 error_text += 'when trying to compile %s.\n' % cwd
522 error_text += 'The compilation fails with the following output message:\n'
523 error_text += ' '+out.replace('\n','\n ')+'\n'
524 error_text += 'Please try to fix this compilations issue and retry.\n'
525 error_text += 'Help might be found at https://answers.launchpad.net/mg5amcnlo.\n'
526 error_text += 'If you think that this is a bug, you can report this at https://bugs.launchpad.net/mg5amcnlo'
527 raise MadGraph5Error, error_text
528 return p.returncode
529
531 """ Returns the gfortran version as a string.
532 Returns '0' if it failed."""
533 try:
534 p = Popen([compiler, '-dumpversion'], stdout=subprocess.PIPE,
535 stderr=subprocess.PIPE)
536 output, error = p.communicate()
537 version_finder=re.compile(r"(?P<version>(\d.)*\d)")
538 version = version_finder.search(output).group('version')
539 return version
540 except Exception:
541 return '0'
542
543 -def mod_compilator(directory, new='gfortran', current=None, compiler_type='gfortran'):
544
545 if type(directory)!=list:
546 directory=[directory]
547
548
549 file_to_change=find_makefile_in_dir(directory)
550 if compiler_type == 'gfortran':
551 comp_re = re.compile('^(\s*)FC\s*=\s*(.+)\s*$')
552 var = 'FC'
553 elif compiler_type == 'cpp':
554 comp_re = re.compile('^(\s*)CXX\s*=\s*(.+)\s*$')
555 var = 'CXX'
556 else:
557 MadGraph5Error, 'Unknown compiler type: %s' % compiler_type
558
559 mod = False
560 for name in file_to_change:
561 lines = open(name,'r').read().split('\n')
562 for iline, line in enumerate(lines):
563 result = comp_re.match(line)
564 if result:
565 if new != result.group(2) and '$' not in result.group(2):
566 mod = True
567 lines[iline] = result.group(1) + var + "=" + new
568 elif compiler_type == 'gfortran' and line.startswith('DEFAULT_F_COMPILER'):
569 lines[iline] = "DEFAULT_F_COMPILER = %s" % new
570 elif compiler_type == 'cpp' and line.startswith('DEFAULT_CPP_COMPILER'):
571 lines[iline] = "DEFAULT_CPP_COMPILER = %s" % new
572
573 if mod:
574 open(name,'w').write('\n'.join(lines))
575
576 mod = False
577
582 """mute_logger (designed to work as with statement),
583 files allow to redirect the output of the log to a given file.
584 """
585
586 - def __init__(self, names, levels, files=None, **opt):
587 assert isinstance(names, list)
588 assert isinstance(names, list)
589
590 self.names = names
591 self.levels = levels
592 if isinstance(files, list):
593 self.files = files
594 else:
595 self.files = [files] * len(names)
596 self.logger_saved_info = {}
597 self.opts = opt
598
609
610 - def __exit__(self, ctype, value, traceback ):
621
623 """ Setup the logger by redirecting them all to logfiles in tmp """
624
625 logs = full_logname.split('.')
626 lognames = [ '.'.join(logs[:(len(logs)-i)]) for i in\
627 range(len(full_logname.split('.')))]
628 for logname in lognames:
629 try:
630 os.remove(path)
631 except Exception, error:
632 pass
633 my_logger = logging.getLogger(logname)
634 hdlr = logging.FileHandler(path)
635
636
637 self.logger_saved_info[logname] = [hdlr, my_logger.handlers]
638
639
640 for old_hdlr in list(my_logger.handlers):
641 my_logger.removeHandler(old_hdlr)
642 my_logger.addHandler(hdlr)
643
644 my_logger.debug('Log of %s' % logname)
645
647 """ Setup the logger by redirecting them all to logfiles in tmp """
648
649 logs = full_logname.split('.')
650 lognames = [ '.'.join(logs[:(len(logs)-i)]) for i in\
651 range(len(full_logname.split('.')))]
652 for logname in lognames:
653 if path:
654 try:
655 os.remove(path)
656 except Exception, error:
657 pass
658 my_logger = logging.getLogger(logname)
659 if logname in self.logger_saved_info:
660 my_logger.removeHandler(self.logger_saved_info[logname][0])
661 for old_hdlr in self.logger_saved_info[logname][1]:
662 my_logger.addHandler(old_hdlr)
663 else:
664 my_logger.setLevel(level)
665
666
667
668
669 nb_open =0
672 """
673 A context manager to temporarily redirect stdout or stderr
674
675 e.g.:
676
677
678 with stdchannel_redirected(sys.stderr, os.devnull):
679 if compiler.has_function('clock_gettime', libraries=['rt']):
680 libraries.append('rt')
681 """
682
683 try:
684 oldstdchannel = os.dup(stdchannel.fileno())
685 dest_file = open(dest_filename, 'w')
686 os.dup2(dest_file.fileno(), stdchannel.fileno())
687 yield
688 finally:
689 if oldstdchannel is not None:
690 os.dup2(oldstdchannel, stdchannel.fileno())
691 os.close(oldstdchannel)
692 if dest_file is not None:
693 dest_file.close()
694
696 '''
697 return the number of open file descriptors for current process
698
699 .. warning: will only work on UNIX-like os-es.
700 '''
701 import subprocess
702 import os
703
704 pid = os.getpid()
705 procs = subprocess.check_output(
706 [ "lsof", '-w', '-Ff', "-p", str( pid ) ] )
707 nprocs = filter(
708 lambda s: s and s[ 0 ] == 'f' and s[1: ].isdigit(),
709 procs.split( '\n' ) )
710
711 return nprocs
712
714 """ Detects whether the specified C++ compiler is clang."""
715
716 try:
717 p = Popen([cpp_compiler, '--version'], stdout=subprocess.PIPE,
718 stderr=subprocess.PIPE)
719 output, error = p.communicate()
720 except Exception, error:
721
722 return False
723 return 'LLVM' in output
724
726 """ Detects if the specified c++ compiler will normally link against the C++
727 standard library -lc++ or -libstdc++."""
728
729 is_clang = detect_if_cpp_compiler_is_clang(cpp_compiler)
730 if is_clang:
731 try:
732 import platform
733 v, _,_ = platform.mac_ver()
734 if not v:
735
736
737 return '-lc++'
738 else:
739 v = float(v.rsplit('.')[1])
740 if v >= 9:
741 return '-lc++'
742 else:
743 return '-lstdc++'
744 except:
745 return '-lstdc++'
746 return '-lstdc++'
747
749 """find the current compiler for the current directory"""
750
751
752
753 if compiler_type == 'fortran':
754 comp = re.compile("^\s*FC\s*=\s*([\w\/\\.\-]+)\s*")
755 elif compiler_type == 'cpp':
756 comp = re.compile("^\s*CXX\s*=\s*([\w\/\\.\-]+)\s*")
757 else:
758 MadGraph5Error, 'Unknown compiler type: %s' % compiler_type
759
760 for line in open(path):
761 if comp.search(line):
762 compiler = comp.search(line).groups()[0]
763 return compiler
764 elif compiler_type == 'fortran' and line.startswith('DEFAULT_F_COMPILER'):
765 return line.split('=')[1].strip()
766 elif compiler_type == 'cpp' and line.startswith('DEFAULT_CPP_COMPILER'):
767 return line.split('=')[1].strip()
768
770 """ return a list of all file starting with makefile in the given directory"""
771
772 out=[]
773
774 if type(directory)==list:
775 for name in directory:
776 out+=find_makefile_in_dir(name)
777 return out
778
779
780 for name in os.listdir(directory):
781 if os.path.isdir(directory+'/'+name):
782 out+=find_makefile_in_dir(directory+'/'+name)
783 elif os.path.isfile(directory+'/'+name) and name.lower().startswith('makefile'):
784 out.append(directory+'/'+name)
785 elif os.path.isfile(directory+'/'+name) and name.lower().startswith('make_opt'):
786 out.append(directory+'/'+name)
787 return out
788
790
791
792 os.path.walk('.', rm_file_extension, '.o')
793
794
795 libraries = ['libblocks.a', 'libgeneric_mw.a', 'libMWPS.a', 'libtools.a', 'libdhelas3.a',
796 'libdsample.a', 'libgeneric.a', 'libmodel.a', 'libpdf.a', 'libdhelas3.so', 'libTF.a',
797 'libdsample.so', 'libgeneric.so', 'libmodel.so', 'libpdf.so']
798 lib_pos='./lib'
799 [os.remove(os.path.join(lib_pos, lib)) for lib in libraries \
800 if os.path.exists(os.path.join(lib_pos, lib))]
801
815
819
823 replace_dict = dict(key_values)
824 replacement_function = lambda match: replace_dict[match.group(0)]
825 pattern = re.compile("|".join([re.escape(k) for k, v in key_values]), re.M)
826 return lambda string: pattern.sub(replacement_function, string)
827
830
833 def deco_check(f):
834 def deco_f(arg, *args, **opt):
835 try:
836 return f(arg, *args, **opt)
837 except OSError, error:
838 logger.debug('try to recover from %s' % error)
839 if isinstance(arg, list):
840 prog = arg[0]
841 else:
842 prog = arg[0]
843
844
845 if error.errno == 13:
846 if os.path.exists(prog):
847 os.system('chmod +x %s' % prog)
848 elif 'cwd' in opt and opt['cwd'] and \
849 os.path.isfile(pjoin(opt['cwd'],arg[0])):
850 os.system('chmod +x %s' % pjoin(opt['cwd'],arg[0]))
851 return f(arg, *args, **opt)
852
853 elif error.errno == 2:
854
855 raise Exception, '%s fails with no such file or directory' \
856 % arg
857 else:
858 raise
859 return deco_f
860 return deco_check
861
862
863 @check_system_error()
864 -def call(arg, *args, **opt):
865 """nice way to call an external program with nice error treatment"""
866 try:
867 return subprocess.call(arg, *args, **opt)
868 except OSError:
869 arg[0] = './%s' % arg[0]
870 return subprocess.call(arg, *args, **opt)
871
872 @check_system_error()
873 -def Popen(arg, *args, **opt):
874 """nice way to call an external program with nice error treatment"""
875 return subprocess.Popen(arg, *args, **opt)
876
879 """try to open a file with multiple try to ensure that filesystem is sync"""
880 return open(filepath, *args, ** opt)
881
882
883
884
885 -def tail(f, n, offset=None):
886 """Reads a n lines from f with an offset of offset lines. The return
887 value is a tuple in the form ``lines``.
888 """
889 avg_line_length = 74
890 to_read = n + (offset or 0)
891
892 while 1:
893 try:
894 f.seek(-(avg_line_length * to_read), 2)
895 except IOError:
896
897
898 f.seek(0)
899 pos = f.tell()
900 lines = f.read().splitlines()
901 if len(lines) >= to_read or pos == 0:
902 return lines[-to_read:offset and -offset or None]
903 avg_line_length *= 1.3
904 avg_line_length = int(avg_line_length)
905
907 """ makes a piping fifo (First-in First-out) file and nicely intercepts
908 error in case the file format of the target drive doesn't suppor tit."""
909
910 try:
911 os.mkfifo(fifo_path)
912 except:
913 raise OSError('MadGraph5_aMCatNLO could not create a fifo file at:\n'+
914 ' %s\n'%fifo_path+'Make sure that this file does not exist already'+
915 ' and that the file format of the target drive supports fifo file (i.e not NFS).')
916
921 """return the last line of a file"""
922
923 return tail(fsock, 1)[0]
924
926 """read a file returning the lines in reverse order for each call of readline()
927 This actually just reads blocks (4096 bytes by default) of data from the end of
928 the file and returns last line in an internal buffer."""
929
930
932 """ readline in a backward way """
933
934 while len(self.data) == 1 and ((self.blkcount * self.blksize) < self.size):
935 self.blkcount = self.blkcount + 1
936 line = self.data[0]
937 try:
938 self.seek(-self.blksize * self.blkcount, 2)
939 self.data = (self.read(self.blksize) + line).split('\n')
940 except IOError:
941 self.seek(0)
942 data = self.read(self.size - (self.blksize * (self.blkcount-1))) + line
943 self.data = data.split('\n')
944
945 if len(self.data) == 0:
946 return ""
947
948 line = self.data.pop()
949 return line + '\n'
950
951 - def __init__(self, filepos, blksize=4096):
952 """initialize the internal structures"""
953
954
955 self.size = os.stat(filepos)[6]
956
957 self.blksize = blksize
958
959 self.blkcount = 1
960 file.__init__(self, filepos, 'rb')
961
962
963 if self.size > self.blksize:
964 self.seek(-self.blksize * self.blkcount, 2)
965 self.data = self.read(self.blksize).split('\n')
966
967
968 if not self.data[-1]:
969 self.data.pop()
970
972 line = self.readline()
973 if line:
974 return line
975 else:
976 raise StopIteration
977
993
1007
1013 """create a temporary directory and ensure this one to be cleaned.
1014 """
1015
1016 - def __init__(self, suffix='', prefix='tmp', dir=None):
1017 self.nb_try_remove = 0
1018 import tempfile
1019 self.path = tempfile.mkdtemp(suffix, prefix, dir)
1020
1021
1022 - def __exit__(self, ctype, value, traceback ):
1023
1024 if False and isinstance(value, Exception):
1025 sprint("Directory %s not cleaned. This directory can be removed manually" % self.path)
1026 return False
1027 try:
1028 shutil.rmtree(self.path)
1029 except OSError:
1030 self.nb_try_remove += 1
1031 if self.nb_try_remove < 3:
1032 time.sleep(10)
1033 self.__exit__(ctype, value, traceback)
1034 else:
1035 logger.warning("Directory %s not completely cleaned. This directory can be removed manually" % self.path)
1036
1039
1041 """create a temporary directory and ensure this one to be cleaned.
1042 """
1043
1044 - def __init__(self, cls, attribute, value):
1045
1046 self.cls = cls
1047 self.attribute = attribute
1048 if isinstance(attribute, list):
1049 self.old_value = []
1050 for key, onevalue in zip(attribute, value):
1051 self.old_value.append(getattr(cls, key))
1052 setattr(self.cls, key, onevalue)
1053 else:
1054 self.old_value = getattr(cls, attribute)
1055 setattr(self.cls, self.attribute, value)
1056
1057 - def __exit__(self, ctype, value, traceback ):
1058
1059 if isinstance(self.attribute, list):
1060 for key, old_value in zip(self.attribute, self.old_value):
1061 setattr(self.cls, key, old_value)
1062 else:
1063 setattr(self.cls, self.attribute, self.old_value)
1064
1066 return self.old_value
1067
1068
1069
1070
1071 -def gunzip(path, keep=False, stdout=None):
1072 """ a standard replacement for os.system('gunzip -f %s.gz ' % event_path)"""
1073
1074 if not path.endswith(".gz"):
1075 if os.path.exists("%s.gz" % path):
1076 path = "%s.gz" % path
1077 else:
1078 raise Exception, "%(path)s does not finish by .gz and the file %(path)s.gz does not exists" %\
1079 {"path": path}
1080
1081
1082
1083 if os.path.getsize(path) > 1e8:
1084 if stdout:
1085 os.system('gunzip -c %s > %s' % (path, stdout))
1086 else:
1087 os.system('gunzip %s' % path)
1088 return 0
1089
1090 if not stdout:
1091 stdout = path[:-3]
1092 try:
1093 gfile = ziplib.open(path, "r")
1094 except IOError:
1095 raise
1096 else:
1097 try:
1098 open(stdout,'w').write(gfile.read())
1099 except IOError:
1100
1101 if stdout == path:
1102 return
1103 else:
1104 files.cp(path, stdout)
1105
1106 if not keep:
1107 os.remove(path)
1108 return 0
1109
1110 -def gzip(path, stdout=None, error=True, forceexternal=False):
1111 """ a standard replacement for os.system('gzip %s ' % path)"""
1112
1113
1114 if os.path.getsize(path) > 1e9 or forceexternal:
1115 call(['gzip', '-f', path])
1116 if stdout:
1117 if not stdout.endswith(".gz"):
1118 stdout = "%s.gz" % stdout
1119 shutil.move('%s.gz' % path, stdout)
1120 return
1121
1122 if not stdout:
1123 stdout = "%s.gz" % path
1124 elif not stdout.endswith(".gz"):
1125 stdout = "%s.gz" % stdout
1126
1127 try:
1128 ziplib.open(stdout,"w").write(open(path).read())
1129 except OverflowError:
1130 gzip(path, stdout, error=error, forceexternal=True)
1131 except Exception:
1132 if error:
1133 raise
1134 else:
1135 os.remove(path)
1136
1141 """ a convinient class to open a file """
1142
1143 web_browser = None
1144 eps_viewer = None
1145 text_editor = None
1146 configured = False
1147
1149 """open a file"""
1150
1151
1152 if not self.configured:
1153 self.configure()
1154
1155 try:
1156 extension = filename.rsplit('.',1)[1]
1157 except IndexError:
1158 extension = ''
1159
1160
1161
1162 if extension in ['html','htm','php']:
1163 self.open_program(self.web_browser, filename, background=True)
1164 elif extension in ['ps','eps']:
1165 self.open_program(self.eps_viewer, filename, background=True)
1166 else:
1167 self.open_program(self.text_editor,filename, mac_check=False)
1168
1169
1170 @classmethod
1193
1194 @classmethod
1232
1233
1234 @staticmethod
1236 """find a valid shell program in the list"""
1237
1238 for p in possibility:
1239 if which(p):
1240 logger.info('Using default %s \"%s\". ' % (program, p) + \
1241 'Set another one in ./input/mg5_configuration.txt')
1242 return p
1243
1244 logger.info('No valid %s found. ' % program + \
1245 'Please set in ./input/mg5_configuration.txt')
1246 return None
1247
1248
1249 - def open_program(self, program, file_path, mac_check=True, background=False):
1250 """ open a file with a given program """
1251
1252 if mac_check==True and sys.platform == 'darwin':
1253 return self.open_mac_program(program, file_path)
1254
1255
1256 if program:
1257 arguments = program.split()
1258 arguments.append(file_path)
1259
1260 if not background:
1261 subprocess.call(arguments)
1262 else:
1263 import thread
1264 thread.start_new_thread(subprocess.call,(arguments,))
1265 else:
1266 logger.warning('Not able to open file %s since no program configured.' % file_path + \
1267 'Please set one in ./input/mg5_configuration.txt')
1268
1270 """ open a text with the text editor """
1271
1272 if not program:
1273
1274 os.system('open %s' % file_path)
1275 elif which(program):
1276
1277 arguments = program.split()
1278 arguments.append(file_path)
1279 subprocess.call(arguments)
1280 else:
1281
1282 os.system('open -a %s %s' % (program, file_path))
1283
1303
1305 """ Try and guess what shell type does the user use."""
1306 try:
1307 if os.environ['SHELL'].endswith('bash'):
1308 return 'bash'
1309 elif os.environ['SHELL'].endswith('tcsh'):
1310 return 'tcsh'
1311 else:
1312
1313 return None
1314 except KeyError:
1315 return None
1316
1318 """ check if a path is executable"""
1319 try:
1320 return os.access(path, os.X_OK)
1321 except Exception:
1322 return False
1323
1325 """Option Peaser which raise an error instead as calling exit"""
1326
1327 - def exit(self, status=0, msg=None):
1332
1334 """Returns the current line number in our program."""
1335
1336 if not __debug__:
1337 return
1338
1339 use_print = False
1340 import inspect
1341 if opt.has_key('cond') and not opt['cond']:
1342 return
1343
1344 if opt.has_key('log'):
1345 log = opt['log']
1346 else:
1347 log = logging.getLogger('madgraph')
1348 if opt.has_key('level'):
1349 level = opt['level']
1350 else:
1351 level = logging.getLogger('madgraph').level
1352 if level == 0:
1353 use_print = True
1354
1355
1356
1357
1358 if opt.has_key('wait'):
1359 wait = bool(opt['wait'])
1360 else:
1361 wait = False
1362
1363 lineno = inspect.currentframe().f_back.f_lineno
1364 fargs = inspect.getframeinfo(inspect.currentframe().f_back)
1365 filename, lineno = fargs[:2]
1366
1367
1368 try:
1369 source = inspect.getsourcelines(inspect.currentframe().f_back)
1370 line = source[0][lineno-source[1]]
1371 line = re.findall(r"misc\.sprint\(\s*(.*)\)\s*($|#)", line)[0][0]
1372 if line.startswith("'") and line.endswith("'") and line.count(",") ==0:
1373 line= ''
1374 elif line.startswith("\"") and line.endswith("\"") and line.count(",") ==0:
1375 line= ''
1376 elif line.startswith(("\"","'")) and len(args)==1 and "%" in line:
1377 line= ''
1378 except Exception:
1379 line=''
1380
1381 if line:
1382 intro = ' %s = \033[0m' % line
1383 else:
1384 intro = ''
1385
1386
1387 if not use_print:
1388 log.log(level, ' '.join([intro]+[str(a) for a in args]) + \
1389 ' \033[1;30m[%s at line %s]\033[0m' % (os.path.basename(filename), lineno))
1390 else:
1391 print ' '.join([intro]+[str(a) for a in args]) + \
1392 ' \033[1;30m[%s at line %s]\033[0m' % (os.path.basename(filename), lineno)
1393
1394 if wait:
1395 raw_input('press_enter to continue')
1396
1397 return
1398
1399
1400
1401
1402 -def equal(a,b,sig_fig=6, zero_limit=True):
1403 """function to check if two float are approximatively equal"""
1404 import math
1405
1406 if isinstance(sig_fig, int):
1407 if not a or not b:
1408 if zero_limit:
1409 if zero_limit is not True:
1410 power = zero_limit
1411 else:
1412 power = sig_fig + 1
1413 else:
1414 return a == b
1415 else:
1416 power = sig_fig - int(math.log10(abs(a))) + 1
1417
1418 return ( a==b or abs(int(a*10**power) - int(b*10**power)) < 10)
1419 else:
1420 return abs(a-b) < sig_fig
1421
1422
1423
1424
1425
1426
1427
1428 -class chdir:
1430 self.newPath = newPath
1431
1433 self.savedPath = os.getcwd()
1434 os.chdir(self.newPath)
1435
1436 - def __exit__(self, etype, value, traceback):
1437 os.chdir(self.savedPath)
1438
1439
1440
1441
1442
1443 -def timeout(func, args=(), kwargs={}, timeout_duration=1, default=None):
1444 '''This function will spwan a thread and run the given function using the args, kwargs and
1445 return the given default value if the timeout_duration is exceeded
1446 '''
1447 import threading
1448 class InterruptableThread(threading.Thread):
1449 def __init__(self):
1450 threading.Thread.__init__(self)
1451 self.result = default
1452 def run(self):
1453 try:
1454 self.result = func(*args, **kwargs)
1455 except Exception,error:
1456 print error
1457 self.result = default
1458 it = InterruptableThread()
1459 it.start()
1460 it.join(timeout_duration)
1461 return it.result
1462
1463
1464
1465
1466
1467 -class digest:
1468
1470 try:
1471 return self.test_hashlib()
1472 except Exception:
1473 pass
1474 try:
1475 return self.test_md5()
1476 except Exception:
1477 pass
1478 try:
1479 return self.test_zlib()
1480 except Exception:
1481 pass
1482
1484 import hashlib
1485 def digest(text):
1486 """using mg5 for the hash"""
1487 t = hashlib.md5()
1488 t.update(text)
1489 return t.hexdigest()
1490 return digest
1491
1493 import md5
1494 def digest(text):
1495 """using mg5 for the hash"""
1496 t = md5.md5()
1497 t.update(text)
1498 return t.hexdigest()
1499 return digest
1500
1502 import zlib
1503 def digest(text):
1504 return zlib.adler32(text)
1505
1506 digest = digest().test_all()
1513 self.cmd_args = args
1514 self.cmd_opts = opts
1515 self.execution_state = False
1516
1518 self.max_vms_memory = 0
1519 self.max_rss_memory = 0
1520
1521 self.t1 = None
1522 self.t0 = time.time()
1523 self.p = subprocess.Popen(*self.cmd_args,**self.cmd_opts)
1524 self.execution_state = True
1525
1527 if not self.check_execution_state():
1528 return False
1529
1530 self.t1 = time.time()
1531
1532
1533
1534 flash = subprocess.Popen("ps -p %i -o rss"%self.p.pid,
1535 shell=True,stdout=subprocess.PIPE,stderr=open(os.devnull,"w"))
1536 stdout_list = flash.communicate()[0].split('\n')
1537 rss_memory = int(stdout_list[1])
1538
1539 vms_memory = 0
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568 self.max_vms_memory = max(self.max_vms_memory,vms_memory)
1569 self.max_rss_memory = max(self.max_rss_memory,rss_memory)
1570
1571 return self.check_execution_state()
1572
1574
1575
1576 return self.p.poll() == None
1577
1579 if not self.execution_state:
1580 return False
1581 if self.is_running():
1582 return True
1583 self.executation_state = False
1584 self.t1 = time.time()
1585 return False
1586
1587 - def close(self,kill=False):
1588
1589 if self.p.poll() == None:
1590 if kill:
1591 self.p.kill()
1592 else:
1593 self.p.terminate()
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606 -class Applenotification(object):
1607
1609 self.init = False
1610 self.working = True
1611
1613 try:
1614 import Foundation
1615 import objc
1616 self.NSUserNotification = objc.lookUpClass('NSUserNotification')
1617 self.NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
1618 except:
1619 self.working=False
1620 self.working=True
1621
1622 - def __call__(self,subtitle, info_text, userInfo={}):
1623
1624 if not self.init:
1625 self.load_notification()
1626 if not self.working:
1627 return
1628 try:
1629 notification = self.NSUserNotification.alloc().init()
1630 notification.setTitle_('MadGraph5_aMC@NLO')
1631 notification.setSubtitle_(subtitle)
1632 notification.setInformativeText_(info_text)
1633 try:
1634 notification.setUserInfo_(userInfo)
1635 except:
1636 pass
1637 self.NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)
1638 except:
1639 pass
1640
1641
1642
1643 apple_notify = Applenotification()
1646
1647 done_notification = False
1648 message_aprilfirst =\
1649 {'error': ['Be careful, a cat is eating a lot of fish today. This makes the code unstable.',
1650 'Really, this sounds fishy.',
1651 'A Higgs boson walks into a church. The priest says "We don\'t allow Higgs bosons in here." The Higgs boson replies, "But without me, how can you have mass?"',
1652 "Why does Heisenberg detest driving cars? Because, every time he looks at the speedometer he gets lost!",
1653 "May the mass times acceleration be with you.",
1654 "NOTE: This product may actually be nine-dimensional. If this is the case, functionality is not affected by the extra five dimensions.",
1655 "IMPORTANT: This product is composed of 100%% matter: It is the responsibility of the User to make sure that it does not come in contact with antimatter.",
1656 'The fish are out of jokes. See you next year for more!'],
1657 'loading': ['Hi %(user)s, You are Loading Madgraph. Please be patient, we are doing the work.'],
1658 'quit': ['Thanks %(user)s for using MadGraph5_aMC@NLO, even on April 1st!']
1659 }
1660
1662
1663 try:
1664 now = time.localtime()
1665 date = now.tm_mday, now.tm_mon
1666 if date in [(1,4)]:
1667 if msgtype in EasterEgg.message_aprilfirst:
1668 choices = EasterEgg.message_aprilfirst[msgtype]
1669 if len(choices) == 0:
1670 return
1671 elif len(choices) == 1:
1672 msg = choices[0]
1673 else:
1674 import random
1675 msg = choices[random.randint(0,len(choices)-2)]
1676 EasterEgg.message_aprilfirst[msgtype].remove(msg)
1677
1678 else:
1679 return
1680 if MADEVENT:
1681 return
1682
1683 import os
1684 import pwd
1685 username =pwd.getpwuid( os.getuid() )[ 0 ]
1686 msg = msg % {'user': username}
1687 if sys.platform == "darwin":
1688 self.call_apple(msg)
1689 else:
1690 self.call_linux(msg)
1691 except Exception, error:
1692 sprint(error)
1693 pass
1694
1696 try:
1697 self.call_apple(msg)
1698 except:
1699 pass
1700
1702
1703
1704 p = subprocess.Popen("osascript -e 'get volume settings'", stdout=subprocess.PIPE, shell=True)
1705 output, _ = p.communicate()
1706
1707 info = dict([[a.strip() for a in l.split(':',1)] for l in output.strip().split(',')])
1708 muted = False
1709 if 'output muted' in info and info['output muted'] == 'true':
1710 muted = True
1711 elif 'output volume' in info and info['output volume'] == '0':
1712 muted = True
1713
1714 if muted:
1715 if not EasterEgg.done_notification:
1716 apple_notify('On April first','turn up your volume!')
1717 EasterEgg.done_notification = True
1718 else:
1719 os.system('say %s' % msg)
1720
1721
1723
1724 fishPath = madgraph.MG5DIR+"/input/.cowgraph.cow"
1725 if os.path.exists(fishPath):
1726 fishPath = " -f " + fishPath
1727
1728
1729
1730 fishPole = which('cowthink')
1731 if not os.path.exists(fishPole):
1732 if os.path.exists(which('cowsay')):
1733 fishPole = which('cowsay')
1734 else:
1735 return
1736
1737
1738 fishCmd = fishPole + fishPath + " " + msg
1739 os.system(fishCmd)
1740
1741
1742 if __debug__:
1743 try:
1744 import os
1745 import pwd
1746 username =pwd.getpwuid( os.getuid() )[ 0 ]
1747 if 'hirschi' in username or 'vryonidou' in username and __debug__:
1748 EasterEgg('loading')
1749 except:
1750 pass
1754 """ return v2 if v1>v2
1755 return v1 if v1<v2
1756 return v1 if v1=v2
1757 return v1 if v2 is not in 1.2.3.4.5 format
1758 return v2 if v1 is not in 1.2.3.4.5 format
1759 """
1760 from itertools import izip_longest
1761 for a1, a2 in izip_longest(v1, v2, fillvalue=0):
1762 try:
1763 a1= int(a1)
1764 except:
1765 return v2
1766 try:
1767 a2= int(a2)
1768 except:
1769 return v1
1770 if a1 > a2:
1771 return v2
1772 elif a1 < a2:
1773 return v1
1774 return v1
1775
1776
1777
1778 plugin_support = {}
1816
1817
1818
1819 -def set_global(loop=False, unitary=True, mp=False, cms=False):
1849 return deco_f_set
1850 return deco_set
1851
1856 """convenient way to import a plugin file/function"""
1857
1858 try:
1859 _temp = __import__('PLUGIN.%s' % module, globals(), locals(), fcts, -1)
1860 except ImportError:
1861 try:
1862 _temp = __import__('MG5aMC_PLUGIN.%s' % module, globals(), locals(), fcts, -1)
1863 except ImportError:
1864 raise MadGraph5Error, error_msg
1865
1866 if not fcts:
1867 return _temp
1868 elif len(fcts) == 1:
1869 return getattr(_temp,fcts[0])
1870 else:
1871 return [getattr(_temp,name) for name in fcts]
1872
1873 -def from_plugin_import(plugin_path, target_type, keyname=None, warning=False,
1874 info=None):
1875 """return the class associated with keyname for a given plugin class
1876 if keyname is None, return all the name associated"""
1877
1878 validname = []
1879 for plugpath in plugin_path:
1880 plugindirname = os.path.basename(plugpath)
1881 for plug in os.listdir(plugpath):
1882 if os.path.exists(pjoin(plugpath, plug, '__init__.py')):
1883 try:
1884 with stdchannel_redirected(sys.stdout, os.devnull):
1885 __import__('%s.%s' % (plugindirname,plug))
1886 except Exception, error:
1887 if warning:
1888 logger.warning("error detected in plugin: %s.", plug)
1889 logger.warning("%s", error)
1890 continue
1891 plugin = sys.modules['%s.%s' % (plugindirname,plug)]
1892 if hasattr(plugin, target_type):
1893 if not is_plugin_supported(plugin):
1894 continue
1895 if keyname is None:
1896 validname += getattr(plugin, target_type).keys()
1897 else:
1898 if keyname in getattr(plugin, target_type):
1899 if not info:
1900 logger.info('Using from plugin %s mode %s' % (plug, keyname), '$MG:color:BLACK')
1901 else:
1902 logger.info(info % {'plug': plug, 'key':keyname}, '$MG:color:BLACK')
1903 return getattr(plugin, target_type)[keyname]
1904
1905 if not keyname:
1906 return validname
1907
1908
1909
1910
1911 python_lhapdf=None
1913 """load the python module of lhapdf return None if it can not be loaded"""
1914
1915
1916 global python_lhapdf
1917 if python_lhapdf:
1918 if python_lhapdf == -1:
1919 return None
1920 else:
1921 return python_lhapdf
1922
1923 use_lhapdf=False
1924 try:
1925 lhapdf_libdir=subprocess.Popen([lhapdfconfig,'--libdir'],\
1926 stdout=subprocess.PIPE).stdout.read().strip()
1927 except:
1928 use_lhapdf=False
1929 return False
1930 else:
1931 try:
1932 candidates=[dirname for dirname in os.listdir(lhapdf_libdir) \
1933 if os.path.isdir(os.path.join(lhapdf_libdir,dirname))]
1934 except OSError:
1935 candidates=[]
1936 for candidate in candidates:
1937 if os.path.isfile(os.path.join(lhapdf_libdir,candidate,'site-packages','lhapdf.so')):
1938 sys.path.insert(0,os.path.join(lhapdf_libdir,candidate,'site-packages'))
1939 try:
1940 import lhapdf
1941 use_lhapdf=True
1942 break
1943 except ImportError:
1944 sys.path.pop(0)
1945 continue
1946 if not use_lhapdf:
1947 try:
1948 candidates=[dirname for dirname in os.listdir(lhapdf_libdir+'64') \
1949 if os.path.isdir(os.path.join(lhapdf_libdir+'64',dirname))]
1950 except OSError:
1951 candidates=[]
1952 for candidate in candidates:
1953 if os.path.isfile(os.path.join(lhapdf_libdir+'64',candidate,'site-packages','lhapdf.so')):
1954 sys.path.insert(0,os.path.join(lhapdf_libdir+'64',candidate,'site-packages'))
1955 try:
1956 import lhapdf
1957 use_lhapdf=True
1958 break
1959 except ImportError:
1960 sys.path.pop(0)
1961 continue
1962 if not use_lhapdf:
1963 try:
1964 import lhapdf
1965 use_lhapdf=True
1966 except ImportError:
1967 print 'fail'
1968 logger.warning("Failed to access python version of LHAPDF: "\
1969 "If the python interface to LHAPDF is available on your system, try "\
1970 "adding its location to the PYTHONPATH environment variable and the"\
1971 "LHAPDF library location to LD_LIBRARY_PATH (linux) or DYLD_LIBRARY_PATH (mac os x).")
1972
1973 if use_lhapdf:
1974 python_lhapdf = lhapdf
1975 python_lhapdf.setVerbosity(0)
1976 else:
1977 python_lhapdf = None
1978 return python_lhapdf
1979
1981 """implement newton method for solving f(x)=0, df is the derivate"""
1982 x = x0
1983 iter=0
1984 while abs(f(x)) > error:
1985 iter+=1
1986 x = x - f(x)/df(x)
1987 if iter ==maxiter:
1988 sprint('fail to solve equation')
1989 raise Exception
1990 return x
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017