Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CarbonHBondPotential.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/carbon_hbonds/AtomVDW.hh
11 /// @brief
12 /// @author Rhiju Das
13 
14 
15 // Unit Headers
17 #include <core/scoring/rna/RNA_Util.hh> // for get_fade_correction
18 
19 // Package headers
20 
21 // Project headers
24 
25 #include <basic/database/open.hh>
26 #include <basic/options/option.hh>
27 #include <basic/options/keys/corrections.OptionKeys.gen.hh>
28 
29 // Utility headers
30 #include <utility/io/izstream.hh>
31 
32 #include <numeric/conversions.hh>
33 // AUTO-REMOVED #include <numeric/xyz.functions.hh>
34 // AUTO-REMOVED #include <numeric/xyz.io.hh>
35 
37 #include <basic/options/keys/OptionKeys.hh>
38 
39 #include <utility/vector1.hh>
40 #include <numeric/xyzVector.hh>
41 
42 
43 namespace core {
44 namespace scoring {
45 namespace carbon_hbonds {
46 
47 /// @details ctor, reads data file. Need to configure to allow alternate tables/atom_sets
49  bin_width_( 0 ),
50  max_dist_( 0 ),
51  aroC_scale_factor_( 2.0 ),
52  num_carbon_donor_atoms_( 5 ),
53  num_bins_( 45 ),
54  rna_cos_theta_cutoff_( cos( numeric::conversions::radians( 60.0 ) ) /* 0.50 */),
55  rna_cos_theta_fade_zone_( 0.2 ),
56  rna_ch_o_bond_distance_( 2.35 )
57 {
59 }
60 
61 ////////////////////////////////////////////////////////////////////////////////////////
62 //Why doesn't this helper function already exist in vector class?
63 Size
65 {
66  Size count( 1 );
67  for ( utility::vector1<std::string>::iterator iter = vec.begin(); iter < vec.end(); iter++ ) {
68  if (*iter == element) return count;
69  count++;
70  }
71  vec.push_back( element );
72  return count;
73 }
74 
75 ////////////////////////////////////////////////////////////////////////////////////////
76 void
78 {
79  using namespace basic::options;
80  using namespace basic::options::OptionKeys::corrections::score;
81 
82  //Read in data file, and fill in private data.
83  utility::io::izstream stream;
84 
85  // search in the local directory first
86  stream.open( option[ ch_o_bond_potential ] );
87  // then try database
88  if ( !stream.good() ) {
89  stream.close();
90  basic::database::open( stream, option[ ch_o_bond_potential ] );
91  }
92 
93  //This doesn't actually need to be hardwired -- if
94  // I wasn't so lazy, I'd make it figure out the
95  // dimensions based on the input file.
96  for (Size i = 1; i <= num_carbon_donor_atoms_; i++ ){
97  ObjexxFCL::FArray1D<Real> new_array; // = new ObjexxFCL::FArray1D< Real> ;
98  carbon_hbond_parameter_.push_back( new_array );
99  carbon_hbond_parameter_[ i ].dimension( num_bins_ );
100  carbon_hbond_parameter_[ i ] = 0.0;
101  }
102 
103  if ( !stream.good() ) utility_exit_with_message( "Unable to open ch_o_bond_potential!" );
104 
105  std::string line, atom_name;
106  Real bin_min, bin_max, value;
107  bin_width_ = 0.0;
108 
109  while ( getline( stream, line ) ) {
110  std::istringstream l( line );
111  l >> atom_name >> bin_min >> bin_max >> value;
112  // atom_name = line.substr(0,4);
113 
114  Size const pos = get_position_in_vector( carbon_donors_, atom_name );
115 
116  if ( bin_width_ < 0.00001 ) bin_width_ = bin_max - bin_min;
117  if (bin_max > max_dist_ ) max_dist_ = bin_max;
118 
119  Size const bin = static_cast<Size>( bin_max/bin_width_ + 0.001 );
120  if (bin <= num_bins_ ) {
121  carbon_hbond_parameter_[pos]( bin ) = value;
122  }
123  }
124 
125  // Force potential to be zero at boundary?
126  // for (Size i = 1; i <= num_carbon_donor_atoms_; i++ ) carbon_hbond_parameter_[i]( num_bins_ ) = 0.0;
127 
128  //Now read in atom type set, and lookup strings.
129  core::chemical::AtomTypeSetCAP atom_type_set_cap =
131  chemical::AtomTypeSet const & atom_type_set = *atom_type_set_cap;
132 
133  standard_atomtype_to_carbon_donor_index_.dimension( atom_type_set.n_atomtypes() );
135  for (Size i = 1; i <= num_carbon_donor_atoms_; i++ ){
136  Size const standard_atomtype_index = atom_type_set.atom_type_index( carbon_donors_[i] );
137  // std::cout << "HEY! " << i << " " << carbon_donors_[i] << " " << standard_atomtype_index << std::endl;
138  standard_atomtype_to_carbon_donor_index_( standard_atomtype_index ) = i;
139  }
140 
141  // Fudge for aromatic carbons.
142  // Note this is totally based on intuition that DNA/RNA bases should make stronger carbon H-bonds than
143  // what is inferred from proteins, due to activation by exocyclic atoms.
144  // It would perhaps make sense to only apply the fudge for nucleic acids, and maybe then only
145  // for appropriate positions.
146  //
147  Size const aro_index = standard_atomtype_to_carbon_donor_index_( atom_type_set.atom_type_index( "aroC" ) );
148  for (Size j = 1; j <= num_bins_; j++ ) {
149  carbon_hbond_parameter_[ aro_index ]( j ) *= aroC_scale_factor_;
150  }
151 
152  //
153  // Precalculate derivative. Would it make sense to do this and the interpolation via splines?
154  // And is the potential smooth enough?
155  //
156  // carbon_hbond_deriv_.dimension( carbon_hbond_parameter_.size1(), carbon_hbond_parameter_.size2() );
157  // carbon_hbond_deriv_ = 0.0;
158  // for (Size i = 1; i <= carbon_hbond_parameter_.size1(); i++ ) {
159  // for (Size j = 1; j < carbon_hbond_parameter_.size2(); j++ ) {
160  // carbon_hbond_deriv_(i,j) = ( carbon_hbond_parameter_(i,j+1) - carbon_hbond_parameter_(i,j) )/bin_width_;
161  // }
162  // }
163 }
164 
165 
166 //////////////////////////////////////////////////////////////////
167 Real
169  Vector const & r_vec,
170  Vector const & z_i /*unit vector pointing from donor to its connected hydrogen*/,
171  bool const & update_deriv,
172  Vector & deriv_vector
173 ) const
174 {
175 
176  Real const r = r_vec.length();
177  Real const z = dot( z_i, r_vec );
178  Real const cos_kappa = z / r;
179 
180  //Orientation dependence
181  Real angle_fade_value( 1.0 ), angle_fade_deriv( 0.0 );
182  core::scoring::rna::get_fade_correction( cos_kappa, rna_cos_theta_cutoff_, 1.5, rna_cos_theta_fade_zone_, angle_fade_value, angle_fade_deriv );
183  Real score = angle_fade_value;
184 
185  //Distance dependence
186  Real const d_H_A = r_vec.length();
187 
188  Real const scaled_dist_H_A = d_H_A/ rna_ch_o_bond_distance_ ;
189  Real const lj_style_distance_dependence = ( 1.0/std::pow(scaled_dist_H_A, 8) - 2.0/std::pow(scaled_dist_H_A, 4) );
190  score *= lj_style_distance_dependence;
191 
192  Real distance_fade_value( 1.0 ), distance_fade_deriv( 0.0 );
193  core::scoring::rna::get_fade_correction( d_H_A, 0, max_dist_, 0.5, distance_fade_value, distance_fade_deriv );
194  score *= distance_fade_value;
195 
196  if ( update_deriv ) {
197  Real const dEdcoskappa( angle_fade_deriv * lj_style_distance_dependence);
198 
199  Real dEdr = angle_fade_value * distance_fade_value * ( -8.0/rna_ch_o_bond_distance_ ) * ( 1.0/std::pow( scaled_dist_H_A, 9) - 1.0/std::pow( scaled_dist_H_A, 5) );
200  dEdr += angle_fade_value * distance_fade_deriv * lj_style_distance_dependence;
201 
202  //Coordinate system ... z points along donor-hydrogen vector. x is orthogonal, and points towards acceptor.
203  Vector x_i = r_vec - z_i * dot(r_vec,z_i);
204  Real const x = x_i.length();
205  x_i = x_i.normalize();
206 
207  Real const dEdx = dEdr * (x/r) + ( - x * z ) * dEdcoskappa / (r * r * r);
208  Real const dEdz = dEdr * (z/r) + ( r*r - z*z) * dEdcoskappa / (r * r * r);
209 
210  deriv_vector = dEdx * x_i + dEdz * z_i;
211 
212  }
213 
214  return score;
215 
216 }
217 
218 /////////////////////////////////////////////////////////////////////////////////////////
219 Real
221  Size const & atom_type_index,
222  Vector const & H_A_vector,
223  Vector const & D_H_vector,
224  Vector const & B_A_vector,
225  bool calculate_deriv,
226  Vector & deriv_vector
227 ) const
228 {
229  deriv_vector = 0.;
230 
231  Real dist_H_A = H_A_vector.length();
232  Vector H_A_norm_vector ( H_A_vector ); H_A_norm_vector.normalize();
233  Vector D_H_norm_vector ( D_H_vector ); D_H_norm_vector.normalize();
234  Vector B_A_norm_vector ( B_A_vector ); B_A_norm_vector.normalize();
235 
236  Real neg_cos_theta = dot ( H_A_norm_vector, D_H_norm_vector );
237  Real neg_cos_psi = -dot ( H_A_norm_vector, B_A_norm_vector );
238 
239  Size const carbon_donor_index( standard_atomtype_to_carbon_donor_index_( atom_type_index ) );
240  if ( carbon_donor_index == 0 ) return 0.0;
241 
242  Real dist_value( 0.0 );
243  Real dEdHA( 0.0 );
244  // We need to interpolate
246  carbon_hbond_parameter_[ carbon_donor_index ], bin_width_,
247  dist_H_A, dist_value, dEdHA );
248 
249  Real theta_fade_value( 1.0 ), theta_fade_deriv( 0.0 );
250  Real psi_fade_value( 1.0 ), psi_fade_deriv( 0.0 );
251  core::scoring::rna::get_fade_correction( neg_cos_theta, 0.5, 1.5, 0.2, theta_fade_value, theta_fade_deriv );
252  core::scoring::rna::get_fade_correction( neg_cos_psi, 0.4, 1.5, 0.2, psi_fade_value, psi_fade_deriv );
253 
254  Real const value( dist_value * theta_fade_value * psi_fade_value );
255 
256  if ( ! calculate_deriv ) return value;
257 
258  deriv_vector = -dEdHA * theta_fade_value * psi_fade_value * H_A_norm_vector;
259 
260  Real neg_sin_theta = -(cross(D_H_norm_vector, H_A_norm_vector)).length();
261  Vector theta_i = -cross( cross(D_H_norm_vector, H_A_norm_vector), H_A_norm_vector);
262  theta_i.normalize();
263  Vector theta_fade_gradient = (1./ dist_H_A) * theta_fade_deriv * neg_sin_theta * theta_i;
264  deriv_vector += dist_value * psi_fade_value * theta_fade_gradient;
265 
266  Real neg_sin_psi = -(cross(B_A_norm_vector, H_A_norm_vector)).length();
267  Vector psi_i = cross( cross(B_A_norm_vector, H_A_norm_vector), H_A_norm_vector);
268  psi_i.normalize();
269  Vector psi_fade_gradient = (1. / dist_H_A) * psi_fade_deriv * neg_sin_psi * psi_i;
270  deriv_vector += dist_value * theta_fade_value * psi_fade_gradient;
271 
272  //Vector H_A_vector_incr = H_A_vector + 0.01 * psi_i;
273  //Vector H_A_norm_vector_incr(H_A_vector_incr); H_A_norm_vector_incr.normalize();
274  //Real neg_cos_psi_incr = -dot ( H_A_norm_vector_incr, B_A_norm_vector );
275  //Real psi_fade_value_incr( 1.0 ), psi_fade_deriv_incr( 0.0 );
276  //core::scoring::rna::get_fade_correction( neg_cos_psi_incr, 0.3, 1.5, 0.3, psi_fade_value_incr, psi_fade_deriv_incr );
277  //std::cout
278  //<< " incr = " << std::setw(8) << std::fixed << std::setprecision(5) << (neg_cos_psi_incr - neg_cos_psi)
279  //<< " ∆E(psi) = " << std::setw(8) << std::fixed << std::setprecision(5) << (psi_fade_value_incr - psi_fade_value)
280  //<< " psi = " << std::setw(8) << std::fixed << std::setprecision(5) << psi_i
281  //<< " -cos(psi) = " << std::setw(8) << std::fixed << std::setprecision(5) << neg_cos_psi
282  //<< " -sin(psi) = " << std::setw(8) << std::fixed << std::setprecision(5) << neg_sin_psi
283  //<< " psi_fade_deriv1 = " << std::setw(8) << std::fixed << std::setprecision(5) << -(0.01 / dist_H_A) * psi_fade_deriv * neg_sin_psi
284  //<< " psi_fade_deriv2 = " << std::setw(8) << std::fixed << std::setprecision(5) << -(0.01) * psi_fade_deriv * neg_sin_psi
285  //<< " psi_fade_deriv3 = " << std::setw(8) << std::fixed << std::setprecision(5) << -(0.01) * psi_fade_deriv
286  //<< std::endl;
287 
288  //∇{f(r)*g(theta)} = g(theta)∇f(r) + f(r)∇g(theta)
289  //∇g(theta) = 1/r * ∂g(theta)/∂theta * theta_i
290  //∂g(theta)/∂theta = -sin(theta) * theta_fade_deriv
291  //theta_i = normalize(D_H_i X H_A_i) X H_A_i
292 
293  // Real comparison_energy( 0.0 );
294  // Size const bin = static_cast<Size> ( dist_H_A / bin_width_ ) + 1;
295  // if ( bin <= num_bins_ ) comparison_energy = carbon_hbond_parameter_[carbon_donor_index]( bin );
296  // if ( value != 0.0 ){
297  // std::cout << "COMPARE: " << value << " " << comparison_energy << std::endl;
298  // }
299  // value = comparison_energy;
300 
301  return value;
302 }
303 
304 /// @details Locally allocated deriv_vector is passed by reference into the more general implementation
305 /// of the get_potential function; moreover, the calculate-derivative flag is set to false in that call.
306 /// This is the "evaluate only the score" interface to the chbond potential.
307 Real
309  Size const & atom_type_index,
310  Vector const & H_A_vector, //vector of hydrogen to acceptor
311  Vector const & D_H_vector, //vector of donor hv atom to hydrogen
312  Vector const & B_A_vector //vector of acceptor's base atom to acceptor
313 ) const
314 {
315  Vector deriv_vector;
316  return get_potential(atom_type_index, H_A_vector, D_H_vector, B_A_vector, false, deriv_vector);
317 }
318 
319 
320 } // namespace carbon_hbonds
321 } // namespace scoring
322 } // namespace core
323