Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ScoreFunction.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/ScoreFunction.cc
11 /// @brief ScoreFunction class definition.
12 /// @author Stuart G. Mentzer (Stuart_Mentzer@objexx.com)
13 /// @author Kevin P. Hinshaw (KevinHinshaw@gmail.com)
14 /// @author Modified by Sergey Lyskov
15 
16 
17 // Unit headers
19 
20 // C/C++ headers
21 #include <algorithm>
22 #include <string>
23 #include <vector>
24 
25 // External headers
26 // AUTO-REMOVED #include <boost/format.hpp>
27 #include <boost/algorithm/string/join.hpp>
28 // AUTO-REMOVED #include <boost/math/distributions/normal.hpp>
29 
30 // Package headers
52 #include <core/scoring/Energies.hh>
53 
54 // Project headers
56 #include <core/id/TorsionID.hh>
59 // AUTO-REMOVED #include <core/conformation/symmetry/util.hh>
60 #include <core/pose/Pose.hh>
61 
62 /// Utility headers
63 #include <basic/prof.hh>
64 #include <basic/Tracer.hh>
65 #include <basic/database/open.hh>
66 #include <numeric/random/DistributionSampler.hh>
67 #include <ObjexxFCL/format.hh>
68 #include <utility/io/izstream.hh>
69 #include <utility/string_util.hh>
70 
71 #include <core/id/DOF_ID.hh>
72 #include <utility/vector1.hh>
73 
74 //Auto Headers
76 
77 static basic::Tracer tr("core.scoring");
78 
79 using namespace ObjexxFCL;
80 using namespace ObjexxFCL::fmt;
81 
82 namespace core {
83 namespace scoring {
84 
85 #ifdef USELUA
86 void lregister_ScoreFunction( lua_State * lstate ) {
87  luabind::module(lstate, "core")
88  [
89  luabind::namespace_("scoring")
90  [
91  luabind::class_<ScoreFunction>("ScoreFunction")
92  ]
93  ];
94 }
95 #endif
96 
97 #ifdef APL_TEMP_DEBUG
98 Size n_minimization_sfxn_evals( 0 );
99 #endif
100 
101 ///////////////////////////////////////////////////////////////////////////////
102 ScoreFunction::ScoreFunction()
103 {
104  reset();
105 }
106 
107 
108 ScoreFunction::~ScoreFunction() {}
109 
110 ///////////////////////////////////////////////////////////////////////////////
113 {
114  ScoreFunctionOP new_score_function( new ScoreFunction( *this ) );
115  return new_score_function;
116 }
117 
118 ///////////////////////////////////////////////////////////////////////////////
119 /// @details reset function that can be called either independently or from default
120 /// ScoreFunction creation
121 void
122 ScoreFunction::reset()
123 {
124  score_function_info_current_ = true;
125  score_function_info_ = new ScoreFunctionInfo;
126  any_intrares_energies_ = false;
127  energy_method_options_ = new methods::EnergyMethodOptions;
128  initialize_methods_arrays();
129  weights_.clear();
130 }
131 
132 ///////////////////////////////////////////////////////////////////////////////
133 /// read info from file
134 ///
135 
136 void
137 ScoreFunction::initialize_from_file( std::string const & filename )
138 {
139  reset();
140 
141  add_weights_from_file( filename );
142 }
143 
144 /// Format: { term : weight, ... }
145 std::string ScoreFunction::serialize_weights() const {
146  using std::string;
147  using std::vector;
148 
149  vector<string> tokens;
150  ScoreTypes terms = get_nonzero_weighted_scoretypes();
151  for (ScoreTypes::const_iterator i = terms.begin(); i != terms.end(); ++i) {
152  const ScoreType& term = *i;
153  if (has_nonzero_weight(term)) {
154  tokens.push_back(str(boost::format("%1% : %2%") % term % get_weight(term)));
155  }
156  }
157  return "{" + boost::algorithm::join(tokens, ", ") + "}";
158 }
159 
160 /// @detail Perturbs each non-zero weight independently by adding a Gaussian
161 /// noise with u=0 and sd=weight / 8. Weights are not allowed to become negative.
162 /// - 68% of the time, percent change [0, 12.5)
163 /// - 26% of the time, percent change [12.5, 25)
164 /// - 4% of the time, percent change [25...
165 void ScoreFunction::perturb_weights() {
166  using boost::math::normal;
167  using core::Real;
168  using numeric::random::DistributionSampler;
169 
170  // Perturb the weights of the non-zero score terms
171  ScoreTypes terms = get_nonzero_weighted_scoretypes();
172  for (ScoreTypes::const_iterator i = terms.begin(); i != terms.end(); ++i) {
173  const ScoreType& term = *i;
174  if (has_nonzero_weight(term)) {
175  Real weight = get_weight(term);
176 
177  normal dist(0, weight / 8);
178  DistributionSampler<normal> sampler(dist);
179 
180  Real perturbed_weight = weight + sampler.sample();
181  set_weight(term, std::max(perturbed_weight, 0.0));
182  tr.Debug << name_from_score_type(term) << ": "
183  << weight << " => " << perturbed_weight << std::endl;
184  }
185  }
186 }
187 
188 ///////////////////////////////////////////////////////////////////////////////
189 /// read weights/etc from file, which may be in database directory.
190 /// Does not clear weights beforehand.
191 
192 void
193 ScoreFunction::add_weights_from_file( std::string const & filename )
194 {
195  _add_weights_from_file( find_weights_file(filename, ".wts") );
196 }
197 
198 ///////////////////////////////////////////////////////////////////////////////
199 /// read weights/etc from file. Does not clear weights beforehand.
200 /// no lookup in database directory
201 
202 void
203 ScoreFunction::_add_weights_from_file( std::string const & filename, bool patch/*=false*/ )
204 {
205  utility::io::izstream data( filename );
206  if ( !data.good() ){
207  if ( ! patch ) { utility_exit_with_message( "Unable to open weights file: "+filename ); }
208  else { utility_exit_with_message( "Unable to open weights-patch file: "+filename ); }
209  }
210 
211  std::string line,tag,operation;
212  ScoreType score_type;
213  Real wt;
214  while ( getline( data, line ) ) {
215  std::istringstream l( line );
216  l >> tag;
217  if ( l.fail() || tag[0] == '#' ) continue;
218 
219  // //////////// Property Setting Tags ///////////////////////
220  if ( tag == "ETABLE" ) {
221  l >> tag;
222  set_etable( tag );
223  } else if ( tag == "METHOD_WEIGHTS" ) {
224  l >> score_type;
225  if ( l.fail() ) {
226  utility_exit_with_message( "unrecognized score_type: "+line );
227  }
229  while ( !l.fail() ) {
230  l >> wt;
231  if ( l.fail() ) break;
232  wts.push_back( wt );
233  }
234  energy_method_options_->set_method_weights( score_type, wts );
235  } else if ( tag == "STRAND_STRAND_WEIGHTS" ) {
237  int value;
238  while ( !l.fail() ) {
239  l >> value;
240  if ( l.fail() ) break;
241  values.push_back( value );
242  }
243  if ( values.size() != 2 )
244  utility_exit_with_message( "incorrect number of arguments to STRAND_STRAND_WEIGHTS: " + line );
245  energy_method_options_->set_strand_strand_weights( values[1], values[2] );
246  } else if ( tag == "NO_PROTEIN_PROTEIN_HACK_ELEC" ) {
247  energy_method_options_->exclude_protein_protein_hack_elec( true );
248  } else if ( tag == "NO_MONOMER_HACK_ELEC" ) {
249  energy_method_options_->exclude_monomer_hack_elec( true );
250  } else if ( tag == "INCLUDE_DNA_DNA" ) {
251  energy_method_options_->exclude_DNA_DNA( false );
252  } else if ( tag == "NO_HB_ENV_DEP" ) {
253  energy_method_options_->hbond_options().use_hb_env_dep( false );
254  } else if ( tag == "NO_HB_ENV_DEP_DNA" ) {
255  energy_method_options_->hbond_options().use_hb_env_dep_DNA( false );
256  } else if ( tag == "NO_SMOOTH_HB_ENV_DEP" ) {
257  energy_method_options_->hbond_options().smooth_hb_env_dep( false );
258  } else if ( tag == "NO_BB_DONOR_ACCEPTOR_CHECK" ) {
259  energy_method_options_->hbond_options().bb_donor_acceptor_check( false );
260  } else if ( tag == "COARSE_RNA" ) {
261  std::cout << "ATOM_VDW set to COARSE_RNA" << std::endl;
262  energy_method_options_->atom_vdw_atom_type_set_name( "coarse_rna" );
263  } else if ( tag == "INCLUDE_INTRA_RES_RNA_HB" ) {
264  std::cout << "INCLUDE_INTRA_RES_RNA_HB==true" << std::endl;
265  energy_method_options_->hbond_options().include_intra_res_RNA( true );
266  } else if ( tag == "INCLUDE_HB_DNA_DNA" ) {
267  energy_method_options_->hbond_options().exclude_DNA_DNA( false );
268  } else if ( tag == "BOND_ANGLE_CENTRAL_ATOMS_TO_SCORE" ) {
269  utility::vector1<std::string> central_atoms;
270  std::string central_atom;
271  while ( !l.fail() ) {
272  l >> central_atom;
273  if ( l.fail() ) break;
274  central_atoms.push_back( central_atom );
275  }
276  if ( ! energy_method_options_->bond_angle_residue_type_param_set() ) {
277  energy_method_options_->bond_angle_residue_type_param_set( new core::scoring::mm::MMBondAngleResidueTypeParamSet() );
278  }
279  energy_method_options_->bond_angle_residue_type_param_set()->central_atoms_to_score( central_atoms );
280  } else if ( tag == "BOND_ANGLE_USE_RESIDUE_TYPE_THETA0" ) {
281  if ( ! energy_method_options_->bond_angle_residue_type_param_set() ) {
282  energy_method_options_->bond_angle_residue_type_param_set( new core::scoring::mm::MMBondAngleResidueTypeParamSet() );
283  }
284  energy_method_options_->bond_angle_residue_type_param_set()->use_residue_type_theta0( true );
285  } else if ( tag == "UNFOLDED_ENERGIES_TYPE" ) {
286  std::string type;
287  l >> type;
288  energy_method_options_->unfolded_energies_type( type );
289  } else if ( tag == "HACK_ELEC_MIN_DIS" ) {
290  Real value;
291  l >> value;
292  energy_method_options_->hackelec_min_dis( value );
293  } else if ( tag == "HACK_ELEC_MAX_DIS" ) {
294  Real value;
295  l >> value;
296  energy_method_options_->hackelec_max_dis( value );
297  } else if ( tag == "HACK_ELEC_NO_DIS_DEP_DIE" ) {
298  energy_method_options_->hackelec_no_dis_dep_die( true );
299  } else {
300 
301  // //////////// Regular Weights ///////////////////////
302  l.str( line );
303 
304  if ( ! patch ) {
305 
306  // Weights file parsing
307  l >> score_type >> wt;
308  if ( l.fail() ) {
309  utility_exit_with_message( "bad line in file "+filename+":"+line );
310  }
311  set_weight( score_type, wt );
312 
313  } else {
314 
315  // Patch file parsing
316  l >> score_type >> operation >> wt;
317  if ( l.fail() ) {
318  tr.Error << "could not parse line in patch-file: " << line << std::endl;
319  continue;
320  }
321  if ( operation == "*=" ) {
322  set_weight( score_type, weights_[ score_type ]*wt );
323  } else if ( operation == "=" ) {
324  set_weight( score_type, wt );
325  } else {
326  utility_exit_with_message(
327  "unrecognized scorefunction patch operation "+operation+" in file: "+filename
328  );
329  }
330 
331  } // if ( ! patch )
332  } // if ... else if ... else if ...
333  } // while ( getline( data, line ) )
334 }
335 
336 
337 
338 ///////////////////////////////////////////////////////////////////////////////
339 void
340 ScoreFunction::set_energy_method_options(
342  energy_method_options_in )
343 {
344  energy_method_options_
345  = methods::EnergyMethodOptionsOP( new methods::EnergyMethodOptions( energy_method_options_in ) );
346  //*energy_method_options_ = energy_method_options_in;
347 
348 // Some of the energy methods only know about these options when
349 // they are constructed. So the safest thing is to destroy them and
350 // create them again.
351  reset_energy_methods();
352 
353  score_function_info_current_ = false;
354 }
355 
356 
357 ///////////////////////////////////////////////////////////////////////////////
358 ///////////////////////////////////////////////////////////////////////////////
359 void
360 ScoreFunction::reset_energy_methods()
361 {
362  //Note from rhiju: This is super hacky, but it was Andrew Leaver-Fay's idea.
363  // Zero out the weights ... which
364  // destroys the methods. Then return the weights to their
365  // non-zero values to construct them again from scratch.
366  EnergyMap weights_old( weights_ );
367  for ( Size i = 1; i <= n_score_types; ++i ) {
368  set_weight( ScoreType( i ), 0.0 );
369  }
370  for ( Size i = 1; i <= n_score_types; ++i ) {
371  set_weight( ScoreType( i ), weights_old.get( ScoreType( i ) ) );
372  }
373 
374 }
375 
376 void
377 ScoreFunction::apply_patch_from_file( std::string const & patch_tag )
378 {
379  _add_weights_from_file( find_weights_file(patch_tag, ".wts_patch"), /*patch=*/ true );
380 }
381 
382 
383 /// @brief Given a filename (represented by a std::string), set the e_table for this ScoreFunction.
384 void
385 ScoreFunction::set_etable(
386  std::string const & etable_name
387 )
388 {
389  // ensure that this has been done before the relevant EnergyMethod is created
390  // this needs to be fixed to be smarter
391  // assert( weights_[ fa_atr ] == 0.0 && weights_[ fa_rep ] == 0.0 && weights_[ fa_sol ] == 0.0 );
392  energy_method_options_->etable_type( etable_name );
393  reset_energy_methods();
394  score_function_info_current_ = false;
395 }
396 
397 ///
398 void
399 ScoreFunction::set_method_weights(
400  ScoreType const & t,
401  utility::vector1< Real > const & wts
402 )
403 {
404  // assert( weights_[ t ] == 0.0 );
405  energy_method_options_->set_method_weights( t, wts );
406  reset_energy_methods();
407  score_function_info_current_ = false;
408 }
409 
410 ///////////////////////////////////////////////////////////////////////////////
412 ScoreFunction::operator=( ScoreFunction const & src )
413 {
414  if ( this == &src ) return *this;
415 
416  // copy the weights
417  weights_ = src.weights_;
418 
419  // deep copy of the energy method options
420  energy_method_options_ = new methods::EnergyMethodOptions( * src.energy_method_options_ );
421 
422  // copy the methods:
423  initialize_methods_arrays(); // clears & sizes the arrays
424 
425  for ( AllMethods::const_iterator it = src.all_methods_.begin(),
426  ite = src.all_methods_.end(); it != ite; ++it ) {
427  add_method( (*it)->clone() );
428  }
429  update_intrares_energy_status();
430  assert( check_methods() );
431 
432  /// SL: Fri Jun 29 12:51:25 EDT 2007 @744 /Internet Time/
433  score_function_info_current_ = src.score_function_info_current_;
434  score_function_info_ = new ScoreFunctionInfo( *src.score_function_info_ );
435 
436  any_intrares_energies_ = src.any_intrares_energies_;
437 
438  return *this;
439 }
440 
441 ///////////////////////////////////////////////////////////////////////////////
442 ScoreFunction::ScoreFunction( ScoreFunction const & src ):
443  ReferenceCount()
444 {
445  *this = src;
446 }
447 
448 
449 ///////////////////////////////////////////////////////////////////////////////
450 void
451 ScoreFunction::show( std::ostream & out ) const
452 {
453  out << "ScoreFunction::show():\nweights:";
454  for ( int i=1; i<= n_score_types; ++i ) {
455  if ( weights_[ ScoreType(i) ] != 0.0 ) {
456  out << " (" << ScoreType(i) << ' '<< weights_[ScoreType(i)] << ')';
457  }
458  }
459  out << '\n';
460 
461  out << "energy_method_options: " << *energy_method_options_ << '\n';
462 }
463 
464 ///////////////////////////////////////////////////////////////////////////////
465 void
466 ScoreFunction::merge( const ScoreFunction scorefxn_to_be_merged )
467 {
468  for ( int i=1; i<= n_score_types; ++i ) {
469  core::Real the_weight;
470  the_weight = scorefxn_to_be_merged.get_weight( ScoreType(i) );
471  if ( the_weight != 0.0 ) {
472  set_weight( ScoreType(i), the_weight );
473  }
474  }
475 
476 }
477 
478 ///////////////////////////////////////////////////////////////////////////////
479 void
480 ScoreFunction::show( std::ostream & out, pose::Pose & pose ) const
481 {
482  (*this)(pose); //make sure scores are set
483  out << "------------------------------------------------------------\n";
484  out << " Scores Weight Raw Score Wghtd.Score\n";
485  out << "------------------------------------------------------------\n";
486  float sum_weighted=0.0;
487  for ( int i=1; i<= n_score_types; ++i ) {
488  if ( weights_[ ScoreType(i) ] != 0.0 ) {
489  out << ' ' << LJ(24,ScoreType(i)) << ' '<< F(9,3,weights_[ ScoreType(i) ]) << " "
490  << F(9,3,pose.energies().total_energies()[ ScoreType(i) ] ) << " "
491  << F(9,3, weights_[ ScoreType(i) ] * pose.energies().total_energies()[ ScoreType(i) ] )
492  << '\n';
493  sum_weighted += weights_[ ScoreType(i) ] * pose.energies().total_energies()[ ScoreType(i) ];
494  }
495  }
496  out << "---------------------------------------------------\n";
497  out << " Total weighted score: " << F(9,3,sum_weighted) << '\n';
498 }
499 
500 ///////////////////////// output as show( os, pose ) but without the pose //////////////////////////
501 void
502 ScoreFunction::show_pretty( std::ostream & out ) const {
503  out << "---------------------------------------------\n";
504  out << " Scores Weight \n";
505  out << "---------------------------------------------\n";
506  //float sum_weighted=0.0;
507  for ( int i=1; i<= n_score_types; ++i ) {
508  if ( weights_[ ScoreType(i) ] != 0.0 ) {
509  out << ' ' << LJ(24,ScoreType(i)) << ' '<< F(9,3,weights_[ ScoreType(i) ]) << " "
510  << '\n';
511  }
512  }
513  out << "---------------------------------------------------\n";
514 }
515 
516 ///////////////////////////////////////////////////////////////////////////////
517 void
518 show_detail( std::ostream & out, EnergyMap & energies, EnergyMap weights )
519 {
520  out << "------------------------------------------------------------\n";
521  out << " Scores Weight Raw Score Wghtd.Score\n";
522  out << "------------------------------------------------------------\n";
523  float sum_weighted=0.0;
524  for ( int i=1; i<= n_score_types; ++i ) {
525  if ( weights[ ScoreType(i) ] != 0.0 ) {
526  out << ' ' << LJ(24,ScoreType(i)) << ' '<< F(9,3,weights[ ScoreType(i) ]) << " "
527  << F(9,3,energies[ ScoreType(i) ] ) << " "
528  << F(9,3, weights[ ScoreType(i) ] * energies[ ScoreType(i) ] )
529  << '\n';
530  sum_weighted += weights[ ScoreType(i) ] * energies[ ScoreType(i) ];
531  }
532  }
533  out << "---------------------------------------------------\n";
534  out << " Total weighted score: " << F(9,3,sum_weighted) << '\n';
535 }
536 
537 ///////////////////////////////////////////////////////////////////////////////
538 void
539 ScoreFunction::show_line_headers( std::ostream & out ) const
540 {
541 
542  for ( int i=1; i<= n_score_types; ++i ) {
543  if ( weights_[ ScoreType(i) ] != 0.0 ) {
544  out << ' ' << LJ(16,ScoreType(i)) << ' ';
545  }
546  }
547 
548 }
549 ///////////////////////////////////////////////////////////////////////////////
550 void
551 ScoreFunction::show_line( std::ostream & out, pose::Pose const & pose ) const
552 {
553 
554  float sum_weighted=0.0;
555  for ( int i=1; i<= n_score_types; ++i ) {
556  if ( weights_[ ScoreType(i) ] != 0.0 ) {
557  sum_weighted += weights_[ ScoreType(i) ] * pose.energies().total_energies()[ ScoreType(i) ];
558  }
559  }
560  out << F(9,3,sum_weighted);
561 
562  for ( int i=1; i<= n_score_types; ++i ) {
563  if ( weights_[ ScoreType(i) ] != 0.0 ) {
564  // OL: added the " " to the output. Otherwise column separation can be missing in silent-files
565  // OL: if large numbers come into play
566  // OL: reduced F(9,3) to F(8,3) to account for the extra space.
567  out << " " << F(8,3, weights_[ ScoreType(i) ] * pose.energies().total_energies()[ ScoreType(i) ] );
568  }
569  }
570 
571 }
572 
573 
574 ///////////////////////////////////////////////////////////////////////////////
575 
576 // to start out, just thinking fullatom energies
577 //
578 // NOTE: no freakin rotamer trials inside scoring!
579 
580 Real
582 {
583 #ifdef APL_TEMP_DEBUG
584  if ( n_minimization_sfxn_evals != 0 && ! pose.energies().use_nblist() ) {
585  std::cout << "n_minimization_sfxn_evals: " << n_minimization_sfxn_evals << std::endl;
586  n_minimization_sfxn_evals = 0;
587  }
588  if ( pose.energies().use_nblist() ) {
589  ++n_minimization_sfxn_evals;
590  }
591 #endif
592 
593  // completely unnecessary temporary hack to force refold if nec. for profiling
594  if(pose.total_residue() > 0) {
595  pose.residue( pose.total_residue() );
596  }
597 
598  //fpd fail if this is called on a symmetric pose
599  runtime_assert( !core::pose::symmetry::is_symmetric( pose ) );
600 
601  PROF_START( basic::SCORE );
602  //std::cout << "ScoreFunction::operator()\n";
603 
604  // notify the pose that we are starting a score evaluation.
605  // also tells the cached energies object about the scoring
606  // parameters, for the purposes of invalidating cached data
607  // if necessary
608  //
609  // at this point the dof/xyz-moved information will be converted
610  // to a domain map. Energy/neighbor links between pair-moved residues
611  // will be deleted, and 1d energies of res-moved residues will be
612  // cleared.
613  //
614  // further structure modification will be prevented until scoring is
615  // completed
616  //
617  PROF_START( basic::SCORE_BEGIN_NOTIFY );
618  pose.scoring_begin( *this );
619 
620  //std::cout << "ScoreFunction::operator() 1\n";
621  if ( pose.energies().total_energy() != 0.0 ) {
622  std::cout << "STARTING SCORE NON-ZERO!" << std::endl;
623  }
624  PROF_STOP( basic::SCORE_BEGIN_NOTIFY );
625  // ensure that the total_energies are zeroed out -- this happens in Energies.scoring_begin()
626  //std::cout << "ScoreFunction::operator() 2\n";
627  PROF_START( basic::SCORE_SETUP );
628  // do any setup necessary
629  setup_for_scoring( pose );
630  //std::cout << "ScoreFunction::operator() 3\n";
631  PROF_STOP( basic::SCORE_SETUP );
632 
633  // evaluate the residue-residue energies that only exist between
634  // neighboring residues
635  PROF_START( basic::SCORE_NEIGHBOR_ENERGIES );
636 
638 
639  PROF_STOP ( basic::SCORE_NEIGHBOR_ENERGIES );
640 
641  // evaluate the residue pair energies that exist between possibly-distant residues
642  PROF_START( basic::SCORE_LONG_RANGE_ENERGIES );
643 
645 
646  PROF_STOP ( basic::SCORE_LONG_RANGE_ENERGIES );
647 
648  PROF_START( basic::SCORE_ONEBODY_ENERGIES );
649 
650  // evaluate the onebody energies -- rama, dunbrack, ...
651  eval_onebody_energies( pose );
652 
653  PROF_STOP( basic::SCORE_ONEBODY_ENERGIES );
654 
655  PROF_START( basic::SCORE_FINALIZE );
656  // give energyfunctions a chance update/finalize energies
657  // etable nblist calculation is performed here
658  for ( AllMethods::const_iterator it=all_methods_.begin(),
659  it_end = all_methods_.end(); it != it_end; ++it ) {
660  (*it)->finalize_total_energy( pose, *this, pose.energies().finalized_energies() );
661  }
662 
663  pose.energies().total_energies() += pose.energies().finalized_energies();
664 
665  if ( pose.energies().use_nblist() ) {
666  pose.energies().total_energies() += pose.energies().minimization_graph()->fixed_energies();
667  }
668 
669  PROF_STOP( basic::SCORE_FINALIZE );
670 
671  //std::cout << "Total energies: ";
672  //pose.energies().total_energies().show_if_nonzero_weight( std::cout, weights_ );
673  //std::cout << std::endl;
674  PROF_START( basic::SCORE_DOT );
675 
676  // dot the weights with the scores
677  pose.energies().total_energy() = pose.energies().total_energies().dot( weights_ );
679 
680  PROF_STOP( basic::SCORE_DOT );
681 
682  PROF_START( basic::SCORE_END_NOTIFY );
683 
684  // notify that scoring is over
685  pose.scoring_end( *this );
686 
687  PROF_STOP( basic::SCORE_END_NOTIFY );
688 
689  PROF_STOP ( basic::SCORE );
690 
691  return pose.energies().total_energy();
692 }
693 
694 Real
696  return (*this)(pose);
697 }
698 
699 /*
700 /// @details This operates much like the regular score function evaluation, except
701 /// that it waits to compute the two-body energies until after the other components of the
702 /// score function evaluation has completed. It relies on the mechanism already present in
703 /// the Energies object to update the component energies lazily. This mechanism will
704 /// update both the EnergyGraph and the EnergyGraphLite objects.
705 Real
706 ScoreFunction::score_components( pose::Pose & pose ) const
707 {
708  // completely unnecessary temporary hack to force refold if nec. for profiling
709  pose.residue( pose.total_residue() );
710 
711  PROF_START( basic::SCORE );
712  //std::cout << "ScoreFunction::operator()\n";
713 
714  // notify the pose that we are starting a score evaluation.
715  // also tells the cached energies object about the scoring
716  // parameters, for the purposes of invalidating cached data
717  // if necessary
718  //
719  // at this point the dof/xyz-moved information will be converted
720  // to a domain map. Energy/neighbor links between pair-moved residues
721  // will be deleted, and 1d energies of res-moved residues will be
722  // cleared.
723  //
724  // further structure modification will be prevented until scoring is
725  // completed
726  //
727  pose.scoring_begin( *this );
728  //std::cout << "ScoreFunction::operator() 1\n";
729 
730  if ( pose.energies().total_energy() != 0.0 ) {
731  std::cout << "STARTING SCORE NON-ZERO!" << std::endl;
732  }
733 
734  // ensure that the total_energies are zeroed out -- this happens in Energies.scoring_begin()
735  // unneccessary pose.energies().total_energies().clear();
736  //std::cout << "ScoreFunction::operator() 2\n";
737 
738  // do any setup necessary
739  setup_for_scoring( pose );
740 
741  // evaluate the residue pair energies that exist between possibly-distant residues
742  PROF_START( basic::LONG_RANGE_ENERGIES );
743 
744  eval_long_range_twobody_energies( pose );
745 
746  PROF_STOP ( basic::LONG_RANGE_ENERGIES );
747 
748  // evaluate the onebody energies -- rama, dunbrack, ...
749  eval_onebody_energies( pose );
750 
751  // give energyfunctions a chance update/finalize energies
752  // etable nblist calculation is performed here
753  for ( AllMethods::const_iterator it=all_methods_.begin(),
754  it_end = all_methods_.end(); it != it_end; ++it ) {
755  (*it)->finalize_total_energy( pose, *this, pose.energies().finalized_energies() );
756  }
757 
758  // notify that scoring is over
759  pose.scoring_end( *this );
760 
761  PROF_STOP ( basic::SCORE );
762 
763  /// Now go back and score to the two-body energies -- triggered automatically accessing the
764  /// energy graph.
765  pose.energies().energy_graph();
766 
767  /// The above call forced the computation of the total_energies emap; the total score can
768  /// now be computed.
769  EnergyMap const & total_energies( pose.energies().total_energies() );
770 
771  pose.energies().total_energy() = total_energies.dot( weights_ );
772  return pose.energies().total_energy();
773 }*/
774 
775 ///////////////////////////////////////////////////////////////////////////////
778  pose::Pose const & pose,
779  utility::vector1< bool > const & residue_mask
780 ) const {
781  assert(residue_mask.size() == pose.total_residue());
782 
783  // retrieve cached energies object
784  Energies const & energies( pose.energies() );
785  assert(energies.energies_updated());
786  // the neighbor/energy links
787  EnergyGraph const & energy_graph( energies.energy_graph() );
788 
789  // should be zeroed at the beginning of scoring
790  Real total( 0.0 ); //( energies.totals() );
791  for ( Size i=1, i_end = pose.total_residue(); i<= i_end; ++i ) {
792  if(!residue_mask[i]) continue;
793 
795  iru = energy_graph.get_node(i)->const_upper_edge_list_begin(),
796  irue = energy_graph.get_node(i)->const_upper_edge_list_end();
797  iru != irue; ++iru ) {
798  EnergyEdge const & edge( static_cast< EnergyEdge const &> (**iru) );
799  Size const j( edge.get_second_node_ind() );
800  if(!residue_mask[j]) continue;
801 
802  total += edge.dot( weights_ );
803  } // nbrs of i
804  } // i=1,nres
805 
806  ///////////////////////////////////////////////////////////////
807  // context independent onebody energies
808 
809  for ( Size i=1; i<= pose.total_residue(); ++i ) {
810  if(!residue_mask[i]) continue;
811  EnergyMap const & emap( energies.onebody_energies( i ) );
812 
813  total += weights_.dot( emap, ci_1b_types() );
814  total += weights_.dot( emap, cd_1b_types() );
815 
816  // 2body energy methods are allowed to define 1body intxns //////
817  if ( any_intrares_energies_ ) {
818  // context independent:
819  total += weights_.dot( emap, ci_2b_types() );
820  total += weights_.dot( emap, ci_lr_2b_types() );
821  // contex dependent:
822  total += weights_.dot( emap, cd_2b_types() );
823  total += weights_.dot( emap, cd_lr_2b_types() );
824  }
825  }
826 
827  // add in hbonding
828  if ( pose.energies().data().has( EnergiesCacheableDataType::HBOND_SET )) {
829 
830  hbonds::HBondSet const & hbond_set
831  ( static_cast< hbonds::HBondSet const & >
833 
834  hbonds::HBondSet hbond_set_excl(hbond_set, residue_mask);
835  EnergyMap hbond_emap;
836  hbonds::get_hbond_energies(hbond_set_excl, hbond_emap);
837  total += weights_[hbond_sr_bb] * hbond_emap[hbond_sr_bb];
838  total += weights_[hbond_lr_bb] * hbond_emap[hbond_lr_bb];
839  }
840 
841  //////////////////////////////////////////////////
842  /// Context Independent Long Range 2Body methods
843 
844  for(CI_LR_2B_Methods::const_iterator iter = ci_lr_2b_methods_.begin(),
845  iter_end = ci_lr_2b_methods_.end(); iter != iter_end; ++iter ) {
846  LREnergyContainerCOP lrec = pose.energies().long_range_container( (*iter)->long_range_type() );
847  if( !lrec || lrec->empty() ) continue; // only score non-emtpy energies.
848 
849  // Potentially O(N^2) operation...
850  for( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
851  if(!residue_mask[ii]) continue;
852 
854  rni = lrec->const_upper_neighbor_iterator_begin( ii ),
855  rniend = lrec->const_upper_neighbor_iterator_end( ii );
856  (*rni) != (*rniend); ++(*rni) ) {
857  if(!residue_mask[rni->upper_neighbor_id()]) continue;
858 
859  EnergyMap emap;
860  rni->retrieve_energy( emap ); // pbmod
861  total += weights_.dot( emap, ci_lr_2b_types() );
862  }
863  }
864  }
865  /////////////////////////////////////////////////////
866  /// Context Independent Long Range twobody methods
867 
868  for( CD_LR_2B_Methods::const_iterator iter = cd_lr_2b_methods_.begin(),
869  iter_end = cd_lr_2b_methods_.end(); iter != iter_end; ++iter ) {
870  LREnergyContainerCOP lrec =
871  pose.energies().long_range_container( (*iter)->long_range_type() );
872  // Potentially O(N^2) operation...
873  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
874  if(!residue_mask[ii]) continue;
876  rni = lrec->const_upper_neighbor_iterator_begin( ii ),
877  rniend = lrec->const_upper_neighbor_iterator_end( ii );
878  (*rni) != (*rniend); ++(*rni) ) {
879  if(!residue_mask[rni->upper_neighbor_id()]) continue;
880 
881  EnergyMap emap;
882  rni->retrieve_energy( emap ); // pbmod
883  total += weights_.dot( emap, cd_lr_2b_types() );
884  }
885  }
886  }
887 
888  return total;
889 }
890 
893  pose::Pose & pose,
894  utility::vector1< bool > const & residue_mask
895 ) const {
896  //If the energies are not up-to-date score the pose
897  if(!pose.energies().energies_updated()) (*this)(pose);
898 
899  return get_sub_score(const_cast<pose::Pose const &>(pose), residue_mask);
900 }
901 
902 
903 ///////////////////////////////////////////////////////////////////////////////
904 void
906  pose::Pose const & pose,
907  utility::vector1< bool > const & residue_mask,
908  EnergyMap & emap
909 ) const {
910  assert(residue_mask.size() == pose.total_residue());
911 
912  // retrieve cached energies object
913  Energies const & energies( pose.energies() );
914  assert(energies.energies_updated());
915 
916  // the neighbor/energy links
917  EnergyGraph const & energy_graph( energies.energy_graph() );
918 
919  // should be zeroed at the beginning of scoring
920  for ( Size i=1, i_end = pose.total_residue(); i<= i_end; ++i ) {
921  if(!residue_mask[i]) continue;
922 
924  iru = energy_graph.get_node(i)->const_upper_edge_list_begin(),
925  irue = energy_graph.get_node(i)->const_upper_edge_list_end();
926  iru != irue; ++iru ) {
927  EnergyEdge const & edge( static_cast< EnergyEdge const &> (**iru) );
928  Size const j( edge.get_second_node_ind() );
929  if(!residue_mask[j]) continue;
930 
931  EnergyMap edge_emap(edge.fill_energy_map());
932  edge_emap *= weights_;
933  emap += edge_emap;
934  } // nbrs of i
935  } // i=1,nres
936 
937 
938  ///////////////////////////////////////////////////////////////
939  // context independent onebody energies
940 
941  for ( Size i=1; i<= pose.total_residue(); ++i ) {
942  if(!residue_mask[i]) continue;
943  EnergyMap onebody_emap(energies.onebody_energies(i));
944  onebody_emap *= weights_;
945 
946  emap.accumulate( onebody_emap, ci_1b_types() );
947  emap.accumulate( onebody_emap, cd_1b_types() );
948 
949  // 2body energy methods are allowed to define 1body intxns //////
950  if ( any_intrares_energies_ ) {
951  emap.accumulate( onebody_emap, ci_2b_types() );
952  emap.accumulate( onebody_emap, ci_lr_2b_types() );
953  emap.accumulate( onebody_emap, cd_2b_types() );
954  emap.accumulate( onebody_emap, cd_lr_2b_types() );
955  }
956  }
957 
958  // add in hbonding
959  if ( pose.energies().data().has( EnergiesCacheableDataType::HBOND_SET )) {
960 
961  hbonds::HBondSet const & hbond_set
962  ( static_cast< hbonds::HBondSet const & >
964 
965  hbonds::HBondSet hbond_set_excl(hbond_set, residue_mask);
966  EnergyMap hbond_emap;
967  hbonds::get_hbond_energies(hbond_set_excl, hbond_emap);
968  emap[hbond_sr_bb] += weights_[hbond_sr_bb] * hbond_emap[hbond_sr_bb];
969  emap[hbond_lr_bb] += weights_[hbond_lr_bb] * hbond_emap[hbond_lr_bb];
970  }
971 
972  //////////////////////////////////////////////////
973  /// Context Independent Long Range 2Body methods
974 
975  for(CI_LR_2B_Methods::const_iterator iter = ci_lr_2b_methods_.begin(),
976  iter_end = ci_lr_2b_methods_.end(); iter != iter_end; ++iter ) {
977  LREnergyContainerCOP lrec =
978  pose.energies().long_range_container((*iter)->long_range_type());
979  if( !lrec || lrec->empty() ) continue; // only score non-emtpy energies.
980 
981  // Potentially O(N^2) operation...
982  for( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
983  if(!residue_mask[ii]) continue;
984 
986  rni = lrec->const_upper_neighbor_iterator_begin( ii ),
987  rniend = lrec->const_upper_neighbor_iterator_end( ii );
988  (*rni) != (*rniend); ++(*rni) ) {
989  if(!residue_mask[rni->upper_neighbor_id()]) continue;
990 
991  EnergyMap lr_emap;
992  rni->retrieve_energy( lr_emap ); // pbmod
993  emap += lr_emap;
994  }
995  }
996 
997  /////////////////////////////////////////////////////
998  /// Context Independent Long Range twobody methods
999 
1000  for( CD_LR_2B_Methods::const_iterator iter = cd_lr_2b_methods_.begin(),
1001  iter_end = cd_lr_2b_methods_.end(); iter != iter_end; ++iter ) {
1002  LREnergyContainerCOP lrec =
1003  pose.energies().long_range_container((*iter)->long_range_type());
1004  // Potentially O(N^2) operation...
1005  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
1006  if(!residue_mask[ii]) continue;
1008  rni = lrec->const_upper_neighbor_iterator_begin( ii ),
1009  rniend = lrec->const_upper_neighbor_iterator_end( ii );
1010  (*rni) != (*rniend); ++(*rni) ) {
1011  if(!residue_mask[rni->upper_neighbor_id()]) continue;
1012 
1013  EnergyMap lr_emap;
1014  rni->retrieve_energy( lr_emap ); // pbmod
1015  emap += lr_emap;
1016 
1017  }
1018  }
1019  }
1020  }
1021 }
1022 
1023 void
1025  pose::Pose & pose,
1026  utility::vector1< bool > const & residue_mask,
1027  EnergyMap & emap
1028 ) const {
1029  //If the energies are not up-to-date score the pose
1030  if(!pose.energies().energies_updated()) (*this)(pose);
1031  return get_sub_score(const_cast<pose::Pose const &>(pose), residue_mask, emap);
1032 }
1033 
1034 
1035 ///////////////////////////////////////////////////////////////////////////////
1036 Real
1038  pose::Pose const & pose,
1039  utility::vector1< Size > const & exclude_res
1040 ) const {
1041 
1042  utility::vector1< bool > residue_mask(pose.total_residue(), true);
1043  for(
1045  ii = exclude_res.begin(), ie = exclude_res.end();
1046  ii != ie; ++ii){
1047  residue_mask[*ii] = false;
1048  }
1049  return get_sub_score(pose, residue_mask);
1050 }
1051 
1052 ///////////////////////////////////////////////////////////////////////////////
1053 Real
1055  pose::Pose & pose,
1056  utility::vector1< Size > const & exclude_res
1057 ) const {
1058 
1059  //If the energies are not up-to-date score the pose
1060  if(!pose.energies().energies_updated()) (*this)(pose);
1061 
1062  utility::vector1< bool > residue_mask(pose.total_residue(), true);
1063  for(
1065  ii = exclude_res.begin(), ie = exclude_res.end();
1066  ii != ie; ++ii){
1067  residue_mask[*ii] = false;
1068  }
1069  return get_sub_score(const_cast<pose::Pose const &>(pose), residue_mask);
1070 }
1071 
1072 
1073 
1074 ///////////////////////////////////////////////////////////////////////////////
1075 void
1077  pose::Pose const & pose,
1078  utility::vector1< core::Size > const & exclude_res,
1079  EnergyMap & emap
1080 ) const {
1081  utility::vector1< bool > residue_mask(pose.total_residue(), true);
1082  for(
1084  ii = exclude_res.begin(), ie = exclude_res.end();
1085  ii != ie; ++ii){
1086  residue_mask[*ii] = false;
1087  }
1088  get_sub_score(pose, residue_mask, emap);
1089 }
1090 
1091 ///////////////////////////////////////////////////////////////////////////////
1092 void
1094  pose::Pose & pose,
1095  utility::vector1< core::Size > const & exclude_res,
1096  EnergyMap & emap
1097 ) const {
1098 
1099  //If the energies are not up-to-date score the pose
1100  if(!pose.energies().energies_updated()) (*this)(pose);
1101 
1102  utility::vector1< bool > residue_mask(pose.total_residue(), true);
1103  for(
1105  ii = exclude_res.begin(), ie = exclude_res.end();
1106  ii != ie; ++ii){
1107  residue_mask[*ii] = false;
1108  }
1109  get_sub_score(const_cast<pose::Pose const &>(pose), residue_mask, emap);
1110 }
1111 
1112 
1113 ///////////////////////////////////////////////////////////////////////////////
1114 void
1116  pose::Pose & pose
1117 ) const
1118 {
1119 
1120  /// Use the EnergyGraph or the MinimizationGraph to direct scoring
1121 
1122  // cached energies object
1123  Energies & energies( pose.energies() );
1124 
1125  EnergyMap & total_energies( const_cast< EnergyMap & > ( energies.total_energies() ) );
1126 
1127  // the neighbor/energy links
1128  EnergyGraph & energy_graph( energies.energy_graph() );
1129 
1130  // are we using the atom-atom nblist?
1131  // renaming for true purpose: are we minimizing -- if so,
1132  // zero the energies stored on edges in the Energy graph, but do
1133  // not mark the edges as having had their energies computed
1134  bool const minimizing( energies.use_nblist() );
1135 
1136  if ( minimizing ) {
1137  /// When minimizing, do not touch the EnergyGraph -- leave it fixed
1138  MinimizationGraphCOP g = energies.minimization_graph();
1139  for ( Size ii = 1; ii < pose.total_residue(); ++ii ) {
1140  conformation::Residue const & ii_rsd( pose.residue( ii ) );
1142  edge_iter = g->get_node( ii )->const_upper_edge_list_begin(),
1143  edge_iter_end = g->get_node( ii )->const_upper_edge_list_end();
1144  edge_iter != edge_iter_end; ++edge_iter ) {
1145  Size const jj = (*edge_iter)->get_second_node_ind();
1146  conformation::Residue const & jj_rsd( pose.residue( jj ));
1147  MinimizationEdge const & minedge( static_cast< MinimizationEdge const & > (**edge_iter) );
1148 
1149  eval_res_pair_energy_for_minedge( minedge, ii_rsd, jj_rsd, pose, *this, total_energies );
1150  }
1151  }
1152 
1153  } else {
1154  EnergyMap tbemap;
1155 
1156  for ( Size i=1, i_end = pose.total_residue(); i<= i_end; ++i ) {
1157  conformation::Residue const & resl( pose.residue( i ) );
1159  iru = energy_graph.get_node(i)->upper_edge_list_begin(),
1160  irue = energy_graph.get_node(i)->upper_edge_list_end();
1161  iru != irue; ++iru ) {
1162  EnergyEdge & edge( static_cast< EnergyEdge & > (**iru) );
1163 
1164  Size const j( edge.get_second_node_ind() );
1165  conformation::Residue const & resu( pose.residue( j ) );
1166  // the pair energies cached in the link
1167  ///EnergyMap & emap( energy_edge->energy_map() );
1168  tbemap.zero( cd_2b_types() );
1169  tbemap.zero( ci_2b_types() );
1170 
1171  // the context-dependent guys can't be cached, so they are always reevaluated
1172  eval_cd_2b( resl, resu, pose, tbemap );
1173 
1174  if ( edge.energies_not_yet_computed() ) {
1175  // energies not yet computed? <-> (during minimization w/ nblist) moving rsd pair
1176  /// TEMP zero portions;
1177 
1178  if ( minimizing ) { // APL -- 5/18/2010 -- DEPRICATED
1179  // confirm that this rsd-rsd interaction will be included
1180  // in the atom pairs on the nblist:
1181  //assert( ( pose.energies().domain_map(i) !=
1182  // pose.energies().domain_map(j) ) ||
1183  // ( pose.energies().res_moved(i) ) );
1184  // ensure that these are zeroed, since we will hit them at the
1185  // end inside the nblist calculation
1186  // they almost certainly should be, since the energies have not
1187  // yet been computed...
1188  eval_ci_2b( resl, resu, pose, tbemap );
1189  edge.store_active_energies( tbemap );
1190  // do not mark energies as computed!!!!!!!!!!!!!
1191  } else {
1192  eval_ci_2b( resl, resu, pose, tbemap );
1193  edge.store_active_energies( tbemap );
1194  edge.mark_energies_computed();
1195  }
1196  } else {
1197  /// Read the CI energies from the edge, as they are still valid;
1198  for ( Size ii = 1; ii <= ci_2b_types().size(); ++ii ) {
1199  tbemap[ ci_2b_types()[ ii ]] = edge[ ci_2b_types()[ ii ] ];
1200  }
1201 
1202  /// Save the freshly computed CD energies on the edge
1203  edge.store_active_energies( tbemap, cd_2b_types() );
1204  }
1205 
1206  total_energies.accumulate( tbemap, ci_2b_types() );
1207  total_energies.accumulate( tbemap, cd_2b_types() );
1208  } // nbrs of i
1209  } // i=1,nres
1210  } // not minimizing
1211 }
1212 
1213 void
1215 {
1216  EnergyMap & total_energies(const_cast< EnergyMap & > (pose.energies().total_energies()));
1217 
1218  bool const minimizing( pose.energies().use_nblist() );
1219  if ( minimizing ) return; // long range energies are handled as part of the 2-body energies in the minimization graph
1220 
1221  for ( CI_LR_2B_Methods::const_iterator iter = ci_lr_2b_methods_.begin(),
1222  iter_end = ci_lr_2b_methods_.end(); iter != iter_end; ++iter ) {
1223 
1224  LREnergyContainerOP lrec = pose.energies().nonconst_long_range_container( (*iter)->long_range_type() );
1225  if ( !lrec || lrec->empty() ) continue; // only score non-emtpy energies.
1226 
1227  // Potentially O(N^2) operation...
1228  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
1230  rni = lrec->upper_neighbor_iterator_begin( ii ),
1231  rniend = lrec->upper_neighbor_iterator_end( ii );
1232  (*rni) != (*rniend); ++(*rni) ) {
1233  EnergyMap emap;
1234  if ( ! rni->energy_computed() ) {
1235  (*iter)->residue_pair_energy(
1236  pose.residue(ii),
1237  pose.residue( rni->upper_neighbor_id() ),
1238  pose, *this, emap );
1239  rni->save_energy( emap );
1240 
1241  /// DANGER DANGER DANGER. use_nblist() now means "In the process of a minimization". There is
1242  /// no such thing as a non-neighborlist minimization. This will confuse people at some point.
1243  /// We ought to have some "are we minimizing currently" flag who's meaning can be decoupled
1244  /// from the neighborlist idea.
1245  if ( ! pose.energies().use_nblist() ) {
1246  rni->mark_energy_computed();
1247  }
1248  } else {
1249  rni->retrieve_energy( emap ); // pbmod
1250  }
1251  total_energies += emap;
1252  }
1253  }
1254 
1255  }
1256 
1257  for ( CD_LR_2B_Methods::const_iterator iter = cd_lr_2b_methods_.begin(),
1258  iter_end = cd_lr_2b_methods_.end(); iter != iter_end; ++iter ) {
1259 
1260  LREnergyContainerOP lrec
1261  = pose.energies().nonconst_long_range_container( (*iter)->long_range_type() );
1262 
1263  // Potentially O(N^2) operation...
1264  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
1266  rni = lrec->upper_neighbor_iterator_begin( ii ),
1267  rniend = lrec->upper_neighbor_iterator_end( ii );
1268  (*rni) != (*rniend); ++(*rni) ) {
1269 
1270  EnergyMap emap;
1271  (*iter)->residue_pair_energy(
1272  pose.residue(ii),
1273  pose.residue( rni->upper_neighbor_id() ),
1274  pose, *this, emap );
1275 
1276  rni->save_energy( emap );
1277  //rni->mark_energy_computed();
1278 
1279  total_energies += emap;
1280 
1281  }
1282  }
1283 
1284  }
1285 }
1286 
1287 ///////////////////////////////////////////////////////////////////////////////
1288 /*
1289 void
1290 ScoreFunction::accumulate_residue_total_energies(
1291  pose::Pose & pose
1292 ) const
1293 {
1294  // cached energies object
1295  Energies & energies( pose.energies() );
1296 
1297  // the neighbor/energy links
1298  EnergyGraph & energy_graph( energies.energy_graph() );
1299 
1300  // debug
1301  assert( !energies.use_nblist() && energies.energies_updated() );
1302 
1303  // zero out the scores we are going to accumulate
1304  for ( Size i=1, i_end = pose.total_residue(); i<= i_end; ++i ) {
1305  EnergyMap & emap( energies.residue_total_energies(i) );
1306  emap.zero();
1307  emap += energies.onebody_energies(i);
1308  }
1309 
1310  for ( Size i=1, i_end = pose.total_residue(); i<= i_end; ++i ) {
1311  for ( graph::Graph::EdgeListIter
1312  iru = energy_graph.get_node(i)->upper_edge_list_begin(),
1313  irue = energy_graph.get_node(i)->upper_edge_list_end();
1314  iru != irue; ++iru ) {
1315 
1316  EnergyEdge * edge( static_cast< EnergyEdge *> (*iru) );
1317 
1318  Size const j( edge->get_second_node_ind() );
1319 
1320  // the pair energies cached in the link
1321  EnergyMap const & emap( edge->energy_map());
1322 
1323  assert( !edge->energies_not_yet_computed() );
1324 
1325  // accumulate energies
1326  energies.residue_total_energies(i).accumulate( emap, ci_2b_types(), 0.5 );
1327  energies.residue_total_energies(i).accumulate( emap, cd_2b_types(), 0.5 );
1328 
1329  energies.residue_total_energies(j).accumulate( emap, ci_2b_types(), 0.5 );
1330  energies.residue_total_energies(j).accumulate( emap, cd_2b_types(), 0.5 );
1331  } // nbrs of i
1332  } // i=1,nres
1333 
1334  Real tmp_score( 0.0 );
1335 
1336  for ( LR_2B_Methods::const_iterator iter = lr_2b_methods_.begin(),
1337  iter_end = lr_2b_methods_.end(); iter != iter_end; ++iter ) {
1338  // Why is this non-const?!
1339  LREnergyContainerOP lrec
1340  = pose.energies().nonconst_long_range_container( (*iter)->long_range_type() );
1341  assert( lrec );
1342  if ( lrec->empty() ) continue;
1343  ScoreTypes const & lrec_score_types = score_types_by_method_type_[ (*iter)->method_type() ];
1344 
1345  // Potentially O(N^2) operation...
1346  for ( Size i = 1; i <= pose.total_residue(); ++i ) {
1347  for ( ResidueNeighborConstIteratorOP
1348  rni = lrec->const_upper_neighbor_iterator_begin( i ),
1349  rniend = lrec->const_upper_neighbor_iterator_end( i );
1350  (*rni) != (*rniend); ++(*rni) ) {
1351  Size j = rni->upper_neighbor_id();
1352  EnergyMap emap;
1353  rni->retrieve_energy( emap );
1354 
1355  energies.residue_total_energies(i).accumulate( emap, lrec_score_types, 0.5 );
1356  energies.residue_total_energies(j).accumulate( emap, lrec_score_types, 0.5 );
1357  }
1358  }
1359  }
1360 
1361  for ( Size i=1, i_end = pose.total_residue(); i<= i_end; ++i ) {
1362  EnergyMap & emap( energies.residue_total_energies(i) );
1363  emap[ total_score ] = emap.dot( weights_ );
1364  tmp_score += emap[ total_score ];
1365  }
1366 
1367 #ifdef NDEBUG
1368  return;
1369 #endif
1370 
1371  /////////////////////////////////////////////////////////////////////////////
1372  // just for debugging, since this involves some extra calculation
1373 
1374  { // extra scores
1375  EnergyMap emap;
1376  for ( AllMethods::const_iterator it=all_methods_.begin(),
1377  it_end = all_methods_.end(); it != it_end; ++it ) {
1378  (*it)->finalize_total_energy( pose, *this, emap );
1379  }
1380  //std::cout << "before: " << tmp_score << std::endl;
1381  tmp_score += emap.dot( weights_ );
1382 
1383 
1384  // this warning is only relevant if all energies are 1body or 2body,
1385  // ie no whole-structure energies which are not assigned to an
1386  // individual residue
1387  Real const expected_score( energies.total_energy() );
1388  //std::cout << "[ DEBUG ] score-check: " << tmp_score << ' ' <<
1389  // expected_score << std::endl;
1390  if ( std::abs( tmp_score - expected_score ) > 1e-2 ) {
1391  std::cout << "[ WARNING ] score mismatch: " << tmp_score << ' ' <<
1392  expected_score << std::endl;
1393  }
1394  }
1395 } // accumulate_residue_total_energies
1396 
1397 */
1398 
1399 ///////////////////////////////////////////////////////////////////////////////
1400 void
1402 {
1403  // context independent onebody energies
1404  Energies & energies( pose.energies() );
1405  EnergyMap & totals( energies.total_energies() );
1406 
1407  bool const minimizing( energies.use_nblist() );
1408 
1409  if ( minimizing ) {
1410  MinimizationGraphCOP mingraph = energies.minimization_graph();
1411  assert( mingraph );
1412  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
1413  conformation::Residue const & rsd = pose.residue( ii );
1414 
1415  MinimizationNode const & iiminnode = * mingraph->get_minimization_node( ii );
1416  eval_res_onebody_energies_for_minnode( iiminnode, rsd, pose, *this, totals );
1417 
1418  }
1419 
1420  } else {
1421  for ( Size i=1; i<= pose.total_residue(); ++i ) {
1422  EnergyMap & emap( energies.onebody_energies( i ) );
1423 
1424  // 1body intxns ///////////////////////////
1425  if ( energies.res_moved( i ) ) {
1426  // have to recalculate
1427  emap.clear(); // should already have been done when the domain map was internalized
1428  eval_ci_1b( pose.residue(i), pose, emap );
1429  }
1430 
1431  emap.zero( cd_1b_types() ); // cant be cached
1432  eval_cd_1b( pose.residue(i), pose, emap );
1433 
1434 
1435  // 2body energy methods are allowed to define 1body intxns ///////////////////////////
1436  if ( any_intrares_energies_ ) {
1437  // context independent:
1438  if ( energies.res_moved( i ) ) {
1439  eval_ci_intrares_energy( pose.residue(i), pose, emap );
1440  }
1441  // context dependent
1442  emap.zero( cd_2b_types() ); // cant be cached (here only intrares are relevant)
1443  emap.zero( cd_lr_2b_types() ); // cant be cached (here only intrares are relevant)
1444  eval_cd_intrares_energy( pose.residue(i), pose, emap );
1445  }
1446 
1447  totals += emap;
1448 
1449  energies.reset_res_moved( i ); // mark one body energies as having been calculated
1450  //std::cout << "totals: "<< i << totals;
1451  }
1452  }
1453 }
1454 
1455 void
1457  conformation::Residue const & rsd,
1458  pose::Pose const & pose,
1459  EnergyMap & emap
1460 ) const
1461 {
1462  if ( ! any_intrares_energies_ ) return;
1463  for ( TWO_B_Methods::const_iterator iter = ci_2b_intrares_.begin(),
1464  iter_end = ci_2b_intrares_.end(); iter != iter_end; ++iter ) {
1465  (*iter)->eval_intrares_energy( rsd, pose, *this, emap );
1466  }
1467  for ( TWO_B_Methods::const_iterator iter = cd_2b_intrares_.begin(),
1468  iter_end = cd_2b_intrares_.end(); iter != iter_end; ++iter ) {
1469  (*iter)->eval_intrares_energy( rsd, pose, *this, emap );
1470  }
1471 }
1472 
1473 void
1475  conformation::RotamerSetBase const & set,
1476  pose::Pose const & pose,
1478 ) const
1479 {
1480  if ( ! any_intrares_energies_ ) return;
1481  for ( TWO_B_Methods::const_iterator iter = ci_2b_intrares_.begin(),
1482  iter_end = ci_2b_intrares_.end(); iter != iter_end; ++iter ) {
1483  (*iter)->evaluate_rotamer_intrares_energies( set, pose, *this, energies );
1484  }
1485  for ( TWO_B_Methods::const_iterator iter = cd_2b_intrares_.begin(),
1486  iter_end = cd_2b_intrares_.end(); iter != iter_end; ++iter ) {
1487  (*iter)->evaluate_rotamer_intrares_energies( set, pose, *this, energies );
1488  }
1489 }
1490 
1491 void
1493  conformation::RotamerSetBase const & set,
1494  pose::Pose const & pose,
1496 ) const
1497 {
1498  if ( ! any_intrares_energies_ ) return;
1499  for ( TWO_B_Methods::const_iterator iter = ci_2b_intrares_.begin(),
1500  iter_end = ci_2b_intrares_.end(); iter != iter_end; ++iter ) {
1501  (*iter)->evaluate_rotamer_intrares_energy_maps( set, pose, *this, emaps );
1502  }
1503  for ( TWO_B_Methods::const_iterator iter = cd_2b_intrares_.begin(),
1504  iter_end = cd_2b_intrares_.end(); iter != iter_end; ++iter ) {
1505  (*iter)->evaluate_rotamer_intrares_energy_maps( set, pose, *this, emaps );
1506  }
1507 }
1508 
1509 void
1511  conformation::Residue const & rsd,
1512  pose::Pose const & pose,
1513  EnergyMap & emap
1514 ) const
1515 {
1516  if ( ! any_intrares_energies_ ) return;
1517  for ( TWO_B_Methods::const_iterator iter = ci_2b_intrares_.begin(),
1518  iter_end = ci_2b_intrares_.end(); iter != iter_end; ++iter ) {
1519  (*iter)->eval_intrares_energy( rsd, pose, *this, emap );
1520  }
1521 }
1522 
1523 void
1525  conformation::Residue const & rsd,
1526  pose::Pose const & pose,
1527  EnergyMap & emap
1528 ) const
1529 {
1530  if ( ! any_intrares_energies_ ) return;
1531  for ( TWO_B_Methods::const_iterator iter = cd_2b_intrares_.begin(),
1532  iter_end = cd_2b_intrares_.end(); iter != iter_end; ++iter ) {
1533  (*iter)->eval_intrares_energy( rsd, pose, *this, emap );
1534  }
1535 }
1536 
1537 
1538 ///////////////////////////////////////////////////////////////////////////////
1539 void
1541  conformation::Residue const & rsd,
1542  pose::Pose const & pose,
1543  EnergyMap & emap
1544 ) const
1545 {
1546  for ( CI_1B_Methods::const_iterator iter = ci_1b_methods_.begin(),
1547  iter_end = ci_1b_methods_.end(); iter != iter_end; ++iter ) {
1548  (*iter)->residue_energy( rsd, pose, emap );
1549  }
1550 }
1551 
1552 void
1554  conformation::Residue const & rsd,
1555  pose::Pose const & pose,
1556  EnergyMap & emap
1557 ) const
1558 {
1559  for ( CD_1B_Methods::const_iterator iter = cd_1b_methods_.begin(),
1560  iter_end = cd_1b_methods_.end(); iter != iter_end; ++iter ) {
1561  (*iter)->residue_energy( rsd, pose, emap );
1562  }
1563 }
1564 
1565 
1566 ///////////////////////////////////////////////////////////////////////////////
1567 void
1569  conformation::Residue const & rsd1,
1570  conformation::Residue const & rsd2,
1571  pose::Pose const & pose,
1572  EnergyMap & emap
1573 ) const
1574 {
1575  for ( CI_2B_Methods::const_iterator iter = ci_2b_methods_.begin(),
1576  iter_end = ci_2b_methods_.end(); iter != iter_end; ++iter ) {
1577  (*iter)->residue_pair_energy( rsd1, rsd2, pose, *this, emap );
1578  }
1579 
1580 }
1581 
1582 
1583 void
1585  conformation::Residue const & rsd1,
1586  conformation::Residue const & rsd2,
1587  pose::Pose const & pose,
1588  EnergyMap & emap
1589 ) const
1590 {
1591  for ( CI_2B_Methods::const_iterator iter = ci_2b_methods_.begin(),
1592  iter_end = ci_2b_methods_.end(); iter != iter_end; ++iter ) {
1593  (*iter)->backbone_backbone_energy( rsd1, rsd2, pose, *this, emap );
1594  }
1595 
1596 }
1597 
1598 
1599 void
1601  conformation::Residue const & rsd1,
1602  conformation::Residue const & rsd2,
1603  pose::Pose const & pose,
1604  EnergyMap & emap
1605 ) const
1606 {
1607  for ( CI_2B_Methods::const_iterator iter = ci_2b_methods_.begin(),
1608  iter_end = ci_2b_methods_.end(); iter != iter_end; ++iter ) {
1609  (*iter)->backbone_sidechain_energy( rsd1, rsd2, pose, *this, emap );
1610  }
1611 
1612 }
1613 
1614 void
1616  conformation::Residue const & rsd1,
1617  conformation::Residue const & rsd2,
1618  pose::Pose const & pose,
1619  EnergyMap & emap
1620 ) const
1621 {
1622  for ( CI_2B_Methods::const_iterator iter = ci_2b_methods_.begin(),
1623  iter_end = ci_2b_methods_.end(); iter != iter_end; ++iter ) {
1624  (*iter)->sidechain_sidechain_energy( rsd1, rsd2, pose, *this, emap );
1625  }
1626 
1627 }
1628 
1629 
1630 
1631 ///////////////////////////////////////////////////////////////////////////////
1632 void
1634  conformation::Residue const & rsd1,
1635  conformation::Residue const & rsd2,
1636  pose::Pose const & pose,
1637  EnergyMap & emap
1638 ) const
1639 {
1640  for ( CD_2B_Methods::const_iterator
1641  iter = cd_2b_methods_.begin(),
1642  iter_end = cd_2b_methods_.end(); iter != iter_end; ++iter ) {
1643  (*iter)->residue_pair_energy( rsd1, rsd2, pose, *this, emap );
1644  }
1645 }
1646 
1647 void
1649  conformation::Residue const & rsd1,
1650  conformation::Residue const & rsd2,
1651  pose::Pose const & pose,
1652  EnergyMap & emap
1653 ) const
1654 {
1655  for ( CD_2B_Methods::const_iterator iter = cd_2b_methods_.begin(),
1656  iter_end = cd_2b_methods_.end(); iter != iter_end; ++iter ) {
1657  (*iter)->backbone_backbone_energy( rsd1, rsd2, pose, *this, emap );
1658  }
1659 
1660 }
1661 
1662 
1663 void
1665  conformation::Residue const & rsd1,
1666  conformation::Residue const & rsd2,
1667  pose::Pose const & pose,
1668  EnergyMap & emap
1669 ) const
1670 {
1671  for ( CD_2B_Methods::const_iterator iter = cd_2b_methods_.begin(),
1672  iter_end = cd_2b_methods_.end(); iter != iter_end; ++iter ) {
1673  (*iter)->backbone_sidechain_energy( rsd1, rsd2, pose, *this, emap );
1674  }
1675 
1676 }
1677 
1678 void
1680  conformation::Residue const & rsd1,
1681  conformation::Residue const & rsd2,
1682  pose::Pose const & pose,
1683  EnergyMap & emap
1684 ) const
1685 {
1686  for ( CD_2B_Methods::const_iterator iter = cd_2b_methods_.begin(),
1687  iter_end = cd_2b_methods_.end(); iter != iter_end; ++iter ) {
1688  (*iter)->sidechain_sidechain_energy( rsd1, rsd2, pose, *this, emap );
1689  }
1690 
1691 }
1692 
1693 
1694 
1695 /// @brief score the sidechain from rsd1 against the entirety of rsd2
1696 ///
1697 /// low fidelity description of what it would be like to replace
1698 /// the sidechain of rsd1 at a particular position -- only those scoring functions
1699 /// that specify they should be included in the bump check will be evaluated.
1700 /// The inaccuracy in this function is based on the change in LK solvation types
1701 /// and/or charges for backbone atoms when residues are mutated from one amino
1702 /// acid type to another (or from any other residue with backbone atoms)
1703 void
1705  conformation::Residue const & rsd1,
1706  conformation::Residue const & rsd2,
1707  pose::Pose const & pose,
1708  EnergyMap & emap
1709 ) const
1710 {
1711  for ( CD_2B_Methods::const_iterator iter = cd_2b_methods_.begin(),
1712  iter_end = cd_2b_methods_.end(); iter != iter_end; ++iter ) {
1713  (*iter)->bump_energy_full( rsd1, rsd2, pose, *this, emap );
1714  }
1715  for ( CI_2B_Methods::const_iterator iter = ci_2b_methods_.begin(),
1716  iter_end = ci_2b_methods_.end(); iter != iter_end; ++iter ) {
1717  (*iter)->bump_energy_full( rsd1, rsd2, pose, *this, emap );
1718  }
1719 
1720 }
1721 
1722 
1723 /// @details low fidelity description of what it would be like to replace
1724 /// the sidechain of rsd1 at a particular position knowing that
1725 /// rsd2's sidechain might also change sychronously.
1726 /// only those scoring functions that specify they should be included in the
1727 /// bump check will be evaluated.
1728 /// The inaccuracy in this function is based on the change in LK solvation types
1729 /// and/or charges for backbone atoms when residues are mutated from one amino
1730 /// acid type to another (or from any other residue with backbone atoms)
1731 void
1733  conformation::Residue const & rsd1,
1734  conformation::Residue const & rsd2,
1735  pose::Pose const & pose,
1736  EnergyMap & emap
1737 ) const
1738 {
1739  for ( CD_2B_Methods::const_iterator iter = cd_2b_methods_.begin(),
1740  iter_end = cd_2b_methods_.end(); iter != iter_end; ++iter ) {
1741  (*iter)->bump_energy_backbone( rsd1, rsd2, pose, *this, emap );
1742  }
1743  for ( CI_2B_Methods::const_iterator iter = ci_2b_methods_.begin(),
1744  iter_end = ci_2b_methods_.end(); iter != iter_end; ++iter ) {
1745  (*iter)->bump_energy_backbone( rsd1, rsd2, pose, *this, emap );
1746  }
1747 
1748 }
1749 
1750 void
1752  conformation::RotamerSetBase const & set1,
1753  conformation::RotamerSetBase const & set2,
1754  pose::Pose const & pose,
1755  FArray2D< core::PackerEnergy > & energy_table
1756 ) const
1757 {
1758  for ( CD_2B_Methods::const_iterator iter = cd_2b_methods_.begin(),
1759  iter_end = cd_2b_methods_.end(); iter != iter_end; ++iter ) {
1760  (*iter)->evaluate_rotamer_pair_energies(
1761  set1, set2, pose, *this, weights(), energy_table );
1762  }
1763  for ( CI_2B_Methods::const_iterator iter = ci_2b_methods_.begin(),
1764  iter_end = ci_2b_methods_.end(); iter != iter_end; ++iter ) {
1765  (*iter)->evaluate_rotamer_pair_energies(
1766  set1, set2, pose, *this, weights(), energy_table );
1767  }
1768 
1769 }
1770 
1771 /// @details Determines whether two positions could have non-zero interaction energy
1772 bool
1774  pose::Pose const & pose,
1775  Size const pos1,
1776  Size const pos2
1777 ) const
1778 {
1779  conformation::Residue const & rsd1( pose.residue( pos1 ) );
1780  conformation::Residue const & rsd2( pose.residue( pos2 ) );
1781 
1782  Real const intxn_radius( rsd1.nbr_radius() + rsd2.nbr_radius() + max_atomic_interaction_cutoff() );
1783 
1784  return ( ( intxn_radius > 0 &&
1785  rsd1.nbr_atom_xyz().distance_squared( rsd2.nbr_atom_xyz() ) < intxn_radius * intxn_radius ) ||
1786  ( any_lr_residue_pair_energy( pose, pos1, pos2 ) ) );
1787 }
1788 
1789 
1790 bool
1792  pose::Pose const & pose,
1793  Size res1,
1794  Size res2
1795 ) const
1796 {
1797  for ( LR_2B_Methods::const_iterator iter = lr_2b_methods_.begin(),
1798  iter_end = lr_2b_methods_.end(); iter != iter_end; ++iter ) {
1799  if ( (*iter)->defines_residue_pair_energy( pose, res1, res2 )) {
1800  return true;
1801  }
1802  }
1803 
1804  return false;
1805 }
1806 
1809 {
1810  return all_methods_.begin();
1811 }
1812 
1815 {
1816  return all_methods_.end();
1817 }
1818 
1821 {
1822  return lr_2b_methods_.begin();
1823 }
1824 
1827 {
1828  return lr_2b_methods_.end();
1829 }
1830 
1833 {
1834  return ci_2b_intrares_.begin();
1835 }
1836 
1839 {
1840  return ci_2b_intrares_.end();
1841 }
1842 
1845 {
1846  return cd_2b_intrares_.begin();
1847 }
1848 
1851 {
1852  return cd_2b_intrares_.end();
1853 }
1854 
1855 ScoreFunction::CI_2B_Methods::const_iterator
1857 {
1858  return ci_2b_methods_.begin();
1859 }
1860 
1861 ScoreFunction::CI_2B_Methods::const_iterator
1863 {
1864  return ci_2b_methods_.end();
1865 }
1866 
1867 ScoreFunction::CD_2B_Methods::const_iterator
1869 {
1870  return cd_2b_methods_.begin();
1871 }
1872 
1873 ScoreFunction::CD_2B_Methods::const_iterator
1875 {
1876  return cd_2b_methods_.end();
1877 }
1878 
1879 
1882 {
1883  return ci_lr_2b_methods_.begin();
1884 }
1885 
1888 {
1889  return ci_lr_2b_methods_.end();
1890 }
1891 
1894 {
1895  return cd_lr_2b_methods_.begin();
1896 }
1897 
1900 {
1901  return cd_lr_2b_methods_.end();
1902 }
1903 
1906 {
1907  return ws_methods_.begin();
1908 }
1909 
1912 {
1913  return ws_methods_.end();
1914 }
1915 
1916 /// @details Evaluate the energies between a set of rotamers and a single other (background) residue
1917 void
1919  conformation::RotamerSetBase const & set1,
1920  conformation::Residue const & residue2,
1921  pose::Pose const & pose,
1923 ) const
1924 {
1925  for ( CD_2B_Methods::const_iterator iter = cd_2b_methods_.begin(),
1926  iter_end = cd_2b_methods_.end(); iter != iter_end; ++iter ) {
1927  (*iter)->evaluate_rotamer_background_energies(
1928  set1, residue2, pose, *this, weights(), energy_vector );
1929  }
1930  for ( CI_2B_Methods::const_iterator iter = ci_2b_methods_.begin(),
1931  iter_end = ci_2b_methods_.end(); iter != iter_end; ++iter ) {
1932  (*iter)->evaluate_rotamer_background_energies(
1933  set1, residue2, pose, *this, weights(), energy_vector );
1934  }
1935 }
1936 
1937 
1938 ///////////////////////////////////////////////////////////////////////////////
1939 /// @details set the weight
1940 void
1941 ScoreFunction::set_weight( ScoreType const & t, Real const & setting )
1942 {
1943  using namespace methods;
1944 
1945  Real const old_weight( weights_[t] );
1946  weights_[t] = setting;
1947 
1948  if ( setting == Real(0.0) ) {
1949  if ( old_weight != Real(0.0) ) {
1950 
1952  assert( method );
1953 
1954  // check to see if there's a non-zero weight for this method
1955  bool has_nonzero_weight( false );
1956  for ( ScoreTypes::const_iterator
1957  iter = method->score_types().begin(),
1958  iter_end = method->score_types().end(); iter != iter_end; ++iter ) {
1959  if ( weights_[ *iter ] != 0.0 ) {
1960  has_nonzero_weight = true;
1961  break;
1962  }
1963  }
1964  if ( ! has_nonzero_weight ) {
1965  score_function_info_current_ = false; // cached score_function_info_ object no longer up-to-date
1966  remove_method( const_cast< EnergyMethod * > (method()) ); // cast to non-const, though, all this does is delete the object
1967  }
1968  } else {
1969  // Nothing needs doing. Early return. Be careful of intrares status and check_methods() for early returns!!!
1970  return;
1971  }
1972  } else {
1973  if ( old_weight == Real(0.0) ) {
1974  // do we already have a method that evaluates this score??
1975  if ( ! methods_by_score_type_[ t ] != 0 &&
1976  ( t != python ) ) { // sheffler
1977 
1978  score_function_info_current_ = false; // cached score_function_info_ object no longer up-to-date
1979  assert( std::abs( old_weight ) < 1e-2 ); // sanity
1980 
1981  // get pointer to the energyfunction that evaluates this score
1982  EnergyMethodOP method ( ScoringManager::get_instance()->energy_method( t, *energy_method_options_));
1983  add_method( method );
1984  } else {
1985  if ( t == python ) return; // escape for python defined scores -- intentially avoid update_intrares_status
1986  }
1987  } else {
1988  // only adjusted a weight that was already non-zero. Nothing else needs doing.
1989  // Early return. Be careful of intrares status and check_methods() for early returns!!!
1990  assert( old_weight != Real( 0.0 ) || weights_[ t ] != Real( 0.0 ) );
1991  return;
1992  }
1993  }
1994 
1995  // arriving here, we know that a weight went either to or from zero.
1996  // perform some neccessary bookkeeping.
1997  assert( old_weight == Real( 0.0 ) || weights_[ t ] == Real( 0.0 ) );
1998 
2000  assert( check_methods() );
2001 }
2002 
2003 
2004 ///////////////////////////////////////////////////////////////////////////////
2005 /// @details get the weight
2006 Real
2008 {
2009  return weights_[t];
2010 }
2011 
2012 
2013 ///////////////////////////////////////////////////////////////////////////////
2014 /// @details private
2015 bool
2017 {
2018  using namespace methods;
2019 
2020  EnergyMap counter;
2021  // counter indexes scoretypes to the number of energy methods. Each scoretype should only
2022  // map to one energy method.
2023  for ( AllMethods::const_iterator it=all_methods_.begin(),
2024  it_end = all_methods_.end(); it != it_end; ++it ) {
2025  for ( ScoreTypes::const_iterator t=(*it)->score_types().begin(),
2026  t_end=(*it)->score_types().end(); t != t_end; ++t ) {
2027  //++counter[ *t ]; //++ not defined for floats, right?
2028  counter[ *t ] += 1;
2029  }
2030  }
2031  for ( EnergyMap::const_iterator it=counter.begin(), it_end=counter.end();
2032  it != it_end; ++it ) {
2033  // total hack!!!
2034  ScoreType const t( static_cast< ScoreType >( it - counter.begin() + 1));
2035  Real const count( *it );
2036  if ( count > 1.5 ) {
2037  utility_exit_with_message("multiple methods for same score type!" );
2038  } else if ( count < 0.5 && std::abs( weights_[ t ] > 1e-2 ) ) {
2039  utility_exit_with_message(
2040  "no method for scoretype " + name_from_score_type( t ) + " w/nonzero weight!"
2041  );
2042  }
2043  }
2044  return true;
2045 }
2046 
2047 void
2049 {
2050  any_intrares_energies_ = false;
2051  ci_2b_intrares_.clear();
2052  cd_2b_intrares_.clear();
2053  for ( CD_2B_Methods::const_iterator iter = cd_2b_methods_.begin(),
2054  iter_end = cd_2b_methods_.end(); iter != iter_end; ++iter ) {
2055  if ( (*iter)->defines_intrares_energy(weights())) {
2056  any_intrares_energies_ = true;
2057  cd_2b_intrares_.push_back( (*iter)() );
2058  }
2059  }
2060  for ( CD_LR_2B_Methods::const_iterator iter = cd_lr_2b_methods_.begin(),
2061  iter_end = cd_lr_2b_methods_.end(); iter != iter_end; ++iter ) {
2062  if ( (*iter)->defines_intrares_energy(weights())) {
2063  any_intrares_energies_ = true;
2064  cd_2b_intrares_.push_back( (*iter)() );
2065  }
2066  }
2067 
2068  for ( CI_2B_Methods::const_iterator iter = ci_2b_methods_.begin(),
2069  iter_end = ci_2b_methods_.end(); iter != iter_end; ++iter ) {
2070  if ( (*iter)->defines_intrares_energy( weights() )) {
2071  any_intrares_energies_ = true;
2072  ci_2b_intrares_.push_back( (*iter)() );
2073  }
2074  }
2075  for ( CI_LR_2B_Methods::const_iterator iter = ci_lr_2b_methods_.begin(),
2076  iter_end = ci_lr_2b_methods_.end(); iter != iter_end; ++iter ) {
2077  if ( (*iter)->defines_intrares_energy( weights() )) {
2078  any_intrares_energies_ = true;
2079  ci_2b_intrares_.push_back( (*iter)() );
2080  }
2081  }
2082 }
2083 
2084 void
2086  pose::Pose & pose
2087 ) const
2088 {
2089 
2090  if ( ! pose.energies().use_nblist() ) {
2091  for ( AllMethods::const_iterator it=all_methods_.begin(),
2092  it_end = all_methods_.end(); it != it_end; ++it ) {
2093  (*it)->setup_for_scoring( pose, *this );
2094  }
2095  } else {
2096  assert( pose.energies().minimization_graph() );
2097  MinimizationGraphOP mingraph = pose.energies().minimization_graph();
2098 
2099  /// 1. setup_for_scoring for residue singles
2100  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
2101  mingraph->get_minimization_node( ii )->setup_for_scoring( pose.residue( ii ), pose, *this );
2102  }
2103 
2104  /// 2. inter-residue setup for derivatives
2106  edgeit = mingraph->edge_list_begin(), edgeit_end = mingraph->edge_list_end();
2107  edgeit != edgeit_end; ++edgeit ) {
2108  MinimizationEdge & minedge = static_cast< MinimizationEdge & > ( (**edgeit) );
2109  minedge.setup_for_scoring(
2110  pose.residue(minedge.get_first_node_ind()),
2111  pose.residue(minedge.get_second_node_ind()),
2112  pose, *this );
2113  }
2114 
2115  /// 3. Whole-pose-context energies should be allowed to setup for scoring now.
2116  for ( MinimizationGraph::Energies::const_iterator
2117  iter = mingraph->whole_pose_context_enmeths_begin(),
2118  iter_end = mingraph->whole_pose_context_enmeths_end();
2119  iter != iter_end; ++iter ) {
2120  (*iter)->setup_for_scoring( pose, *this );
2121  }
2122  }
2123 }
2124 
2125 ///////////////////////////////////////////////////////////////////////////////
2126 void
2128  pose::Pose & pose,
2129  utility::vector1< bool > const & residues_repacking,
2130  utility::vector1< bool > const & residues_designing
2131 ) const
2132 {
2133  for ( AllMethods::const_iterator iter=all_methods_.begin(),
2134  iter_end= all_methods_.end(); iter != iter_end; ++iter ) {
2135  (*iter)->setup_for_packing( pose, residues_repacking, residues_designing );
2136  }
2137 }
2138 
2139 ///
2140 void
2142  pose::Pose const & pose,
2144 ) const
2145 {
2146  for ( AllMethods::const_iterator iter=all_methods_.begin(),
2147  iter_end= all_methods_.end(); iter != iter_end; ++iter ) {
2148  (*iter)->prepare_rotamers_for_packing( pose, set );
2149  }
2150 }
2151 
2152 ///
2153 void
2155  pose::Pose & pose,
2156  Size resid
2157 ) const
2158 {
2159  for ( AllMethods::const_iterator iter=all_methods_.begin(),
2160  iter_end= all_methods_.end(); iter != iter_end; ++iter ) {
2161  (*iter)->update_residue_for_packing( pose, resid );
2162  }
2163 }
2164 
2165 ///////////////////////////////////////////////////////////////////////////////
2166 void
2168  pose::Pose & pose
2169 ) const
2170 {
2171  //std::cout << "ScoreFunction::setup_for_derivatives" << std::endl;
2172  //for ( AllMethods::const_iterator iter=all_methods_.begin(),
2173  // iter_end= all_methods_.end(); iter != iter_end; ++iter ) {
2174  // (*iter)->setup_for_derivatives( pose, *this );
2175  //}
2176 
2177  assert( pose.energies().minimization_graph() );
2178  MinimizationGraphOP mingraph = pose.energies().minimization_graph();
2179 
2180  /// 1. setup_for_derivatives for residue singles
2181  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
2182  MinimizationNode & iiminnode( * mingraph->get_minimization_node( ii ));
2183  iiminnode.setup_for_derivatives( pose.residue(ii), pose, *this );
2184  }
2185 
2186  /// 2. inter-residue setup for derivatives
2188  edgeit = mingraph->edge_list_begin(), edgeit_end = mingraph->edge_list_end();
2189  edgeit != edgeit_end; ++edgeit ) {
2190  MinimizationEdge & minedge = static_cast< MinimizationEdge & > ( (**edgeit) );
2191  minedge.setup_for_derivatives(
2192  pose.residue(minedge.get_first_node_ind()),
2193  pose.residue(minedge.get_second_node_ind()),
2194  pose, *this );
2195  }
2196 
2197  /// 3. Whole-pose-context energies should be allowed to setup for derivatives now.
2198  for ( MinimizationGraph::Energies::const_iterator
2199  iter = mingraph->whole_pose_context_enmeths_begin(),
2200  iter_end = mingraph->whole_pose_context_enmeths_end();
2201  iter != iter_end; ++iter ) {
2202  (*iter)->setup_for_derivatives( pose, *this );
2203  }
2204 
2205 }
2206 
2207 ///////////////////////////////////////////////////////////////////////////////
2208 void
2210  pose::Pose & pose
2211 ) const
2212 {
2213  //std::cout << "ScoreFunction::setup_for_derivatives" << std::endl;
2214  for ( AllMethods::const_iterator iter=all_methods_.begin(),
2215  iter_end= all_methods_.end(); iter != iter_end; ++iter ) {
2216  (*iter)->finalize_after_derivatives( pose, *this );
2217  }
2218 }
2219 
2220 ///////////////////////////////////////////////////////////////////////////////
2221 void
2223  pose::Pose & pose,
2224  kinematics::MinimizerMapBase const & min_map
2225 ) const
2226 {
2227 
2228  /// 1. Initialize the nodes in the energy graph with one-body
2229  /// and the intra-residue two-body energy methods
2230 
2231  /// 2. Initialize the short-ranged edges in the energy graph with
2232  /// the short-ranged two-body energy methods.
2233 
2234  /// 3. Initialize any additional edges with the long-range
2235  /// two-body energies
2236 
2237  /// 4. Drop any edges from the minimization graph that produce no
2238  /// energies, and call setup-for-minimization on all edges that remain
2239 
2240  /// 5. Setup whole-structure energies and energy methods that opt-out
2241  /// of the minimization-graph control over derivative evaluation.
2242 
2243 
2245  std::list< methods::EnergyMethodCOP > eval_derivs_with_pose_enmeths;
2246  for ( AllMethods::const_iterator iter=all_methods_.begin(),
2247  iter_end= all_methods_.end(); iter != iter_end; ++iter ) {
2248  if ((*iter)->defines_high_order_terms( pose ) || (*iter)->minimize_in_whole_structure_context( pose ) )
2249  eval_derivs_with_pose_enmeths.push_back( *iter );
2250  }
2251 
2252  EnergyMap fixed_energies; // portions of the score function that will not change over the course of minimization.
2253 
2254  kinematics::DomainMap const & domain_map = min_map.domain_map();
2255  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
2256  setup_for_minimizing_for_node( * g->get_minimization_node( ii ), pose.residue( ii ),
2257  min_map, pose, true, fixed_energies );
2258  }
2259 
2260  //EnergyGraph const & energy_graph( pose.energies().energy_graph() );
2261  g->copy_connectivity( pose.energies().energy_graph() );
2262  // 2. Now initialize the edges of the minimization graph using the edges of the EnergyGraph;
2263  // The energy graph should be up-to-date before this occurs
2265  edge_iter = g->edge_list_begin(),
2266  edge_iter_end = g->edge_list_end(),
2267  ee_edge_iter = pose.energies().energy_graph().edge_list_begin();
2268  edge_iter != edge_iter_end; ++edge_iter, ++ee_edge_iter ) {
2269  Size const node1 = (*edge_iter)->get_first_node_ind();
2270  Size const node2 = (*edge_iter)->get_second_node_ind();
2271  assert( node1 == (*ee_edge_iter)->get_first_node_ind() ); // copy_connectivity should preserve the energy-graph edge ordering
2272  assert( node2 == (*ee_edge_iter)->get_second_node_ind() ); // copy_connectivity should preserve the energy-graph edge ordering
2273 
2274  MinimizationEdge & minedge( static_cast< MinimizationEdge & > (**edge_iter) );
2275  // domain map check here?
2276  bool const res_moving_wrt_eachother(
2277  domain_map( node1 ) == 0 ||
2278  domain_map( node2 ) == 0 ||
2279  domain_map( node1 ) != domain_map( node2 ) );
2280 
2282  pose.residue( node1 ), pose.residue( node2 ),
2283  minedge, min_map, pose, res_moving_wrt_eachother, true,
2284  static_cast< EnergyEdge const * > (*ee_edge_iter), fixed_energies );
2285  }
2286 
2287  /// 3. Long range energies need time to get included into the graph, which may require the addition of new edges
2288  /// 3a: CILR2B energies
2289  /// i. Iterate across all ci2b long range energy methods
2290  /// ii. Iterate across all residue pairs indicated in the long-range energy containers
2291  /// iii. If two residues have the same non-zero domain-map coloring, then accumulate their interaction energy and move on
2292  /// iv. otherwise, find the corresponding minimization-graph edge for this residue pair
2293  /// v. adding a new edge if necessary,
2294  /// vi. and prepare the minimization data for this edge
2295 
2296  for ( LR_2B_MethodIterator
2297  iter = long_range_energies_begin(),
2298  iter_end = long_range_energies_end();
2299  iter != iter_end; ++iter ) {
2300 
2301  // NO! go ahead an include these terms in the minimization graph for the sake of scoring
2302  /// if ( (*iter)->minimize_in_whole_structure_context( pose ) ) continue;
2303 
2304  LREnergyContainerCOP lrec = pose.energies().long_range_container( (*iter)->long_range_type() );
2305  if ( !lrec || lrec->empty() ) continue;
2306 
2307  // Potentially O(N^2) operation...
2308  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
2310  rni = lrec->const_upper_neighbor_iterator_begin( ii ),
2311  rniend = lrec->const_upper_neighbor_iterator_end( ii );
2312  (*rni) != (*rniend); ++(*rni) ) {
2313  Size const jj = rni->upper_neighbor_id();
2314  bool const res_moving_wrt_eachother(
2315  domain_map( ii ) == 0 ||
2316  domain_map( jj ) == 0 ||
2317  domain_map( ii ) != domain_map( jj ) );
2319  pose.residue( ii ), pose.residue( jj ), *iter, *g, min_map, pose,
2320  res_moving_wrt_eachother, true, rni, fixed_energies );
2321  }
2322  }
2323  }
2324 
2325  /// 4. Call setup_for_minimizing on each edge that has active twobody energies, and drop
2326  /// all other edges.
2327  for ( core::graph::Graph::EdgeListIter edge_iter = g->edge_list_begin(),
2328  edge_iter_end = g->edge_list_end(); edge_iter != edge_iter_end; /* no increment */ ) {
2329  Size const node1 = (*edge_iter)->get_first_node_ind();
2330  Size const node2 = (*edge_iter)->get_second_node_ind();
2331 
2332  MinimizationEdge & minedge( static_cast< MinimizationEdge & > (**edge_iter) );
2333 
2334  core::graph::Graph::EdgeListIter edge_iter_next( edge_iter );
2335  ++edge_iter_next;
2336 
2337  if ( minedge.any_active_enmeths() ) {
2338  minedge.setup_for_minimizing( pose.residue(node1), pose.residue(node2), pose, *this, min_map );
2339  } else {
2340  /// The edge will not contribute anything to scoring during minimization,
2341  /// so delete it from the graph, so we don't have to pay the expense of traversing
2342  /// through it.
2343  g->delete_edge( *edge_iter );
2344  }
2345  edge_iter = edge_iter_next;
2346  }
2347 
2348  /// 5. Whole structure energies and energies that are opting out of the MinimizationGraph
2349  /// routines get a chance to setup for minimizing (using the entire pose as context) and
2350  for ( std::list< methods::EnergyMethodCOP >::const_iterator
2351  iter = eval_derivs_with_pose_enmeths.begin(),
2352  iter_end = eval_derivs_with_pose_enmeths.end();
2353  iter != iter_end; ++iter ) {
2354  (*iter)->setup_for_minimizing( pose, *this, min_map );
2355  g->add_whole_pose_context_enmeth( *iter );
2356  }
2357 
2358 
2359  //std::cout << "Fixed energies: ";
2360  //fixed_energies.show_if_nonzero_weight( std::cout, weights_ );
2361  //std::cout << std::endl;
2362 
2363  g->set_fixed_energies( fixed_energies );
2364  pose.energies().set_minimization_graph( g );
2365 }
2366 
2367 /// @details Note that energy methods should be added to the MinimizationGraph
2368 /// reguardless of whether or not they have been modernized to use the
2369 /// eval_residue_derivatives/eval_residue_pair_derivatives machinery.
2370 /// (Grandfathered EnergyMethods return "false" in their version of
2371 /// minimize_in_whole_structure_context() and have their derivatives still
2372 /// evaluated in the one-atom-at-a-time scheme.) The reason these
2373 /// grandfathered energy methods should be added to the MinimizationGraph is
2374 /// to ensure that their energies are still computed during minimization-score-
2375 /// function evaluation.
2376 void
2378  MinimizationNode & min_node,
2379  conformation::Residue const & rsd,
2380  kinematics::MinimizerMapBase const & min_map,
2381  pose::Pose & pose, // context
2382  bool accumulate_fixed_energies,
2383  EnergyMap & fixed_energies
2384 ) const
2385 {
2386  kinematics::DomainMap const & domain_map( min_map.domain_map() );
2387  Size seqpos( rsd.seqpos() );
2388  /// 1a: context-independent 1body energies
2389  for ( CI_1B_Methods::const_iterator iter = ci_1b_methods_.begin(),
2390  iter_end = ci_1b_methods_.end(); iter != iter_end; ++iter ) {
2391 
2392  min_node.add_onebody_enmeth( *iter, rsd, pose, domain_map( seqpos ) );
2393  if ( domain_map( seqpos ) != 0 && accumulate_fixed_energies ) {
2394  fixed_energies.accumulate( pose.energies().onebody_energies( seqpos ), (*iter)->score_types() );
2395  }
2396  }
2397  /// 1b: context-dependent 1body energies
2398  for ( CD_1B_Methods::const_iterator iter = cd_1b_methods_.begin(),
2399  iter_end = cd_1b_methods_.end(); iter != iter_end; ++iter ) {
2400  // domain map check here?
2401  continue;
2402  min_node.add_onebody_enmeth( *iter, rsd, pose, domain_map( seqpos ) );
2403  }
2404  /// 1c: context-independent 2body energies
2405  for ( CI_2B_Methods::const_iterator iter = ci_2b_methods_.begin(),
2406  iter_end = ci_2b_methods_.end(); iter != iter_end; ++iter ) {
2407  // domain map check here?
2408  //std::cout << "seqpos " << seqpos << " " << domain_map( seqpos ) << std::endl;
2409  min_node.add_twobody_enmeth( *iter, rsd, pose, weights_, domain_map( seqpos ) );
2410  if ( domain_map( seqpos ) != 0 && accumulate_fixed_energies ) {
2411  //std::cout << "accumulating one body energies for " << seqpos << std::endl;
2412  fixed_energies.accumulate( pose.energies().onebody_energies( seqpos ), (*iter)->score_types() );
2413  }
2414  }
2415 
2416  /// 1d: context-dependent 2body energies
2417  for ( CD_2B_Methods::const_iterator iter = cd_2b_methods_.begin(),
2418  iter_end = cd_2b_methods_.end(); iter != iter_end; ++iter ) {
2419  min_node.add_twobody_enmeth( *iter, rsd, pose, weights_, domain_map( seqpos ) );
2420  }
2421  /// 1e: all long-range 2body energies -- maybe this should be divided into ci and cd loops?
2422  for ( LR_2B_Methods::const_iterator iter = lr_2b_methods_.begin(),
2423  iter_end = lr_2b_methods_.end(); iter != iter_end; ++iter ) {
2424  min_node.add_twobody_enmeth( *iter, rsd, pose, weights_, domain_map( seqpos ) );
2425  if ( domain_map( seqpos ) == 0 && accumulate_fixed_energies && (*iter)->method_type() == methods::ci_lr_2b ) {
2426  fixed_energies.accumulate( pose.energies().onebody_energies( seqpos ), (*iter)->score_types() );
2427  }
2428  }
2429  min_node.setup_for_minimizing( rsd, pose, *this, min_map );
2430 }
2431 
2432 void
2434  MinimizationNode & min_node,
2435  conformation::Residue const & rsd,
2436  kinematics::MinimizerMapBase const & min_map,
2437  pose::Pose & pose // context
2438 ) const
2439 {
2440  min_node.update_active_enmeths_for_residue( rsd, pose, weights_, min_map.domain_map()( rsd.seqpos() ) );
2441  min_node.setup_for_minimizing( rsd, pose, *this, min_map );
2442 /*
2443  kinematics::DomainMap const & domain_map( min_map.domain_map() );
2444  Size seqpos( rsd.seqpos() );
2445  /// 1a: context-independent 1body energies
2446  for ( CI_1B_Methods::const_iterator iter = ci_1b_methods_.begin(),
2447  iter_end = ci_1b_methods_.end(); iter != iter_end; ++iter ) {
2448  if ( domain_map( seqpos ) == 0 && ! (*iter)->minimize_in_whole_structure_context( pose ) ) {
2449  if ( (*iter)->defines_score_for_residue( rsd )) {
2450  (*iter)->setup_for_minimizing_for_residue(
2451  rsd, pose, *this, min_map,
2452  min_node.res_min_data() );
2453  }
2454  }
2455  }
2456  /// 1b: context-dependent 1body energies
2457  for ( CD_1B_Methods::const_iterator iter = cd_1b_methods_.begin(),
2458  iter_end = cd_1b_methods_.end(); iter != iter_end; ++iter ) {
2459  // domain map check here?
2460  if ( ! (*iter)->minimize_in_whole_structure_context( pose ) && (*iter)->defines_score_for_residue( rsd )) {
2461  (*iter)->setup_for_minimizing_for_residue(
2462  rsd, pose, *this, min_map,
2463  min_node.res_min_data() );
2464  }
2465  }
2466  /// 1c: context-independent 2body energies
2467  for ( CI_2B_Methods::const_iterator iter = ci_2b_methods_.begin(),
2468  iter_end = ci_2b_methods_.end(); iter != iter_end; ++iter ) {
2469  if ( ! (*iter)->minimize_in_whole_structure_context( pose ) ) {
2470  /// Only provide the setup opportunity to enmeths that are not relying on whole-structure
2471  /// minimization logic
2472  (*iter)->setup_for_minimizing_for_residue(
2473  rsd, pose, *this, min_map,
2474  min_node.res_min_data() );
2475  }
2476  }
2477 
2478  /// 1d: context-dependent 2body energies
2479  for ( CD_2B_Methods::const_iterator iter = cd_2b_methods_.begin(),
2480  iter_end = cd_2b_methods_.end(); iter != iter_end; ++iter ) {
2481  // domain map check here?
2482  if ( ! (*iter)->minimize_in_whole_structure_context( pose ) ) {
2483  (*iter)->setup_for_minimizing_for_residue(
2484  rsd, pose, *this, min_map,
2485  min_node.res_min_data() );
2486  }
2487  }
2488  /// 1e: all long-range 2body energies -- maybe this should be divided into ci and cd loops?
2489  for ( LR_2B_Methods::const_iterator iter = lr_2b_methods_.begin(),
2490  iter_end = lr_2b_methods_.end(); iter != iter_end; ++iter ) {
2491  // domain map check here? -- should separate CI and CD LR2B energies
2492  if ( ! (*iter)->minimize_in_whole_structure_context( pose ) ) {
2493  (*iter)->setup_for_minimizing_for_residue(
2494  rsd, pose, *this, min_map,
2495  min_node.res_min_data() );
2496  }
2497  }*/
2498 
2499 }
2500 
2501 
2502 void
2504  conformation::Residue const & res1,
2505  conformation::Residue const & res2,
2506  MinimizationEdge & min_edge,
2508  pose::Pose & pose,
2509  bool const res_moving_wrt_eachother,
2510  bool accumulate_fixed_energies,
2511  EnergyEdge const * energy_edge,
2512  EnergyMap & fixed_energies,
2513  Real const // apl -- remove this parameter edge_weight
2514 ) const
2515 {
2516  assert( ! accumulate_fixed_energies || energy_edge );
2517 
2518  /// First, the context-independent 2body energies
2519  if ( res_moving_wrt_eachother ) {
2520  for ( CI_2B_Methods::const_iterator iter = ci_2b_methods_.begin(),
2521  iter_end = ci_2b_methods_.end(); iter != iter_end; ++iter ) {
2522  min_edge.add_twobody_enmeth( *iter, res1, res2, pose, res_moving_wrt_eachother );
2523  }
2524  } else if ( accumulate_fixed_energies ) {
2525  energy_edge->add_to_energy_map( fixed_energies, ci_2b_types() );
2526  }
2527 
2528  /// Second, the context-dependent 2body energies
2529  for ( CD_2B_Methods::const_iterator iter = cd_2b_methods_.begin(),
2530  iter_end = cd_2b_methods_.end(); iter != iter_end; ++iter ) {
2531  if ( ! min_edge.add_twobody_enmeth( *iter, res1, res2, pose, res_moving_wrt_eachother )
2532  && accumulate_fixed_energies ) {
2533  energy_edge->add_to_energy_map( fixed_energies, (*iter)->score_types() );
2534  }
2535  }
2536 }
2537 
2538 void
2540  conformation::Residue const & res1,
2541  conformation::Residue const & res2,
2543  MinimizationGraph & g,
2545  pose::Pose & pose,
2546  bool const res_moving_wrt_eachother,
2547  bool accumulate_fixed_energies,
2549  EnergyMap & fixed_energies,
2550  Real const edge_weight
2551 ) const
2552 {
2553  Size const seqpos1( res1.seqpos() );
2554  Size const seqpos2( res2.seqpos() );
2555 
2556  if ( res_moving_wrt_eachother &&
2557  lr2benergy->defines_score_for_residue_pair( res1, res2, res_moving_wrt_eachother )) {
2558 
2559  /// 3. iv Find the edge in the graph
2560  MinimizationEdge * minedge( static_cast< MinimizationEdge * > (g.find_edge( seqpos1, seqpos2)) );
2561  /// 3. v Create a new edge if necessary
2562  if ( ! minedge ) minedge = static_cast< MinimizationEdge * > (g.add_edge( seqpos1, seqpos2));
2563  /// 3. vi. Now initialize this edge
2564 
2565  minedge->add_twobody_enmeth( lr2benergy, res1, res2, pose, res_moving_wrt_eachother );
2566  minedge->weight( edge_weight );
2567  } else if ( accumulate_fixed_energies ) {
2568 
2569  /// Even if edge_weight != 1.0, don't scale the energies stored in the residue-neighbor-iterator,
2570  /// because, in the case of symmetric scoring, these energies have already been scaled.
2571  rni->accumulate_energy( fixed_energies );
2572  }
2573 
2574 }
2575 
2576 ///////////////////////////////////////////////////////////////////////////////
2577 void
2579  id::AtomID const & atom_id,
2580  pose::Pose const & pose,
2581  kinematics::DomainMap const & domain_map,
2582  Vector & F1,
2583  Vector & F2
2584 ) const
2585 {
2586  //for ( AllMethods::const_iterator iter=all_methods_.begin(),
2587  // iter_end= all_methods_.end(); iter != iter_end; ++iter ) {
2588  // (*iter)->eval_atom_derivative( atom_id, pose, domain_map, *this, weights_, F1, F2 );
2589  //}
2590 
2591  assert( pose.energies().minimization_graph() );
2592  MinimizationGraphCOP mingraph = pose.energies().minimization_graph();
2593 
2594  /// Whole-pose-context energies should have their contribution calculated here.
2595  for ( MinimizationGraph::Energies::const_iterator
2596  iter = mingraph->whole_pose_context_enmeths_begin(),
2597  iter_end = mingraph->whole_pose_context_enmeths_end();
2598  iter != iter_end; ++iter ) {
2599  (*iter)->eval_atom_derivative( atom_id, pose, domain_map, *this, weights_, F1, F2 );
2600  }
2601 
2602 }
2603 
2604 ///////////////////////////////////////////////////////////////////////////////
2605 Real
2607  id::DOF_ID const & dof_id,
2608  id::TorsionID const & torsion_id,
2609  pose::Pose const & pose
2610 ) const
2611 {
2612 
2613  /*for ( AllMethods::const_iterator iter=all_methods_.begin(),
2614  iter_end= all_methods_.end(); iter != iter_end; ++iter ) {
2615 // for ( CI_1B_Methods::const_iterator iter = ci_1b_methods_.begin(),
2616 // iter_end = ci_1b_methods_.end(); iter != iter_end; ++iter ) {
2617  deriv += (*iter)->eval_dof_derivative( dof_id, torsion_id, pose, *this, weights_ );
2618  }*/
2619 
2620  assert( pose.energies().minimization_graph() );
2621  MinimizationGraphCOP mingraph = pose.energies().minimization_graph();
2622 
2623  Size const rsdno = torsion_id.valid() ? torsion_id.rsd() : dof_id.atom_id().rsd();
2624  conformation::Residue const & rsd = pose.residue( rsdno );
2625 
2626  MinimizationNode const & minnode = * mingraph->get_minimization_node( rsdno );
2627 
2628  return eval_dof_deriv_for_minnode( minnode, rsd, pose, dof_id, torsion_id, *this, weights_ );
2629 }
2630 
2631 ///////////////////////////////////////////////////////////////////////////////
2632 // void
2633 // ScoreFunction::zero_energies(
2634 // methods::EnergyMethodType const & t,
2635 // EnergyMap & emap
2636 // ) const
2637 // {
2638 // using namespace methods;
2639 
2640 // for ( AllMethods::const_iterator iter= all_methods_.begin(),
2641 // iter_end = all_methods_.end(); iter != iter_end; ++iter ) {
2642 // if ( (*iter)->method_type() == t ) {
2643 // for ( ScoreTypes::const_iterator it2 = (*iter)->score_types().begin(),
2644 // it2_end = (*iter)->score_types().end(); it2 != it2_end; ++it2 ) {
2645 // emap[ *it2 ] = 0.0;
2646 // }
2647 // }
2648 // }
2649 // }
2650 
2651 
2652 ///////////////////////////////////////////////////////////////////////////////
2655 {
2656  if ( ! score_function_info_current_ ) {
2657  score_function_info_->initialize_from( *this );
2659  }
2660  return new ScoreFunctionInfo( *score_function_info_ );
2661 }
2662 
2664  return all_methods_;
2665 }
2666 
2667 
2668 
2669 ///////////////////////////////////////////////////////////////////////////////
2670 /// @details private -- handles setting the derived data
2671 
2672 void
2674 {
2675  using namespace methods;
2676 
2677  all_methods_.push_back( method );
2678 
2679  // mapping from ScoreType to EnergyMethod
2680  for ( ScoreTypes::const_iterator
2681  iter = method->score_types().begin(),
2682  iter_end = method->score_types().end(); iter != iter_end; ++iter ) {
2683  methods_by_score_type_[ *iter ] = method;
2684  score_types_by_method_type_[ method->method_type() ].push_back( *iter );
2685  }
2686 
2687  // PHIL replace these with utility::down_cast when it's working
2688  switch ( method->method_type() ) {
2689  case ci_2b:
2690  // there must be an easier way to cast these owning pointers!
2691  ci_2b_methods_.push_back
2692  ( static_cast< ContextIndependentTwoBodyEnergy* >( method() ) );
2693  break;
2694 
2695  case cd_2b:
2696  cd_2b_methods_.push_back
2697  ( static_cast< ContextDependentTwoBodyEnergy* >( method() ) );
2698  break;
2699 
2700  case ci_1b:
2701  ci_1b_methods_.push_back
2702  ( static_cast< ContextIndependentOneBodyEnergy* >( method() ) );
2703  break;
2704 
2705  case cd_1b:
2706  cd_1b_methods_.push_back
2707  ( static_cast< ContextDependentOneBodyEnergy* >( method() ) );
2708  break;
2709 
2710  case ci_lr_2b:
2711  ci_lr_2b_methods_.push_back(
2712  static_cast< ContextIndependentLRTwoBodyEnergy* >( method() ) );
2713  lr_2b_methods_.push_back(
2714  static_cast< LongRangeTwoBodyEnergy* >( method() ) );
2715  break;
2716 
2717  case cd_lr_2b:
2718  cd_lr_2b_methods_.push_back(
2719  static_cast< ContextDependentLRTwoBodyEnergy* >( method() ) );
2720  lr_2b_methods_.push_back(
2721  static_cast< LongRangeTwoBodyEnergy* >( method() ) );
2722  break;
2723 
2724  case ws:
2725  ws_methods_.push_back(
2726  static_cast< WholeStructureEnergy* >( method() ) );
2727  break;
2728 
2729  default:
2730  utility_exit_with_message( "unrecognized method type " );
2731  } // switch
2732 }
2733 
2734 
2735 /// @details Add a scoring method that's not necessarily included in the core library
2736 /// @note Currently only works for methods associated with a single specific score_type
2737 void
2739  ScoreType const & new_type,
2740  Real const new_weight,
2741  methods::EnergyMethod const & new_method
2742 )
2743 {
2744  if ( weights_[ new_type] != Real( 0.0 ) ||
2745  new_weight == Real(0.0) ||
2746  new_method.score_types().size() != 1 ||
2747  new_method.score_types().front() != new_type ) {
2748  utility_exit_with_message( "bad call to ScoreFunction::add_extra_method" );
2749  }
2750  weights_[ new_type ] = new_weight;
2751  add_method( new_method.clone() );
2752 }
2753 
2754 
2755 /// @details Add a scoring method that's not necessarily included in the core library
2756 ///
2757 void
2759  std::map< ScoreType, Real > const & new_weights,
2760  methods::EnergyMethod const & new_method
2761 )
2762 {
2763  for ( std::map< ScoreType, Real >::const_iterator it= new_weights.begin(); it != new_weights.end(); ++it ) {
2764  ScoreType const new_type( it->first );
2765  Real const new_weight( it->second );
2766  if ( ( weights_[ new_type ] != Real(0.0) ) ||
2767  ( std::find( new_method.score_types().begin(), new_method.score_types().end(), new_type ) ==
2768  new_method.score_types().end() ) ) {
2769  utility_exit_with_message( "bad call to ScoreFunction::add_extra_method" );
2770  }
2771  weights_[ new_type ] = new_weight;
2772  }
2773  add_method( new_method.clone() );
2774 }
2775 
2776 
2777 ///////////////////////////////////////////////////////////////////////////////
2778 /// private -- handles setting the derived data
2779 
2780 // This can/should be moved to utility/vector1.hh
2781 template< class T >
2782 inline
2783 void
2785 {
2786  assert( std::find( v.begin(), v.end(), t ) != v.end() );
2787  v.erase( std::find( v.begin(), v.end(), t ) );
2788 }
2789 
2790 void
2792 {
2793  using namespace methods;
2795 
2796  // mapping from ScoreType to EnergyMethod
2797  for ( ScoreTypes::const_iterator
2798  iter = method->score_types().begin(),
2799  iter_end = method->score_types().end(); iter != iter_end; ++iter ) {
2800  methods_by_score_type_[ *iter ] = 0;
2801  vector1_remove( score_types_by_method_type_[ method->method_type() ], *iter );
2802  }
2803 
2804  bool rebuild_lr_methods( false );
2805  // PHIL replace these with utility::down_cast when it's working
2806  switch ( method->method_type() ) {
2807  case ci_2b:
2808  // there must be an easier way to cast these owning pointers!
2810  ContextIndependentTwoBodyEnergyOP(( static_cast< ContextIndependentTwoBodyEnergy* >( method() ) )));
2811  break;
2812 
2813  case cd_2b:
2815  ContextDependentTwoBodyEnergyOP(( static_cast< ContextDependentTwoBodyEnergy* >( method() ) ) ));
2816  break;
2817 
2818  case ci_1b:
2820  ContextIndependentOneBodyEnergyOP(( static_cast< ContextIndependentOneBodyEnergy* >( method() ) )));
2821  break;
2822 
2823  case cd_1b:
2825  ContextDependentOneBodyEnergyOP(( static_cast< ContextDependentOneBodyEnergy* >( method() ) )));
2826  break;
2827 
2828  case ci_lr_2b:
2829  rebuild_lr_methods = true;
2831  ContextIndependentLRTwoBodyEnergyOP(static_cast< ContextIndependentLRTwoBodyEnergy* >( method() )));
2832  break;
2833 
2834  case cd_lr_2b:
2835  rebuild_lr_methods = true;
2837  ContextDependentLRTwoBodyEnergyOP( static_cast< ContextDependentLRTwoBodyEnergy* >( method() )));
2838  break;
2839 
2840  case ws:
2842  WholeStructureEnergyOP( static_cast< WholeStructureEnergy* >( method() )));
2843  break;
2844 
2845  default:
2846  utility_exit_with_message( "unrecognized method type " );
2847  } // switch
2848 
2849  if ( rebuild_lr_methods ) {
2850  lr_2b_methods_.clear();
2851  for ( CD_LR_2B_Methods::const_iterator iter = cd_lr_2b_methods_.begin(),
2852  iter_end = cd_lr_2b_methods_.end(); iter != iter_end; ++iter ) {
2853  lr_2b_methods_.push_back( *iter );
2854  }
2855  for ( CI_LR_2B_Methods::const_iterator iter = ci_lr_2b_methods_.begin(),
2856  iter_end = ci_lr_2b_methods_.end(); iter != iter_end; ++iter ) {
2857  lr_2b_methods_.push_back( *iter );
2858  }
2859  }
2860 
2861 }
2862 
2863 ///////////////////////////////////////////////////////////////////////////////
2864 void
2866 {
2867  // clear (may not be necessary)
2868  all_methods_.clear();
2869  methods_by_score_type_.clear();
2871 
2872  ci_2b_methods_.clear();
2873  cd_2b_methods_.clear();
2874  ci_1b_methods_.clear();
2875  cd_1b_methods_.clear();
2876  ci_lr_2b_methods_.clear();
2877  cd_lr_2b_methods_.clear();
2878  lr_2b_methods_.clear();
2879  ws_methods_.clear();
2880 
2881  // some need resizing
2883  //std::fill( methods_by_score_type_.begin(), methods_by_score_type_.end(), ); // wipe old pointers
2884  for ( Size ii = 1; ii <= n_score_types; ++ii ) { methods_by_score_type_[ ii ] = 0; }
2886  for ( Size ii = 1; ii <= methods::n_energy_method_types; ++ii ) {
2887  score_types_by_method_type_[ ii ].clear();
2888  }
2889 }
2890 
2891 /// @details determines the furthest-reach of the short-range two body energies
2892 /// as well as the whole-structure energies, which are allowed to require
2893 /// that the EnergyGraph have edges of a minimum length.
2894 Distance
2896  Distance max_cutoff = 0;
2897 
2898  for ( CD_2B_Methods::const_iterator iter = cd_2b_methods_.begin(),
2899  iter_end = cd_2b_methods_.end(); iter != iter_end; ++iter ) {
2900  if ( (*iter)->atomic_interaction_cutoff() > max_cutoff ) {
2901  max_cutoff = (*iter)->atomic_interaction_cutoff();
2902  }
2903  }
2904  for ( CI_2B_Methods::const_iterator iter = ci_2b_methods_.begin(),
2905  iter_end = ci_2b_methods_.end(); iter != iter_end; ++iter ) {
2906  if ( (*iter)->atomic_interaction_cutoff() > max_cutoff ) {
2907  max_cutoff = (*iter)->atomic_interaction_cutoff();
2908  }
2909  }
2910  for ( WS_Methods::const_iterator iter = ws_methods_.begin(),
2911  iter_end = ws_methods_.end(); iter != iter_end; ++iter ) {
2912  if ( (*iter)->atomic_interaction_cutoff() > max_cutoff ) {
2913  max_cutoff = (*iter)->atomic_interaction_cutoff();
2914  }
2915  }
2916 
2917  return max_cutoff;
2918 }
2919 
2920 ///@brief scoring function fills in the context graphs that its energy methods require
2921 ///
2922 /// input vector should be false and have num_context_graph_types slots. Each method
2923 /// ors its required context graphs
2924 void
2926  utility::vector1< bool > & context_graphs_required
2927 ) const
2928 {
2929  for ( AllMethods::const_iterator it=all_methods_.begin(),
2930  it_end = all_methods_.end(); it != it_end; ++it ) {
2931  (*it)->indicate_required_context_graphs(context_graphs_required);
2932  }
2933 }
2934 
2935 
2936 ///////////////////////////////////////////////////////////////////////////////
2937 ///////////////////////////////////////////////////////////////////////////////
2938 ///////////////////////////////////////////////////////////////////////////////
2939 
2940 /// @brief Utility function to locate a weights or patch file, either with a fully qualified path,
2941 /// in the local directory, or in the database. Names may be passed either with or without the
2942 /// optional extension.
2943 
2946  utility::io::izstream data1( name );
2947  if ( data1.good() ) {
2948  return name;
2949  } else {
2950  utility::io::izstream data2( name + extension );
2951  if ( data2.good() ) {
2952  return name + extension;
2953  } else {
2954  utility::io::izstream data3( basic::database::full_name( "scoring/weights/"+name+extension, /*warn=*/false ) );
2955  if ( data3.good() ) {
2956  return basic::database::full_name( "scoring/weights/"+name+extension );
2957  } else {
2958  utility::io::izstream data4( basic::database::full_name( "scoring/weights/"+name, false ) );
2959  if ( data4.good() ) {
2960  return basic::database::full_name( "scoring/weights/"+name );
2961  } else {
2962  utility_exit_with_message( "Unable to open weights/patch file. None of (./)" + name + " or " +
2963  "(./)" + name + extension + " or " +
2964  basic::database::full_name( "scoring/weights/"+name, false ) + " or " +
2965  basic::database::full_name( "scoring/weights/"+name+extension, false ) + " exist" );
2966  return "invalid"; // To make the compiler happy - should never reach here.
2967  }
2968  }
2969  }
2970  }
2971 }
2972 
2973 
2974 
2975 } // namespace scoring
2976 } // namespace core