Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ProClosureEnergy.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/ProClosureEnergy.cc
11 /// @brief Proline ring closure energy method class implementation
12 /// @author Andrew Leaver-Fay
13 
14 // Unit Headers
17 
18 // Package Headers
20 //#include <core/scoring/ScoringManager.hh>
21 // AUTO-REMOVED #include <core/scoring/constraints/DihedralConstraint.hh>
22 // AUTO-REMOVED #include <core/scoring/constraints/HarmonicFunc.hh>
23 
24 // Project headers
26 // AUTO-REMOVED #include <core/pose/Pose.hh>
27 
28 // Utility headers
29 #include <numeric/constants.hh>
30 #include <numeric/conversions.hh>
31 #include <numeric/xyz.functions.hh>
32 #include <numeric/deriv/distance_deriv.hh>
33 #include <numeric/deriv/dihedral_deriv.hh>
34 
35 // STL Headers
36 #include <string>
37 
38 // options
39 #include <basic/options/option.hh>
40 #include <basic/options/keys/score.OptionKeys.gen.hh>
41 
43 #include <utility/vector1.hh>
44 
45 
46 namespace core {
47 namespace scoring {
48 namespace methods {
49 
50 
51 /// @details This must return a fresh instance of the ProClosureEnergy class,
52 /// never an instance already in use
56 ) const {
57  return new ProClosureEnergy;
58 }
59 
62  ScoreTypes sts;
63  sts.push_back( pro_close );
64  return sts;
65 }
66 
67 
68 using namespace numeric::constants::d;
69 
70 
71 /// ctor
74  n_nv_dist_sd_( basic::options::option[ basic::options::OptionKeys::score::pro_close_planar_constraint ] ), // totally fictional
75 
76  /// measured from 4745 prolines from 1.25 A and higher resolution protein structures
77  trans_chi4_mean_( 176.3 * numeric::constants::d::degrees_to_radians ),
78  trans_chi4_sd_( 6.0158 * numeric::constants::d::degrees_to_radians ),
79  cis_chi4_mean_( -2.9105 * numeric::constants::d::degrees_to_radians ),
80  cis_chi4_sd_( 5.8239 * numeric::constants::d::degrees_to_radians ),
81 
82  bbN_( "N" ),
83  scNV_( "NV" ),
84  scCD_( "CD" ),
85  bbC_( "C" ),
86  bbO_( "O")
87 {}
88 
90 {}
91 
92 /// clone
95 {
96  return new ProClosureEnergy;
97 }
98 
99 /////////////////////////////////////////////////////////////////////////////
100 // methods for ContextIndependentTwoBodyEnergies
101 /////////////////////////////////////////////////////////////////////////////
102 bool
104  conformation::Residue const & res1,
105  conformation::Residue const & res2,
106  bool res_moving_wrt_eachother
107 ) const
108 {
109  conformation::Residue const & resl( res1.seqpos() < res2.seqpos() ? res1 : res2 );
110  conformation::Residue const & resu( res1.seqpos() < res2.seqpos() ? res2 : res1 );
111 
112  return res_moving_wrt_eachother && resu.aa() == chemical::aa_pro
113  && resl.seqpos() + 1 == resu.seqpos() && resl.is_bonded( resu );
114 }
115 
116 void
118  conformation::Residue const & rsd1,
119  conformation::Residue const & rsd2,
120  pose::Pose const &,
121  ScoreFunction const &,
122  EnergyMap & emap
123 ) const
124 {
125  using namespace conformation;
126  using namespace chemical;
127 
128  if ( rsd1.is_virtual_residue() ) return;
129  if ( rsd2.is_virtual_residue() ) return;
130 
131  if (( rsd2.aa() == aa_pro && rsd1.is_bonded( rsd2 ) &&
132  rsd1.seqpos() == rsd2.seqpos() - 1 ) ||
133  (rsd1.aa() == aa_pro && rsd1.is_bonded( rsd2 ) &&
134  rsd1.seqpos() - 1 == rsd2.seqpos() )) {
135  Residue const & upper_res( rsd1.seqpos() > rsd2.seqpos() ? rsd1 : rsd2 );
136  Residue const & lower_res( rsd1.seqpos() > rsd2.seqpos() ? rsd2 : rsd1 );
137 
138  Real chi4 = measure_chi4( lower_res, upper_res );
139  emap[ pro_close ] += chi4E( chi4 );
140  }
141 }
142 
143 void
145  conformation::Residue const & rsd1,
146  conformation::Residue const & rsd2,
149  ResPairMinimizationData const &,
150  pose::Pose const &,
151  EnergyMap const & weights,
152  utility::vector1< DerivVectorPair > & r1_atom_derivs,
153  utility::vector1< DerivVectorPair > & r2_atom_derivs
154 ) const
155 {
156  bool const r1_upper( rsd1.seqpos() > rsd2.seqpos() );
157  conformation::Residue const & upper_res( r1_upper ? rsd1 : rsd2 );
158  conformation::Residue const & lower_res( r1_upper ? rsd2 : rsd1 );
159 
160  assert( upper_res.aa() == chemical::aa_pro );
161 
162  utility::vector1< DerivVectorPair > & upper_res_atom_derivs( r1_upper ? r1_atom_derivs : r2_atom_derivs );
163  utility::vector1< DerivVectorPair > & lower_res_atom_derivs( r1_upper ? r2_atom_derivs : r1_atom_derivs );
164 
165  /// Atoms on the upper res
166  /// 1. N, CD
167  /// Atoms on the lower res
168  /// 2. C, O
169  Size N_up_id = upper_res.atom_index( bbN_ );
170  Size CD_up_id = upper_res.atom_index( scCD_ );
171  Size C_lo_id = lower_res.atom_index( bbC_ );
172  Size O_lo_id = lower_res.atom_index( bbO_ );
173 
174  // N upper
175  Vector f1( 0.0 ), f2( 0.0 );
176  Real chi4( 0.0 );
177  numeric::deriv::dihedral_p2_cosine_deriv(
178  upper_res.xyz( CD_up_id ), upper_res.xyz( N_up_id ),
179  lower_res.xyz( C_lo_id ), lower_res.xyz( O_lo_id ),
180  chi4, f1, f2 );
181  Real deriv( weights[ pro_close ] * dchi4E_dchi4( chi4 ) );
182 
183  f1 *= deriv; f2 *= deriv;
184  upper_res_atom_derivs[ N_up_id ].f1() += f1;
185  upper_res_atom_derivs[ N_up_id ].f2() += f2;
186 
187  /// C lower
188  numeric::deriv::dihedral_p2_cosine_deriv(
189  lower_res.xyz( O_lo_id ), lower_res.xyz( C_lo_id ),
190  upper_res.xyz( N_up_id ), upper_res.xyz( CD_up_id ),
191  chi4, f1, f2 );
192  f1 *= deriv; f2 *= deriv;
193  lower_res_atom_derivs[ C_lo_id ].f1() += f1;
194  lower_res_atom_derivs[ C_lo_id ].f2() += f2;
195 
196 
197  // CD upper
198  //f1 = 0.0; f2 = 0.0;
199  numeric::deriv::dihedral_p1_cosine_deriv(
200  upper_res.xyz( CD_up_id ), upper_res.xyz( N_up_id ),
201  lower_res.xyz( C_lo_id ), lower_res.xyz( O_lo_id ),
202  chi4, f1, f2 );
203  f1 *= deriv; f2 *= deriv;
204  upper_res_atom_derivs[ CD_up_id ].f1() += f1;
205  upper_res_atom_derivs[ CD_up_id ].f2() += f2;
206 
207  // O lower
208  numeric::deriv::dihedral_p1_cosine_deriv(
209  lower_res.xyz( O_lo_id ), lower_res.xyz( C_lo_id ),
210  upper_res.xyz( N_up_id ), upper_res.xyz( CD_up_id ),
211  chi4, f1, f2 );
212  f1 *= deriv; f2 *= deriv;
213  lower_res_atom_derivs[ O_lo_id ].f1() += f1;
214  lower_res_atom_derivs[ O_lo_id ].f2() += f2;
215 
216 
217 }
218 
219 
220 /// @brief Penalize the pucker-up residue type if its chi1 is positive;
221 /// penalize the pucker-down residue type if its chi1 is negative. Only
222 /// applies this penalty when the other_residue is the next polymeric residue
223 /// after pro_residue (i+1), unless pro_residue is an upper_term,
224 /// in which case it applies the penalty for pro_residue's previous polymeric
225 /// residue.
226 void
228  conformation::Residue const & ,
229  conformation::Residue const & ,
230  pose::Pose const &,
231  ScoreFunction const &,
232  EnergyMap &
233 ) const
234 {
235  /*
236  static const std::string prd_name( "PRD" );
237  static const std::string pru_name( "PRU" );
238 
239  if ( pro_residue.aa() == chemical::aa_pro ) {
240  if ( pro_residue.is_bonded( other_residue ) &&
241  ( ! pro_residue.is_upper_terminus() &&
242  pro_residue.seqpos() + 1 == other_residue.seqpos() )
243  ||
244  ( pro_residue.is_upper_terminus() &&
245  pro_residue.seqpos() == other_residue.seqpos() + 1 ) ) {
246  if ( pro_residue.name3() == prd_name && pro_residue.chi( 1 ) < 0 ) {
247  emap[ pro_close ] = 10;
248  } else if ( pro_residue.name3() == pru_name && pro_residue.chi( 1 ) > 0 ) {
249  emap[ pro_close ] = 10;
250  }
251  }
252  }
253  */
254 }
255 
256 /// @brief Penalize the pucker-up residue type if its chi1 is positive;
257 /// penalize the pucker-down residue type if its chi1 is negative. Only
258 /// applies this penalty when the other_residue is the next polymeric residue
259 /// after pro_residue (i+1), unless pro_residue is an upper_term,
260 /// in which case it applies the penalty for pro_residue's previous polymeric
261 /// residue.
262 void
264  conformation::Residue const & ,
265  conformation::Residue const & ,
266  pose::Pose const & ,
267  ScoreFunction const & ,
268  EnergyMap &
269 ) const
270 {
271  //bump_energy_full( pro_residue, other_residue, pose, sfxn, emap );
272 }
273 
274 
275 bool
277 {
278  return true;
279 }
280 
281 
282 ///
283 void
285  conformation::Residue const & rsd,
286  pose::Pose const & ,
287  ScoreFunction const & ,
288  EnergyMap & emap
289 ) const
290 {
291 
292  if ( rsd.aa() == chemical::aa_pro ) {
293  if ( rsd.is_virtual_residue() )return;
294  Distance const dist2 = rsd.xyz( bbN_ ).distance_squared( rsd.xyz( scNV_ ) );
295  emap[ pro_close ] += dist2 / ( n_nv_dist_sd_ * n_nv_dist_sd_ );
296  }
297 
298 }
299 
300 
301 
302 
303 bool
305  conformation::Residue const & res
306 ) const
307 {
308  return res.aa() == chemical::aa_pro;
309 }
310 
311 void
313  conformation::Residue const & rsd,
315  pose::Pose const &,
316  EnergyMap const & weights,
318 ) const
319 {
320  assert ( rsd.aa() == chemical::aa_pro );
321 
322  assert( rsd.has( scNV_ ) );
323  assert( rsd.has( bbN_ ) );
324  if ( rsd.is_virtual_residue() ) return;
325 
326  Size NV_ind = rsd.atom_index( scNV_ );
327  Size N_ind = rsd.atom_index( bbN_ );
328 
329  Vector const & nv_pos( rsd.xyz( NV_ind ));
330  Vector const & n_pos( rsd.xyz( N_ind ));
331  /// Numeric deriv version to consolidate code.
332  Vector f1( 0.0 ), f2( 0.0 );
333  Distance dist( 0.0 );
334  numeric::deriv::distance_f1_f2_deriv( nv_pos, n_pos, dist, f1, f2 );
335  Real deriv( weights[ pro_close ] * 2 * dist / ( n_nv_dist_sd_ * n_nv_dist_sd_ ));
336  f1 *= deriv; f2 *= deriv;
337 
338  atom_derivs[ NV_ind ].f1() += f1;
339  atom_derivs[ NV_ind ].f2() += f2;
340  atom_derivs[ N_ind ].f1() -= f1;
341  atom_derivs[ N_ind ].f2() -= f2;
342 
343 }
344 
345 
346 /*void
347 ProClosureEnergy::eval_intrares_atom_derivative2(
348  Size const atom_index,
349  conformation::Residue const & rsd,
350  EnergyMap const & weights,
351  Vector & F1,
352  Vector & F2
353 ) const
354 {
355  assert ( rsd.aa() == chemical::aa_pro );
356 
357  if ( rsd.atom_index( scNV_ ) == atom_index ) {
358 
359  Vector const & nv_pos( rsd.xyz( atom_index ));
360  Vector const & n_pos( rsd.xyz( bbN_ ));
361  /// Numeric deriv version to consolidate code.
362  Vector f1( 0.0 ), f2( 0.0 );
363  Distance dist( 0.0 );
364  numeric::deriv::distance_f1_f2_deriv( nv_pos, n_pos, dist, f1, f2 );
365  Real deriv( weights[ pro_close ] * 2 * dist / ( n_nv_dist_sd_ * n_nv_dist_sd_ ));
366  F1 += deriv * f1;
367  F2 += deriv * f2;
368 
369  } else if ( rsd.atom_index( bbN_ ) == atom_index ) {
370  //std::cout << "evaluating N pro-closure energy derivative" << std::endl;
371  Vector const & n_pos( rsd.xyz( atom_index ));
372  Vector const & nv_pos( rsd.xyz( scNV_ ));
373 
374  { /// Scope: Distance derivative.
375  Vector f1( 0.0 ), f2( 0.0 );
376  Distance dist( 0.0 );
377  numeric::deriv::distance_f1_f2_deriv( n_pos, nv_pos, dist, f1, f2 );
378  Real deriv( weights[ pro_close ] * 2 * dist / ( n_nv_dist_sd_ * n_nv_dist_sd_ ));
379  F1 += deriv * f1;
380  F2 += deriv * f2;
381  }
382 
383  }
384 }*/
385 
386 /// @brief ProClosureEnergy Energy is context independent and thus
387 /// indicates that no context graphs need to
388 /// be maintained by class Energies
389 void
391  utility::vector1< bool > & /*context_graphs_required*/
392 )
393 const
394 {}
395 
396 Real
398  conformation::Residue const & lower_res,
399  conformation::Residue const & upper_res
400 ) const
401 {
402  using namespace numeric;
403  using namespace numeric::constants::d;
404 
405  assert( upper_res.aa() == chemical::aa_pro );
406  assert( lower_res.is_bonded( upper_res ) );
407  assert( lower_res.seqpos() == upper_res.seqpos() - 1 );
408 
409  Real chi4 = dihedral_radians(
410  upper_res.xyz( scCD_ ),
411  upper_res.xyz( bbN_ ),
412  lower_res.xyz( bbC_ ),
413  lower_res.xyz( bbO_ ));
414  if ( chi4 < -pi_over_2 ) chi4 += pi_2; // wrap
415  return chi4;
416 }
417 
418 /// @details chi4 is in radians and should be in the range between -pi_over_2 and 3/2 pi
419 Real
421  Real chi4
422 ) const
423 {
424  using namespace numeric::constants::d;
425 
426  if ( chi4 > pi_over_2 ) {
427  Real diff = chi4 - trans_chi4_mean_;
428  return diff * diff / ( trans_chi4_sd_ * trans_chi4_sd_ );
429  } else {
430  Real diff = chi4 - cis_chi4_mean_;
431  return diff * diff / ( cis_chi4_sd_ * cis_chi4_sd_ );
432  }
433 }
434 
435 
436 /// @details chi4 is in radians and should be in the range between -pi and pi
437 Real
439  Real chi4
440 ) const
441 {
442  using namespace numeric::constants::d;
443  if ( chi4 < -pi_over_2 ) chi4 += pi_2;
444 
445  if ( chi4 > pi_over_2 ) {
446  Real diff = chi4 - trans_chi4_mean_;
447  return 2 * diff / ( trans_chi4_sd_ * trans_chi4_sd_ );
448  } else {
449  Real diff = chi4 - cis_chi4_mean_;
450  return 2 * diff / ( cis_chi4_sd_ * cis_chi4_sd_ );
451  }
452 }
455 {
456  return 1; // Initial versioning
457 }
458 
459 
460 } // methods
461 } // scoring
462 } // core
463