IMP logo
IMP Reference Guide  develop.79b55d17a3,2021/04/16
The Integrative Modeling Platform
Model.h
Go to the documentation of this file.
1 /**
2  * \file IMP/Model.h
3  * \brief Storage of a model, its restraints, constraints and particles.
4  *
5  * Copyright 2007-2021 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPKERNEL_MODEL_H
10 #define IMPKERNEL_MODEL_H
11 
12 #include <IMP/kernel_config.h>
13 #include "ModelObject.h"
14 #include "ScoringFunction.h"
15 #include "Restraint.h"
16 #include "RestraintSet.h"
17 #include "ScoreState.h"
18 #include "container_macros.h"
19 #include "base_types.h"
20 //#include "Particle.h"
21 #include "Undecorator.h"
22 #include "internal/AttributeTable.h"
23 #include "internal/attribute_tables.h"
24 #include <IMP/Object.h>
25 #include <IMP/Pointer.h>
26 #include <boost/unordered_map.hpp>
27 #include <boost/unordered_set.hpp>
28 #include <IMP/tuple_macros.h>
29 #include <boost/iterator/transform_iterator.hpp>
30 #include <boost/iterator/filter_iterator.hpp>
31 
32 #include <limits>
33 
34 IMPKERNEL_BEGIN_NAMESPACE
35 
36 class ModelObject;
37 class Undecorator;
38 class Particle;
39 
40 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
41 namespace internal {
42 enum Stage {
43  NOT_EVALUATING,
44  BEFORE_EVALUATING,
45  EVALUATING,
46  AFTER_EVALUATING,
47  COMPUTING_DEPENDENCIES
48 };
49 }
50 #endif
51 
52 class Model;
53 
54 //! Class for storing model, its restraints, constraints, and particles.
55 /** The Model maintains a standard \imp container for each of Particle,
56  ScoreState and Restraint object types.
57 
58  Each Float attribute has an associated range which reflects the
59  range of values that it is expected to take on during optimization.
60  The optimizer can use these ranges to make the optimization process
61  more efficient. By default, the range estimates are simply the
62  range of values for that attribute in the various particles, but
63  it can be set to another value. For example, an attribute storing
64  an angle could have the range set to (0,PI).
65 
66  The ranges are not enforced; they are just guidelines. In order to
67  enforce ranges, see, for example,
68  IMP::example::ExampleSingletonModifier.
69 
70  \headerfile Model.h "IMP/Model.h"
71  */
72 class IMPKERNELEXPORT Model : public Object
73 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
74  ,
75  public internal::Masks,
76  // The attribute tables provide fast access to
77  // e.g. particle attributes, etc.
78  public internal::FloatAttributeTable,
79  public internal::StringAttributeTable,
80  public internal::IntAttributeTable,
81  public internal::ObjectAttributeTable,
82  public internal::WeakObjectAttributeTable,
83  public internal::IntsAttributeTable,
84  public internal::FloatsAttributeTable,
85  public internal::ObjectsAttributeTable,
86  public internal::ParticleAttributeTable,
87  public internal::ParticlesAttributeTable
88 #endif
89  {
91  // must be up top
92  // we don't want any liveness checks
93  IMP_NAMED_TUPLE_5(NodeInfo, NodeInfos, Edges, inputs, Edges, input_outputs,
94  Edges, outputs, Edges, readers, Edges, writers, );
95  typedef boost::unordered_map<const ModelObject *, NodeInfo> DependencyGraph;
96  DependencyGraph dependency_graph_;
97  boost::unordered_set<const ModelObject *> no_dependencies_;
98  boost::unordered_map<const ModelObject *, ScoreStatesTemp>
99  required_score_states_;
100 
101  // basic representation
102  boost::unordered_map<FloatKey, FloatRange> ranges_;
103 
104  ParticleIndexes free_particles_;
107 
108  Vector<PointerMember<Object> > model_data_;
109 
110  void do_add_dependencies(const ModelObject *mo);
111  void do_clear_required_score_states(ModelObject *mo);
112  void do_check_required_score_states(const ModelObject *mo) const;
113  void do_check_update_order(const ScoreState *ss) const;
114  void do_check_inputs_and_outputs(const ModelObject *mo) const;
115  void do_check_readers_and_writers(const ModelObject *mo) const;
116  void do_check_not_in_readers_and_writers(const ModelObject *mo) const;
117  void do_clear_dependencies(const ModelObject *mo);
118 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
119  // things the evaluate template functions need, can't be bothered with friends
120  public:
121 #endif
122  // check more things on the first call
123  bool first_call_;
124  // the stage of evaluation
125  internal::Stage cur_stage_;
126 
127  ModelObjectsTemp get_dependency_graph_inputs(const ModelObject *mo) const;
128  ModelObjectsTemp get_dependency_graph_outputs(const ModelObject *mo) const;
129  bool do_get_has_dependencies(const ModelObject *mo) const {
130  return no_dependencies_.find(mo) == no_dependencies_.end();
131  }
132  void do_set_has_dependencies(const ModelObject *mo, bool tf);
133  void do_set_has_all_dependencies(bool tf);
134 
135  void validate_computed_derivatives() const {}
136  void set_has_all_dependencies(bool tf);
137  bool get_has_all_dependencies() const;
138  void check_dependency_invariants() const;
139  void check_dependency_invariants(const ModelObject *mo) const;
140  ScoreStatesTemp get_ancestor_score_states(const ModelObject *mo) const;
141  ScoreStatesTemp get_descendent_score_states(const ModelObject *mo) const;
142 
143  void before_evaluate(const ScoreStatesTemp &states);
144  void after_evaluate(const ScoreStatesTemp &states, bool calc_derivs);
145 
146  internal::Stage get_stage() const { return cur_stage_; }
147  ParticleIndex add_particle_internal(Particle *p);
148  static void do_remove_score_state(ScoreState *obj);
149  void do_add_score_state(ScoreState *obj);
150  void do_remove_particle(ParticleIndex pi);
151  bool do_get_has_required_score_states(const ModelObject *mo) const;
152  void do_set_has_required_score_states(ModelObject *mo, bool tf);
153  const ScoreStatesTemp &do_get_required_score_states(const ModelObject *mo)
154  const {
155  IMP_USAGE_CHECK(do_get_has_required_score_states(mo),
156  "Doesn't have score states");
157  return required_score_states_.find(mo)->second;
158  }
159  void do_add_model_object(ModelObject *mo);
160  void do_remove_model_object(ModelObject *mo);
161 
162  public:
163  //! Construct an empty model
164  Model(std::string name = "Model %1%");
165 
166  public:
167 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
168  IMP_MODEL_IMPORT(internal::FloatAttributeTable);
169  IMP_MODEL_IMPORT(internal::StringAttributeTable);
170  IMP_MODEL_IMPORT(internal::IntAttributeTable);
171  IMP_MODEL_IMPORT(internal::ObjectAttributeTable);
172  IMP_MODEL_IMPORT(internal::WeakObjectAttributeTable);
173  IMP_MODEL_IMPORT(internal::IntsAttributeTable);
174  IMP_MODEL_IMPORT(internal::FloatsAttributeTable);
175  IMP_MODEL_IMPORT(internal::ObjectsAttributeTable);
176  IMP_MODEL_IMPORT(internal::ParticleAttributeTable);
177  IMP_MODEL_IMPORT(internal::ParticlesAttributeTable);
178 #endif
179  //! Clear all the cache attributes of a given particle.
180  void clear_particle_caches(ParticleIndex pi);
181 
182  //! Add particle to the model
183  ParticleIndex add_particle(std::string name);
184 
185  //! Get the name of a particle
186  std::string get_particle_name(ParticleIndex pi);
187 
188  //! Add the passed Undecorator to the particle.
189  void add_undecorator(ParticleIndex pi, Undecorator *d);
190 
191  /** @name States
192 
193  ScoreStates maintain invariants in the Model (see ScoreState
194  for more information.)
195 
196  ScoreStates do not need to be explictly added to the Model, but they
197  can be if desired in order to keep them alive as long as the model is
198  alive.
199 
200  \advancedmethod
201  */
202  /**@{*/
203  IMP_LIST_ACTION(public, ScoreState, ScoreStates, score_state, score_states,
204  ScoreState *, ScoreStates, do_add_score_state(obj), {},
205  do_remove_score_state(obj));
206  /**@}*/
207 
208  public:
209 #ifndef SWIG
210  using Object::clear_caches;
211 #endif
212 
213  //! Sometimes it is useful to be able to make sure the model is up to date
214  /** This method updates all the state but does not necessarily compute the
215  score. Use this to make sure that your containers and rigid bodies are
216  up to date.
217  */
218  void update();
219 
220 #ifdef IMP_DOXYGEN
221  /** \name Accessing attributes
222  \anchor model_attributes
223  All the attribute data associated with each Particle are stored in the
224  Model. For each type of attribute, there are the methods detailed below
225  (where, eg, TypeKey is FloatKey or StringKey)
226  @{
227  */
228  //! add particle atribute with the specied key and initial value
229  /** \pre get_has_attribute(attribute_key, particle) is false*/
230  void add_attribute(TypeKey attribute_key, ParticleIndex particle, Type value);
231 
232  //! remove particle attribute with the specied key
233  /** \pre get_has_attribute(attribute_key, particle) is true*/
234  void remove_attribute(TypeKey attribute_key, ParticleIndex particle);
235 
236  //! return true if particle has attribute with the specified key
237  bool get_has_attribute(TypeKey attribute_key, ParticleIndex particle) const;
238 
239  //! set the value of particle attribute with the specified key
240  /** \pre get_has_attribute(attribute_key, particle) is true*/
241  void set_attribute(TypeKey attribute_key, ParticleIndex particle, Type value);
242 
243  //! get the value of the particle attribute with the specified key
244  /** \pre get_has_attribute(attribute_key, particle) is true*/
245  Type get_attribute(TypeKey attribute_key, ParticleIndex particle);
246 
247  /** Cache attributes, unlike normal attributes, can be added during
248  evaluation. They are also cleared by the clear_cache_attributes() method.
249  Cache attributes should be used when one is adding data to a particle
250  to aid scoring (eg cache the rigid body collision acceleration structure).
251 
252  When some pertinent aspect of the particle changes, the clear method
253  should
254  be called (yes, this is a bit vague). Examples where it should be cleared
255  include changing the set of members of a core::RigidBody or their
256  coordinates, changing the members of an atom::Hierarchy.
257  */
258  void add_cache_attribute(TypeKey attribute_key, ParticleIndex particle,
259  Type value);
260 
261  //! Optimized attributes are the parameters of the model that are
262  //! allowed to be modified by samplers and optimizers
263  void set_is_optimized(TypeKey attribute_key, ParticleIndex particle,
264  bool true_or_false);
265 /** @} */
266 #endif
267 
268 #ifdef SWIG
269 #define IMP_MODEL_ATTRIBUTE_METHODS(Type, Value) \
270  void add_attribute(Type##Key attribute_key, ParticleIndex particle, \
271  Value value); \
272  void remove_attribute(Type##Key attribute_key, ParticleIndex particle); \
273  bool get_has_attribute(Type##Key attribute_key, \
274  ParticleIndex particle) const; \
275  void set_attribute(Type##Key attribute_key, ParticleIndex particle, \
276  Value value); \
277  Value get_attribute(Type##Key attribute_key, ParticleIndex particle); \
278  void add_cache_attribute(Type##Key attribute_key, ParticleIndex particle, \
279  Value value)
280 
281  IMP_MODEL_ATTRIBUTE_METHODS(Float, Float);
282  IMP_MODEL_ATTRIBUTE_METHODS(Int, Int);
283  IMP_MODEL_ATTRIBUTE_METHODS(Floats, Floats);
284  IMP_MODEL_ATTRIBUTE_METHODS(Ints, Ints);
285  IMP_MODEL_ATTRIBUTE_METHODS(String, String);
286  IMP_MODEL_ATTRIBUTE_METHODS(ParticleIndexes, ParticleIndexes);
287  IMP_MODEL_ATTRIBUTE_METHODS(ParticleIndex, ParticleIndex);
288  IMP_MODEL_ATTRIBUTE_METHODS(Object, Object *);
289  IMP_MODEL_ATTRIBUTE_METHODS(WeakObject, Object *);
290  void set_is_optimized(FloatKey, ParticleIndex, bool);
291  void add_to_derivative(FloatKey k, ParticleIndex particle, double v,
292  const DerivativeAccumulator &da);
293 #endif
294 
295  //! Get the particle from an index.
297  IMP_USAGE_CHECK(get_has_particle(p), "Invalid particle requested");
298  return particle_index_[p];
299  }
300 
301  //! Check whether a given particle index exists.
303  if (particle_index_.size() <= get_as_unsigned_int(p)) return false;
304  return particle_index_[p];
305  }
306 
307  //! Get all particle indexes
309 
310  //! Get all the ModelObjects associated with this Model.
311  ModelObjectsTemp get_model_objects() const;
312 
313  //! Remove a particle from the Model.
314  /** The particle will then be inactive and cannot be used for anything
315  and all data stored in the particle is lost.
316  */
317  void remove_particle(ParticleIndex pi);
318 
319  /** \name Storing data in the model
320 
321  One can store data associated with the model. This is used, for example,
322  to keep a central ScoreState to normalize rigid body rotational variables.
323  @{ */
324  //! Store a piece of data in the model referenced by the key.
325  void add_data(ModelKey mk, Object *o);
326  //! Get back some data stored in the model.
327  Object *get_data(ModelKey mk) const;
328  //! Remove data stored in the model.
329  void remove_data(ModelKey mk);
330  //! Check if the model has a certain piece of data attached.
331  bool get_has_data(ModelKey mk) const;
332  /** @} */
333 
335 
336  public:
337 #if !defined(IMP_DOXYGEN)
338  virtual void do_destroy() IMP_OVERRIDE;
339 #endif
340 };
341 
342 IMPKERNEL_END_NAMESPACE
343 
344 // This is needed for per cpp compilations, a not even sure why
345 // (perhaps cause Model returns ParticleIterator here and there?)
346 // - Feel free to remove if you *really* know what you're doing
347 #include "IMP/Particle.h"
348 
349 #endif /* IMPKERNEL_MODEL_H */
Particle * get_particle(ParticleIndex p) const
Get the particle from an index.
Definition: Model.h:296
Basic types used by IMP.
Used to hold a set of related restraints.
boost::graph DependencyGraph
Directed graph on the interactions between the various objects in the model.
The base class for undecorators.
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Definition: object_macros.h:25
void add_particle(RMF::FileHandle fh, Particle *hs)
Macros to help in defining tuple classes.
virtual void clear_caches()
Definition: Object.h:227
bool get_has_particle(ParticleIndex p) const
Check whether a given particle index exists.
Definition: Model.h:302
Macros to define containers of objects.
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:72
Base class for objects in a Model that depend on other objects.
Definition: ModelObject.h:26
virtual void do_destroy()
Definition: Object.h:231
Common base class for heavy weight IMP objects.
Definition: Object.h:106
ParticleIndexes get_particle_indexes(ParticlesTemp const &particles)
ScoreStates maintain invariants in the Model.
Definition: ScoreState.h:54
Implements a vector tied to a particular index of type Index<Tag>.
Definition: Index.h:57
Shared score state.
Base class for objects in a Model that depend on other objects.
Classes to handle individual model particles. (Note that implementation of inline functions is in int...
A nullptr-initialized pointer to an IMP Object.
A shared base class to help in debugging and things.
Represents a scoring function on the model.
double Float
Basic floating-point value (could be float, double...)
Definition: types.h:20
Class to handle individual particles of a Model object.
Definition: Particle.h:41
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
Definition: check_macros.h:168
Abstract base class for all restraints.
int Int
Basic integer value.
Definition: types.h:35
std::string String
Basic string value.
Definition: types.h:44
#define IMP_OVERRIDE
Cause a compile error if this method does not override a parent method.
Class for adding derivatives from restraints to the model.