def setUp(self):
        self.x = array([[51.65, -1.90, 50.07], [50.40, -1.23, 50.65],
                        [50.68, -0.04, 51.54], [50.22, -0.02, 52.85]])

        self.y = array([[51.30, -2.99, 46.54], [51.09, -1.88, 47.58],
                        [52.36, -1.20, 48.03], [52.71, -1.18, 49.38]])

        self.sup = QCPSuperimposer()
        self.sup.set(self.x, self.y)
    def setUp(self):
        self.x = array([[51.65, -1.90, 50.07],
                        [50.40, -1.23, 50.65],
                        [50.68, -0.04, 51.54],
                        [50.22, -0.02, 52.85]])

        self.y = array([[51.30, -2.99, 46.54],
                        [51.09, -1.88, 47.58],
                        [52.36, -1.20, 48.03],
                        [52.71, -1.18, 49.38]])

        self.sup = QCPSuperimposer()
        self.sup.set(self.x, self.y)
Beispiel #3
0
    def align(self, structure, transform=True):
        """Align the input structure onto the reference structure.

        Parameters
        ----------
        transform: bool, optional
            If True (default), apply the rotation/translation that minimizes
            the RMSD between the two structures to the input structure. If
            False, the structure is not modified but the optimal RMSD will
            still be calculated.
        """
        self.rms = None  # clear before aligning

        coord = self.get_guide_coord_from_structure(structure)

        if len(coord) < self.window_size * 2:
            n_atoms = len(coord)
            msg = (f"Too few atoms in the mobile structure ({n_atoms}). "
                   "Try reducing the window_size parameter.")
            raise PDBException(msg)

        # Run CEAlign
        # CEAlign returns the best N paths, where each path is a pair of lists
        # with aligned atom indices. Paths are not guaranteed to be unique.
        paths = run_cealign(self.refcoord, coord, self.window_size,
                            self.max_gap)
        unique_paths = {(tuple(pA), tuple(pB)) for pA, pB in paths}

        # Iterate over unique paths and find the one that gives the lowest
        # corresponding RMSD. Use QCP to align the molecules.
        best_rmsd, best_u = 1e6, None
        for u_path in unique_paths:
            idxA, idxB = u_path

            coordsA = np.array([self.refcoord[i] for i in idxA])
            coordsB = np.array([coord[i] for i in idxB])

            aln = QCPSuperimposer()
            aln.set(coordsA, coordsB)
            aln.run()
            if aln.rms < best_rmsd:
                best_rmsd = aln.rms
                best_u = (aln.rot, aln.tran)

        if best_u is None:
            raise RuntimeError("Failed to find a suitable alignment.")

        if transform:
            # Transform all atoms
            rotmtx, trvec = best_u
            for chain in structure.get_chains():
                for resid in chain.get_unpacked_list():
                    for atom in resid.get_unpacked_list():
                        atom.transform(rotmtx, trvec)

        self.rms = best_rmsd
 def calc_rmsd(self, source_atoms, target_atoms):
     from math import sqrt
     import numpy as np
     from Bio.PDB.QCPSuperimposer import QCPSuperimposer
     if len(source_atoms) != len(target_atoms):
         return -1
     source_arr = []
     for atom in source_atoms:
         xyz = [atom.coord[0], atom.coord[1], atom.coord[2]]
         source_arr.append(xyz)
     source_arr = np.array(source_arr)
     target_arr = []
     for atom in target_atoms:
         xyz = [atom.coord[0], atom.coord[1], atom.coord[2]]
         target_arr.append(xyz)
     target_arr = np.array(target_arr)
     sup = QCPSuperimposer()
     sup.set(source_arr, target_arr)
     sup.run()
     return sup.get_rms()
        "C module in Bio.QCPSuperimposer not compiled")


# start with two coordinate sets (Nx3 arrays - Float0)

x = array([[51.65, -1.90, 50.07],
         [50.40, -1.23, 50.65],
         [50.68, -0.04, 51.54],
         [50.22, -0.02, 52.85]], 'f')

y = array([[51.30, -2.99, 46.54],
         [51.09, -1.88, 47.58],
         [52.36, -1.20, 48.03],
         [52.71, -1.18, 49.38]], 'f')

sup = QCPSuperimposer()

# set the coords
# y will be rotated and translated on x
sup.set(x, y)

# do the qcp fit
sup.run()

# get the rmsd
rms = sup.get_rms()

# get rotation (right multiplying!) and the translation
rot, tran = sup.get_rotran()

# rotate y on x manually
Beispiel #6
0
        "Install NumPy if you want to use Bio.QCPSuperimposer.")

from Bio import BiopythonExperimentalWarning
with warnings.catch_warnings():
    warnings.simplefilter('ignore', BiopythonExperimentalWarning)
    from Bio.PDB.QCPSuperimposer import QCPSuperimposer

# start with two coordinate sets (Nx3 arrays - Float0)

x = array([[51.65, -1.90, 50.07], [50.40, -1.23, 50.65], [50.68, -0.04, 51.54],
           [50.22, -0.02, 52.85]], 'f')

y = array([[51.30, -2.99, 46.54], [51.09, -1.88, 47.58], [52.36, -1.20, 48.03],
           [52.71, -1.18, 49.38]], 'f')

sup = QCPSuperimposer()

# set the coords
# y will be rotated and translated on x
sup.set(x, y)

# do the qcp fit
sup.run()

# get the rmsd
rms = sup.get_rms()

# get rotation (right multiplying!) and the translation
rot, tran = sup.get_rotran()

# rotate y on x manually
class QCPSuperimposerTest(unittest.TestCase):
    def setUp(self):
        self.x = array([[51.65, -1.90, 50.07], [50.40, -1.23, 50.65],
                        [50.68, -0.04, 51.54], [50.22, -0.02, 52.85]])

        self.y = array([[51.30, -2.99, 46.54], [51.09, -1.88, 47.58],
                        [52.36, -1.20, 48.03], [52.71, -1.18, 49.38]])

        self.sup = QCPSuperimposer()
        self.sup.set(self.x, self.y)

    # Public methods

    def test_set(self):
        self.assertTrue(
            array_equal(around(self.sup.reference_coords, decimals=3),
                        around(self.x, decimals=3)))
        self.assertTrue(
            array_equal(around(self.sup.coords, decimals=3),
                        around(self.y, decimals=3)))
        self.assertIsNone(self.sup.transformed_coords)
        self.assertIsNone(self.sup.rot)
        self.assertIsNone(self.sup.tran)
        self.assertIsNone(self.sup.rms)
        self.assertIsNone(self.sup.init_rms)

    def test_run(self):
        self.sup.run()
        self.assertTrue(
            array_equal(around(self.sup.reference_coords, decimals=3),
                        around(self.x, decimals=3)))
        self.assertTrue(
            array_equal(around(self.sup.coords, decimals=3),
                        around(self.y, decimals=3)))
        self.assertIsNone(self.sup.transformed_coords)
        calc_rot = array([[0.68304939, -0.5227742, -0.51004967],
                          [0.53664482, 0.83293151, -0.13504605],
                          [0.49543503, -0.18147239, 0.84947743]])
        self.assertTrue(
            array_equal(around(self.sup.rot, decimals=3),
                        around(calc_rot, decimals=3)))
        calc_tran = array([-7.43885125, 36.51522275, 36.81135533])
        self.assertTrue(
            array_equal(around(self.sup.tran, decimals=3),
                        around(calc_tran, decimals=3)))
        calc_rms = 0.003
        self.assertEqual(float('%.3f' % self.sup.rms), calc_rms)
        self.assertIsNone(self.sup.init_rms)

    def test_get_transformed(self):
        self.sup.run()
        transformed_coords = array([[49.05456082, -1.23928381, 50.58427566],
                                    [50.02204971, -0.39367917, 51.42494181],
                                    [51.47738545, -0.57287128, 51.06760944],
                                    [52.39602307, -0.98417088, 52.03318837]])
        self.assertTrue(
            array_equal(around(self.sup.get_transformed(), decimals=3),
                        around(transformed_coords, decimals=3)))

    def test_get_init_rms(self):
        x = array([[1.1, 1.2, 1.3], [1.4, 1.5, 1.6], [1.7, 1.8, 1.9]])
        y = array([[1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0]])
        self.sup.set(x, y)
        self.assertIsNone(self.sup.init_rms)
        init_rms = array([0.81, 0.9, 0.98])
        self.assertTrue(
            array_equal(around(self.sup.get_init_rms(), decimals=2),
                        around(init_rms, decimals=2)))

    def test_get_rotran(self):
        self.sup.run()
        calc_rot = array([[0.68304939, -0.5227742, -0.51004967],
                          [0.53664482, 0.83293151, -0.13504605],
                          [0.49543503, -0.18147239, 0.84947743]])
        calc_tran = array([-7.43885125, 36.51522275, 36.81135533])
        rot, tran = self.sup.get_rotran()
        self.assertTrue(
            array_equal(around(rot, decimals=3), around(calc_rot, decimals=3)))
        self.assertTrue(
            array_equal(around(tran, decimals=3), around(calc_tran,
                                                         decimals=3)))

    def test_get_rms(self):
        self.sup.run()
        calc_rms = 0.003
        self.assertEqual(float('%.3f' % self.sup.get_rms()), calc_rms)

    # Old test from Bio/PDB/QCPSuperimposer/__init__.py

    def test_oldTest(self):
        x = array([[-2.803, -15.373, 24.556], [0.893, -16.062, 25.147],
                   [1.368, -12.371, 25.885], [-1.651, -12.153, 28.177],
                   [-0.440, -15.218, 30.068], [2.551, -13.273, 31.372],
                   [0.105, -11.330, 33.567]])

        y = array([[-14.739, -18.673, 15.040], [-12.473, -15.810, 16.074],
                   [-14.802, -13.307, 14.408], [-17.782, -14.852, 16.171],
                   [-16.124, -14.617, 19.584], [-15.029, -11.037, 18.902],
                   [-18.577, -10.001, 17.996]])

        self.sup.set(x, y)
        self.assertTrue(
            array_equal(around(self.sup.reference_coords, decimals=3),
                        around(x, decimals=3)))
        self.assertTrue(
            array_equal(around(self.sup.coords, decimals=3),
                        around(y, decimals=3)))

        self.sup.run()
        rot = array([[0.72216358, 0.69118937, -0.0271479],
                     [-0.52038257, 0.51700833, -0.67963547],
                     [-0.45572112, 0.50493528, 0.73304748]])
        tran = array([11.68878393, -4.13245037, 6.05208344])
        rms = 0.7191064509622271
        self.assertTrue(
            array_equal(around(self.sup.rot, decimals=3),
                        around(rot, decimals=3)))
        self.assertTrue(
            array_equal(around(self.sup.tran, decimals=3),
                        around(tran, decimals=3)))
        self.assertEqual(float('%.3f' % self.sup.rms), around(rms, decimals=3))

        rms_get = self.sup.get_rms()
        self.assertTrue(
            array_equal(around(rms_get, decimals=3), around(rms, decimals=3)))

        rot_get, tran_get = self.sup.get_rotran()
        self.assertTrue(
            array_equal(around(rot_get, decimals=3), around(rot, decimals=3)))
        self.assertTrue(
            array_equal(around(tran_get, decimals=3), around(tran,
                                                             decimals=3)))

        y_on_x1 = dot(y, rot) + tran
        y_x_solution = array([[3.90787281, -16.37976032, 30.16808376],
                              [3.58322456, -12.81122728, 28.91874135],
                              [1.3580194, -13.96815768, 26.05958411],
                              [-0.79347336, -15.93647897, 28.48288439],
                              [-1.27379224, -12.9456459, 30.78004989],
                              [-2.03519089, -10.6822696, 27.81728956],
                              [-4.72366028, -13.05646024, 26.54536695]])
        self.assertTrue(
            array_equal(around(y_on_x1, decimals=3),
                        around(y_x_solution, decimals=3)))

        y_on_x2 = self.sup.get_transformed()
        self.assertTrue(
            array_equal(around(y_on_x2, decimals=3),
                        around(y_x_solution, decimals=3)))
class QCPSuperimposerTest(unittest.TestCase):

    def setUp(self):
        self.x = array([[51.65, -1.90, 50.07],
                        [50.40, -1.23, 50.65],
                        [50.68, -0.04, 51.54],
                        [50.22, -0.02, 52.85]])

        self.y = array([[51.30, -2.99, 46.54],
                        [51.09, -1.88, 47.58],
                        [52.36, -1.20, 48.03],
                        [52.71, -1.18, 49.38]])

        self.sup = QCPSuperimposer()
        self.sup.set(self.x, self.y)

    # Public methods

    def test_set(self):
        self.assertTrue(
            array_equal(around(self.sup.reference_coords, decimals=3), around(self.x, decimals=3)))
        self.assertTrue(
            array_equal(around(self.sup.coords, decimals=3), around(self.y, decimals=3)))
        self.assertIsNone(self.sup.transformed_coords)
        self.assertIsNone(self.sup.rot)
        self.assertIsNone(self.sup.tran)
        self.assertIsNone(self.sup.rms)
        self.assertIsNone(self.sup.init_rms)

    def test_run(self):
        self.sup.run()
        self.assertTrue(
            array_equal(around(self.sup.reference_coords, decimals=3), around(self.x, decimals=3)))
        self.assertTrue(
            array_equal(around(self.sup.coords, decimals=3), around(self.y, decimals=3)))
        self.assertIsNone(self.sup.transformed_coords)
        calc_rot = array([[0.68304939, -0.5227742, -0.51004967],
                          [0.53664482, 0.83293151, -0.13504605],
                          [0.49543503, -0.18147239, 0.84947743]])
        self.assertTrue(
            array_equal(around(self.sup.rot, decimals=3), around(calc_rot, decimals=3)))
        calc_tran = array([-7.43885125, 36.51522275, 36.81135533])
        self.assertTrue(
            array_equal(around(self.sup.tran, decimals=3), around(calc_tran, decimals=3)))
        calc_rms = 0.003
        self.assertEqual(float('%.3f' % self.sup.rms), calc_rms)
        self.assertIsNone(self.sup.init_rms)

    def test_get_transformed(self):
        self.sup.run()
        transformed_coords = array([[49.05456082, -1.23928381, 50.58427566],
                                    [50.02204971, -0.39367917, 51.42494181],
                                    [51.47738545, -0.57287128, 51.06760944],
                                    [52.39602307, -0.98417088, 52.03318837]])
        self.assertTrue(
            array_equal(around(self.sup.get_transformed(), decimals=3), around(transformed_coords, decimals=3)))

    def test_get_init_rms(self):
        x = array([[1.1, 1.2, 1.3],
                  [1.4, 1.5, 1.6],
                  [1.7, 1.8, 1.9]])
        y = array([[1.0, 1.0, 1.0],
                  [1.0, 1.0, 1.0],
                  [1.0, 1.0, 1.0]])
        self.sup.set(x, y)
        self.assertIsNone(self.sup.init_rms)
        init_rms = array([0.81, 0.9, 0.98])
        self.assertTrue(
            array_equal(around(self.sup.get_init_rms(), decimals=2), around(init_rms, decimals=2)))

    def test_get_rotran(self):
        self.sup.run()
        calc_rot = array([[0.68304939, -0.5227742, -0.51004967],
                          [0.53664482, 0.83293151, -0.13504605],
                          [0.49543503, -0.18147239, 0.84947743]])
        calc_tran = array([-7.43885125, 36.51522275, 36.81135533])
        rot, tran = self.sup.get_rotran()
        self.assertTrue(
            array_equal(around(rot, decimals=3), around(calc_rot, decimals=3)))
        self.assertTrue(
            array_equal(around(tran, decimals=3), around(calc_tran, decimals=3)))

    def test_get_rms(self):
        self.sup.run()
        calc_rms = 0.003
        self.assertEqual(float('%.3f' % self.sup.get_rms()), calc_rms)

    # Old test from Bio/PDB/QCPSuperimposer/__init__.py

    def test_oldTest(self):
        x = array([[-2.803, -15.373, 24.556],
                   [0.893, -16.062, 25.147],
                   [1.368, -12.371, 25.885],
                   [-1.651, -12.153, 28.177],
                   [-0.440, -15.218, 30.068],
                   [2.551, -13.273, 31.372],
                   [0.105, -11.330, 33.567]])

        y = array([[-14.739, -18.673, 15.040],
                   [-12.473, -15.810, 16.074],
                   [-14.802, -13.307, 14.408],
                   [-17.782, -14.852, 16.171],
                   [-16.124, -14.617, 19.584],
                   [-15.029, -11.037, 18.902],
                   [-18.577, -10.001, 17.996]])

        self.sup.set(x, y)
        self.assertTrue(
            array_equal(around(self.sup.reference_coords, decimals=3), around(x, decimals=3)))
        self.assertTrue(
            array_equal(around(self.sup.coords, decimals=3), around(y, decimals=3)))

        self.sup.run()
        rot = array([[0.72216358, 0.69118937, -0.0271479],
                     [-0.52038257, 0.51700833, -0.67963547],
                     [-0.45572112, 0.50493528, 0.73304748]])
        tran = array([11.68878393, -4.13245037, 6.05208344])
        rms = 0.7191064509622271
        self.assertTrue(
            array_equal(around(self.sup.rot, decimals=3), around(rot, decimals=3)))
        self.assertTrue(
            array_equal(around(self.sup.tran, decimals=3), around(tran, decimals=3)))
        self.assertEqual(float('%.3f' % self.sup.rms), around(rms, decimals=3))

        rms_get = self.sup.get_rms()
        self.assertTrue(
            array_equal(around(rms_get, decimals=3), around(rms, decimals=3)))

        rot_get, tran_get = self.sup.get_rotran()
        self.assertTrue(
            array_equal(around(rot_get, decimals=3), around(rot, decimals=3)))
        self.assertTrue(
            array_equal(around(tran_get, decimals=3), around(tran, decimals=3)))

        y_on_x1 = dot(y, rot) + tran
        y_x_solution = array([[3.90787281, -16.37976032, 30.16808376],
                              [3.58322456, -12.81122728, 28.91874135],
                              [1.3580194, -13.96815768, 26.05958411],
                              [-0.79347336, -15.93647897, 28.48288439],
                              [-1.27379224, -12.9456459, 30.78004989],
                              [-2.03519089, -10.6822696, 27.81728956],
                              [-4.72366028, -13.05646024, 26.54536695]])
        self.assertTrue(
            array_equal(around(y_on_x1, decimals=3), around(y_x_solution, decimals=3)))

        y_on_x2 = self.sup.get_transformed()
        self.assertTrue(
            array_equal(around(y_on_x2, decimals=3), around(y_x_solution, decimals=3)))
Beispiel #9
0
from Bio.PDB.QCPSuperimposer import QCPSuperimposer
sup = QCPSuperimposer()
# set the coords
# y will be rotated and translated on x
sup.set(x, y)
# do the lsq fit
sup.run()
# get the rmsd
rms = sup.get_rms()