Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LK_CosThetaEnergy.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/methods/LK_CosThetaEnergy.hh
11 /// @author Rhiju Das
12 
13 
14 // Unit headers
17 
19 #include <core/scoring/Energies.hh>
27 
28 // Project headers
29 #include <core/pose/Pose.hh>
30 // AUTO-REMOVED #include <core/scoring/ScoreFunction.hh>
33 
34 // AUTO-REMOVED #include <core/scoring/constraints/AngleConstraint.hh>
35 
36 #include <ObjexxFCL/format.hh>
37 
38 // AUTO-REMOVED #include <numeric/constants.hh>
39 // AUTO-REMOVED #include <numeric/xyz.functions.hh>
40 
42 #include <core/id/AtomID.hh>
43 #include <utility/vector1.hh>
44 
45 
46 namespace core {
47 namespace scoring {
48 namespace methods {
49 
50 using namespace ObjexxFCL::fmt;
51 
52 /// @details This must return a fresh instance of the LK_CosThetaEnergy class,
53 /// never an instance already in use
56  methods::EnergyMethodOptions const & options
57 ) const {
58  return new LK_CosThetaEnergy( *( ScoringManager::get_instance()->etable( options.etable_type() )) );
59 }
60 
63  ScoreTypes sts;
64  sts.push_back( lk_costheta );
65  sts.push_back( lk_polar );
66  sts.push_back( lk_nonpolar );
67  sts.push_back( lk_polar_intra_RNA );
68  sts.push_back( lk_nonpolar_intra_RNA );
69  return sts;
70 }
71 
72 
73 
76  etable_(etable_in),
77  solv1_(etable_in.solv1()),
78  solv2_(etable_in.solv2()),
79  dsolv1_( etable_in.dsolv1() ),
80  safe_max_dis2_( etable_in.get_safe_max_dis2() ),
81  get_bins_per_A2_( etable_in.get_bins_per_A2()),
82  verbose_( false ),
83  lk_costheta_weight_()
84 {}
85 
86 
87 
88 bool
90 {
91  bool method_1= (weights[lk_polar_intra_RNA]>0.0 || weights[lk_nonpolar_intra_RNA]>0.0) ? true : false;
92 
93  return method_1;
94 }
95 
96 
97 
98 void
100  conformation::Residue const & rsd,
101  pose::Pose const & pose,
102  ScoreFunction const & ,
103  EnergyMap & emap
104 ) const{
105 
106  if(rsd.is_RNA()==false) return;
107 
108  Real lk_polar_intra_RNA_score, lk_nonpolar_intra_RNA_score, lk_costheta_intra_RNA_score;
109 
110  get_residue_energy_RNA_intra( rsd, pose, lk_polar_intra_RNA_score, lk_nonpolar_intra_RNA_score, lk_costheta_intra_RNA_score );
111  emap[ lk_polar_intra_RNA ] += lk_polar_intra_RNA_score;
112  emap[ lk_nonpolar_intra_RNA ] += lk_nonpolar_intra_RNA_score;
113 
114 }
115 
116 
117 
118 Distance
120 {
121  return etable_.max_dis();
122 }
123 
124 /// clone
127 {
128  return new LK_CosThetaEnergy( *this );
129 }
130 
131 ////////////////////////////////////////////////
133  parent( src ),
134  etable_(src.etable_),
135  solv1_( src.solv1_ ),
136  solv2_( src.solv2_ ),
137  dsolv1_( src.dsolv1_ ),
138  safe_max_dis2_( src.safe_max_dis2_ ),
139  get_bins_per_A2_( src.get_bins_per_A2_ ),
140  verbose_( src.verbose_ ),
141  lk_costheta_weight_()
142 {}
143 
144 
145 /////////////////////////////////////////////////////////////////////////////
146 // scoring
147 /////////////////////////////////////////////////////////////////////////////
148 
149 ///
150 void
152  conformation::Residue const & rsd1,
153  conformation::Residue const & rsd2,
154  pose::Pose const & pose,
155  ScoreFunction const &,
156  EnergyMap & emap
157 ) const
158 {
159  Real lk_polar_score, lk_nonpolar_score, lk_costheta_score;
160 
161  get_residue_pair_energy_one_way( rsd1, rsd2, pose, lk_polar_score, lk_nonpolar_score, lk_costheta_score );
162  emap[ lk_polar ] += lk_polar_score;
163  emap[ lk_nonpolar ] += lk_nonpolar_score;
164  emap[ lk_costheta ] += lk_costheta_score;
165 
166  get_residue_pair_energy_one_way( rsd2, rsd1, pose, lk_polar_score, lk_nonpolar_score, lk_costheta_score );
167  emap[ lk_polar ] += lk_polar_score;
168  emap[ lk_nonpolar ] += lk_nonpolar_score;
169  emap[ lk_costheta ] += lk_costheta_score;
170 
171  // std::cout << "BLAH! " << rsd1.seqpos() << " " << rsd2.seqpos() << " " << lk_polar_score << " " << emap[ lk_polar ] << std::endl;
172 }
173 
174 ////////////////////////////////////////////////
175 Vector
176 LK_CosThetaEnergy::get_base_vector( conformation::Residue const & rsd1, Size const i, pose::Pose const & pose ) const
177 {
178  // Use DB/ALF prescription of looking through bonded neighbors.
179  Size non_H_neighbors = 0;
180  Vector base_pseudo_atom(0);
181  for (Size ii = 1; ii <=rsd1.bonded_neighbor(i).size(); ++ii){
182  Size neighbor_id = rsd1.bonded_neighbor(i)[ii];
183  if ( ! rsd1.atom_is_hydrogen(neighbor_id)){
184  base_pseudo_atom += rsd1.xyz(neighbor_id);
185  non_H_neighbors++;
186  }
187  }
188 
189  if ( rsd1.type().n_residue_connections_for_atom(i) > 0 ) {
190  /// CONTEXT DEPENDENCY HERE -- e.g. if c_prev moves, rsd1 needs to be rescored. Fortunately,
191  /// if c_prev moves, the internal "psi" for rsd1 will be updated, and this residue will be rescored.
192 
193  for ( Size ii = 1; ii <= rsd1.type().residue_connections_for_atom(i).size(); ++ii ) {
194  chemical::ResConnID const ii_conn = rsd1.connect_map( rsd1.type().residue_connections_for_atom(i)[ ii ] );
195  Size const neighbor_res_id( ii_conn.resid() );
196  if (neighbor_res_id < 1 ) continue;
197  Size const nieghbor_atom_id( pose.residue( ii_conn.resid() ).residue_connection( ii_conn.connid() ).atomno() );
198  if ( ! pose.residue( neighbor_res_id ).atom_is_hydrogen( nieghbor_atom_id ) ) {
199  base_pseudo_atom += pose.residue( neighbor_res_id ).xyz( nieghbor_atom_id );
200  non_H_neighbors++;
201  }
202  }
203  }
204 
205  if (non_H_neighbors > 0 ) base_pseudo_atom /= non_H_neighbors;
206 
207  // Note -- probably should have a big WARNING show up
208  // if we're trying to compute this scorefunction for water or something
209  // where there is no base atom. That's where non_H_neighbors is 0.
210 
211  Vector res1_base_vector = rsd1.xyz(i) - base_pseudo_atom;
212  Vector res1_base_vector_norm = (res1_base_vector).normalized();
213  return res1_base_vector_norm;
214 }
215 
216 ////////////////////////////////////////////////
217 void
219  conformation::Residue const & rsd,
220  pose::Pose const & pose,
221  Real & lk_polar_intra_RNA_score,
222  Real & lk_nonpolar_intra_RNA_score,
223  Real & lk_costheta_intra_RNA_score
224 ) const
225 {
226 
227  using namespace etable::count_pair;
228 
229  lk_polar_intra_RNA_score = 0.0;
230  lk_nonpolar_intra_RNA_score = 0.0;
231  lk_costheta_intra_RNA_score = 0.0;
232 
233  conformation::Residue const & rsd1=rsd; //Assume rsd1 contributes polar atoms.
234  conformation::Residue const & rsd2=rsd; //Assume rsd2 contributes occluding atoms.
235 
236  //CountPairFunctionOP cpfxn = CountPairFactory::create_count_pair_function( rsd1, rsd2, CP_CROSSOVER_4 );
237 
238  CountPairFunctionOP cpfxn = CountPairFactory::create_intrares_count_pair_function( rsd, CP_CROSSOVER_4); //intra_res version!
239 
240  /*Comment this out after testing (Updated on Dec 24 ,2011)!////
241  ///Testing make sure that this works for intra_res!///
242  for ( Size i = 1, i_end = rsd1.nheavyatoms(); i <= i_end; ++i ) {
243 
244  for ( Size j = 1, j_end = rsd2.nheavyatoms(); j <= j_end; ++j ) {
245  Real cp_weight = 1.0;
246  Size path_dist( 0 );
247  std::cout << "cpfxn->count(" << i << " [" << rsd1.atom_name( i) << "] " << ", " << j << " [" << rsd2.atom_name( j ) << "] " << ")= " << cpfxn->count( i, j, cp_weight, path_dist );
248  std::cout << " cp_weight= " << cp_weight << " path_dist= " << path_dist << std::endl;
249  }
250  }
251  ////Comment this out after testing!*/
252 
253  for ( Size i = 1, i_end = rsd1.nheavyatoms(); i <= i_end; ++i ) {
254 
255  Vector const heavy_atom_i( rsd1.xyz( i ) );
256 
257  //Just compute cos(theta) for polars.
258  bool is_polar( false );
259  if ( rsd1.atom_type(i).is_acceptor() || rsd1.atom_type(i).is_donor()) is_polar = true;
260 
261  //Need to figure out "direction"...
262  Vector const res1_base_vector_norm = is_polar ? get_base_vector( rsd1, i, pose ) : Vector( 0.0 );
263 
264  for ( Size j = 1, j_end = rsd2.nheavyatoms(); j <= j_end; ++j ) {
265 
266  Real cp_weight = 1.0;
267  Size path_dist( 0 );
268  if ( cpfxn->count( i, j, cp_weight, path_dist ) ) {
269 
270  if(core::scoring::rna::Is_base_phosphate_atom_pair(rsd1, rsd2, i, j)==false) continue;
271 
272  Vector const heavy_atom_j( rsd2.xyz( j ) );
273 
274  Vector const d_ij = heavy_atom_j - heavy_atom_i;
275  Real const d2 = d_ij.length_squared();
276 
277  if ( ( d2 >= safe_max_dis2_) || ( d2 == Real(0.0) ) ) continue;
278 
279  Real dotprod( 1.0 );
280  Real dummy_deriv( 0.0 );
281  Real temp_score = cp_weight * eval_lk( rsd1.atom( i ), rsd2.atom( j ), d2, dummy_deriv);
282 
283  Real const START_lk_polar_intra_RNA_score=lk_polar_intra_RNA_score;
284  Real const START_lk_costheta_intra_RNA_score=lk_costheta_intra_RNA_score;
285  Real const START_lk_nonpolar_intra_RNA_score=lk_nonpolar_intra_RNA_score;
286 
287 
288  if ( is_polar ) {
289  lk_polar_intra_RNA_score += temp_score;
290 
291  Vector const d_ij = heavy_atom_j - heavy_atom_i;
292  Vector const d_ij_norm = d_ij.normalized();
293  dotprod = dot( res1_base_vector_norm, d_ij_norm );
294  temp_score *= dotprod;
295  lk_costheta_intra_RNA_score += temp_score;
296 
297  if ( verbose_ && std::abs( temp_score ) > 0.1 ){
298  std::cout << "Occlusion penalty: " << rsd1.name1() << rsd1.seqpos() << " " << rsd1.atom_name( i ) << " covered by " <<
299  rsd2.name1() << rsd2.seqpos() << " " << rsd2.atom_name(j) << " ==> " << F(8,3,temp_score) << ' ' << F(8,3,dotprod) << std::endl;
300  }
301 
302  } else {
303  lk_nonpolar_intra_RNA_score += temp_score;
304  }
305 
306 
307  //consistency check!
308  if(rsd.is_virtual(i) || rsd.is_virtual(j)){
309 
310  Real const diff_polar =lk_polar_intra_RNA_score-START_lk_polar_intra_RNA_score;
311  Real const diff_costheta =lk_costheta_intra_RNA_score-START_lk_costheta_intra_RNA_score;
312  Real const diff_non_polar =lk_nonpolar_intra_RNA_score-START_lk_nonpolar_intra_RNA_score;
313 
314  if(diff_polar>0.001 || diff_polar<-0.001){
315  std::cout << "At least one of the atoms in the pair " << i << "," << j << " | res= " << rsd.seqpos() << " is virtual";
316  std::cout << " but diff_polar= " << diff_polar << " is non-zero!" <<std::endl;
317  utility_exit_with_message("diff_polar>0.001 || diff_polar<-0.001");
318  }
319 
320  if(diff_costheta>0.001 || diff_costheta<-0.001){
321  std::cout << "At least one of the atoms in the pair " << i << "," << j << " | res= " << rsd.seqpos() << " is virtual";
322  std::cout << " but diff_costheta= " << diff_costheta << " is non-zero!" <<std::endl;
323  utility_exit_with_message("diff_costheta>0.001 || diff_costheta<-0.001");
324  }
325 
326  if(diff_non_polar>0.001 || diff_non_polar<-0.001){
327  std::cout << "At least one of the atoms in the pair " << i << "," << j << " | res= " << rsd.seqpos() << " is virtual";
328  std::cout << " but diff_non_polar= " << diff_non_polar << " is non-zero!" <<std::endl;
329  utility_exit_with_message("diff_non_polar>0.001 || diff_non_polar<-0.001");
330  }
331  }
332 
333 
334  } // cp
335 
336  } // j
337  } // i
338 
339 }
340 
341 ////////////////////////////////////////////////
342 void
343 LK_CosThetaEnergy::get_residue_pair_energy_one_way(
344  conformation::Residue const & rsd1,
345  conformation::Residue const & rsd2,
346  pose::Pose const & pose,
347  Real & lk_polar_score,
348  Real & lk_nonpolar_score,
349  Real & lk_costheta_score
350 ) const
351 {
352  using namespace etable::count_pair;
353  CountPairFunctionOP cpfxn =
354  CountPairFactory::create_count_pair_function( rsd1, rsd2, CP_CROSSOVER_4 );
355 
356  lk_polar_score = 0.0;
357  lk_nonpolar_score = 0.0;
358  lk_costheta_score = 0.0;
359 
360  //Assume rsd1 contributes polar atoms.
361  //Assume rsd2 contributes occluding atoms.
362  for ( Size i = 1, i_end = rsd1.nheavyatoms(); i <= i_end; ++i ) {
363 
364  Vector const heavy_atom_i( rsd1.xyz( i ) );
365 
366  //Just compute cos(theta) for polars.
367  bool is_polar( false );
368  if ( rsd1.atom_type(i).is_acceptor() || rsd1.atom_type(i).is_donor()) is_polar = true;
369 
370  //Need to figure out "direction"...
371  Vector const res1_base_vector_norm = is_polar ? get_base_vector( rsd1, i, pose ) : Vector( 0.0 );
372 
373  for ( Size j = 1, j_end = rsd2.nheavyatoms(); j <= j_end; ++j ) {
374 
375  Real cp_weight = 1.0;
376  Size path_dist( 0 );
377  if ( cpfxn->count( i, j, cp_weight, path_dist ) ) {
378 
379  Vector const heavy_atom_j( rsd2.xyz( j ) );
380 
381  Vector const d_ij = heavy_atom_j - heavy_atom_i;
382  Real const d2 = d_ij.length_squared();
383 
384  if ( ( d2 >= safe_max_dis2_) || ( d2 == Real(0.0) ) ) continue;
385 
386  Real dotprod( 1.0 );
387  Real dummy_deriv( 0.0 );
388  Real temp_score = cp_weight * eval_lk( rsd1.atom( i ), rsd2.atom( j ), d2, dummy_deriv);
389 
390  if ( is_polar ) {
391  lk_polar_score += temp_score;
392 
393  Vector const d_ij = heavy_atom_j - heavy_atom_i;
394  Vector const d_ij_norm = d_ij.normalized();
395  dotprod = dot( res1_base_vector_norm, d_ij_norm );
396  temp_score *= dotprod;
397  lk_costheta_score += temp_score;
398 
399  if ( verbose_ && std::abs( temp_score ) > 0.1 ){
400  std::cout << "Occlusion penalty: " << rsd1.name1() << rsd1.seqpos() << " " << rsd1.atom_name( i ) << " covered by " <<
401  rsd2.name1() << rsd2.seqpos() << " " << rsd2.atom_name(j) << " ==> " << F(8,3,temp_score) << ' ' << F(8,3,dotprod) << std::endl;
402  }
403 
404  } else {
405  lk_nonpolar_score += temp_score;
406  }
407 
408 
409  } // cp
410 
411  } // j
412  } // i
413 
414 }
415 
416 /////////////////////////////////////////////////////////////////////////////
417 // derivatives
418 /////////////////////////////////////////////////////////////////////////////
419 void
420 LK_CosThetaEnergy::setup_for_derivatives(
421  pose::Pose & pose,
422  ScoreFunction const &
423 ) const
424 {
425  pose.update_residue_neighbors();
426 }
427 
428 
429 ////////////////////////////////////////////////
430 Real
431 LK_CosThetaEnergy::eval_lk(
432  conformation::Atom const & atom1,
433  conformation::Atom const & atom2,
434  Real const & d2,
435  Real & deriv ) const
436 {
437 
438  Real temp_score( 0.0 );
439  deriv = 0.0;
440  //Make this an input option for efficiency
441  bool const eval_deriv( true );
442 
443  if ( ( d2 < safe_max_dis2_) && ( d2 != Real(0.0) ) ) {
444 
445  Real const d2_bin = d2 * get_bins_per_A2_;
446  int disbin = static_cast< int >( d2_bin ) + 1;
447  Real frac = d2_bin - ( disbin - 1 );
448 
449  // l1 and l2 are FArray LINEAR INDICES for fast lookup:
450  // [ l1 ] == (disbin ,attype2,attype1)
451  // [ l2 ] == (disbin+1,attype2,attype1)
452 
453  int const l1 = solv1_.index( disbin, atom2.type(), atom1.type() );
454  int const l2 = l1 + 1;
455  temp_score = ( (1.-frac)* solv1_[ l1 ] + frac * solv1_[ l2 ]);
456 
457 
458  if (eval_deriv) {
459  // int const l1 = dsolv1_.index( disbin, atom2.type(), atom1.type() ),
460  // l2 = l1 + 1;
461  // Real e1 = dsolv1_[ l1 ];
462  // deriv = ( e1 + frac * ( dsolv1_[ l2 ] - e1 ) );
463  deriv = ( solv1_[ l2 ] - solv1_[ l1 ] ) * get_bins_per_A2_ * std::sqrt( d2 ) * 2;
464  }
465 
466  }
467 
468  return temp_score;
469 
470 }
471 
472 //////////////////////////////////////////////////////////////////////////////////////
473 void
474 LK_CosThetaEnergy::eval_atom_derivative_intra_RNA(
475  id::AtomID const & atom_id,
476  pose::Pose const & pose,
477  kinematics::DomainMap const & /*domain_map*/,
478  EnergyMap const & weights,
479  Vector & F1,
480  Vector & F2
481 ) const
482 {
483 
484 
485  bool do_eval_intra_RNA= (weights[lk_polar_intra_RNA]>0.0 || weights[lk_nonpolar_intra_RNA]>0.0) ? true : false;
486 
487  if(do_eval_intra_RNA==false) return; //early return.
488 
489  Size const i( atom_id.rsd() );
490  Size const j( atom_id.rsd() );
491 
492  conformation::Residue const & rsd1( pose.residue( i ) );
493  conformation::Residue const & rsd2( pose.residue( j ) );
494 
495  if(rsd1.is_RNA()==false) return;
496  if(rsd2.is_RNA()==false) return; //no effect!
497 
498  Size const m( atom_id.atomno() );
499 
500  if ( m > rsd1.nheavyatoms() ) return;
501 
502  if(verbose_){
503  std::cout << "Start LK_CosThetaEnergy::eval_atom_derivative, intra_res case, res= " << i << " atomno= " << m << "[" << rsd1.atom_name(m) << "]" << std::endl;
504  }
505 
506  //bool const pos1_fixed( domain_map( i ) != 0 );
507 
508  //if( pos1_fixed && domain_map(i) == domain_map(j) ){ //MOD OUT ON July 19th, 2011...THIS MIGHT BE BUGGY!
509  //std::cout << "LK_CosThetaEnergy::eval_atom_derivative early return since pos1_fixed && domain_map(i=" << i << ") == domain_map(j=" << j << ")" << std::endl;
510  // return; //Fixed w.r.t. one another.
511  //}
512 
513  Vector const heavy_atom_i( rsd1.xyz( m ) );
514 
515  // cached energies object
516  //Energies const & energies( pose.energies() );
517 
518  // the neighbor/energy links
519  //EnergyGraph const & energy_graph( energies.energy_graph() );
520 
521  Real deriv( 0.0 );
522  Vector const res1_base_vector_norm = get_base_vector( rsd1, m, pose );
523 
524  using namespace etable::count_pair;
525 
526  CountPairFunctionOP cpfxn = CountPairFactory::create_intrares_count_pair_function( rsd1, CP_CROSSOVER_4); //intra_res version!
527 
528  bool atom1_is_polar( false );
529  if (rsd1.atom_type(m).is_acceptor() || rsd1.atom_type(m).is_donor() ) atom1_is_polar = true;
530 
531  for ( Size n = 1; n <= rsd2.nheavyatoms(); ++n ) {
532 
533  Real cp_weight = 1.0;
534  Size path_dist( 0 );
535  if ( cpfxn->count(m, n, cp_weight, path_dist ) ) {
536 
537  if(core::scoring::rna::Is_base_phosphate_atom_pair(rsd1, rsd2, m, n)==false) continue;
538 
539  Vector const heavy_atom_j( rsd2.xyz( n ) );
540  Vector const d_ij = heavy_atom_j - heavy_atom_i;
541  Real const d2 = d_ij.length_squared();
542  Real const d = std::sqrt( d2 );
543  Vector const d_ij_norm = d_ij.normalized();
544 
545  if ( ( d2 >= safe_max_dis2_) || ( d2 == Real(0.0) ) ) continue;
546 
547  bool atom2_is_polar( false );
548  if (rsd2.atom_type(n).is_acceptor() || rsd2.atom_type(n).is_donor() ) atom2_is_polar = true;
549 
550  Vector const res2_base_vector_norm = get_base_vector( rsd2, n, pose );
551 
552  // Real const dist_ij = d_ij.length();
553 
554  Vector f1_fwd( 0.0 ), f2_fwd( 0.0 ), f1_bkd( 0.0 ), f2_bkd( 0.0 );
555  Real lk_score1( 0.0 ), lk_score2( 0.0 );
556  Real dotprod_fwd( 1.0 ), dotprod_bkd( 1.0 );
557 
558  //Forward direction first.
559  lk_score1 = cp_weight * eval_lk( rsd1.atom(m), rsd2.atom(n), d2, deriv );
560 
561  f2_fwd = -1.0 * cp_weight * deriv * d_ij_norm;
562  f1_fwd = 1.0 * cross( f2_fwd, heavy_atom_j );
563 
564  if ( atom1_is_polar ) {
565 
566  F1 += weights[ lk_polar_intra_RNA ] * f1_fwd;
567  F2 += weights[ lk_polar_intra_RNA ] * f2_fwd;
568 
569  dotprod_fwd = dot( res1_base_vector_norm, d_ij_norm );
570 
571  f2_fwd *= dotprod_fwd;
572  f2_fwd -= lk_score1 * ( 1/d ) * (res1_base_vector_norm - dotprod_fwd * d_ij_norm );
573 
574  f1_fwd = 1.0 * cross( f2_fwd, heavy_atom_j );
575 
576  //F1 += weights[ lk_costheta ] * f1_fwd;
577  //F2 += weights[ lk_costheta ] * f2_fwd;
578 
579  lk_score1 *= dotprod_fwd; //to check later (verbose)
580  } else {
581 
582  F1 += weights[ lk_nonpolar_intra_RNA ] * f1_fwd;
583  F2 += weights[ lk_nonpolar_intra_RNA ] * f2_fwd;
584 
585  }
586 
587  /////////////////////////////////
588  // Backwards
589  Vector d_ji_norm = -d_ij_norm;
590 
591  lk_score2 = cp_weight * eval_lk( rsd2.atom(n), rsd1.atom(m), d2, deriv );
592 
593  f2_bkd = -1.0 * deriv * cp_weight * d_ji_norm;
594  f1_bkd = 1.0 * cross( f2_bkd, heavy_atom_i );
595 
596 
597  if ( atom2_is_polar ){
598 
599  F1 -= weights[ lk_polar_intra_RNA ] * f1_bkd;
600  F2 -= weights[ lk_polar_intra_RNA ] * f2_bkd;
601 
602  dotprod_bkd = dot( res2_base_vector_norm, d_ji_norm );
603 
604  f2_bkd *= dotprod_bkd;
605  f2_bkd -= lk_score2 * ( 1/d ) * (res2_base_vector_norm - dotprod_bkd * d_ji_norm );
606 
607  f1_bkd = 1.0 * cross( f2_bkd, heavy_atom_i );
608 
609  //F1 -= weights[ lk_costheta ] * f1_bkd;
610  //F2 -= weights[ lk_costheta ] * f2_bkd;
611 
612  lk_score2 *= dotprod_bkd; //to check later (verbose)
613  } else {
614 
615  F1 -= weights[ lk_nonpolar_intra_RNA ] * f1_bkd;
616  F2 -= weights[ lk_nonpolar_intra_RNA ] * f2_bkd;
617 
618  }
619 
620  if ( verbose_ && (std::abs( lk_score1 ) > 0.1 || std::abs( lk_score2 ) > 0.1 ) ) {
621  std::cout << "Occlusion penalty: " << rsd1.name1() << rsd1.seqpos() << " " << rsd1.atom_name( m ) << " covered by " <<
622  rsd2.name1() << rsd2.seqpos() << " " << rsd2.atom_name(n) <<
623  " " << F(8,3,lk_score1) << " " << F(8,3,lk_score2) <<
624  " ==> " << " DERIV " <<
625  F(8,6,f2_fwd( 1 ) ) << ' ' << F(8,6,f2_bkd(1) ) <<
626  ' ' << std::sqrt( d2 ) << " " << cp_weight << " " <<
627  F(8,3,dotprod_fwd) << " " << F(8,3,dotprod_bkd) << std::endl;
628  }
629 
630 
631  }
632 
633 
634  }
635 
636  if(verbose_){
637  std::cout << "LK_CosThetaEnergy::eval_atom_derivative, intra_res :";
638  std::cout << " F1= " << F1[0] << " " << F1[1] << " " << F1[2];
639  std::cout << " F2= " << F2[0] << " " << F2[1] << " " << F2[2] << std::endl;
640  std::cout << "Finish LK_CosThetaEnergy::eval_atom_derivative, intra_res case, res= " << i << " atomno= " << m << "[" << rsd1.atom_name(m) << "]" << std::endl;
641  }
642 
643 }
644 
645 //////////////////////////////////////////////////////////////////////////////////////
646 void
648  id::AtomID const & atom_id,
649  pose::Pose const & pose,
650  kinematics::DomainMap const & domain_map,
651  ScoreFunction const &,// sfxn,
652  EnergyMap const & weights,
653  Vector & F1,
654  Vector & F2
655 ) const
656 {
657 
658  eval_atom_derivative_intra_RNA(atom_id, pose, domain_map, weights, F1, F2);
659 
660  Size const i( atom_id.rsd() );
661  Size const m( atom_id.atomno() );
662  conformation::Residue const & rsd1( pose.residue( i ) );
663 
664  if ( m > rsd1.nheavyatoms() ) return;
665 
666  Vector const heavy_atom_i( rsd1.xyz( m ) );
667 
668  bool const pos1_fixed( domain_map( i ) != 0 );
669 
670  // cached energies object
671  Energies const & energies( pose.energies() );
672 
673  // the neighbor/energy links
674  EnergyGraph const & energy_graph( energies.energy_graph() );
675 
676  Real deriv( 0.0 );
677  Vector const res1_base_vector_norm = get_base_vector( rsd1, m, pose );
678 
680  iter = energy_graph.get_node( i )->const_edge_list_begin(),
681  itere = energy_graph.get_node( i )->const_edge_list_end();
682  iter != itere; ++iter ) {
683 
684  Size const j( (*iter)->get_other_ind( i ) );
685 
686  if ( pos1_fixed && domain_map(i) == domain_map(j) ) continue; //Fixed w.r.t. one another.
687 
688  conformation::Residue const & rsd2( pose.residue( j ) );
689 
690  using namespace etable::count_pair;
691  CountPairFunctionOP cpfxn =
692  CountPairFactory::create_count_pair_function( rsd1, rsd2, CP_CROSSOVER_4 );
693 
694  bool atom1_is_polar( false );
695  if (rsd1.atom_type(m).is_acceptor() || rsd1.atom_type(m).is_donor() ) atom1_is_polar = true;
696 
697  for ( Size n = 1; n <= rsd2.nheavyatoms(); ++n ) {
698 
699  Real cp_weight = 1.0;
700  Size path_dist( 0 );
701  if ( cpfxn->count(m, n, cp_weight, path_dist ) ) {
702 
703  Vector const heavy_atom_j( rsd2.xyz( n ) );
704  Vector const d_ij = heavy_atom_j - heavy_atom_i;
705  Real const d2 = d_ij.length_squared();
706  Real const d = std::sqrt( d2 );
707  Vector const d_ij_norm = d_ij.normalized();
708 
709  if ( ( d2 >= safe_max_dis2_) || ( d2 == Real(0.0) ) ) continue;
710 
711  bool atom2_is_polar( false );
712  if (rsd2.atom_type(n).is_acceptor() || rsd2.atom_type(n).is_donor() ) atom2_is_polar = true;
713 
714  Vector const res2_base_vector_norm = get_base_vector( rsd2, n, pose );
715 
716  // Real const dist_ij = d_ij.length();
717 
718  Vector f1_fwd( 0.0 ), f2_fwd( 0.0 ), f1_bkd( 0.0 ), f2_bkd( 0.0 );
719  Real lk_score1( 0.0 ), lk_score2( 0.0 );
720  Real dotprod_fwd( 1.0 ), dotprod_bkd( 1.0 );
721 
722  //Forward direction first.
723  lk_score1 = cp_weight * eval_lk( rsd1.atom(m), rsd2.atom(n), d2, deriv );
724 
725  f2_fwd = -1.0 * cp_weight * deriv * d_ij_norm;
726  f1_fwd = 1.0 * cross( f2_fwd, heavy_atom_j );
727 
728  if ( atom1_is_polar ) {
729 
730  F1 += weights[ lk_polar ] * f1_fwd;
731  F2 += weights[ lk_polar ] * f2_fwd;
732 
733  dotprod_fwd = dot( res1_base_vector_norm, d_ij_norm );
734 
735  f2_fwd *= dotprod_fwd;
736  f2_fwd -= lk_score1 * ( 1/d ) * (res1_base_vector_norm - dotprod_fwd * d_ij_norm );
737 
738  f1_fwd = 1.0 * cross( f2_fwd, heavy_atom_j );
739 
740  F1 += weights[ lk_costheta ] * f1_fwd;
741  F2 += weights[ lk_costheta ] * f2_fwd;
742 
743  lk_score1 *= dotprod_fwd; //to check later (verbose)
744  } else {
745 
746  F1 += weights[ lk_nonpolar ] * f1_fwd;
747  F2 += weights[ lk_nonpolar ] * f2_fwd;
748 
749  }
750 
751  /////////////////////////////////
752  // Backwards
753  Vector d_ji_norm = -d_ij_norm;
754 
755  lk_score2 = cp_weight * eval_lk( rsd2.atom(n), rsd1.atom(m), d2, deriv );
756 
757  f2_bkd = -1.0 * deriv * cp_weight * d_ji_norm;
758  f1_bkd = 1.0 * cross( f2_bkd, heavy_atom_i );
759 
760 
761  if ( atom2_is_polar ){
762 
763  F1 -= weights[ lk_polar ] * f1_bkd;
764  F2 -= weights[ lk_polar ] * f2_bkd;
765 
766  dotprod_bkd = dot( res2_base_vector_norm, d_ji_norm );
767 
768  f2_bkd *= dotprod_bkd;
769  f2_bkd -= lk_score2 * ( 1/d ) * (res2_base_vector_norm - dotprod_bkd * d_ji_norm );
770 
771  f1_bkd = 1.0 * cross( f2_bkd, heavy_atom_i );
772 
773  F1 -= weights[ lk_costheta ] * f1_bkd;
774  F2 -= weights[ lk_costheta ] * f2_bkd;
775 
776  lk_score2 *= dotprod_bkd; //to check later (verbose)
777  } else {
778 
779  F1 -= weights[ lk_nonpolar ] * f1_bkd;
780  F2 -= weights[ lk_nonpolar ] * f2_bkd;
781 
782  }
783 
784  if ( verbose_ && (std::abs( lk_score1 ) > 0.1 || std::abs( lk_score2 ) > 0.1 ) ) {
785  std::cout << "Occlusion penalty: " << rsd1.name1() << rsd1.seqpos() << " " << rsd1.atom_name( m ) << " covered by " <<
786  rsd2.name1() << rsd2.seqpos() << " " << rsd2.atom_name(n) <<
787  " " << F(8,3,lk_score1) << " " << F(8,3,lk_score2) <<
788  " ==> " << " DERIV " <<
789  F(8,6,f2_fwd( 1 ) ) << ' ' << F(8,6,f2_bkd(1) ) <<
790  ' ' << std::sqrt( d2 ) << " " << cp_weight << " " <<
791  F(8,3,dotprod_fwd) << " " << F(8,3,dotprod_bkd) << std::endl;
792  }
793 
794 
795  }
796 
797 
798  }
799  }
800 
801 }
802 
803 
804 ////////////////////////////////////////////////
805 void
807  utility::vector1< bool > & /* context_graphs_required */ ) const
808 {}
809 
810 ////////////////////////////////////////////////
811 void
813  pose::Pose &,
814  ScoreFunction const &,
815  EnergyMap &
816 ) const
817 {
818  if (verbose_) std::cout << "DONE SCORING" << std::endl;
819 }
822 {
823  return 1; // Initial versioning
824 }
825 
826 }
827 }
828 }
829 
830 
831