Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
structural_alignment.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # :noTabs=true:
3 
4 
5 # (c) Copyright Rosetta Commons Member Institutions.
6 # (c) This file is part of the Rosetta software suite and is made available under license.
7 # (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
8 # (c) For more information, see http://www.rosettacommons.org. Questions about this can be
9 # (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
10 
11 ## @file structural_alignment.py
12 ## @brief
13 ## @author Evan H. Baugh, Johns Hopkins University
14 
15 ##############################################################################
16 #
17 # @SUMMARY: -- QKabsch.py. A python implementation of the optimal superposition
18 # of two sets of vectors as proposed by Kabsch 1976 & 1978.
19 #
20 # @AUTHOR: Jason Vertrees
21 # @COPYRIGHT: Jason Vertrees (C), 2005-2007
22 # @LICENSE: Released under GPL:
23 # This program is free software; you can redistribute it and/or modify
24 # it under the terms of the GNU General Public License as published by
25 # the Free Software Foundation; either version 2 of the License, or
26 # (at your option) any later version.
27 # This program is distributed in the hope that it will be useful, but WITHOUT
28 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
29 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
30 #
31 # You should have received a copy of the GNU General Public License along with
32 # this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
33 # Street, Fifth Floor, Boston, MA 02110-1301, USA
34 #
35 # DATE : 2007-01-01
36 # REV : 2
37 # REQUIREMENTS: numpy
38 #
39 #############################################################################
40 # script modified by Evan H. Baugh for usage with PyRosetta
41 #
42 # DATA : 2011-06-20
43 # REV : 1
44 # REQUIREMENTS: numpy, PyRosetta
45 
46 # using numpy for linear algebra
47 import numpy
48 
49 from rosetta import Pose
50 from rosetta.numeric import xyzVector
51 
52 # other tools
53 from extract_coords_pose import extract_coordinates_from_pose_1x3
54 
55 def kabsch_alignment( pose1, pose2 , pose1sel = [], pose2sel =[] ):
56  """
57  optAlign performs the Kabsch alignment algorithm upon the alpha-carbons of two selections.
58 
59  By default, this program will optimally align the ALPHA CARBONS of the selections provided.
60  To turn off this feature remove the lines between the commented "REMOVE ALPHA CARBONS" below.
61 
62  This is a hacky modification for usage in PyRosetta,
63  The geometry/math is the same but it uses poses instead of PyMOL
64 
65  @param pose1: First pose
66  @param pose2: Second pose
67  @param pose1sel: List of residues to align in the first pose
68  @param pose2sel: List of residues to align in the second pose
69  """
70 
71  # default to all the residues
72  if not pose1sel:
73  pose1sel = range(1,pose1.total_residue()+1)
74  if not pose2sel:
75  pose2sel = range(1,pose2.total_residue()+1)
76 
77  # obtain a list of the atom positions to align
78  stsel1 = extract_coordinates_from_pose_1x3(pose1,pose1sel,['CA'])
79  stsel2 = extract_coordinates_from_pose_1x3(pose2,pose2sel,['CA'])
80  """
81  stsel1 = []
82  for r in pose1sel:
83  v = pose1.residue(r).atom('CA').xyz()
84  stsel1.append([v[0],v[1],v[2]])
85  stsel2 = []
86  for r in pose2sel:
87  v = pose2.residue(r).atom('CA').xyz()
88  stsel2.append([v[0],v[1],v[2]])
89  """
90  # remember all of each pose's atom positions, to apply transformation
91  # later for updating
92  molsel1 = extract_coordinates_from_pose_1x3(pose1)
93  molsel2 = extract_coordinates_from_pose_1x3(pose2)
94  """
95  molsel1 = []
96  for r in range(pose1.total_residue()):
97  r = pose1.residue(r+1)
98  for a in range(r.natoms()):
99  v = r.xyz(a+1)
100  molsel1.append([v[0],v[1],v[2]])
101  molsel2 = []
102  for r in range(pose2.total_residue()):
103  r = pose2.residue(r+1)
104  for a in range(r.natoms()):
105  v = r.xyz(a+1)
106  molsel2.append([v[0],v[1],v[2]])
107  """
108 
109  # check for consistency, same number of selected residues
110  assert len(stsel1) == len(stsel2)
111  L = len(stsel1)
112  assert L > 0
113 
114  # must alway center the two proteins to avoid affine transformations
115  # Center the two proteins to their selections
116  COM1 = numpy.sum(stsel1,axis=0) / float(L)
117  COM2 = numpy.sum(stsel2,axis=0) / float(L)
118  stsel1 -= COM1
119  stsel2 -= COM2
120 
121  # Initial residual, see Kabsch.
122  E0 = numpy.sum( numpy.sum(stsel1 * stsel1,axis=0),axis=0) + numpy.sum( numpy.sum(stsel2 * stsel2,axis=0),axis=0)
123 
124  # This beautiful step provides the answer. V and Wt are the orthonormal
125  # bases that when multiplied by each other give us the rotation matrix, U.
126  # S, (Sigma, from SVD) provides us with the error! Isn't SVD great!
127  V, S, Wt = numpy.linalg.svd( numpy.dot( numpy.transpose(stsel2), stsel1))
128 
129  # we already have our solution, in the results from SVD.
130  # we just need to check for reflections and then produce
131  # the rotation. V and Wt are orthonormal, so their det's
132  # are +/-1.
133  reflect = float(str(float(numpy.linalg.det(V) * numpy.linalg.det(Wt))))
134 
135  if reflect == -1.0:
136  S[-1] = -S[-1]
137  V[:,-1] = -V[:,-1]
138 
139  RMSD = E0 - (2.0 * sum(S))
140  RMSD = numpy.sqrt(abs(RMSD / L))
141 
142  #U is simply V*Wt
143  U = numpy.dot(V, Wt)
144 
145  # rotate and translate the molecule
146  stsel2 = numpy.dot((molsel2 - COM2), U)
147  stsel2 = stsel2.tolist()
148  # center the molecule
149  stsel1 = molsel1 - COM1
150  stsel1 = stsel1.tolist()
151 
152  # apply the changes to both poses
153  # first pose
154  ind = -1
155  #dummy = rosetta.numeric.xyzVector()
156  dummy = xyzVector()
157  for r in range(pose1.total_residue()):
158  res = pose1.residue(r+1)
159  for a in range(res.natoms()):
160  ind += 1
161  v = stsel1[ind]
162  dummy.x = v[0]
163  dummy.y = v[1]
164  dummy.z = v[2]
165  pose1.residue(r+1).set_xyz(a+1,dummy)
166  # second pose
167  ind = -1
168  for r in range(pose2.total_residue()):
169  res = pose2.residue(r+1)
170  for a in range(res.natoms()):
171  ind += 1
172  v = stsel2[ind]
173  dummy.x = v[0]
174  dummy.y = v[1]
175  dummy.z = v[2]
176  pose2.residue(r+1).set_xyz(a+1,dummy)
177 
178  print 'RMSD=%f' % RMSD
179 
180 
Fstring::size_type len(Fstring const &s)
Length.
Definition: Fstring.hh:2207
Real sum(ddGs &scores_to_sum)
T abs(T const &x)
std::abs( x ) == | x |
Definition: Fmath.hh:295