Index: kernel/include/IMP.h =================================================================== --- kernel/include/IMP.h (revision 338) +++ kernel/include/IMP.h (working copy) @@ -50,8 +50,11 @@ #include "IMP/restraints/PairConnectivityRestraint.h" #include "IMP/restraints/ExclusionVolumeRestraint.h" #include "IMP/restraints/NonbondedRestraint.h" +#include "IMP/restraints/BondDecoratorRestraint.h" #include "IMP/score_states/NonbondedListScoreState.h" +#include "IMP/score_states/BipartiteNonbondedListScoreState.h" #include "IMP/score_states/BondedListScoreState.h" +#include "IMP/score_states/bonded_lists/BondDecoratorListScoreState.h" /** \namespace IMP The IMP namespace. Index: kernel/include/IMP/decorators/bond_decorators.h =================================================================== --- kernel/include/IMP/decorators/bond_decorators.h (revision 338) +++ kernel/include/IMP/decorators/bond_decorators.h (working copy) @@ -30,6 +30,8 @@ extern IMPDLLEXPORT bool bond_keys_initialized_; extern IMPDLLEXPORT IntKey bond_type_key_; extern IMPDLLEXPORT IntKey bond_order_key_; +extern IMPDLLEXPORT FloatKey bond_length_key_; +extern IMPDLLEXPORT FloatKey bond_stiffness_key_; } // namespace internal @@ -48,7 +50,8 @@ public: //! The types a bond can have right now enum Type {UNKNOWN=-1, - COVALENT, HYDROGEN, DISULPHIDE, SALT, PEPTIDE + COVALENT, HYDROGEN, DISULPHIDE, SALT, PEPTIDE, + CUSTOM }; //! Get the atom i of the bond @@ -61,6 +64,11 @@ UNKNOWN); IMP_DECORATOR_GET_SET_OPT(order, internal::bond_order_key_, Int, Int, 1); + + IMP_DECORATOR_GET_SET_OPT(length, internal::bond_length_key_, Float, + Float, -1); + IMP_DECORATOR_GET_SET_OPT(stiffness, internal::bond_stiffness_key_, Float, + Float, -1); }; IMP_OUTPUT_OPERATOR(BondDecorator); @@ -81,7 +89,7 @@ } - //! Get a BondDecorator of the ith child + //! Get a BondDecorator of the ith bond /** \return decorator of the ith child, or throw and exception if there is no such bond */ @@ -90,12 +98,30 @@ internal::bond_graph_data_); return BondDecorator::cast(p); } + + //! Get a BondedDecorator of the ith bonded particle + /** \return decorator of the ith child, or throw and exception if there + is no such bond + + \note I don't entirely like having this here as it duplicates + functionality available otherwise, however it is such a fundamental + operation and kind of a pain to write. It also means that we + could later pull the edge endpoints into the vertex if + desired. + */ + BondedDecorator get_bonded(unsigned int i) const { + Particle *p= graph_get_edge(get_particle(), i, + internal::bond_graph_data_); + BondDecorator bd= BondDecorator::cast(p); + if (bd.get_bonded(0) == *this) return bd.get_bonded(1); + else return bd.get_bonded(0); + } }; IMP_OUTPUT_OPERATOR(BondedDecorator); -BondedDecorator BondDecorator::get_bonded(unsigned int i) const +inline BondedDecorator BondDecorator::get_bonded(unsigned int i) const { Particle *p= graph_get_node(get_particle(), i, internal::bond_graph_data_); @@ -111,6 +137,25 @@ IMPDLLEXPORT BondDecorator bond(BondedDecorator a, BondedDecorator b, Int t); + +//! Connect the two wrapped particles by a custom bond. +/** \param[in] a The first Particle as a BondedDecorator + \param[in] b The second Particle as a BondedDecorator + \param[in] length The length of the bond. + \param[in] stiffness The stiffness of the bond. + \return BondDecorator of the bond Particle. + */ +IMPDLLEXPORT +inline BondDecorator custom_bond(BondedDecorator a, BondedDecorator b, + Float length, Float stiffness=-1) { + IMP_assert(length>=0, "Length must be positive"); + BondDecorator bd=bond(a,b, BondDecorator::CUSTOM); + bd.set_length(length); + if (stiffness >=0) bd.set_stiffness(stiffness); + return bd; +} + + //! Destroy the bond connecting to particles. /** \param[in] b The bond. */ Index: kernel/include/IMP/restraints/SConscript =================================================================== --- kernel/include/IMP/restraints/SConscript (revision 338) +++ kernel/include/IMP/restraints/SConscript (working copy) @@ -5,7 +5,7 @@ 'SphericalRestraint.h', 'DistanceRestraint.h', 'AngleRestraint.h', 'DihedralRestraint.h', 'RestraintSet.h', 'ExclusionVolumeRestraint.h', 'TorusRestraint.h', 'PairConnectivityRestraint.h', - 'NonbondedRestraint.h'] + 'NonbondedRestraint.h', 'BondDecoratorRestraint.h'] # Install the include files: includedir = os.path.join(env['includedir'], 'IMP', 'restraints') Index: kernel/include/IMP/score_states/SConscript =================================================================== --- kernel/include/IMP/score_states/SConscript (revision 338) +++ kernel/include/IMP/score_states/SConscript (working copy) @@ -1,9 +1,12 @@ import os.path Import('env') -files = ['BondedListScoreState.h', 'NonbondedListScoreState.h'] +files = ['BondedListScoreState.h', 'NonbondedListScoreState.h', + 'BipartiteNonbondedListScoreState.h'] # Install the include files: includedir = os.path.join(env['includedir'], 'IMP', 'score_states') inst = env.Install(includedir, files) env.Alias('install', inst) + +SConscript('bonded_lists/SConscript') Index: kernel/include/IMP/score_states/bonded_lists/BondDecoratorListScoreState.h =================================================================== --- kernel/include/IMP/score_states/bonded_lists/BondDecoratorListScoreState.h (revision 0) +++ kernel/include/IMP/score_states/bonded_lists/BondDecoratorListScoreState.h (revision 0) @@ -0,0 +1,57 @@ +/** + * \file BondedListScoreState.h + * \brief Allow iteration through pairs of a set of atoms. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ + +#ifndef __IMP_BONDEDDECORLISTSCORESTATE_H +#define __IMP_BONDEDDECORLISTSCORESTATE_H + +#include "../BondedListScoreState.h" +#include "../../decorators/bond_decorators.h" +#include + +namespace IMP +{ + class BondDecoratorListScoreState; + typedef Index BondDecoratorListIndex; + + //! Keep track of particles that are connected by BondDecorator bonds. + /** + We also may want to add lazy rescanning of bonds rather than doing + it every update call and a faster lookup of bonds. + */ + class IMPDLLEXPORT BondDecoratorListScoreState: public BondedListScoreState { + std::vector bonds_; + Particles ps_; + public: + //! Find bonds amongst the following points. + /** + \param [in] ps The set of particles to use. + */ + BondDecoratorListScoreState(const Particles &ps); + virtual ~BondDecoratorListScoreState(){} + //IMP_SCORE_STATE("0.5", "Daniel Russel"); + + virtual void set_particles(const Particles &ps); + + virtual bool are_bonded(Particle *a, Particle *b) const; + + virtual void update(); + + //! This iterates through the pairs of bonded particles + /** + \precondition update() must be called first for this to be valid. + */ + typedef std::vector::const_iterator BondIterator; + BondIterator bonds_begin() const { + return bonds_.begin(); + } + BondIterator bonds_end() const { + return bonds_.end(); + } + }; + +} +#endif Index: kernel/include/IMP/score_states/bonded_lists/SConscript =================================================================== --- kernel/include/IMP/score_states/bonded_lists/SConscript (revision 0) +++ kernel/include/IMP/score_states/bonded_lists/SConscript (revision 0) @@ -0,0 +1,9 @@ +import os.path +Import('env') + +files = ['BondDecoratorListScoreState.h'] + +# Install the include files: +includedir = os.path.join(env['includedir'], 'IMP', 'score_states', 'bonded_lists') +inst = env.Install(includedir, files) +env.Alias('install', inst) Index: kernel/pyext/IMP.i =================================================================== --- kernel/pyext/IMP.i (revision 338) +++ kernel/pyext/IMP.i (working copy) @@ -28,6 +28,9 @@ %pythonprepend RestraintSet::add_restraint %{ args[1].thisown=0 %} + %pythonprepend NonbondedListScoreState::add_bonded_list %{ + args[1].thisown=0 + %} %pythonprepend DistanceRestraint::DistanceRestraint %{ args[2].thisown=0 %} @@ -46,6 +49,9 @@ %pythonprepend NonbondedRestraint::NonbondedRestraint %{ args[1].thisown=0 %} + %pythonprepend BondDecoratorRestraint::BondDecoratorRestraint %{ + args[1].thisown=0 + %} %pythonprepend DistancePairScore::DistancePairScore %{ args[1].thisown=0 %} @@ -108,10 +114,14 @@ %include "IMP/restraints/PairConnectivityRestraint.h" %include "IMP/restraints/ExclusionVolumeRestraint.h" %include "IMP/restraints/NonbondedRestraint.h" +%include "IMP/restraints/BondDecoratorRestraint.h" %include "IMP/score_states/BondedListScoreState.h" %include "IMP/score_states/NonbondedListScoreState.h" +%include "IMP/score_states/BipartiteNonbondedListScoreState.h" +%include "IMP/score_states/bonded_lists/BondDecoratorListScoreState.h" %include "IMP/RigidBody.h" + namespace IMP { %template(IntIndex) Index; %template(FloatIndex) Index; @@ -120,6 +130,7 @@ %template(RestraintIndex) Index; %template(ScoreStateIndex) Index; %template(OptimizerStateIndex) Index; + %template(BondeListIndex) Index; %template(FloatKey) Key; %template(IntKey) Key; %template(StringKey) Key; Index: kernel/src/SConscript =================================================================== --- kernel/src/SConscript (revision 338) +++ kernel/src/SConscript (working copy) @@ -9,6 +9,7 @@ optimizers_files = SConscript('optimizers/SConscript') decorators_files = SConscript('decorators/SConscript') unary_functions_files = SConscript('unary_functions/SConscript') +score_states_files = SConscript('score_states/SConscript') pair_scores_files = SConscript('pair_scores/SConscript') score_states_files = SConscript('score_states/SConscript') Index: kernel/src/decorators/bond_decorators.cpp =================================================================== --- kernel/src/decorators/bond_decorators.cpp (revision 338) +++ kernel/src/decorators/bond_decorators.cpp (working copy) @@ -19,6 +19,7 @@ FloatKey bond_length_key_; IntKey bond_type_key_; IntKey bond_order_key_; +FloatKey bond_stiffness_key_; } // namespace internal @@ -54,6 +55,8 @@ internal::bond_graph_data_= internal::GraphData("bond"); internal::bond_type_key_= IntKey("bond type"); internal::bond_order_key_=IntKey("bond order"); + internal::bond_length_key_=FloatKey("bond length"); + internal::bond_stiffness_key_=FloatKey("bond stiffness"); internal::bond_keys_initialized_=true; } } Index: kernel/src/restraints/SConscript =================================================================== --- kernel/src/restraints/SConscript (revision 338) +++ kernel/src/restraints/SConscript (working copy) @@ -5,7 +5,7 @@ 'SphericalRestraint.cpp', 'RestraintSet.cpp', 'DistanceRestraint.cpp', 'AngleRestraint.cpp', 'DihedralRestraint.cpp', 'TorusRestraint.cpp', 'ExclusionVolumeRestraint.cpp', - 'NonbondedRestraint.cpp'] + 'NonbondedRestraint.cpp', 'BondDecoratorRestraint.cpp'] files = [File(x) for x in files] Return('files') Index: kernel/src/score_states/SConscript =================================================================== --- kernel/src/score_states/SConscript (revision 338) +++ kernel/src/score_states/SConscript (working copy) @@ -1,6 +1,9 @@ Import('env') -files = ['NonbondedListScoreState.cpp'] +bd_files= SConscript('bonded_lists/SConscript') +files = ['NonbondedListScoreState.cpp', + 'BipartiteNonbondedListScoreState.cpp'] +bd_files + files = [File(x) for x in files] Return('files') Index: kernel/test/states/test_nonbonded_list.py =================================================================== --- kernel/test/states/test_nonbonded_list.py (revision 338) +++ kernel/test/states/test_nonbonded_list.py (working copy) @@ -13,10 +13,17 @@ def show(self, t): print "One Pair" +class OneScore(IMP.UnaryFunction): + def __init__(self): + IMP.UnaryFunction.__init__(self) + def __call__(self, *args): + return 100 + def show(self, *args): + print "One score" class TestNBL(IMP.test.TestCase): def setUp(self): - IMP.set_log_level(IMP.TERSE) + IMP.set_log_level(IMP.VERBOSE) def test_it(self): """Test the nonbonded list and restraint which uses it""" @@ -28,14 +35,66 @@ d.set_x(0) d.set_y(1) d.set_z(1) - s= IMP.NonbondedListScoreState(m.get_particles(), 100) + s= IMP.NonbondedListScoreState(m.get_particles()) m.add_score_state(s) o= OnePair() r= IMP.NonbondedRestraint(s, o) m.add_restraint(r) score= m.evaluate(False) self.assertEqual(score, 45, "Wrong score") + def test_bl(self): + """Test the bonded list""" + m= IMP.Model() + bds=[] + 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) + bds.append(IMP.BondedDecorator.create(p)) + pts=IMP.Particles() + for p in m.get_particles(): + pts.append(p) + for i in range(1,10): + IMP.custom_bond(bds[i-1], bds[i], 1, .1) + s= IMP.NonbondedListScoreState(pts) + b= IMP.BondDecoratorListScoreState(pts) + s.add_bonded_list(b) + m.add_score_state(s) + o= OnePair() + r= IMP.NonbondedRestraint(s, o) + os=OneScore() + print os(6) + br= IMP.BondDecoratorRestraint(b, os) + m.add_restraint(r) + m.add_restraint(br) + score= m.evaluate( False ) + self.assertEqual(score, 900+45-9, "Wrong score") + def test_bnbl(self): + """Test the bipartite nonbonded list and restraint which uses it""" + m= IMP.Model() + ps0=IMP.Particles() + ps1=IMP.Particles() + 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) + if (i < 5): + ps0.append(p) + else: + ps1.append(p) + s= IMP.BipartiteNonbondedListScoreState(ps0, ps1) + m.add_score_state(s) + o= OnePair() + r= IMP.NonbondedRestraint(s, o) + m.add_restraint(r) + score= m.evaluate(False) + self.assertEqual(score, 25, "Wrong score") - if __name__ == '__main__': unittest.main() Index: kernel/include/IMP/restraints/BondDecoratorRestraint.h =================================================================== --- kernel/include/IMP/restraints/BondDecoratorRestraint.h (revision 0) +++ kernel/include/IMP/restraints/BondDecoratorRestraint.h (revision 0) @@ -0,0 +1,52 @@ +/** + * \file BondDecoratorRestraint.h + * \brief Apply a UnaryFunction to all bonded pairs. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + * + */ + +#ifndef __IMP_BOND_DECORATOR_RESTRAINT_H +#define __IMP_BOND_DECORATOR_RESTRAINT_H + +#include "../IMP_config.h" +#include "../Restraint.h" + +#include + +namespace IMP +{ + +class BondDecoratorListScoreState; +class UnaryFunction; + +//! Restrain all pairs of non-bonded particles +/** + This restraint currently only works for bonds which have their + length set explicitly. Eventually we should add a table for standard + molecular bonds. + + The bond stiffness is assumed to be 1 if it is not specified in + the bond. This can become a parameter eventually. + */ +class IMPDLLEXPORT BondDecoratorRestraint : public Restraint +{ +public: + //! Create the bond restraint. + /** \param[in] bl The BondDecoratorListScoreState to use to get the list + of bonds. + \param[in] f The UnaryFunction to apply to the particles. + */ + BondDecoratorRestraint(BondDecoratorListScoreState *nbl, UnaryFunction *f); + virtual ~BondDecoratorRestraint(){} + + IMP_RESTRAINT("0.5", "Daniel Russel"); + +protected: + BondDecoratorListScoreState *bl_; + std::auto_ptr f_; +}; + +} // namespace IMP + +#endif /* __IMP_BOND_DECORATOR_RESTRAINT_H */ Index: kernel/src/score_states/bonded_lists/BondDecoratorListScoreState.cpp =================================================================== --- kernel/src/score_states/bonded_lists/BondDecoratorListScoreState.cpp (revision 0) +++ kernel/src/score_states/bonded_lists/BondDecoratorListScoreState.cpp (revision 0) @@ -0,0 +1,47 @@ +/** + * \file BondDecoratorListScoreState.h + * \brief Allow iteration through pairs of a set of atoms. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ +#include "IMP/score_states/bonded_lists/BondDecoratorListScoreState.h" + +namespace IMP +{ +BondDecoratorListScoreState +::BondDecoratorListScoreState(const Particles &ps): ps_(ps) { +} + +void BondDecoratorListScoreState::update() { + bonds_.clear(); + for (unsigned int i=0; i< ps_.size(); ++i) { + BondedDecorator di= BondedDecorator::cast(ps_[i]); + ParticleIndex pi= ps_[i]->get_index(); + for (unsigned int j=0; j< di.get_number_of_bonds(); ++j) { + BondedDecorator dj= di.get_bonded(j); + if (di < dj) { + bonds_.push_back(di.get_bond(j)); + } + } + } + IMP_LOG(VERBOSE, "Found " << bonds_.size() << " bonds"<< std::endl); +} + +void BondDecoratorListScoreState::set_particles(const Particles &ps) { + ps_=ps; + bonds_.clear(); +} + + +bool BondDecoratorListScoreState::are_bonded(Particle *a, Particle *b) const { + try { + BondedDecorator da= BondedDecorator::cast(a); + BondedDecorator db= BondedDecorator::cast(b); + return get_bond(da, db) != BondDecorator(); + } catch (...) { + IMP_LOG(VERBOSE, "Exception thrown in are_bonded"<< std::endl); + } + return false; +} + +} Index: kernel/src/score_states/bonded_lists/SConscript =================================================================== --- kernel/src/score_states/bonded_lists/SConscript (revision 0) +++ kernel/src/score_states/bonded_lists/SConscript (revision 0) @@ -0,0 +1,6 @@ +Import('env') + +files = ['BondDecoratorListScoreState.cpp'] + +files = [File(x) for x in files] +Return('files') Index: kernel/src/decorators/bond_decorators.cpp =================================================================== --- kernel/src/decorators/bond_decorators.cpp (revision 338) +++ kernel/src/decorators/bond_decorators.cpp (working copy) @@ -19,6 +19,7 @@ FloatKey bond_length_key_; IntKey bond_type_key_; IntKey bond_order_key_; +FloatKey bond_stiffness_key_; } // namespace internal @@ -54,6 +55,8 @@ internal::bond_graph_data_= internal::GraphData("bond"); internal::bond_type_key_= IntKey("bond type"); internal::bond_order_key_=IntKey("bond order"); + internal::bond_length_key_=FloatKey("bond length"); + internal::bond_stiffness_key_=FloatKey("bond stiffness"); internal::bond_keys_initialized_=true; } }