1 Overview {#library_overview}
6 The %IMP library provides tools to implement the computational parts of
7 the [integrative modeling iterative process](@ref procedure) (steps 2-4).
8 %IMP is primarily implemented in C++
for speed; however, each of the classes
9 is wrapped so that it can also be used from Python. A protocol can thus
10 be developed from scratch by simply writing a Python script.
11 The examples below will use Python scripts.
13 # Modular structure of IMP {#overview_modular}
15 Functionality in %IMP is grouped into modules, each with its own
16 namespace (in C++) or package (in Python). For %example, the functionality
17 for IMP::core can be found like
27 A module contains classes, methods and data which are related.
28 The top-level "%IMP", otherwise known as the %IMP kernel, is a small
29 collection of classes that define the storage of information about the system
30 and the main interfaces used to interact with that information. However, in
31 most cases the kernel does not provide actual implementations of these classes;
32 these are provided in other modules.
33 For example, it merely defines a [Restraint](@ref IMP::Restraint)
34 as any
object that, given a set of particles, returns a score, and an
35 [Optimizer](@ref IMP::Optimizer) as an
object that changes the
36 attributes of all particles to yield an optimized score over all restraints.
37 It is the [core module](@ref IMP::core) that provides, for example, a
38 [concrete Restraint](@ref IMP::core::DistanceRestraint) that acts like a
39 harmonic 'spring' between two point-like particles, an Optimizer that
40 [utilizes the conjugate gradients minimization method](@ref IMP::core::ConjugateGradients),
41 and much other functionality.
43 Other %IMP modules provide the basic building blocks needed to construct
44 a protocol, such as the [atom module](@ref IMP::atom) that
45 provides atom-like particles, a molecular dynamics optimizer, etc.
46 Other modules provide support for specific types of experimental data
47 or specialized optimizers, such as the [em module](@ref IMP::em) that
48 supports electron microscopy data, and the [domino module](@ref IMP::domino)
49 that provides an inference-based divide-and-conquer optimizer.
50 [Many other modules are available](../ref/namespaces.html)
51 in this version of %IMP.
53 %IMP is designed so that it is easy to add a new module; for example,
54 a developer working on incorporating data from a new experimental
55 technique may add a new %IMP module that translates the data from this
56 technique into spatial restraints.
58 # Representation: IMP::Model {#overview_representation}
60 In IMP, the system is represented by the
IMP::Model class, which stores
61 a collection of
"particles", each of which is a
62 flexible and
abstract data container, able to hold whatever information is
63 necessary to represent the system. For example, a given particle may be
64 assigned x, y, and z attributes to store point coordinates, another may be
65 assigned x, y, z, and a radius to represent a sphere, and another may
66 contain two pointers to other particles to represent a bond or another
69 In IMP, particle attributes can be numbers, strings, or lists of other
70 particles, among other things. Each particle is identified by an index
72 it easier to understand. Finally, attributes are identified by keys
73 (e.g. IMP::
StringKey for
string attributes). The key identifies one type of
74 data that may be contained in many particles.
76 At the most basic, to create particles and manipulate attributes you can do
80 particle_0= model.add_particle("my first particle")
81 string_key = IMP.
StringKey("my first data")
82 model.add_attribute(string_key, particle_0, "Hi, particle 0")
84 particle_1= model.add_particle("my second particle")
85 model.add_attribute(string_key, particle_1, "Hi, particle 1")
87 print(model.get_attribute(string_key, particle_0))
89 Certain of the attributes can be marked as parameters of the model. These
90 are attributes that you want to sample or optimize. To do so you can do
91 model.set_is_optimized(float_key, particle_0)
93 \note A lot of %IMP uses IMP::Particle objects instead of IMP::
ParticleIndex objects to identify particles. They should be treated as roughly the same. To map from an index to a particle you use IMP::Model::get_particle() and to go the other way IMP::Particle::get_index(). Using the indexes is preferred. When doing it on lists, you can use IMP::get_indexes() and IMP::get_particles().
95 # Decorators {#overview_decorators}
97 Accessing all your data at such a low level can
get tiresome, so we provide
98 decorators to make it easier. Each type of decorator provides an interface
99 to manipulate a particular type of data. For example, an IMP.atom.Residue
100 decorator provides access to residue associated information (e.g. the index
101 of the residue, or its type) in particles that have it.
103 residue= IMP.atom.Residue(model, my_residue)
104 print(residue.get_residue_type())
106 Multiple decorators can be applied to a single particle,
if appropriate;
107 for example, an atom-like particle could be treated like a
112 Decorators provide a standard
interface to add their data to a particle,
113 decorate a particle that already has the needed data or check if a particle
114 is appropriate to have the decorator used with it.
116 # add coordinates to a particle
117 decorated_particle = IMP.core.XYZ.setup_particle(model, my_particle,
118 IMP.algebra.Vector3D(1,2,3))
119 print(decorated_particle.get_coordinates())
121 # my_other_particle has already been set up, so we can just decorate
123 another_decorated_particle = IMP.core.XYZ(model, my_other_particle)
124 print(another_decorated_particle.get_coordinates())
126 # we can change the coordinates too
127 another_decorated_particle.set_coordinates(IMP.algebra.Vector3D(5,4,3))
129 (
Vector3D is a simple %IMP
class that represents a 3D vector, or point.
130 The IMP::algebra module contains many such general purpose algebraic and
131 geometric methods and classes.)
133 Decorators can also be used to create relationships between particles.
135 decorator. Each rigid body has a collection of other particles that move
136 along with it, each of which is decorated with the
139 # Representing biological molecules {#overview_biomolecules}
141 Biological modules are represented hierarchically in IMP
using the
IMP::atom::Hierarchy. These hierarchies follow the natural hierarchical nature of most biomolecules. A protein from a PDB would be a hierarchy with a root
for the whole PDB file with a child per chain. Each chain particle has a child
for each residue in the chain, and each residue has a child
for each atom. Each particle has various types of associated data. For example an atom has data
using the
IMP::atom::Atom,
IMP::core::XYZR,
IMP::atom::Mass and
IMP::atom::Hierarchy decorators.
143 The structures represented
do not have to be atomic and can be multi-resolution - that is, they can have coordinates at any level of the hierarchy. The invariants are that the leaves must have coordinates, radii and mass. Pieces of the hierarchy can be picked out
using IMP::atom::Selection using the standard sorts of biological criteria:
145 # Select residues 10 through 49.
146 my_residues= IMP.atom.
Selection(my_pdb, residue_indexes=range(10,50)).get_particles()
149 # Containers {#overview_containers}
151 You can manipulate and maintain collections of particles
using IMP::Container. A collection can be anything from a list of particles gathered manually, to all pairs of particles from some list that are closer than a certain distance to one another. For example, to maintain a list of all close pairs of particles you can
do
153 # all particle pairs closer than 3A
154 # it is always good to give things names; that is what the last argument does
155 close_pairs= IMP.container.ClosePairContainer(all_my_particles, 3,
"My close pairs")
157 These containers can then be used to create scoring functions or analyze the data.
159 #
Constraints and Invariants {#overview_constraints}
161 Many things such as rigid bodies and lists of all close pairs depend on maintaining some
property as the model changes. These properties are maintained by
IMP::Constraint objects. Since the invariants may depend on things that are reasonably expensive to compute, these invariants are updated only when requested. This means that
if you change the coordinates of some particles, the contents of the close pairs list might be incorrect until it is updated. The required update can be triggered implicitly,
for example when some scoring
function needs it, or explicitly, when
IMP::Model::update() is called.
163 Behind the scenes, IMP maintains an IMP::
DependencyGraph that tracks how information flows between the particles and the containers, based on the constraints. It is used to detect, for example, that a particular particle is part of a rigid body, and so if its coordinates are needed for scoring, the rigid body must be brought up to date and the appropriate constraint must be asked to update the member particle's coordinates. In order to be able to track this information, relevant objects (IMP::ModelObject) have methods IMP::ModelObject::get_inputs() and IMP::ModelObject::get_outputs() that return the things that are read and written respectively.
165 # Scoring {#overview_scoring}
167 One then needs to be able to evaluate how well the current configuration of the model fits
this data that one is
using to model. In addition to scores, when requested derivatives of the total score as a
function of each parameter can be computed.
171 An
IMP::Restraint computes a score on some set of particles. For example, a restraint be used to penalize configurations of the model that have collisions
173 # penalize collisions with a spring constant of 10 kcal/mol/A
174 soft_sphere_pair_score= IMP.core.SoftSpherePairScore(10)
175 my_excluded_volume_restraint= IMP.container.PairsRestraint(soft_sphere_pair_score,
179 \note Many restraints (including
this one) are made more flexible by delegating
181 See the [example script](@ref library_example)
for an %example.
185 ## Scoring functions {#overview_scoring_functions}
188 is simply the sum of its terms (restraints). You can create many different
189 scoring functions
for different purposes and each restraint can be part
190 of multiple scoring functions.
192 my_scoring_function= IMP.core.RestraintsScoringFunction([my_excluded_volume_restraint],
193 "score excluded volume")
195 \note You will see old example code that, instead of creating an
IMP::ScoringFunction, adds the restraints to the model. This creates an implicit scoring
function consisting of all the restraints so added. But it should not be done in
new code.
197 # Sampling {#overview_sampling}
199 It is now time to find configurations of the model that score well with
200 regards to the scoring
function you developed. %IMP provides a number of
205 An
IMP::Optimizer takes the current configuration of the model and perturbs it,
206 typically trying to make it better (but perhaps just into a different
207 configuration following some rule, such as
209 function you provide to guide the process.
211 my_optimizer= IMP.core.ConjugateGradients(m)
212 my_optimizer.set_scoring_function(my_scoring_function)
213 my_optimizer.optimize(1000)
215 \note In old code, the scoring
function may not be explicitly set on the optimizer. The optimizer then uses the implicit scoring
function in the IMP::Model. This shouldn
't be done in new code as it is a bit error prone and may become an error at some point.
217 Optionally, you can use an IMP::Sampler, which uses an IMP::Optimizer to
218 produce a set of configurations of the model using some sampling scheme.
220 # Storing and analysis {#overview_analsysis}
222 Configurations of the model can be saved and visualized in a variety of ways. Atomic structures can be written as PDB files using IMP::atom::write_pdb(). More flexibly, coarse grained models, geometry and information about the scoring function can be written to [RMF files](https://integrativemodeling.org/rmf).
224 my_rmf= RMF.create_rmf_file("my.rmf")
225 IMP.rmf.add_hierarchy(my_rmf, my_hierarchy)
226 IMP.rmf.add_restraint(my_rmf, my_excluded_volume_restraint)
227 IMP.rmf.save_frame(my_rmf)
229 # Further reading {#overview_further}
231 For more information on the various %IMP classes and modules, see the
232 [Reference Guide](../ref/).
Selection(Hierarchy hierarchy=None, Hierarchies hierarchies=[], Strings molecules=[], Ints residue_indexes=[], Strings chain_ids=[], AtomTypes atom_types=[], ResidueTypes residue_types=[], Strings domains=[], double resolution=0, RepresentationType representation_type=IMP.atom.BALLS, std::string molecule=None, int residue_index=None, std::string chain_id=None, AtomType atom_type=None, ResidueType residue_type=None, Ints hierarchy_types=None, Element element=None, Terminus terminus=None, std::string domain=None, core::ParticleType particle_type=None, core::ParticleTypes particle_types=[], int copy_index=-1, Ints copy_indexes=[], int state_index=-1, Ints state_indexes=[])
boost::graph DependencyGraph
Index< ParticleIndexTag > ParticleIndex