Index: kernel/pyext/IMP/test.py
===================================================================
--- kernel/pyext/IMP/test.py	(revision 481)
+++ kernel/pyext/IMP/test.py	(working copy)
@@ -12,7 +12,7 @@
         diff = abs(num1 - num2)
         if msg is None:
             msg = "%f != %f within %g" % (num1, num2, tolerance)
-        self.assert_(diff < tolerance, msg)
+        self.assert_(diff <= tolerance, msg)
 
     def randomize_particles(self, particles, deviation):
         """Randomize the xyz coordinates of a list of particles"""
@@ -22,113 +22,6 @@
             d.set_y(random.uniform(-deviation, deviation))
             d.set_z(random.uniform(-deviation, deviation))
 
-    def load_coordinates(self, pdb_file):
-        """Load coordinates from a PDB file"""
-        fp = open(pdb_file, 'r')
-
-        coords = []
-        for line in fp:
-            if line[0:4] == 'ATOM':
-                coords.append((float(line[30:38]), float(line[38:46]),
-                               float(line[46:54])))
-
-        fp.close()
-        return coords
-
-    def load_attributes(self, attr_file):
-        """Load attributes from an IMP attributes file"""
-        fp = open("test_attr.imp", "r")
-
-        out = {}
-        for line in fp:
-            items = re.split('\s+', line)
-            next_item = 0;
-            num_items = len(items)
-            loading = True
-            state = 'GET_NAME'
-            data = []
-
-            while loading:
-                if next_item >= num_items or items[next_item] == '':
-                    if state == 'GET_NAME':
-                        loading = False;
-                    else:
-                        line = fp.next()
-                        items = re.split('\s+', line)
-                        next_item = 0
-                        num_items = len(items)
-
-                else:
-                    if state == 'GET_NAME':
-                        name = items[next_item]
-                        state = 'GET_TYPE'
-
-                    elif state == 'GET_TYPE':
-                        type = items[next_item]
-                        state = 'GET_NUM_ATTRS'
-
-                    elif state == 'GET_NUM_ATTRS':
-                        num_attrs = int(items[next_item])
-                        state = 'GET_DATA'
-                        data_cnt = 0
-
-                    elif state == 'GET_DATA':
-                        if type == 'INT_ARRAY':
-                            data.append(int(items[next_item]))
-                        elif type == 'FLOAT_ARRAY':
-                            data.append(float(items[next_item]))
-                        data_cnt = data_cnt + 1
-                        if data_cnt >= num_attrs:
-                            loading = False
-
-                    next_item = next_item + 1
-
-            if state == 'GET_DATA':
-                out[name] = data
-
-        fp.close()
-        return out
-
-    def check_abs_pos(self, particle, operator, ref_value, x_mask, y_mask,
-                      z_mask):
-        """Test absolute position of the given xyz particle. Use masks to
-           indicate which coordinates to use"""
-        point = (particle.x(), particle.y(), particle.z())
-        if x_mask + y_mask + z_mask < 2:
-            value = point[0]*x_mask + point[1]*y_mask + point[2]*z_mask
-        else:
-            value = math.sqrt(point[0]*point[0]*x_mask + \
-                              point[1]*point[1]*y_mask + \
-                              point[2]*point[2]*z_mask)
-
-        if eval(str(value) + operator + str(ref_value)) == False:
-            print "  ** FAILED ** ", str(value) + operator + str(ref_value), \
-                  "  (", x_mask, y_mask, z_mask, point, ")"
-        return eval(str(value) + operator + str(ref_value))
-
-    def check_in_torus(self, point, main_radius, tube_radius):
-        """Test if given point is in the torus"""
-        rad_dist = math.sqrt(point[0]*point[0] + point[1]*point[1])
-        tube_ctr_x = point[0] / rad_dist * main_radius
-        tube_ctr_y = point[1] / rad_dist * main_radius
-        dx = abs(point[0] - tube_ctr_x)
-        dy = abs(point[1] - tube_ctr_y)
-        tube_dist = math.sqrt(dx*dx + dy*dy + point[2]*point[2])
-
-        if tube_dist < tube_radius:
-            return True
-        else:
-            print "  ** FAILED ** ", tube_dist, " > ", tube_radius, "  (", \
-                  point, ")"
-            return False
-
-    def get_distance(self, pointA, pointB):
-        """Return distance between two given points"""
-        dx = pointA[0] - pointB[0]
-        dy = pointA[1] - pointB[1]
-        dz = pointA[2] - pointB[2]
-        return math.sqrt(dx*dx + dy*dy + dz*dz)
-
     def particle_distance(self, particles, idx0, idx1):
         """Return distance between two given particles"""
         dx = particles[idx0].x() - particles[idx1].x()
@@ -136,20 +29,34 @@
         dz = particles[idx0].z() - particles[idx1].z()
         return math.sqrt(dx*dx + dy*dy + dz*dz)
 
-    def check_min_distance(self, pointA, pointB, dist):
-        """Test if given points are more than the given distance apart"""
-        if self.get_distance(pointA, pointB) > dist:
-            return True
-        else:
-            print "  ** FAILED ** ", self.get_distance(pointA, pointB), \
-                  " < ", dist, "  (", pointA, ",", pointB, ")"
-            return False
+    def check_unary_function_deriv(self, uf, lb, ub, step):
+        for i in range(0, int((ub-lb)/step)):
+            f= lb+ i*step
+            (v,d)= uf.evaluate_deriv(f)
+            if (i != 0):
+                offset= step/1024
+                vmn= uf.evaluate(f-offset)
+                vmx= uf.evaluate(f+offset)
+                da= (vmx-vmn)/(2*offset)
+                print str(f) + ": " + str(d) + ", " + str(da)
+                if (abs(d-da) > abs(.1 *d)):
+                    print f
+                    print d
+                    print da
+                self.assert_(abs(d-da) <= abs(.1 *d),
+                             "Deriv and approximation are not close")
 
-    def check_max_distance(self, pointA, pointB, dist):
-        """Test if given points are less than the given distance apart"""
-        if self.get_distance(pointA, pointB) < dist:
-            return True
-        else:
-            print "  ** FAILED ** ", self.get_distance(pointA, pointB), \
-                  " > ", dist, "  (", pointA, ",", pointB, ")"
-            return False
+    def check_unary_function_min(self, uf, lb, ub, step, minf):
+        vmin = uf.evaluate(lb)
+        fmin = lb
+        for i in range(0, int((ub-lb)/step)):
+            f= lb+ i*step
+            (v,d)= uf.evaluate_deriv(f)
+            cv= uf.evaluate(f)
+            self.assertInTolerance(cv, v, .1*cv,
+                                   "Values not equal for deriv and"
+                                   " nonderiv call")
+            if (v < vmin):
+                fmin= f
+                vmin= v
+        self.assert_(abs(fmin - minf) < step, "Wrong minimum")
Index: kernel/test/unary_functions/test_harmonic.py
===================================================================
--- kernel/test/unary_functions/test_harmonic.py	(revision 481)
+++ kernel/test/unary_functions/test_harmonic.py	(working copy)
@@ -26,6 +26,8 @@
             self.assertEqual(score, scoreonly)
             self.assertInTolerance(expscore, score, 0.1)
             self.assertInTolerance(expderiv, deriv, 0.1)
+        self.check_unary_function_min(func, -30, 50, .5, 10)
+        self.check_unary_function_deriv(func, -30, 50, .5)
 
     def test_accessors(self):
         """Test Harmonic accessors"""