IMP  2.3.0
The Integrative Modeling Platform
kernel/Model.h
Go to the documentation of this file.
1 /**
2  * \file IMP/kernel/Model.h
3  * \brief Storage of a model, its restraints,
4  * constraints and particles.
5  *
6  * Copyright 2007-2014 IMP Inventors. All rights reserved.
7  *
8  */
9 
10 #ifndef IMPKERNEL_MODEL_H
11 #define IMPKERNEL_MODEL_H
12 
13 #include <IMP/kernel/kernel_config.h>
14 #include "ModelObject.h"
15 #include "ScoringFunction.h"
16 #include "Restraint.h"
17 #include "RestraintSet.h"
18 #include "ScoreState.h"
19 #include "container_macros.h"
20 #include "base_types.h"
21 //#include "Particle.h"
22 #include "Undecorator.h"
23 #include "internal/AttributeTable.h"
24 #include "internal/attribute_tables.h"
25 #include <IMP/base/Object.h>
26 #include <IMP/base/Pointer.h>
27 #include <boost/unordered_map.hpp>
28 #include <boost/unordered_set.hpp>
29 #include <IMP/base/tuple_macros.h>
30 #include <boost/iterator/transform_iterator.hpp>
31 #include <boost/iterator/filter_iterator.hpp>
32 
33 #include <limits>
34 
35 IMPKERNEL_BEGIN_NAMESPACE
36 
37 class ModelObject;
38 class Undecorator;
39 class Particle;
40 
41 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
42 namespace internal {
43 enum Stage {
44  NOT_EVALUATING,
45  BEFORE_EVALUATING,
46  EVALUATING,
47  AFTER_EVALUATING,
48  COMPUTING_DEPENDENCIES
49 };
50 }
51 #endif
52 
53 class Model;
54 
55 //! Class for storing model, its restraints, constraints, and particles.
56 /** The Model maintains a standard \imp container for each of Particle,
57  ScoreState and Restraint object types.
58 
59  Each Float attribute has an associated range which reflects the
60  range of values that it is expected to take on during optimization.
61  The optimizer can use these ranges to make the optimization process
62  more efficient. By default, the range estimates are simply the
63  range of values for that attribute in the various particles, but
64  it can be set to another value. For example, an attribute storing
65  an angle could have the range set to (0,PI).
66 
67  The ranges are not enforced; they are just guidelines. In order to
68  enforce ranges, see, for example,
69  IMP::example::ExampleSingletonModifier.
70 
71  \headerfile Model.h "IMP/Model.h"
72  */
73 class IMPKERNELEXPORT Model : public base::Object
74 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
75  ,
76  public internal::Masks,
77  // The attribute tables provide fast access to
78  // e.g. particle attributes, etc.
79  public internal::FloatAttributeTable,
80  public internal::StringAttributeTable,
81  public internal::IntAttributeTable,
82  public internal::ObjectAttributeTable,
83  public internal::WeakObjectAttributeTable,
84  public internal::IntsAttributeTable,
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 
109  ////////////// DEPRECATED
110  // for old code that uses the model for the scoring function
112 
113  void do_add_dependencies(const ModelObject *mo);
114  void do_clear_required_score_states(kernel::ModelObject *mo);
115  void do_check_required_score_states(const ModelObject *mo) const;
116  void do_check_update_order(const ScoreState *ss) const;
117  void do_check_inputs_and_outputs(const ModelObject *mo) const;
118  void do_check_readers_and_writers(const ModelObject *mo) const;
119  void do_check_not_in_readers_and_writers(const ModelObject *mo) const;
120  void do_clear_dependencies(const ModelObject *mo);
121 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
122  // things the evaluate template functions need, can't be bothered with friends
123  public:
124 #endif
125  // check more things on the first call
126  bool first_call_;
127  // the stage of evaluation
128  internal::Stage cur_stage_;
129 
130  ModelObjectsTemp get_dependency_graph_inputs(const ModelObject *mo) const;
131  ModelObjectsTemp get_dependency_graph_outputs(const ModelObject *mo) const;
132  bool do_get_has_dependencies(const ModelObject *mo) const {
133  return no_dependencies_.find(mo) == no_dependencies_.end();
134  }
135  void do_set_has_dependencies(const ModelObject *mo, bool tf);
136  void do_set_has_all_dependencies(bool tf);
137 
138  void validate_computed_derivatives() const {}
139  void set_has_all_dependencies(bool tf);
140  bool get_has_all_dependencies() const;
141  void check_dependency_invariants() const;
142  void check_dependency_invariants(const ModelObject *mo) const;
143  ScoreStatesTemp get_ancestor_score_states(const ModelObject *mo) const;
144  ScoreStatesTemp get_descendent_score_states(const ModelObject *mo) const;
145 
146  void before_evaluate(const ScoreStatesTemp &states);
147  void after_evaluate(const ScoreStatesTemp &states, bool calc_derivs);
148 
149  internal::Stage get_stage() const { return cur_stage_; }
150  ParticleIndex add_particle_internal(Particle *p);
151  static void do_remove_score_state(ScoreState *obj);
152  void do_add_score_state(ScoreState *obj);
153  void do_remove_particle(ParticleIndex pi);
154  bool do_get_has_required_score_states(const ModelObject *mo) const;
155  void do_set_has_required_score_states(kernel::ModelObject *mo, bool tf);
156  const ScoreStatesTemp &do_get_required_score_states(const ModelObject *mo)
157  const {
158  IMP_USAGE_CHECK(do_get_has_required_score_states(mo),
159  "Doesn't have score states");
160  return required_score_states_.find(mo)->second;
161  }
162  void do_add_model_object(kernel::ModelObject *mo);
163  void do_remove_model_object(kernel::ModelObject *mo);
164 
165  public:
166  /** Construct an empty model */
167  Model(std::string name = "Model %1%");
168 
169  public:
170 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
171  IMP_MODEL_IMPORT(internal::FloatAttributeTable);
172  IMP_MODEL_IMPORT(internal::StringAttributeTable);
173  IMP_MODEL_IMPORT(internal::IntAttributeTable);
174  IMP_MODEL_IMPORT(internal::ObjectAttributeTable);
175  IMP_MODEL_IMPORT(internal::WeakObjectAttributeTable);
176  IMP_MODEL_IMPORT(internal::IntsAttributeTable);
177  IMP_MODEL_IMPORT(internal::ObjectsAttributeTable);
178  IMP_MODEL_IMPORT(internal::ParticleAttributeTable);
179  IMP_MODEL_IMPORT(internal::ParticlesAttributeTable);
180 #endif
181  /** Clear all the cache attributes of a given particle.*/
182  void clear_particle_caches(ParticleIndex pi);
183 
184  //! Add particle to the model
185  ParticleIndex add_particle(std::string name);
186 
187  //! Get the name of a particle
188  std::string get_particle_name(ParticleIndex pi);
189 
190  /** Add the passed Undecorator to the particle.*/
191  void add_undecorator(ParticleIndex pi, Undecorator *d);
192 
193  /** @name States
194 
195  ScoreStates can be added to the Model in order to keep them
196  alive as long as the model is alive. Being added does affect
197  their ability to perform their required action. See ScoreState
198  for more information.
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 is 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  /** \pre get_has_attribute(attribute_key, particle) is false*/
229  void add_attribute(TypeKey attribute_key, ParticleIndex particle, Type value);
230 
231  /** \pre get_has_attribute(attribute_key, particle) is true*/
232  void remove_attribute(TypeKey attribute_key, ParticleIndex particle);
233 
234  bool get_has_attribute(TypeKey attribute_key, ParticleIndex particle) const;
235 
236  /** \pre get_has_attribute(attribute_key, particle) is true*/
237  void set_attribute(TypeKey attribute_key, ParticleIndex particle, Type value);
238 
239  /** \pre get_has_attribute(attribute_key, particle) is true*/
240  Type get_attribute(TypeKey attribute_key, ParticleIndex particle);
241 
242  /** Cache attributes, unklike normal attributes, can be added during
243  evaluation. They are also cleared by the clear_cache_attributes() method.
244  Cache attributes should be used when one is adding data to a particle
245  to aid scoring (eg cache the rigid body collision acceleration structure).
246 
247  When some pertinent aspect of the particle changes, the clear method
248  should
249  be called (yes, this is a bit vague). Examples where it should be cleared
250  include changing the set of members of a core::RigidBody or their
251  coordinates, changing the members of an atom::Hierarchy.
252  */
253  void add_cache_attribute(TypeKey attribute_key, ParticleIndex particle,
254  Type value);
255 
256  //! Optimized attributes are the parameters of the model
257  /** They will be modified by the samplers and optimizers.
258  */
259  void set_is_optimized(TypeKey attribute_key, ParticleIndex particle,
260  bool true_or_false);
261 /** @} */
262 #endif
263 
264 #ifdef SWIG
265 #define IMP_MODEL_ATTRIBUTE_METHODS(Type, Value) \
266  void add_attribute(Type##Key attribute_key, ParticleIndex particle, \
267  Value value); \
268  void remove_attribute(Type##Key attribute_key, ParticleIndex particle); \
269  bool get_has_attribute(Type##Key attribute_key, \
270  ParticleIndex particle) const; \
271  void set_attribute(Type##Key attribute_key, ParticleIndex particle, \
272  Value value); \
273  Value get_attribute(Type##Key attribute_key, ParticleIndex particle); \
274  void add_cache_attribute(Type##Key attribute_key, ParticleIndex particle, \
275  Value value)
276 
277  IMP_MODEL_ATTRIBUTE_METHODS(Float, Float);
278  IMP_MODEL_ATTRIBUTE_METHODS(Int, Int);
279  IMP_MODEL_ATTRIBUTE_METHODS(Ints, Ints);
280  IMP_MODEL_ATTRIBUTE_METHODS(String, String);
281  IMP_MODEL_ATTRIBUTE_METHODS(ParticleIndexes, ParticleIndexes);
282  IMP_MODEL_ATTRIBUTE_METHODS(ParticleIndex, ParticleIndex);
283  IMP_MODEL_ATTRIBUTE_METHODS(Object, Object *);
284  IMP_MODEL_ATTRIBUTE_METHODS(WeakObject, Object *);
285  void set_is_optimized(FloatKey, ParticleIndex, bool);
286 #endif
287 
288  /** Get the particle from an index. */
289  Particle *get_particle(ParticleIndex p) const;
290 
291  /** Get the particle from an index. */
292  bool get_has_particle(ParticleIndex p) const;
293 
294  /** Get all particle indexes */
295  ParticleIndexes get_particle_indexes();
296 
297  /** Get all the ModelObjects associated with this Model.
298  */
299  ModelObjectsTemp get_model_objects() const;
300 
301  /** Remove a particle from the Model. The particle will then be inactive and
302  cannot be used for anything and all data stored in the particle is lost.
303  */
304  void remove_particle(ParticleIndex pi);
305 
306  /** \name Storing data in the model
307 
308  One can store data associated with the model. This is used, for example,
309  to keep a central ScoreState to normalize rigid body rotational variables.
310  @{ */
311  /** Store a piece of data in the model referenced by the key. */
312  void add_data(kernel::ModelKey mk, base::Object *o);
313  /** Get back some data stored in the model. */
314  base::Object *get_data(kernel::ModelKey mk) const;
315  /** Remove data stored in the model. */
316  void remove_data(kernel::ModelKey mk);
317  /** Check if the model has a certain piece of data attached. */
318  bool get_has_data(kernel::ModelKey mk) const;
319  /** @} */
320 
322 
323  public:
324 // deprecated
325 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
326  struct NotNull {
327  bool operator()(const base::Pointer<Particle> &p) { return p; }
328  };
329  typedef boost::filter_iterator<
330  NotNull, base::Vector<base::Pointer<Particle> >::const_iterator>
331  ParticleIterator;
332 #endif
333 
334 // all deprecated but too used to add warnings about now
335 #if !defined(IMP_DOXYGEN)
336  ScoringFunction *create_model_scoring_function();
337  void add_restraint(Restraint *r);
338  void remove_restraint(Restraint *r);
341  virtual void do_destroy() IMP_OVERRIDE;
342 #endif
343 
344  /** \deprecated_at{2.1} Use a RestraintSet instead.*/
345  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
346  unsigned int get_number_of_restraints() const;
347  /** \deprecated_at{2.1} Use a RestraintSet instead.*/
348  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
349  Restraint *get_restraint(unsigned int i) const;
350  /** \deprecated_at{2.1} Use a ScoringFunction instead.*/
351  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
352  double evaluate(bool tf, bool warn = true);
353  /** \deprecated_at{2.1} Use the ParticleIndex version.*/
354  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
355  void remove_particle(Particle *p);
356  /** \deprecated_at{2.1} Use get_particle_indexes(). */
357  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
358  unsigned int get_number_of_particles() const;
359  /** \deprecated_at{2.1} Use get_particle_indexes(). */
360  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
361  ParticlesTemp get_particles() const;
362  /** \deprecated_at{2.1} Using a ScoringFunction instead. */
363  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
364  RestraintSet *get_root_restraint_set();
365  /** \deprecated_at{2.1} Get the maximum directly from the restraint.*/
366  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
367  double get_maximum_score(Restraint *r) const;
368  /** \deprecated_at{2.1} Set get the maximum directly on the restraint.*/
369  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
370  void set_maximum_score(Restraint *r, double s);
371  /** \deprecated_at{2.1} You should use a ScoringFunction or a RestraintSet.*/
372  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
373  void set_maximum_score(double s);
374  /** \deprecated_at{2.1} You should use a ScoringFunction or a RestraintSet.*/
375  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
376  double get_maximum_score() const;
377 #ifndef SWIG
378  /** \deprecated_at{2.1} Use get_particle_indexes(). */
379  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
380  ParticleIterator particles_begin() const;
381  /** \deprecated_at{2.1} Use get_particle_indexes(). */
382  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
383  ParticleIterator particles_end() const;
384  /** \deprecated_at{2.1} Use a ScoringFunction instead. */
385  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
386  operator Restraint *() const { return restraints_.get(); }
387 #endif
388 };
389 
390 IMPKERNEL_END_NAMESPACE
391 
392 // This is needed for per cpp compilations, a not even sure why
393 // (perhaps cause Model returns ParticleIterator here and there?)
394 // - Feel free to remove if you *really* know what you're doing
395 #include "IMP/kernel/Particle.h"
396 
397 #endif /* IMPKERNEL_MODEL_H */
IMP::kernel::ModelObject ModelObject
The base class for decorators.
A smart pointer to a ref-counted Object that is a class member.
Definition: Pointer.h:147
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Definition: object_macros.h:25
ParticlesTemp get_particles(kernel::Model *m, const ParticleIndexes &ps)
Basic types used by IMP.
IMP::base::Vector< IMP::base::WeakPointer< Restraint > > RestraintsTemp
Object used to hold a set of restraints.
A smart pointer to a reference counted object.
Definition: Pointer.h:87
kernel::RestraintsTemp get_restraints(const Subset &s, const ParticleStatesTable *pst, const DependencyGraph &dg, kernel::RestraintSet *rs)
Various general useful macros for IMP.
Represents a scoring function on the model.
ScoreStates maintain invariants in the Model.
ScoringFunction * create_scoring_function(RestraintType *rs, double weight=1.0, double max=NO_MAX, std::string name=std::string())
virtual void clear_caches()
Definition: Object.h:227
Single variable function.
Abstract base class for all restraints.
Storage of a model, its restraints, constraints and particles.
IMP::kernel::Model Model
A restraint is a term in an IMP ScoringFunction.
Used to hold a set of related restraints.
Shared score state.
Class to handle individual model particles.
IMP::kernel::DependencyGraph DependencyGraph
Common base class for heavy weight IMP objects.
Definition: Object.h:106
Classes to handle individual model particles. (Note that implementation of inline functions in in int...
A nullptr-initialized pointer to an IMP Object.
A shared base class to help in debugging and things.
IMP::kernel::Particle Particle
double Float
Basic floating-point value (could be float, double...)
Definition: types.h:20
virtual void do_destroy()
Definition: Object.h:231
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
Definition: check_macros.h:170
int Int
Basic integer value.
Definition: types.h:35
Macros to define containers of objects.
void add_particle(RMF::FileHandle fh, kernel::Particle *hs)
void add_restraint(RMF::FileHandle fh, kernel::Restraint *hs)
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 storing model, its restraints, constraints, and particles.
Definition: kernel/Model.h:73