IMP  2.0.1
The Integrative Modeling Platform
kernel/declare_Restraint.h
Go to the documentation of this file.
1 /**
2  * \file IMP/kernel/declare_Restraint.h
3  * \brief Abstract base class for all restraints.
4  *
5  * Copyright 2007-2013 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPKERNEL_DECLARE_RESTRAINT_H
10 #define IMPKERNEL_DECLARE_RESTRAINT_H
11 
12 #include <IMP/kernel/kernel_config.h>
13 #include "ModelObject.h"
14 #include "ScoreAccumulator.h"
15 #include "DerivativeAccumulator.h"
16 #include "constants.h"
17 #include <IMP/base/tracking.h>
19 
20 IMPKERNEL_BEGIN_NAMESPACE
22 
23 //! A restraint is a term in an \imp ScoringFunction.
24 /**
25  \note Restraints will print a warning message if they are destroyed
26  without ever having been added to a model as this is an easy mistake
27  to make. To disable this warning for a particular restraint, call
28  set_was_used(true).
29 
30 To implement a new restraint, just implement the two methods:
31 - IMP::Restraint::do_add_score_and_derivatives()
32  (or IMP::Restraint::unprotected_evaluate())
33 - IMP::ModelObject::do_get_inputs();
34 and use the macro to handle IMP::base::Object
35 - IMP_OBJECT_METHODS()
36 
37  \note When logging is VERBOSE, restraints should print enough information
38  in evaluate to reproduce the the entire flow of data in evaluate. When
39  logging is TERSE the restraint should print out only a constant number of
40  lines per evaluate call.
41 
42  \note Physical restraints should use the units of kcal/mol for restraint
43  values and kcal/mol/A for derivatives.
44 
45  When implementing an expensive restraint it makes sense to support early
46  abort of evaluation if the user is only interested in good scores or scores
47  below a threshold. To do this, look at the fields of the ScoreAccumulator
48  object such as
49  - ScoreAccumulator::get_is_evaluate_if_below(),
50  - ScoreAccumulator::get_is_evaluate_if_good()
51  - ScoreAccumulator::get_maximum()
52 
53  \headerfile Restraint.h "IMP/Restraint.h"
54 
55  See IMP::example::ExampleRestraint for an example.
56  */
57 class IMPKERNELEXPORT Restraint : public ModelObject
58 {
59 public:
60  /** Create a restraint and register it with the model. The restraint is
61  not added to implicit scoring function in the Model.*/
62  Restraint(Model *m, std::string name);
63 #ifndef IMP_DOXYGEN
64 #ifndef SWIG
65  struct ModelInitTag{};
66  // for model
67  Restraint(ModelInitTag, std::string name="Restraint %1%");
68 #endif
69  Restraint(std::string name="Restraint %1%");
70 #endif
71 
72  /** Compute and return the current score for the restraint.
73  */
74  double get_score() const;
75 
76 #ifndef IMP_DOXYGEN
77  //! Return the score for this restraint for the current state of the model.
78  /** \return Current score.
79 
80  This method is equivalent to calling:
81  \code
82  model->evaluate(RestraintsTemp(1,this), calc_derivs)
83  \endcode
84  */
85  double evaluate(bool calc_derivs) const;
86 
87  //! See Model::evaluate_if_good()
88  double evaluate_if_good(bool calc_derivatives) const;
89 
90  //! See Model::evaluate_with_maximum()
91  double evaluate_if_below(bool calc_derivatives, double max) const;
92 
93  /** \name Evaluation implementation
94  These methods are called in order to perform the actual restraint
95  scoring. The restraints should assume that all appropriate ScoreState
96  objects have been updated and so that the input particles and containers
97  are up to date. The returned score should be the unweighted score.
98 
99  \note These functions probably should be called \c do_evaluate, but
100  were grandfathered in.
101  \note Although the returned score is unweighted, the DerivativeAccumulator
102  passed in had better be properly weighted.
103  @{
104  */
105  /** Return the unweighted score for the restraint.*/
106  virtual double unprotected_evaluate(DerivativeAccumulator *da) const;
107  /** The function calling this will treat any score >= get_maximum_score
108  as bad and so can return early as soon as such a situation is found.*/
109  virtual double unprotected_evaluate_if_good(DerivativeAccumulator *da,
110  double max) const {
111  IMP_UNUSED(max);
112  return unprotected_evaluate(da);
113  }
114 
115  /** The function calling this will treat any score >= max as bad.*/
116  virtual double unprotected_evaluate_if_below(DerivativeAccumulator *da,
117  double max) const {
118  IMP_UNUSED(max);
119  return unprotected_evaluate(da);
120  }
121  /** @} */
122 #endif
123 
124  /** This methid is called in order to perform the actual restraint
125  scoring. The restraints should assume that all appropriate ScoreState
126  objects have been updated and so that the input particles and containers
127  are up to date. The returned score should be the unweighted score.
128  */
129  void add_score_and_derivatives(ScoreAccumulator sa) const;
130 
131  //! Decompose this restraint into constituent terms
132  /** Given the set of input particles, decompose the restraint into as
133  simple parts as possible. For many restraints, the simplest
134  part is simply the restraint itself.
135 
136  If a restraint can be decomposed, it should return a
137  RestraintSet so that the maximum score and weight can be
138  passed properly.
139 
140  The restraints returned have had set_model() called and so can
141  be evaluated.
142  */
144 
145  //! Decompose this restraint into constituent terms for the current conf
146  /** Return a decomposition that is value for the current conformation,
147  but will not necessarily be valid if any of the particles are
148  changed. This is the same as create_decomposition() for
149  non-conditional restraints.
150 
151  The restraints returned have had set_model() called and so can be
152  evaluated.
153  */
154  Restraint* create_current_decomposition() const;
155 
156 
157  /** \name Weights
158  Each restraint's contribution to the model score is weighted. The
159  total weight for the restraint is the some over all the paths containing
160  it. That is, if a restraint is in a RestraintSet with weight .5 and
161  another with weight 2, and the restaint itself has weight 3, then the
162  total weight of the restraint is \f$.5 \cdot 3 + 2 \cdot 3 = 7.5 \f$.
163  @{
164  */
165  void set_weight(Float weight);
166  Float get_weight() const { return weight_; }
167  /** @} */
168  /** \name Filtering
169  We are typically only interested in "good" conformations of
170  the model. These are described by specifying maximum scores
171  per restraint and for the whole model. Samplers, optimizers
172  etc are free to ignore configurations they encounter which
173  go outside these bounds.
174 
175  \note The maximum score is for the unweighted restraint.
176  That is, the restraint evaluation is bad if the value
177  is greater than the maximum score divided by the weight.
178  @{
179  */
180  double get_maximum_score() const {
181  return max_;
182  }
183  void set_maximum_score(double s);
184  /** @} */
185 
186  /** Create a scoring function with only this restarint.
187 
188  \note This method cannot be implemented in python due to memory
189  management issues (and the question of why you would ever
190  want to).
191  */
192 #ifndef SWIG
193 virtual
194 #endif
195 ScoringFunction *create_scoring_function(double weight=1.0,
196  double max
197  = NO_MAX) const;
198 #if !defined(IMP_DOXYGEN)
199  void set_last_score(double s) const { last_score_=s;}
200 #endif
201 
202  /** Return the (unweighted) score for this restraint last time it was
203  evaluated.
204  \note If some sort of special evaluation (eg Model::evaluate_if_good())
205  was the last call, the score, if larger than the max, is not accurate.
206  */
207  virtual double get_last_score() const {return last_score_;}
208  /** Return whether this restraint violated it maximum last time it was
209  evaluated.
210  */
211  bool get_was_good() const {return get_last_score() < max_;}
212 
213 #if IMP_HAS_DEPRECATED
214  /** \deprecated use get_inputs() instead.*/
216  /** \deprecated use get_inputs() instead.*/
217  IMP_DEPRECATED_WARN ContainersTemp get_input_containers() const;
218 #endif
219 
221 
222 protected:
223  /** A Restraint should override this if they want to decompose themselves
224  for domino and other purposes. The returned restraints will be made
225  in to a RestraintSet, if needed and the weight and maximum score
226  set for the restraint set.
227  */
229  return Restraints(1, const_cast<Restraint*>(this));
230  }
231  /** A Restraint should override this if they want to decompose themselves
232  for display and other purposes. The returned restraints will be made
233  in to a RestraintSet, if needed and the weight and maximum score
234  set for the restraint set.
235 
236  The returned restraints should be only the non-zero terms and should
237  have their last scores set appropriately;
238  */
240  return do_create_decomposition();
241  }
242  /** A restraint should override this to compute the score and derivatives.
243  */
244  virtual void do_add_score_and_derivatives(ScoreAccumulator sa) const;
245 
246  /** There is no interesting dependency tracking. */
247  virtual void do_update_dependencies() IMP_OVERRIDE{}
248  /** No outputs. */
250  return ModelObjectsTemp();
251  }
252  private:
253  ScoringFunction *create_internal_scoring_function() const;
254 
255  double weight_;
256  double max_;
257  mutable double last_score_;
258  // cannot be released outside the class
259  mutable base::Pointer<ScoringFunction> cached_internal_scoring_function_;
260 };
261 
262 IMPKERNEL_END_NAMESPACE
263 
264 #endif /* IMPKERNEL_DECLARE_RESTRAINT_H */