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