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
579 """Check whether pid exists in the current process table.
580 UNIX only.
581 https://stackoverflow.com/questions/568271/how-to-check-if-there-exists-a-process-with-a-given-pid-in-python
582 """
583 import errno
584
585 if pid < 0:
586 return False
587 if pid == 0:
588
589
590
591
592 raise ValueError('invalid PID 0')
593 try:
594 os.kill(pid, 0)
595 except OSError as err:
596 if err.errno == errno.ESRCH:
597
598 return False
599 elif err.errno == errno.EPERM:
600
601 return True
602 else:
603
604
605 raise
606 else:
607 return True
608
613 """mute_logger (designed to work as with statement),
614 files allow to redirect the output of the log to a given file.
615 """
616
617 - def __init__(self, names, levels, files=None, **opt):
618 assert isinstance(names, list)
619 assert isinstance(names, list)
620
621 self.names = names
622 self.levels = levels
623 if isinstance(files, list):
624 self.files = files
625 else:
626 self.files = [files] * len(names)
627 self.logger_saved_info = {}
628 self.opts = opt
629
640
641 - def __exit__(self, ctype, value, traceback ):
652
654 """ Setup the logger by redirecting them all to logfiles in tmp """
655
656 logs = full_logname.split('.')
657 lognames = [ '.'.join(logs[:(len(logs)-i)]) for i in\
658 range(len(full_logname.split('.')))]
659 for logname in lognames:
660 try:
661 os.remove(path)
662 except Exception, error:
663 pass
664 my_logger = logging.getLogger(logname)
665 hdlr = logging.FileHandler(path)
666
667
668 self.logger_saved_info[logname] = [hdlr, my_logger.handlers]
669
670
671 for old_hdlr in list(my_logger.handlers):
672 my_logger.removeHandler(old_hdlr)
673 my_logger.addHandler(hdlr)
674
675 my_logger.debug('Log of %s' % logname)
676
678 """ Setup the logger by redirecting them all to logfiles in tmp """
679
680 logs = full_logname.split('.')
681 lognames = [ '.'.join(logs[:(len(logs)-i)]) for i in\
682 range(len(full_logname.split('.')))]
683 for logname in lognames:
684 if path:
685 try:
686 os.remove(path)
687 except Exception, error:
688 pass
689 my_logger = logging.getLogger(logname)
690 if logname in self.logger_saved_info:
691 my_logger.removeHandler(self.logger_saved_info[logname][0])
692 for old_hdlr in self.logger_saved_info[logname][1]:
693 my_logger.addHandler(old_hdlr)
694 else:
695 my_logger.setLevel(level)
696
697
698
699
700 nb_open =0
703 """
704 A context manager to temporarily redirect stdout or stderr
705
706 e.g.:
707
708
709 with stdchannel_redirected(sys.stderr, os.devnull):
710 if compiler.has_function('clock_gettime', libraries=['rt']):
711 libraries.append('rt')
712 """
713
714 try:
715 oldstdchannel = os.dup(stdchannel.fileno())
716 dest_file = open(dest_filename, 'w')
717 os.dup2(dest_file.fileno(), stdchannel.fileno())
718 yield
719 finally:
720 if oldstdchannel is not None:
721 os.dup2(oldstdchannel, stdchannel.fileno())
722 os.close(oldstdchannel)
723 if dest_file is not None:
724 dest_file.close()
725
727 '''
728 return the number of open file descriptors for current process
729
730 .. warning: will only work on UNIX-like os-es.
731 '''
732 import subprocess
733 import os
734
735 pid = os.getpid()
736 procs = subprocess.check_output(
737 [ "lsof", '-w', '-Ff', "-p", str( pid ) ] )
738 nprocs = filter(
739 lambda s: s and s[ 0 ] == 'f' and s[1: ].isdigit(),
740 procs.split( '\n' ) )
741
742 return nprocs
743
745 """ Detects whether the specified C++ compiler is clang."""
746
747 try:
748 p = Popen([cpp_compiler, '--version'], stdout=subprocess.PIPE,
749 stderr=subprocess.PIPE)
750 output, error = p.communicate()
751 except Exception, error:
752
753 return False
754 return 'LLVM' in output
755
757 """ Detects if the specified c++ compiler will normally link against the C++
758 standard library -lc++ or -libstdc++."""
759
760 is_clang = detect_if_cpp_compiler_is_clang(cpp_compiler)
761 if is_clang:
762 try:
763 import platform
764 v, _,_ = platform.mac_ver()
765 if not v:
766
767
768 return '-lc++'
769 else:
770 v = float(v.rsplit('.')[1])
771 if v >= 9:
772 return '-lc++'
773 else:
774 return '-lstdc++'
775 except:
776 return '-lstdc++'
777 return '-lstdc++'
778
780 """find the current compiler for the current directory"""
781
782
783
784 if compiler_type == 'fortran':
785 comp = re.compile("^\s*FC\s*=\s*([\w\/\\.\-]+)\s*")
786 elif compiler_type == 'cpp':
787 comp = re.compile("^\s*CXX\s*=\s*([\w\/\\.\-]+)\s*")
788 else:
789 MadGraph5Error, 'Unknown compiler type: %s' % compiler_type
790
791 for line in open(path):
792 if comp.search(line):
793 compiler = comp.search(line).groups()[0]
794 return compiler
795 elif compiler_type == 'fortran' and line.startswith('DEFAULT_F_COMPILER'):
796 return line.split('=')[1].strip()
797 elif compiler_type == 'cpp' and line.startswith('DEFAULT_CPP_COMPILER'):
798 return line.split('=')[1].strip()
799
801 """ return a list of all file starting with makefile in the given directory"""
802
803 out=[]
804
805 if type(directory)==list:
806 for name in directory:
807 out+=find_makefile_in_dir(name)
808 return out
809
810
811 for name in os.listdir(directory):
812 if os.path.isdir(directory+'/'+name):
813 out+=find_makefile_in_dir(directory+'/'+name)
814 elif os.path.isfile(directory+'/'+name) and name.lower().startswith('makefile'):
815 out.append(directory+'/'+name)
816 elif os.path.isfile(directory+'/'+name) and name.lower().startswith('make_opt'):
817 out.append(directory+'/'+name)
818 return out
819
821
822
823 os.path.walk('.', rm_file_extension, '.o')
824
825
826 libraries = ['libblocks.a', 'libgeneric_mw.a', 'libMWPS.a', 'libtools.a', 'libdhelas3.a',
827 'libdsample.a', 'libgeneric.a', 'libmodel.a', 'libpdf.a', 'libdhelas3.so', 'libTF.a',
828 'libdsample.so', 'libgeneric.so', 'libmodel.so', 'libpdf.so']
829 lib_pos='./lib'
830 [os.remove(os.path.join(lib_pos, lib)) for lib in libraries \
831 if os.path.exists(os.path.join(lib_pos, lib))]
832
846
850
854 replace_dict = dict(key_values)
855 replacement_function = lambda match: replace_dict[match.group(0)]
856 pattern = re.compile("|".join([re.escape(k) for k, v in key_values]), re.M)
857 return lambda string: pattern.sub(replacement_function, string)
858
861
864 def deco_check(f):
865 def deco_f(arg, *args, **opt):
866 try:
867 return f(arg, *args, **opt)
868 except OSError, error:
869 logger.debug('try to recover from %s' % error)
870 if isinstance(arg, list):
871 prog = arg[0]
872 else:
873 prog = arg[0]
874
875
876 if error.errno == 13:
877 if os.path.exists(prog):
878 os.system('chmod +x %s' % prog)
879 elif 'cwd' in opt and opt['cwd'] and \
880 os.path.isfile(pjoin(opt['cwd'],arg[0])):
881 os.system('chmod +x %s' % pjoin(opt['cwd'],arg[0]))
882 return f(arg, *args, **opt)
883
884 elif error.errno == 2:
885
886 raise Exception, '%s fails with no such file or directory' \
887 % arg
888 else:
889 raise
890 return deco_f
891 return deco_check
892
893
894 @check_system_error()
895 -def call(arg, *args, **opt):
896 """nice way to call an external program with nice error treatment"""
897 try:
898 return subprocess.call(arg, *args, **opt)
899 except OSError:
900 arg[0] = './%s' % arg[0]
901 return subprocess.call(arg, *args, **opt)
902
903 @check_system_error()
904 -def Popen(arg, *args, **opt):
905 """nice way to call an external program with nice error treatment"""
906 return subprocess.Popen(arg, *args, **opt)
907
908 @check_system_error()
909 -def call_stdout(arg, *args, **opt):
910 """nice way to call an external program with nice error treatment"""
911 try:
912 out = subprocess.Popen(arg, *args, stdout=subprocess.PIPE, **opt)
913 except OSError:
914 arg[0] = './%s' % arg[0]
915 out = subprocess.call(arg, *args, stdout=subprocess.PIPE, **opt)
916
917 str_out = out.stdout.read().strip()
918 return str_out
919
920
921 @multiple_try()
922 -def mult_try_open(filepath, *args, **opt):
923 """try to open a file with multiple try to ensure that filesystem is sync"""
924 return open(filepath, *args, ** opt)
925
926
927
928
929 -def tail(f, n, offset=None):
930 """Reads a n lines from f with an offset of offset lines. The return
931 value is a tuple in the form ``lines``.
932 """
933 avg_line_length = 74
934 to_read = n + (offset or 0)
935
936 while 1:
937 try:
938 f.seek(-(avg_line_length * to_read), 2)
939 except IOError:
940
941
942 f.seek(0)
943 pos = f.tell()
944 lines = f.read().splitlines()
945 if len(lines) >= to_read or pos == 0:
946 return lines[-to_read:offset and -offset or None]
947 avg_line_length *= 1.3
948 avg_line_length = int(avg_line_length)
949
951 """ makes a piping fifo (First-in First-out) file and nicely intercepts
952 error in case the file format of the target drive doesn't suppor tit."""
953
954 try:
955 os.mkfifo(fifo_path)
956 except:
957 raise OSError('MadGraph5_aMCatNLO could not create a fifo file at:\n'+
958 ' %s\n'%fifo_path+'Make sure that this file does not exist already'+
959 ' and that the file format of the target drive supports fifo file (i.e not NFS).')
960
965 """return the last line of a file"""
966
967 return tail(fsock, 1)[0]
968
970 """read a file returning the lines in reverse order for each call of readline()
971 This actually just reads blocks (4096 bytes by default) of data from the end of
972 the file and returns last line in an internal buffer."""
973
974
976 """ readline in a backward way """
977
978 while len(self.data) == 1 and ((self.blkcount * self.blksize) < self.size):
979 self.blkcount = self.blkcount + 1
980 line = self.data[0]
981 try:
982 self.seek(-self.blksize * self.blkcount, 2)
983 self.data = (self.read(self.blksize) + line).split('\n')
984 except IOError:
985 self.seek(0)
986 data = self.read(self.size - (self.blksize * (self.blkcount-1))) + line
987 self.data = data.split('\n')
988
989 if len(self.data) == 0:
990 return ""
991
992 line = self.data.pop()
993 return line + '\n'
994
995 - def __init__(self, filepos, blksize=4096):
996 """initialize the internal structures"""
997
998
999 self.size = os.stat(filepos)[6]
1000
1001 self.blksize = blksize
1002
1003 self.blkcount = 1
1004 file.__init__(self, filepos, 'rb')
1005
1006
1007 if self.size > self.blksize:
1008 self.seek(-self.blksize * self.blkcount, 2)
1009 self.data = self.read(self.blksize).split('\n')
1010
1011
1012 if not self.data[-1]:
1013 self.data.pop()
1014
1016 line = self.readline()
1017 if line:
1018 return line
1019 else:
1020 raise StopIteration
1021
1037
1051
1057 """create a temporary directory and ensure this one to be cleaned.
1058 """
1059
1060 - def __init__(self, suffix='', prefix='tmp', dir=None):
1061 self.nb_try_remove = 0
1062 import tempfile
1063 self.path = tempfile.mkdtemp(suffix, prefix, dir)
1064
1065
1066 - def __exit__(self, ctype, value, traceback ):
1067
1068 if False and isinstance(value, Exception):
1069 sprint("Directory %s not cleaned. This directory can be removed manually" % self.path)
1070 return False
1071 try:
1072 shutil.rmtree(self.path)
1073 except OSError:
1074 self.nb_try_remove += 1
1075 if self.nb_try_remove < 3:
1076 time.sleep(10)
1077 self.__exit__(ctype, value, traceback)
1078 else:
1079 logger.warning("Directory %s not completely cleaned. This directory can be removed manually" % self.path)
1080
1083
1085 """create a temporary directory and ensure this one to be cleaned.
1086 """
1087
1088 - def __init__(self, cls, attribute, value):
1089
1090 self.cls = cls
1091 self.attribute = attribute
1092 if isinstance(attribute, list):
1093 self.old_value = []
1094 for key, onevalue in zip(attribute, value):
1095 self.old_value.append(getattr(cls, key))
1096 setattr(self.cls, key, onevalue)
1097 else:
1098 self.old_value = getattr(cls, attribute)
1099 setattr(self.cls, self.attribute, value)
1100
1101 - def __exit__(self, ctype, value, traceback ):
1102
1103 if isinstance(self.attribute, list):
1104 for key, old_value in zip(self.attribute, self.old_value):
1105 setattr(self.cls, key, old_value)
1106 else:
1107 setattr(self.cls, self.attribute, self.old_value)
1108
1110 return self.old_value
1111
1112
1113
1114
1115 -def gunzip(path, keep=False, stdout=None):
1116 """ a standard replacement for os.system('gunzip -f %s.gz ' % event_path)"""
1117
1118 if not path.endswith(".gz"):
1119 if os.path.exists("%s.gz" % path):
1120 path = "%s.gz" % path
1121 else:
1122 raise Exception, "%(path)s does not finish by .gz and the file %(path)s.gz does not exists" %\
1123 {"path": path}
1124
1125
1126
1127 if os.path.getsize(path) > 1e8:
1128 if stdout:
1129 os.system('gunzip -c %s > %s' % (path, stdout))
1130 else:
1131 os.system('gunzip %s' % path)
1132 return 0
1133
1134 if not stdout:
1135 stdout = path[:-3]
1136 try:
1137 gfile = ziplib.open(path, "r")
1138 except IOError:
1139 raise
1140 else:
1141 try:
1142 open(stdout,'w').write(gfile.read())
1143 except IOError:
1144
1145 if stdout == path:
1146 return
1147 else:
1148 files.cp(path, stdout)
1149
1150 if not keep:
1151 os.remove(path)
1152 return 0
1153
1154 -def gzip(path, stdout=None, error=True, forceexternal=False):
1155 """ a standard replacement for os.system('gzip %s ' % path)"""
1156
1157
1158 if os.path.getsize(path) > 1e9 or forceexternal:
1159 call(['gzip', '-f', path])
1160 if stdout:
1161 if not stdout.endswith(".gz"):
1162 stdout = "%s.gz" % stdout
1163 shutil.move('%s.gz' % path, stdout)
1164 return
1165
1166 if not stdout:
1167 stdout = "%s.gz" % path
1168 elif not stdout.endswith(".gz"):
1169 stdout = "%s.gz" % stdout
1170
1171 try:
1172 ziplib.open(stdout,"w").write(open(path).read())
1173 except OverflowError:
1174 gzip(path, stdout, error=error, forceexternal=True)
1175 except Exception:
1176 if error:
1177 raise
1178 else:
1179 os.remove(path)
1180
1185 """ a convinient class to open a file """
1186
1187 web_browser = None
1188 eps_viewer = None
1189 text_editor = None
1190 configured = False
1191
1193 """open a file"""
1194
1195
1196 if not self.configured:
1197 self.configure()
1198
1199 try:
1200 extension = filename.rsplit('.',1)[1]
1201 except IndexError:
1202 extension = ''
1203
1204
1205
1206 if extension in ['html','htm','php']:
1207 self.open_program(self.web_browser, filename, background=True)
1208 elif extension in ['ps','eps']:
1209 self.open_program(self.eps_viewer, filename, background=True)
1210 else:
1211 self.open_program(self.text_editor,filename, mac_check=False)
1212
1213
1214 @classmethod
1237
1238 @classmethod
1276
1277
1278 @staticmethod
1280 """find a valid shell program in the list"""
1281
1282 for p in possibility:
1283 if which(p):
1284 logger.info('Using default %s \"%s\". ' % (program, p) + \
1285 'Set another one in ./input/mg5_configuration.txt')
1286 return p
1287
1288 logger.info('No valid %s found. ' % program + \
1289 'Please set in ./input/mg5_configuration.txt')
1290 return None
1291
1292
1293 - def open_program(self, program, file_path, mac_check=True, background=False):
1294 """ open a file with a given program """
1295
1296 if mac_check==True and sys.platform == 'darwin':
1297 return self.open_mac_program(program, file_path)
1298
1299
1300 if program:
1301 arguments = program.split()
1302 arguments.append(file_path)
1303
1304 if not background:
1305 subprocess.call(arguments)
1306 else:
1307 import thread
1308 thread.start_new_thread(subprocess.call,(arguments,))
1309 else:
1310 logger.warning('Not able to open file %s since no program configured.' % file_path + \
1311 'Please set one in ./input/mg5_configuration.txt')
1312
1314 """ open a text with the text editor """
1315
1316 if not program:
1317
1318 os.system('open %s' % file_path)
1319 elif which(program):
1320
1321 arguments = program.split()
1322 arguments.append(file_path)
1323 subprocess.call(arguments)
1324 else:
1325
1326 os.system('open -a %s %s' % (program, file_path))
1327
1347
1349 """ Try and guess what shell type does the user use."""
1350 try:
1351 if os.environ['SHELL'].endswith('bash'):
1352 return 'bash'
1353 elif os.environ['SHELL'].endswith('tcsh'):
1354 return 'tcsh'
1355 else:
1356
1357 return None
1358 except KeyError:
1359 return None
1360
1362 """ check if a path is executable"""
1363 try:
1364 return os.access(path, os.X_OK)
1365 except Exception:
1366 return False
1367
1369 """Option Peaser which raise an error instead as calling exit"""
1370
1371 - def exit(self, status=0, msg=None):
1376
1378 """Returns the current line number in our program."""
1379
1380 if not __debug__:
1381 return
1382
1383
1384 import inspect
1385 if opt.has_key('cond') and not opt['cond']:
1386 return
1387
1388 use_print = False
1389 if opt.has_key('use_print') and opt['use_print']:
1390 use_print = True
1391
1392 if opt.has_key('log'):
1393 log = opt['log']
1394 else:
1395 log = logging.getLogger('madgraph')
1396 if opt.has_key('level'):
1397 level = opt['level']
1398 else:
1399 level = logging.getLogger('madgraph').level
1400 if level == 0:
1401 use_print = True
1402
1403
1404
1405
1406 if opt.has_key('wait'):
1407 wait = bool(opt['wait'])
1408 else:
1409 wait = False
1410
1411 lineno = inspect.currentframe().f_back.f_lineno
1412 fargs = inspect.getframeinfo(inspect.currentframe().f_back)
1413 filename, lineno = fargs[:2]
1414
1415
1416 try:
1417 source = inspect.getsourcelines(inspect.currentframe().f_back)
1418 line = source[0][lineno-source[1]]
1419 line = re.findall(r"misc\.sprint\(\s*(.*)\)\s*($|#)", line)[0][0]
1420 if line.startswith("'") and line.endswith("'") and line.count(",") ==0:
1421 line= ''
1422 elif line.startswith("\"") and line.endswith("\"") and line.count(",") ==0:
1423 line= ''
1424 elif line.startswith(("\"","'")) and len(args)==1 and "%" in line:
1425 line= ''
1426 except Exception:
1427 line=''
1428
1429 if line:
1430 intro = ' %s = \033[0m' % line
1431 else:
1432 intro = ''
1433
1434
1435 if not use_print:
1436 log.log(level, ' '.join([intro]+[str(a) for a in args]) + \
1437 ' \033[1;30m[%s at line %s]\033[0m' % (os.path.basename(filename), lineno))
1438 else:
1439 print ' '.join([intro]+[str(a) for a in args]) + \
1440 ' \033[1;30m[%s at line %s]\033[0m' % (os.path.basename(filename), lineno)
1441
1442 if wait:
1443 raw_input('press_enter to continue')
1444 elif opt.has_key('sleep'):
1445 time.sleep(int(opt['sleep']))
1446
1447 return
1448
1449
1450
1451
1452 -def equal(a,b,sig_fig=6, zero_limit=True):
1453 """function to check if two float are approximatively equal"""
1454 import math
1455
1456 if isinstance(sig_fig, int):
1457 if not a or not b:
1458 if zero_limit:
1459 if zero_limit is not True:
1460 power = zero_limit
1461 else:
1462 power = sig_fig + 1
1463 else:
1464 return a == b
1465 else:
1466 power = sig_fig - int(math.log10(abs(a))) + 1
1467
1468 return ( a==b or abs(int(a*10**power) - int(b*10**power)) < 10)
1469 else:
1470 return abs(a-b) < sig_fig
1471
1472
1473
1474
1475
1476
1477
1478 -class chdir:
1480 self.newPath = newPath
1481
1483 self.savedPath = os.getcwd()
1484 os.chdir(self.newPath)
1485
1486 - def __exit__(self, etype, value, traceback):
1487 os.chdir(self.savedPath)
1488
1489
1490
1491
1492
1493 -def timeout(func, args=(), kwargs={}, timeout_duration=1, default=None):
1494 '''This function will spwan a thread and run the given function using the args, kwargs and
1495 return the given default value if the timeout_duration is exceeded
1496 '''
1497 import threading
1498 class InterruptableThread(threading.Thread):
1499 def __init__(self):
1500 threading.Thread.__init__(self)
1501 self.result = default
1502 def run(self):
1503 try:
1504 self.result = func(*args, **kwargs)
1505 except Exception,error:
1506 print error
1507 self.result = default
1508 it = InterruptableThread()
1509 it.start()
1510 it.join(timeout_duration)
1511 return it.result
1512
1513
1514
1515
1516
1517 -class digest:
1518
1520 try:
1521 return self.test_hashlib()
1522 except Exception:
1523 pass
1524 try:
1525 return self.test_md5()
1526 except Exception:
1527 pass
1528 try:
1529 return self.test_zlib()
1530 except Exception:
1531 pass
1532
1534 import hashlib
1535 def digest(text):
1536 """using mg5 for the hash"""
1537 t = hashlib.md5()
1538 t.update(text)
1539 return t.hexdigest()
1540 return digest
1541
1543 import md5
1544 def digest(text):
1545 """using mg5 for the hash"""
1546 t = md5.md5()
1547 t.update(text)
1548 return t.hexdigest()
1549 return digest
1550
1552 import zlib
1553 def digest(text):
1554 return zlib.adler32(text)
1555
1556 digest = digest().test_all()
1563 self.cmd_args = args
1564 self.cmd_opts = opts
1565 self.execution_state = False
1566
1568 self.max_vms_memory = 0
1569 self.max_rss_memory = 0
1570
1571 self.t1 = None
1572 self.t0 = time.time()
1573 self.p = subprocess.Popen(*self.cmd_args,**self.cmd_opts)
1574 self.execution_state = True
1575
1577 if not self.check_execution_state():
1578 return False
1579
1580 self.t1 = time.time()
1581
1582
1583
1584 flash = subprocess.Popen("ps -p %i -o rss"%self.p.pid,
1585 shell=True,stdout=subprocess.PIPE,stderr=open(os.devnull,"w"))
1586 stdout_list = flash.communicate()[0].split('\n')
1587 rss_memory = int(stdout_list[1])
1588
1589 vms_memory = 0
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618 self.max_vms_memory = max(self.max_vms_memory,vms_memory)
1619 self.max_rss_memory = max(self.max_rss_memory,rss_memory)
1620
1621 return self.check_execution_state()
1622
1624
1625
1626 return self.p.poll() == None
1627
1629 if not self.execution_state:
1630 return False
1631 if self.is_running():
1632 return True
1633 self.executation_state = False
1634 self.t1 = time.time()
1635 return False
1636
1637 - def close(self,kill=False):
1638
1639 if self.p.poll() == None:
1640 if kill:
1641 self.p.kill()
1642 else:
1643 self.p.terminate()
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656 -class Applenotification(object):
1657
1659 self.init = False
1660 self.working = True
1661
1663 try:
1664 import Foundation
1665 import objc
1666 self.NSUserNotification = objc.lookUpClass('NSUserNotification')
1667 self.NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
1668 except:
1669 self.working=False
1670 self.working=True
1671
1672 - def __call__(self,subtitle, info_text, userInfo={}):
1673
1674 if not self.init:
1675 self.load_notification()
1676 if not self.working:
1677 return
1678 try:
1679 notification = self.NSUserNotification.alloc().init()
1680 notification.setTitle_('MadGraph5_aMC@NLO')
1681 notification.setSubtitle_(subtitle)
1682 notification.setInformativeText_(info_text)
1683 try:
1684 notification.setUserInfo_(userInfo)
1685 except:
1686 pass
1687 self.NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)
1688 except:
1689 pass
1690
1691
1692
1693 apple_notify = Applenotification()
1696
1697 done_notification = False
1698 message_aprilfirst =\
1699 {'error': ['Be careful, a cat is eating a lot of fish today. This makes the code unstable.',
1700 'Really, this sounds fishy.',
1701 '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?"',
1702 "Why does Heisenberg detest driving cars? Because, every time he looks at the speedometer he gets lost!",
1703 "May the mass times acceleration be with you.",
1704 "NOTE: This product may actually be nine-dimensional. If this is the case, functionality is not affected by the extra five dimensions.",
1705 "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.",
1706 'The fish are out of jokes. See you next year for more!'],
1707 'loading': ['Hi %(user)s, You are Loading Madgraph. Please be patient, we are doing the work.'],
1708 'quit': ['Thanks %(user)s for using MadGraph5_aMC@NLO, even on April 1st!']
1709 }
1710
1712
1713 try:
1714 now = time.localtime()
1715 date = now.tm_mday, now.tm_mon
1716 if date in [(1,4)]:
1717 if msgtype in EasterEgg.message_aprilfirst:
1718 choices = EasterEgg.message_aprilfirst[msgtype]
1719 if len(choices) == 0:
1720 return
1721 elif len(choices) == 1:
1722 msg = choices[0]
1723 else:
1724 import random
1725 msg = choices[random.randint(0,len(choices)-2)]
1726 EasterEgg.message_aprilfirst[msgtype].remove(msg)
1727
1728 else:
1729 return
1730 if MADEVENT:
1731 return
1732
1733 import os
1734 import pwd
1735 username =pwd.getpwuid( os.getuid() )[ 0 ]
1736 msg = msg % {'user': username}
1737 if sys.platform == "darwin":
1738 self.call_apple(msg)
1739 else:
1740 self.call_linux(msg)
1741 except Exception, error:
1742 sprint(error)
1743 pass
1744
1746 try:
1747 self.call_apple(msg)
1748 except:
1749 pass
1750
1752
1753
1754 p = subprocess.Popen("osascript -e 'get volume settings'", stdout=subprocess.PIPE, shell=True)
1755 output, _ = p.communicate()
1756
1757 info = dict([[a.strip() for a in l.split(':',1)] for l in output.strip().split(',')])
1758 muted = False
1759 if 'output muted' in info and info['output muted'] == 'true':
1760 muted = True
1761 elif 'output volume' in info and info['output volume'] == '0':
1762 muted = True
1763
1764 if muted:
1765 if not EasterEgg.done_notification:
1766 apple_notify('On April first','turn up your volume!')
1767 EasterEgg.done_notification = True
1768 else:
1769 os.system('say %s' % msg)
1770
1771
1773
1774 fishPath = madgraph.MG5DIR+"/input/.cowgraph.cow"
1775 if os.path.exists(fishPath):
1776 fishPath = " -f " + fishPath
1777
1778
1779
1780 fishPole = which('cowthink')
1781 if not os.path.exists(fishPole):
1782 if os.path.exists(which('cowsay')):
1783 fishPole = which('cowsay')
1784 else:
1785 return
1786
1787
1788 fishCmd = fishPole + fishPath + " " + msg
1789 os.system(fishCmd)
1790
1791
1792 if __debug__:
1793 try:
1794 import os
1795 import pwd
1796 username =pwd.getpwuid( os.getuid() )[ 0 ]
1797 if 'hirschi' in username or 'vryonidou' in username and __debug__:
1798 EasterEgg('loading')
1799 except:
1800 pass
1804 """ return v2 if v1>v2
1805 return v1 if v1<v2
1806 return v1 if v1=v2
1807 return v1 if v2 is not in 1.2.3.4.5 format
1808 return v2 if v1 is not in 1.2.3.4.5 format
1809 """
1810 from itertools import izip_longest
1811 for a1, a2 in izip_longest(v1, v2, fillvalue=0):
1812 try:
1813 a1= int(a1)
1814 except:
1815 return v2
1816 try:
1817 a2= int(a2)
1818 except:
1819 return v1
1820 if a1 > a2:
1821 return v2
1822 elif a1 < a2:
1823 return v1
1824 return v1
1825
1826
1827
1828 plugin_support = {}
1866
1867
1868
1869 -def set_global(loop=False, unitary=True, mp=False, cms=False):
1899 return deco_f_set
1900 return deco_set
1901
1906 """convenient way to import a plugin file/function"""
1907
1908 try:
1909 _temp = __import__('PLUGIN.%s' % module, globals(), locals(), fcts, -1)
1910 except ImportError:
1911 try:
1912 _temp = __import__('MG5aMC_PLUGIN.%s' % module, globals(), locals(), fcts, -1)
1913 except ImportError:
1914 raise MadGraph5Error, error_msg
1915
1916 if not fcts:
1917 return _temp
1918 elif len(fcts) == 1:
1919 return getattr(_temp,fcts[0])
1920 else:
1921 return [getattr(_temp,name) for name in fcts]
1922
1923 -def from_plugin_import(plugin_path, target_type, keyname=None, warning=False,
1924 info=None):
1925 """return the class associated with keyname for a given plugin class
1926 if keyname is None, return all the name associated"""
1927
1928 validname = []
1929 for plugpath in plugin_path:
1930 plugindirname = os.path.basename(plugpath)
1931 for plug in os.listdir(plugpath):
1932 if os.path.exists(pjoin(plugpath, plug, '__init__.py')):
1933 try:
1934 with stdchannel_redirected(sys.stdout, os.devnull):
1935 __import__('%s.%s' % (plugindirname,plug))
1936 except Exception, error:
1937 if warning:
1938 logger.warning("error detected in plugin: %s.", plug)
1939 logger.warning("%s", error)
1940 continue
1941 plugin = sys.modules['%s.%s' % (plugindirname,plug)]
1942 if hasattr(plugin, target_type):
1943 if not is_plugin_supported(plugin):
1944 continue
1945 if keyname is None:
1946 validname += getattr(plugin, target_type).keys()
1947 else:
1948 if keyname in getattr(plugin, target_type):
1949 if not info:
1950 logger.info('Using from plugin %s mode %s' % (plug, keyname), '$MG:BOLD')
1951 else:
1952 logger.info(info % {'plug': plug, 'key':keyname}, '$MG:BOLD')
1953 return getattr(plugin, target_type)[keyname]
1954
1955 if not keyname:
1956 return validname
1957
1958
1959
1960
1961 python_lhapdf=None
1963 """load the python module of lhapdf return None if it can not be loaded"""
1964
1965
1966 global python_lhapdf
1967 if python_lhapdf:
1968 if python_lhapdf == -1:
1969 return None
1970 else:
1971 return python_lhapdf
1972
1973 use_lhapdf=False
1974 try:
1975 lhapdf_libdir=subprocess.Popen([lhapdfconfig,'--libdir'],\
1976 stdout=subprocess.PIPE).stdout.read().strip()
1977 except:
1978 use_lhapdf=False
1979 return False
1980 else:
1981 try:
1982 candidates=[dirname for dirname in os.listdir(lhapdf_libdir) \
1983 if os.path.isdir(os.path.join(lhapdf_libdir,dirname))]
1984 except OSError:
1985 candidates=[]
1986 for candidate in candidates:
1987 if os.path.isfile(os.path.join(lhapdf_libdir,candidate,'site-packages','lhapdf.so')):
1988 sys.path.insert(0,os.path.join(lhapdf_libdir,candidate,'site-packages'))
1989 try:
1990 import lhapdf
1991 use_lhapdf=True
1992 break
1993 except ImportError:
1994 sys.path.pop(0)
1995 continue
1996 if not use_lhapdf:
1997 try:
1998 candidates=[dirname for dirname in os.listdir(lhapdf_libdir+'64') \
1999 if os.path.isdir(os.path.join(lhapdf_libdir+'64',dirname))]
2000 except OSError:
2001 candidates=[]
2002 for candidate in candidates:
2003 if os.path.isfile(os.path.join(lhapdf_libdir+'64',candidate,'site-packages','lhapdf.so')):
2004 sys.path.insert(0,os.path.join(lhapdf_libdir+'64',candidate,'site-packages'))
2005 try:
2006 import lhapdf
2007 use_lhapdf=True
2008 break
2009 except ImportError:
2010 sys.path.pop(0)
2011 continue
2012 if not use_lhapdf:
2013 try:
2014 import lhapdf
2015 use_lhapdf=True
2016 except ImportError:
2017 print 'fail'
2018 logger.warning("Failed to access python version of LHAPDF: "\
2019 "If the python interface to LHAPDF is available on your system, try "\
2020 "adding its location to the PYTHONPATH environment variable and the"\
2021 "LHAPDF library location to LD_LIBRARY_PATH (linux) or DYLD_LIBRARY_PATH (mac os x).")
2022
2023 if use_lhapdf:
2024 python_lhapdf = lhapdf
2025 python_lhapdf.setVerbosity(0)
2026 else:
2027 python_lhapdf = None
2028 return python_lhapdf
2029
2031 """implement newton method for solving f(x)=0, df is the derivate"""
2032 x = x0
2033 iter=0
2034 while abs(f(x)) > error:
2035 iter+=1
2036 x = x - f(x)/df(x)
2037 if iter ==maxiter:
2038 sprint('fail to solve equation')
2039 raise Exception
2040 return x
2041
2042 -def wget(http, path, *args, **opt):
2043 """a wget function for both unix and mac"""
2044
2045 if sys.platform == "darwin":
2046 return call(['curl', '-L', http, '-o%s' % path], *args, **opt)
2047 else:
2048 return call(['wget', http, '--output-document=%s'% path], *args, **opt)
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073