00001 /** 00002 * \file IMP/Restraint.h \brief Abstract base class for all restraints. 00003 * 00004 * Copyright 2007-2010 IMP Inventors. All rights reserved. 00005 * 00006 */ 00007 00008 #ifndef IMP_RESTRAINT_H 00009 #define IMP_RESTRAINT_H 00010 00011 #include "kernel_config.h" 00012 #include "DerivativeAccumulator.h" 00013 #include "Model.h" 00014 #include "Particle.h" 00015 #include "VersionInfo.h" 00016 #include "Object.h" 00017 #include "Pointer.h" 00018 #include "log.h" 00019 #include "utility.h" 00020 #include "container_macros.h" 00021 #include "container_base.h" 00022 00023 #include <vector> 00024 #include <iostream> 00025 #include <limits> 00026 00027 IMP_BEGIN_NAMESPACE 00028 00029 00030 class Model; 00031 00032 //! Abstract class for representing restraints 00033 /** Restraints should take their score function or UnaryFunction 00034 as the first argument. Restraints which act on large numbers of 00035 particles should allow the particle list to be skipped in the 00036 constructor and should provide methods so that the set of particles 00037 can be modified after construction. 00038 00039 A restraint can be added to the model multiple times or to multiple 00040 restraint sets in the same model. 00041 00042 \note When logging is VERBOSE, restraints should print enough information 00043 in evaluate to reproduce the the entire flow of data in evaluate. When 00044 logging is TERSE the restraint should print out only a constant number of 00045 lines per evaluate call. 00046 00047 \note Physical restraints should use the units of kcal/mol for restraint 00048 values and kcal/mol/A for derivatives. 00049 00050 \note Restraints will print a warning message if they are destroyed 00051 without ever having been added to a model as this is an easy mistake 00052 to make. To disable this warning for a particular restraint, call 00053 set_was_used(true). 00054 00055 \implementation{Restraint, IMP_RESTRAINT, IMP::example::ExampleRestraint} 00056 */ 00057 class IMPEXPORT Restraint : public Object 00058 { 00059 public: 00060 Restraint(std::string name="Restraint %1%"); 00061 00062 //! Return the score for this restraint for the current state of the model. 00063 /** \return Current score. 00064 00065 This method is equivalent to calling: 00066 \code 00067 model->evaluate(RestraintsTemp(1,this), calc_derivs) 00068 \endcode 00069 */ 00070 double evaluate(bool calc_derivs) const; 00071 00072 /** \name Incremental Evaluation 00073 00074 When optimizers move the particles a few at a time, scoring can 00075 be made more efficient by incremental score evaluation. To do 00076 so, a Restraint must implement Restraint::get_is_incremental() 00077 so that it returns \c true and implement 00078 Restraint::incremental_evaluate() to do the following 00079 00080 - the return value should be the total score given the new 00081 conformation 00082 00083 - for a Particle \c p, the sum of the derivatives of 00084 p->get_prechange_particle() 00085 00086 and \c p should be equal to the difference in derivatives 00087 between the current and prior conformations. This is most easily 00088 done by accumulating the negative of the prior derivative in 00089 p->get_prechange_particle() and the new derivative in p, for any 00090 particle touched. 00091 00092 @{ 00093 */ 00094 //! Return true if the incremental_evaluate() function is implemented 00095 virtual bool get_is_incremental() const {return false;} 00096 00097 /** @} */ 00098 00099 /** \brief The restraint can override this in order to take action 00100 when added to a Model 00101 00102 Users should generally not call this method directly; instead 00103 they should just use Model::add_restraint() to add the 00104 restraint to the Model. 00105 00106 Restraints 00107 that want to take action when they are added to the model can 00108 override this method (but be sure to call Restraint::set_model() 00109 to set the actual model pointer). 00110 */ 00111 virtual void set_model(Model* model); 00112 00113 //! Return the model containing this restraint 00114 Model *get_model() const { 00115 IMP_INTERNAL_CHECK(model_, 00116 "get_model() called before set_model()"); 00117 return model_; 00118 } 00119 00120 //! Return true if this particle is part of a model 00121 bool get_is_part_of_model() const { 00122 return model_; 00123 } 00124 00125 #ifndef IMP_DOXYGEN 00126 virtual double 00127 unprotected_incremental_evaluate(DerivativeAccumulator *) const { 00128 IMP_FAILURE(get_name() << " does not support incremental evaluation."); 00129 return 0; 00130 } 00131 virtual double unprotected_evaluate(DerivativeAccumulator *) const=0; 00132 00133 #endif 00134 00135 //! Restraints cannot update other objects 00136 ObjectsTemp get_output_objects() const { 00137 return ObjectsTemp(); 00138 } 00139 //! Restraints cannot update other particles 00140 ParticlesTemp get_output_particles() const { 00141 return ParticlesTemp(); 00142 } 00143 00144 /** \name Interactions 00145 Certain sorts of operations, such as evaluation of restraints in 00146 isolation, benefit from being able to determine which containers 00147 and particles are needed by which restraints. 00148 @{ 00149 */ 00150 virtual ContainersTemp get_input_containers() const=0; 00151 /** Given that the containers are up to date.*/ 00152 virtual ParticlesTemp get_input_particles() const=0; 00153 virtual ParticlesList get_interacting_particles() const=0; 00154 /** @} */ 00155 00156 IMP_REF_COUNTED_DESTRUCTOR(Restraint); 00157 private: 00158 /* This pointer should never be ref counted as Model has a 00159 pointer to this object. 00160 */ 00161 WeakPointer<Model> model_; 00162 }; 00163 00164 IMP_END_NAMESPACE 00165 00166 // for Restraints 00167 #include "Model.h" 00168 00169 #endif /* IMP_RESTRAINT_H */