00001 /** 00002 * \file SingletonModifier.h \brief A Modifier on Particles 00003 * 00004 * This file is generated by a script (core/tools/make-container). 00005 * Do not edit directly. 00006 * 00007 * Copyright 2007-2010 IMP Inventors. All rights reserved. 00008 */ 00009 00010 #ifndef IMP_SINGLETON_MODIFIER_H 00011 #define IMP_SINGLETON_MODIFIER_H 00012 00013 #include "kernel_config.h" 00014 #include "internal/container_helpers.h" 00015 #include "DerivativeAccumulator.h" 00016 #include "base_types.h" 00017 #include "VectorOfRefCounted.h" 00018 00019 IMP_BEGIN_NAMESPACE 00020 // to keep swig happy 00021 class Particle; 00022 00023 //! A base class for modifiers of Particles 00024 /** The primary function of such a class is to change 00025 the passed particles. 00026 00027 A given SingletonModifier may only work when passed a 00028 DerivativeAccumulator or when not passed one. 00029 00030 \see IMP::SingletonFunctor 00031 00032 Implementors should see IMP_SINGLETON_MODIFIER() and 00033 IMP_SINGLETON_MODIFIER_DA(). 00034 */ 00035 class IMPEXPORT SingletonModifier : public Object 00036 { 00037 public: 00038 SingletonModifier(std::string name="SingletonModifier %1%"); 00039 00040 /** Apply the function to a single value*/ 00041 virtual void apply(Particle* vt, 00042 DerivativeAccumulator &da) const { 00043 IMP_FAILURE("This SingletonModifier must be called without a" 00044 << " DerivativeAccumulator."); 00045 } 00046 00047 /** Apply the function to a single value*/ 00048 virtual void apply(Particle* vt) const { 00049 IMP_FAILURE("This SingletonModifier must be called with a" 00050 << " DerivativeAccumulator."); 00051 } 00052 00053 /** Apply the function to a collection of Particles */ 00054 virtual void apply(const ParticlesTemp &o) const { 00055 IMP_FAILURE("This SingletonModifier must be called with a" 00056 << " DerivativeAccumulator."); 00057 } 00058 00059 /** Apply the function to a collection of Particles */ 00060 virtual void apply(const ParticlesTemp &o, 00061 DerivativeAccumulator &da) const { 00062 IMP_FAILURE("This SingletonModifier must be called without a" 00063 << " DerivativeAccumulator."); 00064 } 00065 00066 /** Get the set of interactions induced by applying to the 00067 argument.*/ 00068 virtual ParticlesList 00069 get_interacting_particles(Particle* vt) const =0; 00070 00071 /** Get the set of particles read when applied to the arguments.*/ 00072 virtual ParticlesTemp 00073 get_input_particles(Particle* vt) const =0; 00074 /** Get the set of particles modifier when applied to the arguments.*/ 00075 virtual ParticlesTemp 00076 get_output_particles(Particle* vt) const =0; 00077 /** Get the set of input containers when this modifier is applied to 00078 the arguments. */ 00079 virtual ContainersTemp 00080 get_input_containers(Particle* vt) const =0; 00081 /** Get the set of output containers when this modifier is applied to 00082 the arguments. */ 00083 virtual ContainersTemp 00084 get_output_containers(Particle* vt) const =0; 00085 }; 00086 00087 IMP_OUTPUT_OPERATOR(SingletonModifier); 00088 00089 00090 IMP_OBJECTS(SingletonModifier); 00091 00092 //! Create a functor which can be used with build in C++ and python commands 00093 /** For example, you can do 00094 \code 00095 std::for_each(particles.begin(), particles.end(), 00096 IMP::SingletonFunctor(new IMP::core::Transform(tr))); 00097 IMP::for_each(particles, 00098 IMP::SingletonFunctor(new IMP::core::Transform(tr))); 00099 \endcode 00100 in C++ (the second can be used with when \c particles is a temporary 00101 value) or 00102 \verbatim 00103 map(SingletonFunctor(Transform(tr)), particles) 00104 \endverbatim 00105 in python. 00106 00107 \see IMP::SingletonModifier 00108 */ 00109 class SingletonFunctor { 00110 Pointer<const SingletonModifier> f_; 00111 DerivativeAccumulator *da_; 00112 public: 00113 //! Store the SingletonModifier and the optional DerivativeAccumulator 00114 SingletonFunctor(const SingletonModifier *f): f_(f), da_(NULL){} 00115 SingletonFunctor(const SingletonModifier *f, 00116 DerivativeAccumulator *da): f_(f), da_(da){ 00117 IMP_USAGE_CHECK(da_, 00118 "The passed derivative accumulator should not be null."); 00119 } 00120 void operator()( Particle* p) const { 00121 if (da_) { 00122 f_->apply(p, *da_); 00123 } else { 00124 f_->apply(p); 00125 } 00126 } 00127 }; 00128 00129 00130 00131 IMP_END_NAMESPACE 00132 00133 #endif /* IMP_SINGLETON_MODIFIER_H */