IMP logo
IMP Reference Guide  2.7.0
The Integrative Modeling Platform
test/__init__.py
1 # This file was automatically generated by SWIG (http://www.swig.org).
2 # Version 3.0.10
3 #
4 # Do not make changes to this file unless you know what you are doing--modify
5 # the SWIG interface file instead.
6 
7 # This wrapper is part of IMP,
8 # Copyright 2007-2017 IMP Inventors. All rights reserved.
9 
10 from __future__ import print_function, division, absolute_import
11 
12 
13 
14 
15 from sys import version_info as _swig_python_version_info
16 if _swig_python_version_info >= (2, 7, 0):
17  def swig_import_helper():
18  import importlib
19  pkg = __name__.rpartition('.')[0]
20  mname = '.'.join((pkg, '_IMP_test')).lstrip('.')
21  try:
22  return importlib.import_module(mname)
23  except ImportError:
24  return importlib.import_module('_IMP_test')
25  _IMP_test = swig_import_helper()
26  del swig_import_helper
27 elif _swig_python_version_info >= (2, 6, 0):
28  def swig_import_helper():
29  from os.path import dirname
30  import imp
31  fp = None
32  try:
33  fp, pathname, description = imp.find_module('_IMP_test', [dirname(__file__)])
34  except ImportError:
35  import _IMP_test
36  return _IMP_test
37  if fp is not None:
38  try:
39  _mod = imp.load_module('_IMP_test', fp, pathname, description)
40  finally:
41  fp.close()
42  return _mod
43  _IMP_test = swig_import_helper()
44  del swig_import_helper
45 else:
46  import _IMP_test
47 del _swig_python_version_info
48 try:
49  _swig_property = property
50 except NameError:
51  pass # Python < 2.2 doesn't have 'property'.
52 
53 try:
54  import builtins as __builtin__
55 except ImportError:
56  import __builtin__
57 
58 def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
59  if (name == "thisown"):
60  return self.this.own(value)
61  if (name == "this"):
62  if type(value).__name__ == 'SwigPyObject':
63  self.__dict__[name] = value
64  return
65  method = class_type.__swig_setmethods__.get(name, None)
66  if method:
67  return method(self, value)
68  if (not static):
69  object.__setattr__(self, name, value)
70  else:
71  raise AttributeError("You cannot add attributes to %s" % self)
72 
73 
74 def _swig_setattr(self, class_type, name, value):
75  return _swig_setattr_nondynamic(self, class_type, name, value, 0)
76 
77 
78 def _swig_getattr(self, class_type, name):
79  if (name == "thisown"):
80  return self.this.own()
81  method = class_type.__swig_getmethods__.get(name, None)
82  if method:
83  return method(self)
84  raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name))
85 
86 
87 def _swig_repr(self):
88  try:
89  strthis = "proxy of " + self.this.__repr__()
90  except __builtin__.Exception:
91  strthis = ""
92  return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
93 
94 
95 def _swig_setattr_nondynamic_method(set):
96  def set_attr(self, name, value):
97  if (name == "thisown"):
98  return self.this.own(value)
99  if hasattr(self, name) or (name == "this"):
100  set(self, name, value)
101  else:
102  raise AttributeError("You cannot add attributes to %s" % self)
103  return set_attr
104 
105 
106 try:
107  import weakref
108  weakref_proxy = weakref.proxy
109 except __builtin__.Exception:
110  weakref_proxy = lambda x: x
111 
112 
113 class IMP_TEST_SwigPyIterator(object):
114  """Proxy of C++ swig::IMP_TEST_SwigPyIterator class."""
115 
116  thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
117 
118  def __init__(self, *args, **kwargs):
119  raise AttributeError("No constructor defined - class is abstract")
120  __repr__ = _swig_repr
121  __swig_destroy__ = _IMP_test.delete_IMP_TEST_SwigPyIterator
122  __del__ = lambda self: None
123 
124  def value(self):
125  """value(IMP_TEST_SwigPyIterator self) -> PyObject *"""
126  return _IMP_test.IMP_TEST_SwigPyIterator_value(self)
127 
128 
129  def incr(self, n=1):
130  """
131  incr(IMP_TEST_SwigPyIterator self, size_t n=1) -> IMP_TEST_SwigPyIterator
132  incr(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator
133  """
134  return _IMP_test.IMP_TEST_SwigPyIterator_incr(self, n)
135 
136 
137  def decr(self, n=1):
138  """
139  decr(IMP_TEST_SwigPyIterator self, size_t n=1) -> IMP_TEST_SwigPyIterator
140  decr(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator
141  """
142  return _IMP_test.IMP_TEST_SwigPyIterator_decr(self, n)
143 
144 
145  def distance(self, x):
146  """distance(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> ptrdiff_t"""
147  return _IMP_test.IMP_TEST_SwigPyIterator_distance(self, x)
148 
149 
150  def equal(self, x):
151  """equal(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
152  return _IMP_test.IMP_TEST_SwigPyIterator_equal(self, x)
153 
154 
155  def copy(self):
156  """copy(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator"""
157  return _IMP_test.IMP_TEST_SwigPyIterator_copy(self)
158 
159 
160  def next(self):
161  """next(IMP_TEST_SwigPyIterator self) -> PyObject *"""
162  return _IMP_test.IMP_TEST_SwigPyIterator_next(self)
163 
164 
165  def __next__(self):
166  """__next__(IMP_TEST_SwigPyIterator self) -> PyObject *"""
167  return _IMP_test.IMP_TEST_SwigPyIterator___next__(self)
168 
169 
170  def previous(self):
171  """previous(IMP_TEST_SwigPyIterator self) -> PyObject *"""
172  return _IMP_test.IMP_TEST_SwigPyIterator_previous(self)
173 
174 
175  def advance(self, n):
176  """advance(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
177  return _IMP_test.IMP_TEST_SwigPyIterator_advance(self, n)
178 
179 
180  def __eq__(self, x):
181  """__eq__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
182  return _IMP_test.IMP_TEST_SwigPyIterator___eq__(self, x)
183 
184 
185  def __ne__(self, x):
186  """__ne__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
187  return _IMP_test.IMP_TEST_SwigPyIterator___ne__(self, x)
188 
189 
190  def __iadd__(self, n):
191  """__iadd__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
192  return _IMP_test.IMP_TEST_SwigPyIterator___iadd__(self, n)
193 
194 
195  def __isub__(self, n):
196  """__isub__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
197  return _IMP_test.IMP_TEST_SwigPyIterator___isub__(self, n)
198 
199 
200  def __add__(self, n):
201  """__add__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
202  return _IMP_test.IMP_TEST_SwigPyIterator___add__(self, n)
203 
204 
205  def __sub__(self, *args):
206  """
207  __sub__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator
208  __sub__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> ptrdiff_t
209  """
210  return _IMP_test.IMP_TEST_SwigPyIterator___sub__(self, *args)
211 
212  def __iter__(self):
213  return self
214 IMP_TEST_SwigPyIterator_swigregister = _IMP_test.IMP_TEST_SwigPyIterator_swigregister
215 IMP_TEST_SwigPyIterator_swigregister(IMP_TEST_SwigPyIterator)
216 
217 
218 _value_types=[]
219 _object_types=[]
220 _raii_types=[]
221 _plural_types=[]
222 
223 IMP_DEBUG = _IMP_test.IMP_DEBUG
224 IMP_RELEASE = _IMP_test.IMP_RELEASE
225 IMP_SILENT = _IMP_test.IMP_SILENT
226 IMP_PROGRESS = _IMP_test.IMP_PROGRESS
227 IMP_TERSE = _IMP_test.IMP_TERSE
228 IMP_VERBOSE = _IMP_test.IMP_VERBOSE
229 IMP_MEMORY = _IMP_test.IMP_MEMORY
230 IMP_NONE = _IMP_test.IMP_NONE
231 IMP_USAGE = _IMP_test.IMP_USAGE
232 IMP_INTERNAL = _IMP_test.IMP_INTERNAL
233 IMP_KERNEL_HAS_LOG4CXX = _IMP_test.IMP_KERNEL_HAS_LOG4CXX
234 IMP_COMPILER_HAS_AUTO = _IMP_test.IMP_COMPILER_HAS_AUTO
235 IMP_COMPILER_HAS_DEBUG_VECTOR = _IMP_test.IMP_COMPILER_HAS_DEBUG_VECTOR
236 IMP_COMPILER_HAS_UNIQUE_PTR = _IMP_test.IMP_COMPILER_HAS_UNIQUE_PTR
237 IMP_KERNEL_HAS_BOOST_RANDOM = _IMP_test.IMP_KERNEL_HAS_BOOST_RANDOM
238 IMP_KERNEL_HAS_GPERFTOOLS = _IMP_test.IMP_KERNEL_HAS_GPERFTOOLS
239 IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER = _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER
240 IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER = _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER
241 IMPKERNEL_SHOW_WARNINGS = _IMP_test.IMPKERNEL_SHOW_WARNINGS
242 
243 import sys
244 class _DirectorObjects(object):
245  """@internal Simple class to keep references to director objects
246  to prevent premature deletion."""
247  def __init__(self):
248  self._objects = []
249  def register(self, obj):
250  """Take a reference to a director object; will only work for
251  refcounted C++ classes"""
252  if hasattr(obj, 'get_ref_count'):
253  self._objects.append(obj)
254  def cleanup(self):
255  """Only drop our reference and allow cleanup by Python if no other
256  Python references exist (we hold 3 references: one in self._objects,
257  one in x, and one in the argument list for getrefcount) *and* no
258  other C++ references exist (the Python object always holds one)"""
259  objs = [x for x in self._objects if sys.getrefcount(x) > 3 \
260  or x.get_ref_count() > 1]
261 # Do in two steps so the references are kept until the end of the
262 # function (deleting references may trigger a fresh call to this method)
263  self._objects = objs
264  def get_object_count(self):
265  """Get number of director objects (useful for testing only)"""
266  return len(self._objects)
267 _director_objects = _DirectorObjects()
268 
269 class _ostream(object):
270  """Proxy of C++ std::ostream class."""
271 
272  thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
273 
274  def __init__(self, *args, **kwargs):
275  raise AttributeError("No constructor defined")
276  __repr__ = _swig_repr
277 
278  def write(self, osa_buf):
279  """write(_ostream self, char const * osa_buf)"""
280  return _IMP_test._ostream_write(self, osa_buf)
281 
282 _ostream_swigregister = _IMP_test._ostream_swigregister
283 _ostream_swigregister(_ostream)
284 
285 IMP_COMPILER_HAS_OVERRIDE = _IMP_test.IMP_COMPILER_HAS_OVERRIDE
286 IMP_COMPILER_HAS_FINAL = _IMP_test.IMP_COMPILER_HAS_FINAL
287 IMP_HAS_NOEXCEPT = _IMP_test.IMP_HAS_NOEXCEPT
288 import IMP
289 IMP_TEST_HAS_BOOST_FILESYSTEM = _IMP_test.IMP_TEST_HAS_BOOST_FILESYSTEM
290 IMP_TEST_HAS_BOOST_PROGRAMOPTIONS = _IMP_test.IMP_TEST_HAS_BOOST_PROGRAMOPTIONS
291 IMP_TEST_HAS_BOOST_RANDOM = _IMP_test.IMP_TEST_HAS_BOOST_RANDOM
292 IMP_TEST_HAS_BOOST_SYSTEM = _IMP_test.IMP_TEST_HAS_BOOST_SYSTEM
293 IMPTEST_SHOW_WARNINGS = _IMP_test.IMPTEST_SHOW_WARNINGS
294 
295 
296 """@namespace IMP::test
297  @brief Methods and classes for testing the IMP kernel and modules.
298  @ingroup python
299 """
300 
301 import re, math
302 import sys
303 import os
304 import re
305 import tempfile
306 import random
307 import IMP
308 import time
309 import types
310 import shutil
311 from . import _compat_python
312 from ._compat_python import unittest2
313 import datetime
314 import pickle
315 import contextlib
316 
317 # Fall back to the sets.Set class on older Pythons that don't have
318 # the 'set' builtin type.
319 try:
320  set = set
321 except NameError:
322  import sets
323  set = sets.Set
324 
325 # Load a new enough unittest package (should have the 'skip' decorator)
326 # - On Python 2.7 or 3.2, the standard 'unittest' package will work.
327 # - On older Pythons, use the 'unittest2' package if available, otherwise use
328 # our bundled version of this package.
329 def __load_unittest_package():
330  errors = []
331  for modname, fromlist in (('unittest', []),
332  ('unittest2', []),
333  ):
334  try:
335  u = __import__(modname, {}, {}, fromlist)
336  if hasattr(u, 'skip'):
337  return u
338  else:
339  errors.append("'%s' does not have the 'skip' decorator" \
340  % modname)
341  except ImportError as e:
342  errors.append(str(e))
343 #u = __import__("_compat_python.unittest2
344  return _compat_python.unittest2
345  raise ImportError("IMP.test requires a newer version of Python's unittest "
346  "package than is available. Either upgrade to a new "
347  "enough Python (at least 2.7 or 3.2) or install the "
348  "unittest2 package. Encountered errors: %s" \
349  % "; ".join(errors))
350 unittest = __load_unittest_package()
351 
352 # Expose some unittest decorators for convenience
353 expectedFailure = unittest.expectedFailure
354 skip = unittest.skip
355 skipIf = unittest.skipIf
356 skipUnless = unittest.skipUnless
357 
358 @IMP.deprecated_object("2.7", "Use temporary_working_directory() instead.")
359 class RunInTempDir(object):
360  """Simple RAII-style class to run in a temporary directory.
361  When the object is created, the temporary directory is created
362  and becomes the current working directory. When the object goes out
363  of scope, the working directory is reset and the temporary directory
364  deleted."""
365  def __init__(self):
366  self.origdir = os.getcwd()
367  self.tmpdir = tempfile.mkdtemp()
368  os.chdir(self.tmpdir)
369  def __del__(self):
370  os.chdir(self.origdir)
371  shutil.rmtree(self.tmpdir, ignore_errors=True)
372 
373 @contextlib.contextmanager
375  """Simple context manager to run in a temporary directory.
376  While the context manager is active (within the 'with' block)
377  the current working directory is set to a temporary directory.
378  When the context manager exists, the working directory is reset
379  and the temporary directory deleted."""
380  origdir = os.getcwd()
381  tmpdir = tempfile.mkdtemp()
382  os.chdir(tmpdir)
383  yield tmpdir
384  os.chdir(origdir)
385  shutil.rmtree(tmpdir, ignore_errors=True)
386 
387 @IMP.deprecated_object("2.7", "Use temporary_directory() instead.")
388 class TempDir(object):
389  """Simple RAII-style class to make a temporary directory. When the object
390  is created, the temporary directory is created. When the object goes
391  out of scope, the temporary directory is deleted."""
392  def __init__(self, dir=None):
393  self.tmpdir = tempfile.mkdtemp(dir=dir)
394  def __del__(self):
395  shutil.rmtree(self.tmpdir, ignore_errors=True)
396 
397 class _TempDir(object):
398  def __init__(self, dir=None):
399  self.tmpdir = tempfile.mkdtemp(dir=dir)
400  def __del__(self):
401  shutil.rmtree(self.tmpdir, ignore_errors=True)
402 
403 @contextlib.contextmanager
404 def temporary_directory(dir=None):
405  """Simple context manager to make a temporary directory.
406  The temporary directory has the same lifetime as the context manager
407  (i.e. it is created at the start of the 'with' block, and deleted
408  at the end of the block).
409  @param dir If given, the temporary directory is made as a subdirectory
410  of that directory, rather than in the default temporary
411  directory location (e.g. /tmp)
412  @return the full path to the temporary directory.
413  """
414  tmpdir = tempfile.mkdtemp(dir=dir)
415  yield tmpdir
416  shutil.rmtree(tmpdir, ignore_errors=True)
417 
418 def numerical_derivative(func, val, step):
419  """Calculate the derivative of the single-value function `func` at
420  point `val`. The derivative is calculated using simple finite
421  differences starting with the given `step`; Richardson extrapolation
422  is then used to extrapolate the derivative at step=0."""
423  maxsteps = 50
424  con = 1.4
425  safe = 2.0
426  err = 1.0e30
427  f1 = func(val + step)
428  f2 = func(val - step)
429 # create first element in triangular matrix d of derivatives
430  d = [[(f1 - f2) / (2.0 * step)]]
431  retval = None
432  for i in range(1, maxsteps):
433  d.append([0.] * (i + 1))
434  step /= con
435  f1 = func(val + step)
436  f2 = func(val - step)
437  d[i][0] = (f1 - f2) / (2.0 * step)
438  fac = con * con
439  for j in range(1, i + 1):
440  d[i][j] = (d[i][j-1] * fac - d[i-1][j-1]) / (fac - 1.)
441  fac *= con * con
442  errt = max(abs(d[i][j] - d[i][j-1]),
443  abs(d[i][j] - d[i-1][j-1]))
444  if errt <= err:
445  err = errt
446  retval = d[i][j]
447  if abs(d[i][i] - d[i-1][i-1]) >= safe * err:
448  break
449  if retval is None:
450  raise ValueError("Cannot calculate numerical derivative")
451  return retval
452 
453 
454 def xyz_numerical_derivatives(sf, xyz, step):
455  """Calculate the x,y and z derivatives of the scoring function `sf`
456  on the `xyz` particle. The derivatives are approximated numerically
457  using the numerical_derivatives() function."""
458  class _XYZDerivativeFunc(object):
459  def __init__(self, sf, xyz, basis_vector):
460  self._xyz = xyz
461  self._sf = sf
462  self._basis_vector = basis_vector
463  self._starting_coordinates = xyz.get_coordinates()
464 
465  def __call__(self, val):
466  self._xyz.set_coordinates(self._starting_coordinates + \
467  self._basis_vector * val)
468  return self._sf.evaluate(False)
469 
470  return tuple([IMP.test.numerical_derivative(_XYZDerivativeFunc(sf, xyz,
471  IMP.algebra.Vector3D(*x)), 0, 0.01) \
472  for x in ((1,0,0), (0,1,0), (0,0,1))])
473 
474 
475 class TestCase(unittest.TestCase):
476  """Super class for IMP test cases.
477  This provides a number of useful IMP-specific methods on top of
478  the standard Python `unittest.TestCase` class.
479  Test scripts should generally contain a subclass of this class,
480  conventionally called `Tests` (this makes it easier to run an
481  individual test from the commane line) and use IMP::test::main()
482  as their main function."""
483 
484  def __init__(self, *args, **keys):
485  unittest.TestCase.__init__(self, *args, **keys)
486  self._progname = os.path.abspath(sys.argv[0])
487 
488  def setUp(self):
489  self.__check_level = IMP.get_check_level()
490 # Turn on expensive runtime checks while running the test suite:
491  IMP.set_check_level(IMP.USAGE_AND_INTERNAL)
492 # python ints are bigger than C++ ones, so we need to make sure it fits
493 # otherwise python throws fits
494  IMP.random_number_generator.seed(hash(time.time())%2**30)
495 
496  def tearDown(self):
497 # Restore original check level
498  IMP.set_check_level(self.__check_level)
499 # Clean up any temporary files
500  if hasattr(self, '_tmpdir'):
501  del self._tmpdir
502 
503  def get_input_file_name(self, filename):
504  """Get the full name of an input file in the top-level
505  test directory."""
506  testdir = os.path.dirname(self._progname)
507  dirs = testdir.split(os.path.sep)
508  for i in range(len(dirs), 0, -1):
509  input = os.path.sep.join(dirs[:i] + ['input'])
510  if os.path.isdir(input):
511  ret = os.path.join(input, filename)
512  if not os.path.exists(ret):
513  raise IOError("Test input file "+ret+" does not exist")
514  return ret
515  raise IOError("No test input directory found")
516 
517  def open_input_file(self, filename, mode='rb'):
518  """Open and return an input file in the top-level test directory."""
519  return open(self.get_input_file_name(filename), mode)
520 
521  def get_tmp_file_name(self, filename):
522  """Get the full name of an output file in the tmp directory.
523  The directory containing this file will be automatically
524  cleaned up when the test completes."""
525  if not hasattr(self, '_tmpdir'):
526  self._tmpdir = _TempDir(os.environ['IMP_TMP_DIR'])
527  tmpdir = self._tmpdir.tmpdir
528  return os.path.join(tmpdir, filename)
529 
530  def get_magnitude(self, vector):
531  """Get the magnitude of a list of floats"""
532  return sum([x*x for x in vector], 0)**.5
533 
534  def assertRaisesUsageException(self, c, *args, **keys):
535  """Assert that the given callable object raises UsageException.
536  This differs from unittest's assertRaises in that the test
537  is skipped in fast mode (where usage checks are turned off)."""
538  if IMP.get_check_level() >= IMP.USAGE:
539  return self.assertRaises(IMP.UsageException, c, *args, **keys)
540 
541  def assertRaisesInternalException(self, c, *args, **keys):
542  """Assert that the given callable object raises InternalException.
543  This differs from unittest's assertRaises in that the test
544  is skipped in fast mode (where internal checks are turned off)."""
545  if IMP.get_check_level() >= IMP.USAGE_AND_INTERNAL:
546  return self.assertRaises(IMP.InternalException, c, *args, **keys)
547 
548  def assertNotImplemented(self, c, *args, **keys):
549  """Assert that the given callable object is not implemented."""
550  return self.assertRaises(IMP.InternalException, c, *args, **keys)
551 
552  def assertXYZDerivativesInTolerance(self, sf, xyz, tolerance=0,
553  percentage=0):
554  """Assert that x,y,z analytical derivatives match numerical within
555  a tolerance, or a percentage (of the analytical value), whichever
556  is larger. `sf` should be a ScoringFunction or Restraint,
557  although for backwards compatibility a Model is also accepted."""
558  sf.evaluate(True)
559  derivs = xyz.get_derivatives()
560  num_derivs = xyz_numerical_derivatives(sf, xyz, 0.01)
561  pct = percentage / 100.0
562  self.assertAlmostEqual(self.get_magnitude(derivs-num_derivs),0,
563  delta=tolerance+percentage*self.get_magnitude(num_derivs),
564  msg="Don't match "+str(derivs) + str(num_derivs))
565  self.assertAlmostEqual(derivs[0], num_derivs[0],
566  delta=max(tolerance, abs(derivs[0]) * pct))
567  self.assertAlmostEqual(derivs[1], num_derivs[1],
568  delta=max(tolerance, abs(derivs[1]) * pct))
569  self.assertAlmostEqual(derivs[2], num_derivs[2],
570  delta=max(tolerance, abs(derivs[2]) * pct))
571 
572  def create_point_particle(self, model, x, y, z):
573  """Make a particle with optimizable x, y and z attributes, and
574  add it to the model."""
575  p = IMP.Particle(model)
576  p.add_attribute(IMP.FloatKey("x"), x, True)
577  p.add_attribute(IMP.FloatKey("y"), y, True)
578  p.add_attribute(IMP.FloatKey("z"), z, True)
579  return p
580 
581  def probabilistic_test(self, testcall, chance_of_failure):
582  """Help handle a test which is expected to fail some fraction of
583  the time. The test is run multiple times and an exception
584  is thrown only if it fails too many times.
585  @note Use of this function should be avoided. If there is a corner
586  case that results in a test 'occasionally' failing, write a
587  new test specifically for that corner case and assert that
588  it fails consistently (and remove the corner case from the
589  old test).
590  """
591  prob=chance_of_failure
592  tries=1
593  while prob > .001:
594  tries=tries+1
595  prob= prob*chance_of_failure
596  for i in range(0, tries):
597  try:
598  eval(testcall)
599  except:
600  pass
601  else:
602  return
603  eval(testcall)
604  raise AssertError("Too many failures")
605 
606  def failure_probability(self, testcall):
607  """Estimate how likely a given block of code is to raise an
608  AssertionError."""
609  failures=0
610  tries=0.0
611  while failures < 10 and tries <1000:
612  try:
613  eval(testcall)
614  except:
615  failures=failures+1
616  tries=tries+1
617  return failures/tries
618 
619  def randomize_particles(self, particles, deviation):
620  """Randomize the xyz coordinates of a list of particles"""
621 # Note: cannot use XYZ here since that pulls in IMP.core
622  xkey = IMP.FloatKey("x")
623  ykey = IMP.FloatKey("y")
624  zkey = IMP.FloatKey("z")
625  for p in particles:
626  p.set_value(xkey, random.uniform(-deviation, deviation))
627  p.set_value(ykey, random.uniform(-deviation, deviation))
628  p.set_value(zkey, random.uniform(-deviation, deviation))
629 
630  def particle_distance(self, p1, p2):
631  """Return distance between two given particles"""
632  xkey = IMP.FloatKey("x")
633  ykey = IMP.FloatKey("y")
634  zkey = IMP.FloatKey("z")
635  dx = p1.get_value(xkey) - p2.get_value(xkey)
636  dy = p1.get_value(ykey) - p2.get_value(ykey)
637  dz = p1.get_value(zkey) - p2.get_value(zkey)
638  return math.sqrt(dx*dx + dy*dy + dz*dz)
639 
640  def check_unary_function_deriv(self, func, lb, ub, step):
641  """Check the unary function func's derivatives against numerical
642  approximations between lb and ub"""
643  for f in [lb + i * step for i in range(1, int((ub-lb)/step))]:
644  (v,d)= func.evaluate_with_derivative(f)
645  da = numerical_derivative(func.evaluate, f, step / 10.)
646  self.assertAlmostEqual(d, da, delta=max(abs(.1 *d), 0.01))
647 
648  def check_unary_function_min(self, func, lb, ub, step, expected_fmin):
649  """Make sure that the minimum of the unary function func over the
650  range between lb and ub is at expected_fmin"""
651  fmin, vmin = lb, func.evaluate(lb)
652  for f in [lb + i * step for i in range(1, int((ub-lb)/step))]:
653  v = func.evaluate(f)
654  if v < vmin:
655  fmin, vmin = f, v
656  self.assertAlmostEqual(fmin, expected_fmin, delta=step)
657 
658  def check_get_from(self, obj):
659  """Check that the get_from() static method works correctly"""
660  cls = type(obj)
661  self.assertIsNotNone(cls.get_from(obj))
662  self.assertRaises(ValueError, cls.get_from, IMP.Model())
663 
664  def create_particles_in_box(self, model, num=10,
665  lb= [0,0,0],
666  ub= [10,10,10]):
667  """Create a bunch of particles in a box"""
668  import IMP.algebra
669  lbv=IMP.algebra.Vector3D(lb[0],lb[1],lb[2])
670  ubv=IMP.algebra.Vector3D(ub[0],ub[1],ub[2])
671  ps= []
672  for i in range(0,num):
674  p = self.create_point_particle(model, v[0], v[1], v[2])
675  ps.append(p)
676  return ps
677  def _get_type(self, module, name):
678  return eval('type('+module+"."+name+')')
679  def assertValueObjects(self, module, exceptions_list):
680  "Check that all the C++ classes in the module are values or objects."
681  all= dir(module)
682  ok = set(exceptions_list + module._value_types + module._object_types + module._raii_types + module._plural_types)
683 
684  bad=[]
685  for name in all:
686  if self._get_type(module.__name__, name)==type and not name.startswith("_"):
687  if name.find("SwigPyIterator") != -1:
688  continue
689 # Exclude Python-only classes
690  if not eval('hasattr(%s.%s, "__swig_destroy__")' \
691  % (module.__name__, name)):
692  continue
693  if name in ok:
694  continue
695  bad.append(name)
696  message="All IMP classes should be labeled as values or objects to get memory management correct in Python. The following are not:\n%s\nPlease add an IMP_SWIG_OBJECT or IMP_SWIG_VALUE call to the Python wrapper, or if the class has a good reason to be neither, add the name to the value_object_exceptions list in the IMPModuleTest call." \
697  % (str(bad))
698  self.assertEqual(len(bad), 0, message)
699  for e in exceptions_list:
700  self.assertTrue(e not in module._value_types
701  + module._object_types
702  + module._raii_types
703  + module._plural_types,
704  "Value/Object exception "+e+" is not an exception")
705 
706  def _check_spelling(self, word, words):
707  """Check that the word is spelled correctly"""
708  if "words" not in dir(self):
709  with open(IMP.test.get_data_path("linux.words"), "r") as fh:
710  wordlist= fh.read().split("\n")
711 # why is "all" missing on my mac?
712  custom_words=["info", "prechange", "int", "ints", "optimizeds", "graphviz",
713  "voxel", "voxels", "endian", 'rna', 'dna',
714  "xyzr", "pdbs", "fft", "ccc", "gaussian"]
715 # Exclude some common alternative spellings - we want to
716 # be consistent
717  exclude_words = set(["adapter", "grey"])
718  self.words=set(wordlist+custom_words) - exclude_words
719  if self.words:
720  for i in "0123456789":
721  if i in word:
722  return True
723  if word in words:
724  return True
725  if word in self.words:
726  return True
727  else:
728  return False
729  else:
730  return True
731  def assertClassNames(self, module, exceptions, words):
732  """Check that all the classes in the module follow the IMP
733  naming conventions."""
734  all= dir(module)
735  misspelled = []
736  bad=[]
737  cc=re.compile("([A-Z][a-z]*)")
738  for name in all:
739  if self._get_type(module.__name__, name)==type and not name.startswith("_"):
740  if name.find("SwigPyIterator") != -1:
741  continue
742  for t in re.findall(cc, name):
743  if not self._check_spelling(t.lower(), words):
744  misspelled.append(t.lower())
745  bad.append(name)
746 
747  self.assertEqual(len(bad), 0,
748  "All IMP classes should be properly spelled. The following are not: %s.\nMisspelled words: %s. Add words to the spelling_exceptions variable of the IMPModuleTest if needed." \
749  % (str(bad), ", ".join(set(misspelled))))
750 
751  for name in all:
752  if self._get_type(module.__name__, name)==type and not name.startswith("_"):
753  if name.find("SwigPyIterator") != -1:
754  continue
755  if name.find('_') != -1:
756  bad.append(name)
757  if name.lower== name:
758  bad.append(name)
759  for t in re.findall(cc, name):
760  if not self._check_spelling(t.lower(), words):
761  print("misspelled %s in %s" % (t, name))
762  bad.append(name)
763  message="All IMP classes should have CamelCase names. The following do not: %s." \
764  % ("\n".join(bad))
765  self.assertEqual(len(bad), 0, message)
766 
767  def _check_function_name(self, prefix, name, verbs, all, exceptions, words,
768  misspelled):
769  if prefix:
770  fullname=prefix+"."+name
771  else:
772  fullname=name
773  old_exceptions=['unprotected_evaluate', "unprotected_evaluate_if_good",
774  "unprotected_evaluate_if_below",
775  "after_evaluate", "before_evaluate", "has_attribute",
776  "decorate_particle","particle_is_instance"]
777  if name in old_exceptions:
778  return []
779 #print "name", fullname
780  if fullname in exceptions:
781  return []
782  if name.endswith("swigregister"):
783  return []
784  if name.lower() != name:
785  if name[0].lower() != name[0] and name.split('_')[0] in all:
786 # static methods
787  return []
788  else:
789  return [fullname]
790  tokens= name.split("_")
791  if tokens[0] not in verbs:
792  return [fullname]
793  for t in tokens:
794  if not self._check_spelling(t, words):
795  misspelled.append(t)
796  print("misspelled %s in %s" % (t, name))
797  return [fullname]
798  return []
799 
800  def _static_method(self, module, prefix, name):
801  """For static methods of the form Foo.bar SWIG creates free functions
802  named Foo_bar. Exclude these from spelling checks since the method
803  Foo.bar has already been checked."""
804  if prefix is None and '_' in name:
805  modobj = eval(module)
806  cls, meth = name.split('_', 1)
807  if hasattr(modobj, cls):
808  clsobj = eval(module + '.' + cls)
809  if hasattr(clsobj, meth):
810  return True
811 
812  def _check_function_names(self, module, prefix, names, verbs, all,
813  exceptions, words, misspelled):
814  bad=[]
815  for name in names:
816  typ = self._get_type(module, name)
817  if name.startswith("_") or name =="weakref_proxy":
818  continue
819  if typ in (types.BuiltinMethodType, types.MethodType) \
820  or (typ == types.FunctionType and \
821  not self._static_method(module, prefix, name)):
822  bad.extend(self._check_function_name(prefix, name, verbs, all,
823  exceptions, words,
824  misspelled))
825  if typ == type and "SwigPyIterator" not in name:
826  members=eval("dir("+module+"."+name+")")
827  bad.extend(self._check_function_names(module+"."+name,
828  name, members, verbs, [],
829  exceptions, words,
830  misspelled))
831  return bad
832 
833  def assertFunctionNames(self, module, exceptions, words):
834  """Check that all the functions in the module follow the IMP
835  naming conventions."""
836  all= dir(module)
837  verbs=set(["add", "remove", "get", "set", "evaluate", "compute", "show", "create", "destroy",
838  "push", "pop", "write", "read", "do", "show", "load", "save", "reset",
839  "accept", "reject",
840  "clear", "handle", "update", "apply", "optimize", "reserve", "dump",
841  "propose", "setup", "teardown", "visit", "find", "run", "swap", "link",
842  "validate"])
843  misspelled = []
844  bad=self._check_function_names(module.__name__, None, all, verbs, all, exceptions, words, misspelled)
845  message="All IMP methods and functions should have lower case names separated by underscores and beginning with a verb, preferably one of ['add', 'remove', 'get', 'set', 'create', 'destroy']. Each of the words should be a properly spelled English word. The following do not (given our limited list of verbs that we check for):\n%(bad)s\nIf there is a good reason for them not to (eg it does start with a verb, just one with a meaning that is not covered by the normal list), add them to the function_name_exceptions variable in the standards_exceptions file. Otherwise, please fix. The current verb list is %(verbs)s" \
846  % {"bad":"\n".join(bad), "verbs":verbs}
847  if len(misspelled) > 0:
848  message += "\nMisspelled words: " + ", ".join(set(misspelled)) \
849  + ". Add words to the spelling_exceptions variable " \
850  + "of the standards_exceptions file if needed."
851  self.assertEqual(len(bad), 0, message)
852 
853 
854  def assertShow(self, modulename, exceptions):
855  """Check that all the classes in modulename have a show method"""
856  all= dir(modulename)
857  not_found=[]
858  for f in all:
859 # Exclude SWIG C global variables object
860  if f == 'cvar':
861  continue
862 # Exclude Python-only classes; they are all showable
863  if not eval('hasattr(%s.%s, "__swig_destroy__")' \
864  % (modulename.__name__, f)):
865  continue
866  if self._get_type(modulename.__name__, f) == type \
867  and not f.startswith("_") \
868  and not f.endswith("_swigregister")\
869  and f not in exceptions\
870  and not f.endswith("Temp") and not f.endswith("Iterator")\
871  and not f.endswith("Exception") and\
872  f not in modulename._raii_types and \
873  f not in modulename._plural_types:
874  if not hasattr(getattr(modulename, f), 'show'):
875  not_found.append(f)
876  message="All IMP classes should support show and __str__. The following do not:\n%s\n If there is a good reason for them not to, add them to the show_exceptions variable in the IMPModuleTest call. Otherwise, please fix." \
877  % "\n".join(not_found)
878  self.assertEqual(len(not_found), 0, message)
879  for e in exceptions:
880  self.assertIn(e, all, "Show exception "+e+" is not a class in module")
881  self.assertTrue(not hasattr(getattr(modulename, e), 'show'),
882  "Exception "+e+" is not really a show exception")
883 
884  def run_example(self, filename):
885  """Run the named example script.
886  @return a dictionary of all the script's global variables.
887  This can be queried in a test case to make sure
888  the example performed correctly."""
889  class _FatalError(Exception): pass
890 
891 # Add directory containing the example to sys.path, so it can import
892 # other Python modules in the same directory
893  path, name = os.path.split(filename)
894  oldsyspath = sys.path[:]
895  olssysargv= sys.argv[:]
896  sys.path.insert(0, path)
897  sys.argv=[filename]
898  vars = {}
899  try:
900  try:
901  exec(open(filename).read(), vars)
902 # Catch sys.exit() called from within the example; a non-zero exit
903 # value should cause the test case to fail
904  except SystemExit as e:
905  if e.code != 0 and e.code is not None:
906  raise _FatalError("Example exit with code %s" % str(e.code))
907  finally:
908 # Restore sys.path (note that Python 2.3 does not allow
909 # try/except/finally, so we need to use nested trys)
910  sys.path = oldsyspath
911  sys.argv= olssysargv
912 
913  return _ExecDictProxy(vars)
914 
915  def run_python_module(self, module, args):
916  """Run a Python module as if with "python -m <modname>",
917  with the given list of arguments as sys.argv.
918 
919  If module is an already-imported Python module, run its 'main'
920  function and return the result.
921 
922  If module is a string, run the module in a subprocess and return
923  a subprocess.Popen-like object containing the child stdin,
924  stdout and stderr.
925  """
926  if type(module) == type(os):
927  mod = module
928  else:
929  mod = __import__(module, {}, {}, [''])
930  modpath = mod.__file__
931  if modpath.endswith('.pyc'):
932  modpath = modpath[:-1]
933  if type(module) == type(os):
934  old_sys_argv = sys.argv
935 # boost parser doesn't like being called multiple times per process
936  IMP.OptionParser._use_boost_parser = False
937  try:
938  sys.argv = [modpath] + args
939  return module.main()
940  finally:
941  IMP.OptionParser._use_boost_parser = True
942  sys.argv = old_sys_argv
943  else:
944  return _SubprocessWrapper(sys.executable, [modpath] + args)
945 
946  def check_runnable_python_module(self, module):
947  """Check a Python module designed to be runnable with 'python -m'
948  to make sure it supports standard command line options."""
949 # --help should return with exit 0, no errors
950  r = self.run_python_module(module, ['--help'])
951  out, err = r.communicate()
952  self.assertEqual(r.returncode, 0)
953  self.assertNotEqual(err, "")
954  self.assertEqual(out, "")
955 
956 
957 class _ExecDictProxy(object):
958  """exec returns a Python dictionary, which contains IMP objects, other
959  Python objects, as well as base Python modules (such as sys and
960  __builtins__). If we just delete this dictionary, it is entirely
961  possible that base Python modules are removed from the dictionary
962  *before* some IMP objects. This will prevent the IMP objects' Python
963  destructors from running properly, so C++ objects will not be
964  cleaned up. This class proxies the base dict class, and on deletion
965  attempts to remove keys from the dictionary in an order that allows
966  IMP destructors to fire."""
967  def __init__(self, d):
968  self._d = d
969  def __del__(self):
970 # Try to release example objects in a sensible order
971  module_type = type(IMP)
972  d = self._d
973  for k in d.keys():
974  if type(d[k]) != module_type:
975  del d[k]
976 
977  for meth in ['__contains__', '__getitem__', '__iter__', '__len__',
978  'get', 'has_key', 'items', 'keys', 'values']:
979  exec("def %s(self, *args, **keys): "
980  "return self._d.%s(*args, **keys)" % (meth, meth))
981 
982 
983 class _TestResult(unittest.TextTestResult):
984 
985  def __init__(self, stream=None, descriptions=None, verbosity=None):
986  super(_TestResult, self).__init__(stream, descriptions, verbosity)
987  self.all_tests = []
988 
989  def stopTestRun(self):
990  if 'IMP_TEST_DETAIL_DIR' in os.environ:
991  fname = os.path.join(os.environ['IMP_TEST_DETAIL_DIR'],
992  os.path.basename(sys.argv[0]))
993  with open(fname, 'wb') as fh:
994  pickle.dump(self.all_tests, fh, -1)
995  super(_TestResult, self).stopTestRun()
996 
997  def startTest(self, test):
998  super(_TestResult, self).startTest(test)
999  test.start_time=datetime.datetime.now()
1000 
1001  def _test_finished(self, test, state, detail=None):
1002  delta = datetime.datetime.now() - test.start_time
1003  try:
1004  pv= delta.total_seconds()
1005  except AttributeError:
1006  pv = (float(delta.microseconds) \
1007  + (delta.seconds + delta.days * 24 * 3600) * 10**6) / 10**6
1008  if pv > 1:
1009  self.stream.write("in %.3fs ... " % pv)
1010  if detail is not None and not isinstance(detail, str):
1011  detail = self._exc_info_to_string(detail, test)
1012  test_doc = self.getDescription(test)
1013  test_name = test.id()
1014  if test_name.startswith('__main__.'):
1015  test_name = test_name[9:]
1016  self.all_tests.append({'name': test_name,
1017  'docstring': test_doc,
1018  'time': pv, 'state': state, 'detail': detail})
1019 
1020  def addSuccess(self, test):
1021  self._test_finished(test, 'OK')
1022  super(_TestResult, self).addSuccess(test)
1023 
1024  def addError(self, test, err):
1025  self._test_finished(test, 'ERROR', err)
1026  super(_TestResult, self).addError(test, err)
1027 
1028  def addFailure(self, test, err):
1029  self._test_finished(test, 'FAIL', err)
1030  super(_TestResult, self).addFailure(test, err)
1031 
1032  def addSkip(self, test, reason):
1033  self._test_finished(test, 'SKIP', reason)
1034  super(_TestResult, self).addSkip(test, reason)
1035 
1036  def addExpectedFailure(self, test, err):
1037  self._test_finished(test, 'EXPFAIL', err)
1038  super(_TestResult, self).addExpectedFailure(test, err)
1039 
1040  def addUnexpectedSuccess(self, test):
1041  self._test_finished(test, 'UNEXPSUC')
1042  super(_TestResult, self).addUnexpectedSuccess(test)
1043 
1044  def getDescription(self, test):
1045  doc_first_line = test.shortDescription()
1046  if self.descriptions and doc_first_line:
1047  return doc_first_line
1048  else:
1049  return str(test)
1050 
1051 
1052 class _TestRunner(unittest.TextTestRunner):
1053  def _makeResult(self):
1054  return _TestResult(self.stream, self.descriptions, self.verbosity)
1055 
1056 
1057 def main(*args, **keys):
1058  """Run a set of tests; similar to unittest.main().
1059  Obviates the need to separately import the 'unittest' module, and
1060  ensures that main() is from the same unittest module that the
1061  IMP.test testcases are. In addition, turns on some extra checks
1062  (e.g. trying to use deprecated code will cause an exception
1063  to be thrown)."""
1064  import IMP
1066  return unittest.main(testRunner=_TestRunner, *args, **keys)
1067 
1068 import subprocess
1069 class _SubprocessWrapper(subprocess.Popen):
1070  def __init__(self, app, args):
1071 # For (non-Python) applications to work on Windows, the
1072 # PATH must include the directory containing built DLLs
1073  if sys.platform == 'win32' and app != sys.executable:
1074 # Hack to find the location of build/lib/
1075  libdir = os.environ['PYTHONPATH'].split(';')[0]
1076  env = os.environ.copy()
1077  env['PATH'] += ';' + libdir
1078  else:
1079  env = None
1080  subprocess.Popen.__init__(self, [app]+list(args),
1081  stdin=subprocess.PIPE,
1082  stdout=subprocess.PIPE,
1083  stderr=subprocess.PIPE, env=env,
1084  universal_newlines=True)
1085 
1086 
1088  """Super class for simple IMP application test cases"""
1089  def _get_application_file_name(self, filename):
1090 # If we ran from run-all-tests.py, it set an env variable for us with
1091 # the top-level test directory
1092  if sys.platform == 'win32':
1093  filename += '.exe'
1094 #if 'IMP_BUILD_ROOT' in os.environ:
1095 # testdir = os.environ['IMP_BUILD_ROOT']
1096 # return os.path.join(testdir, "build", "bin", filename)
1097  return filename
1098 
1099  def run_application(self, app, args):
1100  """Run an application with the given list of arguments.
1101  @return a subprocess.Popen-like object containing the child stdin,
1102  stdout and stderr.
1103  """
1104  filename = self._get_application_file_name(app)
1105  if sys.platform == 'win32':
1106 # Cannot rely on PATH on wine builds, so use full pathname
1107  return _SubprocessWrapper(os.path.join(os.environ['IMP_BIN_DIR'],
1108  filename), args)
1109  else:
1110  return _SubprocessWrapper(filename, args)
1111 
1112  def run_python_application(self, app, args):
1113  """Run a Python application with the given list of arguments.
1114  The Python application should be self-runnable (i.e. it should
1115  be executable and with a #! on the first line).
1116  @return a subprocess.Popen-like object containing the child stdin,
1117  stdout and stderr.
1118  """
1119 # Handle platforms where /usr/bin/python doesn't work
1120  if sys.executable != '/usr/bin/python' and 'IMP_BIN_DIR' in os.environ:
1121  return _SubprocessWrapper(sys.executable,
1122  [os.path.join(os.environ['IMP_BIN_DIR'], app)] + args)
1123  else:
1124  return _SubprocessWrapper(app, args)
1125 
1127  """Import an installed Python application, rather than running it.
1128  This is useful to directly test components of the application.
1129  @return the Python module object."""
1130  try:
1131  import importlib.machinery
1132  imp = None
1133  except ImportError:
1134  import imp
1135  name = os.path.splitext(app)[0]
1136  pathname = os.path.join(os.environ['IMP_BIN_DIR'], app)
1137  if imp is None:
1138  return importlib.machinery.SourceFileLoader(name,
1139  pathname).load_module()
1140  else:
1141  return imp.load_source(name, pathname)
1142 
1143  def run_script(self, app, args):
1144  """Run an application with the given list of arguments.
1145  @return a subprocess.Popen-like object containing the child stdin,
1146  stdout and stderr.
1147  """
1148  return _SubprocessWrapper(sys.executable, [app]+args)
1149 
1150  def assertApplicationExitedCleanly(self, ret, error):
1151  """Assert that the application exited cleanly (return value = 0)."""
1152  if ret < 0:
1153  raise OSError("Application exited with signal %d\n" % -ret\
1154  +error)
1155  else:
1156  self.assertEqual(ret, 0,
1157  "Application exited uncleanly, with exit code %d\n" % ret\
1158  + error)
1159 
1160  def read_shell_commands(self, doxfile):
1161  """Read and return a set of shell commands from a doxygen file.
1162  Each command is assumed to be in a \code{.sh}...\endcode block.
1163  The doxygen file is specified relative to the test file itself.
1164  This is used to make sure the commands shown in an application
1165  example actually work (the testcase can also check the resulting
1166  files for correctness)."""
1167  def win32_normpath(p):
1168 # Sometimes Windows can read Unix-style paths, but sometimes it
1169 # gets confused... so normalize all paths to be sure
1170  return " ".join([os.path.normpath(x) for x in p.split()])
1171  def fix_win32_command(cmd):
1172 # Make substitutions so a Unix shell command works on Windows
1173  if cmd.startswith('cp -r '):
1174  return 'xcopy /E ' + win32_normpath(cmd[6:])
1175  elif cmd.startswith('cp '):
1176  return 'copy ' + win32_normpath(cmd[3:])
1177  else:
1178  return cmd
1179  d = os.path.dirname(sys.argv[0])
1180  doc = os.path.join(d, doxfile)
1181  inline = False
1182  cmds = []
1183  example_path = os.path.abspath(IMP.get_example_path('..'))
1184  with open(doc) as fh:
1185  for line in fh.readlines():
1186  if '\code{.sh}' in line:
1187  inline = True
1188  elif '\endcode' in line:
1189  inline = False
1190  elif inline:
1191  cmds.append(line.rstrip('\r\n').replace(
1192  '<imp_example_path>', example_path))
1193  if sys.platform == 'win32':
1194  cmds = [fix_win32_command(x) for x in cmds]
1195  return cmds
1196 
1197  def run_shell_command(self, cmd):
1198  "Print and run a shell command, as returned by read_shell_commands()"
1199  import subprocess
1200  print(cmd)
1201  p = subprocess.call(cmd, shell=True)
1202  if p != 0:
1203  raise OSError("%s failed with exit value %d" % (cmd, p))
1204 
1205 
1206 class RefCountChecker(object):
1207  """Check to make sure the number of C++ object references is as expected"""
1208 
1209  def __init__(self, testcase):
1210 # Make sure no director objects are hanging around; otherwise these
1211 # may be unexpectedly garbage collected later, decreasing the
1212 # live object count
1213  IMP._director_objects.cleanup()
1214  self.__testcase = testcase
1215  if IMP.get_check_level() >= IMP.USAGE_AND_INTERNAL:
1216  self.__basenum = IMP.Object.get_number_of_live_objects()
1217  self.__names= IMP.get_live_object_names()
1218 
1219  def assert_number(self, expected):
1220  "Make sure that the number of references matches the expected value."
1221  t = self.__testcase
1222  IMP._director_objects.cleanup()
1223  if IMP.get_check_level() >= IMP.USAGE_AND_INTERNAL:
1224  newnames=[x for x in IMP.get_live_object_names() if x not in self.__names]
1225  newnum=IMP.Object.get_number_of_live_objects()-self.__basenum
1226  t.assertEqual(newnum, expected,
1227  "Number of objects don't match: "\
1228  +str(newnum)\
1229  +" != "+ str(expected) +" found "+\
1230  str(newnames))
1231 
1232 
1233 
1235  """Check to make sure the number of director references is as expected"""
1236 
1237  def __init__(self, testcase):
1238  IMP._director_objects.cleanup()
1239  self.__testcase = testcase
1240  self.__basenum = IMP._director_objects.get_object_count()
1241 
1242  def assert_number(self, expected, force_cleanup=True):
1243  """Make sure that the number of references matches the expected value.
1244  If force_cleanup is set, clean up any unused references first before
1245  doing the assertion.
1246  """
1247  t = self.__testcase
1248  if force_cleanup:
1249  IMP._director_objects.cleanup()
1250  t.assertEqual(IMP._director_objects.get_object_count() \
1251  - self.__basenum, expected)
1252 
1253 # Make sure that the IMP binary directory (build/bin) is in the PATH, if
1254 # we're running under wine (the imppy.sh script normally ensures this, but
1255 # wine overrides the PATH). This is needed so that tests of imported Python
1256 # applications can successfully spawn C++ applications (e.g. idock.py tries
1257 # to run recompute_zscore.exe). build/lib also needs to be in the PATH, since
1258 # that's how Windows locates dependent DLLs such as libimp.dll.
1259 if sys.platform == 'win32' and 'PYTHONPATH' in os.environ \
1260  and 'IMP_BIN_DIR' in os.environ:
1261  libdir = os.environ['PYTHONPATH'].split(';')[0]
1262  bindir = os.environ['IMP_BIN_DIR']
1263  path = os.environ['PATH']
1264  if libdir not in path or bindir not in path:
1265  os.environ['PATH'] = bindir + ';' + libdir + ';' + path
1266 
1267 
1268 def get_module_version():
1269  """get_module_version() -> std::string const"""
1270  return _IMP_test.get_module_version()
1271 
1272 def get_example_path(fname):
1273  """get_example_path(std::string fname) -> std::string"""
1274  return _IMP_test.get_example_path(fname)
1275 
1276 def get_data_path(fname):
1277  """get_data_path(std::string fname) -> std::string"""
1278  return _IMP_test.get_data_path(fname)
1279 
1280 from . import _version_check
1281 _version_check.check_version(get_module_version())
1282 __version__ = get_module_version()
1283 
1284 
1285 
def run_python_module
Run a Python module as if with "python -m <modname>", with the given list of arguments as sys...
def temporary_working_directory
Simple context manager to run in a temporary directory.
def assertApplicationExitedCleanly
Assert that the application exited cleanly (return value = 0).
def check_get_from
Check that the get_from() static method works correctly.
CheckLevel get_check_level()
Get the current audit mode.
Definition: exception.h:81
def import_python_application
Import an installed Python application, rather than running it.
def open_input_file
Open and return an input file in the top-level test directory.
def run_application
Run an application with the given list of arguments.
def randomize_particles
Randomize the xyz coordinates of a list of particles.
A general exception for an internal error in IMP.
Definition: exception.h:102
def main
Run a set of tests; similar to unittest.main().
An exception for an invalid usage of IMP.
Definition: exception.h:123
Super class for simple IMP application test cases.
def assertRaisesInternalException
Assert that the given callable object raises InternalException.
std::string get_example_path(std::string file_name)
Return the full path to one of this module's example files.
def assert_number
Make sure that the number of references matches the expected value.
Check to make sure the number of director references is as expected.
def assertShow
Check that all the classes in modulename have a show method.
def run_shell_command
Print and run a shell command, as returned by read_shell_commands()
def assertRaisesUsageException
Assert that the given callable object raises UsageException.
Vector3D get_random_vector_in(const Cylinder3D &c)
Generate a random vector in a cylinder with uniform density.
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:72
def run_python_application
Run a Python application with the given list of arguments.
def assert_number
Make sure that the number of references matches the expected value.
Simple RAII-style class to run in a temporary directory.
Strings get_live_object_names()
Return the names of all live objects.
def particle_distance
Return distance between two given particles.
def check_unary_function_deriv
Check the unary function func's derivatives against numerical approximations between lb and ub...
def get_tmp_file_name
Get the full name of an output file in the tmp directory.
def run_example
Run the named example script.
def get_magnitude
Get the magnitude of a list of floats.
void set_deprecation_exceptions(bool tf)
Toggle whether an exception is thrown when a deprecated method is used.
def check_unary_function_min
Make sure that the minimum of the unary function func over the range between lb and ub is at expected...
def probabilistic_test
Help handle a test which is expected to fail some fraction of the time.
def create_particles_in_box
Create a bunch of particles in a box.
def deprecated_object
Python decorator to mark a class as deprecated.
Definition: __init__.py:9619
General purpose algebraic and geometric methods that are expected to be used by a wide variety of IMP...
def assertNotImplemented
Assert that the given callable object is not implemented.
The general base class for IMP exceptions.
Definition: exception.h:49
def numerical_derivative
Calculate the derivative of the single-value function func at point val.
std::string get_example_path(std::string file_name)
Return the full path to one of this module's example files.
def xyz_numerical_derivatives
Calculate the x,y and z derivatives of the scoring function sf on the xyz particle.
def failure_probability
Estimate how likely a given block of code is to raise an AssertionError.
VectorD< 3 > Vector3D
Definition: VectorD.h:395
def assertClassNames
Check that all the classes in the module follow the IMP naming conventions.
def create_point_particle
Make a particle with optimizable x, y and z attributes, and add it to the model.
Class to handle individual particles of a Model object.
Definition: Particle.h:41
def read_shell_commands
Read and return a set of shell commands from a doxygen file.
std::string get_data_path(std::string file_name)
Return the full path to one of this module's data files.
Check to make sure the number of C++ object references is as expected.
Simple RAII-style class to make a temporary directory.
def assertFunctionNames
Check that all the functions in the module follow the IMP naming conventions.
def assertValueObjects
Check that all the C++ classes in the module are values or objects.
Super class for IMP test cases.
def assertXYZDerivativesInTolerance
Assert that x,y,z analytical derivatives match numerical within a tolerance, or a percentage (of the ...
def temporary_directory
Simple context manager to make a temporary directory.
def run_script
Run an application with the given list of arguments.
def get_input_file_name
Get the full name of an input file in the top-level test directory.
def check_runnable_python_module
Check a Python module designed to be runnable with 'python -m' to make sure it supports standard comm...
void set_check_level(CheckLevel tf)
Control runtime checks in the code.
Definition: exception.h:73