Index: kernel/test/states/test_nonbonded_list.py =================================================================== --- kernel/test/states/test_nonbonded_list.py (revision 0) +++ kernel/test/states/test_nonbonded_list.py (revision 0) @@ -0,0 +1,33 @@ +import unittest +import IMP, IMP.test +import os.path + +class OnePair(IMP.PairScore): + def evaluate(self, da): + return 1 + + +class TestNBL(IMP.test.TestCase): + def setUp(self): + IMP.set_log_level(IMP.TERSE) + + def test_it(self): + """Test the nonbonded list and restraint which uses it""" + m= IMP.Model() + for i in range(0,10): + p= IMP.Particle() + m.add_particle(p) + d=IMP.XYZDecorator.create(p) + d.set_x(0) + d.set_y(1) + d.set_z(1) + s= IMP.NonbondedListScoreState(m.get_particles(), 100) + m.add_score_state(s) + r= IMP.NonbondedRestraint(s, OnePair()) + m.add_restraint(r) + score= m.evaluate() + self.assertEqual(score, 45, "Wrong score") + + +if __name__ == '__main__': + unittest.main() Index: kernel/include/IMP/SConscript =================================================================== --- kernel/include/IMP/SConscript (revision 326) +++ kernel/include/IMP/SConscript (working copy) @@ -18,3 +18,5 @@ SConscript('optimizers/SConscript') SConscript('decorators/SConscript') SConscript('unary_functions/SConscript') +SConscript('pair_scores/SConscript') +SConscript('score_states/SConscript') Index: kernel/include/IMP/utility.h =================================================================== --- kernel/include/IMP/utility.h (revision 326) +++ kernel/include/IMP/utility.h (working copy) @@ -40,6 +40,41 @@ return (field<= o.field); \ } +//! Implement comparison in a class using field as the variable to compare +/** The macro requires that This be defined as the type of the current class. + */ +#define IMP_COMPARISONS_2(f0, f1) \ + /** */ bool operator==(const This &o) const { \ + return (f0== o.f0 && f1==o.f1); \ + } \ + /** */ bool operator!=(const This &o) const { \ + return (f0!= o.f0 || f1 != o.f1); \ + } \ + /** */ bool operator<(const This &o) const { \ + IMP_assert(!is_default() && !o.is_default(), \ + "Ordering with uninitialized index is undefined"); \ + if (f0< o.f0) return true; \ + else if (f0 > o.f0) return false; \ + else return f1 < o.f1; \ + } \ + /** */ bool operator>(const This &o) const { \ + IMP_assert(!is_default() && !o.is_default(), \ + "Ordering with uninitialized index is undefined"); \ + if (f0 > o.f0) return true; \ + else if (f0 < o.f0) return false; \ + else return f1 > o.f1; \ + } \ + /** */ bool operator>=(const This &o) const { \ + IMP_assert(!is_default() && !o.is_default(), \ + "Ordering with uninitialized index is undefined"); \ + return operator>(o) || operator==(o); \ + } \ + /** */ bool operator<=(const This &o) const { \ + IMP_assert(!is_default() && !o.is_default(), \ + "Ordering with uninitialized index is undefined"); \ + return operator<(o) || operator==(o); \ + } + //! Implement operator<< on class name, assuming it has one template argument /** class name should also define the method std::ostream &show(std::ostream&) */ @@ -92,7 +127,32 @@ virtual std::string last_modified_by() const {return std::string(lmb_string);} +//! Define the basics needed for an OptimizerState +/** + This macro declares the required functions + - void update() + - void show(std::ostream &out) const + and defines the functions + - version + - last_modified_by + \param[in] version_string The version. + \param[in] lmb_string The person who last modified it. +*/ +#define IMP_OPTIMIZER_STATE(version_string, lmb_string) \ + /** update the state*/ \ + virtual void update(); \ + /** write information about the state to the stream*/ \ + virtual void show(std::ostream &out=std::cout) const; \ + /** \return the current version*/ \ + virtual std::string version() const {return std::string(version_string);} \ + /** \return the last person to modify this restraint */ \ + virtual std::string last_modified_by() const {return std::string(lmb_string);} + +//! See IMP_OPTIMIZER_STATE +#define IMP_SCORE_STATE(version_string, lmb_string)\ + IMP_OPTIMIZER_STATE(version_string, lmb_string) + //! Use the swap_with member function to swap two objects #define IMP_SWAP(name) \ inline void swap(name &a, name &b) { \ Index: kernel/include/IMP/score_states/NonbondedListScoreState.h =================================================================== --- kernel/include/IMP/score_states/NonbondedListScoreState.h (revision 0) +++ kernel/include/IMP/score_states/NonbondedListScoreState.h (revision 0) @@ -0,0 +1,59 @@ +/** + * \file NonbondedListScoreState.h + * \brief Allow iteration through pairs of a set of atoms. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ + +#ifndef __IMP_NONBONDEDLISTSCORESTATE_H +#define __IMP_NONBONDEDLISTSCORESTATE_H + +#include "../ScoreState.h" +#include "BondedListScoreState.h" +#include +#include + +namespace IMP +{ + class BondedListScoreState; + //! This class maintains a list of non-bonded pairs. + /** + The distance cutoff is an optimization hint rather than a + strict cutoff. That is, the NonbondedListScoreState may + choose to ignore pairs above that cutoff, but may not. + */ + class IMPDLLEXPORT NonbondedListScoreState: public ScoreState { + Particles ps_; + typedef std::vector > NBL; + NBL nbl_; + float dist_cutoff_; + + void rescan(); + + public: + NonbondedListScoreState(const Particles &ps, + float dist_cutoff + =std::numeric_limits::max()); + virtual ~NonbondedListScoreState(){} + IMP_CONTAINER(BondedListScoreState, bonded_list_score_state, + BondedListIndex); + public: + IMP_SCORE_STATE("0.5", "Daniel Russel"); + + void set_particles(const Particles &ps); + + //! This iterates through the pairs of non-bonded particles + /** + \precondition update() must be called first for this to be valid. + */ + typedef NBL::const_iterator NonbondedIterator; + NonbondedIterator nonbonded_begin() const { + return nbl_.begin(); + } + NonbondedIterator nonbonded_end() const { + return nbl_.end(); + } + }; + +} +#endif Index: kernel/include/IMP/score_states/SConscript =================================================================== --- kernel/include/IMP/score_states/SConscript (revision 0) +++ kernel/include/IMP/score_states/SConscript (revision 0) @@ -0,0 +1,9 @@ +import os.path +Import('env') + +files = ['BondedListScoreState.h', 'NonbondedListScoreState.h'] + +# Install the include files: +includedir = os.path.join(env['includedir'], 'IMP', 'score_states') +inst = env.Install(includedir, files) +env.Alias('install', inst) Index: kernel/include/IMP/score_states/BondedListScoreState.h =================================================================== --- kernel/include/IMP/score_states/BondedListScoreState.h (revision 0) +++ kernel/include/IMP/score_states/BondedListScoreState.h (revision 0) @@ -0,0 +1,55 @@ +/** + * \file BondedListScoreState.h + * \brief Allow iteration through pairs of a set of atoms. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ + +#ifndef __IMP_BONDEDLISTSCORESTATE_H +#define __IMP_BONDEDLISTSCORESTATE_H + +#include "../ScoreState.h" +#include "../Index.h" +#include "../Particle.h" +#include + +namespace IMP +{ + class BondedListScoreState; + typedef Index BondedListIndex; + + //! This abstract class maintains a list of bonded pairs. + class IMPDLLEXPORT BondedListScoreState: public ScoreState { + struct BP: public std::pair { + typedef BP This; + typedef std::pair P; + BP(): P(NULL, NULL){} + bool is_default() const {return first==NULL && second==NULL;} + BP(Particle* a, Particle *b): P(std::min(a,b),std::max(a,b)){} + IMP_COMPARISONS_2(first, second); + }; + //std::set bonds_; + + public: + BondedListScoreState(){} + virtual ~BondedListScoreState(){} + //IMP_SCORE_STATE("0.5", "Daniel Russel"); + + virtual bool are_bonded(Particle *a, Particle *b) const =0; +#if 0 + //! This iterates through the pairs of non-bonded particles + /** + \precondition update() must be called first for this to be valid. + */ + typedef std::set::const_iterator BondedIterator; + BondedIterator bonded_begin() const { + return bonds_.begin(); + } + BondedIterator bonded_end() const { + return bonds_.end(); + } +#endif + }; + +} +#endif Index: kernel/include/IMP/restraints/SConscript =================================================================== --- kernel/include/IMP/restraints/SConscript (revision 326) +++ kernel/include/IMP/restraints/SConscript (working copy) @@ -4,7 +4,7 @@ files = ['ConnectivityRestraint.h', 'ProximityRestraint.h', 'SphericalRestraint.h', 'DistanceRestraint.h', 'AngleRestraint.h', 'DihedralRestraint.h', 'RestraintSet.h', 'ExclusionVolumeRestraint.h', - 'TorusRestraint.h', 'PairConnectivityRestraint.h'] + 'TorusRestraint.h', 'PairConnectivityRestraint.h', 'NonbondedRestraint.h'] # Install the include files: includedir = os.path.join(env['includedir'], 'IMP', 'restraints') Index: kernel/include/IMP/restraints/NonbondedRestraint.h =================================================================== --- kernel/include/IMP/restraints/NonbondedRestraint.h (revision 0) +++ kernel/include/IMP/restraints/NonbondedRestraint.h (revision 0) @@ -0,0 +1,50 @@ +/** + * \file NonbondedRestraint.h + * \brief Apply a PairScore to all nonbonded pairs. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + * + */ + +#ifndef __IMP_NEARBYPAIRS_RESTRAINT_H +#define __IMP_NEARBYPAIRS_RESTRAINT_H + +#include +#include + +#include "../IMP_config.h" +#include "../ModelData.h" +#include "../Restraint.h" + + +namespace IMP +{ + +class NonbondedListScoreState; +class PairScore; + +//! Restraint all pairs of non-bonded particles +/** + */ +class IMPDLLEXPORT NonbondedRestraint : public Restraint +{ +public: + //! Create the nonbonded restraint. + /** \param[in] nbl The non-bonded list to use to get the list + of particles. + \param[in] ps The pair score function to apply to the pairs. This + object is deleted upon destruction. + */ + NonbondedRestraint(NonbondedListScoreState *nbl, PairScore *ps ); + virtual ~NonbondedRestraint(){} + + IMP_RESTRAINT("0.5", "Daniel Russel"); + + protected: + NonbondedListScoreState *nbl_; + std::auto_ptr sf_; +}; + +} // namespace IMP + +#endif /* __IMP_NONBONDED_RESTRAINT_H */ Index: kernel/include/IMP/restraints/DistanceRestraint.h =================================================================== --- kernel/include/IMP/restraints/DistanceRestraint.h (revision 326) +++ kernel/include/IMP/restraints/DistanceRestraint.h (working copy) @@ -12,8 +12,7 @@ #include #include "../IMP_config.h" -#include "../ModelData.h" -#include "../UnaryFunction.h" +#include "../pair_scores/DistancePairScore.h" #include "../Restraint.h" @@ -35,13 +34,13 @@ */ DistanceRestraint(Particle* p1, Particle* p2, UnaryFunction* score_func); - virtual ~DistanceRestraint(); + virtual ~DistanceRestraint(){} IMP_RESTRAINT("0.5", "Daniel Russel") protected: //! scoring function for this restraint - UnaryFunction* score_func_; + DistancePairScore dp_; }; } // namespace IMP Index: kernel/include/IMP/decorators/graph_base.h =================================================================== --- kernel/include/IMP/decorators/graph_base.h (revision 326) +++ kernel/include/IMP/decorators/graph_base.h (working copy) @@ -102,4 +102,115 @@ } // namespace IMP +//! Define a class of graphs +/** + This defines several methods. It depends on there being a class + UCNameDecorator which defines the edges data. It also requires that + the method + - UCNameDecorator lcname(UCNamedDecorator, UCNamedDecorator) + be defined. +*/ +#define IMP_DECLARE_GRAPH(UCName, lcname) \ + class UCName##Decorator; \ + class UCName##edDecorator; \ + \ + namespace internal \ + { \ + extern IMPDLLEXPORT GraphData lcname##_graph_data_; \ + extern IMPDLLEXPORT bool lcname##_keys_initialized_; \ + } \ + \ + \ + /**\brief A decorator for a particle which has bonds. */ \ + class IMPDLLEXPORT UCName##edDecorator: public DecoratorBase \ + { \ + IMP_DECORATOR(UCName##edDecorator, DecoratorBase, return true, ); \ + public: \ + unsigned int get_number_of_##lcname##s() const { \ + return graph_get_number_of_edges(get_particle(), \ + internal::lcname##_graph_data_); \ + } \ + \ + \ + /**\brief Get a BondDecorator of the ith child + \return decorator of the ith child, or throw and exception if there + is no such bond + */ \ +UCName##Decorator get_##lcname(unsigned int i) const { \ + Particle *p= graph_get_edge(get_particle(), i, \ + internal::lcname##_graph_data_); \ + return UCName##Decorator::cast(p); \ +} \ +}; \ + \ +IMP_OUTPUT_OPERATOR(BondedDecorator); \ + \ + \ +UCName##edDecorator \ +UCName##Decorator::get_##lcname##ed(unsigned int i) const \ +{ \ + Particle *p= graph_get_node(get_particle(), i, \ + internal::lcname##_graph_data_); \ + return UCName##edDecorator::cast(p); \ +} \ + \ + \ +/** \brief Destroy the bond connecting two particles. + \param[in] b The bond. +*/ \ +IMPDLLEXPORT \ +void un#lcname(UCName##Decorator b); \ + \ + \ +/** + \brief Get the bond between two particles. + BondDecorator() is returned if the particles are not bonded. +*/ \ +IMPDLLEXPORT UCName##Decorator \ +get_##lcname(UCName##edDecorator a, UCName##edDecorator b); + + +#define IMP_DEFINE_GRAPH(UCName, lcname) \ + namespace internal \ + { \ + GraphData lcname##_graph_data_; \ + bool lcname##_keys_initialized_=false; \ + } \ + \ + \ + void UCName##Decorator \ + ::show(std::ostream &out, std::string) const \ + { \ + out << #UCName " between " \ + << get_##lcname##ed(0).get_particle()->get_index() << " and " \ + << get_##lcname##ed(1).get_particle()->get_index() \ + << " of type " << get_type() << " and order " << get_order() \ + << std::endl; \ + } \ + \ + \ + IMP_DECORATOR_INITIALIZE(UCName##Decorator, DecoratorBase, \ + lcname##_initialize_static_data()); \ + \ + \ + \ + \ + void un##lcname(UCName##Decorator b) { \ + graph_disconnect(b.get_particle(), internal::lcname##_graph_data_); \ + } \ + \ + UCName##Decorator \ + get_##lcname(UCName##edDecorator a, UCName##edDecorator b) { \ + for (unsigned int i=0; i < a.get_number_of_##lcname##s(); ++i) { \ + UCName##Decorator bd= a.get_##lcname(i); \ + if (bd.get_##lcname(0) == b || bd.get_##lcname(1) == b) { \ + return bd; \ + } \ + } \ + return UCName##Decorator(); \ + } \ + + +// define method setup_##lcname to do the combinatorial work for a bond +// check why I need bond? #endif /* __IMP_GRAPH_DECORATORS_H */ Index: kernel/include/IMP/pair_scores/SphereDistancePairScore.h =================================================================== --- kernel/include/IMP/pair_scores/SphereDistancePairScore.h (revision 0) +++ kernel/include/IMP/pair_scores/SphereDistancePairScore.h (revision 0) @@ -0,0 +1,35 @@ +/** + * \file SphereDistancePairScore.h + * \brief A Score on the distance between a pair of spheres. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ + +#ifndef __IMP_SPAIRSCORE_H +#define __IMP_SPAIRSCORE_H + +#include "../PairScore.h" + +namespace IMP +{ +class UnaryFunction; + +//! Apply a function to the distance between two particles. +/** + */ +class IMPDLLEXPORT SphereDistancePairScore : public PairScore +{ + std::auto_ptr f_; + FloatKey radius_; +public: + SphereDistancePairScore(UnaryFunction *f, + FloatKey radius=FloatKey("radius")); + virtual ~SphereDistancePairScore(){} + virtual Float evaluate(Particle *a, Particle *b, + DerivativeAccumulator *da); + virtual void show(std::ostream &out=std::cout) const; +}; + +} // namespace IMP + +#endif /* __IMP_SPHEREDISTANCEPAIRSCORE_H */ Index: kernel/include/IMP/pair_scores/SConscript =================================================================== --- kernel/include/IMP/pair_scores/SConscript (revision 0) +++ kernel/include/IMP/pair_scores/SConscript (revision 0) @@ -0,0 +1,9 @@ +import os.path +Import('env') + +files = ['DistancePairScore.h', 'SphereDistancePairScore.h'] + +# Install the include files: +includedir = os.path.join(env['includedir'], 'IMP', 'pair_scores') +inst = env.Install(includedir, files) +env.Alias('install', inst) Index: kernel/include/IMP/pair_scores/DistancePairScore.h =================================================================== --- kernel/include/IMP/pair_scores/DistancePairScore.h (revision 0) +++ kernel/include/IMP/pair_scores/DistancePairScore.h (revision 0) @@ -0,0 +1,33 @@ +/** + * \file DistancePairScore.h + * \brief A Score on the distance between a pair of particles. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ + +#ifndef __IMP_DPAIRSCORE_H +#define __IMP_DPAIRSCORE_H + +#include "../PairScore.h" +#include "../UnaryFunction.h" + +namespace IMP +{ + +//! Apply a function to the distance between two particles. +/** + */ +class IMPDLLEXPORT DistancePairScore : public PairScore +{ + std::auto_ptr f_; +public: + DistancePairScore(UnaryFunction *f); + virtual ~DistancePairScore(){} + virtual Float evaluate(Particle *a, Particle *b, + DerivativeAccumulator *da); + virtual void show(std::ostream &out=std::cout) const; +}; + +} // namespace IMP + +#endif /* __IMP_DISTANCEPAIRSCORE_H */ Index: kernel/include/IMP/PairScore.h =================================================================== --- kernel/include/IMP/PairScore.h (revision 0) +++ kernel/include/IMP/PairScore.h (revision 0) @@ -0,0 +1,35 @@ +/** + * \file PairScore.h \brief A Score on a pair of particles. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ + +#ifndef __IMP_PAIRSCORE_H +#define __IMP_PAIRSCORE_H + +#include "IMP_config.h" +#include "base_types.h" +#include "Object.h" +#include "Particle.h" +#include "DerivativeAccumulator.h" + +namespace IMP +{ + +//! Abstract score function for a pair of particles. +/** + */ +class IMPDLLEXPORT PairScore : public Object +{ +public: + PairScore() {} + virtual ~PairScore() {} + //! Compute the score for the pair and the deriv if needed. + virtual Float evaluate(Particle *a, Particle *b, + DerivativeAccumulator *da) = 0; + virtual void show(std::ostream &out=std::cout) const = 0; +}; + +} // namespace IMP + +#endif /* __IMP_PAIRSCORE_H */ Index: kernel/include/IMP.h =================================================================== --- kernel/include/IMP.h (revision 326) +++ kernel/include/IMP.h (working copy) @@ -23,6 +23,7 @@ #include "IMP/RigidBody.h" #include "IMP/ModelData.h" #include "IMP/Model.h" +#include "IMP/PairScore.h" #include "IMP/Vector3D.h" #include "IMP/decorators/HierarchyDecorator.h" #include "IMP/decorators/MolecularHierarchyDecorator.h" @@ -35,6 +36,8 @@ #include "IMP/optimizers/ConjugateGradients.h" #include "IMP/optimizers/MolecularDynamics.h" #include "IMP/optimizers/states/VRMLLogOptimizerState.h" +#include "IMP/pair_scores/DistancePairScore.h" +#include "IMP/pair_scores/SphereDistancePairScore.h" #include "IMP/restraints/RestraintSet.h" #include "IMP/restraints/DistanceRestraint.h" #include "IMP/restraints/AngleRestraint.h" @@ -45,6 +48,9 @@ #include "IMP/restraints/ConnectivityRestraint.h" #include "IMP/restraints/PairConnectivityRestraint.h" #include "IMP/restraints/ExclusionVolumeRestraint.h" +#include "IMP/restraints/NonbondedRestraint.h" +#include "IMP/score_states/NonbondedListScoreState.h" +#include "IMP/score_states/BondedListScoreState.h" /** \namespace IMP The IMP namespace. Index: kernel/src/SConscript =================================================================== --- kernel/src/SConscript (revision 326) +++ kernel/src/SConscript (working copy) @@ -9,6 +9,8 @@ optimizers_files = SConscript('optimizers/SConscript') decorators_files = SConscript('decorators/SConscript') unary_functions_files = SConscript('unary_functions/SConscript') +pair_scores_files = SConscript('pair_scores/SConscript') +score_states_files = SConscript('score_states/SConscript') # Source files files = ['base_types.cpp', 'Model.cpp', 'ModelData.cpp', @@ -16,7 +18,7 @@ 'OptimizerState.cpp', 'Log.cpp', 'Restraint.cpp', 'Optimizer.cpp', 'Object.cpp', 'BasicScoreFuncParams.cpp' ] + decorators_files + restraints_files + optimizers_files \ - + unary_functions_files + + unary_functions_files + pair_scores_files + score_states_files # Build the shared library: lib = env.SharedLibrary('imp', files) Index: kernel/src/score_states/NonbondedListScoreState.cpp =================================================================== --- kernel/src/score_states/NonbondedListScoreState.cpp (revision 0) +++ kernel/src/score_states/NonbondedListScoreState.cpp (revision 0) @@ -0,0 +1,52 @@ +/** + * \file NonbondedListScoreState.cpp + * \brief Allow iteration through pairs of a set of atoms. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ + +#include "IMP/score_states/NonbondedListScoreState.h" + +namespace IMP { + NonbondedListScoreState::NonbondedListScoreState(const Particles &ps, + float dist_cutoff): + dist_cutoff_(dist_cutoff) + { + set_particles(ps); + } + + void NonbondedListScoreState::rescan() { + nbl_.clear(); + for (unsigned int i=0; i< ps_.size(); ++i) { + Particle *pi= ps_[i]; + for (unsigned int j=0; j < i; ++j) { + Particle *pj= ps_[j]; + bool found=false; + for (BondedListScoreStateIterator bli= bonded_list_score_states_begin(); + bli != bonded_list_score_states_end(); ++bli) { + if ((*bli)->are_bonded(pi, pj)) { + found=true; + break; + } + } + if (!found) { + nbl_.push_back(std::make_pair(pi, pj)); + } + } + } + } + + void NonbondedListScoreState::set_particles(const Particles &ps) { + ps_=ps; + rescan(); + } + void NonbondedListScoreState::update() { + rescan(); + } + void NonbondedListScoreState::show(std::ostream &out) const { + out << "NonbondedList" << std::endl; + } + + IMP_CONTAINER_IMPL(NonbondedListScoreState, BondedListScoreState, + bonded_list_score_state, BondedListIndex, ); +} Index: kernel/src/score_states/BondedListScoreState.cpp =================================================================== --- kernel/src/score_states/BondedListScoreState.cpp (revision 0) +++ kernel/src/score_states/BondedListScoreState.cpp (revision 0) @@ -0,0 +1,11 @@ +/** + * \file BondedListScoreState.cpp + * \brief Allow iteration through pairs of a set of atoms. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ +#include "IMP/score_states/BondedListScoreState.h" + +namespace IMP { + +} Index: kernel/src/score_states/SConscript =================================================================== --- kernel/src/score_states/SConscript (revision 0) +++ kernel/src/score_states/SConscript (revision 0) @@ -0,0 +1,6 @@ +Import('env') + +files = ['BondedListScoreState.cpp', 'NonbondedListScoreState.cpp'] + +files = [File(x) for x in files] +Return('files') Index: kernel/src/restraints/NonbondedRestraint.cpp =================================================================== --- kernel/src/restraints/NonbondedRestraint.cpp (revision 0) +++ kernel/src/restraints/NonbondedRestraint.cpp (revision 0) @@ -0,0 +1,49 @@ +/** + * \file NonbondedRestraint.cpp + * \brief A nonbonded restraint. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + * + */ + +#include + +#include "IMP/PairScore.h" +#include "IMP/log.h" +#include "IMP/restraints/NonbondedRestraint.h" +#include "IMP/score_states/NonbondedListScoreState.h" + +namespace IMP +{ + +NonbondedRestraint::NonbondedRestraint(NonbondedListScoreState *nbl, + PairScore *ps ) + : nbl_(nbl), sf_(ps) +{ +} + + +Float NonbondedRestraint::evaluate(DerivativeAccumulator *accum) +{ + + IMP_CHECK_OBJECT(sf_); + IMP_CHECK_OBJECT(nbl_); + Float score=0; + + for (NonbondedListScoreState::NonbondedIterator it= nbl_->nonbonded_begin(); + it != nbl_->nonbonded_end(); ++it) { + sf_->evaluate(it->first, it->second, accum); + } + + return score; +} + + +void NonbondedRestraint::show(std::ostream& out) const +{ + out << "Nonbonded restraint with score function "; + sf_->show(out); + out << std::endl; +} + +} // namespace IMP Index: kernel/src/restraints/DistanceRestraint.cpp =================================================================== --- kernel/src/restraints/DistanceRestraint.cpp (revision 326) +++ kernel/src/restraints/DistanceRestraint.cpp (working copy) @@ -12,6 +12,7 @@ #include "IMP/log.h" #include "IMP/restraints/DistanceRestraint.h" #include "IMP/decorators/XYZDecorator.h" +#include "IMP/pair_scores/DistancePairScore.h" namespace IMP { @@ -20,22 +21,13 @@ static const Float MIN_DISTANCE = 0.0000001; DistanceRestraint::DistanceRestraint(Particle* p1, Particle* p2, - UnaryFunction* score_func) + UnaryFunction* score_func): + dp_(score_func) { add_particle(p1); add_particle(p2); - - score_func_ = score_func; } - -//! Destructor -DistanceRestraint::~DistanceRestraint() -{ - delete score_func_; -} - - //! Calculate the score for this distance restraint. /** \param[in] accum If not NULL, use this object to accumulate partial first derivatives. @@ -43,48 +35,7 @@ */ Float DistanceRestraint::evaluate(DerivativeAccumulator *accum) { - - IMP_CHECK_OBJECT(score_func_); - - Float d2=0, delta[3]; - Float score; - - XYZDecorator d0= XYZDecorator::cast(get_particle(0)); - XYZDecorator d1= XYZDecorator::cast(get_particle(1)); - for (int i=0; i< 3; ++i ){ - delta[i]= d0.get_coordinate(i)- d1.get_coordinate(i); - d2+= square(delta[i]); - } - - Float distance = std::sqrt(d2); - - // if needed, calculate the partial derivatives of the scores with respect - // to the particle attributes - // avoid division by zero if the distance is too small - if (accum && distance >= MIN_DISTANCE) { - Float deriv; - - // calculate the score and feature derivative based on the distance feature - score = (*score_func_)(distance, deriv); - - for (int i=0; i< 3; ++i ){ - Float d= delta[i]/distance*deriv; - d0.add_to_coordinate_derivative(i, d, *accum); - d1.add_to_coordinate_derivative(i, -d, *accum); - } - - } - - else { - // calculate the score based on the distance feature - score = (*score_func_)(distance); - } - - IMP_LOG(VERBOSE, "For " << get_particle(0)->get_index() - << " and " << get_particle(1)->get_index() - << " distance: " << distance - << " score: " << score << std::endl); - return score; + return dp_.evaluate(get_particle(0), get_particle(1), accum); } @@ -104,7 +55,7 @@ out << " particles: " << get_particle(0)->get_index(); out << " and " << get_particle(1)->get_index(); out << " "; - score_func_->show(out); + dp_.show(out); out << std::endl; } Index: kernel/src/restraints/SConscript =================================================================== --- kernel/src/restraints/SConscript (revision 326) +++ kernel/src/restraints/SConscript (working copy) @@ -4,7 +4,8 @@ 'ConnectivityRestraint.cpp', 'ProximityRestraint.cpp', 'SphericalRestraint.cpp', 'RestraintSet.cpp', 'DistanceRestraint.cpp', 'AngleRestraint.cpp', 'DihedralRestraint.cpp', - 'TorusRestraint.cpp', 'ExclusionVolumeRestraint.cpp'] + 'TorusRestraint.cpp', 'ExclusionVolumeRestraint.cpp', + 'NonbondedRestraint.cpp'] files = [File(x) for x in files] Return('files') Index: kernel/src/decorators/bond_decorators.cpp =================================================================== --- kernel/src/decorators/bond_decorators.cpp (revision 326) +++ kernel/src/decorators/bond_decorators.cpp (working copy) @@ -16,7 +16,6 @@ GraphData bond_graph_data_; bool bond_keys_initialized_=false; -FloatKey bond_length_key_; IntKey bond_type_key_; IntKey bond_order_key_; Index: kernel/src/pair_scores/DistancePairScore.cpp =================================================================== --- kernel/src/pair_scores/DistancePairScore.cpp (revision 0) +++ kernel/src/pair_scores/DistancePairScore.cpp (revision 0) @@ -0,0 +1,65 @@ +/** + * \file DistancePairScore.cpp + * \brief A Score on the distance between a pair of particles. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ + +#include "IMP/pair_scores/DistancePairScore.h" +#include "IMP/decorators/XYZDecorator.h" +#include "IMP/UnaryFunction.h" + +namespace IMP { + + static const Float MIN_DISTANCE=.00001; + + DistancePairScore::DistancePairScore(UnaryFunction *f): f_(f){} + + Float DistancePairScore::evaluate(Particle *a, Particle *b, + DerivativeAccumulator *da) { + IMP_CHECK_OBJECT(f_); + + Float d2=0, delta[3]; + Float score; + + XYZDecorator d0= XYZDecorator::cast(a); + XYZDecorator d1= XYZDecorator::cast(b); + for (int i=0; i< 3; ++i ){ + delta[i]= d0.get_coordinate(i)- d1.get_coordinate(i); + d2+= square(delta[i]); + } + + Float distance = std::sqrt(d2); + + // if needed, calculate the partial derivatives of the scores with respect + // to the particle attributes + // avoid division by zero if the distance is too small + if (da && distance >= MIN_DISTANCE) { + Float deriv; + + score = (*f_)(distance, deriv); + + for (int i=0; i< 3; ++i ){ + Float d= delta[i]/distance*deriv; + d0.add_to_coordinate_derivative(i, d, *da); + d1.add_to_coordinate_derivative(i, -d, *da); + } + } + else { + // calculate the score based on the distance feature + score = (*f_)(distance); + } + + IMP_LOG(VERBOSE, "For " << a->get_index() + << " and " << b->get_index() + << " distance: " << distance + << " score: " << score << std::endl); + return score; + } + + void DistancePairScore::show(std::ostream &out) const { + out << "DistancePairScore using "; + f_->show(out); + } + +} Index: kernel/src/pair_scores/SConscript =================================================================== --- kernel/src/pair_scores/SConscript (revision 0) +++ kernel/src/pair_scores/SConscript (revision 0) @@ -0,0 +1,6 @@ +Import('env') + +files = ['DistancePairScore.cpp', 'SphereDistancePairScore.cpp'] + +files = [File(x) for x in files] +Return('files') Index: kernel/src/pair_scores/SphereDistancePairScore.cpp =================================================================== --- kernel/src/pair_scores/SphereDistancePairScore.cpp (revision 0) +++ kernel/src/pair_scores/SphereDistancePairScore.cpp (revision 0) @@ -0,0 +1,71 @@ +/** + * \file SphereDistancePairScore.cpp + * \brief A Score on the distance between a pair of particles. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ + +#include "IMP/pair_scores/SphereDistancePairScore.h" +#include "IMP/decorators/XYZDecorator.h" +#include "IMP/UnaryFunction.h" + +namespace IMP { + + static const Float MIN_DISTANCE =.00001; + + SphereDistancePairScore::SphereDistancePairScore(UnaryFunction *f, + FloatKey radius): f_(f), + radius_(radius){} + + Float SphereDistancePairScore::evaluate(Particle *a, Particle *b, + DerivativeAccumulator *da) { + IMP_CHECK_OBJECT(f_); + + Float d2=0, delta[3]; + Float score; + + XYZDecorator d0= XYZDecorator::cast(a); + XYZDecorator d1= XYZDecorator::cast(b); + for (int i=0; i< 3; ++i ){ + delta[i]= d0.get_coordinate(i)- d1.get_coordinate(i); + d2+= square(delta[i]); + } + + Float distance = std::sqrt(d2); + Float ra= a->get_value(radius_); + Float rb= b->get_value(radius_); + Float shifted_distance = distance- (ra+rb); + + // if needed, calculate the partial derivatives of the scores with respect + // to the particle attributes + // avoid division by zero if the distance is too small + if (da && distance >= MIN_DISTANCE) { + Float deriv; + + score = (*f_)(shifted_distance, deriv); + + for (int i=0; i< 3; ++i ){ + Float d= delta[i]/distance*deriv; + d0.add_to_coordinate_derivative(i, d, *da); + d1.add_to_coordinate_derivative(i, -d, *da); + } + } + + else { + // calculate the score based on the distance feature + score = (*f_)(shifted_distance); + } + + IMP_LOG(VERBOSE, "For " << a->get_index() + << " and " << b->get_index() + << " distance: " << distance + << " score: " << score << std::endl); + return score; + } + + void SphereDistancePairScore::show(std::ostream &out) const { + out << "SphereDistancePairScore using "; + f_->show(out); + } + +} Index: kernel/pyext/IMP_macros.i =================================================================== --- kernel/pyext/IMP_macros.i (revision 326) +++ kernel/pyext/IMP_macros.i (working copy) @@ -35,3 +35,12 @@ const std::vector &get_##lcname##s() const {\ return lcname##_vector_;}\ + #define IMP_OPTIMIZER_STATE(version_string, lmb_string) \ + virtual void update(); \ + virtual void show(std::ostream &out=std::cout) const; \ + virtual std::string version() const {return std::string(version_string);} \ + virtual std::string last_modified_by() const {return std::string(lmb_string);} + + +#define IMP_SCORE_STATE(version_string, lmb_string)\ + IMP_OPTIMIZER_STATE(version_string, lmb_string) Index: kernel/pyext/IMP.i =================================================================== --- kernel/pyext/IMP.i (revision 326) +++ kernel/pyext/IMP.i (working copy) @@ -66,6 +66,7 @@ %include "IMP/OptimizerState.h" %include "IMP/log.h" %include "IMP/Model.h" +%include "IMP/PairScore.h" %include "IMP/Particle.h" %include "IMP/Vector3D.h" %include "IMP/DecoratorBase.h" @@ -82,6 +83,8 @@ %include "IMP/optimizers/ConjugateGradients.h" %include "IMP/optimizers/MolecularDynamics.h" %include "IMP/optimizers/states/VRMLLogOptimizerState.h" +%include "IMP/pair_scores/DistancePairScore.h" +%include "IMP/pair_scores/SphereDistancePairScore.h" %include "IMP/restraints/DistanceRestraint.h" %include "IMP/restraints/AngleRestraint.h" %include "IMP/restraints/DihedralRestraint.h" @@ -91,6 +94,8 @@ %include "IMP/restraints/ConnectivityRestraint.h" %include "IMP/restraints/PairConnectivityRestraint.h" %include "IMP/restraints/ExclusionVolumeRestraint.h" +%include "IMP/score_states/BondedListScoreState.h" +%include "IMP/score_states/NonbondedListScoreState.h" %include "IMP/RigidBody.h" namespace IMP {