Index: kernel/include/IMP/singleton_scores/DistanceToSingletonScore.h =================================================================== --- kernel/include/IMP/singleton_scores/DistanceToSingletonScore.h (revision 0) +++ kernel/include/IMP/singleton_scores/DistanceToSingletonScore.h (revision 0) @@ -0,0 +1,35 @@ +/** + * \file DistanceToSingletonScore.h + * \brief A Score on the distance between to a fixed point. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ + +#ifndef __IMP_DISTANCE_TO_SINGLETON_SCORE_H +#define __IMP_DISTANCE_TO_SINGLETON_SCORE_H + +#include "../SingletonScore.h" +#include "../Vector3D.h" +namespace IMP +{ + +class UnaryFunction; + +//! Apply a function to the distance to a fixed point. +/** \ingroup singleton + */ +class IMPDLLEXPORT DistanceToSingletonScore : public SingletonScore +{ + std::auto_ptr f_; + Vector3D pt_; +public: + DistanceToSingletonScore(const Vector3D& pt, UnaryFunction *f); + virtual ~DistanceToSingletonScore(){} + virtual Float evaluate(Particle *a, + DerivativeAccumulator *da); + virtual void show(std::ostream &out=std::cout) const; +}; + +} // namespace IMP + +#endif /* __IMP_DISTANCE_TO_SINGLETON_SCORE_H */ Index: kernel/include/IMP/singleton_scores/SConscript =================================================================== --- kernel/include/IMP/singleton_scores/SConscript (revision 0) +++ kernel/include/IMP/singleton_scores/SConscript (revision 0) @@ -0,0 +1,9 @@ +import os.path +Import('env') + +files = ['DistanceToSingletonScore.h'] + +# Install the include files: +includedir = os.path.join(env['includedir'], 'IMP', 'singleton_scores') +inst = env.Install(includedir, files) +env.Alias('install', inst) Index: kernel/include/IMP/SingletonScore.h =================================================================== --- kernel/include/IMP/SingletonScore.h (revision 0) +++ kernel/include/IMP/SingletonScore.h (revision 0) @@ -0,0 +1,41 @@ +/** + * \file SingletonScore.h \brief A Score on a single particle. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ + +#ifndef __IMP_SINGLETON_SCORE_H +#define __IMP_SINGLETON_SCORE_H + +#include "IMP_config.h" +#include "base_types.h" +#include "Object.h" +#include "DerivativeAccumulator.h" + +namespace IMP +{ + +class Particle; + +/** + \ingroup restraint + \addtogroup singleton Score functions on one particle + Score functions to by applied to a single particle. These can be + used to make more flexible restraints. + */ + +//! Abstract score function for a single particle. +class IMPDLLEXPORT SingletonScore : public Object +{ +public: + SingletonScore() {} + virtual ~SingletonScore() {} + //! Compute the score for the pair and the derivative if needed. + virtual Float evaluate(Particle *a, + DerivativeAccumulator *da) = 0; + virtual void show(std::ostream &out=std::cout) const = 0; +}; + +} // namespace IMP + +#endif /* __IMP_SINGLETON_SCORE_H */ Index: kernel/include/IMP/restraints/ListRestraint.h =================================================================== --- kernel/include/IMP/restraints/ListRestraint.h (revision 0) +++ kernel/include/IMP/restraints/ListRestraint.h (revision 0) @@ -0,0 +1,50 @@ +/** + * \file ListRestraint.h + * \brief Apply a SingletonScore to each particle in a list. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + * + */ + +#ifndef __IMP_LIST_RESTRAINT_H +#define __IMP_LIST_RESTRAINT_H + +#include + +#include "../IMP_config.h" +#include "../Restraint.h" + +namespace IMP +{ + +class SingletonScore; + +//! Applies a SingletonScore to each Particle in a list. +/** + \ingroup restraint + */ +class IMPDLLEXPORT ListRestraint : public Restraint +{ +public: + //! Create the list restraint. + /** \param[in] ps The list of particles to use in the restraint. + \param[in] ss The function to apply to each particle. + */ + ListRestraint(const Particles &ps, SingletonScore *ss); + virtual ~ListRestraint(){} + + IMP_RESTRAINT("0.5", "Daniel Russel"); + + //! Set the list of particles + void set_particles(const Particles &ps) { + Restraint::clear_particles(); + Restraint::add_particles(ps); + } + +protected: + std::auto_ptr ss_; +}; + +} // namespace IMP + +#endif /* __IMP_LIST_RESTRAINT_H */ Index: kernel/src/restraints/ListRestraint.cpp =================================================================== --- kernel/src/restraints/ListRestraint.cpp (revision 0) +++ kernel/src/restraints/ListRestraint.cpp (revision 0) @@ -0,0 +1,47 @@ +/** + * \file ListRestraint.cpp + * \brief Apply a score fgunction toa list of particles. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + * + */ + +#include + +#include "IMP/SingletonScore.h" +#include "IMP/log.h" +#include "IMP/restraints/ListRestraint.h" + +namespace IMP +{ + +ListRestraint::ListRestraint(const Particles &ps, + SingletonScore *s) : ss_(s) +{ + set_particles(ps); +} + + +Float ListRestraint::evaluate(DerivativeAccumulator *accum) +{ + + IMP_CHECK_OBJECT(ss_.get()); + + Float score=0; + + for (unsigned int i=0; i< number_of_particles(); ++i) { + score += ss_->evaluate(get_particle(i), accum); + } + + return score; +} + + +void ListRestraint::show(std::ostream& out) const +{ + out << "List restraint with score function "; + ss_->show(out); + out << std::endl; +} + +} // namespace IMP Index: kernel/src/singleton_scores/SConscript =================================================================== --- kernel/src/singleton_scores/SConscript (revision 0) +++ kernel/src/singleton_scores/SConscript (revision 0) @@ -0,0 +1,6 @@ +Import('env') + +files = ['DistanceToSingletonScore.cpp'] + +files = [File(x) for x in files] +Return('files') Index: kernel/src/singleton_scores/DistanceToSingletonScore.cpp =================================================================== --- kernel/src/singleton_scores/DistanceToSingletonScore.cpp (revision 0) +++ kernel/src/singleton_scores/DistanceToSingletonScore.cpp (revision 0) @@ -0,0 +1,86 @@ +/** + * \file DistanceToSingletonScore.cpp + * \brief A Score on the distance to a fixed point. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + */ + +#include "IMP/singleton_scores/DistanceToSingletonScore.h" +#include "IMP/decorators/XYZDecorator.h" +#include "IMP/UnaryFunction.h" + +namespace IMP +{ + +namespace internal +{ + +static const Float MIN_DISTANCE = .00001; +Float evaluate_distance_to_singleton_score(const Vector3D &v, + Particle *b, + DerivativeAccumulator *da, + UnaryFunction *f, + Float offset, + Float scale) +{ + IMP_CHECK_OBJECT(f); + IMP_CHECK_OBJECT(b); + + Float d2 = 0, delta[3]; + Float score; + + XYZDecorator d1 = XYZDecorator::cast(b); + if (!d1.get_coordinates_are_optimized()) { + IMP_WARN("DistanceToSingletonScore called on non optimized particle" + << b->get_index() <= MIN_DISTANCE) { + Float deriv; + + score = (*f)(shifted_distance, deriv); + + for (int i = 0; i < 3; ++i) { + Float d = delta[i] / distance * deriv; + d1.add_to_coordinate_derivative(i, -d, *da); + } + } else { + // calculate the score based on the distance feature + score = (*f)(shifted_distance); + } + + return score; +} + +} // namespace internal + + DistanceToSingletonScore::DistanceToSingletonScore(const Vector3D &v, + UnaryFunction *f): f_(f), + pt_(v){} + +Float DistanceToSingletonScore::evaluate(Particle *b, + DerivativeAccumulator *da) +{ + return internal::evaluate_distance_to_singleton_score(pt_,b, da, + f_.get(), 0,1); +} + +void DistanceToSingletonScore::show(std::ostream &out) const +{ + out << "DistanceToSingletScore using "; + f_->show(out); +} + +} // namespace IMP Index: kernel/test/restraints/test_list.py =================================================================== --- kernel/test/restraints/test_list.py (revision 0) +++ kernel/test/restraints/test_list.py (revision 0) @@ -0,0 +1,60 @@ +import unittest +import IMP, IMP.test + +class OneSingle(IMP.SingletonScore): + def __init__(self): + IMP.SingletonScore.__init__(self) + def evaluate(self, pa, da): + return 1 + def last_modified_by(self): + return "Me" + def version(self): + return "0.5" + def show(self, t): + print "One Singleton" + +class Linear(IMP.UnaryFunction): + def __init__(self): + IMP.UnaryFunction.__init__(self) + def __call__(self, *args): + return args[0] + def show(self, *args): + print "identity" + +class TestList(IMP.test.TestCase): + def setUp(self): + IMP.set_log_level(IMP.VERBOSE) + + def test_it(self): + """Test the singleton restraint""" + m= IMP.Model() + for i in range(0,10): + p= IMP.Particle() + m.add_particle(p) + os= OneSingle() + s= IMP.ListRestraint(m.get_particles(), os) + m.add_restraint(s) + score= m.evaluate(False) + self.assertEqual(score, 10, "Wrong score") + + def test_ss(self): + """Test the distanceto score""" + m= IMP.Model() + p= IMP.Particle() + m.add_particle(p) + d=IMP.XYZDecorator.create(p) + d.set_x(0) + d.set_y(1) + d.set_z(1) + d.set_coordinates_are_optimized(True) + v= IMP.Vector3D(3,1,5) + l= Linear() + s= IMP.DistanceToSingletonScore(v, l) + r= IMP.ListRestraint(m.get_particles(), s) + m.add_restraint(r) + e= m.evaluate(False) + self.assertEqual(e,5, "Wrong distance in score") + + +if __name__ == '__main__': + unittest.main()