Index: impEM/test/test_em_fit.py =================================================================== --- impEM/test/test_em_fit.py (revision 499) +++ impEM/test/test_em_fit.py (working copy) @@ -31,11 +31,11 @@ self.particle_indexes = IMP.Ints() origin = 3.0 - self.particles.append(IMP.utils.XYZParticle(self.imp_model, 9.+origin, + self.particles.append(self.create_point_particle(self.imp_model, 9.+origin, 9.+origin, 9.+origin)) - self.particles.append(IMP.utils.XYZParticle(self.imp_model, 12.+origin, + self.particles.append(self.create_point_particle(self.imp_model, 12.+origin, 3.+origin, 3.+origin)) - self.particles.append(IMP.utils.XYZParticle(self.imp_model, 3.+origin, + self.particles.append(self.create_point_particle(self.imp_model, 3.+origin, 12.+origin,12.+origin)) p1 = self.particles[0] p1.add_attribute(radius_key, 1.0) Index: impEM/test/test_sample_particles.py =================================================================== --- impEM/test/test_sample_particles.py (revision 499) +++ impEM/test/test_sample_particles.py (working copy) @@ -38,7 +38,7 @@ ## - create a set of three particles in imp npart = 3 for i in range(npart): - self.particles.append(IMP.utils.XYZParticle(self.imp_model, 0,0,0)) + self.particles.append(self.create_point_particle(self.imp_model, 0,0,0)) # - add the particles attributes ( other than X,Y,Z) rad = 1.0 wei = 1.0 Index: kernel/test/optimizers/test_md_optimizer.py =================================================================== --- kernel/test/optimizers/test_md_optimizer.py (revision 499) +++ kernel/test/optimizers/test_md_optimizer.py (working copy) @@ -53,7 +53,7 @@ self.model = IMP.Model() self.particles = [] - self.particles.append(IMP.utils.XYZParticle(self.model, + self.particles.append(self.create_point_particle(self.model, -43.0, 65.0, 93.0)) self.particles[-1].add_attribute(masskey, cmass, False) self.md = IMP.MolecularDynamics() @@ -138,7 +138,7 @@ # Averages for temperature only make sense if we have a comparatively # large number of particles: for i in range(500): - self.particles.append(IMP.utils.XYZParticle(self.model, + self.particles.append(self.create_point_particle(self.model, -43.0, 65.0, 93.0)) self.particles[-1].add_attribute(masskey, cmass, False) # Initial temperature should be zero: @@ -161,7 +161,7 @@ def test_rescaling(self): """Test thermostatting by velocity rescaling""" for i in range(100): - self.particles.append(IMP.utils.XYZParticle(self.model, + self.particles.append(self.create_point_particle(self.model, -43.0, 65.0, 93.0)) self.particles[-1].add_attribute(masskey, cmass, False) self.md.assign_velocities(100.0) Index: kernel/test/optimizers/test_sd_optimizer.py =================================================================== --- kernel/test/optimizers/test_sd_optimizer.py (revision 499) +++ kernel/test/optimizers/test_sd_optimizer.py (working copy) @@ -15,11 +15,11 @@ self.rsrs = [] # create particles 0 - 1 - self.particles.append(IMP.utils.XYZParticle(self.imp_model, + self.particles.append(self.create_point_particle(self.imp_model, -43.0, 65.0, 93.0)) - self.particles.append(IMP.utils.XYZParticle(self.imp_model, + self.particles.append(self.create_point_particle(self.imp_model, 20.0, 74.0, -80.0)) - self.particles.append(IMP.utils.XYZParticle(self.imp_model, + self.particles.append(self.create_point_particle(self.imp_model, 4.0, -39.0, 26.0)) radkey= IMP.FloatKey("radius") @@ -69,10 +69,7 @@ # Start off with all particles in close proximity (but not actually # colocated, as the derivative of zero distance is zero): - for p in self.particles: - p.set_x(random.uniform(-0.01, 0.01)) - p.set_y(random.uniform(-0.01, 0.01)) - p.set_z(random.uniform(-0.01, 0.01)) + self.randomize_particles(self.particles, .01) self.steepest_descent.optimize(50) Index: kernel/test/particles/test_particles.py =================================================================== --- kernel/test/particles/test_particles.py (revision 499) +++ kernel/test/particles/test_particles.py (working copy) @@ -20,7 +20,7 @@ # create particles 0 - 11 for i in range(0,12): - self.particles.append(IMP.utils.XYZParticle(self.model, + self.particles.append(self.create_point_particle(self.model, i*2, i*3, i*4)) p1 = self.particles[i] p1.add_attribute(radkey, 1.5 * i, False) Index: kernel/test/unary_functions/test_harmonic.py =================================================================== --- kernel/test/unary_functions/test_harmonic.py (revision 499) +++ 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""" Index: kernel/test/distance/test_distance.py =================================================================== --- kernel/test/distance/test_distance.py (revision 499) +++ kernel/test/distance/test_distance.py (working copy) @@ -13,11 +13,11 @@ self.rsrs = [] # create particles 0 - 1 - self.particles.append(IMP.utils.XYZParticle(self.imp_model, + self.particles.append(self.create_point_particle(self.imp_model, -3.0, 0.0, 0.0)) - self.particles.append(IMP.utils.XYZParticle(self.imp_model, + self.particles.append(self.create_point_particle(self.imp_model, 0.0, 0.0, 0.0)) - self.particles.append(IMP.utils.XYZParticle(self.imp_model, + self.particles.append(self.create_point_particle(self.imp_model, 4.0, 0.0, 0.0)) p1 = self.particles[0] Index: kernel/test/misc/test_restraint_sets.py =================================================================== --- kernel/test/misc/test_restraint_sets.py (revision 499) +++ kernel/test/misc/test_restraint_sets.py (working copy) @@ -11,9 +11,9 @@ self.particles = [] # create particles - self.particles.append(IMP.utils.XYZParticle(self.model, + self.particles.append(self.create_point_particle(self.model, -43.0, 65.0, 93.0)) - self.particles.append(IMP.utils.XYZParticle(self.model, + self.particles.append(self.create_point_particle(self.model, 20.0, 74.0, -80.0)) # separate particles by 5.0: Index: kernel/test/restraints/test_dihedral.py =================================================================== --- kernel/test/restraints/test_dihedral.py (revision 499) +++ kernel/test/restraints/test_dihedral.py (working copy) @@ -13,10 +13,10 @@ `scored_angle`.""" model = IMP.Model() particles = IMP.Particles() - particles.append(IMP.utils.XYZParticle(model, 1.0, 0.0, -1.0)) - particles.append(IMP.utils.XYZParticle(model, 0.0, 0.0, -1.0)) - particles.append(IMP.utils.XYZParticle(model, 0.0, 0.0, 0.0)) - particles.append(IMP.utils.XYZParticle(model, math.cos(system_angle), + particles.append(self.create_point_particle(model, 1.0, 0.0, -1.0)) + particles.append(self.create_point_particle(model, 0.0, 0.0, -1.0)) + particles.append(self.create_point_particle(model, 0.0, 0.0, 0.0)) + particles.append(self.create_point_particle(model, math.cos(system_angle), math.sin(system_angle), 0.0)) k = IMP.Harmonic.k_from_standard_deviation(.1) r = IMP.DistanceRestraint(IMP.Harmonic(1.0, k), Index: kernel/test/restraints/test_angle.py =================================================================== --- kernel/test/restraints/test_angle.py (revision 499) +++ kernel/test/restraints/test_angle.py (working copy) @@ -13,9 +13,9 @@ `scored_angle`.""" model = IMP.Model() particles = IMP.Particles() - particles.append(IMP.utils.XYZParticle(model, -1.0, 0.0, 0.0)) - particles.append(IMP.utils.XYZParticle(model, 0.0, 0.0, 0.0)) - particles.append(IMP.utils.XYZParticle(model, -math.cos(system_angle), + particles.append(self.create_point_particle(model, -1.0, 0.0, 0.0)) + particles.append(self.create_point_particle(model, 0.0, 0.0, 0.0)) + particles.append(self.create_point_particle(model, -math.cos(system_angle), math.sin(system_angle), 0.0)) k = IMP.Harmonic.k_from_standard_deviation(0.1) r = IMP.DistanceRestraint(IMP.Harmonic(1.0, k),particles[0], particles[1]) Index: kernel/pyext/IMP/test.py =================================================================== --- kernel/pyext/IMP/test.py (revision 499) +++ kernel/pyext/IMP/test.py (working copy) @@ -12,8 +12,48 @@ 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 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_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") + + def create_point_particle(self, model, x, y, z): + p = IMP.Particle() + model.add_particle(p) + p.add_attribute(IMP.FloatKey("x"), x, True) + p.add_attribute(IMP.FloatKey("y"), y, True) + p.add_attribute(IMP.FloatKey("z"), z, True) + return p + def randomize_particles(self, particles, deviation): """Randomize the xyz coordinates of a list of particles""" for p in particles: @@ -22,134 +62,12 @@ 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() - dy = particles[idx0].y() - particles[idx1].y() - dz = particles[idx0].z() - particles[idx1].z() + dx = particles[idx0].get_value(IMP.FloatKey("x")) -\ + particles[idx1].get_value(IMP.FloatKey("x")) + dy = particles[idx0].get_value(IMP.FloatKey("y")) -\ + particles[idx1].get_value(IMP.FloatKey("y")) + dz = particles[idx0].get_value(IMP.FloatKey("z")) -\ + particles[idx1].get_value(IMP.FloatKey("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_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 Index: kernel/pyext/IMP/utils.py =================================================================== --- kernel/pyext/IMP/utils.py (revision 499) +++ kernel/pyext/IMP/utils.py (working copy) @@ -3,75 +3,6 @@ import IMP import math -class XYZParticle(IMP.Particle): - """Wrapper for IMP particles that focuses on x,y,z coordinates""" - - def __init__(self, model, x=None, y=None, z=None): - """Initialize particle with IMP model it belongs to and its xyz - coordinates""" - IMP.Particle.__init__(self) - model.add_particle(self) - # Map xyz strings to FloatKeys only once for all XYZParticles - if not hasattr(self, '_xkey'): - XYZParticle._xkey = IMP.FloatKey("x") - XYZParticle._ykey = IMP.FloatKey("y") - XYZParticle._zkey = IMP.FloatKey("z") - if x is not None: - self.add_attribute(self._xkey, x, True) - if y is not None: - self.add_attribute(self._ykey, y, True) - if z is not None: - self.add_attribute(self._zkey, z, True) - - def x(self): - """Get x position of particle""" - return self.get_value(self._xkey) - - def y(self): - """Get y position of particle""" - return self.get_value(self._ykey) - - def z(self): - """Get z position of particle""" - return self.get_value(self._zkey) - - def set_x(self, value): - """Set x position of particle""" - self.set_value(self._xkey, value) - - def set_y(self, value): - """Set y position of particle""" - self.set_value(self._ykey, value) - - def set_z(self, value): - """Set z position of particle""" - self.set_value(self._zkey, value) - - def dx(self): - """Get partial derivative of score with respect to particle's x position""" - return self.get_derivative(self._xkey) - - def dy(self): - """Get partial derivative of score with respect to particle's y position""" - return self.get_derivative(self._ykey) - - def dz(self): - """Get partial derivative of score with respect to particle's z position""" - return self.get_derivative(self._zkey) - - def add_to_dx(self, value, da): - """Add to partial derivative of score with respect to particle's x position""" - self.add_to_derivative(self._xkey, value, da) - - def add_to_dy(self, value, da): - """Add to partial derivative of score with respect to particle's y position""" - self.add_to_derivative(self._ykey, value, da) - - def add_to_dz(self, value, da): - """Add to partial derivative of score with respect to particle's z position""" - self.add_to_derivative(self._zkey, value, da) - - def set_restraint_set_is_active(model, restraint_set_name, is_active): """Set whether the given restraint set is active (True) or inactive (False)""" Index: kernel/pyext/IMP/modeller_intf.py =================================================================== --- kernel/pyext/IMP/modeller_intf.py (revision 499) +++ kernel/pyext/IMP/modeller_intf.py (working copy) @@ -156,8 +156,16 @@ def init_imp_from_modeller(model, particles, atoms): """Init IMP particles from Modeller atoms""" + xk= IMP.FloatKey("x") + yk= IMP.FloatKey("y") + zk= IMP.FloatKey("z") for (num, at) in enumerate(atoms): - particles.append(IMP.utils.XYZParticle(model, at.x, at.y, at.z)) + p = IMP.Particle() + model.add_particle(p) + p.add_attribute(xk, at.x, True) + p.add_attribute(yk, at.y, True) + p.add_attribute(zk, at.z, True) + particles.append(p) def copy_imp_coords_to_modeller(particles, atoms):