Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RNA_FullAtomStackingEnergy.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 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/rna/RNA_FullAtomStacking.cc
11 /// @brief Statistically derived rotamer pair potential class implementation
12 /// @author Phil Bradley
13 /// @author Andrew Leaver-Fay
14 /// @author Rhiju Das
15 
16 
17 // Unit headers
20 
21 // Package headers
22 // AUTO-REMOVED #include <core/scoring/rna/RNA_LowResolutionPotential.hh>
25 // AUTO-REMOVED #include <core/scoring/rna/RNA_Util.hh>
26 //#include <core/scoring/ScoringManager.hh>
27 #include <core/scoring/Energies.hh>
29 #include <basic/Tracer.hh>
30 
31 // Project headers
32 #include <core/pose/Pose.hh>
34 
36 
37 
38 // Utility headers
39 
40 #include <numeric/xyzMatrix.hh>
41 #include <numeric/xyzVector.hh>
42 // AUTO-REMOVED #include <numeric/xyz.functions.hh>
43 
44 //Auto Headers
45 #include <core/id/AtomID.hh>
46 #include <utility/vector1.hh>
47 
48 
49 
50 // C++
51 
52 static basic::Tracer tr("core.scoring.rna.RNA_FullAtomStackingEnergy");
53 
54 namespace core {
55 namespace scoring {
56 namespace rna {
57 
58 
59 /// @details This must return a fresh instance of the RNA_FullAtomStackingEnergy class,
60 /// never an instance already in use
64 ) const {
65  return new RNA_FullAtomStackingEnergy;
66 }
67 
70  ScoreTypes sts;
71  sts.push_back( fa_stack );
72  sts.push_back( fa_stack_aro );
73  return sts;
74 }
75 
76 
77 /// c-tor
80  //Parameters are totally arbitrary and made up!
81  prefactor_ ( 0.2 ),
82  full_stack_cutoff_ ( 4.0 ), //Encompass next base stack
83  dist_cutoff_ ( 6.0 ), // Do not to next-nearest base stack!
84  dist_cutoff2_ ( dist_cutoff_ * dist_cutoff_ ),
85  base_base_only_( true )
86 {}
87 
88 //clone
91 {
92  return new RNA_FullAtomStackingEnergy;
93 }
94 
95 
96 /////////////////////////////////////////////////////////////////////////////
97 // scoring
98 /////////////////////////////////////////////////////////////////////////////
99 
100 
101 ///
102 void
104 {
106 
108  rna::RNA_CentroidInfo & rna_centroid_info( rna_scoring_info.rna_centroid_info() );
109  rna_centroid_info.update( pose );
110 
111 }
112 
113 void
115 {
117 
119  rna::RNA_CentroidInfo & rna_centroid_info( rna_scoring_info.rna_centroid_info() );
120  rna_centroid_info.update( pose );
121 
122 }
123 
124 //////////////////////////////////////////////////////////////////////////////////////////
125 void
127  conformation::Residue const & rsd1,
128  conformation::Residue const & rsd2,
129  pose::Pose const & pose,
130  ScoreFunction const &,
131  EnergyMap & emap
132 ) const
133 {
134 
135  if ( !rsd1.is_RNA() ) return;
136  if ( !rsd2.is_RNA() ) return;
137 
138  Real score_aro1( 0.0 ), score_aro2( 0.0 );
139 
140  Real const score = residue_pair_energy_one_way( rsd1, rsd2, pose, score_aro1 ) +
141  residue_pair_energy_one_way( rsd2, rsd1, pose, score_aro2 ) ;
142 
143  emap[ fa_stack ] += score;
144 
145  emap[ fa_stack_aro ] += score_aro1 + score_aro2;
146 
147  if ( score <= -0.0001 ) {
148  // tr.Info << rsd1.name3() << rsd1.seqpos() << "---" << rsd2.name3() << rsd2.seqpos() << ": " << score << std::endl;
149  }
150 
151 }
152 
153 
154 //////////////////////////////////////////////////////////////////////////////////////////
155 Real
157  conformation::Residue const & rsd1,
158  conformation::Residue const & rsd2,
159  pose::Pose const & pose,
160  Real & score_aro
161 ) const
162 {
163 
164  score_aro = 0.0;
165 
166  rna::RNA_ScoringInfo const & rna_scoring_info( rna::rna_scoring_info_from_pose( pose ) );
167  rna::RNA_CentroidInfo const & rna_centroid_info( rna_scoring_info.rna_centroid_info() );
168  // utility::vector1< Vector > const & base_centroids( rna_centroid_info.base_centroids() );
169  utility::vector1< kinematics::Stub > const & base_stubs( rna_centroid_info.base_stubs() );
170 
171  Real score( 0.0 );
172 
173  Size const i( rsd1.seqpos() );
174  // Size const j( rsd2.seqpos() );
175 
176  // Vector const & centroid_i( base_centroids[i] );
177  kinematics::Stub const & stub_i( base_stubs[i] );
178  Matrix const M_i ( stub_i.M );
179 
180  // Loop over base heavy atoms.
181  // If I want to generalize this to proteins, maybe could loop over "aromatic" atoms.
182  for ( Size m = rsd1.first_sidechain_atom(); m <= rsd1.nheavyatoms(); ++m ) {
183  //Need to be careful nheavyatoms count includes hydrogen! when the hydrogen is made virtual..
184 
185  if(rsd1.is_virtual(m)) continue;
186 
187  if(m==rsd1.first_sidechain_atom()){
188  //Consistency check
189  if(rsd1.type().atom_name(m) !=" O2*") utility_exit_with_message( "m==rsd1.first_sidechain_atom() but rsd1.type().atom_name(m) !=\" O2*\" ");
190  continue;
191  }
192 
193  Vector const heavy_atom_i( rsd1.xyz( m ) );
194 
195  //Look for occlusion by other base atoms? Or all other heavy atoms?
196  Size const atom_num_start = base_base_only_ ? rsd2.first_sidechain_atom() : 1 ;
197 
198  for ( Size n = atom_num_start; n <= rsd2.nheavyatoms(); ++n ) {
199 
200  if(rsd2.is_virtual(n)) continue;
201 
202  if(n==rsd2.first_sidechain_atom() && base_base_only_){
203  //Consistency check
204  if(rsd2.type().atom_name(n) !=" O2*") utility_exit_with_message( "n==rsd2.first_sidechain_atom() but rsd2.type().atom_name(n) !=\" O2*\" ");
205  continue;
206  }
207 
208 
209 
210 
211  Vector const heavy_atom_j( rsd2.xyz( n ) );
212  Vector r = heavy_atom_j - heavy_atom_i;
213  Real const dist2 = r.length_squared();
214 
215  if ( dist2 < dist_cutoff2_ ) {
216 
217  // Distance const dist = sqrt( dist2 );
218  Real const fa_stack_score = get_fa_stack_score( r, M_i );
219  score += fa_stack_score;
220 
221  if ( is_aro( rsd1, m) && is_aro( rsd2, n) ) score_aro += fa_stack_score;
222 
223  // Real const cos_kappa_j = dot( r, z_j);
224  // score += get_score( dist, cos_kappa_j );
225 
226  //DEBUG
227 // std::cout << "ONE " << "res_name= " << rsd1.name() << " res_seqpos= " << rsd1.seqpos();
228 // std::cout << " atom " << m << " " << "name= " << rsd1.type().atom_name(m) << " type= " << rsd1.atom_type(m).name();
229 
230 // std::cout << "TWO " << "res_name= " << rsd2.name() << " res_seqpos= " << rsd2.seqpos();
231 // std::cout << " atom " << n << " " << "name= " << rsd2.type().atom_name(n) << " type= " << rsd2.atom_type(n).name() << std::endl;
232 
233  }
234  }
235  }
236 
237 
238  return score;
239 }
240 
241 
242 //////////////////////////////////////////////////////////////////////////////
243 // Depending on the option "base_base_only_" allow a stacking interaction
244 // between an atom in a nucleobase and othe nucleobase atoms or *any*
245 // other atom.
246 //
247 //if ( !check_base_base_OK( rsd1, rsd2, m, n ) && !check_base_base_OK( rsd2, rsd1, n, m ) ) continue;
248 //NEED BOTH TO BE NOT OK TO CONTINUE;
249 //rsd1 with m, rsd2 with n
250 //m needs to be a side chain atom no matter what
251 //IN base_base_only_mode, n needs to be a side chain atom
252 
253 //So if base_base_only, then only consider interaction between base atoms of each base.
254 //if base_base_only==false, then consider interaction bewteen base atom of one base and all other atoms of the other base.
255 
256 bool
258  conformation::Residue const & rsd1,
259  conformation::Residue const & rsd2,
260  Size const & m, Size const & n ) const {
261 
262  if ( m < rsd1.first_sidechain_atom() || m > rsd1.nheavyatoms() ) return false;
263 
264  if(m==rsd1.first_sidechain_atom()){
265  //Consistency check
266  if(rsd1.type().atom_name(m) !=" O2*") utility_exit_with_message( "m==rsd1.first_sidechain_atom() but rsd1.type().atom_name(m) !=\" O2*\" ");
267  return false;
268  }
269 
270  if ( n > rsd2.nheavyatoms() ) return false;
271 
272  if (base_base_only_ && n < rsd2.first_sidechain_atom() ) return false;
273 
274  if(n==rsd2.first_sidechain_atom() && base_base_only_){
275  //Consistency check
276  if(rsd2.type().atom_name(n) !=" O2*") utility_exit_with_message( "n==rsd2.first_sidechain_atom() but rsd2.type().atom_name(n) !=\" O2*\" ");
277  return false;
278  }
279 
280  return true;
281 
282 }
283 
284 
285 //////////////////////////////////////////////////////////////////////////////
286 bool
288  conformation::Residue const & rsd1,
289  Size const & m ) const {
290 
291  return ( rsd1.atom_type( m ).is_aromatic() );
292  return true;
293 
294 }
295 
296 ////////////////////////////////////////////////////////////////////////////// (Need to condition this? Parin Sep 2, 2009)
297 void
299  id::AtomID const & atom_id,
300  pose::Pose const & pose,
301  kinematics::DomainMap const & domain_map,
302  ScoreFunction const &,
303  EnergyMap const & weights,
304  Vector & F1,
305  Vector & F2
306  ) const
307 {
308 
309  Size const i( atom_id.rsd() );
310  Size const m( atom_id.atomno() );
311  conformation::Residue const & rsd1( pose.residue( i ) );
312 
313  if (rsd1.is_virtual(m)) return;
314  if ( !rsd1.is_RNA() ) return;
315 
316  if ( m > rsd1.nheavyatoms() ) return;
317 
318  rna::RNA_ScoringInfo const & rna_scoring_info( rna::rna_scoring_info_from_pose( pose ) );
319  rna::RNA_CentroidInfo const & rna_centroid_info( rna_scoring_info.rna_centroid_info() );
320  // utility::vector1< Vector > const & base_centroids( rna_centroid_info.base_centroids() );
321  utility::vector1< kinematics::Stub > const & base_stubs( rna_centroid_info.base_stubs() );
322 
323  // Vector const & centroid_i( base_centroids[i] );
324  kinematics::Stub const & stub_i( base_stubs[i] );
325  Matrix const M_i ( stub_i.M );
326 
327  Vector const heavy_atom_i( rsd1.xyz( m ) );
328 
329  bool const pos1_fixed( domain_map( i ) != 0 );
330 
331  // cached energies object
332  Energies const & energies( pose.energies() );
333 
334  // the neighbor/energy links
335  EnergyGraph const & energy_graph( energies.energy_graph() );
336 
338  iter = energy_graph.get_node( i )->const_edge_list_begin(),
339  itere = energy_graph.get_node( i )->const_edge_list_end();
340  iter != itere; ++iter ) {
341 
342  Size const j( (*iter)->get_other_ind( i ) );
343 
344  if ( pos1_fixed && domain_map(i) == domain_map(j) ) continue; //Fixed w.r.t. one another.
345 
346  conformation::Residue const & rsd2( pose.residue( j ) );
347 
348  if ( !rsd2.is_RNA() ) continue;
349 
350  //Look for occlusion by other base atoms? Or all other heavy atoms?
351  // Size const atom_num_start = base_base_only_ ? rsd2.first_sidechain_atom() : 1 ; //check_base_base_OK take care of this part.
352 
353  kinematics::Stub const & stub_j( base_stubs[j] );
354  Matrix const M_j ( stub_j.M );
355 
356  for ( Size n = 1; n <= rsd2.nheavyatoms(); ++n ) {
357 
358 
359  if(rsd2.is_virtual(n)) continue;
360 
361  if ( !check_base_base_OK( rsd1, rsd2, m, n ) && !check_base_base_OK( rsd2, rsd1, n, m ) ) continue; //This screen for nonbase atoms
362 
363  Vector const heavy_atom_j( rsd2.xyz( n ) );
364  Vector r = heavy_atom_j - heavy_atom_i;
365  Real const dist2 = r.length_squared();
366 
367  if ( dist2 < dist_cutoff2_ ) { //dist_cutoff2=dist_cutoff*dist_cutoff. Energy fade from max to 0 between full_stack_cutoff_ and dist_cutoff_
368 
369  if ( check_base_base_OK( rsd1, rsd2, m, n ) ) {
370  Vector force_vector_i = weights[ fa_stack ] * get_fa_stack_deriv( r, M_i );
371 
372  if ( is_aro( rsd1, m ) && is_aro( rsd2, n ) ) force_vector_i += weights[ fa_stack_aro ] * get_fa_stack_deriv( r, M_i );
373 
374  //Force/torque with which occluding atom j acts on "dipole" i.
375  F1 += -1.0 * cross( force_vector_i, heavy_atom_j );
376  F2 += -1.0 * force_vector_i;
377  }
378 
379  if ( check_base_base_OK( rsd2, rsd1, n, m ) ) {
380  //Force/torque with which occluding atom i acts on "dipole" j.
381  // Note that this calculation is a repeat of some other call to this function.
382  // Might make more sense to do some (alternative) bookkeeping.
383  Vector force_vector_j = weights[ fa_stack ] * get_fa_stack_deriv( -r, M_j );
384 
385  if ( is_aro( rsd1, m ) && is_aro( rsd2, n ) ) force_vector_j += weights[ fa_stack_aro ] * get_fa_stack_deriv( -r, M_j );
386 
387  F1 += cross( force_vector_j, heavy_atom_i );
388  F2 += force_vector_j;
389  }
390 
391  }
392  }
393  }
394 
395 }
396 
397 
398 //////////////////////////////////////////////////////////////////////////////////////////
399 //get_fa_stack_deriv evaluates the fa_stack_score between a pair of atoms. (r_vec is the vector between them, M_i is the coordinate matrix of one of the base)
400 //This function is called by residue_pair_energy_one_way
401 Real
403 {
404 
405  Vector const z_i = M_i.col_z();
406 
407  Real const r = r_vec.length();
408  Real const z = dot( z_i, r_vec );
409  Real const cos_kappa = z / r;
410 
411  Real score = -1.0 * prefactor_;
412 
413  //Orientation dependence
414  score *= cos_kappa * cos_kappa ;
415 
417 
418  //Just use a simple cubic spline to fade from 1 to 0,
419  // and to force derivatives to be continuous.
420  if ( b > 0.0 ) {
422  Real const b2 = b*b;
423  Real const b3 = b2*b;
424  score *= ( 2 * b3 - 3 * b2 + 1 );
425  }
426 
427  return score;
428 
429 }
430 
431 
432 //////////////////////////////////////////////////////////////////////////////////////////
433 //get_fa_stack_deriv evaluates the fa_stack_deriv between a pair of atoms. (r_vec is the vector between them, M_i is the coordinate matrix of one of the base)
434 //This function is called by eval_atom_derivative
435 Vector
437 {
438 
439  // Well, the energy is a function of the inter-atom distance and a special cos(angle)
440  // E = E ( r, cos(theta ) ).
441  // so
442  // dE/dx = dE/dr (x/r) + ( - x * z / r^3 ) ( dE/dcos(theta) )
443  // dE/dy = dE/dr (y/r) + ( - y * z / r^3 ) ( dE/dcos(theta) )
444  // dE/dz = dE/dr (z/r) + ( (r^2 - z^2) / r^3 ) ( dE/dcos(theta) )
445  //
446 
447  Vector const x_i = M_i.col_x();
448  Vector const y_i = M_i.col_y();
449  Vector const z_i = M_i.col_z();
450 
451  Real const r = r_vec.length();
452  Real const x = dot( x_i, r_vec );
453  Real const y = dot( y_i, r_vec );
454  Real const z = dot( z_i, r_vec );
455  Real const cos_kappa = z / r;
456 
457  /////////////////////////////////
458  //dE_dcoskappa
459  /////////////////////////////////
460  Real dE_dcoskappa = -1.0 * prefactor_;
461 
462  //Orientation dependence
463  dE_dcoskappa *= 2 * cos_kappa ;
464 
466  Distance distance_scale = (dist_cutoff_ - full_stack_cutoff_ );
467  b /= distance_scale;
468 
469  Real b2( 0.0 ), b3( 0.0 );
470  //Just use a simple cubic spline to fade from 1 to 0,
471  // and to force derivatives to be continuous.
472  if ( b > 0.0 && b < 1.0) {
473  b2 = b*b;
474  b3 = b2*b;
475  dE_dcoskappa *= ( 2 * b3 - 3 * b2 + 1 );
476  }
477 
478  /////////////////////////////////
479  //dE_dr
480  /////////////////////////////////
481  Real dE_dr = -1.0 * prefactor_;
482 
483  //Orientation dependence
484  dE_dr *= cos_kappa * cos_kappa ;
485 
486  //Just use a simple cubic spline to fade from 1 to 0,
487  // and to force derivatives to be continuous.
488  if ( b > 0.0 && b < 1.0) {
489  dE_dr *= ( 6 * b2 - 6 * b );
490  dE_dr /= distance_scale;
491  } else {
492  dE_dr = 0.0;
493  }
494 
495  Real const dE_dx = ( dE_dr ) * (x/r) - (dE_dcoskappa) * (x * z)/ (r*r*r) ;
496  Real const dE_dy = ( dE_dr ) * (y/r) - (dE_dcoskappa) * (y * z)/ (r*r*r) ;
497  Real const dE_dz = ( dE_dr ) * (z/r) + (dE_dcoskappa) * (x*x + y*y)/ (r*r*r);
498 
499  // std::cout << " HELLO " << r << " " << dE_dr << " " << dE_dcoskappa << std::endl;
500 
501  return (dE_dx * x_i + dE_dy * y_i + dE_dz * z_i );
502 
503 }
504 
505 
506 //////////////////////////////////////////////////////////////////////////////////////////
507 void
509  pose::Pose & pose,
510  ScoreFunction const &,
511  EnergyMap &
512 ) const
513 {
514 
516  rna::RNA_CentroidInfo & rna_centroid_info( rna_scoring_info.rna_centroid_info() );
517  rna_centroid_info.calculated() = false;
518 
519 }
520 
521 /// @brief RNA_FullAtomStackingEnergy distance cutoff
522 Distance
524 {
525  return 0.0; /// Uh, I don't know.
526 }
527 
530 {
531  return 1; // Initial versioning
532 }
533 
534 
535 }
536 }
537 }