Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DisulfideMatchingPotential.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 sw=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file core/scoring/disulfides/CentroidDisulfidePotential.cc
11 /// @brief Centroid Disulfide Energy Potentials
12 /// @author rvernon@u.washington.edu
13 /// @date 02/09/10
14 
15 // Unit Headers
18 
19 // Project Headers
22 // AUTO-REMOVED #include <core/chemical/ResidueTypeSet.hh>
23 // AUTO-REMOVED #include <core/chemical/ChemicalManager.hh>
24 // AUTO-REMOVED #include <basic/database/open.hh>
25 // AUTO-REMOVED #include <core/scoring/constraints/util.hh>
27 #include <core/kinematics/RT.hh>
28 #include <core/pose/Pose.hh>
29 
30 // Utility Headers
31 // AUTO-REMOVED #include <utility/io/izstream.hh>
32 #include <utility/vector1.hh>
34 
35 #include <basic/Tracer.hh>
36 
37 //Auto Headers
40 
41 //Auto Headers
42 #include <numeric/xyz.functions.hh>
43 #include <ObjexxFCL/FArray2A.hh>
44 #include <basic/options/keys/score.OptionKeys.gen.hh>
45 #include <basic/options/option.hh>
46 
47 
48 
49 static basic::Tracer TR("core.scoring.disulfides.CentroidMatchingPotential");
50 
51 
52 using namespace core;
55 using std::string;
56 using utility::vector1;
57 
58 namespace core {
59 namespace scoring {
60 namespace disulfides {
61 
62 /**
63  * Constructor
64  */
66 {
67 
68 
69 }
70 
71 /**
72  * Deconstructor
73  */
75 
76 /**
77  * @brief Calculates scoring terms
78  *
79  */
80 void
82  Residue const & res1,
83  Residue const & res2,
84  Energy & match_t,
85  Energy & match_r,
86  Energy & match_rt
87  ) const
88 {
89 
90  const core::Real probe_radius( basic::options::option[ basic::options::OptionKeys::score::disulf_matching_probe ] );
91 
92  //Calculate the distances and angles of this disulfide
93  core::kinematics::RT scoring_RT(disulfide_RT(res1, res2));
94 
96  db_disulfides( matching_database_.get_all_disulfides() );
97 
98  float mt_dist, mr_dist, mrt_dist; //best distance observed
99  float t_dist, r_dist, rt_dist; //current distance being compared
100 
101  mr_dist = 3.0;//2.8; // maybe max should be pi?
102  mrt_dist = 3.0+probe_radius;//3.75;
103 
104  mt_dist = std::sqrt( scoring_RT.get_translation().distance_squared( db_disulfides[1].get_translation() ));
105  r_dist = std::sqrt( scoring_RT.get_rotation().col(1).distance_squared( db_disulfides[1].get_rotation().col(1) ) +
106  scoring_RT.get_rotation().col(2).distance_squared( db_disulfides[1].get_rotation().col(2) ) +
107  scoring_RT.get_rotation().col(3).distance_squared( db_disulfides[1].get_rotation().col(3) ) );
108  rt_dist = core::kinematics::distance( scoring_RT, db_disulfides[1] );
109 
110  if (( r_dist <= mr_dist ) && ( mt_dist <= probe_radius )) mr_dist = r_dist;
111 
112  if (( rt_dist <= mrt_dist ) && ( mt_dist <= probe_radius )) mrt_dist = rt_dist;
113 
114  //std::cout << "CHECKING " << db_disulfides.size() << " " << mt_dist << " " << mr_dist << " " << mrt_dist << " " << std::endl;
115 
116  for ( Size d = 2; d <= db_disulfides.size(); ++d ) {
117 
118  t_dist = std::sqrt( scoring_RT.get_translation().distance_squared( db_disulfides[1].get_translation() ));
119  r_dist = std::sqrt( scoring_RT.get_rotation().col(1).distance_squared( db_disulfides[1].get_rotation().col(1) ) +
120  scoring_RT.get_rotation().col(2).distance_squared( db_disulfides[1].get_rotation().col(2) ) +
121  scoring_RT.get_rotation().col(3).distance_squared( db_disulfides[1].get_rotation().col(3) ) );
122  rt_dist = core::kinematics::distance( scoring_RT, db_disulfides[d] );
123 
124  //std::cout << "HEYO " << d << " " << mt_dist << " " << mr_dist << " " << mrt_dist << " " << t_dist << " " << r_dist << " " << rt_dist << std::endl;
125 
126  if ( t_dist <= mt_dist ) mt_dist = t_dist;
127  if (( r_dist <= mr_dist ) && ( t_dist <= probe_radius )) mr_dist = r_dist;
128  if (( rt_dist <= mrt_dist ) && ( t_dist <= probe_radius )) mrt_dist = rt_dist;
129  }
130 
131  // if (mrt_dist > 1.0) {
132  // mrt_dist -= 1;
133  // } else {
134  // mrt_dist = 0;
135  // }
136 
137  match_t = mt_dist;
138  match_r = mr_dist;
139  match_rt = mrt_dist;
140 }
141 
142 // Not used by scoring machinery, exists so that other apps can compute the score directly
144 
145  Energy match_RT(0.0);
146 
149 
150  if ( disulfides.size() > 0 ) {
151 
152  for ( Size i = 1; i <= disulfides.size(); ++i ) {
153 
154  Energy temp_RT(0.0), junk_rot(0.0), junk_trans(0.0);
155 
157  pose.residue(disulfides[i].first),
158  pose.residue(disulfides[i].second),
159  junk_rot,
160  junk_trans,
161  temp_RT
162  );
163 
164  match_RT += temp_RT;
165  }
166  }
167 
168  return match_RT;
169 }
170 
171 
172 /**
173  * @brief calculates some degrees of freedom between two centroid cys residues
174  *
175  * If one of the residues is glycine it will be substituted with an idealize
176  * alanine geometry for the calculations which require a Cb molecule.
177  *
178  * centroid_distance requires CEN atoms be defined. If full atom residues
179  * are specified this function returns centroid_distance of -1.
180  *
181  * @param cbcb_distance The distance between Cbetas squared
182  * @param centroid_distance The distance between centroids squared
183  * @param cacbcb_angle_1 The Ca1-Cb1-Cb2 planar angle, in degrees
184  * @param cacbcb_angle_2 The Ca2-Cb2-Cb1 planar angle, in degrees
185  * @param cacbcbca_dihedral The Ca1-Cb1-Cb2-Ca2 dihedral angle
186  * @param backbone_dihedral The N-Ca1-Ca2-C2 dihedral angle
187  */
190  Residue const& res1,
191  Residue const& res2 ) const
192 {
193  conformation::ResidueCAP res1_ptr(&res1);
194  conformation::ResidueCAP res2_ptr(&res2);
195 
196  Size const MAX_POS( 5 );
197  ObjexxFCL::FArray2D_float Epos1(3, MAX_POS), Epos2(3,MAX_POS);
198 
199  Epos1(1,2) = res1_ptr->atom(res1_ptr->atom_index("CA")).xyz()(1);
200  Epos1(2,2) = res1_ptr->atom(res1_ptr->atom_index("CA")).xyz()(2);
201  Epos1(3,2) = res1_ptr->atom(res1_ptr->atom_index("CA")).xyz()(3);
202 
203  Epos1(1,1) = res1_ptr->atom(res1_ptr->atom_index("N")).xyz()(1);
204  Epos1(2,1) = res1_ptr->atom(res1_ptr->atom_index("N")).xyz()(2);
205  Epos1(3,1) = res1_ptr->atom(res1_ptr->atom_index("N")).xyz()(3);
206 
207  Epos1(1,4) = res1_ptr->atom(res1_ptr->atom_index("C")).xyz()(1);
208  Epos1(2,4) = res1_ptr->atom(res1_ptr->atom_index("C")).xyz()(2);
209  Epos1(3,4) = res1_ptr->atom(res1_ptr->atom_index("C")).xyz()(3);
210 
211  Epos2(1,2) = res2_ptr->atom(res2_ptr->atom_index("CA")).xyz()(1);
212  Epos2(2,2) = res2_ptr->atom(res2_ptr->atom_index("CA")).xyz()(2);
213  Epos2(3,2) = res2_ptr->atom(res2_ptr->atom_index("CA")).xyz()(3);
214 
215  Epos2(1,1) = res2_ptr->atom(res2_ptr->atom_index("N")).xyz()(1);
216  Epos2(2,1) = res2_ptr->atom(res2_ptr->atom_index("N")).xyz()(2);
217  Epos2(3,1) = res2_ptr->atom(res2_ptr->atom_index("N")).xyz()(3);
218 
219  Epos2(1,4) = res2_ptr->atom(res2_ptr->atom_index("C")).xyz()(1);
220  Epos2(2,4) = res2_ptr->atom(res2_ptr->atom_index("C")).xyz()(2);
221  Epos2(3,4) = res2_ptr->atom(res2_ptr->atom_index("C")).xyz()(3);
222 
223  //core::scoring::disulfides::RT_helper helper;
224 
225  core::kinematics::RT this_RT(RT_helper::RT_from_epos(Epos1,Epos2));
226 
227  return this_RT;
228 }
229 
230 void
232  numeric::xyzMatrix_double const & p, //FArray2A_double p, // input
233  numeric::xyzMatrix_double & m //FArray2A_double m // output
234 )
235 {
236  using namespace numeric;
237 
238  xyzVector_double a1 = p.col_x() - p.col_y();
239  xyzVector_double a2 = p.col_z() - p.col_y();
240  a1.normalize();
241  xyzVector_double a3 = cross( a1, a2 );
242  a3.normalize();
243  a2 = cross( a3, a1 );
244 
245  m = xyzMatrix_double::cols( a1, a2, a3 );
246 }
247 
248 void
250  ObjexxFCL::FArray2A_float pos,
251  numeric::xyzMatrix_double & p
252 )
253 {
254  pos.dimension( 3, 5 );
255  using namespace numeric;
256 
257  xyzVector_double n( &pos(1,1) );
258  xyzVector_double ca( &pos(1,2) );
259  xyzVector_double c( &pos(1,4) );
260 
261  p = xyzMatrix_double::cols( n, ca, c );
262 
263 }
264 
265 numeric::xyzMatrix_double
266 RT_helper::get_ncac ( ObjexxFCL::FArray2A_float pos )
267 {
268  pos.dimension( 3, 5 );
269  using namespace numeric;
270 
271  xyzVector_double n( &pos(1,1) );
272  xyzVector_double ca( &pos(1,2) );
273  xyzVector_double c( &pos(1,4) );
274 
275  return xyzMatrix_double::cols( n, ca, c );
276 }
277 
278 
279 //helper code to make an RT from two Epos
280 // does this live somewhere else in mini, haven't found it !
282 RT_helper::RT_from_epos( ObjexxFCL::FArray2A_float Epos1, ObjexxFCL::FArray2A_float Epos2)
283 {
284  /// rotation matrix, written in stub1 frame
285  core::kinematics::RT::Matrix rotation( 0.0 ); // 3x3
286  /// tranlsation vector, written in stub1 frame
287  core::kinematics::RT::Vector translation( 0.0 ); // 3
288 
289  Size const MAX_POS( 5 ); // param::MAX_POS
290  Epos1.dimension(3,MAX_POS);
291  Epos2.dimension(3,MAX_POS);
292 
293  //bool const local_debug ( false );
294 
295  numeric::xyzMatrix_double p1, p2, m1, m2;
296 
297  // get coordinate systems from both residues
298  get_ncac(Epos1,p1);
299  get_ncac(Epos2,p2);
300  get_coordinate_system(p1,m1);
301  get_coordinate_system(p2,m2);
302 
303  // consider this: |xx xy xz|
304  // coordinate frame M = |yx yy yz|
305  // |zx zy zz|
306  // each column is a unit vector written in genuine frame.
307  //
308  // vector A in frame M can be rewritten as B in genuine frame
309  // by the formula B = M x A, thus A = M^T x B
310  // a simple example of this would be: the unit vector (1,0,0) in frame M
311  // is actually (xx,yx,zx) in genuine frame. mathematically,
312  // |xx| |xx xy xz| |1|
313  // |yx| = |yx yy yz| x |0| ==> B = M x A
314  // |zx| |zx zy zz| |0|
315  //
316  // the above formula has another layer of meaning: rotation
317  // keeping the genuine frame fixed, a vector can be rotated by applying
318  // matrix M onto it, e.g., (1,0,0) rotated to (xx,yx,zx)
319 
320  numeric::xyzVector_double e1( &Epos1(1,2) );
321  numeric::xyzVector_double e2( &Epos2(1,2) );
322 
323  // ( e2 - e1 ) is the vector in genuine frame,
324  // translation is the vector in m1 frame. so m1^T is multiplied.
325  translation = m1.transposed() * ( e2 - e1 );
326 
327  // let's look at the rotation matrix
328  // A, B, C are three vectors in genuine frame and are related by rotation
329  // B = M1 x A; C = M2 x A;
330  // ==> A = M1^T x B = M2^T x C
331  // ==> C = M2 x M1^T x B
332  // but note that C and B are both in genuine frame and we want a rotation
333  // matrix to be applied onto a vector in M1 frame, so comes another step of
334  // conversion -- left-multiply M1^T on both sides:
335  // M1^T x C = M1^T x M2 x M1^T x B
336  // C' = M1^T x M2 x B', as C' and B' are written in M1 frame.
337  // so we get the rotation matrix as M1^T x M2.
338  // but wait a minute, what Phil orginally got below is M2^T x M1 and it is
339  // impossible for that to be wrong, then what happens?
340 
341  // It turns out when this rotation matrix is further applied to a vector,
342  // it uses Charlies' (col,row) convention (see Dvect_multiply()
343  // in RT::make_jump) which means there is one more transpose to do.
344  // Now an agreement is reached:
345  // (M2^T x M1)^T = M1^T x (M2^T)^T = M1^T x M2
346  // since xyzMatrix uses the normal (row,col) convention, we will switch to
347  // rotation = M1^T x M2
348 
349  rotation = m1.transposed() * m2;
350  /************************Phil's legacy code *********************/
351  // rotation(j,*) is the j-th unit vector of 2nd coord sys written in 1st coord-sys
352  // for ( int i=1; i<=3; ++i ) {
353  // for ( int j=1; j<=3; ++j ) {
354  // // DANGER: not sure about the order... ////////////////////////
355  // // should sync with make_jump
356  // rotation(j,i) = Ddotprod( m1(1,i), m2(1,j) ); // 2nd guess
357  // //rotation(j,i) = Ddotprod( m1(1,j), m2(1,i) ); // 1st guess
358  // }
359  // }
360  /************************Phil's legacy code ********************/
362  rt.set_translation( translation );
363  rt.set_rotation( rotation );
364 
365  return rt;
366 }
367 
368 
369 
370 } // disulfides
371 } // scoring
372 } // core