IMP logo
IMP Reference Guide  2.8.0
The Integrative Modeling Platform
modeller/__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_modeller')).lstrip('.')
21  try:
22  return importlib.import_module(mname)
23  except ImportError:
24  return importlib.import_module('_IMP_modeller')
25  _IMP_modeller = 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_modeller', [dirname(__file__)])
34  except ImportError:
35  import _IMP_modeller
36  return _IMP_modeller
37  if fp is not None:
38  try:
39  _mod = imp.load_module('_IMP_modeller', fp, pathname, description)
40  finally:
41  fp.close()
42  return _mod
43  _IMP_modeller = swig_import_helper()
44  del swig_import_helper
45 else:
46  import _IMP_modeller
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_MODELLER_SwigPyIterator(object):
114  """Proxy of C++ swig::IMP_MODELLER_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_modeller.delete_IMP_MODELLER_SwigPyIterator
122  __del__ = lambda self: None
123 
124  def value(self):
125  """value(IMP_MODELLER_SwigPyIterator self) -> PyObject *"""
126  return _IMP_modeller.IMP_MODELLER_SwigPyIterator_value(self)
127 
128 
129  def incr(self, n=1):
130  """
131  incr(IMP_MODELLER_SwigPyIterator self, size_t n=1) -> IMP_MODELLER_SwigPyIterator
132  incr(IMP_MODELLER_SwigPyIterator self) -> IMP_MODELLER_SwigPyIterator
133  """
134  return _IMP_modeller.IMP_MODELLER_SwigPyIterator_incr(self, n)
135 
136 
137  def decr(self, n=1):
138  """
139  decr(IMP_MODELLER_SwigPyIterator self, size_t n=1) -> IMP_MODELLER_SwigPyIterator
140  decr(IMP_MODELLER_SwigPyIterator self) -> IMP_MODELLER_SwigPyIterator
141  """
142  return _IMP_modeller.IMP_MODELLER_SwigPyIterator_decr(self, n)
143 
144 
145  def distance(self, x):
146  """distance(IMP_MODELLER_SwigPyIterator self, IMP_MODELLER_SwigPyIterator x) -> ptrdiff_t"""
147  return _IMP_modeller.IMP_MODELLER_SwigPyIterator_distance(self, x)
148 
149 
150  def equal(self, x):
151  """equal(IMP_MODELLER_SwigPyIterator self, IMP_MODELLER_SwigPyIterator x) -> bool"""
152  return _IMP_modeller.IMP_MODELLER_SwigPyIterator_equal(self, x)
153 
154 
155  def copy(self):
156  """copy(IMP_MODELLER_SwigPyIterator self) -> IMP_MODELLER_SwigPyIterator"""
157  return _IMP_modeller.IMP_MODELLER_SwigPyIterator_copy(self)
158 
159 
160  def next(self):
161  """next(IMP_MODELLER_SwigPyIterator self) -> PyObject *"""
162  return _IMP_modeller.IMP_MODELLER_SwigPyIterator_next(self)
163 
164 
165  def __next__(self):
166  """__next__(IMP_MODELLER_SwigPyIterator self) -> PyObject *"""
167  return _IMP_modeller.IMP_MODELLER_SwigPyIterator___next__(self)
168 
169 
170  def previous(self):
171  """previous(IMP_MODELLER_SwigPyIterator self) -> PyObject *"""
172  return _IMP_modeller.IMP_MODELLER_SwigPyIterator_previous(self)
173 
174 
175  def advance(self, n):
176  """advance(IMP_MODELLER_SwigPyIterator self, ptrdiff_t n) -> IMP_MODELLER_SwigPyIterator"""
177  return _IMP_modeller.IMP_MODELLER_SwigPyIterator_advance(self, n)
178 
179 
180  def __eq__(self, x):
181  """__eq__(IMP_MODELLER_SwigPyIterator self, IMP_MODELLER_SwigPyIterator x) -> bool"""
182  return _IMP_modeller.IMP_MODELLER_SwigPyIterator___eq__(self, x)
183 
184 
185  def __ne__(self, x):
186  """__ne__(IMP_MODELLER_SwigPyIterator self, IMP_MODELLER_SwigPyIterator x) -> bool"""
187  return _IMP_modeller.IMP_MODELLER_SwigPyIterator___ne__(self, x)
188 
189 
190  def __iadd__(self, n):
191  """__iadd__(IMP_MODELLER_SwigPyIterator self, ptrdiff_t n) -> IMP_MODELLER_SwigPyIterator"""
192  return _IMP_modeller.IMP_MODELLER_SwigPyIterator___iadd__(self, n)
193 
194 
195  def __isub__(self, n):
196  """__isub__(IMP_MODELLER_SwigPyIterator self, ptrdiff_t n) -> IMP_MODELLER_SwigPyIterator"""
197  return _IMP_modeller.IMP_MODELLER_SwigPyIterator___isub__(self, n)
198 
199 
200  def __add__(self, n):
201  """__add__(IMP_MODELLER_SwigPyIterator self, ptrdiff_t n) -> IMP_MODELLER_SwigPyIterator"""
202  return _IMP_modeller.IMP_MODELLER_SwigPyIterator___add__(self, n)
203 
204 
205  def __sub__(self, *args):
206  """
207  __sub__(IMP_MODELLER_SwigPyIterator self, ptrdiff_t n) -> IMP_MODELLER_SwigPyIterator
208  __sub__(IMP_MODELLER_SwigPyIterator self, IMP_MODELLER_SwigPyIterator x) -> ptrdiff_t
209  """
210  return _IMP_modeller.IMP_MODELLER_SwigPyIterator___sub__(self, *args)
211 
212  def __iter__(self):
213  return self
214 IMP_MODELLER_SwigPyIterator_swigregister = _IMP_modeller.IMP_MODELLER_SwigPyIterator_swigregister
215 IMP_MODELLER_SwigPyIterator_swigregister(IMP_MODELLER_SwigPyIterator)
216 
217 
218 _value_types=[]
219 _object_types=[]
220 _raii_types=[]
221 _plural_types=[]
222 
223 IMP_DEBUG = _IMP_modeller.IMP_DEBUG
224 IMP_RELEASE = _IMP_modeller.IMP_RELEASE
225 IMP_SILENT = _IMP_modeller.IMP_SILENT
226 IMP_PROGRESS = _IMP_modeller.IMP_PROGRESS
227 IMP_TERSE = _IMP_modeller.IMP_TERSE
228 IMP_VERBOSE = _IMP_modeller.IMP_VERBOSE
229 IMP_MEMORY = _IMP_modeller.IMP_MEMORY
230 IMP_NONE = _IMP_modeller.IMP_NONE
231 IMP_USAGE = _IMP_modeller.IMP_USAGE
232 IMP_INTERNAL = _IMP_modeller.IMP_INTERNAL
233 IMP_KERNEL_HAS_LOG4CXX = _IMP_modeller.IMP_KERNEL_HAS_LOG4CXX
234 IMP_COMPILER_HAS_AUTO = _IMP_modeller.IMP_COMPILER_HAS_AUTO
235 IMP_COMPILER_HAS_DEBUG_VECTOR = _IMP_modeller.IMP_COMPILER_HAS_DEBUG_VECTOR
236 IMP_COMPILER_HAS_UNIQUE_PTR = _IMP_modeller.IMP_COMPILER_HAS_UNIQUE_PTR
237 IMP_KERNEL_HAS_BOOST_RANDOM = _IMP_modeller.IMP_KERNEL_HAS_BOOST_RANDOM
238 IMP_KERNEL_HAS_GPERFTOOLS = _IMP_modeller.IMP_KERNEL_HAS_GPERFTOOLS
239 IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER = _IMP_modeller.IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER
240 IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER = _IMP_modeller.IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER
241 IMPKERNEL_SHOW_WARNINGS = _IMP_modeller.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_modeller._ostream_write(self, osa_buf)
281 
282 _ostream_swigregister = _IMP_modeller._ostream_swigregister
283 _ostream_swigregister(_ostream)
284 
285 IMP_COMPILER_HAS_OVERRIDE = _IMP_modeller.IMP_COMPILER_HAS_OVERRIDE
286 IMP_COMPILER_HAS_FINAL = _IMP_modeller.IMP_COMPILER_HAS_FINAL
287 IMP_HAS_NOEXCEPT = _IMP_modeller.IMP_HAS_NOEXCEPT
288 import IMP
289 IMP_CGAL_HAS_BOOST_FILESYSTEM = _IMP_modeller.IMP_CGAL_HAS_BOOST_FILESYSTEM
290 IMP_CGAL_HAS_BOOST_PROGRAMOPTIONS = _IMP_modeller.IMP_CGAL_HAS_BOOST_PROGRAMOPTIONS
291 IMP_CGAL_HAS_BOOST_RANDOM = _IMP_modeller.IMP_CGAL_HAS_BOOST_RANDOM
292 IMP_CGAL_HAS_BOOST_SYSTEM = _IMP_modeller.IMP_CGAL_HAS_BOOST_SYSTEM
293 IMPCGAL_SHOW_WARNINGS = _IMP_modeller.IMPCGAL_SHOW_WARNINGS
294 import IMP.cgal
295 IMP_ALGEBRA_HAS_IMP_CGAL = _IMP_modeller.IMP_ALGEBRA_HAS_IMP_CGAL
296 IMP_ALGEBRA_HAS_BOOST_FILESYSTEM = _IMP_modeller.IMP_ALGEBRA_HAS_BOOST_FILESYSTEM
297 IMP_ALGEBRA_HAS_BOOST_PROGRAMOPTIONS = _IMP_modeller.IMP_ALGEBRA_HAS_BOOST_PROGRAMOPTIONS
298 IMP_ALGEBRA_HAS_BOOST_RANDOM = _IMP_modeller.IMP_ALGEBRA_HAS_BOOST_RANDOM
299 IMP_ALGEBRA_HAS_BOOST_SYSTEM = _IMP_modeller.IMP_ALGEBRA_HAS_BOOST_SYSTEM
300 IMP_ALGEBRA_HAS_CGAL = _IMP_modeller.IMP_ALGEBRA_HAS_CGAL
301 IMP_ALGEBRA_HAS_ANN = _IMP_modeller.IMP_ALGEBRA_HAS_ANN
302 IMPALGEBRA_SHOW_WARNINGS = _IMP_modeller.IMPALGEBRA_SHOW_WARNINGS
303 import IMP.algebra
304 IMP_DISPLAY_HAS_IMP_CGAL = _IMP_modeller.IMP_DISPLAY_HAS_IMP_CGAL
305 IMP_DISPLAY_HAS_BOOST_FILESYSTEM = _IMP_modeller.IMP_DISPLAY_HAS_BOOST_FILESYSTEM
306 IMP_DISPLAY_HAS_BOOST_PROGRAMOPTIONS = _IMP_modeller.IMP_DISPLAY_HAS_BOOST_PROGRAMOPTIONS
307 IMP_DISPLAY_HAS_BOOST_RANDOM = _IMP_modeller.IMP_DISPLAY_HAS_BOOST_RANDOM
308 IMP_DISPLAY_HAS_BOOST_SYSTEM = _IMP_modeller.IMP_DISPLAY_HAS_BOOST_SYSTEM
309 IMP_DISPLAY_HAS_CGAL = _IMP_modeller.IMP_DISPLAY_HAS_CGAL
310 IMPDISPLAY_SHOW_WARNINGS = _IMP_modeller.IMPDISPLAY_SHOW_WARNINGS
311 import IMP.display
312 IMP_SCORE_FUNCTOR_HAS_IMP_CGAL = _IMP_modeller.IMP_SCORE_FUNCTOR_HAS_IMP_CGAL
313 IMP_SCORE_FUNCTOR_HAS_BOOST_FILESYSTEM = _IMP_modeller.IMP_SCORE_FUNCTOR_HAS_BOOST_FILESYSTEM
314 IMP_SCORE_FUNCTOR_HAS_BOOST_PROGRAMOPTIONS = _IMP_modeller.IMP_SCORE_FUNCTOR_HAS_BOOST_PROGRAMOPTIONS
315 IMP_SCORE_FUNCTOR_HAS_BOOST_RANDOM = _IMP_modeller.IMP_SCORE_FUNCTOR_HAS_BOOST_RANDOM
316 IMP_SCORE_FUNCTOR_HAS_BOOST_SYSTEM = _IMP_modeller.IMP_SCORE_FUNCTOR_HAS_BOOST_SYSTEM
317 IMP_SCORE_FUNCTOR_HAS_CGAL = _IMP_modeller.IMP_SCORE_FUNCTOR_HAS_CGAL
318 IMP_SCORE_FUNCTOR_HAS_HDF5 = _IMP_modeller.IMP_SCORE_FUNCTOR_HAS_HDF5
319 IMPSCOREFUNCTOR_SHOW_WARNINGS = _IMP_modeller.IMPSCOREFUNCTOR_SHOW_WARNINGS
320 import IMP.score_functor
321 IMP_CORE_HAS_IMP_CGAL = _IMP_modeller.IMP_CORE_HAS_IMP_CGAL
322 IMP_CORE_HAS_IMP_KERNEL = _IMP_modeller.IMP_CORE_HAS_IMP_KERNEL
323 IMP_CORE_HAS_BOOST_FILESYSTEM = _IMP_modeller.IMP_CORE_HAS_BOOST_FILESYSTEM
324 IMP_CORE_HAS_BOOST_PROGRAMOPTIONS = _IMP_modeller.IMP_CORE_HAS_BOOST_PROGRAMOPTIONS
325 IMP_CORE_HAS_BOOST_RANDOM = _IMP_modeller.IMP_CORE_HAS_BOOST_RANDOM
326 IMP_CORE_HAS_BOOST_SYSTEM = _IMP_modeller.IMP_CORE_HAS_BOOST_SYSTEM
327 IMP_CORE_HAS_CGAL = _IMP_modeller.IMP_CORE_HAS_CGAL
328 IMP_CORE_HAS_HDF5 = _IMP_modeller.IMP_CORE_HAS_HDF5
329 IMPCORE_SHOW_WARNINGS = _IMP_modeller.IMPCORE_SHOW_WARNINGS
330 import IMP.core
331 IMP_MODELLER_HAS_IMP_ALGEBRA = _IMP_modeller.IMP_MODELLER_HAS_IMP_ALGEBRA
332 IMP_MODELLER_HAS_IMP_CGAL = _IMP_modeller.IMP_MODELLER_HAS_IMP_CGAL
333 IMP_MODELLER_HAS_IMP_DISPLAY = _IMP_modeller.IMP_MODELLER_HAS_IMP_DISPLAY
334 IMP_MODELLER_HAS_IMP_KERNEL = _IMP_modeller.IMP_MODELLER_HAS_IMP_KERNEL
335 IMP_MODELLER_HAS_IMP_SCORE_FUNCTOR = _IMP_modeller.IMP_MODELLER_HAS_IMP_SCORE_FUNCTOR
336 IMP_MODELLER_HAS_BOOST_FILESYSTEM = _IMP_modeller.IMP_MODELLER_HAS_BOOST_FILESYSTEM
337 IMP_MODELLER_HAS_BOOST_PROGRAMOPTIONS = _IMP_modeller.IMP_MODELLER_HAS_BOOST_PROGRAMOPTIONS
338 IMP_MODELLER_HAS_BOOST_RANDOM = _IMP_modeller.IMP_MODELLER_HAS_BOOST_RANDOM
339 IMP_MODELLER_HAS_BOOST_SYSTEM = _IMP_modeller.IMP_MODELLER_HAS_BOOST_SYSTEM
340 IMP_MODELLER_HAS_CGAL = _IMP_modeller.IMP_MODELLER_HAS_CGAL
341 IMP_MODELLER_HAS_HDF5 = _IMP_modeller.IMP_MODELLER_HAS_HDF5
342 IMPMODELLER_SHOW_WARNINGS = _IMP_modeller.IMPMODELLER_SHOW_WARNINGS
343 
344 
345 import math
346 import imp
347 import os
348 import sys
349 import tempfile
350 import shutil
351 import IMP.atom
352 import IMP.container
353 import modeller.scripts
354 import modeller.optimizers
355 
356 class _TempDir(object):
357  """Make a temporary directory that is deleted when the object is."""
358 
359  def __init__(self):
360  self.tmpdir = tempfile.mkdtemp()
361 
362  def __del__(self):
363  shutil.rmtree(self.tmpdir, ignore_errors=True)
364 
365 
366 class IMPRestraints(modeller.terms.energy_term):
367  """A Modeller restraint which evaluates an IMP scoring function.
368  This can be used to incorporate IMP Restraints into an existing
369  comparative modeling pipeline, or to use Modeller optimizers or
370  protocols.
371  """
372 
373  _physical_type = modeller.physical.absposition
374 
375  def __init__(self, particles, scoring_function=None):
376  """Constructor.
377  @param particles A list of the IMP atoms (as Particle objects),
378  same order as the Modeller atoms.
379  @param scoring_function An IMP::ScoringFunction object that will
380  be incorporated into the Modeller score (molpdf).
381  @note since Modeller, unlike IMP, is sensitive to the ordering
382  of atoms, it usually makes sense to create the model in
383  Modeller and then use ModelLoader to load it into IMP,
384  since that will preserve the Modeller atom ordering in IMP.
385  """
386  modeller.terms.energy_term.__init__(self)
387  self._particles = particles
388  if scoring_function:
389  self._sf = scoring_function
390  else:
391  self._sf = particles[0].get_model()
392 
393  def eval(self, mdl, deriv, indats):
394  atoms = self.indices_to_atoms(mdl, indats)
395  _copy_modeller_coords_to_imp(atoms, self._particles)
396  if len(self._particles) == 0:
397  score = 0.
398  else:
399  score = self._sf.evaluate(deriv)
400  if deriv:
401  dvx = [0.] * len(indats)
402  dvy = [0.] * len(indats)
403  dvz = [0.] * len(indats)
404  _get_imp_derivs(self._particles, dvx, dvy, dvz)
405  return (score, dvx, dvy, dvz)
406  else:
407  return score
408 
409 
411  """An IMP restraint using all defined Modeller restraints.
412  This is useful if you want to use Modeller restraints with an IMP
413  optimizer, or in combination with IMP restraints.
414 
415  @note Currently only the coordinates of the atoms are translated
416  between Modeller and IMP; thus, a Modeller restraint which
417  uses any other attribute (e.g. charge) will not react if
418  this attribute is changed by IMP.
419  """
420 
421  def __init__(self, model, modeller_model, particles):
422  """Constructor.
423  @param model The IMP Model object.
424  @param modeller_model The Modeller model object.
425  @param particles A list of the IMP atoms (as Particle objects),
426  in the same order as the Modeller atoms.
427  @note since Modeller, unlike IMP, is sensitive to the ordering
428  of atoms, it usually makes sense to create the model in
429  Modeller and then use ModelLoader to load it into IMP,
430  since that will preserve the Modeller atom ordering in IMP.
431  """
432  def get_particle(x):
433  if hasattr(x, 'get_particle'):
434  return x.get_particle()
435  else:
436  return x
437  IMP.Restraint.__init__(self, model, "ModellerRestraints %1%")
438  self._modeller_model = modeller_model
439  self._particles = [get_particle(x) for x in particles]
440 
441  def unprotected_evaluate(self, accum):
442  atoms = self._modeller_model.atoms
443  sel = modeller.selection(self._modeller_model)
444  _copy_imp_coords_to_modeller(self._particles, atoms)
445  energies = sel.energy()
446  if accum:
447  _add_modeller_derivs_to_imp(atoms, self._particles, accum)
448 
449  return energies[0]
450 
451  def get_version_info(self):
452  return IMP.VersionInfo("IMP developers", "0.1")
453  def do_show(self, fh):
454  fh.write("ModellerRestraints")
455  def do_get_inputs(self):
456  return self._particles
457 
458 
459 def _copy_imp_coords_to_modeller(particles, atoms):
460  """Copy atom coordinates from IMP to Modeller"""
461  xkey = IMP.FloatKey("x")
462  ykey = IMP.FloatKey("y")
463  zkey = IMP.FloatKey("z")
464  for (num, at) in enumerate(atoms):
465  at.x = particles[num].get_value(xkey)
466  at.y = particles[num].get_value(ykey)
467  at.z = particles[num].get_value(zkey)
468 
469 
470 def _copy_modeller_coords_to_imp(atoms, particles):
471  """Copy atom coordinates from Modeller to IMP"""
472  xkey = IMP.FloatKey("x")
473  ykey = IMP.FloatKey("y")
474  zkey = IMP.FloatKey("z")
475  for (num, at) in enumerate(atoms):
476  particles[num].set_value(xkey, at.x)
477  particles[num].set_value(ykey, at.y)
478  particles[num].set_value(zkey, at.z)
479 
480 
481 def _add_modeller_derivs_to_imp(atoms, particles, accum):
482  """Add atom derivatives from Modeller to IMP"""
483  for (num, at) in enumerate(atoms):
484  xyz = IMP.core.XYZ(particles[num])
485  xyz.add_to_derivative(0, at.dvx, accum)
486  xyz.add_to_derivative(1, at.dvy, accum)
487  xyz.add_to_derivative(2, at.dvz, accum)
488 
489 
490 def _get_imp_derivs(particles, dvx, dvy, dvz):
491  """Move atom derivatives from IMP to Modeller"""
492  xkey = IMP.FloatKey("x")
493  ykey = IMP.FloatKey("y")
494  zkey = IMP.FloatKey("z")
495  for idx in range(0, len(dvx)):
496  dvx[idx] = particles[idx].get_derivative(xkey)
497  dvy[idx] = particles[idx].get_derivative(ykey)
498  dvz[idx] = particles[idx].get_derivative(zkey)
499 
500 
501 # Generators to create IMP UnaryFunction objects from Modeller parameters:
502 def _HarmonicLowerBoundGenerator(parameters, modalities):
503  (mean, stdev) = parameters
505  return IMP.core.HarmonicLowerBound(mean, k)
506 
507 def _HarmonicUpperBoundGenerator(parameters, modalities):
508  (mean, stdev) = parameters
510  return IMP.core.HarmonicUpperBound(mean, k)
511 
512 def _HarmonicGenerator(parameters, modalities):
513  (mean, stdev) = parameters
515  return IMP.core.Harmonic(mean, k)
516 
517 def _CosineGenerator(parameters, modalities):
518  (phase, force_constant) = parameters
519  (periodicity,) = modalities
520  return IMP.core.Cosine(force_constant, periodicity, phase)
521 
522 def _LinearGenerator(parameters, modalities):
523  (scale,) = parameters
524  return IMP.core.Linear(0, scale)
525 
526 def _SplineGenerator(parameters, modalities):
527  (open, low, high, delta, lowderiv, highderiv) = parameters[:6]
528  values = []
529  for v in parameters[6:]:
530  values.append(v)
531  if open < 0.0:
532  return IMP.core.ClosedCubicSpline(values, low, delta)
533  else:
534  return IMP.core.OpenCubicSpline(values, low, delta)
535 
536 #: Mapping from Modeller math form number to a unary function generator
537 _unary_func_generators = {
538  1: _HarmonicLowerBoundGenerator,
539  2: _HarmonicUpperBoundGenerator,
540  3: _HarmonicGenerator,
541  7: _CosineGenerator,
542  8: _LinearGenerator,
543  10: _SplineGenerator,
544 }
545 
546 # Generators to make IMP Restraint objects from Modeller features
547 def _DistanceRestraintGenerator(form, modalities, atoms, parameters):
548  unary_func_gen = _unary_func_generators[form]
549  return IMP.core.DistanceRestraint(atoms[0].get_model(),
550  unary_func_gen(parameters, modalities),
551  atoms[0], atoms[1])
552 
553 def _AngleRestraintGenerator(form, modalities, atoms, parameters):
554  unary_func_gen = _unary_func_generators[form]
555  return IMP.core.AngleRestraint(atoms[0].get_model(),
556  unary_func_gen(parameters, modalities),
557  atoms[0], atoms[1], atoms[2])
558 
559 def _MultiBinormalGenerator(form, modalities, atoms, parameters):
560  nterms = modalities[0]
561  if len(parameters) != nterms * 6:
562  raise ValueError("Incorrect number of parameters (%d) for multiple "
563  "binormal restraint - expecting %d (%d terms * 6)" \
564  % (len(parameters), nterms * 6, nterms))
565  r = IMP.core.MultipleBinormalRestraint(atoms[0].get_model(),
566  atoms[:4], atoms[4:8])
567  for i in range(nterms):
569  t.set_weight(parameters[i])
570  t.set_means((parameters[nterms + i * 2],
571  parameters[nterms + i * 2 + 1]))
572  t.set_standard_deviations((parameters[nterms * 3 + i * 2],
573  parameters[nterms * 3 + i * 2 + 1]))
574  t.set_correlation(parameters[nterms * 5 + i])
575  r.add_term(t)
576  return r
577 
578 def _DihedralRestraintGenerator(form, modalities, atoms, parameters):
579  if form == 9:
580  return _MultiBinormalGenerator(form, modalities, atoms, parameters)
581  unary_func_gen = _unary_func_generators[form]
582  return IMP.core.DihedralRestraint(atoms[0].get_model(),
583  unary_func_gen(parameters, modalities),
584  atoms[0], atoms[1], atoms[2], atoms[3])
585 
586 def _get_protein_atom_particles(protein):
587  """Given a protein particle, get the flattened list of all child atoms"""
588  atom_particles = []
589  for ichain in range(protein.get_number_of_children()):
590  chain = protein.get_child(ichain)
591  for ires in range(chain.get_number_of_children()):
592  residue = chain.get_child(ires)
593  for iatom in range(residue.get_number_of_children()):
594  atom = residue.get_child(iatom)
595  atom_particles.append(atom.get_particle())
596  return atom_particles
597 
598 def _load_restraints_line(line, atom_particles):
599  """Parse a single Modeller restraints file line and return the
600  corresponding IMP restraint."""
601  spl = line.split()
602  typ = spl.pop(0)
603  if typ == 'MODELLER5':
604  return
605  elif typ != 'R':
606  raise NotImplementedError("Only 'R' lines currently read from " + \
607  "Modeller restraints files")
608  form = int(spl.pop(0))
609  modalities = [int(spl.pop(0))]
610  features = [int(spl.pop(0))]
611 # Discard group
612  spl.pop(0)
613  natoms = [int(spl.pop(0))]
614  nparam = int(spl.pop(0))
615  nfeat = int(spl.pop(0))
616  for i in range(nfeat - 1):
617  modalities.append(int(spl.pop(0)))
618  features.append(int(spl.pop(0)))
619  natoms.append(int(spl.pop(0)))
620  atoms = [int(spl.pop(0)) for x in range(natoms[0])]
621  for i in range(len(atoms)):
622  atoms[i] = atom_particles[atoms[i] - 1]
623  parameters = [float(spl.pop(0)) for x in range(nparam)]
624  restraint_generators = {
625  1 : _DistanceRestraintGenerator,
626  2 : _AngleRestraintGenerator,
627  3 : _DihedralRestraintGenerator,
628  }
629  restraint_gen = restraint_generators[features[0]]
630  return restraint_gen(form, modalities, atoms, parameters)
631 
632 
633 def _load_entire_restraints_file(filename, protein):
634  """Yield a set of IMP restraints from a Modeller restraints file."""
635  atoms = _get_protein_atom_particles(protein)
636  fh = open(filename, 'r')
637  for line in fh:
638  try:
639  rsr = _load_restraints_line(line, atoms)
640  if rsr is not None:
641  yield rsr
642  except Exception as err:
643  print("Cannot read restraints file line:\n" + line)
644  raise
645 
646 
647 def _copy_residue(r, model):
648  """Copy residue information from modeller to imp"""
649 #print "residue "+str(r)
650  p=IMP.Particle(model)
652  r.index)
653  p.set_name(str("residue "+r.num));
654  return p
655 
656 
657 def _copy_atom(a, model):
658  """Copy atom information from modeller"""
659 #print "atom "+str(a)
660  p=IMP.Particle(model)
662  xyzd= IMP.core.XYZ.setup_particle(p, IMP.algebra.Vector3D(a.x, a.y, a.z))
663 # Alignment structures don't have charges or atom types; models do
664  if hasattr(a, 'charge'):
666  if hasattr(a, 'type'):
667  IMP.atom.CHARMMAtom.setup_particle(p, a.type.name)
668  ap.set_input_index(a.index)
669  return p
670 
671 def _copy_chain(c, model):
672  """Copy chain information from modeller"""
673 #print "atom "+str(a)
674  p=IMP.Particle(model)
675 #set the chain name
676  cp = IMP.atom.Chain.setup_particle(p,c.name)
677  return p
678 
679 def _get_forcefield(submodel):
680  if submodel == 3:
682  IMP.atom.get_data_path('top_heav.lib'),
683  IMP.atom.get_data_path('par.lib'))
684  else:
686  IMP.atom.get_data_path('top.lib'),
687  IMP.atom.get_data_path('par.lib'))
688  return ff
689 
690 def add_soft_sphere_radii(hierarchy, submodel, scale=1.0, filename=None):
691  """Add radii to the hierarchy using the Modeller radius library, radii.lib.
692  Each radius is scaled by the given scale (Modeller usually scales radii
693  by a factor of 0.82). submodel specifies the topology submodel, which is
694  the column in radii.lib to use."""
695  if filename is None:
696  filename = IMP.atom.get_data_path('radii.lib')
697  radii = {}
698  for line in open(filename):
699  if line.startswith('#'): continue
700  spl = line.split()
701  if len(spl) > 11:
702  radii[spl[0]] = float(spl[submodel])
703  atoms = IMP.atom.get_by_type(hierarchy, IMP.atom.ATOM_TYPE)
704  for a in atoms:
705  p = a.get_particle()
706  ct = IMP.atom.CHARMMAtom(p).get_charmm_type()
707  if ct in radii:
708  IMP.core.XYZR.setup_particle(p, radii[ct] * scale)
709 
710 
711 class ModelLoader(object):
712  """Read a Modeller model into IMP. After creating this object, the atoms
713  in the Modeller model can be loaded into IMP using the load_atoms()
714  method, then optionally any Modeller static restraints can be read in
715  with load_static_restraints() or load_static_restraints_file().
716 
717  This class can also be used to read Modeller alignment structures;
718  however, only load_atoms() will be useful in such a case (since
719  alignment structures don't have restraints or other information).
720 
721  """
722 
723  def __init__(self, modeller_model):
724  """Constructor.
725  @param modeller_model The Modeller model or alignment structure
726  object to read.
727  """
728  self._modeller_model = modeller_model
729 
730  def load_atoms(self, model):
731  """Construct an IMP::atom::Hierarchy that contains the same atoms as
732  the Modeller model or alignment structure.
733 
734  IMP atoms created from a Modeller model will be given charges and
735  CHARMM types, extracted from the model. Alignment structures don't
736  contain this information, so the IMP atoms won't either.
737 
738  @param model The IMP::Model object in which the hierarchy will be
739  created. The highest level hierarchy node is a PROTEIN.
740  @return the newly-created root IMP::atom::Hierarchy.
741  """
742  pp = IMP.Particle(model)
744  self._atoms = {}
745  for chain in self._modeller_model.chains:
746  cp = IMP.Particle(model)
747  hcp = IMP.atom.Chain.setup_particle(cp, chain.name)
748 # We don't really know the type yet
749  hpp.add_child(hcp)
750  for residue in chain.residues:
751  rp = _copy_residue(residue, model)
752  hrp = IMP.atom.Hierarchy(rp)
753  hcp.add_child(hrp)
754  for atom in residue.atoms:
755  ap = _copy_atom(atom, model)
756  hap = IMP.atom.Hierarchy(ap)
757  hrp.add_child(hap)
758  self._atoms[atom.index] = ap
759  lastres = hrp
760  self._modeller_hierarchy = hpp
761  return hpp
762 
763  def _get_nonbonded_list(self, atoms, pair_filter, edat, distance):
764  nbl = IMP.container.ClosePairContainer(atoms, distance,
765  edat.update_dynamic)
766 
767 # Exclude the same sets of atoms as Modeller
768  if pair_filter is None:
769  pair_filter = IMP.atom.StereochemistryPairFilter()
770  if edat.excl_local[0]:
771  pair_filter.set_bonds(list(self.load_bonds()))
772  if edat.excl_local[1]:
773  pair_filter.set_angles(list(self.load_angles()))
774  if edat.excl_local[2]:
775  pair_filter.set_dihedrals(list(self.load_dihedrals()))
776  nbl.add_pair_filter(pair_filter)
777  return nbl
778 
779  def load_bonds(self):
780  """Load the Modeller bond topology into the IMP model. Each bond is
781  represented in IMP as an IMP::atom::Bond, with no defined length
782  or stiffness. These bonds are primarily useful as input to
783  IMP::atom::StereochemistryPairFilter, to exclude bond interactions
784  from the nonbonded list. Typically the contribution to the scoring
785  function from the bonds is included in the Modeller static restraints
786  (use load_static_restraints() or load_static_restraints_file() to
787  load these). If you want to regenerate the stereochemistry in IMP,
788  do not use these functions (as then stereochemistry scoring terms
789  and exclusions would be double-counted) and instead use the
790  IMP::atom::CHARMMTopology class.
791 
792  You must call load_atoms() prior to using this function.
793  @see load_angles(), load_dihedrals(), load_impropers()
794  @return A generator listing all of the bonds.
795  """
796  if not hasattr(self, '_modeller_hierarchy'):
797  raise ValueError("Call load_atoms() first.")
798  for (maa, mab) in self._modeller_model.bonds:
799  pa = self._atoms[maa.index]
800  pb = self._atoms[mab.index]
802  ba= IMP.atom.Bonded(pa)
803  else:
806  bb= IMP.atom.Bonded(pb)
807  else:
809  yield IMP.atom.create_bond(ba, bb,
810  IMP.atom.Bond.SINGLE).get_particle()
811 
812  def load_angles(self):
813  """Load the Modeller angle topology into the IMP model.
814  See load_bonds() for more details."""
815  return self._internal_load_angles(self._modeller_model.angles,
817 
818  def load_dihedrals(self):
819  """Load the Modeller dihedral topology into the IMP model.
820  See load_bonds() for more details."""
821  return self._internal_load_angles(self._modeller_model.dihedrals,
823 
824  def load_impropers(self):
825  """Load the Modeller improper topology into the IMP model.
826  See load_bonds() for more details."""
827  return self._internal_load_angles(self._modeller_model.impropers,
829 
830  def _internal_load_angles(self, angles, angle_class):
831  if not hasattr(self, '_modeller_hierarchy'):
832  raise ValueError("Call load_atoms() first.")
833  for modeller_atoms in angles:
834  imp_particles = [self._atoms[x.index] for x in modeller_atoms]
835  p = IMP.Particle(imp_particles[0].get_model())
836  a = angle_class.setup_particle(p,
837  *[IMP.core.XYZ(x) for x in imp_particles])
838  yield a.get_particle()
839 
840  def load_static_restraints_file(self, filename):
841  """Convert a Modeller static restraints file into equivalent
842  IMP::Restraints. load_atoms() must have been called first to read
843  in the atoms that the restraints will act upon.
844  @param filename Name of the Modeller restraints file. The restraints
845  in this file are assumed to act upon the model read in by
846  load_atoms(); no checking is done to enforce this.
847  @return A Python generator of the newly-created IMP::Restraint
848  objects.
849  """
850  if not hasattr(self, '_modeller_hierarchy'):
851  raise ValueError("Call load_atoms() first.")
852  return _load_entire_restraints_file(filename, self._modeller_hierarchy)
853 
854 
856  """Convert the current set of Modeller static restraints into equivalent
857  IMP::Restraints. load_atoms() must have been called first to read
858  in the atoms that the restraints will act upon.
859  @return A Python generator of the newly-created IMP::Restraint
860  objects.
861  """
862  class _RestraintGenerator(object):
863  """Simple generator wrapper"""
864  def __init__(self, gen):
865  self._gen = gen
866  def __iter__(self, *args, **keys):
867  return self
868  def close(self, *args, **keys):
869  return self._gen.close(*args, **keys)
870  def next(self):
871  return next(self._gen)
872  __next__ = next
873  def send(self, *args, **keys):
874  return self._gen.send(*args, **keys)
875  def throw(self, *args, **keys):
876  return self._gen.throw(*args, **keys)
877 # Write current restraints into a temporary file
878  t = _TempDir()
879  rsrfile = os.path.join(t.tmpdir, 'restraints.rsr')
880  self._modeller_model.restraints.write(file=rsrfile)
881 # Read the file back in
882  gen = self.load_static_restraints_file(rsrfile)
883  wrap = _RestraintGenerator(gen)
884 # Ensure that tmpdir remains until we're done with the generator
885  wrap._tempdir = t
886  return wrap
887 
888  def load_dynamic_restraints(self, pair_filter=None):
889  """Convert Modeller dynamic restraints into IMP::Restraint objects.
890 
891  For each currently active Modeller dynamic restraint
892  (e.g. soft-sphere, electrostatics) an equivalent IMP::Restraint
893  is created.
894  load_atoms() must have been called first to read
895  in the atoms that the restraints will act upon.
896 
897  If pair_filter is given, it is an IMP::PairFilter object to exclude
898  pairs from the nonbonded lists used by the dynamic restraints.
899  Otherwise, an IMP::atom::StereochemistryPairFilter object is created
900  to exclude Modeller bonds, angles and dihedrals, as specified by
901  edat.excl_local. (Note that this calls load_bonds(), load_angles()
902  and load_dihedrals(), so will create duplicate lists of bonds if
903  those methods are called manually as well.)
904 
905  @note Currently only soft-sphere, electrostatic and Lennard-Jones
906  restraints are loaded.
907  @return A Python generator of the newly-created IMP::Restraint
908  objects.
909  """
910  if not hasattr(self, '_modeller_hierarchy'):
911  raise ValueError("Call load_atoms() first.")
912  edat = self._modeller_model.env.edat
913  libs = self._modeller_model.env.libs
914  atoms = IMP.atom.get_leaves(self._modeller_hierarchy)
915  m = atoms[0].get_model()
917 
918  if edat.dynamic_sphere:
919 # Note: cannot use Modeller's cutoff distance, as that is
920 # center-to-center; IMP's is sphere surface-surface
921  nbl = self._get_nonbonded_list(atoms, pair_filter, edat, 0.)
922 # No way to get Modeller radii, so we have to reassign them
923  add_soft_sphere_radii(self._modeller_hierarchy,
924  libs.topology.submodel, edat.radii_factor)
925  k = \
929  yield IMP.container.PairsRestraint(ps, nbl)
930 
931  if edat.dynamic_lennard or edat.dynamic_coulomb:
932 # 3.0 is roughly the max. atom diameter
933  d = max(edat.contact_shell - 3.0, 0.0)
934  nbl = self._get_nonbonded_list(atoms, pair_filter, edat, d)
935  ff = _get_forcefield(libs.topology.submodel)
936  ff.add_radii(self._modeller_hierarchy)
937 
938  if edat.dynamic_lennard:
939  ff.add_well_depths(self._modeller_hierarchy)
940  sf = IMP.atom.ForceSwitch(edat.lennard_jones_switch[0],
941  edat.lennard_jones_switch[1])
943  yield IMP.container.PairsRestraint(ps, nbl)
944 
945  if edat.dynamic_coulomb:
946  sf = IMP.atom.ForceSwitch(edat.coulomb_switch[0],
947  edat.coulomb_switch[1])
949  ps.set_relative_dielectric(edat.relative_dielectric)
950  yield IMP.container.PairsRestraint(ps, nbl)
951 
952 
953 
954 def get_module_version():
955  """get_module_version() -> std::string const"""
956  return _IMP_modeller.get_module_version()
957 
958 def get_example_path(fname):
959  """get_example_path(std::string fname) -> std::string"""
960  return _IMP_modeller.get_example_path(fname)
961 
962 def get_data_path(fname):
963  """get_data_path(std::string fname) -> std::string"""
964  return _IMP_modeller.get_data_path(fname)
965 
966 from . import _version_check
967 _version_check.check_version(get_module_version())
968 __version__ = get_module_version()
969 
970 
971 
static CHARMMAtom setup_particle(Model *m, ParticleIndex pi, String charmm_type)
Definition: CHARMMAtom.h:37
static Charged setup_particle(Model *m, ParticleIndex pi, Float charge)
Definition: Charged.h:46
Lower bound harmonic function (non-zero when feature < mean)
def load_static_restraints
Convert the current set of Modeller static restraints into equivalent IMP::Restraints.
std::string get_example_path(std::string file_name)
Return the full path to one of this module's example files.
def load_bonds
Load the Modeller bond topology into the IMP model.
A Modeller restraint which evaluates an IMP scoring function.
Coulomb (electrostatic) score between a pair of particles.
static Atom setup_particle(Model *m, ParticleIndex pi, Atom other)
Definition: atom/Atom.h:242
Various classes to hold sets of particles.
Upper bound harmonic function (non-zero when feature > mean)
static XYZR setup_particle(Model *m, ParticleIndex pi)
Definition: XYZR.h:48
A decorator for a particle which has bonds.
def load_impropers
Load the Modeller improper topology into the IMP model.
Make CGAL functionality available to IMP.
Cosine function.
Definition: Cosine.h:22
std::string get_data_path(std::string file_name)
Return the full path to one of this module's data files.
Dihedral restraint between four particles.
def load_static_restraints_file
Convert a Modeller static restraints file into equivalent IMP::Restraints.
The type of an atom.
A score on the distance between the surfaces of two spheres.
Return all close unordered pairs of particles taken from the SingletonContainer.
static Residue setup_particle(Model *m, ParticleIndex pi, ResidueType t, int index, int insertion_code)
Definition: Residue.h:157
A single binormal term in a MultipleBinormalRestraint.
def load_dynamic_restraints
Convert Modeller dynamic restraints into IMP::Restraint objects.
Distance restraint between two particles.
static XYZ setup_particle(Model *m, ParticleIndex pi)
Definition: XYZ.h:51
Composable functors to implement scores via compile-time composition.
An IMP restraint using all defined Modeller restraints.
CHARMM force field parameters.
Bond create_bond(Bonded a, Bonded b, Bond o)
Connect the two wrapped particles by a custom bond.
def load_dihedrals
Load the Modeller dihedral topology into the IMP model.
static Float get_k_from_standard_deviation(Float sd, Float t=297.15)
Return the k to use for a given Gaussian standard deviation.
Definition: core/Harmonic.h:62
Angle restraint between three particles.
static Hierarchy setup_particle(Model *m, ParticleIndex pi, ParticleIndexesAdaptor children=ParticleIndexesAdaptor())
Create a Hierarchy of level t by adding the needed attributes.
ParticleIndexPairs get_indexes(const ParticlePairsTemp &ps)
Lennard-Jones score between a pair of particles.
A particle that describes an angle between three particles.
The standard decorator for manipulating molecular structures.
Store a list of ParticleIndexes.
static Bonded setup_particle(Model *m, ParticleIndex pi)
The type for a residue.
def load_atoms
Construct an IMP::atom::Hierarchy that contains the same atoms as the Modeller model or alignment str...
Version and module information for Objects.
Definition: VersionInfo.h:28
A decorator for a particle with x,y,z coordinates.
Definition: XYZ.h:30
Modeller-style multiple binormal (phi/psi) restraint.
Linear function
Definition: Linear.h:19
def add_soft_sphere_radii
Add radii to the hierarchy using the Modeller radius library, radii.lib.
A particle that describes a dihedral angle between four particles.
def load_angles
Load the Modeller angle topology into the IMP model.
Basic functionality that is expected to be used by a wide variety of IMP users.
General purpose algebraic and geometric methods that are expected to be used by a wide variety of IMP...
static bool get_is_setup(const IMP::ParticleAdaptor &p)
virtual VersionInfo get_version_info() const
Get information about the module and version of the object.
Definition: Object.h:173
VectorD< 3 > Vector3D
Definition: VectorD.h:395
A filter that excludes bonds, angles and dihedrals.
Read a Modeller model into IMP.
Class to handle individual particles of a Model object.
Definition: Particle.h:41
std::string get_data_path(std::string file_name)
Return the full path to one of this module's data files.
Smooth interaction scores by switching the derivatives (force switch).
Output IMP model data in various file formats.
Functionality for loading, creating, manipulating and scoring atomic structures.
static Chain setup_particle(Model *m, ParticleIndex pi, std::string id)
Definition: Chain.h:41
Hierarchies get_leaves(const Selection &h)
Applies a PairScore to each Pair in a list.
virtual ModelObjectsTemp do_get_inputs() const =0
Closed cubic spline function.
A decorator for an atom that has a defined CHARMM type.
Definition: CHARMMAtom.h:24
A restraint is a term in an IMP ScoringFunction.
Definition: Restraint.h:52
Harmonic function (symmetric about the mean)
Definition: core/Harmonic.h:24