IMP logo
IMP Manual  develop.d97d4ead1f,2024/11/22
Example of using the library

A complete modeling script, simple.py, written in Python, is shown below:

1 ## \example core/simple.py
2 # Illustration of simple usage of the IMP library from Python.
3 #
4 
5 import IMP
6 import IMP.algebra
7 import IMP.core
8 import sys
9 
10 IMP.setup_from_argv(sys.argv, "simple example")
11 
12 m = IMP.Model()
13 
14 # Create two "untyped" particles
15 p1 = m.add_particle('p1')
16 p2 = m.add_particle('p2')
17 
18 # "Decorate" the particles with x,y,z attributes (point-like particles)
19 d1 = IMP.core.XYZ.setup_particle(m, p1)
20 d2 = IMP.core.XYZ.setup_particle(m, p2)
21 
22 # Use some XYZ-specific functionality (set coordinates)
23 d1.set_coordinates(IMP.algebra.Vector3D(10.0, 10.0, 10.0))
24 d2.set_coordinates(IMP.algebra.Vector3D(-10.0, -10.0, -10.0))
25 print(d1, d2)
26 
27 # Harmonically restrain p1 to be zero distance from the origin
28 f = IMP.core.Harmonic(0.0, 1.0)
30 r1 = IMP.core.SingletonRestraint(m, s, p1)
31 
32 # Harmonically restrain p1 and p2 to be distance 5.0 apart
33 f = IMP.core.Harmonic(5.0, 1.0)
35 r2 = IMP.core.PairRestraint(m, s, (p1, p2))
36 
37 # Optimize the x,y,z coordinates of both particles with conjugate gradients
38 sf = IMP.core.RestraintsScoringFunction([r1, r2], "scoring function")
39 d1.set_coordinates_are_optimized(True)
40 d2.set_coordinates_are_optimized(True)
42 o.set_scoring_function(sf)
43 o.optimize(50)
44 print(d1, d2)

In the first part of the script, the IMP kernel and the algebra and core modules are loaded, as regular Python modules. We then proceed to set up the representation of the system, using the Model and Particle classes defined in the kernel. Here we give the two particles (p1 and p2) point-like attributes using the IMP::core::XYZ decorator.

In the second part, we set up the scoring of the system. We add two restraints to the Model, one of which harmonically restrains p1 to the origin and the other of which restrains p1 and p2 to be distance 5.0 apart. (IMP does not enforce any units of distance; however, some physical optimizers, such as molecular dynamics, expect distances to be in angstroms.)

Note that the core module provides suitable building block restraints for this purpose. In the first case, we use the IMP::core::SingletonRestraint class that creates a restraint on a single particle (p1). It delegates the task of actually scoring the particle, however, to another class called IMP::SingletonScore that is simply given the Particle and asked for its score. In this example, we use a type of SingletonScore called IMP::core::DistanceToSingletonScore that calculates the Cartesian distance between the point-like Particle and a fixed point (in this case the origin), and again delegates the task of scoring the distance to another class, an IMP::UnaryFunction. In this case, the UnaryFunction is a simple harmonic function, IMP::core::Harmonic, with a mean of zero. Thus, the Particle p1 is harmonically restrained to be at the origin. The second restraint is set up similarly; however, in this case the restraints and scores act on a pair of particles. This building block functionality makes it easy to add a new type of restraint; for example, to implement a van der Waals potential it is only necessary to provide a suitable PairScore that scores a single pair of particles; the functionality for efficiently enumerating all pairs of such particles is already provided in IMP.

Finally, in the third part of the script, we tell IMP that it can move the two point-like particles, and to build a system configuration that is consistent with all the restraints. In this example, a simple conjugate gradients optimization is used.

The script is a regular Python script. Thus, provided that both IMP and Python are installed, it can be run on any machine, by typing on a command line, in the same directory as the script:

python simple.py

The script will run the optimization, printing IMP log messages as it goes, and finally print the coordinates of the optimized particles.

IMP is designed such that the C++ and Python interfaces are similar to use. Thus, IMP applications or protocols can be constructed either in C++ or in Python, and new IMP functionality (for example, new types of Restraint) can be implemented in either language. For a comparison, please inspect the simple.cpp file below. This file implements the same protocol as the first part of simple.py but uses the IMP C++ classes rather than their Python equivalents. The two programs are very similar; the only differences are in the language syntax (eg, the Python 'import IMP.algebra' translates to '#include <IMP/algebra.h>' in C++) and in memory handling (Python handles memory automatically; in C++, memory handling must be done explicitly by using the IMP::Pointer class or the IMP_NEW macro, which adds reference counting to automatically clean up after IMP objects when they are no longer in use).

/** \example core/simple.cpp
Simple example of using the IMP C++ library.
This should be equivalent to the first part of the Python example simple.py.
*/
#include <fstream>
#include <IMP.h>
#include <IMP/algebra.h>
#include <IMP/core.h>
#include <IMP/flags.h>
int main(int argc, char *argv[]) {
IMP::setup_from_argv(argc, argv,
"Simple example of using the IMP C++ library.");
// Create two "untyped" particles
IMP::ParticleIndex p1 = m->add_particle("p1");
IMP::ParticleIndex p2 = m->add_particle("p2");
// "Decorate" the particles with x,y,z attributes (point-like
// particles)
IMP::core::XYZ d1 = IMP::core::XYZ::setup_particle(m, p1);
IMP::core::XYZ d2 = IMP::core::XYZ::setup_particle(m, p2);
// Use some XYZ-specific functionality (set coordinates)
d1.set_coordinates(IMP::algebra::Vector3D(10.0, 10.0, 10.0));
d2.set_coordinates(IMP::algebra::Vector3D(-10.0, -10.0, -10.0));
std::cout << d1 << " " << d2 << std::endl;
return 0;
}