def get_pdb_transform(pdb, center_res, top_res): """ Returns a transformation matrix that centers pdb to center_res on the z-axis and moves top_res above center_res on the y-axis """ soup = pdbatoms.Soup(pdb) atoms = soup.atoms() soup_center = pdbatoms.get_center(atoms) translation = v3.translation(-soup_center) soup.transform(translation) result = translation center_atom = find_ca_of_resname(soup.atoms(), center_res) view = v3.vector(0, 0, 1) axis = v3.cross(view, center_atom.pos) angle = v3.vec_dihedral(view, axis, center_atom.pos) rotation = v3.rotation(axis, angle) soup.transform(rotation) result = v3.combine(rotation, result) top_atom = find_ca_of_resname(soup.atoms(), top_res) top_dir = v3.vector(0, 1, 0) axis = view.copy() angle = v3.vec_dihedral(top_dir, axis, top_atom.pos) rotation2 = v3.rotation(axis, angle) result = v3.combine(rotation2, result) del soup return result
def rmsd_of_soups(soup1, soup2, segments1=[], segments2=[], atom_types=['CA'], transform_pdb1=None): """ Returns the RMSD between two PDB structures and optionally writes the best transformed structure of pdb1 in transform_pdb. By default, it chooses the CA atoms in the soup. Args: segments1 (list): list of pairs of residue names in pdb1, such as ['A:1','A:3'], interpreted as the two ends of a fragment in soup that we want the atom index of segments2 (list): same as above but for pdb2 atom_types (list): list of atom_types in the residues that we want to generate the indices from. """ atoms1 = get_superposable_atoms(soup1, segments1, atom_types) atoms2 = get_superposable_atoms(soup2, segments2, atom_types) crds1 = [a.pos for a in atoms1] crds2 = [a.pos for a in atoms2] center1 = v3.get_center(crds1) center2 = v3.get_center(crds2) soup1.transform(v3.translation(-center1)) soup2.transform(v3.translation(-center2)) rmsd, transform_1_to_2 = calc_rmsd_rot(crds1, crds2) if not transform_pdb1: return rmsd soup1.transform(transform_1_to_2) soup1.transform(v3.translation(center2)) soup2.transform(v3.translation(center2)) soup1.write_pdb(transform_pdb1) return sum_rmsd(crds1, crds2)
def rmsd_of_soups( soup1, soup2, segments1=[], segments2=[], atom_types=['CA'], transform_pdb1=None): """ Returns the RMSD between two PDB structures and optionally writes the best transformed structure of pdb1 in transform_pdb. By default, it chooses the CA atoms in the soup. Args: segments1 (list): list of pairs of residue names in pdb1, such as ['A:1','A:3'], interpreted as the two ends of a fragment in soup that we want the atom index of segments2 (list): same as above but for pdb2 atom_types (list): list of atom_types in the residues that we want to generate the indices from. """ atoms1 = get_superposable_atoms(soup1, segments1, atom_types) atoms2 = get_superposable_atoms(soup2, segments2, atom_types) crds1 = [a.pos for a in atoms1] crds2 = [a.pos for a in atoms2] center1 = v3.get_center(crds1) center2 = v3.get_center(crds2) soup1.transform(v3.translation(-center1)) soup2.transform(v3.translation(-center2)) rmsd, transform_1_to_2 = calc_rmsd_rot(crds1, crds2) if not transform_pdb1: return rmsd soup1.transform(transform_1_to_2) soup1.transform(v3.translation(center2)) soup2.transform(v3.translation(center2)) soup1.write_pdb(transform_pdb1) return sum_rmsd(crds1, crds2)