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,49 @@
+/**
+ *  \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 <iostream>
+
+#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::set_particles(ps);
+  }
+
+protected:
+  std::auto_ptr<SingletonScore> ss_;
+};
+
+} // namespace IMP
+
+#endif  /* __IMP_LIST_RESTRAINT_H */
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/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<UnaryFunction> 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/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 <<std::endl);
+    return 0;
+  }
+  for (int i = 0; i < 3; ++i) {
+    delta[i] = v.get_component(i) - d1.get_coordinate(i);
+    d2 += square(delta[i]);
+  }
+
+  Float distance = std::sqrt(d2);
+
+  Float shifted_distance = scale*(distance - offset);
+
+  // 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;
+      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/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 <cmath>
+
+#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_);
+
+  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/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()
Index: kernel/pyext/IMP.i
===================================================================
--- kernel/pyext/IMP.i	(revision 345)
+++ kernel/pyext/IMP.i	(working copy)
@@ -49,13 +49,22 @@
   %pythonprepend NonbondedRestraint::NonbondedRestraint %{
         args[1].thisown=0
   %}
   %pythonprepend BondDecoratorRestraint::BondDecoratorRestraint %{
         args[1].thisown=0
   %}
-  %pythonprepend DistancePairScore::DistancePairScore %{
+  %pythonprepend ListRestraint::ListRestraint %{
         args[1].thisown=0
   %}
-  %pythonprepend SphericalDistancePairScore::SphericalDistancePairScore %{
+  %pythonprepend DistancePairScore::DistancePairScore %{
+        args[0].thisown=0
+  %}
+  %pythonprepend SphereDistancePairScore::SphereDistancePairScore %{
+        args[0].thisown=0
+  %}
+  %pythonprepend DistanceToSingletonScore::DistanceToSingletonScore %{
         args[1].thisown=0
   %}
 }
@@ -82,6 +91,7 @@
 %include "IMP/Restraint.h"
 %include "IMP/restraints/RestraintSet.h"
 %include "IMP/ScoreState.h"
+%include "IMP/SingletonScore.h"
 %include "IMP/OptimizerState.h"
 %include "IMP/log.h"
 %include "IMP/Model.h"
@@ -104,6 +114,7 @@
 %include "IMP/optimizers/states/VRMLLogOptimizerState.h"
 %include "IMP/pair_scores/DistancePairScore.h"
 %include "IMP/pair_scores/SphereDistancePairScore.h"
+%include "IMP/singleton_scores/DistanceToSingletonScore.h"
 %include "IMP/restraints/DistanceRestraint.h"
 %include "IMP/restraints/AngleRestraint.h"
 %include "IMP/restraints/DihedralRestraint.h"
@@ -115,6 +126,7 @@
 %include "IMP/restraints/ExclusionVolumeRestraint.h"
 %include "IMP/restraints/NonbondedRestraint.h"
 %include "IMP/restraints/BondDecoratorRestraint.h"
+%include "IMP/restraints/ListRestraint.h"
 %include "IMP/score_states/BondedListScoreState.h"
 %include "IMP/score_states/NonbondedListScoreState.h"
 %include "IMP/score_states/BipartiteNonbondedListScoreState.h"
@@ -135,7 +147,7 @@
   %template(StringKey) Key<String>;
   %template(AtomType) Key<AtomTypeTag>;
   %template(ResidueType) Key<ResidueTypeTag>;     
-  %template(show_named_nierarchy) show<NameDecorator>;
+  %template(show_named_hierarchy) show<NameDecorator>;
   %template(show_molecular_hierarchy) show<MolecularHierarchyDecorator>;
   %template(Particles) ::std::vector<Particle*>;       
   %template(Restraints) ::std::vector<Restraint*>;       
Index: kernel/include/IMP.h
===================================================================
--- kernel/include/IMP.h	(revision 345)
+++ kernel/include/IMP.h	(working copy)
@@ -25,6 +25,7 @@
 #include "IMP/ModelData.h"
 #include "IMP/Model.h"
 #include "IMP/PairScore.h"
+#include "IMP/SingletonScore.h"
 #include "IMP/Vector3D.h"
 #include "IMP/decorators/HierarchyDecorator.h"
 #include "IMP/decorators/MolecularHierarchyDecorator.h"
@@ -39,6 +40,7 @@
 #include "IMP/optimizers/states/VRMLLogOptimizerState.h"
 #include "IMP/pair_scores/DistancePairScore.h"
 #include "IMP/pair_scores/SphereDistancePairScore.h"
+#include "IMP/singleton_scores/DistanceToSingletonScore.h"
 #include "IMP/restraints/RestraintSet.h"
 #include "IMP/restraints/DistanceRestraint.h"
 #include "IMP/restraints/AngleRestraint.h"
@@ -50,6 +52,7 @@
 #include "IMP/restraints/PairConnectivityRestraint.h"
 #include "IMP/restraints/ExclusionVolumeRestraint.h"
 #include "IMP/restraints/NonbondedRestraint.h"
+#include "IMP/restraints/ListRestraint.h"
 #include "IMP/restraints/BondDecoratorRestraint.h"
 #include "IMP/score_states/BipartiteNonbondedListScoreState.h"
 #include "IMP/score_states/NonbondedListScoreState.h"
Index: kernel/include/IMP/SConscript
===================================================================
--- kernel/include/IMP/SConscript	(revision 345)
+++ kernel/include/IMP/SConscript	(working copy)
@@ -6,7 +6,7 @@
          'ModelData.h', 'RigidBody.h', 'log.h', 'DerivativeAccumulator.h',
          'Key.h', 'AttributeTable.h', 'utility.h', 'Restraint.h', 'Optimizer.h',
          'DecoratorBase.h', 'Object.h', 'Vector3D.h', 'ScoreFuncParams.h',
-         'UnaryFunction.h', 'PairScore.h']
+         'UnaryFunction.h', 'PairScore.h', 'SingletonScore.h', 'Grid3D.h']
 
 # Install the include files:
 includedir = os.path.join(env['includedir'], 'IMP')
@@ -19,4 +19,5 @@
 SConscript('decorators/SConscript')
 SConscript('unary_functions/SConscript')
 SConscript('pair_scores/SConscript')
+SConscript('singleton_scores/SConscript')
 SConscript('score_states/SConscript')
Index: kernel/src/SConscript
===================================================================
--- kernel/src/SConscript	(revision 345)
+++ kernel/src/SConscript	(working copy)
@@ -11,6 +11,7 @@
 unary_functions_files = SConscript('unary_functions/SConscript')
 score_states_files = SConscript('score_states/SConscript')
 pair_scores_files = SConscript('pair_scores/SConscript')
+singleton_scores_files = SConscript('singleton_scores/SConscript')
 score_states_files = SConscript('score_states/SConscript')
 
 # Source files
@@ -19,7 +20,8 @@
          'OptimizerState.cpp', 'Log.cpp', 'Restraint.cpp', 'Optimizer.cpp',
          'Object.cpp', 'BasicScoreFuncParams.cpp'
         ] + decorators_files + restraints_files + optimizers_files \
-          + unary_functions_files + pair_scores_files + score_states_files
+          + unary_functions_files + pair_scores_files + score_states_files\
+          + singleton_scores_files
 
 # Build the shared library:
 lib = env.SharedLibrary('imp', files)
Index: kernel/src/restraints/SConscript
===================================================================
--- kernel/src/restraints/SConscript	(revision 345)
+++ kernel/src/restraints/SConscript	(working copy)
@@ -5,7 +5,8 @@
          'SphericalRestraint.cpp', 'RestraintSet.cpp',
          'DistanceRestraint.cpp', 'AngleRestraint.cpp', 'DihedralRestraint.cpp',
          'TorusRestraint.cpp', 'ExclusionVolumeRestraint.cpp',
-         'NonbondedRestraint.cpp', 'BondDecoratorRestraint.cpp']
+         'NonbondedRestraint.cpp', 'BondDecoratorRestraint.cpp',
+         'ListRestraint.cpp']
 
 files = [File(x) for x in files]
 Return('files')