Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MMLJEnergyInter.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/MMLJEnergyInter.hh
11 /// @brief molecular mechanics lj energy
12 /// @author P. Douglas Renfrew (renfrew@unc.edu)
13 
14 // Unit headers
18 
20 
21 // Project headers
23 
26 
27 #include <core/pose/Pose.hh>
28 
32 
35 
36 #include <core/scoring/Energies.hh>
37 
39 
40 #include <basic/prof.hh>
41 
43 
51 
56 // AUTO-REMOVED #include <core/scoring/etable/etrie/TrieCountPair1BC4.hh>
58 // AUTO-REMOVED #include <core/scoring/etable/etrie/TrieCountPairNone.hh>
59 
60 //#include <core/pack/rotamer_set/RotamerSetFactory.hh>
61 
62 // Numeric headers
63 #include <numeric/xyzVector.hh>
64 
65 // C++ headers
66 #include <iostream>
67 
69 #include <utility/vector1.hh>
70 
71 
72 namespace core {
73 namespace scoring {
74 namespace methods {
75 
76 /// @details This must return a fresh instance of the MMTorsionEnergy class,
77 /// never an instance already in use
81 ) const {
82  return new MMLJEnergyInter;
83 }
84 
87  ScoreTypes sts;
88  sts.push_back( mm_lj_inter_atr );
89  sts.push_back( mm_lj_inter_rep );
90  return sts;
91 }
92 
95  potential_( scoring::ScoringManager::get_instance()->get_MMLJEnergyTable() )
96 {}
97 
98 /// clone
101 {
102  return new MMLJEnergyInter();
103 }
104 
105 void
107  pose::Pose & pose,
108  ScoreFunction const & sfxn,
109  kinematics::MinimizerMapBase const & min_map
110 ) const
111 {
112  // taken for the most part from BaseETableEnergy.hh
113 
114  if ( pose.energies().use_nblist() ) {
115  // stash our nblist inside the pose's energies object
116  Energies & energies( pose.energies() );
117 
118  // get a reference to the MMLJLibrary we are using
120 
121  // setup the atom-atom nblist
122  NeighborListOP nblist( new NeighborList(
123  min_map.domain_map(),
124  library.nblist_dis2_cutoff_XX(),
125  library.nblist_dis2_cutoff_XH(),
126  library.nblist_dis2_cutoff_HH())
127  );
128 
129  if ( pose.energies().use_nblist_auto_update() ) {
130  // setting this to one angstrom fudge factor
131  nblist->set_auto_update( 1 ); // MAGIC NUMBER
132  }
133  // this partially becomes the MMLJEnergy classes's responsibility
134  nblist->setup( pose, sfxn, *this );
135 
136  energies.set_nblist( EnergiesCacheableDataType::MM_LJ_INTER_NBLIST, nblist );
137  //std::cout << "In MMLJEnergyInter setup_for_minimizing()" << std::endl;
138  }
139 }
140 
141 // The MMLJEnergyInter method stores a vector of rotamer trie objects in the Energies
142 // object for use in rapid rotamer/background energy calculations. Overrides default
143 // do-nothing behavior.
144 void
146  pose::Pose & pose,
147  utility::vector1< bool > const &,
149 ) const
150 {
151  using namespace trie;
152 
153  TrieCollectionOP tries = new TrieCollection;
154  tries->total_residue( pose.total_residue() );
155  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
156  // Do not compute energy for virtual residues.
157  if ( pose.residue(ii).aa() == core::chemical::aa_vrt) continue;
158 
159  RotamerTrieBaseOP one_rotamer_trie = create_rotamer_trie( pose.residue( ii ), pose );
160  tries->trie( ii, one_rotamer_trie );
161  }
163 
164 }
165 
166 /// @brief create a rotamer trie for a particular set, deciding upon the kind of count pair data that
167 /// needs to be contained by the trie.
168 ///
171  conformation::RotamerSetBase const & rotset,
172  pose::Pose const & // will be need to create tries for disulfides
173 ) const
174 {
175  using namespace trie;
176  using namespace etable::etrie;
177  using namespace core::scoring::mm::mmtrie;
178 
179  CPDataCorrespondence cpdata_map( create_cpdata_correspondence_for_rotamerset( rotset ) );
180  if ( cpdata_map.n_entries() == 1 || cpdata_map.n_entries() == 0 /* HACK! */ ) {
181  MMEnergyTableAtom at; CountPairData_1_1 cpdat;
182  return create_trie( rotset, at, cpdat, cpdata_map, hydrogen_interaction_cutoff() );
183  } else if ( cpdata_map.n_entries() == 2 ) {
184  MMEnergyTableAtom at; CountPairData_1_2 cpdat;
185  return create_trie( rotset, at, cpdat, cpdata_map, hydrogen_interaction_cutoff() );
186  } else if ( cpdata_map.n_entries() == 3 ) {
187  MMEnergyTableAtom at; CountPairData_1_3 cpdat;
188  return create_trie( rotset, at, cpdat, cpdata_map, hydrogen_interaction_cutoff() );
189  } else {
190  std::cerr << "Unsupported number of residue connections in trie construction." << std::endl;
191  utility_exit();
192  return 0;
193  }
194 }
195 
198  conformation::Residue const & res,
199  pose::Pose const & // will be need to create tries for disulfides
200 ) const
201 {
202  using namespace trie;
203  using namespace etable::etrie;
204  using namespace core::scoring::mm::mmtrie;
205 
206  CPDataCorrespondence cpdata_map( create_cpdata_correspondence_for_rotamer( res ) );
207  if ( cpdata_map.n_entries() == 1 || cpdata_map.n_entries() == 0 /* HACK! */ ) {
208  MMEnergyTableAtom at; CountPairData_1_1 cpdat;
209  return create_trie( res, at, cpdat, cpdata_map, hydrogen_interaction_cutoff() );
210  } else if ( cpdata_map.n_entries() == 2 ) {
211  MMEnergyTableAtom at; CountPairData_1_2 cpdat;
212  return create_trie( res, at, cpdat, cpdata_map, hydrogen_interaction_cutoff() );
213  } else if ( cpdata_map.n_entries() == 3 ) {
214  MMEnergyTableAtom at; CountPairData_1_3 cpdat;
215  return create_trie( res, at, cpdat, cpdata_map, hydrogen_interaction_cutoff() );
216  } else {
217  std::cerr << "Unsupported number of residue connections in trie construction." << std::endl;
218  utility_exit();
219  return 0;
220  }
221 }
222 
223 
224 // @brief Creates a rotamer trie for the input set of rotamers and stores the trie
225 // in the rotamer set.
226 void
228  pose::Pose const & pose,
230 ) const
231 {
232  trie::RotamerTrieBaseOP rottrie = create_rotamer_trie( set, pose );
234 }
235 
236 // @brief Updates the cached rotamer trie for a residue if it has changed during the course of
237 // a repacking
238 void
240  pose::Pose & pose,
241  Size resid
242 ) const
243 {
244  using namespace trie;
245 
246  trie::RotamerTrieBaseOP one_rotamer_trie = create_rotamer_trie( pose.residue( resid ), pose );
247 
248  // grab non-const & of the cached tries and replace resid's trie with a new one.
249  TrieCollection & trie_collection
250  ( static_cast< TrieCollection & > (pose.energies().data().get( EnergiesCacheableDataType::MM_LJ_TRIE_COLLECTION )));
251  trie_collection.trie( resid, one_rotamer_trie );
252 
253 }
254 
255 ///
256 bool
258 {
259  return false;
260 }
261 
262 void
264  conformation::Residue const & rsd1,
265  conformation::Residue const & rsd2,
266  pose::Pose const & pose,
267  ScoreFunction const & scrfxn,
268  EnergyMap & emap
269 ) const
270 {
271  using namespace chemical;
272  using namespace conformation;
273  using namespace etable;
274  using namespace count_pair;
275 
276  Real total_rep( 0.0 ), total_atr( 0.0 );
277 
278  // get residue info
279  ResidueType const & rsd1type( rsd1.type() );
280  ResidueType const & rsd2type( rsd2.type() );
281  Size const & rsd1natom = rsd1type.natoms();
282  Size const & rsd2natom = rsd2type.natoms();
283 
284  // get count pair function
285  //CountPairFunctionOP cpfxn = CountPairFactory::create_count_pair_function( rsd1, rsd2, CP_CROSSOVER_3 );
286  CountPairFunctionCOP cpfxn( (*this).get_count_pair_function( rsd1, rsd2, pose, scrfxn ) );
287 
288  // iterate over all pairs of atom between the residues
289  for ( int i = 1, i_end = rsd1natom; i <= i_end; ++i ) {
290  conformation::Atom const & atom1( rsd1.atom(i) );
291  for ( int j = 1, j_end = rsd2natom; j <= j_end; ++j ) {
292  conformation::Atom const & atom2( rsd2.atom(j) );
293 
294  Real weight(1.0); // unused
295  Size path_dist(0);
296 
297  // ask count pair if we should score it
298  if ( cpfxn->count( i, j, weight, path_dist ) ) {
299  // calc dist
300  Real dist_squared( atom1.xyz().distance_squared( atom2.xyz() ) );
301  // calc energy
302  Real rep(0), atr(0);
303  potential_.score( rsd1type.atom( i ).mm_atom_type_index(), rsd2type.atom( j ).mm_atom_type_index(), path_dist, dist_squared, rep, atr );
304 
305  if( rep != rep ){
306  std::cout << "REP NAN REP NAN REP NAN" << std::endl;
307  rep = 0;
308  potential_.score( rsd1type.atom( i ).mm_atom_type_index(), rsd2type.atom( j ).mm_atom_type_index(), path_dist, dist_squared, rep, atr );
309  }
310  if( atr != atr ){
311  std::cout << "ATR NAN ATR NAN ATR NAN" << std::endl;
312  atr = 0;
313  potential_.score( rsd1type.atom( i ).mm_atom_type_index(), rsd2type.atom( j ).mm_atom_type_index(), path_dist, dist_squared, rep, atr );
314  }
315 
316  total_rep += rep;
317  total_atr += atr;
318 
319 // std::cout << "INTER"
320 // << " RSD1: " << std::setw(22) << rsd1type.name()
321 // << " ATM1: " << std::setw(4) << rsd1type.atom(i).mm_atom_name()
322 // << " RSD2: " << std::setw(22) << rsd2type.name()
323 // << " ATM2: " << std::setw(4) << rsd2type.atom(j).mm_atom_name()
324 // << " PDST: " << std::setw(3) << path_dist
325 // << " DIST: " << std::setw(8) << std::sqrt(dist_squared)
326 // << " WGHT: " << std::setw(4) << weight
327 // << " REP: " << std::setw(8) << rep
328 // << " ATR: " << std::setw(8) << atr
329 // << std::endl;
330 
331  }
332  }
333  }
334 
335  // add energies to emap
336  emap[ mm_lj_inter_rep ] += total_rep;
337  emap[ mm_lj_inter_atr ] += total_atr;
338 }
339 
340 void
342  id::AtomID const & id,
343  pose::Pose const & pose,
344  kinematics::DomainMap const & /* domain_map*/,
345  ScoreFunction const & /*sfxn*/,
346  EnergyMap const & /*weights*/,
347  Vector & F1,
348  Vector & F2
349 ) const
350 {
351  // get atom1 from id
352  conformation::Atom const & atom1( pose.residue( id.rsd() ).atom( id.atomno() ) );
353 
354  // check to see if we are using the neighbor list
355  if ( pose.energies().use_nblist() ) {
356 
357  // get atom1's neighbors
358  scoring::Energies const & energies( pose.energies() );
359  scoring::NeighborList const & nblist( energies.nblist( EnergiesCacheableDataType::MM_LJ_INTRA_NBLIST ) );
360  scoring::AtomNeighbors const & nbrs( nblist.atom_neighbors( id ) );
361 
362  // iterate over all of atom1's neighbors using the neighbor list
363  for ( scoring::AtomNeighbors::const_iterator iter=nbrs.begin(), iter_end=nbrs.end(); iter != iter_end; ++iter ) {
364  scoring::AtomNeighbor const & nbr( *iter );
365  conformation::Atom const & atom2( pose.residue( nbr.rsd() ).atom( nbr.atomno() ) );
366 
367  // calculate f1 and f2
368  Vector f1( atom1.xyz().cross( atom2.xyz() ) );
369  Vector f2( atom1.xyz() - atom2.xyz() );
370 
371  // get count pair weight from neighbor list
372  //Real const cp_weight( nbr.weight() );
373 
374  // get distance
375  Real dist_squared( atom1.xyz().distance_squared( atom2.xyz() ) );
376 
377  // get path distance
378  Size path_dist( nbr.path_dist() );
379 
380  // calc deriv
381  Real drep(0), datr(0);
382  potential_.deriv_score( atom1.mm_type(), atom2.mm_type(), path_dist, dist_squared, drep, datr );
383 
384  Real deriv( drep + datr );
385 
386  if ( deriv != 0.0 ) {
387  F1 += deriv * f1;
388  F2 += deriv * f2;
389  }
390  }
391  } else {
392  utility_exit_with_message("non-nblist minimize!");
393  }
394 }
395 
396 void
398  conformation::Residue const & ,
399  pose::Pose const & ,
400  ScoreFunction const & ,
401  EnergyMap &
402 ) const {}
403 
404 void
406  conformation::RotamerSetBase const & set1,
407  conformation::RotamerSetBase const & set2,
408  pose::Pose const & pose,
409  ScoreFunction const & sfxn,
410  EnergyMap const & /*weights*/,
411  ObjexxFCL::FArray2D< core::PackerEnergy > & energy_table
412 ) const
413 {
414  assert( set1.resid() != set2.resid() );
415 
416  using namespace methods;
417  using namespace trie;
418  ObjexxFCL::FArray2D< core::PackerEnergy > temp_table1( energy_table );
419  ObjexxFCL::FArray2D< core::PackerEnergy > temp_table2( energy_table );
420 
421  temp_table1 = 0; temp_table2 = 0;
422 
423 // // save weight information so that its available during tvt execution
424 // hackelec_weight_ = weights[ hack_elec ];
425 
426  RotamerTrieBaseCOP trie1( static_cast< trie::RotamerTrieBase const * > ( set1.get_trie( mm_lj_energy_inter_method )() ));
427  RotamerTrieBaseCOP trie2( static_cast< trie::RotamerTrieBase const * > ( set2.get_trie( mm_lj_energy_inter_method )() ));
428 
429  // figure out which trie countPairFunction needs to be used for this set
430  TrieCountPairBaseOP cp = get_count_pair_function_trie( set1, set2, pose, sfxn );
431 
432  /// now execute the trie vs trie algorithm.
433  /// this steps through three rounds of type resolution before finally arriving at the
434  /// actual trie_vs_trie method. The type resolution calls allow the trie-vs-trie algorithm
435  /// to be templated with full type knowledge (and therefore be optimized by the compiler for
436  /// each variation on the count pair data used and the count pair funtions invoked.
437  trie1->trie_vs_trie( *trie2, *cp, *this, temp_table1, temp_table2 );
438 
439  /// add in the energies calculated by the tvt alg.
440  energy_table += temp_table1;
441  //std::cout << "FINISHED evaluate_rotamer_pair_energies" << std::endl;
442 }
443 
444 void
446  conformation::RotamerSetBase const & set,
447  conformation::Residue const & residue,
448  pose::Pose const & pose,
449  ScoreFunction const & sfxn,
450  EnergyMap const & /*weights*/,
452 ) const
453 {
454  using namespace methods;
455  using namespace trie;
456 
457  // allocate space for the trie-vs-trie algorithm
458  utility::vector1< core::PackerEnergy > temp_vector1( set.num_rotamers(), 0.0 );
459  utility::vector1< core::PackerEnergy > temp_vector2( set.num_rotamers(), 0.0 );
460 
461  RotamerTrieBaseCOP trie1( static_cast< RotamerTrieBase const * > ( set.get_trie( mm_lj_energy_inter_method )() ) );
462  RotamerTrieBaseCOP trie2 = ( static_cast< TrieCollection const & >
463  ( pose.energies().data().get( EnergiesCacheableDataType::MM_LJ_TRIE_COLLECTION )) ).trie( residue.seqpos() );
464 
465  // figure out which trie countPairFunction needs to be used for this set
466  TrieCountPairBaseOP cp = get_count_pair_function_trie( pose.residue( set.resid() ), residue, trie1, trie2, pose, sfxn );
467 
468  /// now execute the trie vs trie algorithm.
469  /// this steps through three rounds of type resolution before finally arriving at the
470  /// actual trie_vs_trie method. The type resolution calls allow the trie-vs-trie algorithm
471  /// to be templated with full type knowledge (and therefore be optimized by the compiler for
472  /// each variation on the count pair data used and the count pair funtions invoked.
473  trie1->trie_vs_path( *trie2, *cp, *this, temp_vector1, temp_vector2 );
474 
475  /// add in the energies calculated by the tvt alg.
476  for ( Size ii = 1; ii <= set.num_rotamers(); ++ii ) {
477  energy_vector[ ii ] += temp_vector1[ ii ];
478  }
479  //std::cout << "FINISHED evaluate_rotamer_background_energies" << std::endl;
480 }
481 
482 
483 /// @brief MMLJEnergy does not have an atomic interation threshold
484 Distance
486 {
487  // this will probably screw up other stuff, but it might not since etable goes to zero at 5.5
488  return 7.0;
489 }
490 
491 /// @brief MMLJEnergy is context independent; indicates that no context graphs are required
492 void
494 {}
495 
496 /// @brief required for neighbor list and to be more lke the ETable
499  Size res1,
500  Size res2,
501  pose::Pose const & pose,
502  ScoreFunction const & sfxn
503 ) const
504 {
505  return get_count_pair_function( pose.residue( res1 ), pose.residue( res2 ), pose, sfxn );
506 }
507 
508 /// @brief required for neighbor list and to be more lke the ETable
511  conformation::Residue const & res1,
512  conformation::Residue const & res2,
513  pose::Pose const & /*pose*/,
514  ScoreFunction const & /*sfxn*/
515 ) const
516 {
517  using namespace etable;
518  using namespace count_pair;
519 
520  return CountPairFunctionOP( CountPairFactory::create_count_pair_function( res1, res2, CP_CROSSOVER_3 ) );
521 }
522 
523 /// @brief required for neighbor list and to be more lke the ETable
526  conformation::Residue const & res,
527  pose::Pose const & /*pose*/,
528  ScoreFunction const & /*sfxn*/
529 ) const
530 {
531  using namespace etable;
532  using namespace count_pair;
533 
534  return CountPairFunctionOP( CountPairFactory::create_intrares_count_pair_function( res, CP_CROSSOVER_3 ) );
535 }
536 
537 /// @brief figure out the trie count pair function to use
538 /// Need to refactor this so that the decision "what kind of count pair behavior should I use" can be decoupled
539 /// from class instantiation, and therefore shared between the creation of the trie count pair classes and the regular
540 /// count pair classes
543  conformation::RotamerSetBase const & set1,
544  conformation::RotamerSetBase const & set2,
545  pose::Pose const & pose,
546  ScoreFunction const & sfxn
547 ) const
548 {
549  conformation::Residue const & res1( pose.residue( set1.resid() ) );
550  conformation::Residue const & res2( pose.residue( set2.resid() ) );
551 
552  trie::RotamerTrieBaseCOP trie1( static_cast< trie::RotamerTrieBase const * > ( set1.get_trie( methods::mm_lj_energy_inter_method )() ));
553  trie::RotamerTrieBaseCOP trie2( static_cast< trie::RotamerTrieBase const * > ( set2.get_trie( methods::mm_lj_energy_inter_method )() ));
554 
555  return get_count_pair_function_trie( res1, res2, trie1, trie2, pose, sfxn );
556 }
557 
558 
561  conformation::Residue const & res1,
562  conformation::Residue const & res2,
565  pose::Pose const &,
566  ScoreFunction const &
567 ) const
568 {
569  using namespace etable::count_pair;
570  using namespace trie;
571  using namespace etable::etrie;
572 
573  TrieCountPairBaseOP tcpfxn;
574 
575  CPResidueConnectionType connection( CountPairFactory::determine_residue_connection( res1, res2 ) );
576  Size conn1 = trie1->get_count_pair_data_for_residue( res2.seqpos() );
577  Size conn2 = trie2->get_count_pair_data_for_residue( res1.seqpos() );
578 
579  if ( connection != CP_NO_BONDS ) {
580  tcpfxn = new TrieCountPair1BC3( conn1, conn2 );
581  } else {
582  tcpfxn = new TrieCountPairAll;
583  }
584  return tcpfxn;
585 
586 }
587 
588 void
590  conformation::Residue const & rsd1,
591  conformation::Residue const & rsd2,
592  pose::Pose const & pose,
593  ScoreFunction const & sfxn,
594  EnergyMap & emap
595 ) const
596 {
597  EnergyMap tbemap;
598  MMLJEnergyInter::residue_pair_energy( rsd1, rsd2, pose, sfxn, tbemap );
599  emap[ mm_lj_inter_rep ] += tbemap[ mm_lj_inter_rep ];
600  emap[ mm_lj_inter_atr ] += tbemap[ mm_lj_inter_atr ];
601 }
602 
603 void
605  conformation::Residue const & rsd1,
606  conformation::Residue const & rsd2,
607  pose::Pose const & pose,
608  ScoreFunction const & sfxn,
609  EnergyMap & emap
610 ) const
611 {
612  // this is not correct, it should iterate over the backbone atoms only
613  // but I wanna see if it works
614  EnergyMap tbemap;
615  MMLJEnergyInter::residue_pair_energy( rsd1, rsd2, pose, sfxn, tbemap );
616  emap[ mm_lj_inter_rep ] += tbemap[ mm_lj_inter_rep ];
617  emap[ mm_lj_inter_atr ] += tbemap[ mm_lj_inter_atr ];
618 }
621 {
622  return 1; // Initial versioning
623 }
624 
625 } // namespace methods
626 } // namespace scoring
627 } // namespace core