IMP  2.2.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 
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 base::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::ObjectsAttributeTable,
85  public internal::ParticleAttributeTable,
86  public internal::ParticlesAttributeTable
87 #endif
88  {
90  // must be up top
91  // we don't want any liveness checks
92  IMP_NAMED_TUPLE_5(NodeInfo, NodeInfos, Edges, inputs, Edges, input_outputs,
93  Edges, outputs, Edges, readers, Edges, writers, );
94  typedef boost::unordered_map<const ModelObject *, NodeInfo> DependencyGraph;
95  DependencyGraph dependency_graph_;
96  boost::unordered_set<const ModelObject *> no_dependencies_;
97  boost::unordered_map<const ModelObject *, ScoreStatesTemp>
98  required_score_states_;
99 
100  // basic representation
101  boost::unordered_map<FloatKey, FloatRange> ranges_;
102 
103  ParticleIndexes free_particles_;
106 
108  ////////////// DEPRECATED
109  // for old code that uses the model for the scoring function
111 
112  void do_add_dependencies(const ModelObject *mo);
113  void do_clear_required_score_states(kernel::ModelObject *mo);
114  void do_check_required_score_states(const ModelObject *mo) const;
115  void do_check_update_order(const ScoreState *ss) const;
116  void do_check_inputs_and_outputs(const ModelObject *mo) const;
117  void do_check_readers_and_writers(const ModelObject *mo) const;
118  void do_check_not_in_readers_and_writers(const ModelObject *mo) const;
119  void do_clear_dependencies(const ModelObject *mo);
120 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
121  // things the evaluate template functions need, can't be bothered with friends
122  public:
123 #endif
124  // check more things on the first call
125  bool first_call_;
126  // the stage of evaluation
127  internal::Stage cur_stage_;
128 
129  ModelObjectsTemp get_dependency_graph_inputs(const ModelObject *mo) const;
130  ModelObjectsTemp get_dependency_graph_outputs(const ModelObject *mo) const;
131  bool do_get_has_dependencies(const ModelObject *mo) const {
132  return no_dependencies_.find(mo) == no_dependencies_.end();
133  }
134  void do_set_has_dependencies(const ModelObject *mo, bool tf);
135  void do_set_has_all_dependencies(bool tf);
136 
137  void validate_computed_derivatives() const {}
138  void set_has_all_dependencies(bool tf);
139  bool get_has_all_dependencies() const;
140  void check_dependency_invariants() const;
141  void check_dependency_invariants(const ModelObject *mo) const;
142  ScoreStatesTemp get_ancestor_score_states(const ModelObject *mo) const;
143  ScoreStatesTemp get_descendent_score_states(const ModelObject *mo) const;
144 
145  void before_evaluate(const ScoreStatesTemp &states);
146  void after_evaluate(const ScoreStatesTemp &states, bool calc_derivs);
147 
148  internal::Stage get_stage() const { return cur_stage_; }
149  ParticleIndex add_particle_internal(Particle *p);
150  static void do_remove_score_state(ScoreState *obj);
151  void do_add_score_state(ScoreState *obj);
152  void do_remove_particle(ParticleIndex pi);
153  bool do_get_has_required_score_states(const ModelObject *mo) const;
154  void do_set_has_required_score_states(kernel::ModelObject *mo, bool tf);
155  const ScoreStatesTemp &do_get_required_score_states(const ModelObject *mo)
156  const {
157  IMP_USAGE_CHECK(do_get_has_required_score_states(mo),
158  "Doesn't have score states");
159  return required_score_states_.find(mo)->second;
160  }
161  void do_add_model_object(kernel::ModelObject *mo);
162  void do_remove_model_object(kernel::ModelObject *mo);
163 
164  public:
165  /** Construct an empty model */
166  Model(std::string name = "Model %1%");
167 
168  public:
169 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
170  IMP_MODEL_IMPORT(internal::FloatAttributeTable);
171  IMP_MODEL_IMPORT(internal::StringAttributeTable);
172  IMP_MODEL_IMPORT(internal::IntAttributeTable);
173  IMP_MODEL_IMPORT(internal::ObjectAttributeTable);
174  IMP_MODEL_IMPORT(internal::WeakObjectAttributeTable);
175  IMP_MODEL_IMPORT(internal::IntsAttributeTable);
176  IMP_MODEL_IMPORT(internal::ObjectsAttributeTable);
177  IMP_MODEL_IMPORT(internal::ParticleAttributeTable);
178  IMP_MODEL_IMPORT(internal::ParticlesAttributeTable);
179 #endif
180  /** Clear all the cache attributes of a given particle.*/
181  void clear_particle_caches(ParticleIndex pi);
182 
183  //! Add particle to the model
184  ParticleIndex add_particle(std::string name);
185 
186  //! Get the name of a particle
188  return get_particle(pi)->get_name();
189  }
190 
191  /** Add the passed Undecorator to the particle.*/
192  void add_undecorator(ParticleIndex pi, Undecorator *d);
193 
194  /** @name States
195 
196  ScoreStates can be added to the Model in order to keep them
197  alive as long as the model is alive. Being added does affect
198  their ability to perform their required action. See ScoreState
199  for more information.
200 
201  \advancedmethod
202  */
203  /**@{*/
204  IMP_LIST_ACTION(public, ScoreState, ScoreStates, score_state, score_states,
205  ScoreState *, ScoreStates, do_add_score_state(obj), {},
206  do_remove_score_state(obj));
207  /**@}*/
208 
209  public:
210 #ifndef SWIG
211  using Object::clear_caches;
212 #endif
213 
214  //! Sometimes it is useful to be able to make sure the model is up to date
215  /** This method updates all the state but does not necessarily compute the
216  score. Use this to make sure that your containers and rigid bodies are
217  up to date.
218  */
219  void update();
220 
221 #ifdef IMP_DOXYGEN
222  /** \name Accessing attributes
223  \anchor model_attributes
224  All the attribute data associated with each Particle is stored in the
225  Model. For each type of attribute, there are the methods detailed below
226  (where, eg, TypeKey is FloatKey or StringKey)
227  @{
228  */
229  /** \pre get_has_attribute(attribute_key, particle) is false*/
230  void add_attribute(TypeKey attribute_key, ParticleIndex particle, Type value);
231 
232  /** \pre get_has_attribute(attribute_key, particle) is true*/
233  void remove_attribute(TypeKey attribute_key, ParticleIndex particle);
234 
235  bool get_has_attribute(TypeKey attribute_key, ParticleIndex particle) const;
236 
237  /** \pre get_has_attribute(attribute_key, particle) is true*/
238  void set_attribute(TypeKey attribute_key, ParticleIndex particle, Type value);
239 
240  /** \pre get_has_attribute(attribute_key, particle) is true*/
241  Type get_attribute(TypeKey attribute_key, ParticleIndex particle);
242 
243  /** Cache attributes, unklike normal attributes, can be added during
244  evaluation. They are also cleared by the clear_cache_attributes() method.
245  Cache attributes should be used when one is adding data to a particle
246  to aid scoring (eg cache the rigid body collision acceleration structure).
247 
248  When some pertinent aspect of the particle changes, the clear method
249  should
250  be called (yes, this is a bit vague). Examples where it should be cleared
251  include changing the set of members of a core::RigidBody or their
252  coordinates, changing the members of an atom::Hierarchy.
253  */
254  void add_cache_attribute(TypeKey attribute_key, ParticleIndex particle,
255  Type value);
256 
257  //! Optimized attributes are the parameters of the model
258  /** They will be modified by the samplers and optimizers.
259  */
260  void set_is_optimized(TypeKey attribute_key, ParticleIndex particle,
261  bool true_or_false);
262 /** @} */
263 #endif
264 
265 #ifdef SWIG
266 #define IMP_MODEL_ATTRIBUTE_METHODS(Type, Value) \
267  void add_attribute(Type##Key attribute_key, ParticleIndex particle, \
268  Value value); \
269  void remove_attribute(Type##Key attribute_key, ParticleIndex particle); \
270  bool get_has_attribute(Type##Key attribute_key, \
271  ParticleIndex particle) const; \
272  void set_attribute(Type##Key attribute_key, ParticleIndex particle, \
273  Value value); \
274  Value get_attribute(Type##Key attribute_key, ParticleIndex particle); \
275  void add_cache_attribute(Type##Key attribute_key, ParticleIndex particle, \
276  Value value)
277 
278  IMP_MODEL_ATTRIBUTE_METHODS(Float, Float);
279  IMP_MODEL_ATTRIBUTE_METHODS(Int, Int);
280  IMP_MODEL_ATTRIBUTE_METHODS(Ints, Ints);
281  IMP_MODEL_ATTRIBUTE_METHODS(String, String);
282  IMP_MODEL_ATTRIBUTE_METHODS(ParticleIndexes, ParticleIndexes);
283  IMP_MODEL_ATTRIBUTE_METHODS(ParticleIndex, ParticleIndex);
284  IMP_MODEL_ATTRIBUTE_METHODS(Object, Object *);
285  IMP_MODEL_ATTRIBUTE_METHODS(WeakObject, Object *);
286  void set_is_optimized(FloatKey, ParticleIndex, bool);
287 #endif
288 
289  /** Get the particle from an index. */
290  Particle *get_particle(ParticleIndex p) const;
291 
292  /** Get the particle from an index. */
293  bool get_has_particle(ParticleIndex p) const;
294 
295  /** Get all particle indexes */
296  ParticleIndexes get_particle_indexes();
297 
298  /** Get all the ModelObjects associated with this Model.
299  */
300  ModelObjectsTemp get_model_objects() const;
301 
302  /** Remove a particle from the Model. The particle will then be inactive and
303  cannot be used for anything and all data stored in the particle is lost.
304  */
305  void remove_particle(ParticleIndex pi);
306 
307  /** \name Storing data in the model
308 
309  One can store data associated with the model. This is used, for example,
310  to keep a central ScoreState to normalize rigid body rotational variables.
311  @{ */
312  /** Store a piece of data in the model referenced by the key. */
313  void add_data(kernel::ModelKey mk, base::Object *o);
314  /** Get back some data stored in the model. */
315  base::Object *get_data(kernel::ModelKey mk) const;
316  /** Remove data stored in the model. */
317  void remove_data(kernel::ModelKey mk);
318  /** Check if the model has a certain piece of data attached. */
319  bool get_has_data(kernel::ModelKey mk) const;
320  /** @} */
321 
323 
324  public:
325 // deprecated
326 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
327  struct NotNull {
328  bool operator()(const base::Pointer<Particle> &p) { return p; }
329  };
330  typedef boost::filter_iterator<
331  NotNull, base::Vector<base::Pointer<Particle> >::const_iterator>
332  ParticleIterator;
333 #endif
334 
335 // all deprecated but too used to add warnings about now
336 #if !defined(IMP_DOXYGEN)
337  ScoringFunction *create_model_scoring_function();
338  void add_restraint(Restraint *r);
339  void remove_restraint(Restraint *r);
342  virtual void do_destroy() IMP_OVERRIDE;
343 #endif
344 
345  /** \deprecated_at{2.1} Use a RestraintSet instead.*/
346  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
347  unsigned int get_number_of_restraints() const;
348  /** \deprecated_at{2.1} Use a RestraintSet instead.*/
349  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
350  Restraint *get_restraint(unsigned int i) const;
351  /** \deprecated_at{2.1} Use a ScoringFunction instead.*/
352  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
353  double evaluate(bool tf, bool warn = true);
354  /** \deprecated_at{2.1} Use the ParticleIndex version.*/
355  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
356  void remove_particle(Particle *p);
357  /** \deprecated_at{2.1} Use get_particle_indexes(). */
358  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
359  unsigned int get_number_of_particles() const;
360  /** \deprecated_at{2.1} Use get_particle_indexes(). */
361  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
362  ParticlesTemp get_particles() const;
363  /** \deprecated_at{2.1} Using a ScoringFunction instead. */
364  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
365  RestraintSet *get_root_restraint_set();
366  /** \deprecated_at{2.1} Get the maximum directly from the restraint.*/
367  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
368  double get_maximum_score(Restraint *r) const;
369  /** \deprecated_at{2.1} Set get the maximum directly on the restraint.*/
370  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
371  void set_maximum_score(Restraint *r, double s);
372  /** \deprecated_at{2.1} You should use a ScoringFunction or a RestraintSet.*/
373  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
374  void set_maximum_score(double s);
375  /** \deprecated_at{2.1} You should use a ScoringFunction or a RestraintSet.*/
376  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
377  double get_maximum_score() const;
378 #ifndef SWIG
379  /** \deprecated_at{2.1} Use get_particle_indexes(). */
380  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
381  ParticleIterator particles_begin() const;
382  /** \deprecated_at{2.1} Use get_particle_indexes(). */
383  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
384  ParticleIterator particles_end() const;
385  /** \deprecated_at{2.1} Use a ScoringFunction instead. */
386  IMPKERNEL_DEPRECATED_METHOD_DECL(2.1)
387  operator Restraint *() const { return restraints_.get(); }
388 #endif
389 };
390 
391 IMPKERNEL_END_NAMESPACE
392 
393 #endif /* IMPKERNEL_MODEL_H */
IMP::kernel::ModelObject ModelObject
The base class for decorators.
IMP::base::Vector< IMP::base::WeakPointer< kernel::ModelObject > > ModelObjectsTemp
A nullptr-initialized pointer to an IMP Object.
A smart pointer to a ref-counted Object that is a class memeber.
Definition: base/Pointer.h:147
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: base/Pointer.h:87
kernel::RestraintsTemp get_restraints(const Subset &s, const ParticleStatesTable *pst, const DependencyGraph &dg, kernel::RestraintSet *rs)
ScoreStates maintian invariants in the Model.
ScoringFunction * create_scoring_function(RestraintType *rs, double weight=1.0, double max=NO_MAX, std::string name=std::string())
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
virtual void clear_caches()
Definition: base/Object.h:227
Various general useful macros for IMP.
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.
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Class to handle individual model particles.
IMP::kernel::DependencyGraph DependencyGraph
Common base class for heavy weight IMP objects.
Definition: base/Object.h:106
Classes to handle individual model particles.
double Float
Basic floating-point value (could be float, double...)
Definition: base/types.h:20
virtual void do_destroy()
Definition: base/Object.h:230
int Int
Basic integer value.
Definition: base/types.h:35
Macros to define containers of objects.
A shared base class to help in debugging and things.
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: base/types.h:44
Class for storing model, its restraints, constraints, and particles.
Definition: kernel/Model.h:72
std::string get_particle_name(ParticleIndex pi)
Get the name of a particle.
Definition: kernel/Model.h:187