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_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_shorthands(): import numpy as np from pyxmolpp2.geometry import Rotation3d, Translation3d, XYZ, Degrees, calc_alignment frame = make_polyglycine([("A", 20)]) for a in frame.asAtoms: a.r = XYZ(*np.random.random(3)) frame2 = frame.copy() asel = frame.asAtoms asel2 = frame2.asAtoms asel.geom_center() asel.mass_center([1.0] * asel.size) asel.inertia_tensor([1.0] * asel.size) asel.geom_inertia_tensor() T = Translation3d(XYZ(1, 0, 0)) asel2.transform(T) assert np.isclose(asel.rmsd(asel2), 1.0) assert np.isclose(asel.rmsd(asel2.toCoords), 1.0) assert np.isclose(asel.rmsd(asel2.toCoords.transform(T.inverted())), 0.0) T = Translation3d(XYZ(1, 0, 0)) * Rotation3d(XYZ(1, 1, 1), Degrees(45)) asel.align_to(asel2) assert np.isclose(asel.rmsd(asel2), 0) asel2.transform(T) asel.align_to(asel2.toCoords) assert np.isclose(asel.rmsd(asel2), 0) T = Translation3d(XYZ(1, 0, 0)) * Rotation3d(XYZ(1, 1, 1), Degrees(45)) asel2.transform(T) assert np.allclose(T.matrix3d(), calc_alignment(asel2.toCoords, asel.toCoords).matrix3d()) assert np.allclose(T.matrix3d(), asel.alignment_to(asel2).matrix3d()) assert np.allclose(T.matrix3d(), asel.alignment_to(asel2.toCoords).matrix3d())
def test_rmsd(): from pyxmolpp2.polymer import AtomName from pyxmolpp2.pdb import PdbFile from pyxmolpp2.geometry import calc_rmsd, calc_alignment, calc_geom_center import glob filenames = sorted(glob.glob("tests_dataset/pdb/rcsb/*.pdb")) for i in range(len(filenames) - 1): frame_1 = PdbFile(filenames[i]).get_frame() residues_1 = [ a.rId for a in frame_1.asChains[0].asAtoms.filter( lambda a: a.name.str == "CA") ] for j in range(i + 1, len(filenames)): frame_2 = PdbFile(filenames[j]).get_frame() residues_2 = [ a.rId for a in frame_2.asChains[0].asAtoms.filter( lambda a: a.name.str == "CA") ] common = set(residues_1) & set(residues_2) ats1 = frame_1.asChains[0].asAtoms.filter(lambda a: ( a.id == a.residue[AtomName("CA")].id) and a.rId in common) ats2 = frame_2.asChains[0].asAtoms.filter(lambda a: ( a.id == a.residue[AtomName("CA")].id) and a.rId in common) assert ats1.size == len(common) assert ats2.size == len(common) assert ats1.size == ats2.size assert len(ats1) > 3 assert len(ats2) > 3 aligment = calc_alignment(ats1.toCoords, ats2.toCoords) not_aligned_rmsd = calc_rmsd(ats1.toCoords, ats2.toCoords) aligned_rmsd = calc_rmsd(ats1.toCoords, ats2.toCoords, aligment)
# Number of residues in chains must be same (strip water, ions, etc.) N = 0 for i in range(frame.size): if frame.asChains[i].size != frame.asChains[0].size: break N += 1 ############################################################################## # Print RMSD matrix for all deposited chains: for i in range(0, N): chain_i_ca = frame.asChains[i].asAtoms.filter(aName == "CA") for j in range(0, i + 1): chain_j_ca = frame.asChains[j].asAtoms.filter(aName == "CA") alignment = calc_alignment(chain_i_ca.toCoords, chain_j_ca.toCoords) rmsd = calc_rmsd(chain_i_ca.toCoords, chain_j_ca.toCoords, alignment) print("%5.1f" % rmsd, end=" ") print() ############################################################################## # Calculate RMSF per residue from pyxmolpp2.geometry import UniformScale3d first_chain_ca = frame.asChains[0].asAtoms.filter(aName == "CA") # initialize average coordinates with (0,0,0)