def test_symmrmsd_atol(i: bool, reference: float) -> None: moli = copy.deepcopy(molecules.docking_1cbr[0]) molj = copy.deepcopy(molecules.docking_1cbr[i]) moli.strip() molj.strip() # Check results are different from 0.0 assert not reference == pytest.approx(0.0) assert (rmsd.symmrmsd( moli.coordinates, molj.coordinates, moli.atomicnums, molj.atomicnums, moli.adjacency_matrix, molj.adjacency_matrix, minimize=True, ) == pytest.approx(reference, abs=1e-5)) assert (rmsd.symmrmsd( moli.coordinates, molj.coordinates, moli.atomicnums, molj.atomicnums, moli.adjacency_matrix, molj.adjacency_matrix, minimize=True, atol=1e9, ) == pytest.approx(0.0))
def test_symmrmsd_centred(mol: molecule.Molecule) -> None: mol1 = copy.deepcopy(mol) mol2 = copy.deepcopy(mol) mol2.translate(np.random.rand(3)) assert (rmsd.symmrmsd( mol1.coordinates, mol2.coordinates, mol1.atomicnums, mol2.atomicnums, mol1.adjacency_matrix, mol2.adjacency_matrix, ) > 0) assert rmsd.symmrmsd( mol1.coordinates, mol2.coordinates, mol1.atomicnums, mol2.atomicnums, mol1.adjacency_matrix, mol2.adjacency_matrix, center=True, ) == pytest.approx(0)
def test_symmrmsd_rotated_benzene_stripped(angle: float) -> None: mol1 = copy.deepcopy(molecules.benzene) mol2 = copy.deepcopy(molecules.benzene) mol2.rotate(angle, np.array([0, 0, 1]), units="deg") mol1.strip() mol2.strip() assert (rmsd.rmsd(mol1.coordinates, mol2.coordinates, mol1.atomicnums, mol2.atomicnums) > 0) assert rmsd.rmsd( mol1.coordinates, mol2.coordinates, mol1.atomicnums, mol2.atomicnums, minimize=True, ) == pytest.approx(0) assert rmsd.hrmsd(mol1.coordinates, mol2.coordinates, mol1.atomicnums, mol2.atomicnums) == pytest.approx(0, abs=1e-4) assert rmsd.symmrmsd( mol1.coordinates, mol2.coordinates, mol1.atomicnums, mol2.atomicnums, mol1.adjacency_matrix, mol2.adjacency_matrix, ) == pytest.approx(0, abs=1e-4)
def test_rmsd_symmrmsd_disconnected_node() -> None: c = np.array([[0.0, 1.0, 2.0], [1.0, 2.0, 3.0], [2.0, 3.0, 4.0]]) a = np.array([0, 1, 4]) # Adjacency matrix with disconnected node A = np.array([[0, 1, 0], [1, 0, 0], [0, 0, 0]]) with pytest.warns(UserWarning, match="Disconnected graph detected."): assert rmsd.symmrmsd(c, c, a, a, A, A) == pytest.approx(0.0, abs=1e-5)
def test_issue_35_2(): """ GitHub Issue #35 from @kjelljorner https://github.com/RMeli/spyrmsd/issues/35 """ elements = np.array([6, 6, 1, 1, 1, 1, 1, 1]) connectivity_matrix = np.array([ [0, 1, 1, 1, 1, 0, 0, 0], [1, 0, 0, 0, 0, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], ]) coordinates_1 = np.array([ [-0.7513646148641476, 0.0212153090068301, 0.0811236469164399], [0.7513646329421021, -0.0212139873589844, -0.0811234544788992], [-1.1912097695762844, -0.9520810297276773, -0.1560519813078418], [-1.0197601491429782, 0.2790338755490671, 1.1099648032811764], [-1.1891251185534542, 0.769045487934088, -0.5868099187409093], [1.1891224079259752, -0.7690462686978631, 0.5868095572711365], [1.0197615786233758, -0.2790344505405097, -1.1099636171164908], [1.191211032645396, 0.9520810638350493, 0.1560509641753798], ]) coordinates_2 = np.array([ [0.752989230839992, 0.0675001892809206, -0.0055472904918074], [-0.7529892426611152, -0.0675008847728476, 0.0055489067798057], [1.0506759954349485, 1.0138756198991818, -0.4668239152871582], [1.2080371182091196, -0.7501873566674166, -0.5724157781772267], [1.148732484392816, 0.0417675099494674, 1.0141322717252037], [-1.050678518706957, -1.0138763219763327, 0.4668256362472835], [-1.148731454954795, -0.0417698443724041, -1.0141315673229787], [-1.208035612554004, 0.7501910886594293, 0.5724117365268774], ], ) mask = elements != 1 r = rmsd.symmrmsd( coordinates_1[mask], coordinates_2[mask], elements[mask], elements[mask], connectivity_matrix[mask, :][:, mask], connectivity_matrix[mask, :][:, mask], center=True, minimize=True, ) assert r == pytest.approx(0.0)
def test_symmrmsd_atol_multi() -> None: references = [0.476858, 1.68089, 1.50267] molc = copy.deepcopy(molecules.docking_1cbr[0]) mols = [copy.deepcopy(mol) for mol in molecules.docking_1cbr[1:4]] molc.strip() for mol in mols: mol.strip() # Check results are different from 0.0 assert not np.allclose(references, 0.0) RMSDs = rmsd.symmrmsd( molc.coordinates, [mol.coordinates for mol in mols], molc.atomicnums, mols[0].atomicnums, molc.adjacency_matrix, mols[0].adjacency_matrix, minimize=True, ) for r, ref in zip(RMSDs, references): assert r == pytest.approx(ref, abs=1e-5) RMSDs = rmsd.symmrmsd( molc.coordinates, [mol.coordinates for mol in mols], molc.atomicnums, mols[0].atomicnums, molc.adjacency_matrix, mols[0].adjacency_matrix, minimize=True, atol=1e9, ) for r in RMSDs: assert r == pytest.approx(0.0)
def test_rmsd_symmrmsd(index: int, RMSD: float, minimize: bool) -> None: molc = copy.deepcopy(molecules.docking_1cbr[0]) mol = copy.deepcopy(molecules.docking_1cbr[index]) molc.strip() mol.strip() assert rmsd.symmrmsd( molc.coordinates, mol.coordinates, molc.atomicnums, mol.atomicnums, molc.adjacency_matrix, mol.adjacency_matrix, minimize=minimize, ) == pytest.approx(RMSD, abs=1e-5)
def test_issue_35_1(): """ GitHub Issue #35 from @kjelljorner https://github.com/RMeli/spyrmsd/issues/35 """ elements = np.array([6, 1, 1, 1, 1]) connectivity_matrix = np.array([ [0, 1, 1, 1, 1], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], ]) coordinates_1 = np.array([ [2.416690358222e-09, -2.979634307864e-08, -9.782357562900e-09], [-6.669665490935e-01, -6.162099127861e-01, -6.069106091317e-01], [-4.258088724928e-01, 9.999808728518e-01, 1.078170393201e-01], [1.178459756093e-01, -4.538168967035e-01, 9.864390766805e-01], [9.749294435604e-01, 7.004596643409e-02, -4.873454970866e-01], ]) coordinates_2 = np.array([ [-2.118450971480e-07, 2.238951108509e-07, 1.839989120690e-07], [-5.297519571039e-01, -4.011375110922e-01, 8.668054003529e-01], [-5.107749001064e-01, 8.975573096842e-01, -3.555275589573e-01], [1.644944812511e-02, -7.486078704316e-01, -7.951194721576e-01], [1.024077620930e00, 2.521878479445e-01, 2.838414467631e-01], ]) r = rmsd.symmrmsd( coordinates_1, coordinates_2, elements, elements, connectivity_matrix, connectivity_matrix, center=True, minimize=True, ) assert r == pytest.approx(0.0)
def test_multi_spyrmsd(minimize: bool, referenceRMSDs: List[float]) -> None: molc = copy.deepcopy(molecules.docking_1cbr[0]) mols = [copy.deepcopy(mol) for mol in molecules.docking_1cbr[1:]] molc.strip() for mol in mols: mol.strip() RMSDs = rmsd.symmrmsd( molc.coordinates, [mol.coordinates for mol in mols], molc.atomicnums, mols[0].atomicnums, molc.adjacency_matrix, mols[0].adjacency_matrix, minimize=minimize, ) for RMSD, referenceRMSD in zip(RMSDs, referenceRMSDs): assert RMSD == pytest.approx(referenceRMSD, abs=1e-5)
def test_symmrmsd_atomicnums_matching_pyridine_stripped() -> None: mol1 = copy.deepcopy(molecules.pyridine) mol2 = copy.deepcopy(molecules.pyridine) mol2.rotate(60, np.array([0, 0, 1]), units="deg") mol1.strip() mol2.strip() # Standard RMSD, correct in this case RMSD = rmsd.rmsd(mol1.coordinates, mol2.coordinates, mol1.atomicnums, mol2.atomicnums) # Isomorphic RMSD with atomic number matching is correct # Without atomic number matching this would be wrong because of higher symmetry assert rmsd.symmrmsd( mol1.coordinates, mol2.coordinates, mol1.atomicnums, mol2.atomicnums, mol1.adjacency_matrix, mol2.adjacency_matrix, ) == pytest.approx(RMSD, abs=1e-4)
def rmsdwrapper( molref, mols, symmetry: bool = True, center: bool = False, minimize: bool = False, strip: bool = True, cache: bool = True, ) -> Any: """ Compute RMSD between two molecule. Parameters ---------- mol1: molecule.Molecule Molecule 1 mol2: molecule.Molecule Molecule 2 symmetry: bool, optional Symmetry-corrected RMSD (using graph isomorphism) center: bool, optional Center molecules at origin minimize: bool, optional Minimised RMSD (using the quaternion polynomial method) strip: bool, optional Strip hydrogen atoms Returns ------- List[float] RMSDs """ if strip: molref.strip() for mol in mols: mol.strip() if minimize: center = True cref = coords_from_molecule(molref, center) cmols = [coords_from_molecule(mol, center) for mol in mols] RMSDlist = [] if symmetry: RMSDlist = rmsd.symmrmsd( cref, cmols, molref.atomicnums, mols[0].atomicnums, molref.adjacency_matrix, mols[0].adjacency_matrix, center=center, minimize=minimize, cache=cache, ) else: # No symmetry for c in cmols: RMSDlist.append( rmsd.rmsd( cref, c, molref.atomicnums, mols[0].atomicnums, center=center, minimize=minimize, )) return RMSDlist
if verbose: print(f"Atomic mapping: '{select}'\n{atomicmap}") time = [] rmsds = [] rmsd_nosymm = [] for ts in tqdm.tqdm(traj.trajectory[::step]): # Align protein backbones old_rmsd, new_rmsd = align.alignto(traj, ref, select="backbone", strict=True) assert new_rmsd <= old_rmsd if symmetry: r = rmsd.symmrmsd(selection.atoms.positions, ref_positions, atomicmap, atomicmap, A, A) else: r = rmsd.rmsd(selection.atoms.positions, ref_positions, atomicmap, atomicmap) time.append(ts.time) rmsds.append(r) rmsd_nosymm.append( rmsd.rmsd(selection.atoms.positions, ref_positions, atomicmap, atomicmap)) # Check rmsd_nosymm is the same as rms.RMDS rmsd_mda = rms.RMSD(traj, ref, select="backbone",