Esempio n. 1
0
def normalize_pts(pts1, pts2):
    #print pts1
    A = pts1[:, 0:2]
    B = pts2[:, 0:2]

    assert len(A) == len(B)

    N = A.shape[0]  # total points

    # find centroids
    centroid_A = rmsd.centroid(A)
    centroid_B = rmsd.centroid(B)

    # centre the points
    AA = A - centroid_A
    BB = B - centroid_B
    
    #get optimal rotation matrix
    R = rmsd.kabsch(AA, BB)
    # Apply transformation
    AA1 = np.dot(AA, R)
    angle1 = math.atan2(R[1][0], R[1][1])
    
    #try flippin' it
    AA[:, 1] *= -1
    #get optimal rotation matrix
    R = rmsd.kabsch(AA, BB)
    # Apply transformation
    AA2 = np.dot(AA, R)#get optimal rotation matrix
    angle2 = math.atan2(R[1][0], R[1][1])
    
    #go with whichever one is better
    a2diff = np.abs(pts2[:,2]-(pts1[:,2]-angle2))
    a1diff = np.abs(pts2[:,2]-(pts1[:,2]+angle1))
    #angle differences are fun!
    for i in range(0, len(a1diff)):
        while (a2diff[i] > np.pi):
            a2diff[i] -= 2*np.pi
        while (a1diff[i] > np.pi):
            a1diff[i] -= 2*np.pi
    print np.degrees(a2diff), np.degrees(a1diff)
    if (np.sum(np.abs(a1diff)) > np.sum(np.abs(a2diff))):
        pts1[:, 0:2] = AA2 + centroid_B
        # rotate the rotations (backwards, since we mirrored the thing)
        pts1[:, 2] -= angle2
        return rmsd.rmsd(AA2, BB)
    else:
        pts1[:, 0:2] = AA1 + centroid_B
        # rotate the rotations
        pts1[:, 2] += angle1
        return rmsd.rmsd(AA1, BB)
Esempio n. 2
0
def get_mappings(ref, structure):

	n = len(structure)
	cs = itertools.permutations(range(n), 3)

	keeps = {}

	for c in cs:
		Q = rmsd.kabsch(ref[:3], structure[list(c)]).T
		assert np.linalg.det(Q) > 0.5

		rotated = np.dot(structure, Q.T)
		ds = scipy.spatial.distance.cdist(rotated, ref)

		_, res = scipy.optimize.linear_sum_assignment(ds)
		res = invert_array(res)
		obj = rmsd.rmsd(rotated[res], structure)
		if obj > 1E-3:
			continue

		key = tuple(res)
		if key not in keeps:
			keeps[key] = Q

	return keeps
    def normalize_pts(self, pts1, pts2):
        #print pts1
        A = pts1[:, 0:2]
        B = pts2[:, 0:2]

        assert len(A) == len(B)

        N = A.shape[0]  # total points

        # find centroids
        centroid_A = rmsd.centroid(A)
        centroid_B = rmsd.centroid(B)

        # centre the points
        AA = A - centroid_A
        BB = B - centroid_B

        #get optimal rotation matrix
        R = rmsd.kabsch(AA, BB)
        # Apply transformation
        AA1 = np.dot(AA, R)
        angle1 = math.atan2(R[1][0], R[1][1])

        pts1[:, 0:2] = AA1 + centroid_B
        # rotate the rotations
        pts1[:, 2] -= angle1
        return rmsd.rmsd(AA1, BB)
Esempio n. 4
0
def alin(A,B):
	A -= rmsd.centroid(A)
	B -= rmsd.centroid(B)
	#print (B)
	U = rmsd.kabsch(A, B)
	A = np.dot(A, U)

	return A, B, rmsd.rmsd(A,B)
def KabschTransform(MAT_B, MAT_R):
    C_road = rmsd.centroid(MAT_R)  # centreroid of the road points
    C_back = rmsd.centroid(MAT_B)  # centreroid of the back points
    XYZroad_centered = MAT_R - C_road  #XYZ of road after centering
    XYZback_centered = MAT_B - C_back  #XYZ of back after centering
    R = rmsd.kabsch(
        XYZroad_centered, XYZback_centered
    )  # the optimal rotation matrix to rotate road points to back coordinates
    return C_road, C_back, R
def get_transformation_matrix_kabsch(q, p):
    # compute centroids
    Pc = rmsd.centroid(p)
    Qc = rmsd.centroid(q)
    # Kabsch algorithm for estimating R and t
    T = np.identity(4)
    T[:3, :3] = rmsd.kabsch(p - Pc, q - Qc)
    T[:3, 3] = Pc - np.dot(T[:3, :3], Qc)

    return T
Esempio n. 7
0
def crmsd_kabsch(A, B):
    # Translate
    A -= rmsd.centroid(A)
    B -= rmsd.centroid(B)

    # Rotate
    U = rmsd.kabsch(A, B)
    A = np.dot(A, U)

    return rmsd.rmsd(A, B)
Esempio n. 8
0
def kabsch(pointsCurrent, pointsRef):

    C_curr = rmsd.centroid(pointsCurrent)
    C_ref = rmsd.centroid(pointsRef)

    points_curr_norm = pointsCurrent - C_curr  # XYZ current after centering
    points_ref_norm = pointsRef - C_ref

    # the optimal rotation matrix to rotate XYZcurrent to XYZref
    R = rmsd.kabsch(points_curr_norm, points_ref_norm)

    return (R, C_curr, C_ref)
Esempio n. 9
0
def test_kabash_algorith_pdb():

    filename_1 = pathlib.PurePath(RESOURCE_PATH, "ci2_1.pdb")
    filename_2 = pathlib.PurePath(RESOURCE_PATH, "ci2_2.pdb")

    p_atoms, p_coord = rmsd.get_coordinates_pdb(filename_1)
    q_atoms, q_coord = rmsd.get_coordinates_pdb(filename_2)

    rotation_matrix = rmsd.kabsch(p_coord, q_coord)

    np.testing.assert_array_almost_equal([-0.5124, 0.8565, 0.0608],
                                         rotation_matrix[0],
                                         decimal=3)
Esempio n. 10
0
def align(q_coord, p_coord):
    """

    align q and p.

    return q coord rotated

    """

    U = rmsd.kabsch(q_coord, p_coord)
    q_coord = np.dot(q_coord, U)

    return q_coord
def center_and_kabsch(P, Q):
    """ returns centroid of P, Q and a rotational matrix (in subsequent analyses, you may want to subtract centroidP/Q from your point sets)
    that minimizes RMSD between corresponding points in P and Q, *when applied to P* """

    P = np.array(P)
    Q = np.array(Q)

    centroidP = rmsd.centroid(P)
    centroidQ = rmsd.centroid(Q)

    P = P - centroidP
    Q = Q - centroidQ

    return centroidP, centroidQ, rmsd.kabsch(P, Q)
Esempio n. 12
0
def calculate_rmsd(mol_id,
                   geometry_id1=None,
                   geometry_id2=None,
                   heavy_atoms_only=False):

    # These cause circular import errors if we put them at the top of the file
    from ._girder import GirderClient
    from ._calculation import GirderMolecule

    # Allow the user to pass in a GirderMolecule instead of an id
    if isinstance(mol_id, GirderMolecule):
        mol_id = mol_id._id

    if geometry_id1 is None:
        cjson1 = GirderClient().get('/molecules/%s/cjson' % mol_id)
    else:
        cjson1 = GirderClient().get('/molecules/%s/geometries/%s/cjson' %
                                    (mol_id, geometry_id1))

    if geometry_id2 is None:
        cjson2 = GirderClient().get('/molecules/%s/cjson' % mol_id)
    else:
        cjson2 = GirderClient().get('/molecules/%s/geometries/%s/cjson' %
                                    (mol_id, geometry_id2))

    coords1 = cjson1['atoms']['coords']['3d']
    coords1_triplets = zip(coords1[0::3], coords1[1::3], coords1[2::3])
    A = np.array([x for x in coords1_triplets])

    coords2 = cjson2['atoms']['coords']['3d']
    coords2_triplets = zip(coords2[0::3], coords2[1::3], coords2[2::3])
    B = np.array([x for x in coords2_triplets])

    if heavy_atoms_only:
        atomic_numbers = cjson1['atoms']['elements']['number']
        heavy_indices = [i for i, n in enumerate(atomic_numbers) if n != 1]

        A = A.take(heavy_indices, 0)
        B = B.take(heavy_indices, 0)

    # Translate
    A -= rmsd.centroid(A)
    B -= rmsd.centroid(B)

    # Rotate
    U = rmsd.kabsch(A, B)
    A = np.dot(A, U)

    return rmsd.rmsd(A, B)
Esempio n. 13
0
def xyz4a_position(i, lines):
    template1 = np.array([[-0.93454, 0.91954, 1.11786],
                          [-0.01675, 0.03488, 0.58954],
                          [1.10621, 0.72253, -0.004],
                          [1.6148, 1.14817, -0.57075]])
    template2 = np.array([[-0.93454, 0.91954, 1.11786],
                          [-0.01675, 0.03488, 0.58954],
                          [1.10621, 0.72253, -0.004],
                          [1.6148, 1.14817, -0.57075],
                          [-0.64719, -0.82998, -0.40926],
                          [-1.12252, -1.99515, -0.72338]])
    amino_acid_position = []
    for k in range(i, i + 4, 1):
        try:
            x = lines[k][30:38]
            y = lines[k][38:46]
            z = lines[k][46:54]
            amino_acid_position.append(np.asarray([x, y, z], dtype=float))
        except:
            sys.exit(
                "Error parsing input for the following line: \n{0:s}".format(
                    lines[k]))
    amino_acid_position = np.asarray(amino_acid_position)
    #print amino_acid_position
    a_acid_p = amino_acid_position - rmsd.centroid(amino_acid_position)
    template1 -= rmsd.centroid(template1)
    #centroid P2 into f
    template2 = template2 - rmsd.centroid(template2)
    #for debug
    print '*************8888888888888888'
    #print template1.shape#(4,3)
    #print a_acid_p.shape#(5,3)
    #print template2.shape#(6.3)
    rot = rmsd.kabsch(template1, a_acid_p)
    #pp is the rotated martix,Rotate matrix P2 unto Q
    new_position = np.dot(template2, rot)
    #translation the P2 into initial position after rotation
    new_position += rmsd.centroid(amino_acid_position)
    C = new_position.tolist()
    #print new_position
    #print lenthg
    #for n in range(0,6,1):
    position5 = ('%8s' % str(float('%.3f' % C[4][0]))) + ('%8s' % str(
        float('%.3f' % C[4][1]))) + ('%8s' % str(float('%.3f' % C[4][2])))
    position6 = ('%8s' % str(float('%.3f' % C[5][0]))) + ('%8s' % str(
        float('%.3f' % C[5][1]))) + ('%8s' % str(float('%.3f' % C[5][2])))
    print 'print the position of position 5 and position 6'
    return position5, position6
Esempio n. 14
0
def getkabschangle(Ac, Bc):

    # Ac = Ac[:,0:3:2]
    # Bc = Bc[:,0:3:2]
    # Manipulate

    A = Ac - rmsd.centroid(Ac)
    B = Bc - rmsd.centroid(Bc)

    U = rmsd.kabsch(A, B)
    # print(U)

    degvals = (rotationMatrixToEulerAngles(U))

    return degvals[1]
    """
Esempio n. 15
0
def save_results(mol, results, filename):

    # make rdkit conformers

    energies = [x[4] for x in results]
    energies = np.array(energies)
    sortidx = np.argsort(energies)

    N_atoms = mol.GetNumAtoms()

    atoms = mol.GetAtoms()
    atoms = [atom.GetSymbol() for atom in atoms]

    coordinates_list = []

    no_hydrogen = np.array([2, 5, 6])
    no_hydrogen -= 1

    for idx in sortidx:
        result = results[idx]
        coord = result[-1]
        coord = np.array(coord)
        coord = coord.reshape((N_atoms, 3))

        coord -= rmsd.centroid(coord[no_hydrogen])

        coordinates_list.append(coord)

    out = []

    # atoms = np.array(atoms)
    # no_hydrogen = np.where(atoms != 'H')

    for i, coord in enumerate(coordinates_list[1:]):

        U = rmsd.kabsch(coord[no_hydrogen], coordinates_list[0][no_hydrogen])

        coord = np.dot(coord, U)

        strxyz = rmsd.set_coordinates(atoms, coord)
        out += [strxyz]

    f = open(filename, 'w')
    f.write("\n".join(out))
    f.close()

    return
Esempio n. 16
0
def calc_rmsd(coords1, coords2):
    """Calculate root-mean square deviation.

    Parameters
    ----------
    coords1 : list(list(str,int,int,int))
        The coordinates for the first
        molecule (conformer).
    coords2 : list(list(str,int,int,int))
        The coordinates for the second
        molecule (conformer).

    Notes
    -----
    The coordinates are given as follows:
    atom name, x coord, y coord, z coord
    Example for carbon monoxide:
    [[C, 0.0, 0.0, 0.0],[O, 1.0, 0.0, 0.0]]
    The distances are in Angstroms.

    Returns
    -------
    rmsd : float
        The rmsd between two molecular
        geometries. This rmsd is calculated
        after applying centering and a
        rotation matrix (calculated via
        the Kabsch algorithm).

    """
    # trivial check
    assert len(coords1) == len(coords2)
    # first turn lists into numpy arrays (otherwise
    # cannot perform some rmsd operations)
    # and excise atom names (not needed for rmsd)
    mol1 = np.array([[coords1[i][1], coords1[i][2], coords1[i][3]] for i in range(len(coords1))])
    mol2 = np.array([[coords2[i][1], coords2[i][2], coords2[i][3]] for i in range(len(coords2))])
    # first center each molecule
    mol1 -= rmsd.centroid(mol1)
    mol2 -= rmsd.centroid(mol2)
    # calculate the rotation matrix
    rot_matrix = rmsd.kabsch(mol1, mol2)
    # apply the rotation matrix
    mol1 = np.dot(mol1, rot_matrix)
    # finally get the rmsd
    return rmsd.rmsd(mol1, mol2)
Esempio n. 17
0
def align_coordinates(coordinates):

    # Align everything to first coordinate

    coordinates = copy.deepcopy(coordinates)

    coordinate_ref = coordinates[0]
    coordinate_ref -= rmsd.centroid(coordinate_ref)
    coordinates[0] = coordinate_ref

    for i, coordinate in enumerate(coordinates[1:]):

        coordinate -= rmsd.centroid(coordinate)
        U = rmsd.kabsch(coordinate, coordinate_ref)
        coordinate = np.dot(coordinate, U)
        coordinates[i] = coordinate

    return coordinates
def calculate_transformation_kabsch(
        src_points: np.ndarray,
        dst_points: np.ndarray) -> Tuple[np.array, float]:
    """
    Calculates the optimal rigid transformation from src_points to
    dst_points
    (regarding the least squares error)
    Parameters:
    -----------
    src_points: array
        (3,N) matrix
    dst_points: array
        (3,N) matrix

    Returns:
    -----------
    rotation_matrix: array
        (3,3) matrix

    translation_vector: array
        (3,1) matrix
    rmsd_value: float
    """
    assert src_points.shape == dst_points.shape
    if src_points.shape[0] != 3:
        raise Exception(
            "The input data matrix had to be transposed in order to compute transformation."
        )

    src_points = src_points.transpose()
    dst_points = dst_points.transpose()

    src_points_centered = src_points - rmsd.centroid(src_points)
    dst_points_centered = dst_points - rmsd.centroid(dst_points)

    rotation_matrix = rmsd.kabsch(src_points_centered, dst_points_centered)
    rmsd_value = rmsd.kabsch_rmsd(src_points_centered, dst_points_centered)

    translation_vector = rmsd.centroid(dst_points) - np.matmul(
        rmsd.centroid(src_points), rotation_matrix)

    return create_homogenous(rotation_matrix.transpose(),
                             translation_vector.transpose()), rmsd_value
Esempio n. 19
0
def find_rotation_matrix(ax, ay, az, imu_ax, imu_ay, imu_az):
    print("Finding rotation matrix...")
    rx = 0
    ry = 0
    rz = 0

    diff_a = []
    imu_a = []

    # Kabsch algorithm setup
    for i in range(np.minimum(len(ax), len(imu_ax))):
        diff_a.append([ax[i] / 9.81, ay[i] / 9.81, az[i] / 9.81])
    for i in range(np.minimum(len(ax), len(imu_ax))):
        imu_a.append([imu_ax[i], imu_ay[i], imu_az[i]])

    diff_a = np.array(diff_a)
    imu_a = np.array(imu_a)

    print("Rotation matrix: ", rmsd.kabsch(diff_a, imu_a))
    print("RMSD: ", rmsd.kabsch_rmsd(diff_a, imu_a))
    # diff_a -= rmsd.centroid(diff_a)
    # imu_a -= rmsd.centroid(imu_a)
    # print("Rotation matrix after translation: ", rmsd.kabsch(diff_a, imu_a))
    # print("RMSD after translation: ", rmsd.kabsch_rmsd(diff_a, imu_a))

    rotated_a = rmsd.kabsch_rotate(diff_a, imu_a)
    r_ax = []
    r_ay = []
    r_az = []
    for i in range(len(rotated_a)):
        r_ax.append(rotated_a[i][0])
        r_ay.append(rotated_a[i][1])
        r_az.append(rotated_a[i][2])

    x_axis = np.array(range(len(r_ax)))
    plt.figure(5)
    plt.title("Rotated Differentiated Acceleration")
    plt.plot(x_axis, r_ax, label='x', color='red')
    plt.plot(x_axis, r_ay, label='y', color='green')
    plt.plot(x_axis, r_az, label='z', color='blue')
    plt.legend()
Esempio n. 20
0
def normalize_pts_old(pts1, pts2, win):
    #print pts1
    A = pts1[:, 0:2]
    B = pts2[:, 0:2]

    assert len(A) == len(B)

    N = A.shape[0]  # total points

    # find centroids
    centroid_A = rmsd.centroid(A)
    centroid_B = rmsd.centroid(B)

    # centre the points
    AA = A - centroid_A
    BB = B - centroid_B
    
    #get optimal rotation matrix
    R = rmsd.kabsch(AA, BB)
    # Apply transformation
    AA1 = np.dot(AA, R)
    angle1 = math.atan2(R[1][0], R[1][1])
    
    i=0
    for pt in pts1:
        pt_graphics = Point(int(pt[0]-centroid_A[0]+centroid_B[0]), int(pt[1]-centroid_A[1]+centroid_B[1]))
        cir = Circle(pt_graphics, 8)
        cir.setOutline('green')
        cir.draw(win)
        line = Line(pt_graphics, Point(pt_graphics.x+8*np.cos(-pt[2]), pt_graphics.y+8*np.sin(-pt[2])))
        line.draw(win)
        text = Text(pt_graphics, str(i))
        i += 1
        text.draw(win)
    
    pts1[:, 0:2] = AA1 + centroid_B
    # rotate the rotations
    pts1[:, 2] -= angle1
    return rmsd.rmsd(AA1, BB)
Esempio n. 21
0
    def calc_rmsd(self):
        """
        Calculate normal, translated, and rotated RMSD.

        """
        tmp_1, tmp_2 = self.coord_1.copy(), self.coord_2.copy()

        self.rmsd_normal = rmsd.rmsd(self.coord_1, self.coord_2)

        # Manipulate recenter
        self.coord_1 -= rmsd.centroid(self.coord_1)
        self.coord_2 -= rmsd.centroid(self.coord_2)

        self.rmsd_translate = rmsd.rmsd(self.coord_1, self.coord_2)

        # Rotate
        rotation_matrix = rmsd.kabsch(self.coord_1, self.coord_2)
        self.coord_1 = np.dot(self.coord_1, rotation_matrix)

        self.rmsd_rotate = rmsd.rmsd(self.coord_1, self.coord_2)

        self.coord_1, self.coord_2 = tmp_1, tmp_2
Esempio n. 22
0
def kabschangleVisual(A, B):
    # Manipulate
    #A = A[:, 0:3:2]
    #B = B[:, 0:3:2]
    print(A)
    print(B)
    print("RMSD", geterror(A, B))

    save_plot(A, B, "plot_beginning")
    A -= rmsd.centroid(A)
    B -= rmsd.centroid(B)

    print("Translated RMSD", geterror(A, B))
    save_plot(A, B, "plot_translated")

    U = rmsd.kabsch(A, B)
    print("Rotation Matrix")
    print(U)
    print("Angle")

    #val = math.acos(U[0][0])
    #print(U[0][0])
    #if(abs(val) <=1):
    #    deg = math.acos(U[0][0]) / 3.14 * 180
    #else:
    #    print("OIII GOT ERROR SIAL")
    #    deg = 0
    degvals = (rotationMatrixToEulerAngles(U))
    print("The degree")
    print(degvals[1])
    #print(deg)

    #A = np.dot(A, U)

    print("Rotated RMSD", geterror(A, B))
    save_plot(A, B, "plot_rotated")
Esempio n. 23
0
def align_structures(structures: np.array, indexes=None):
    '''
    Aligns molecules of a structure array (shape is (n_structures, n_atoms, 3))
    to the first one, based on the indexes. If not provided, all atoms are used
    to get the best alignment. Return is the aligned array.

    '''

    reference = structures[0]
    targets = structures[1:]
    if isinstance(indexes, (list, tuple)):
        indexes = np.array(indexes)

    indexes = slice(0, len(reference)) if indexes is None or len(
        indexes) == 0 else indexes.ravel()

    reference -= np.mean(reference[indexes], axis=0)
    for t, _ in enumerate(targets):
        targets[t] -= np.mean(targets[t, indexes], axis=0)

    output = np.zeros(structures.shape)
    output[0] = reference

    for t, target in enumerate(targets):

        try:
            matrix = kabsch(reference[indexes], target[indexes])

        except LinAlgError:
            # it is actually possible for the kabsch alg not to converge
            matrix = np.eye(3)

        # output[t+1] = np.array([matrix @ vector for vector in target])
        output[t + 1] = (matrix @ target.T).T

    return output
Esempio n. 24
0
    commonData[i] -= centroidPos
    centroidData.append(centroidPos)

# calculate pairwise deviation and rotate
deviations = np.empty((numOfLoci, 0), float)
for i in range(numOfStructures):
    for j in range(numOfStructures):
        if j == i:
            continue
        # mirror image if needed
        mirrorFactor = 1.0
        if rmsd.kabsch_rmsd(commonData[i], commonData[j]) > rmsd.kabsch_rmsd(
                commonData[i], -1.0 * commonData[j]):
            mirrorFactor = -1.0
        # calculate deviation
        rotationMatrix = rmsd.kabsch(mirrorFactor * commonData[j],
                                     commonData[i])
        if j > i:
            deviation = np.linalg.norm(
                np.dot(mirrorFactor * commonData[j], rotationMatrix) -
                commonData[i],
                axis=1).T
            deviations = np.c_[deviations, deviation]
            sys.stderr.write('median deviation between ' + str(i) + ' and ' +
                             str(j) + ': ' + str(np.median(deviation)) + '\n')
        # rotate j to align with i
        sys.stderr.write('aligning ' + str(j) + ' to ' + str(i) + '\n')
        alignedFilename = "aligned_" + str(j) + "_to_" + str(i) + ".3dg"
        alignedFile = open(alignedFilename, "wb")
        for inputLocus in inputData[j]:
            #sys.stderr.write("locus: "+str(inputLocus)+"\n")
            #sys.stderr.write("old: "+str(np.array(inputData[j][inputLocus]))+"\n")
#B = np.append(B, extra, axis = 0)
B += random.uniform(-10, 10)
#np.random.shuffle(B)
#A, B = generate_set(A, B)
plot3d(A, B)
print("Normal RMSD", rmsd.rmsd(A, B))

# Manipulate
A -= rmsd.centroid(A)
B -= rmsd.centroid(B)
plot3d(A, B)
print("Translated RMSD", rmsd.rmsd(A, B))

markA = A[0:3, :]
markB = B[0:3, :]
U = rmsd.kabsch(markA, markB)
A = np.dot(A, U)

plot3d(A, B)
print("Rotated RMSD", rmsd.rmsd(A, B))

#data projection
d = 12
unit = 0.01
maxindex = int(d / unit)
Aindex = np.floor(A / unit)
Bindex = np.floor(B / unit)
Aindex -= np.min(Aindex)
Bindex -= np.min(Bindex)
Axy = Aindex[:, 0:2]
Bxy = Bindex[:, 0:2]
Esempio n. 26
0
def get_angle(vecs1, vecs2):
    """Returns rotation angle between two vector sets, representing inverse lattices"""

    # https://en.wikipedia.org/wiki/Rotation_matrix#Determining_the_angle
    return np.rad2deg(np.arccos((np.trace(rmsd.kabsch(vecs1, vecs2)) - 1) / 2))
Esempio n. 27
0
              [2.0, 1.5]])

# Same "molecule"
B = np.array([[1.0, 1.0],
              [1.0, 2.0],
              [2.0, 1.5]])

B *= 1.4

# Translate
B -= 3

# Rotate
B = np.dot(B, rotation_matrix(90))

print("Normal RMSD", rmsd.rmsd(A, B))
save_plot(A, B, "plot_beginning.png")

# Manipulate
A -= rmsd.centroid(A)
B -= rmsd.centroid(B)

print("Centered RMSD", rmsd.rmsd(A, B))
save_plot(A, B, "plot_centered.png")

U = rmsd.kabsch(A, B)
A = np.dot(A, U)

print("Translated RMSD", rmsd.rmsd(A, B))
save_plot(A, B, "plot_translated.png")
Esempio n. 28
0
def calculate_head_COM(file, output_folder):
    f_cam = 1000
    n_tags = 23
    no_subj = 1
    pose_all = np.empty((no_subj), dtype=object)
    mesh_all = np.empty((no_subj), dtype=object)
    suct = 0

    print('Calculating center of mass on file', file)
    for i in np.array([1]):  # files in os.listdir(path_loc):
        file_path = file
        f = open(file_path)
        csv_f = csv.reader(f, delimiter='\t')

        new_frame = np.empty((23, 7, 1))
        new_frame[:] = np.NAN
        full_array = new_frame.copy()
        count = -1
        for row in csv_f:
            row = row[1:]
            if (count == -1):
                count = count+1
            elif (row[1] == str(NULL_MARKER)):
                full_array = np.append(full_array, new_frame, axis=2)
                count = count+1
            else:
                if (int(row[0]) < 23):
                    read_array = np.asarray(row[2:]).astype(np.float)
                    quart = Quaternion(matrix=rf.eul2mat(read_array[4:]))
                    full_array[int(row[0]), :, count] = np.concatenate(
                        (np.array([-read_array[2], read_array[3], -read_array[1]]), quart.elements), axis=0)
        full_array = full_array[:, :, :-1]
        f.close()

        pose_all[suct] = full_array
        suct += 1
        final_ori = np.zeros((full_array.shape[2], full_array.shape[1]))
        cur_fullmesh = np.empty((n_tags*4, 3, full_array.shape[2]))
        cur_fullmesh[:] = np.NaN
        mesh_visible = np.empty((n_tags*4, 3, full_array.shape[2]))
        mesh_visible[:] = np.NaN

        vismesh_px = np.empty((n_tags*4, 2, full_array.shape[2]))
        vismesh_px[:] = np.NaN

        fullmesh_px = np.empty((n_tags*4, 2, full_array.shape[2]))
        fullmesh_px[:] = np.NaN
        err_dist = np.zeros((full_array.shape[2], 1))

        avg_mesh = np.load("./visualize_2/mesh_calib.npy")

        for f_ct in range(0, full_array.shape[2]):
            cur_mesh = np.empty((n_tags*4, 3))
            cur_mesh[:] = np.NaN
            for tag_ct in range(0, n_tags):
                cur_mesh[tag_ct*4:(tag_ct+1)*4, :] = rf.orient_square(
                    full_array[tag_ct, 0:3, f_ct], Quaternion(full_array[tag_ct, 3:, f_ct]))
            while True:
                mesh1 = avg_mesh[(~np.isnan(cur_mesh[:, 1])), :]
                mesh2 = cur_mesh[(~np.isnan(cur_mesh[:, 1])), :]
                m1c = rmsd.centroid(mesh1)
                m2c = rmsd.centroid(mesh2)
                mesh1 -= m1c
                mesh2 -= m2c
                rot2_1 = rmsd.kabsch(mesh1, mesh2)
                cur_fullmesh[:, :, f_ct] = np.dot(avg_mesh - m1c, rot2_1) + m2c
        #        if f_ct >= 2:
        #            cur_fullmesh[:,:,f_ct] = np.nansum((0.5*cur_fullmesh[:,:,f_ct],0.3*cur_fullmesh[:,:,f_ct-1],0.2*cur_fullmesh[:,:,f_ct-2]),axis = 0)
                err = np.linalg.norm(
                    cur_fullmesh[:, :, f_ct] - cur_mesh, axis=1)
                if mesh1.shape[0] == 0:
                    break
                if np.partition(err, 3)[3] > 0.005:
                    break
                elif (np.nanmean(err) < 0.005):
                    break
                cur_mesh[np.nanargmax(err), :] = np.array(
                    [np.nan, np.nan, np.nan])
            final_ori[f_ct, 0:3] = rmsd.centroid(cur_fullmesh[:, :, f_ct])
            final_ori[f_ct, 3:] = Quaternion(matrix=rot2_1).elements

    #        mesh_visible[(~np.isnan(cur_mesh[:,1])),:] = cur_fullmesh[(~np.isnan(cur_mesh[:,1])),:]
            vismesh_px[:, 0, f_ct] = 960 - \
                (cur_mesh[:, 0]/cur_mesh[:, 2]*f_cam)
            vismesh_px[:, 1, f_ct] = 540 + \
                (cur_mesh[:, 1]/cur_mesh[:, 2]*f_cam)
            fullmesh_px[:, 0, f_ct] = 960 - \
                (cur_fullmesh[:, 0, f_ct]/cur_fullmesh[:, 2, f_ct]*f_cam)
            fullmesh_px[:, 1, f_ct] = 540 + \
                (cur_fullmesh[:, 1, f_ct]/cur_fullmesh[:, 2, f_ct]*f_cam)
            err_dist[f_ct] = np.nanmean(np.linalg.norm(
                cur_fullmesh[:, :, f_ct] - cur_mesh, axis=1))
            if np.size(mesh2, axis=0) <= 12:
                err_dist[f_ct] = 1
            loc = rmsd.centroid(cur_fullmesh)
        #pose_all[suct] = final_ori
        #mesh_all[suct] = fullmesh_px
        suct = suct+1
        print(suct)

    axis_px = np.empty((4, 2, full_array.shape[2]))
    axis_px[:] = np.NaN
    for ct in range(0, full_array.shape[2]):
        rot_mat = Quaternion(np.array(
            [final_ori[ct, 3], final_ori[ct, 4], final_ori[ct, 5], final_ori[ct, 6]])).rotation_matrix/25
        ax = np.c_[rot_mat, final_ori[ct, 0:3]]
        ax_ad = ax.copy()
        for row in range(3):
            ax_ad[:, row] = ax[:, row] + final_ori[ct, 0:3]
            axis_px[:, 0, ct] = 960 - (ax_ad[0, :]/ax_ad[2, :]*f_cam)
            axis_px[:, 1, ct] = 540 + (ax_ad[1, :]/ax_ad[2, :]*f_cam)

    axis_px1 = np.empty((4, 2, full_array.shape[2]))
    axis_px1[:] = np.NaN
    for ct in range(0, full_array.shape[2]):
        rot_mat = Quaternion(np.array(
            [final_ori[ct, 6], final_ori[ct, 5], final_ori[ct, 4], final_ori[ct, 3]])).rotation_matrix/25
        ax = np.c_[rot_mat, final_ori[ct, 0:3]]
        ax_ad = ax.copy()
        for row in range(3):
            ax_ad[:, row] = ax[:, row] + final_ori[ct, 0:3]
            axis_px1[:, 0, ct] = 960 - (ax_ad[0, :]/ax_ad[2, :]*f_cam)
            axis_px1[:, 1, ct] = 540 + (ax_ad[1, :]/ax_ad[2, :]*f_cam)

    # sio.savemat('meshsave_back_2.mat',{'vismesh_px':vismesh_px,'mesh_all':fullmesh_px,'pose_all':pose_all[1],'axis_px':axis_px,'axis_px1':axis_px1})
    sio.savemat('meshsave_back_2.mat', {'vismesh_px': vismesh_px, 'mesh_all': fullmesh_px,
                                        'pose_all': final_ori, 'axis_px': axis_px, 'axis_px1': axis_px1})
Esempio n. 29
0
def align(argv):
    # default parameters
    output_prefix = None

    # read arguments
    try:
        opts, args = getopt.getopt(argv[1:], "o:")
    except getopt.GetoptError as err:
        sys.stderr.write("[E::" + __name__ + "] unknown command\n")
        return 1
    if len(args) == 0:
        sys.stderr.write(
            "Usage: dip-c align [options] <in1.3dg> <in2.3dg> ...\n")
        sys.stderr.write("Options:\n")
        sys.stderr.write("  -o STR        output prefix [no output]\n")
        sys.stderr.write("Output:\n")
        sys.stderr.write("  tab-delimited: homolog, locus, RMSD\n")
        sys.stderr.write(
            "  additionally with \"-o\": 3DG files aligned to each other\n")

        return 1
    for o, a in opts:
        if o == "-o":
            output_prefix = a

    # load 3dg files
    input_data = []
    num_structures = len(args)
    if num_structures < 2:
        sys.stderr.write("[E::" + __name__ +
                         "] at least 2 structures are required\n")
        return 1
    counter = 0
    for input_filename in args:
        sys.stderr.write("[M::" + __name__ + "] reading 3dg file " +
                         str(counter) + ": " + input_filename + "\n")
        input_data.append({})
        for input_file_line in open(input_filename, "rb"):
            input_file_line_data = input_file_line.strip().split()
            input_data[-1][(input_file_line_data[0],
                            int(input_file_line_data[1]))] = [
                                float(input_file_line_data[2]),
                                float(input_file_line_data[3]),
                                float(input_file_line_data[4])
                            ]
        counter += 1

    # find common particles
    common_loci = set(input_data[0])
    for input_structure in input_data[1:]:
        common_loci = common_loci.intersection(set(input_structure))
    num_loci = len(common_loci)
    common_loci = list(common_loci)
    common_data = []
    for input_structure in input_data:
        common_data.append([])
        for common_locus in common_loci:
            common_data[-1].append(input_structure[common_locus])
    sys.stderr.write("[M::" + __name__ + "] found " + str(num_loci) +
                     " common particles\n")

    # subtract centroid
    common_data = np.array(common_data)
    centroid_data = []
    for i in range(num_structures):
        common_data[i] = np.array(common_data[i])
        centroid_pos = rmsd.centroid(common_data[i])
        common_data[i] -= centroid_pos
        centroid_data.append(centroid_pos)
    sys.stderr.write("[M::" + __name__ + "] found centroids for " +
                     str(num_structures) + " structures\n")

    # calculate pairwise deviation and rotate
    deviations = np.empty((num_loci, 0), float)
    for i in range(num_structures):
        for j in range(num_structures):
            if j == i:
                continue
            # mirror image if needed
            mirror_factor = 1.0
            if rmsd.kabsch_rmsd(common_data[i],
                                common_data[j]) > rmsd.kabsch_rmsd(
                                    common_data[i], -1.0 * common_data[j]):
                mirror_factor = -1.0
            # calculate deviation
            rotation_matrix = rmsd.kabsch(mirror_factor * common_data[j],
                                          common_data[i])
            if j > i:
                deviation = np.linalg.norm(
                    np.dot(mirror_factor * common_data[j], rotation_matrix) -
                    common_data[i],
                    axis=1).T
                deviations = np.c_[deviations, deviation]
                sys.stderr.write("[M::" + __name__ +
                                 "] median deviation between file " + str(i) +
                                 " and file " + str(j) + ": " +
                                 str(np.median(deviation)) + "\n")

            # rotate
            if output_prefix is not None:
                # rotate j to align with i
                sys.stderr.write("[M::" + __name__ + "] aligning file " +
                                 str(j) + " to file " + str(i) + "\n")
                aligned_filename = output_prefix + str(j) + "_to_" + str(
                    i) + ".3dg"
                aligned_file = open(aligned_filename, "wb")
                for input_locus in input_data[j]:
                    aligned_pos = np.dot(
                        (np.array(input_data[j][input_locus]) -
                         centroid_data[j]) * mirror_factor,
                        rotation_matrix) + centroid_data[i]
                    aligned_file.write("\t".join([
                        input_locus[0],
                        str(input_locus[1]),
                        str(aligned_pos[0]),
                        str(aligned_pos[1]),
                        str(aligned_pos[2])
                    ]) + "\n")
                aligned_file.close()

    # summarize rmsd and print
    rmsds = np.sqrt((deviations**2).mean(axis=1))
    totalrmsd = np.sqrt((rmsds**2).mean(axis=0))
    sys.stderr.write("[M::" + __name__ + "] RMS RMSD: " + str(totalrmsd) +
                     "\n")
    sys.stderr.write("[M::" + __name__ + "] median RMSD: " +
                     str(np.median(rmsds, axis=0)) + "\n")
    sys.stderr.write("[M::" + __name__ + "] writing output\n")
    for i in range(num_loci):
        sys.stdout.write("\t".join(
            map(str, [common_loci[i][0], common_loci[i][1], rmsds[i]])) + "\n")

    return 0
    def run(self, r1: SetOfResidues, r2: SetOfResidues,
            get_centered_c_alpha_coords: GetCenteredCAlphaCoords):
        P, Q = map(get_centered_c_alpha_coords, (r1, r2))

        return rmsd.kabsch(P, Q)
    def run(self, s1d1: SetOfResidues, s1d2: SetOfResidues,
            s2d1: SetOfResidues, s2d2: SetOfResidues,
            get_c_alpha_coords: GetCAlphaCoords, get_centroid: GetCentroid,
            get_rotation_matrix: GetRotationMatrix) -> (float, float):
        """ :param s1d1: a domain in the first structure
        :param s1d2: another domain in the first structure
        :param s2d1: a domain in the second structure corresponding to s1d1 domain (same length required)
        :param s2d2: a domain in the second structure corresponding to s1d2 domain (same length required)
        :return: tuple of angle (non-negative -- absolute value) and translation (again non-negative).
        Angle (movement of a domain between the structures) and translation -> in the direction of the rotation axis
        """

        # superimpose s2d1 on s1d1 (correspoding domains, 1st domain chosen arbitrarily), taking s2d2 along with it
        # -> translate and rotate

        # superimpose the moved s2d2 on s1d2, remember translation+rotation. Decompose translation+rotation into rotation along a single
        # axis somewhere in space + translation along that axis. (screw motion).

        # axis direction: 1 eigenvector of rot. matrix. Translation along that axis: subtract from translation it's projection
        # to screw axis _|_ space (P_s_|_).
        # [ In case we would need the location of the screw axis: the projection P_s_|_ is the length of
        # the chord line (how the centroid rotated along the positioned screw axis). I know the rot. angle, so the location of screw axis is
        # at two possible positions, above and below the chord line, however the angle sign should solve this
        # r = chord/(2 * sin(angle/2)), compute triangle height <r,chord,r> and multiply by that a unit vector perpendiculat to the chord,
        # and in the rotation plane. This will be the candidate (one of two, see the angle sign) for the screw axis location.
        # (A point lying on the axis). ]

        # superimpose the two structures by their first domain
        U = get_rotation_matrix(s2d1, s1d1)

        s1d2_coords = get_c_alpha_coords(s1d2)
        fixed_s2d2_coords = np.matmul(
            get_c_alpha_coords(s2d2) - get_centroid(s2d1),
            U) + get_centroid(s1d1)

        # compare d2 coords
        fixed_s2d2_coords_centroid = fixed_s2d2_coords.mean(axis=0)

        d2_rotation_m = rmsd.kabsch(
            fixed_s2d2_coords - fixed_s2d2_coords_centroid,
            s1d2_coords - get_centroid(s1d2))
        d2_translation = get_centroid(s1d2) - fixed_s2d2_coords_centroid

        # calculate return values
        angle = np.arccos((np.trace(d2_rotation_m) - 1) /
                          2)  # formula tr(Rot_matrix) = 1 + 2cos(angle)

        rotation_axis_plane = d2_rotation_m - np.eye(
            3
        )  # rotation axis is the normal of that plane, row/col vectors generate the plane
        axis = np.cross(
            rotation_axis_plane[:, 0],
            rotation_axis_plane[:, 1])  # a vector in the direction of the axis
        # (result of cross product is perpendicular to both vectors, these are in rotation_axis_plane) https://math.stackexchange.com/q/2074316/331963
        axis = axis / np.linalg.norm(axis)  # make it a unit vector

        # translation projected into the rotation axis (get the translation component of a screw motion)
        translation_in_axis = np.dot(d2_translation, axis)

        # it could also be possible to calculate here the location of rotation axis --> so we would have the complete screw description
        # of the domain movement, see [ ] above

        return ScrewMotionResult(abs(angle), abs(translation_in_axis),
                                 float(np.linalg.norm(d2_translation)))