IMP logo
IMP Reference Guide  2.17.0
The Integrative Modeling Platform
Restraint.h
Go to the documentation of this file.
1 /**
2  * \file IMP/Restraint.h
3  * \brief Abstract base class for all restraints.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPKERNEL_RESTRAINT_H
10 #define IMPKERNEL_RESTRAINT_H
11 
12 #include <IMP/kernel_config.h>
13 #include "ModelObject.h"
14 #include "ScoreAccumulator.h"
15 #include "DerivativeAccumulator.h"
16 #include "constants.h"
17 #include "base_types.h"
18 #include <IMP/InputAdaptor.h>
19 #include <IMP/deprecation_macros.h>
20 #include <IMP/RestraintInfo.h>
21 
22 IMPKERNEL_BEGIN_NAMESPACE
23 class DerivativeAccumulator;
24 
25 //! A restraint is a term in an \imp ScoringFunction.
26 /**
27  To implement a new restraint, just implement the two methods:
28  - IMP::Restraint::unprotected_evaluate()
29  - IMP::ModelObject::do_get_inputs();
30  and use the macro to handle IMP::Object
31  - IMP_OBJECT_METHODS()
32 
33  \note When logging is VERBOSE, restraints should print enough information
34  in evaluate to reproduce the entire flow of data in evaluate. When
35  logging is TERSE the restraint should print out only a constant number of
36  lines per evaluate call.
37 
38  \note Physical restraints should use the units of kcal/mol for restraint
39  values and kcal/mol/A for derivatives.
40 
41  When implementing an expensive restraint it makes sense to support early
42  abort of evaluation if the user is only interested in good scores or scores
43  below a threshold. To do this, look at the fields of the ScoreAccumulator
44  object such as
45  - ScoreAccumulator::get_is_evaluate_if_below(),
46  - ScoreAccumulator::get_is_evaluate_if_good()
47  - ScoreAccumulator::get_maximum()
48 
49  \headerfile Restraint.h "IMP/Restraint.h"
50 
51  See IMP::example::ExampleRestraint for an example.
52  */
53 class IMPKERNELEXPORT Restraint : public ModelObject {
54  public:
55  /** Create a restraint and register it with the model. The restraint is
56  not added to the implicit scoring function in the Model.*/
57  Restraint(Model *m, std::string name);
58 
59  /** Compute and return the current score for the restraint.
60  */
61  double get_score() const;
62 
63 #ifndef IMP_DOXYGEN
64  //! Return the score for this restraint for the current state of the model.
65  /** \return Current score.
66  */
67  double evaluate(bool calc_derivs) const;
68 
69  //! Score the restraint when some particles have moved.
70  /** No particles in the model other those listed should have been
71  changed (e.g. by Monte Carlo movers) since the last evaluation (although
72  ScoreStates may have moved particles not in this list, as a function of
73  particles that *are* in the list). This method should behave
74  identically to evaluate() but may be more efficient if it can
75  skip terms that involve unchanged particles.
76 
77  \param calc_derivs Whether to calculate first derivatives.
78  \param moved_pis Particles that have moved since the last
79  scoring function evaluation.
80  \param reset_pis Particles that have moved, but back to the
81  positions they had at the last-but-one evaluation
82  (e.g. due to a rejected Monte Carlo move).
83 
84  \return Current score.
85  */
86  double evaluate_moved(bool calc_derivs,
87  const ParticleIndexes &moved_pis,
88  const ParticleIndexes &reset_pis) const;
89 
90  double evaluate_moved_if_below(bool calc_derivatives,
91  const ParticleIndexes &moved_pis,
92  const ParticleIndexes &reset_pis, double max) const;
93 
94  double evaluate_moved_if_good(bool calc_derivatives,
95  const ParticleIndexes &moved_pis,
96  const ParticleIndexes &reset_pis) const;
97 
98  double evaluate_if_good(bool calc_derivatives) const;
99 
100  //! \see Model::evaluate_with_maximum()
101  double evaluate_if_below(bool calc_derivatives, double max) const;
102 #endif
103 
104  /** \name Evaluation implementation
105  These methods are called in order to perform the actual restraint
106  scoring. The restraints should assume that all appropriate ScoreState
107  objects have been updated and so that the input particles and containers
108  are up to date. The returned score should be the unweighted score.
109 
110  \note These functions probably should be called \c do_evaluate, but
111  were grandfathered in.
112  \note Although the returned score is unweighted, the DerivativeAccumulator
113  passed in should be properly weighted.
114  @{
115  */
116  //! Return the unweighted score for the restraint.
117  virtual double unprotected_evaluate(DerivativeAccumulator *da) const;
118 
119  //! Return the unweighted score, taking moving particles into account.
120  /** By default this just calls regular unprotected_evaluate(), but
121  may be overridden by restraints to be more efficient, e.g. by
122  skipping terms that involve unchanged particles.
123 
124  \param da Object to accumulate derivatives, or nullptr.
125  \param moved_pis Particles that have moved since the last
126  scoring function evaluation.
127  \param reset_pis Particles that have moved, but back to the
128  positions they had at the last-but-one evaluation
129  (e.g. due to a rejected Monte Carlo move).
130 
131  \return Current score.
132  */
134  DerivativeAccumulator *da, const ParticleIndexes &moved_pis,
135  const ParticleIndexes &reset_pis) const {
136  IMP_UNUSED(moved_pis);
137  IMP_UNUSED(reset_pis);
138  return unprotected_evaluate(da);
139  }
140 
141  /** The function calling this will treat any score >= get_maximum_score
142  as bad and so can return early as soon as such a situation is found.*/
144  double max) const {
145  IMP_UNUSED(max);
146  return unprotected_evaluate(da);
147  }
148 
149  //! The function calling this will treat any score >= max as bad.
151  double max) const {
152  IMP_UNUSED(max);
153  return unprotected_evaluate(da);
154  }
155 
156  virtual double unprotected_evaluate_moved_if_below(
157  DerivativeAccumulator *da, const ParticleIndexes &moved_pis,
158  const ParticleIndexes &reset_pis, double max) const {
159  IMP_UNUSED(max);
160  return unprotected_evaluate_moved(da, moved_pis, reset_pis);
161  }
162 
163  virtual double unprotected_evaluate_moved_if_good(
164  DerivativeAccumulator *da, const ParticleIndexes &moved_pis,
165  const ParticleIndexes &reset_pis, double max) const {
166  IMP_UNUSED(max);
167  return unprotected_evaluate_moved(da, moved_pis, reset_pis);
168  }
169 
170 /** @} */
171 
172  //! \return static key:value information about this restraint, or null.
173  /** \return a set of key:value pairs that contain static information
174  about this restraint (i.e. information that doesn't change during
175  a sampling run, such as the type of restraint or filename from
176  which information is read). Usually this includes a "type" key with
177  the fully qualified classname (e.g. IMP.mymodule.MyRestraint).
178  If no such information is available, a null pointer is returned.
179  This information is used when writing restraints to files, e.g. by
180  the IMP.rmf module.
181  */
182  virtual RestraintInfo *get_static_info() const {
183  return nullptr;
184  }
185 
186  //! \return dynamic key:value information about this restraint, or null.
187  /** \return a set of key:value pairs that contain dynamic information
188  about this restraint (i.e. information that changes during a sampling
189  run, such as scores or cross correlations).
190  If no such information is available, a null pointer is returned.
191  This information is used when writing restraints to files, e.g. by
192  the IMP.rmf module.
193  */
194  virtual RestraintInfo *get_dynamic_info() const {
195  return nullptr;
196  }
197 
198 #ifndef IMP_DOXYGEN
199  //! Perform the actual restraint scoring.
200  /** The restraints should assume that all appropriate ScoreState
201  objects have been updated and so that the input particles and containers
202  are up to date. The returned score should be the unweighted score.
203  */
204  void add_score_and_derivatives(ScoreAccumulator sa) const;
205 
206  void add_score_and_derivatives_moved(
207  ScoreAccumulator sa, const ParticleIndexes &moved_pis,
208  const ParticleIndexes &reset_pis) const;
209 #endif
210 
211  //! Decompose this restraint into constituent terms
212  /** Given the set of input particles, decompose the restraint into parts
213  that are as simple as possible. For many restraints, the simplest
214  part is simply the restraint itself.
215 
216  If a restraint can be decomposed, it should return a
217  RestraintSet so that the maximum score and weight can be
218  passed properly.
219 
220  The restraints returned have had set_model() called and so can
221  be evaluated.
222  */
224 
225  //! Decompose this restraint into constituent terms for the current conf
226  /** \return a decomposition that is value for the current conformation,
227  but will not necessarily be valid if any of the particles are
228  changed. This is the same as create_decomposition() for
229  non-conditional restraints.
230 
231  The restraints returned have had set_model() called and so can be
232  evaluated.
233  */
234  Restraint *create_current_decomposition() const;
235 
236  /** \name Weights
237  Each restraint's contribution to the model score is weighted. The
238  total weight for the restraint is the some over all the paths containing
239  it. That is, if a restraint is in a RestraintSet with weight .5 and
240  another with weight 2, and the restraint itself has weight 3, then the
241  total weight of the restraint is \f$.5 \cdot 3 + 2 \cdot 3 = 7.5 \f$.
242  @{
243  */
244  void set_weight(Float weight);
245  Float get_weight() const { return weight_; }
246  /** @} */
247  /** \name Filtering
248  We are typically only interested in "good" conformations of
249  the model. These are described by specifying maximum scores
250  per restraint (or RestraintSet). Samplers, optimizers
251  etc are free to ignore configurations they encounter which
252  go outside these bounds.
253 
254  \note The maximum score is for the unweighted restraint.
255  That is, the restraint evaluation is bad if the value
256  is greater than the maximum score divided by the weight.
257  @{
258  */
259  double get_maximum_score() const { return max_; }
260  void set_maximum_score(double s);
261 /** @} */
262 
263 //! Create a scoring function with only this restraint.
264 /** \note This method cannot be implemented in Python due to memory
265  management issues (and the question of why you would ever
266  want to).
267  */
268 #ifndef SWIG
269  virtual
270 #endif
271  ScoringFunction *
272  create_scoring_function(double weight = 1.0,
273  double max = NO_MAX) const;
274 #if !defined(IMP_DOXYGEN)
275  void set_last_score(double s) const {
276  last_last_score_ = last_score_;
277  last_score_ = s;
278  }
279  void set_last_last_score(double s) const { last_last_score_ = s; }
280 #endif
281 
282  /** Return the (unweighted) score for this restraint last time it was
283  evaluated.
284  \note If some sort of special evaluation (eg Model::evaluate_if_good())
285  was the last call, the score, if larger than the max, is not accurate.
286  */
287  virtual double get_last_score() const { return last_score_; }
288 
289  //! Get the unweighted score from the last-but-one time it was evaluated
290  /** \see get_last_score
291  */
292  virtual double get_last_last_score() const { return last_last_score_; }
293 
294  /** Return whether this restraint violated its maximum last time it was
295  evaluated.
296  */
297  bool get_was_good() const { return get_last_score() < max_; }
298 
300 
301  protected:
302  /** A Restraint should override this if it wants to decompose itself
303  for domino and other purposes. The returned restraints will be made
304  into a RestraintSet if needed, with suitable weight and maximum score.
305  */
307  return Restraints(1, const_cast<Restraint *>(this));
308  }
309  /** A Restraint should override this if it wants to decompose itself
310  for display and other purposes. The returned restraints will be made
311  into a RestraintSet if needed, with suitable weight and maximum score.
312 
313  The returned restraints should be only the non-zero terms and should
314  have their last scores set appropriately.
315  */
317  return do_create_decomposition();
318  }
319 
320  virtual void do_add_score_and_derivatives(ScoreAccumulator sa) const;
321 
322  virtual void do_add_score_and_derivatives_moved(
323  ScoreAccumulator sa, const ParticleIndexes &moved_pis,
324  const ParticleIndexes &reset_pis) const;
325 
326  /** No outputs. */
327  ModelObjectsTemp do_get_outputs() const override {
328  return ModelObjectsTemp();
329  }
330 
331  private:
332  ScoringFunction *create_internal_scoring_function() const;
333 
334  double weight_;
335  double max_;
336  mutable double last_score_;
337  mutable double last_last_score_;
338  // cannot be released outside the class
339  mutable Pointer<ScoringFunction> cached_internal_scoring_function_;
340 };
341 
342 //! Provide a consistent interface for things that take Restraints as arguments.
343 /**
344  \note Passing an empty list of restraints should be supported, but problems
345  could arise, so be alert (the problems would not be subtle).
346 */
347 class IMPKERNELEXPORT RestraintsAdaptor :
348 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
349  public Restraints
350 #else
351  public InputAdaptor
352 #endif
353  {
354  static Restraint *get(Restraint *r) { return r; }
355 
356  public:
357  RestraintsAdaptor() {}
358  RestraintsAdaptor(const Restraints &sf) : Restraints(sf) {}
360  : Restraints(sf.begin(), sf.end()) {}
361  RestraintsAdaptor(Restraint *sf) : Restraints(1, sf) {}
362 #ifndef IMP_DOXYGEN
363  template <class T>
364  RestraintsAdaptor(internal::PointerBase<T> t)
365  : Restraints(1, get(t)) {}
366 #endif
367 };
368 
369 //! Return the decomposition of a list of restraints.
370 IMPKERNELEXPORT Restraints create_decomposition(const RestraintsTemp &rs);
371 
372 IMPKERNEL_END_NAMESPACE
373 
374 #endif /* IMPKERNEL_RESTRAINT_H */
Control display of deprecation information.
const double NO_MAX
Use this value when you want to turn off maximum for restraint evaluation.
Basic types used by IMP.
IMP::Vector< IMP::Pointer< Restraint > > Restraints
Definition: base_types.h:86
Class for adding scores from restraints to the model.
virtual RestraintInfo * get_static_info() const
Definition: Restraint.h:182
Various useful constants.
virtual RestraintInfo * get_dynamic_info() const
Definition: Restraint.h:194
Class for adding derivatives from restraints to the model.
virtual Restraints do_create_decomposition() const
Definition: Restraint.h:306
#define IMP_REF_COUNTED_DESTRUCTOR(Name)
Ref counted objects should have private destructors.
A smart pointer to a reference counted object.
Definition: Pointer.h:87
ScoringFunction * create_scoring_function(RestraintType *rs, double weight=1.0, double max=NO_MAX, std::string name=std::string())
Create a ScoringFunction on a single restraint.
Definition: generic.h:23
IMP::Vector< IMP::WeakPointer< ModelObject > > ModelObjectsTemp
Definition: base_types.h:89
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:73
virtual double unprotected_evaluate_if_below(DerivativeAccumulator *da, double max) const
The function calling this will treat any score >= max as bad.
Definition: Restraint.h:150
Base class for objects in a Model that depend on other objects.
Definition: ModelObject.h:26
Convenience class to accept multiple input types.
virtual Restraints do_create_current_decomposition() const
Definition: Restraint.h:316
virtual double unprotected_evaluate_if_good(DerivativeAccumulator *da, double max) const
Definition: Restraint.h:143
#define IMP_UNUSED(variable)
Provide a consistent interface for things that take Restraints as arguments.
Definition: Restraint.h:347
Class for adding up scores during ScoringFunction evaluation.
Restraints create_decomposition(const RestraintsTemp &rs)
Return the decomposition of a list of restraints.
Report key:value information on restraints.
Definition: RestraintInfo.h:35
Base class for objects in a Model that depend on other objects.
virtual double get_last_score() const
Definition: Restraint.h:287
ModelObjectsTemp do_get_outputs() const override
Definition: Restraint.h:327
bool get_was_good() const
Definition: Restraint.h:297
Represents a scoring function on the model.
Report key:value information on restraints.
double Float
Basic floating-point value (could be float, double...)
Definition: types.h:19
virtual double get_last_last_score() const
Get the unweighted score from the last-but-one time it was evaluated.
Definition: Restraint.h:292
Convenience class to accept multiple input types.
Definition: InputAdaptor.h:25
virtual double unprotected_evaluate_moved(DerivativeAccumulator *da, const ParticleIndexes &moved_pis, const ParticleIndexes &reset_pis) const
Return the unweighted score, taking moving particles into account.
Definition: Restraint.h:133
Class for adding derivatives from restraints to the model.
A restraint is a term in an IMP ScoringFunction.
Definition: Restraint.h:53