Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SmoothEnvPairPotential.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/SmoothEnvPairPotential.cc
11 /// @brief Smooth, differentiable version of centroid env and pair terms
12 /// @author Frank DiMaio
13 
14 
16 
17 #include <core/scoring/Energies.hh>
19 
20 #include <core/chemical/AA.hh>
23 #include <basic/database/open.hh>
24 #include <core/pose/Pose.hh>
26 #include <basic/datacache/BasicDataCache.hh>
27 #include <basic/prof.hh>
28 #include <utility/io/izstream.hh>
29 
30 #include <utility/vector1.hh>
31 
32 
33 
34 namespace core {
35 namespace scoring {
36 
37 ///////////////////////////////////////////////////////////////////////////////////////////////
38 
40  Real y = shift_;
41  for (core::Size i=1; i<=sigmoid_coeffs_.size(); ++i) {
43  y += q[0] / (1 + exp( -q[2]*x - q[1] ));
44  }
45  for (core::Size i=1; i<=gaussian_coeffs_.size(); ++i) {
47  y += n[0] * exp( -(x-n[1])*(x-n[1]) / (2*n[2]*n[2]) );
48  }
49  return y;
50 }
51 
52 
54  Real dy = 0;
55  for (core::Size i=1; i<=sigmoid_coeffs_.size(); ++i) {
57  Real e = exp( -q[2]*x - q[1] );
58  Real d = (1 + e);
59  dy += q[0]*q[2]*e / (d*d);
60  }
61  for (core::Size i=1; i<=gaussian_coeffs_.size(); ++i) {
63  dy += n[0] * (n[1]-x) / (n[2]*n[2]) * exp( -(n[1]-x)*(n[1]-x) / (2*n[2]*n[2]) );
64  }
65  return dy;
66 }
67 
68 ///////////////////////////////////////////////////////////////////////////////////////////////
69 
71  cen_dist_cutoff_12_pad = 13.5*13.5;
72 
73  // load the data
74  Size const max_aa( 20 ); // just the standard aa's for now
75  env_.resize(max_aa);
76  pair_.resize(max_aa, utility::vector1< SmoothScoreTermCoeffs >(max_aa) );
77 
78  std::string tag,line;
79  chemical::AA aa1,aa2;
80 
81  utility::io::izstream stream;
82  basic::database::open( stream, "scoring/score_functions/centroid_smooth/cen_smooth_params.txt");
83 
84  while ( getline( stream, line ) ) {
85  std::istringstream l(line);
86  l >> tag;
87  if (tag == "CBETA6:") {
88  // do cbeta stuff
89  l >> tag;
90  if (tag == "SHIFT") {
91  Real shift; l >> shift;
92  cbeta6_.shift(shift);
93  } else if (tag == "GAUSSIAN" || tag == "SIGMOID") {
94  Size ngauss; l >> ngauss;
96  for (core::Size i=1; i<=ngauss; ++i) {
97  l >> g[0] >> g[1] >> g[2];
98  if (tag == "GAUSSIAN")
100  else
101  cbeta6_.add_sigmoid(g);
102  }
103  }
104  } else if (tag == "CBETA12:") {
105  // do cbeta stuff
106  l >> tag;
107  if (tag == "SHIFT") {
108  Real shift; l >> shift;
109  cbeta12_.shift(shift);
110  } else if (tag == "GAUSSIAN" || tag == "SIGMOID") {
111  Size ngauss; l >> ngauss;
113  for (core::Size i=1; i<=ngauss; ++i) {
114  l >> g[0] >> g[1] >> g[2];
115  if (tag == "GAUSSIAN")
117  else
119  }
120  }
121  } else if (tag == "CENPACK:") {
122  // do cenpack stuff
123  l >> tag;
124  if (tag == "SHIFT") {
125  Real shift; l >> shift;
126  cenpack_.shift(shift);
127  } else if (tag == "GAUSSIAN" || tag == "SIGMOID") {
128  Size ngauss; l >> ngauss;
130  for (core::Size i=1; i<=ngauss; ++i) {
131  l >> g[0] >> g[1] >> g[2];
132  if (tag == "GAUSSIAN")
134  else
136  }
137  }
138  } else if (tag == "ENV:") {
139  // do env stuff
140  l >> aa1;
141  SmoothScoreTermCoeffs & currEnv = env_[aa1];
142 
143  l >> tag;
144  if (tag == "SHIFT") {
145  Real shift; l >> shift;
146  currEnv.shift(shift);
147  } else if (tag == "GAUSSIAN" || tag == "SIGMOID") {
148  Size ngauss; l >> ngauss;
150  for (core::Size i=1; i<=ngauss; ++i) {
151  l >> g[0] >> g[1] >> g[2];
152  if (tag == "GAUSSIAN")
153  currEnv.add_gaussian(g);
154  else
155  currEnv.add_sigmoid(g);
156  }
157  }
158  } else if (tag == "PAIR:") {
159  // do pair stuff
160  // do env stuff
161  l >> aa1 >> aa2;
162  SmoothScoreTermCoeffs & currPair =
163  pair_[std::min(aa1,aa2)][std::max(aa1,aa2)]; // symmetrical; just store one half
164 
165  l >> tag;
166  if (tag == "SHIFT") {
167  Real shift; l >> shift;
168  currPair.shift(shift);
169  } else if (tag == "GAUSSIAN" || tag == "SIGMOID") {
170  Size ngauss; l >> ngauss;
172  for (core::Size i=1; i<=ngauss; ++i) {
173  l >> g[0] >> g[1] >> g[2];
174  if (tag == "GAUSSIAN")
175  currPair.add_gaussian(g);
176  else
177  currPair.add_sigmoid(g);
178  }
179  }
180  } else if (tag != "#") {
181  utility_exit_with_message("bad format for cen_smooth_params.txt");
182  }
183 
184  if ( l.fail() ) utility_exit_with_message("bad format for cen_smooth_params.txt");
185  }
186 }
187 
188 void
191  Size const res1,
192  Size const res2,
193  Real const cendist
194 ) const {
195  //fpd At slope = 6, weight = 1.2339e-04 at 1.5A past inflection point
196  Real const SIGMOID_SLOPE = 6.0;
197 
198  //
199  Real interp6 = 1 / (1+exp(SIGMOID_SLOPE*(cendist-6)));
200  cenlist.fcen6(res1) += interp6;
201  cenlist.fcen6(res2) += interp6;
202 
203  Real interp10 = 1 / (1+exp(SIGMOID_SLOPE*(cendist-10)));
204  cenlist.fcen10(res1) += interp10;
205  cenlist.fcen10(res2) += interp10;
206 
207  Real interp12 = 1 / (1+exp(SIGMOID_SLOPE*(cendist-12)));
208  cenlist.fcen12(res1) += interp12 - interp6; // from 6->12 A
209  cenlist.fcen12(res2) += interp12 - interp6; // from 6->12 A
210 }
211 
212 
213 void
216  Size const res1,
217  Size const res2,
218  numeric::xyzVector<Real> const cenvec // vector between centroids
219 ) const {
220  Real const SIGMOID_SLOPE = 6.0; // must match slope in fill_smooth_cenlist
221 
222  Real x = cenvec.length();
223  numeric::xyzVector<Real> gradx = cenvec/x;
224 
225  Real e6 = exp(SIGMOID_SLOPE*(x-6));
226  Real d6 = e6 / ((1-e6)*(1-e6));
227  dcenlist.fcen6(res1) += d6*gradx;
228  dcenlist.fcen6(res2) -= d6*gradx;
229 
230  Real e10 = exp(SIGMOID_SLOPE*(x-10));
231  Real d10 = e10 / ((1-e10)*(1-e10));
232  dcenlist.fcen10(res1) += d10*gradx;
233  dcenlist.fcen10(res2) -= d10*gradx;
234 
235  Real e12 = exp(SIGMOID_SLOPE*(x-12));
236  Real d12 = e12 / ((1-e12)*(1-e12));
237  dcenlist.fcen12(res1) += (d12-d6)*gradx;
238  dcenlist.fcen12(res2) -= (d12-d6)*gradx;
239 }
240 
241 
242 void
244  pose::Pose & pose
245 ) const {
246  // basic::ProfileThis doit( basic::ENERGY_ENVPAIR_POTENTIAL );
247 
249 
250  EnergyGraph const & energy_graph( pose.energies().energy_graph() );
251  Size const nres( energy_graph.num_nodes() );
252 
253  /// calculate the cenlist info only if it has not been calculated since the last score evaluation
254  if ( !cenlist.calculated() ) {
255  cenlist.initialize( pose.total_residue(), 1 ); // every res has 1 neighbor (itself)
256 
257  for ( Size i = 1; i < nres; ++i ) {
258  conformation::Residue const & rsd1 ( pose.residue(i) );
259  if ( !rsd1.is_protein() ) continue;
261  iru = energy_graph.get_node(i)->const_upper_edge_list_begin(),
262  irue = energy_graph.get_node(i)->const_upper_edge_list_end();
263  iru != irue; ++iru ) {
264  EnergyEdge const * edge( static_cast< EnergyEdge const *> (*iru) );
265  Size const j( edge->get_second_node_ind() );
266  conformation::Residue const & rsd2 ( pose.residue(j) );
267  if ( !rsd2.is_protein() ) continue;
268 
269  Real const cendist = edge->square_distance();
270  if ( cendist <= cen_dist_cutoff_12_pad ) {
271  fill_smooth_cenlist( cenlist, i, j, sqrt(cendist) );
272  }
273  }
274  }
275 
276  cenlist.calculated() = true;
277  }
278 }
279 
280 void
282  pose::Pose & pose
283 ) const {
284  // basic::ProfileThis doit( basic::ENERGY_ENVPAIR_POTENTIAL );
285 
287 
288  EnergyGraph const & energy_graph( pose.energies().energy_graph() );
289  Size const nres( energy_graph.num_nodes() );
290 
291  if ( !dcenlist.calculated()) {
292  dcenlist.initialize( pose.total_residue(), numeric::xyzVector< Real >(0,0,0) );
293 
294  for ( Size i = 1; i < nres; ++i ) {
295  conformation::Residue const & rsd1 ( pose.residue(i) );
296  if ( !rsd1.is_protein() ) continue;
298  iru = energy_graph.get_node(i)->const_upper_edge_list_begin(),
299  irue = energy_graph.get_node(i)->const_upper_edge_list_end();
300  iru != irue; ++iru ) {
301  EnergyEdge const * edge( static_cast< EnergyEdge const *> (*iru) );
302  Size const j( edge->get_second_node_ind() );
303  conformation::Residue const & rsd2 ( pose.residue(j) );
304  if ( !rsd2.is_protein() ) continue;
305 
306  numeric::xyzVector<Real> cenvec =
307  rsd1.atom( rsd1.nbr_atom() ).xyz() - rsd2.atom( rsd2.nbr_atom() ).xyz();
308  Real const cendist = edge->square_distance();
309  if ( cendist <= cen_dist_cutoff_12_pad ) {
310  fill_smooth_dcenlist( dcenlist, i, j, cenvec );
311  }
312  }
313  }
314 
315  dcenlist.calculated() = true;
316  }
317 }
318 
319 
320 void
323  cenlist.calculated() = false;
325  dcenlist.calculated() = false;
326 }
327 
328 void
330  pose::Pose const & pose,
331  conformation::Residue const & rsd,
332  Real & env_score,
333  Real & cb_score6,
334  Real & cb_score12
335 ) const {
336  // basic::ProfileThis doit( basic::ENERGY_ENVPAIR_POTENTIAL );
337 
338  SigmoidWeightedCenList< Real > const & cenlist( cenlist_from_pose( pose ));
339 
340  int const position ( rsd.seqpos() );
341 
342  Real const fcen6 ( cenlist.fcen6( position) );
343  Real const fcen10 ( cenlist.fcen10(position) );
344  Real const fcen12 ( cenlist.fcen12(position) );
345 
346  if ( rsd.is_protein() ) {
347  env_score = env_[ rsd.aa() ].func( fcen10 );
348  cb_score6 = cbeta6_.func( fcen6 );
349  cb_score12 = cbeta12_.func( fcen12 );
350  } else {
351  env_score = 0.0;
352  cb_score6 = 0.0;
353  cb_score12 = 0.0;
354  }
355 }
356 
357 
358 void
360  conformation::Residue const & rsd1,
361  conformation::Residue const & rsd2,
362  Real const cendist2,
363  Real & pair_contribution,
364  Real & cenpack_contribution
365 ) const {
366  // basic::ProfileThis doit( basic::ENERGY_ENVPAIR_POTENTIAL );
367 
368  pair_contribution = 0.0;
369  cenpack_contribution = 0.0;
370 
371  if ( !rsd1.is_protein() || !rsd2.is_protein() ) return;
372 
373  chemical::AA const aa1( rsd1.aa() );
374  chemical::AA const aa2( rsd2.aa() );
375 
376  //CAR no pair score if a disulfide
377  if ( aa1 == chemical::aa_cys && aa2 == chemical::aa_cys &&
378  rsd1.is_bonded( rsd2 ) && rsd1.polymeric_sequence_distance( rsd2 ) > 1 &&
380 
381  // no pair score for residues closer than 9 in sequence
382  if ( rsd1.polymeric_sequence_distance( rsd2 ) /* j - i */ <= 8 ) return;
383 
384  Real cendist = sqrt(cendist2);
385  SmoothScoreTermCoeffs const & currPair = pair_[std::min(aa1,aa2)][std::max(aa1,aa2)];
386  pair_contribution = currPair.func( cendist );
387 
388  // smooth pair by an additional sigmoid so pair_score->0 as dist->inf
389  Real const SIGMOID_SLOPE = 6.0;
390  pair_contribution *= 1 / (1+exp(SIGMOID_SLOPE*(cendist-10.5)));
391 
392  cenpack_contribution = cenpack_.func( cendist * 10 + 0.5 );
393 }
394 
395 
396 void
398  pose::Pose const & pose,
399  conformation::Residue const & rsd,
400  numeric::xyzVector<Real> & d_env_score,
401  numeric::xyzVector<Real> & d_cb_score6,
402  numeric::xyzVector<Real> & d_cb_score12
403  ) const {
404  // basic::ProfileThis doit( basic::ENERGY_ENVPAIR_POTENTIAL );
405 
406  d_env_score = 0.0;
407  d_cb_score6 = 0.0;
408  d_cb_score12 = 0.0;
409 
410  if ( !rsd.is_protein() ) return;
411 
412  SigmoidWeightedCenList<Real> const & cenlist( cenlist_from_pose( pose ));
414 
415  int const position ( rsd.seqpos() );
416 
417  // derivative of centroid count wrt x
418  numeric::xyzVector< Real > const dcentroids6_dx ( dcenlist.fcen6(position) );
419  numeric::xyzVector< Real > const dcentroids10_dx ( dcenlist.fcen10(position) );
420  numeric::xyzVector< Real > const dcentroids12_dx ( dcenlist.fcen12(position) );
421 
422  // derivative of score w.r.t centroid count
423  Real const fcen6 ( cenlist.fcen6( position) );
424  Real const fcen10 ( cenlist.fcen10(position) );
425  Real const fcen12 ( cenlist.fcen12(position) );
426  d_env_score = env_[ rsd.aa() ].dfunc( fcen10 ) * dcentroids6_dx;
427  d_cb_score6 = cbeta6_.dfunc( fcen6 ) * dcentroids10_dx;
428  d_cb_score12 = cbeta12_.dfunc( fcen12 ) * dcentroids12_dx;
429 }
430 
431 
432 void
434  conformation::Residue const & rsd1,
435  conformation::Residue const & rsd2,
436  Real const cendist2,
437  Real & d_pair,
438  Real & d_cenpack
439  ) const {
440  // basic::ProfileThis doit( basic::ENERGY_ENVPAIR_POTENTIAL );
441 
442  d_pair = 0.0;
443  d_cenpack = 0.0;
444 
445  if ( !rsd1.is_protein() || !rsd2.is_protein() ) return;
446 
447  chemical::AA const aa1( rsd1.aa() );
448  chemical::AA const aa2( rsd2.aa() );
449 
450  if ( aa1 == chemical::aa_cys && aa2 == chemical::aa_cys &&
451  rsd1.is_bonded( rsd2 ) && rsd1.polymeric_sequence_distance( rsd2 ) > 1 &&
453  if ( rsd1.polymeric_sequence_distance( rsd2 ) <= 8 ) return;
454 
455  // pair
456  Real cendist = sqrt(cendist2);
457  SmoothScoreTermCoeffs const & currPair = pair_[std::min(aa1,aa2)][std::max(aa1,aa2)];
458  Real pair = currPair.func( cendist );
459  Real const SIGMOID_SLOPE = 6.0; // must match slope in evaluate_pair_and_cenpack_score
460  Real e = exp(SIGMOID_SLOPE*(cendist-10.5));
461  Real d = (1 + e);
462  Real sigmoid = 1/d;
463  Real d_sigmoid = -SIGMOID_SLOPE*e / (d*d);
464  d_pair = sigmoid * currPair.dfunc( cendist ) + pair * d_sigmoid;
465 
466  // cenpack
467  d_cenpack = 10 * cenpack_.dfunc( cendist * 10 + 0.5 );
468  // 10 x because cenpack_smooth was fit to original function on 0.1A grid
469 }
470 
471 
472 /// @details Pose must already contain a cenlist object or this method will fail.
475  using namespace core::pose::datacache;
476  return *( static_cast< SigmoidWeightedCenList< Real > const * >( pose.data().get_const_ptr( CacheableDataType::SIGMOID_WEIGHTED_CEN_LIST )() ));
477 
478 }
479 
480 /// @details Either returns a non-const reference to the cenlist object already stored
481 /// in the pose, or creates a new cenist object, places it in the pose, and returns
482 /// a non-const reference to it.
487  }
488  // else
491  return *cenlist;
492 }
493 
494 /// @details Pose must already contain a cenlist object or this method will fail.
497  using namespace core::pose::datacache;
498  return *( static_cast< SigmoidWeightedCenList< numeric::xyzVector< Real > > const * >
499  ( pose.data().get_const_ptr( CacheableDataType::SIGMOID_WEIGHTED_D_CEN_LIST )() ));
500 
501 }
502 
503 /// @details Either returns a non-const reference to the cenlist object already stored
504 /// in the pose, or creates a new cenist object, places it in the pose, and returns
505 /// a non-const reference to it.
509  return *( static_cast< SigmoidWeightedCenList< numeric::xyzVector< Real > > * >
511  }
512  // else
515  return *cenlist;
516 }
517 
518 
519 
520 }
521 }