def test_average_structure(get_fn): traj = md.load(get_fn('frame0.dcd'), top=get_fn('frame0.pdb')) average = compute_average_structure(traj.xyz) # The mean RMSD to the average structure should be less than to any individual frame. sum1 = 0 sum2 = 0 for i in range(traj.n_frames): sum1 += rmsd_qcp(traj.xyz[0], traj.xyz[i]) sum2 += rmsd_qcp(average, traj.xyz[i]) assert sum2 < sum1
def test_average_structure(): traj = md.load(get_fn('frame0.dcd'), top=get_fn('frame0.pdb')) average = compute_average_structure(traj.xyz) # The mean RMSD to the average structure should be less than to any individual frame. sum1 = 0 sum2 = 0 for i in range(traj.n_frames): sum1 += rmsd_qcp(traj.xyz[0], traj.xyz[i]) sum2 += rmsd_qcp(average, traj.xyz[i]) assert sum2 < sum1
def test_trajectory_rmsd(): t = md.load(get_fn('traj.h5')) for parallel in [True, False]: calculated = md.rmsd(t, t, 0, parallel=parallel) reference = np.zeros(t.n_frames) for i in range(t.n_frames): reference[i] = rmsd_qcp(t.xyz[0], t.xyz[i]) eq(calculated, reference, decimal=3)
def test_trajectory_rmsd(get_fn): t = md.load(get_fn('traj.h5')) for parallel in [True, False]: calculated = md.rmsd(t, t, 0, parallel=parallel) reference = np.zeros(t.n_frames) for i in range(t.n_frames): reference[i] = rmsd_qcp(t.xyz[0], t.xyz[i]) eq(calculated, reference, decimal=3)
def test_precentered_1(): # test rmsd against the numpy version, using the same trajectory # as target and reference t1 = md.load(get_fn('traj.h5'), stride=10) t2 = md.load(get_fn('traj.h5'), stride=10) # don't center t1, and use it without precentered # explicitly center t2, and use *with* precentered for parallel in [True, False]: t2.center_coordinates() eq(t1.n_frames, t2.n_frames) for i in range(t1.n_frames): ref = np.zeros(t1.n_frames) for j in range(t1.n_frames): ref[j] = rmsd_qcp(t1.xyz[j], t1.xyz[i]) val1 = md.rmsd(t1, t1, i, parallel=parallel, precentered=False) val2 = md.rmsd(t2, t2, i, parallel=parallel, precentered=True) eq(ref, val1, decimal=3) eq(val1, val2)
def test_precentered_1(get_fn): # test rmsd against the numpy version, using the same trajectory # as target and reference t1 = md.load(get_fn('traj.h5'), stride=10) t2 = md.load(get_fn('traj.h5'), stride=10) # don't center t1, and use it without precentered # explicitly center t2, and use *with* precentered for parallel in [True, False]: t2.center_coordinates() eq(t1.n_frames, t2.n_frames) for i in range(t1.n_frames): ref = np.zeros(t1.n_frames) for j in range(t1.n_frames): ref[j] = rmsd_qcp(t1.xyz[j], t1.xyz[i]) val1 = md.rmsd(t1, t1, i, parallel=parallel, precentered=False) val2 = md.rmsd(t2, t2, i, parallel=parallel, precentered=True) eq(ref, val1, decimal=3) eq(val1, val2)
def test_precentered_2(get_fn): # test rmsd against the numpy version, using the difference # trajectories as target and reference t1_a = md.load(get_fn('traj.h5'), stride=10) t2_a = md.load(get_fn('traj.h5'), stride=10) t1_b = md.load(get_fn('traj.h5'), stride=10) t2_b = md.load(get_fn('traj.h5'), stride=10) # don't center t1, and use it without precentered # explicitly center t2, and use *with* precentered t2_a.center_coordinates() t2_b.center_coordinates() for parallel in [True, False]: for i in range(t1_b.n_frames): ref = np.zeros(t1_a.n_frames) for j in range(t1_a.n_frames): ref[j] = rmsd_qcp(t1_a.xyz[j], t1_b.xyz[i]) val1 = md.rmsd(t1_a, t1_b, i, parallel=parallel, precentered=False) val2 = md.rmsd(t2_a, t2_b, i, parallel=parallel, precentered=True) eq(ref, val1, decimal=3) eq(val1, val2, decimal=4)
def test_precentered_2(): # test rmsd against the numpy version, using the difference # trajectories as target and reference t1_a = md.load(get_fn('traj.h5'), stride=10) t2_a = md.load(get_fn('traj.h5'), stride=10) t1_b = md.load(get_fn('traj.h5'), stride=10) t2_b = md.load(get_fn('traj.h5'), stride=10) # don't center t1, and use it without precentered # explicitly center t2, and use *with* precentered t2_a.center_coordinates() t2_b.center_coordinates() for parallel in [True, False]: for i in range(t1_b.n_frames): ref = np.zeros(t1_a.n_frames) for j in range(t1_a.n_frames): ref[j] = rmsd_qcp(t1_a.xyz[j], t1_b.xyz[i]) val1 = md.rmsd(t1_a, t1_b, i, parallel=parallel, precentered=False) val2 = md.rmsd(t2_a, t2_b, i, parallel=parallel, precentered=True) eq(ref, val1, decimal=3) eq(val1, val2, decimal=4)
# But for some applications like clustering, we want to run many # rmsd() calculations per trajectory frame. Under these circumstances, # the centering of the trajectories is going to be done many times, which # leads to a slight slowdown. If we manually center the trajectory # and then inform the rmsd() function that the centering has been # precomputed, we can achieve ~2x speedup, depending on your machine # and the number of atoms. t.center_coordinates() start = time.time() for i in range(100): md.rmsd(t, t, 0, precomputed=True) print 'md.rmsd(precomputed=True): %.2f rmsds / s' % ((t.n_frames * 100) / (time.time() - start)) # Just for fun, let's compare this code to the straightforward # numpy implementation of the same algorithm, which mdtraj has # (mostly for testing) in the mdtraj.geometry.alignment subpackage from mdtraj.geometry.alignment import rmsd_qcp start = time.time() for k in range(t.n_frames): rmsd_qcp(t.xyz[0], t.xyz[k]) print 'pure numpy rmsd_qcp(): %.2f rmsds / s' % (t.n_frames / (time.time() - start)) # The :func:`md.rmsd()` code is *a lot* faster. If you go look at the :func:`rmsd_qcp` # source code, you'll see that it's not because that code is particularly slow or # unoptimized. It's about as good as you can do with numpy. The reason for the speed # difference is that an inordinate amount of time was put into hand-optimizing # an SSE3 implementation in C for the :func:`md.rmsd()` code.
def test_rmsd_nonzero(): rmsd_kabsch = alignment.rmsd_kabsch(xyz1, xyz3) rmsd_qcp = alignment.rmsd_qcp(xyz1, xyz3) eq(rmsd_kabsch, rmsd_qcp, decimal=5)
def test_rmsd_zero(): rmsd_kabsch = alignment.rmsd_kabsch(xyz1, xyz2) rmsd_qcp = alignment.rmsd_qcp(xyz1, xyz2) eq(float(rmsd_kabsch), 0.0, decimal=5) eq(float(rmsd_qcp), 0.0, decimal=5)