Package mvpa :: Package base :: Module externals
[hide private]
[frames] | no frames]

Source Code for Module mvpa.base.externals

  1  #emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*- 
  2  #ex: set sts=4 ts=4 sw=4 et: 
  3  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 
  4  # 
  5  #   See COPYING file distributed along with the PyMVPA package for the 
  6  #   copyright and license terms. 
  7  # 
  8  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 
  9  """Helper to verify presence of external libraries and modules 
 10  """ 
 11   
 12  __docformat__ = 'restructuredtext' 
 13  import os 
 14   
 15  from mvpa.base import warning 
 16  from mvpa import cfg 
 17   
 18  if __debug__: 
 19      from mvpa.base import debug 
 20   
 21   
22 -def __check_pywt(features=None):
23 """Check for available functionality within pywt 24 25 :Parameters: 26 features : list of basestring 27 List of known features to check such as 'wp reconstruct', 28 'wp reconstruct fixed' 29 """ 30 import pywt 31 import numpy as N 32 data = N.array([ 0.57316901, 0.65292526, 0.75266733, 0.67020084, 0.46505364, 33 0.76478331, 0.33034164, 0.49165547, 0.32979941, 0.09696717, 34 0.72552711, 0.4138999 , 0.54460628, 0.786351 , 0.50096306, 35 0.72436454, 0.2193098 , -0.0135051 , 0.34283984, 0.65596245, 36 0.49598417, 0.39935064, 0.26370727, 0.05572373, 0.40194438, 37 0.47004551, 0.60327258, 0.25628266, 0.32964893, 0.24009889,]) 38 mode = 'per' 39 wp = pywt.WaveletPacket(data, 'sym2', mode) 40 wp2 = pywt.WaveletPacket(data=None, wavelet='sym2', mode=mode) 41 try: 42 for node in wp.get_level(2): wp2[node.path] = node.data 43 except: 44 raise ImportError, \ 45 "Failed to reconstruct WP by specifying data in the layer" 46 47 if 'wp reconstruct fixed' in features: 48 rec = wp2.reconstruct() 49 if N.linalg.norm(rec[:len(data)] - data) > 1e-3: 50 raise ImportError, \ 51 "Failed to reconstruct WP correctly" 52 return True
53 54
55 -def __check_libsvm_verbosity_control():
56 """Check for available verbose control functionality 57 """ 58 import mvpa.clfs.libsvmc._svmc as _svmc 59 try: 60 _svmc.svm_set_verbosity(0) 61 except: 62 raise ImportError, "Provided version of libsvm has no way to control " \ 63 "its level of verbosity"
64
65 -def __check_shogun(bottom_version, custom_versions=[]):
66 """Check if version of shogun is high enough (or custom known) to 67 be enabled in the testsuite 68 69 :Parameters: 70 bottom_version : int 71 Bottom version which must be satisfied 72 custom_versions : list of int 73 Arbitrary list of versions which could got patched for 74 a specific issue 75 """ 76 import shogun.Classifier as __sc 77 ver = __sc.Version_get_version_revision() 78 if (ver in custom_versions) or (ver >= bottom_version): 79 return True 80 else: 81 raise ImportError, 'Version %s is smaller than needed %s' % \ 82 (ver, bottom_version)
83 84
85 -def __check_weave():
86 """Apparently presence of scipy is not sufficient since some 87 versions experience problems. E.g. in Sep,Oct 2008 lenny's weave 88 failed to work. May be some other converter could work (? See 89 http://lists.debian.org/debian-devel/2008/08/msg00730.html for a 90 similar report. 91 92 Following simple snippet checks compilation of the basic code using 93 weave 94 """ 95 from scipy import weave 96 from scipy.weave import converters, build_tools 97 import numpy as N 98 # to shut weave up 99 import sys 100 # we can't rely on weave at all at the restoring argv. On etch box 101 # restore_sys_argv() is apparently is insufficient 102 oargv = sys.argv[:] 103 ostdout = sys.stdout 104 if not( __debug__ and 'EXT_' in debug.active): 105 from StringIO import StringIO 106 sys.stdout = StringIO() 107 # *nix specific solution to shut weave up. 108 # Some users must complain and someone 109 # needs to fix this to become more generic. 110 cargs = [">/dev/null", "2>&1"] 111 else: 112 cargs = [] 113 fmsg = None 114 try: 115 data = N.array([1,2,3]) 116 counter = weave.inline("data[0]=fabs(-1);", ['data'], 117 type_converters=converters.blitz, 118 verbose=0, 119 extra_compile_args=cargs, 120 compiler = 'gcc') 121 except Exception, e: 122 fmsg = "Failed to build simple weave sample." \ 123 " Exception was %s" % str(e) 124 125 sys.stdout = ostdout 126 # needed to fix sweave which might "forget" to restore sysv 127 # build_tools.restore_sys_argv() 128 sys.argv = oargv 129 if fmsg is not None: 130 raise ImportError, fmsg 131 else: 132 return "Everything is cool"
133 134
135 -def __check_atlas_family(family):
136 # XXX I guess pylint will dislike it a lot 137 from mvpa.atlases.warehouse import KNOWN_ATLAS_FAMILIES 138 names, pathpattern = KNOWN_ATLAS_FAMILIES[family] 139 filename = pathpattern % {'name':names[0]} 140 if not os.path.exists(filename): 141 raise ImportError, "Cannot find file %s for atlas family %s" \ 142 % (filename, family) 143 pass
144 145
146 -def __check_stablerdist():
147 import scipy.stats 148 # ATM all known implementations which implement custom cdf for 149 # rdist are misbehaving, so there should be no _cdf 150 if '_cdf' in scipy.stats.distributions.rdist_gen.__dict__.keys(): 151 raise ImportError, "scipy.stats carries misbehaving rdist distribution" 152 pass
153 154
155 -def __check_in_ipython():
156 # figure out if ran within IPython 157 if '__IPYTHON__' in globals()['__builtins__']: 158 return 159 raise RuntimeError, "Not running in IPython session"
160 161
162 -def __check_matplotlib():
163 """Check for presence of matplotlib and set backend if requested.""" 164 import matplotlib 165 backend = cfg.get('matplotlib', 'backend') 166 if backend: 167 matplotlib.use(backend)
168
169 -def __check_pylab():
170 """Check if matplotlib is there and then pylab""" 171 exists('matplotlib', raiseException=True) 172 import pylab as P
173
174 -def __check_pylab_plottable():
175 """Simple check either we can plot anything using pylab. 176 177 Primary use in unittests 178 """ 179 try: 180 exists('pylab', raiseException=True) 181 import pylab as P 182 fig = P.figure() 183 P.plot([1,2], [1,2]) 184 P.close(fig) 185 except: 186 raise RuntimeError, "Cannot plot in pylab" 187 return True
188 189 190 # contains list of available (optional) external classifier extensions 191 _KNOWN = {'libsvm':'import mvpa.clfs.libsvmc._svm as __; x=__.convert2SVMNode', 192 'libsvm verbosity control':'__check_libsvm_verbosity_control();', 193 'nifti':'from nifti import NiftiImage as __', 194 'nifti >= 0.20090205.1': 195 'from nifti.clib import detachDataFromImage as __', 196 'ctypes':'import ctypes as __', 197 'shogun':'import shogun as __', 198 'shogun.mpd': 'import shogun.Classifier as __; x=__.MPDSVM', 199 'shogun.lightsvm': 'import shogun.Classifier as __; x=__.SVMLight', 200 'shogun.svrlight': 'from shogun.Regression import SVRLight as __', 201 'scipy': "import scipy as __", 202 'good scipy.stats.rdist': "__check_stablerdist()", 203 'weave': "__check_weave()", 204 'pywt': "import pywt as __", 205 'pywt wp reconstruct': "__check_pywt(['wp reconstruct'])", 206 'pywt wp reconstruct fixed': "__check_pywt(['wp reconstruct fixed'])", 207 'rpy': "import rpy as __", 208 'lars': "import rpy; rpy.r.library('lars')", 209 'matplotlib': "__check_matplotlib()", 210 'pylab': "__check_pylab()", 211 'pylab plottable': "__check_pylab_plottable()", 212 'openopt': "import scikits.openopt as __", 213 'mdp': "import mdp as __", 214 'sg_fixedcachesize': "__check_shogun(3043, [2456])", 215 # 3318 corresponds to release 0.6.4 216 'sg >= 0.6.4': "__check_shogun(3318)", 217 'hcluster': "import hcluster as __", 218 'griddata': "import griddata as __", 219 'cPickle': "import cPickle as __", 220 'gzip': "import gzip as __", 221 'lxml': "from lxml import objectify as __", 222 'atlas_pymvpa': "__check_atlas_family('pymvpa')", 223 'atlas_fsl': "__check_atlas_family('fsl')", 224 'running ipython env': "__check_in_ipython()", 225 } 226 227
228 -def exists(dep, force=False, raiseException=False, issueWarning=None):
229 """ 230 Test whether a known dependency is installed on the system. 231 232 This method allows us to test for individual dependencies without 233 testing all known dependencies. It also ensures that we only test 234 for a dependency once. 235 236 :Parameters: 237 dep : string or list of string 238 The dependency key(s) to test. 239 force : boolean 240 Whether to force the test even if it has already been 241 performed. 242 raiseException : boolean 243 Whether to raise RuntimeError if dependency is missing. 244 issueWarning : string or None or True 245 If string, warning with given message would be thrown. 246 If True, standard message would be used for the warning 247 text. 248 """ 249 # if we are provided with a list of deps - go through all of them 250 if isinstance(dep, list) or isinstance(dep, tuple): 251 results = [ exists(dep_, force, raiseException) for dep_ in dep ] 252 return bool(reduce(lambda x,y: x and y, results, True)) 253 254 # where to look in cfg 255 cfgid = 'have ' + dep 256 257 # prevent unnecessarry testing 258 if cfg.has_option('externals', cfgid) \ 259 and not cfg.getboolean('externals', 'retest', default='no') \ 260 and not force: 261 if __debug__: 262 debug('EXT', "Skip retesting for '%s'." % dep) 263 return cfg.getboolean('externals', cfgid) 264 265 266 # determine availability of external (non-cached) 267 268 # default to 'not found' 269 result = False 270 271 if not _KNOWN.has_key(dep): 272 raise ValueError, "%s is not a known dependency key." % (dep) 273 else: 274 # try and load the specific dependency 275 if __debug__: 276 debug('EXT', "Checking for the presence of %s" % dep) 277 278 # Exceptions which are silently caught while running tests for externals 279 _caught_exceptions = [ImportError, AttributeError, RuntimeError] 280 281 # check whether RPy is involved and catch its excpetions as well. 282 # however, try to determine whether this is really necessary, as 283 # importing RPy also involved starting a full-blown R session, which can 284 # take seconds and therefore is quite nasty... 285 if dep.count('rpy') or _KNOWN[dep].count('rpy'): 286 try: 287 from rpy import RException 288 _caught_exceptions += [RException] 289 except: 290 pass 291 292 293 estr = '' 294 try: 295 exec _KNOWN[dep] 296 result = True 297 except tuple(_caught_exceptions), e: 298 estr = ". Caught exception was: " + str(e) 299 300 if __debug__: 301 debug('EXT', "Presence of %s is%s verified%s" % 302 (dep, {True:'', False:' NOT'}[result], estr)) 303 304 if not result: 305 if raiseException \ 306 and cfg.getboolean('externals', 'raise exception', True): 307 raise RuntimeError, "Required external '%s' was not found" % dep 308 if issueWarning is not None \ 309 and cfg.getboolean('externals', 'issue warning', True): 310 if issueWarning is True: 311 warning("Required external '%s' was not found" % dep) 312 else: 313 warning(issueWarning) 314 315 316 # store result in config manager 317 if not cfg.has_section('externals'): 318 cfg.add_section('externals') 319 if result: 320 cfg.set('externals', 'have ' + dep, 'yes') 321 else: 322 cfg.set('externals', 'have ' + dep, 'no') 323 324 return result
325 326
327 -def testAllDependencies(force=False):
328 """ 329 Test for all known dependencies. 330 331 :Parameters: 332 force : boolean 333 Whether to force the test even if it has already been 334 performed. 335 336 """ 337 # loop over all known dependencies 338 for dep in _KNOWN: 339 if not exists(dep, force): 340 warning("%s is not available." % dep) 341 342 if __debug__: 343 debug('EXT', 'The following optional externals are present: %s' \ 344 % [ k[5:] for k in cfg.options('externals') 345 if k.startswith('have')])
346