def test_calc_geom_center_exception(): from pyxmolpp2.geometry import calc_geom_center, XYZ, VectorXYZ, calc_rmsd, GeometryException, Transformation3d with pytest.raises(GeometryException): calc_geom_center(VectorXYZ([])) calc_geom_center(VectorXYZ([XYZ(1, 2, 3)]))
def test_calc_alignment(): from pyxmolpp2.geometry import calc_alignment, XYZ, VectorXYZ, calc_rmsd, Rotation3d, Translation3d, Degrees a = VectorXYZ([XYZ(1, 2, 3), XYZ(1, 2, 5), XYZ(4, 2, 7), XYZ(8, 1, 4)]) G = Rotation3d(XYZ(7, 6, 5), Degrees(12)) * Translation3d(XYZ(8, -9, 1)) b = VectorXYZ([G.transform(x) for x in a]) G2 = calc_alignment(a, b) assert calc_rmsd(a, b) > 1 assert calc_rmsd(a, b, G2) == pytest.approx(0)
def test_calc_rmsd(): from pyxmolpp2.geometry import calc_alignment, XYZ, VectorXYZ, calc_rmsd a = VectorXYZ([XYZ(1, 2, 3)]) b = VectorXYZ([XYZ(3, 4, 5)]) assert calc_rmsd(a, b) == pytest.approx(math.sqrt(2**2 * 3)) a = VectorXYZ([XYZ(1, 2, 3), XYZ(1, 2, 3)]) b = VectorXYZ([XYZ(3, 4, 5), XYZ(1, 2, 3)]) assert calc_rmsd(a, b) == pytest.approx(math.sqrt(2**2 * 3 * 0.5))
def test_sasa_two_spheres(): for samples, precision in [ (10, 5e0), # 5% accuracy (50, 1e0), # 1% accuracy (250, 1e-1), # 0.1% accuracy (1000, 1e-2), # 0.01% accuracy (5000, 1e-3), # 0.001% accuracy ]: for _ in range(100): a = XYZ(*(np.random.random(3) * 2 - 1)) b = XYZ(*(np.random.random(3) * 2 - 1)) r1, r2 = np.random.random(2) * 2 + 0.01 S1 = 4 * np.pi * r1 ** 2 S2 = 4 * np.pi * r2 ** 2 S1_loss = first_sphere_hidden_area(a, b, r1, r2) S2_loss = first_sphere_hidden_area(b, a, r2, r1) total_area = S1 + S2 exposed_area_exact = total_area - S1_loss - S2_loss sasa = calc_sasa(VectorXYZ([a, b]), np.array([r1, r2]), 0, n_samples=samples) exposed_area_approx = sum(sasa) exposed_area_percent_exact = exposed_area_exact / total_area * 100 exposed_area_percent_approx = exposed_area_approx / total_area * 100 assert np.isclose(exposed_area_percent_exact, exposed_area_percent_approx, atol=precision)
def test_autocorr(): from pyxmolpp2.geometry import XYZ, VectorXYZ, calc_autocorr_order_2 from numpy.random import random as rnd from timeit import default_timer as timer n = 1000 v = VectorXYZ([XYZ(rnd(), rnd(), rnd()) for i in range(n)]) v2 = [x.to_np for x in v] start = timer() cpp = calc_autocorr_order_2(v) end = timer() cpp_time = end - start start = timer() py = autocorr_all_harmonics(v2) end = timer() py_time = end - start py2 = autocorr_all_harmonics5(v2) assert np.max(np.abs([a - b for a, b in zip(cpp, py)])) < 1e-9 assert np.max(np.abs([a - b for a, b in zip(py2, py)])) < 1e-9 assert pytest.approx(1) == cpp[0] print("Time(c++) = %f" % cpp_time) print("Time(py) = %f" % py_time) print("Speedup = %g%%" % (py_time / cpp_time * 100))
def test_calc_rmsd_exception(): from pyxmolpp2.geometry import calc_alignment, XYZ, VectorXYZ, calc_rmsd, GeometryException, Transformation3d a = VectorXYZ([]) with pytest.raises(GeometryException): calc_rmsd(a, a) with pytest.raises(GeometryException): calc_rmsd(a, a, Transformation3d()) a = [XYZ(1, 2, 3)] * 10 with pytest.raises(GeometryException): calc_rmsd(VectorXYZ(a[:4]), VectorXYZ(a)) with pytest.raises(GeometryException): calc_rmsd(VectorXYZ(a[:4]), VectorXYZ(a), Transformation3d())
def test_calc_mass_center(): from pyxmolpp2.geometry import calc_mass_center, XYZ, VectorXYZ, calc_rmsd, Rotation3d, Translation3d, Degrees import numpy as np a = VectorXYZ([XYZ(0, 1, 0), XYZ(1, 0, 0), XYZ(-1, 0, 0), XYZ(0, -1, 0)]) m = np.random.random((len(a), )).tolist() x = calc_mass_center(a, m) cm = sum([r * M for r, M in zip(a, m)], XYZ(0, 0, 0)) / np.sum(m) assert (x - cm).len() == pytest.approx(0)
def test_vectorXYZ_numpy_conversions(): from timeit import default_timer as timer vectors = np.random.random((10000, 3)) start = timer() v1 = VectorXYZ([XYZ(x, y, z) for x, y, z in vectors]) end = timer() t1 = end - start start = timer() v2 = VectorXYZ.from_numpy(vectors) end = timer() t2 = end - start print("Time(py) = %f" % t1) print("Time(c++) = %f" % t2) print("Speedup = %g%%" % (t1 / t2 * 100)) assert np.allclose(vectors, v2.to_numpy())
def test_calc_inertia_tensor(): from pyxmolpp2.geometry import calc_inertia_tensor, XYZ, VectorXYZ, calc_rmsd, Rotation3d, Translation3d, Degrees import numpy as np a = VectorXYZ([XYZ(0, 1, 0), XYZ(1, 0, 0), XYZ(-1, 0, 0), XYZ(0, -1, 0)]) x = calc_inertia_tensor(a) assert np.allclose(x, np.diag([2, 2, 4])) m = [10, 1, 1, 10] x = calc_inertia_tensor(a, m) assert np.allclose(x, np.diag([20, 2, 22]))
def test_calc_inertia_tensor_off_diagonal(): from pyxmolpp2.geometry import calc_inertia_tensor, XYZ, VectorXYZ, calc_rmsd, Rotation3d, Translation3d, Degrees import numpy as np N = 1000 a = VectorXYZ.from_numpy(np.random.random((N, 3))) x = calc_inertia_tensor(a) V, _, _ = np.linalg.svd(x, full_matrices=True) a.transform(Rotation3d(V.T)) I = calc_inertia_tensor(a) assert np.allclose([I[0, 1], I[0, 2], I[1, 0], I[1, 2], I[2, 0], I[2, 1]], 0)
def test_alignment_exception(): from pyxmolpp2.geometry import calc_alignment, XYZ, VectorXYZ, calc_rmsd, AlignmentError a = [XYZ(1, 2, 3)] * 10 with pytest.raises(AlignmentError): calc_alignment(VectorXYZ(a[:2]), VectorXYZ(a[:2])) calc_alignment(VectorXYZ(a[:3]), VectorXYZ(a[:3])) with pytest.raises(AlignmentError): calc_alignment(VectorXYZ(a[:4]), VectorXYZ(a))
def test_sasa_three_spheres(): for samples, precision in [ (10, 5e0), # 5% accuracy (50, 1e0), # 1% accuracy (250, 1e-1), # 0.1% accuracy (1000, 1e-2), # 0.01% accuracy (5000, 1e-3), # 0.001% accuracy ]: for _ in range(100): r1, r2, r3 = np.random.random(3) * 2 + 0.01 a = XYZ(*(np.random.random(3) * 2 - 1)) b = XYZ(*(np.random.random(3) * 2 - 1)) v = XYZ(*np.random.random(3)) v /= v.len() c = a + v * (r1 + r3) S1 = 4 * np.pi * r1 ** 2 S2 = 4 * np.pi * r2 ** 2 S3 = 4 * np.pi * r3 ** 2 S1_loss = first_sphere_hidden_area(a, b, r1, r2) + first_sphere_hidden_area(a, c, r1, r3) S2_loss = first_sphere_hidden_area(b, a, r2, r1) + first_sphere_hidden_area(b, c, r2, r3) S3_loss = first_sphere_hidden_area(c, a, r3, r1) + first_sphere_hidden_area(c, b, r3, r2) total_area = S1 + S2 + S3 exposed_area_exact = total_area - S1_loss - S2_loss - S3_loss sasa = calc_sasa(VectorXYZ([a, b, c]), np.array([r1, r2, r3]), 0, n_samples=samples) exposed_area_approx = sum(sasa) exposed_area_percent_exact = exposed_area_exact / total_area * 100 exposed_area_percent_approx = exposed_area_approx / total_area * 100 assert np.isclose(exposed_area_percent_exact, exposed_area_percent_approx, atol=precision), (exposed_area_percent_exact, exposed_area_percent_approx,)
def test_sasa_errors(): coords = VectorXYZ.from_numpy(np.random.random((100, 3))) radii = np.random.random((100,)) indices = np.zeros(100).astype(np.intc) calc_sasa(coords, radii, 1.4, indices, 10) # coords.size()!=radii.size() with pytest.raises(RuntimeError): calc_sasa(coords[:-1], radii, 1.4, indices, 10) # too many indices with pytest.raises(RuntimeError): calc_sasa(coords[:-1], radii, 1.4, np.zeros(101).astype(np.intc), 10) # wrong type of indices with pytest.raises(RuntimeError): calc_sasa(coords[:-1], radii, 1.4, np.zeros(101).astype(int), 10) # wrong type of radii with pytest.raises(RuntimeError): calc_sasa(coords[:-1], radii.astype(np.half), 1.4, indices, 10)
def test_vectorXYZ_transformations(): v = VectorXYZ([XYZ(0, 0, 0), XYZ(1, 1, 1)]) v.transform(Translation3d(XYZ(2, 2, 2))) for (a, b) in zip(v, VectorXYZ([XYZ(2, 2, 2), XYZ(3, 3, 3)])): assert (a - b).len() == 0 v.transform(Translation3d(XYZ(2, 2, 2))) v.transform( Transformation3d(Rotation3d(XYZ(1, 1, 1), Degrees(30)), Translation3d(XYZ(2, 2, 2)))) v.transform(Rotation3d(XYZ(1, 1, 1), Degrees(30))) v.transform(UniformScale3d(5))