Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
HackElecEnergyAroAll.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/hackelec/HackElecEnergyAroAll.cc
11 /// @brief Electrostatics energy method for aromatic side chain (stand-in for pi/pi interactions).
12 /// @author Rhiju Das
13 
14 
15 // Unit headers
18 
19 // Package headers
21 #include <core/scoring/Energies.hh>
25 
26 // Project headers
29 #include <core/pose/Pose.hh>
31 
32 #include <core/id/AtomID.hh>
33 #include <utility/vector1.hh>
34 
35 // ObjexxFCL headers
36 
37 // C++
38 
39 
40 /////////////////////////////////////////////////////////////////////////////////////////
41 // Quick version of hack_elec for just aromatic residues in proteins.
42 // This could be made much faster (for packing) by using Andrew Leaver-Fay's trie stuff,
43 // copying/pasting from HackElecEnergy.cc. For now, I just went with what I knew.
44 // -- Rhiju, Nov. 2009
45 //
46 // Modified aroaro to calculate electrostatic interaction between an aromatic residue
47 // and all surrounding atoms from other residues. Derivitives are not implemented.
48 // -- James Gleixner, April 2011
49 
50 /////////////////////////////////////////////////////////////////////////////////////////
51 ///
52 /// Hacky (hence the name) implementation of 10r dielectric model, cutoff at 5.5A
53 ///
54 ///
55 
56 //
57 // alternatives: WARSHEL (from ligand.cc)
58 // E = 322.0637*q1*q2/r/e(r)
59 // if ( r < 3 ) e(r) = 16.55
60 // else e(r) = 1 + 60*(1-exp(-0.1*r))
61 // Warshel, A. Russell, S. T., Q. Rev. Biophys., 1984, 17, 283-422
62 //
63 //
64 // sigmoidal dielectric: (hingerty 1985)
65 //
66 // e(r) = D - (D-D0)/2 [ (rS)**2 + 2rS + 2]exp(-rS)
67 // with eg:
68 // D = 78, D0 = 1, S = 0.3565 (rouzina&bloomfield)
69 // D = 80, D0 = 4, S = 0.4 (rohs)
70 
71 namespace core {
72 namespace scoring {
73 namespace hackelec {
74 
75 
76 /// @details This must return a fresh instance of the HackElecEnergyAroAll class,
77 /// never an instance already in use
80  methods::EnergyMethodOptions const & options
81 ) const {
82  return new HackElecEnergyAroAll( options );
83 }
84 
87  ScoreTypes sts;
88  sts.push_back( hack_elec_aro_all );
89  return sts;
90 }
91 
92 ////////////////////////////////////////////////////////////////////////////
94  methods::EnergyMethodOptions const & options
95 ):
96  parent( options )
97 {
99 }
100 
101 
102 ////////////////////////////////////////////////////////////////////////////
104  parent( src )
105 {
107 }
108 
109 /// clone
112 {
113  return new HackElecEnergyAroAll( *this );
114 }
115 
116 ///
117 void
119 {
121 }
122 
123 ///
124 void
126 {
128 }
129 
130 
131 // The HackElectEnergy method stores a vector of rotamer trie objects in the Energies
132 // object for use in rapid rotamer/background energy calculations. Overrides default
133 // do-nothing behavior.
134 void
136  pose::Pose &,
137  utility::vector1< bool > const &,
139 ) const
140 {
141  /// noop -- this noop is essential for overriding the base class behavior.
142 }
143 
144 // @brief Creates a rotamer trie for the input set of rotamers and stores the trie
145 // in the rotamer set.
146 void
148  pose::Pose const &,
150 ) const
151 {
152  /// noop -- this noop is essential for overriding the base class behavior.
153 }
154 
155 
156 // @brief Updates the cached rotamer trie for a residue if it has changed during the course of
157 // a repacking
158 void
160  pose::Pose &,
161  Size
162 ) const
163 {
164  /// noop -- this noop is essential for overriding the base class behavior.
165 }
166 
167 /////////////////////////////////////////////////////////////////////////////
168 // scoring
169 /////////////////////////////////////////////////////////////////////////////
170 
171 ///
172 void
174  conformation::Residue const & rsd1,
175  conformation::Residue const & rsd2,
176  pose::Pose const &,
177  ScoreFunction const &,
178  EnergyMap & emap
179 ) const
180 {
181  // Aromatic means: PHE, TRP, TYR (not HIS, currently).
182  if ( rsd1.is_aromatic() ) {
183  residue_pair_energy_aro_aro( rsd1, rsd2, emap ); // Only checks to make sure one of the residues is aromatic
184  }
185  //std::cout << rsd1.seqpos() << ' ' << rsd2.seqpos() << ' ' << score << std::endl;
186 }
187 
188 
189 //////////////////////////////////////
190 bool atom_is_aro2( conformation::Residue const & rsd, Size const i )
191 {
192  /////////////////////////////////////////////////////////////////////////////////////////////////////////
193  // String lookup is slow, but overall won't be too bad here because there won't be many aro/aro pairs.
194  // However, we could be fancy and do a one-pass lookup at the beginning of the function...
195  /////////////////////////////////////////////////////////////////////////////////////////////////////////
196  std::string const atom_type_name( rsd.atom_type( i ).name() );
197  if ( atom_type_name == "aroC" ||
198  atom_type_name == "Ntrp" ||
199  atom_type_name == "Nhis" ||
200  atom_type_name == "Oaro" ||
201  atom_type_name == "Haro" ) return true;
202 
203  return false;
204 }
205 
206 //////////////////////////////////////////////////////////////////////////////////
207 // Following copies a little code, but at least separates out this inelegant and
208 // probably useless RNA stuff from the usual stuff.
209 Real
211  conformation::Residue const & rsd1,
212  conformation::Residue const & rsd2,
213  EnergyMap & emap
214 ) const
215 {
216  //assert( rsd1.is_aromatic() );
217  //assert( rsd2.is_aromatic() );
218 
219  using namespace etable::count_pair;
220 
221  Real total_score( 0.0 );
222 
223  CountPairFunctionOP cpfxn =
224  CountPairFactory::create_count_pair_function( rsd1, rsd2, CP_CROSSOVER_4 );
225 
226  for ( Size i=1, i_end = rsd1.natoms(); i<= i_end; ++i ) {
227  Vector const & i_xyz( rsd1.xyz(i) );
228  Real const i_charge( rsd1.atomic_charge(i) );
229 
230  if ( !atom_is_aro2( rsd1, i ) ) continue;
231 
232 //debug output
233 //std::cerr << "residue i " << rsd1.seqpos() << " is aromatic: " << rsd1.is_aromatic() << std::endl;
234 //std::cerr << "residue j " << rsd2.seqpos() << " is aromatic: " << rsd2.is_aromatic() << std::endl;
235 
236  if ( i_charge == 0.0 ) continue;
237 
238 
239  for ( Size j=1, j_end = rsd2.natoms(); j<= j_end; ++j ) {
240 
241  // if ( !atom_is_aro2( rsd2, j ) ) continue;
242 
243  Real const j_charge( rsd2.atomic_charge(j) );
244  if ( j_charge == 0.0 ) continue;
245  Real weight(1.0);
246  Size path_dist( 0 );
247  if ( cpfxn->count( i, j, weight, path_dist ) ) {
248  Real score = weight *
249  eval_atom_atom_hack_elecE( i_xyz, i_charge, rsd2.xyz(j), j_charge);
250 
251  total_score += score;
252  emap[ hack_elec_aro_all ] += score;
253 //debug output
254  //std::cout << "hackelecenergy: " << rsd1.seqpos() << " " << rsd1.atom_name(i) << " " << rsd2.seqpos() << " " << rsd2.atom_name(j) << " is: " << score << std::endl;
255 
256  }
257  }
258  }
259 
260  return total_score;
261 
262 }
263 
264 void
266  conformation::RotamerSetBase const & set1,
267  conformation::RotamerSetBase const & set2,
268  pose::Pose const & pose,
269  ScoreFunction const & sfxn,
270  EnergyMap const & weights,
271  ObjexxFCL::FArray2D< core::PackerEnergy > & energy_table
272 ) const
273 {
274  if ( set1.num_rotamers() >= 1 && set2.num_rotamers() >= 1 &&
275  set1.rotamer(1)->is_aromatic() && set2.rotamer(1)->is_aromatic() ) {
276  grandparent::evaluate_rotamer_pair_energies( set1, set2, pose, sfxn, weights, energy_table );
277  } // else, non aromatic/aromatic interaction; early return
278 }
279 
280 void
282  conformation::RotamerSetBase const & set,
283  conformation::Residue const & residue,
284  pose::Pose const & pose,
285  ScoreFunction const & sfxn,
286  EnergyMap const & weights,
288 ) const
289 {
290  if ( set.num_rotamers() >= 1 && set.rotamer(1)->is_aromatic() && residue.is_aromatic() ) {
291  grandparent::evaluate_rotamer_background_energies( set, residue, pose, sfxn, weights, energy_vector );
292  } // else, non aromatic/aromatic interaction; early return
293 }
294 
295 
296 void
298  id::AtomID const & atom_id,
299  pose::Pose const & pose,
300  kinematics::DomainMap const & domain_map,
301  ScoreFunction const &,
302  EnergyMap const & weights,
303  Vector & F1,
304  Vector & F2
305  ) const
306 {
307  using namespace etable::count_pair;
308 
309  // what is my charge?
310  Size const pos1( atom_id.rsd() );
311  Size const i ( atom_id.atomno() );
312  conformation::Residue const & rsd1( pose.residue( pos1 ) );
313 
314  if ( ! rsd1.is_aromatic() ) return;
315 
316  Real const i_charge( rsd1.atomic_charge( i ) );
317  int const pos1_map( domain_map( pos1 ) );
318  bool const pos1_fixed( pos1_map != 0 );
319 
320  if ( i_charge == 0.0 ) return;
321 
322  //Vector const & i_xyz( rsd1.xyz(i) );
323 
324  // cached energies object
325  Energies const & energies( pose.energies() );
326 
327  // the neighbor/energy links
328  EnergyGraph const & energy_graph( energies.energy_graph() );
329 
330 // kinematics::DomainMap const & domain_map( energies.domain_map() );
331 // bool const pos1_fixed( !energies.res_moved( pos1 ) );
332 // assert( pos1_fixed == ( domain_map(pos1) != 0 ) ); // this is probably not generally true but I'm curious
333 
334  // loop over *all* nbrs of rsd1 (not just upper or lower)
336  iru = energy_graph.get_node( pos1 )->const_edge_list_begin(),
337  irue = energy_graph.get_node( pos1 )->const_edge_list_end();
338  iru != irue; ++iru ) {
339  //EnergyEdge const * edge( static_cast< EnergyEdge const *> (*iru) );
340  //Size const pos2( edge->get_second_node_ind() );
341  Size const pos2( (*iru)->get_other_ind( pos1 ) );
342 
343  if ( pos1_fixed && pos1_map == domain_map( pos2 ) ) continue; // fixed wrt one another
344 
345  conformation::Residue const & rsd2( pose.residue( pos2 ) );
346 
347  assert( pos2 != pos1 );
348 
349  if ( rsd2.is_aromatic() ) {
350  eval_atom_derivative_aro_aro( rsd1, i, rsd2, weights, F1, F2 );
351  }
352 
353  } // loop over nbrs of rsd1
354 
355 }
356 
357 
358 //////////////////////////////////////////////////
359 void
361  conformation::Residue const & rsd1,
362  Size const & i,
363  conformation::Residue const & rsd2,
364  EnergyMap const & weights,
365  Vector & F1,
366  Vector & F2
367  ) const
368 {
369 
370  using namespace etable::count_pair;
371 
372  CountPairFunctionOP cpfxn = CountPairFactory::create_count_pair_function( rsd1, rsd2, CP_CROSSOVER_4 );
373 
374  Real const i_charge( rsd1.atomic_charge( i ) );
375  Vector const & i_xyz( rsd1.xyz(i) );
376 
377  // NOTE THAT is_base, is_sugar, and is_phosphate contains MAGIC NUMBERS (for speed!)
378  // Might be better to make it precomputed as part of the residue_type definition?
379  //This repeats some unnecessary stuff, but hey, derivatives don't have to be that fast.
380  if ( !atom_is_aro2( rsd1, i ) ) return;
381 
382  for ( Size j=1, j_end = rsd2.natoms(); j<= j_end; ++j ) {
383 
384  if ( !atom_is_aro2( rsd2, j ) ) continue;
385 
386  Real const j_charge( rsd2.atomic_charge(j) );
387  if ( j_charge == 0.0 ) continue;
388 
389  Real weight(1.0);
390  Size path_dist( 0 );
391  if ( cpfxn->count( i, j, weight, path_dist ) ) {
392  Vector const & j_xyz( rsd2.xyz(j) );
393  Vector const f2( i_xyz - j_xyz );
394  Real const dis2( f2.length_squared() );
395  Real const dE_dr_over_r = weight *
396  eval_dhack_elecE_dr_over_r( dis2, i_charge, j_charge );
397 
398  if ( dE_dr_over_r != 0.0 ) {
399  Vector const f1( i_xyz.cross( j_xyz ) );
400 
401  F1 += weights[ hack_elec_aro_all ] * dE_dr_over_r * f1;
402  F2 += weights[ hack_elec_aro_all ] * dE_dr_over_r * f2;
403  }
404 
405  }
406  }
407 }
408 
409 
410 /// @brief HackElecEnergyAroAll is context independent; no context graphs required
411 void
413 {
414 }
417 {
418  return 1; // Initial versioning
419 }
420 
421 
422 
423 }
424 }
425 }