Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SymmetricScoreFunction.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 // This file is part of the Rosetta software suite and is made available under license.
5 // The Rosetta software is developed by the contributing members of the Rosetta Commons consortium.
6 // (C) 199x-2009 Rosetta Commons participating institutions and developers.
7 // For more information, see http://www.rosettacommons.org/.
8 
9 /// @file core/scoring/ScoreFunction.cc
10 /// @brief ScoreFunction class definition.
11 /// @author Stuart G. Mentzer (Stuart_Mentzer@objexx.com)
12 /// @author Kevin P. Hinshaw (KevinHinshaw@gmail.com)
13 /// @author Modified by Sergey Lyskov
14 
15 
16 // Unit headers
19 
20 // Package headers
24 
26 // AUTO-REMOVED #include <core/scoring/methods/EnergyMethodOptions.hh>
28 // AUTO-REMOVED #include <core/scoring/methods/ContextIndependentTwoBodyEnergy.hh>
30 // AUTO-REMOVED #include <core/scoring/methods/ContextDependentTwoBodyEnergy.hh>
31 // AUTO-REMOVED #include <core/scoring/methods/ContextIndependentOneBodyEnergy.hh>
32 // AUTO-REMOVED #include <core/scoring/methods/ContextDependentOneBodyEnergy.hh>
37 
38 // // Project headers
40 #include <core/id/TorsionID.hh>
41 #include <basic/Tracer.hh>
42 #include <core/pose/Pose.hh>
43 #include <core/scoring/Energies.hh>
44 #include <basic/prof.hh>
45 
46 // Symmetry extras
47 // AUTO-REMOVED #include <core/conformation/RotamerSetBase.hh> // TMP HACK
49 #include <basic/datacache/CacheableData.hh> //TMP HACK
50 //#include <core/scoring/symmetry/NBListCache.hh>
51 //#include <core/scoring/symmetry/NBListCache.fwd.hh>
54 // AUTO-REMOVED #include <core/conformation/symmetry/util.hh>
55 
57 
58 #include <utility/vector1.hh>
59 
60 //Auto Headers
62 
63 namespace core {
64 namespace scoring {
65 namespace symmetry {
66 
67 using namespace conformation::symmetry;
68 
69 static basic::Tracer TR("core.scoring.SymmetricScoreFunction");
70 ///////////////////////////////////////////////////////////////////////////////
73  {}
74 
75 ///////////////////////////////////////////////////////////////////////////////
78 {
79  return new SymmetricScoreFunction( *this );
80 }
81 
82 ///////////////////////////////////////////////////////////////////////////////
85 {
87  return *this;
88 }
89 
90 ///////////////////////////////////////////////////////////////////////////////
92  ScoreFunction( src )
93 {}
94 
96  ScoreFunction( src )
97 {}
98 
100  ScoreFunction( *src )
101 {}
102 
104  ScoreFunction( *src )
105 {}
106 
107 ///////////////////////////////////////////////////////////////////////////////
108 
109 // to start out, just thinking fullatom energies
110 //
111 // NOTE: no freakin rotamer trials inside scoring!
112 Real
114 {
115  // This is tricky! If we are non-symmetric we want to use the regular score function
116  // instead.
117  if ( !core::pose::symmetry::is_symmetric( pose ) ) {
118  TR << "Warning!!! Using a symmetric score function on a non-symmetric pose" << std::endl;
119  ScoreFunction asym_score( static_cast< ScoreFunction const & >( (*this) ) );
120  return ( asym_score )(pose);
121  }
122 
123  // completely unnecessary temporary hack to force refold if nec. for profiling
124  pose.residue( pose.total_residue() );
125 
126  PROF_START( basic::SCORE );
127  //std::cout << "ScoreFunction::operator()\n";
128 
129  // notify the pose that we are starting a score evaluation.
130  // also tells the cached energies object about the scoring
131  // parameters, for the purposes of invalidating cached data
132  // if necessary
133  //
134  // at this point the dof/xyz-moved information will be converted
135  // to a domain map. Energy/neighbor links between pair-moved residues
136  // will be deleted, and 1d energies of res-moved residues will be
137  // cleared.
138  //
139  // further structure modification will be prevented until scoring is
140  // completed
141  //
142  pose.scoring_begin( *this );
143  //std::cout << "ScoreFunction::operator() 1\n";
144 
145  if ( pose.energies().total_energy() != 0.0 ) {
146  TR.Error << "STARTING SCORE NON-ZERO!" << std::endl;
147  }
148 
149  // ensure that the total_energies are zeroed out -- this happens in Energies.scoring_begin()
150  // unneccessary pose.energies().total_energies().clear();
151  //std::cout << "ScoreFunction::operator() 2\n";
152 
153  // do any setup necessary
154  setup_for_scoring( pose );
155  //std::cout << "ScoreFunction::operator() 3\n";
156 
157  // Make some arrays symmetrical before scoring
159 
160 
161  // evaluate the residue-residue energies that only exist between
162  // neighboring residues
163  PROF_START( basic::SCORE_NEIGHBOR_ENERGIES );
164 
166 
167  PROF_STOP ( basic::SCORE_NEIGHBOR_ENERGIES );
168 
169  // Ingemar, I put this in.... -Will
170  PROF_START( basic::SCORE_LONG_RANGE_ENERGIES );
172  PROF_STOP ( basic::SCORE_LONG_RANGE_ENERGIES );
173 
174  // evaluate the onebody energies -- rama, dunbrack, ...
175  eval_onebody_energies( pose );
176 
177  // give energyfunctions a chance update/finalize energies
178  // etable nblist calculation is performed here
180  iter_end= all_energies_end(); iter != iter_end; ++iter ) {
181  (*iter)->finalize_total_energy( pose, *this, pose.energies().finalized_energies() );
182  }
183 
184  correct_finalize_score( pose );
185 
186  pose.energies().total_energies() += pose.energies().finalized_energies();
187 
188  if ( pose.energies().use_nblist() ) {
189  pose.energies().total_energies() += pose.energies().minimization_graph()->fixed_energies();
190  }
191 
192  //std::cout << "SymSfxn: " << pose.energies().use_nblist() << " ";
193  //pose.energies().total_energies().show_if_nonzero_weight( std::cout, weights() );
194  //std::cout << std::endl;
195 
196  // dot the weights with the scores
197  pose.energies().total_energy() = pose.energies().total_energies().dot( weights() );
199 
200  // notify that scoring is over
201  pose.scoring_end( *this );
202 
203  PROF_STOP ( basic::SCORE );
204 
205  return pose.energies().total_energy();
206 }
207 
208 void
210  pose::Pose & pose,
211  kinematics::MinimizerMapBase const & min_map
212 ) const
213 {
214  /// 1. Initialize the nodes of the minimization graph
215  /// 2. Initialize the edges with the short-ranged two-body energies
216  /// 3. Initialize the edges with the long-ranged two-body energies
217  /// 4. Run setup-for-minimization on the edges of the mingraph; dropping edges with no active 2b enmeths.
218  /// 5. Let whole-structure energies initialize themselves
219 
220  SymmetricConformation & symm_conf (
221  dynamic_cast<SymmetricConformation &> ( pose.conformation()) );
222  SymmetryInfo const & symm_info( * symm_conf.Symmetry_Info() );
223 
224  SymmetricEnergies & symm_energies(
225  dynamic_cast< SymmetricEnergies & > ( pose.energies()) );
226 
227 
229  MinimizationGraphOP dg = new MinimizationGraph( pose.total_residue() ); // derivative graph
230 
231  std::list< methods::EnergyMethodCOP > eval_derivs_with_pose_enmeths;
232  for ( AllMethods::const_iterator iter=all_methods().begin(),
233  iter_end= all_methods().end(); iter != iter_end; ++iter ) {
234  if ((*iter)->defines_high_order_terms( pose ) || (*iter)->minimize_in_whole_structure_context( pose ) )
235  eval_derivs_with_pose_enmeths.push_back( *iter );
236  }
237 
238  EnergyMap fixed_energies; // portions of the score function that will not change over the course of minimization.
239 
240  /// Accumulate the portions of the scoring function for those residues with non-zero domain-map values
241  /// but also let all energy methods register with each node, since some may require a setup-for-scoring opportunity
242  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
243 
244  bool accumulate_fixed_energies( symm_info.fa_is_independent(ii) &&
245  ii > symm_info.num_total_residues_without_pseudo() );
246 
247  setup_for_minimizing_for_node( * g->get_minimization_node( ii ), pose.residue( ii ),
248  min_map, pose, accumulate_fixed_energies, fixed_energies );
249  g->get_minimization_node( ii )->weight( symm_info.score_multiply_factor() );
250  setup_for_minimizing_for_node( * dg->get_minimization_node( ii ), pose.residue( ii ),
251  min_map, pose, false, fixed_energies ); // only accumulate once
252  }
253  g->copy_connectivity( pose.energies().energy_graph() );
254  dg->copy_connectivity( pose.energies().energy_graph() );
255 
256  kinematics::DomainMap const & domain_map( min_map.domain_map() );
258  edge_iter = g->edge_list_begin(),
259  edge_iter_end = g->edge_list_end(),
260  dedge_iter = dg->edge_list_begin(),
261  dedge_iter_end = dg->edge_list_end(),
262  ee_edge_iter = pose.energies().energy_graph().edge_list_begin();
263  edge_iter != edge_iter_end; ++edge_iter, ++dedge_iter, ++ee_edge_iter ) {
264  Size const node1 = (*edge_iter)->get_first_node_ind();
265  Size const node2 = (*edge_iter)->get_second_node_ind();
266  assert( node1 == (*ee_edge_iter)->get_first_node_ind() ); // copy_connectivity should preserve the energy-graph edge ordering
267  assert( node2 == (*ee_edge_iter)->get_second_node_ind() ); // copy_connectivity should preserve the energy-graph edge ordering
268  assert( node1 == (*dedge_iter)->get_first_node_ind() ); // copy_connectivity should preserve the energy-graph edge ordering
269  assert( node2 == (*dedge_iter)->get_second_node_ind() ); // copy_connectivity should preserve the energy-graph edge ordering
270  assert( symm_info.bb_follows( node1 ) == 0 || symm_info.bb_follows( node2 ) == 0 );
271 
272  // domain map check here?
273  bool const res_moving_wrt_eachother(
274  domain_map( node1 ) == 0 ||
275  domain_map( node2 ) == 0 ||
276  domain_map( node1 ) != domain_map( node2 ) );
277 
278  Real edge_weight = symm_info.score_multiply( node1, node2 );
279  if ( edge_weight != 0.0 ) {
280 
281  MinimizationEdge & minedge( static_cast< MinimizationEdge & > (**edge_iter) );
283  pose.residue( node1 ), pose.residue( node2 ),
284  minedge, min_map, pose, res_moving_wrt_eachother, true,
285  static_cast< EnergyEdge const * > (*ee_edge_iter), fixed_energies, edge_weight );
286  minedge.weight( edge_weight );
287  } else {
288  MinimizationEdge & minedge( static_cast< MinimizationEdge & > (**dedge_iter) );
290  pose.residue( node1 ), pose.residue( node2 ),
291  minedge, min_map, pose, res_moving_wrt_eachother, false,
292  static_cast< EnergyEdge const * > (*ee_edge_iter), fixed_energies ); // edge weight of 1
293  }
294  }
295 
296  /// 3. Long range energies need time to get included into the graph, which may require the addition of new edges
297  /// 3a: CILR2B energies
298  /// i. Iterate across all ci2b long range energy methods
299  /// ii. Iterate across all residue pairs indicated in the long-range energy containers
300  /// iii. If two residues have the same non-zero domain-map coloring, then accumulate their interaction energy and move on
301  /// iv. otherwise, find the corresponding minimization-graph edge for this residue pair
302  /// v. adding a new edge if necessary,
303  /// vi. and prepare the minimization data for this edge
304 
306  iter = long_range_energies_begin(),
307  iter_end = long_range_energies_end();
308  iter != iter_end; ++iter ) {
309  // NO! add these terms to the minimization graph for scoring, even if not for derivative evaluation
310  ///if ( (*iter)->minimize_in_whole_structure_context( pose ) ) continue;
311 
312  LREnergyContainerCOP lrec = pose.energies().long_range_container( (*iter)->long_range_type() );
313  if ( !lrec || lrec->empty() ) continue;
314 
315  // Potentially O(N^2) operation...
316  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
318  rni = lrec->const_upper_neighbor_iterator_begin( ii ),
319  rniend = lrec->const_upper_neighbor_iterator_end( ii );
320  (*rni) != (*rniend); ++(*rni) ) {
321  Size const jj = rni->upper_neighbor_id();
322  bool const res_moving_wrt_eachother(
323  domain_map( ii ) == 0 ||
324  domain_map( jj ) == 0 ||
325  domain_map( ii ) != domain_map( jj ) );
326 
327  Real edge_weight = symm_info.score_multiply( ii, jj );
328  if ( edge_weight != 0.0 ) {
329  // adjust/add the edge to the scoring graph
331  pose.residue( ii ), pose.residue( jj ), *iter, *g, min_map, pose,
332  res_moving_wrt_eachother, true, rni, fixed_energies, edge_weight );
333  } else {
334  /// adjust/add this edge to the derivative graph
336  pose.residue( ii ), pose.residue( jj ), *iter, *dg, min_map, pose,
337  res_moving_wrt_eachother, false, rni, fixed_energies ); // no edge weight
338  }
339  }
340  }
341  }
342 
343  /// 4a. drop unused edges from the scoring graph; call setup for minimizing on those remaining
344  for ( core::graph::Graph::EdgeListIter edge_iter = g->edge_list_begin(),
345  edge_iter_end = g->edge_list_end(); edge_iter != edge_iter_end; /* no increment */ ) {
346  Size const node1 = (*edge_iter)->get_first_node_ind();
347  Size const node2 = (*edge_iter)->get_second_node_ind();
348 
349  MinimizationEdge & minedge( static_cast< MinimizationEdge & > (**edge_iter) );
350 
351  core::graph::Graph::EdgeListIter edge_iter_next( edge_iter );
352  ++edge_iter_next;
353 
354  if ( minedge.any_active_enmeths() ) {
355  //std::cout << " active scoring graph edge: " << node1 << " " << node2 << std::endl;
356  minedge.setup_for_minimizing( pose.residue(node1), pose.residue(node2), pose, *this, min_map );
357  } else {
358  /// The edge will not contribute anything to scoring during minimization,
359  /// so delete it from the graph, so we don't have to pay the expense of traversing
360  /// through it.
361  g->delete_edge( *edge_iter );
362  }
363  edge_iter = edge_iter_next;
364  }
365 
366  /// 4b. drop unused edges from the derivatives graph; call setup for minimizing on those remaining
367  for ( core::graph::Graph::EdgeListIter edge_iter = dg->edge_list_begin(),
368  edge_iter_end = dg->edge_list_end(); edge_iter != edge_iter_end; /* no increment */ ) {
369  Size const node1 = (*edge_iter)->get_first_node_ind();
370  Size const node2 = (*edge_iter)->get_second_node_ind();
371 
372  MinimizationEdge & minedge( static_cast< MinimizationEdge & > (**edge_iter) );
373 
374  core::graph::Graph::EdgeListIter edge_iter_next( edge_iter );
375  ++edge_iter_next;
376 
377  if ( minedge.any_active_enmeths() ) {
378  //std::cout << " active deriv graph edge: " << node1 << " " << node2 << std::endl;
379  minedge.setup_for_minimizing( pose.residue(node1), pose.residue(node2), pose, *this, min_map );
380  } else {
381  /// The edge will not contribute anything to derivative evaluation during minimization;
382  /// it either represents an interaction that is not changing as the result of minimization,
383  /// or the interaction is handled by the scoring graph. Delete it from the graph so
384  /// we don't have to pay the expense of traversing through it.
385  g->delete_edge( *edge_iter );
386  }
387  edge_iter = edge_iter_next;
388  }
389 
390  /// 5. Whole structure energies and energies that are opting out of the MinimizationGraph
391  /// routines get a chance to setup for minimizing (using the entire pose as context) and
392  for ( std::list< methods::EnergyMethodCOP >::const_iterator
393  iter = eval_derivs_with_pose_enmeths.begin(),
394  iter_end = eval_derivs_with_pose_enmeths.end();
395  iter != iter_end; ++iter ) {
396  (*iter)->setup_for_minimizing( pose, *this, min_map );
397  g->add_whole_pose_context_enmeth( *iter );
398  }
399 
400 
401  //std::cout << "Fixed energies: ";
402  //fixed_energies.show_if_nonzero_weight( std::cout, weights() );
403  //std::cout << std::endl;
404 
405  g->set_fixed_energies( fixed_energies );
406  symm_energies.set_minimization_graph( g );
407  symm_energies.set_derivative_graph( dg );
408 
409 }
410 
411 
412 ///////////////////////////////////////////////////////////////////////////////
413 
414 void
416  pose::Pose & pose
417 ) const
418 {
419  // cached energies object
420  Energies & energies( pose.energies() );
421 
422  EnergyMap & total_energies( const_cast< EnergyMap & > ( energies.total_energies() ) );
423 
424  SymmetricConformation & SymmConf (
425  dynamic_cast<SymmetricConformation &> ( pose.conformation()) );
426  SymmetryInfoCOP symm_info( SymmConf.Symmetry_Info() );
427 
428  // the neighbor/energy links
429  EnergyGraph & energy_graph( energies.energy_graph() );
430 
431  // are we using the atom-atom nblist?
432  // renaming for true purpose: are we minimizing -- if so,
433  // zero the energies stored on edges in the Energy graph, but do
434  // not mark the edges as having had their energies computed
435  bool const minimizing( energies.use_nblist() );
436 
437  if ( minimizing ) {
438  /// When minimizing, do not touch the EnergyGraph -- leave it fixed
439  MinimizationGraphCOP g = energies.minimization_graph();
440  EnergyMap scratch_emap;
442  edge_iter = g->const_edge_list_begin(),
443  edge_iter_end = g->const_edge_list_end();
444  edge_iter != edge_iter_end; ++edge_iter ) {
445  Size const node1 = (*edge_iter)->get_first_node_ind();
446  Size const node2 = (*edge_iter)->get_second_node_ind();
447  conformation::Residue const & rsd1( pose.residue( node1 ));
448  conformation::Residue const & rsd2( pose.residue( node2 ));
449  MinimizationEdge const & minedge( static_cast< MinimizationEdge const & > (**edge_iter) );
450 
451  eval_weighted_res_pair_energy_for_minedge( minedge, rsd1, rsd2, pose, *this, total_energies, scratch_emap );
452  }
453 
454  } else {
455  EnergyMap tbemap;
456 
457  for ( Size i=1, i_end = pose.total_residue(); i<= i_end; ++i ) {
458  conformation::Residue const & resl( pose.residue( i ) );
460  iru = energy_graph.get_node(i)->upper_edge_list_begin(),
461  irue = energy_graph.get_node(i)->upper_edge_list_end();
462  iru != irue; ++iru ) {
463  EnergyEdge & edge( static_cast< EnergyEdge & > (**iru) );
464 
465  Size const j( edge.get_second_node_ind() );
466  conformation::Residue const & resu( pose.residue( j ) );
467  // the pair energies cached in the link
468  ///EnergyMap & emap( energy_edge->energy_map() );
469  tbemap.zero( cd_2b_types() );
470  tbemap.zero( ci_2b_types() );
471 
472  // the context-dependent guys can't be cached, so they are always reevaluated
473  eval_cd_2b( resl, resu, pose, tbemap );
474 
475  for ( Size ii = 1; ii <= cd_2b_types().size(); ++ii ) {
476  tbemap[ cd_2b_types()[ ii ]] *= symm_info->score_multiply(i,j);
477  }
478 
479  if ( edge.energies_not_yet_computed() ) {
480  // energies not yet computed? <-> (during minimization w/ nblist) moving rsd pair
481  /// TEMP zero portions;
482 
483  if ( minimizing ) {
484  // confirm that this rsd-rsd interaction will be included
485  // in the atom pairs on the nblist:
486  //assert( ( pose.energies().domain_map(i) !=
487  // pose.energies().domain_map(j) ) ||
488  // ( pose.energies().res_moved(i) ) );
489  // ensure that these are zeroed, since we will hit them at the
490  // end inside the nblist calculation
491  // they almost certainly should be, since the energies have not
492  // yet been computed...
493  eval_ci_2b( resl, resu, pose, tbemap );
494  for ( Size ii = 1; ii <= ci_2b_types().size(); ++ii ) {
495  tbemap[ ci_2b_types()[ ii ]] *= symm_info->score_multiply(i,j);
496  }
497 
498  edge.store_active_energies( tbemap );
499  // do not mark energies as computed!!!!!!!!!!!!!
500  } else {
501  eval_ci_2b( resl, resu, pose, tbemap );
502  for ( Size ii = 1; ii <= ci_2b_types().size(); ++ii ) {
503  tbemap[ ci_2b_types()[ ii ]] *= symm_info->score_multiply(i,j);
504  }
505 
506  edge.store_active_energies( tbemap );
507  edge.mark_energies_computed();
508  }
509  } else {
510  /// Read the CI energies from the edge, as they are still valid;
511  for ( Size ii = 1; ii <= ci_2b_types().size(); ++ii ) {
512  tbemap[ ci_2b_types()[ ii ]] = edge[ ci_2b_types()[ ii ] ];
513  }
514 
515  /// Save the freshly computed CD energies on the edge
516  edge.store_active_energies( tbemap, cd_2b_types() );
517  }
518 
519  total_energies.accumulate( tbemap, ci_2b_types() );
520  total_energies.accumulate( tbemap, cd_2b_types() );
521  }
522  } // nbrs of i
523  } // i=1,nres
524 
525 }
526 
527 void
529 {
530  bool const minimizing( pose.energies().use_nblist() );
531  if ( minimizing ) return; // long range energies are handled as part of the 2-body energies in the minimization graph
532 
533  // find SymmInfo
534  SymmetricConformation & SymmConf (
535  dynamic_cast<SymmetricConformation &> ( pose.conformation()) );
536  SymmetryInfoCOP symm_info( SymmConf.Symmetry_Info() );
537 
538  EnergyMap & total_energies(const_cast< EnergyMap & > (pose.energies().total_energies()));
539 
541  iter_end = ci_lr_2b_methods_end(); iter != iter_end; ++iter ) {
542 
543  LREnergyContainerOP lrec = pose.energies().nonconst_long_range_container( (*iter)->long_range_type() );
544  if ( !lrec || lrec->empty() ) continue; // only score non-emtpy energies.
545 
546  // Potentially O(N^2) operation...
547  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
549  rni = lrec->upper_neighbor_iterator_begin( ii ),
550  rniend = lrec->upper_neighbor_iterator_end( ii );
551  (*rni) != (*rniend); ++(*rni) ) {
552  EnergyMap emap;
553  if ( ! rni->energy_computed() ) {
554  Size jj = rni->upper_neighbor_id();
555  (*iter)->residue_pair_energy( pose.residue(ii), pose.residue( jj ), pose, *this, emap );
556  emap *= symm_info->score_multiply( ii, jj );
557  rni->save_energy( emap );
558 
559  /// DANGER DANGER DANGER. use_nblist() now means "In the process of a minimization". There is
560  /// no such thing as a non-neighborlist minimization. This will confuse people at some point.
561  /// We ought to have some "are we minimizing currently" flag who's meaning can be decoupled
562  /// from the neighborlist idea.
563  if ( ! pose.energies().use_nblist() ) {
564  // Do we need to do this symmetrically?
565  rni->mark_energy_computed();
566  }
567  } else {
568  rni->retrieve_energy( emap ); // pbmod
569  }
570  total_energies += emap;
571  }
572  }
573  }
574 
575  //fpd CD LR methods should always be computed
577  iter_end = cd_lr_2b_methods_end(); iter != iter_end; ++iter ) {
578 
580  = pose.energies().nonconst_long_range_container( (*iter)->long_range_type() );
581 
582  // Potentially O(N^2) operation...
583  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
585  rni = lrec->upper_neighbor_iterator_begin( ii ),
586  rniend = lrec->upper_neighbor_iterator_end( ii );
587  (*rni) != (*rniend); ++(*rni) ) {
588 
589  EnergyMap emap;
590  Size jj = rni->upper_neighbor_id();
591  (*iter)->residue_pair_energy( pose.residue(ii), pose.residue(jj), pose, *this, emap );
592  emap *= symm_info->score_multiply( ii, jj );
593 
594  rni->save_energy( emap );
595  //rni->mark_energy_computed();
596 
597  total_energies += emap;
598 
599  }
600  }
601  }
602 }
603 
604 
605 ///////////////////////////////////////////////////////////////////////////////
606 void
608 {
609  // context independent onebody energies
610  Energies & energies( pose.energies() );
611  EnergyMap & totals( energies.total_energies() );
612 
613  // find SymmInfo
614  SymmetricConformation & SymmConf (
615  dynamic_cast<SymmetricConformation &> ( pose.conformation()) );
616  SymmetryInfoCOP symm_info( SymmConf.Symmetry_Info() );
617 
618  bool const minimizing( energies.use_nblist() );
619 
620  if ( minimizing ) {
621  EnergyMap scratch_emap;
622  MinimizationGraphCOP mingraph = energies.minimization_graph();
623  assert( mingraph );
624  for ( Size ii = 1; ii <= symm_info->num_total_residues_without_pseudo(); ++ii ) {
625  if ( !symm_info->fa_is_independent(ii) ) continue;
626 
627  conformation::Residue const & rsd = pose.residue( ii );
628 
629  MinimizationNode const & iiminnode = * mingraph->get_minimization_node( ii );
630  eval_weighted_res_onebody_energies_for_minnode( iiminnode, rsd, pose, *this, totals, scratch_emap );
631 
632  }
633  } else {
634  for ( Size i=1; i<= pose.total_residue(); ++i ) {
635  if ( !symm_info->fa_is_independent(i) ||
636  i > symm_info->num_total_residues_without_pseudo() ) continue;
637 
638  EnergyMap & emap( energies.onebody_energies( i ) );
639 
640  // 1body intxns ///////////////////////////
641  if ( energies.res_moved( i ) ) {
642  // have to recalculate
643  emap.clear(); // should already have been done when the domain map was internalized
644  eval_ci_1b( pose.residue(i), pose, emap );
645  emap *= symm_info->score_multiply(i,i);
646  }
647 
648  emap.zero( cd_1b_types() ); // cant be cached
649  EnergyMap cd_1b_emap;
650  eval_cd_1b( pose.residue(i), pose, cd_1b_emap );
651  cd_1b_emap *= symm_info->score_multiply_factor();
652  emap += cd_1b_emap;
653 
654  // 2body energy methods are allowed to define 1body intxns ///////////////////////////
655  if ( any_intrares_energies() ) {
656  // context independent:
657  if ( energies.res_moved( i ) ) {
658  EnergyMap ci_intrares_emap;
659  eval_ci_intrares_energy( pose.residue(i), pose, ci_intrares_emap );
660  ci_intrares_emap *= symm_info->score_multiply_factor();
661  emap += ci_intrares_emap;
662  }
663  // context dependent
664  emap.zero( cd_2b_types() ); // cant be cached (here only intrares are relevant)
665  emap.zero( cd_lr_2b_types() ); // cant be cached (here only intrares are relevant)
666  EnergyMap cd_2b_emap = emap;
667  eval_cd_intrares_energy( pose.residue(i), pose, emap );
668  cd_2b_emap -= emap;
669  cd_2b_emap *= -1.0;
670  cd_2b_emap *= symm_info->score_multiply_factor();
671  }
672 
673  totals += emap;
674 
675  energies.reset_res_moved( i ); // mark one body energies as having been calculated
676  for ( std::vector< Size>::const_iterator
677  clone = symm_info->bb_clones( i ).begin(),
678  clone_end = symm_info->bb_clones( i ).end();
679  clone != clone_end; ++clone ){
680  energies.reset_res_moved( *clone );
681  }
682  }
683  //std::cout << "totals: "<< i << totals;
684  }
685 }
686 
687 
688 void
690 {
691  SymmetricConformation & symm_conf (
692  dynamic_cast<SymmetricConformation &> ( pose.conformation()) );
693  SymmetryInfoCOP symm_info( symm_conf.Symmetry_Info() );
694 
695  SymmetricEnergies & symm_energies( dynamic_cast< SymmetricEnergies & > ( pose.energies()) );
696 
697  /// 1. Call setup_for_derivatives on the (active) nodes of the scoring graph; a node is active
698  /// if it's part of the asymmetric unit, or if it has any edge
699  MinimizationGraphOP g = symm_energies.minimization_graph();
700  for ( Size ii = 1; ii <= symm_info->num_total_residues_without_pseudo(); ++ii ) {
701  if ( symm_info->bb_is_independent( ii ) || g->get_node( ii )->num_edges() != 0 ) {
702  g->get_minimization_node( ii )->setup_for_derivatives( pose.residue(ii), pose, *this );
703  }
704  }
705  /// 2. Call setup_for_derivatives on the edges of the scoring graph
707  edgeit = g->edge_list_begin(), edgeit_end = g->edge_list_end();
708  edgeit != edgeit_end; ++edgeit ) {
709  MinimizationEdge & minedge = static_cast< MinimizationEdge & > ( (**edgeit) );
710  minedge.setup_for_derivatives(
711  pose.residue(minedge.get_first_node_ind()),
712  pose.residue(minedge.get_second_node_ind()),
713  pose, *this );
714  }
715 
716  MinimizationGraphOP dg = symm_energies.derivative_graph();
717  /// 3. Call setup_for_derivatives on the (active) nodes of the derivatives graph; here, if a node in the asymmetric unit
718  /// has no edges, then all of its derivaties will be handled by the scoring graph; we don't need to call
719  /// setup for derivatives on that node.
720  for ( Size ii = 1; ii <= symm_info->num_total_residues_without_pseudo(); ++ii ) {
721  if ( dg->get_node( ii )->num_edges() != 0 ) {
722  dg->get_minimization_node( ii )->setup_for_derivatives( pose.residue(ii), pose, *this );
723  }
724  }
725  /// 4. Call setup_for_derivatives on the edges of the derivatives graph
727  edgeit = dg->edge_list_begin(), edgeit_end = dg->edge_list_end();
728  edgeit != edgeit_end; ++edgeit ) {
729  MinimizationEdge & minedge = static_cast< MinimizationEdge & > ( (**edgeit) );
730  minedge.setup_for_derivatives(
731  pose.residue(minedge.get_first_node_ind()),
732  pose.residue(minedge.get_second_node_ind()),
733  pose, *this );
734  }
735 
736  /// 5. Whole-pose-context energies should be allowed to setup for derivatives now.
737  for ( MinimizationGraph::Energies::const_iterator
738  iter = g->whole_pose_context_enmeths_begin(),
739  iter_end = g->whole_pose_context_enmeths_end();
740  iter != iter_end; ++iter ) {
741  (*iter)->setup_for_derivatives( pose, *this );
742  }
743 }
744 
745 ///////////////////////////////////////////////////////////////////////////////
746 void
748  id::AtomID const & atom_id,
749  pose::Pose const & pose,
750  kinematics::DomainMap const & domain_map,
751  Vector & F1,
752  Vector & F2
753 ) const
754 {
755  //std::cout << "SymmetricScoreFunction::eval_atom_derivative " << atom_id.rsd() << " " << atom_id.atomno() << " " << F1.x() << " " << F2.x() << std::endl;
756 
757  SymmetricEnergies const & symm_energies( dynamic_cast< SymmetricEnergies const & > (pose.energies()) );
758 
759  assert( pose.energies().minimization_graph() );
760  MinimizationGraphCOP mingraph = symm_energies.minimization_graph();
761  //MinimizationGraphCOP dmingraph = symm_energies.derivative_graph();
762 
763  /*Size const rsdno = atom_id.rsd();
764  Size const atomno = atom_id.atomno();
765 
766  conformation::Residue const & rsd = pose.residue( rsdno );
767 
768  MinimizationNode const & minnode = * mingraph->get_minimization_node( rsdno );
769  /// 1. eval intra-residue derivatives
770  eval_atom_derivative_for_minnode( minnode, atomno, rsd, pose, domain_map, *this, weights(), F1, F2 );
771 
772  ResSingleMinimizationData const & ressingle_min_data( minnode.res_min_data() );
773  /// 2a. eval inter-residue derivatives using edges from the scoring graph
774  for ( graph::Node::EdgeListConstIter
775  edgeit = minnode.const_edge_list_begin(), edgeit_end = minnode.const_edge_list_end();
776  edgeit != edgeit_end; ++edgeit ) {
777  Vector f1(0.0), f2(0.0);
778  MinimizationEdge const & minedge = static_cast< MinimizationEdge const & > ( (**edgeit) );
779  Size const other_rsdno = minedge.get_other_ind( rsdno );
780  conformation::Residue const & other_rsd( pose.residue( other_rsdno ));
781  ResSingleMinimizationData const & other_ressingle_min_data( mingraph->get_minimization_node( other_rsdno )->res_min_data() );
782 
783  eval_atom_deriv_for_minedge( minedge, atomno, rsd, other_rsd,
784  ressingle_min_data, other_ressingle_min_data,
785  pose, domain_map, *this, weights(), f1, f2 );
786  //std::cout << " scoring minedge with " << other_rsdno << " " << f1.x() << " " << f2.x() << std::endl;
787  F1 += f1;
788  F2 += f2;
789  }
790 
791  /// 2b. eval inter-residue derivatives using edges from the scoring graph
792  ResSingleMinimizationData const & dressingle_min_data( dmingraph->get_minimization_node( rsdno )->res_min_data() );
793  for ( graph::Node::EdgeListConstIter
794  edgeit = dmingraph->get_minimization_node( rsdno )->const_edge_list_begin(),
795  edgeit_end = dmingraph->get_minimization_node( rsdno )->const_edge_list_end();
796  edgeit != edgeit_end; ++edgeit ) {
797  Vector f1(0.0), f2(0.0);
798  MinimizationEdge const & minedge = static_cast< MinimizationEdge const & > ( (**edgeit) );
799  Size const other_rsdno = minedge.get_other_ind( rsdno );
800  conformation::Residue const & other_rsd( pose.residue( other_rsdno ));
801  ResSingleMinimizationData const & other_dressingle_min_data( dmingraph->get_minimization_node( other_rsdno )->res_min_data() );
802 
803  eval_atom_deriv_for_minedge( minedge, atomno, rsd, other_rsd,
804  dressingle_min_data, other_dressingle_min_data,
805  pose, domain_map, *this, weights(), f1, f2 );
806  //std::cout << " deriv minedge with " << other_rsdno << " " << f1.x() << " " << f2.x() << std::endl;
807  F1 += f1;
808  F2 += f2;
809  }*/
810 
811  /// 3. Whole-pose-context energies should have their contribution calculated here.
812  for ( MinimizationGraph::Energies::const_iterator
813  iter = mingraph->whole_pose_context_enmeths_begin(),
814  iter_end = mingraph->whole_pose_context_enmeths_end();
815  iter != iter_end; ++iter ) {
816  (*iter)->eval_atom_derivative( atom_id, pose, domain_map, *this, weights(), F1, F2 );
817  }
818 
819 }
820 
821 ///////////////////////////////////////////////////////////////////////////////
822 Real
824  id::DOF_ID const & dof_id,
825  id::TorsionID const & torsion_id,
826  pose::Pose const & pose
827 ) const
828 {
829 
830  assert( pose.energies().minimization_graph() );
832 
833  Size const rsdno = torsion_id.valid() ? torsion_id.rsd() : dof_id.atom_id().rsd();
834  conformation::Residue const & rsd = pose.residue( rsdno );
835 
836  MinimizationNode const & minnode = * mingraph->get_minimization_node( rsdno );
837 
838  return eval_weighted_dof_deriv_for_minnode( minnode, rsd, pose, dof_id, torsion_id, *this, weights() );
839 }
840 
841 void
843  pose::Pose & pose,
844  EnergyMap & intersubunit_energy
845 ) const
846 {
847 
849 
850  hbonds::HBondSet const & hbond_set(
851  static_cast< hbonds::HBondSet const & > ( pose.energies().data().get( HBOND_SET )));
852 
853  SymmetricConformation & SymmConf (
854  dynamic_cast<SymmetricConformation &> ( pose.conformation()) );
855  SymmetryInfoCOP symm_info( SymmConf.Symmetry_Info() );
856 
857 
858  for ( Size i = 1; i <= hbond_set.nhbonds(); ++i ) {
859  hbonds::HBond const & hbond( hbond_set.hbond(i) );
860 
861  Real sr_bb_hbenergy = 0.0;
862  Real lr_bb_hbenergy = 0.0;
863 
864  switch ( get_hbond_weight_type( hbond.eval_type() ) ) {
865  case hbonds::hbw_SR_BB:
866  sr_bb_hbenergy = hbond.energy() * hbond.weight();
867  break;
868  case hbonds::hbw_LR_BB:
869  lr_bb_hbenergy = hbond.energy() * hbond.weight();
870  break;
873  case hbonds::hbw_SC:
874  // dont care about these
875  break;
876  default:
877  TR.Warning << "Warning: energy from unexpected HB type ignored " << hbond.eval_type() << std::endl;
878  break;
879  }
880  Size factor (0);
881 
882  // get the score factor for this edge
883  factor = symm_info->score_multiply( hbond.don_res() , hbond.acc_res() );
884 
885  // adjust for self-hbonds
886  //fpd is this necessary?
887  if ( symm_info->bb_follows( hbond.acc_res() ) == hbond.don_res() ||
888  symm_info->bb_follows( hbond.don_res() ) == hbond.acc_res() ) {
889  factor = symm_info->score_multiply_factor() - 1;
890  }
891  intersubunit_energy[ hbond_lr_bb ] += factor*lr_bb_hbenergy;
892  intersubunit_energy[ hbond_sr_bb ] += factor*sr_bb_hbenergy;
893  }
894 }
895 
896 void
898 {
900 
901  hbonds::HBondSetOP hbond_set
902  ( static_cast< hbonds::HBondSet & > ( pose.energies().data().get( HBOND_SET )));
903 
904  SymmetricConformation & SymmConf (
905  dynamic_cast<SymmetricConformation &> ( pose.conformation()) );
906  SymmetryInfoCOP symm_info( SymmConf.Symmetry_Info() );
907 
908  for ( Size i = 1; i <= hbond_set->nhbonds(); ++i ) {
909  hbonds::HBond const & hbond( hbond_set->hbond(i) );
910  Size acc( hbond.acc_res() );
911  Size don( hbond.don_res() );
912  if ( symm_info->fa_is_independent( acc ) ) {
913  for ( std::vector<Size>::const_iterator clone=symm_info->bb_clones(acc).begin(), clone_end=symm_info->bb_clones(acc).end();
914  clone != clone_end; ++clone ) {
915  hbond_set->set_backbone_backbone_acceptor( *clone, hbond_set->acc_bbg_in_bb_bb_hbond( acc ) );
916  }
917  }
918  if ( symm_info->fa_is_independent( don ) ) {
919  for ( std::vector<Size>::const_iterator clone=symm_info->bb_clones(don).begin(), clone_end=symm_info->bb_clones(don).end();
920  clone != clone_end; ++clone ) {
921  hbond_set->set_backbone_backbone_acceptor( *clone, hbond_set->acc_bbg_in_bb_bb_hbond( don ) );
922  }
923  }
924  }
925  pose.energies().data().set( HBOND_SET, hbond_set );
926 }
927 
928 void
930 {
931 
933 
934  hbonds::HBondSetOP hbond_set
935  ( static_cast< hbonds::HBondSet & >
936  ( pose.energies().data().get( HBOND_SET )));
937 
938  SymmetricConformation & SymmConf (
939  dynamic_cast<SymmetricConformation &> ( pose.conformation()) );
940  SymmetryInfoCOP symm_info( SymmConf.Symmetry_Info() );
941 
942  for ( uint res = 1; res <= pose.total_residue(); ++res ) {
943  if ( symm_info->get_use_symmetry() ) {
944  if ( !symm_info->fa_is_independent( res ) ) {
945  int symm_res ( symm_info->bb_follows( res ) );
946  int neighbors_symm ( hbond_set->nbrs( symm_res ) );
947  hbond_set->set_nbrs( res, neighbors_symm );
948  }
949  }
950  }
951  pose.energies().data().set( HBOND_SET, hbond_set );
952 }
953 
954 void
956 {
957 // EnvPairPotential pairpot;
958 // pairpot.compute_centroid_environment_symmetric( pose );
959 
960  //using core::pose::datacache::CacheableDataType::CEN_LIST_INFO;
961 
962  CenListInfoOP cenlist( *( static_cast< CenListInfo * >( pose.data().get_ptr( core::pose::datacache::CacheableDataType::CEN_LIST_INFO )() )));
963 
964  SymmetricConformation & SymmConf (
965  dynamic_cast<SymmetricConformation &> ( pose.conformation()) );
966  SymmetryInfoCOP symm_info( SymmConf.Symmetry_Info() );
967 
968  for ( uint res = 1; res <= pose.total_residue(); ++res ) {
969  if ( symm_info->get_use_symmetry() ) {
970  if ( !symm_info->fa_is_independent( res ) ) {
971  int symm_res ( symm_info->bb_follows( res ) );
972  double fcen6_symm ( cenlist->fcen6( symm_res) );
973  double fcen10_symm ( cenlist->fcen10( symm_res ) );
974  double fcen12_symm ( cenlist->fcen12( symm_res ) );
975  cenlist->set_fcen6( res, fcen6_symm );
976  cenlist->set_fcen10( res, fcen10_symm );
977  cenlist->set_fcen12( res, fcen12_symm );
978  }
979  }
980  }
982 }
983 
984 void
986 {
987  //using core::pose::datacache::CacheableDataType::CEN_LIST_INFO;
988 
990  set_symmetric_cenlist( pose );
991  }
992 
995  symmetrical_allow_hbonds( pose );
997  }
998 
999 }
1000 
1001 
1002 // energy methods that compute scores in 'finalize_total_energy' (incl all whole structure energies)
1003 // should not be scaled by # subunits
1004 // this method deals with these methods
1005 void
1007 {
1008  EnergyMap delta_energy( pose.energies().total_energies() );
1009  EnergyMap interface_energies;//, etable_energy;
1010 
1011  SymmetricConformation & SymmConf (
1012  dynamic_cast<SymmetricConformation &> ( pose.conformation()) );
1013  SymmetryInfoCOP symm_info( SymmConf.Symmetry_Info() );
1014  Size const factor ( symm_info->score_multiply_factor() - 1 );
1015 
1016  if ( ! pose.energies().use_nblist() ) {
1017  /// apl mod -- hbonds now calculate bb/bb hbonds during residue_pair_energy_ext, so this is no longer necessary during minimization
1018  interface_energies[ hbond_lr_bb ] = pose.energies().finalized_energies()[hbond_lr_bb];
1019  interface_energies[ hbond_sr_bb ] = pose.energies().finalized_energies()[hbond_sr_bb];
1020  }
1021  interface_energies[ interchain_contact ] = pose.energies().finalized_energies()[interchain_contact];
1022 
1023  if ( pose.energies().use_nblist() ) {
1024  // apl mod -- old style neighborlist has been depricated
1025  //etable_energy[fa_atr] = pose.energies().finalized_energies()[fa_atr];
1026  //etable_energy[fa_rep] = pose.energies().finalized_energies()[fa_rep];
1027  //etable_energy[fa_sol] = pose.energies().finalized_energies()[fa_sol];
1028  //etable_energy[fa_intra_rep] = pose.energies().finalized_energies()[fa_intra_rep];
1029  //etable_energy *= factor;
1030  }
1031 
1032  delta_energy = pose.energies().finalized_energies();
1033  delta_energy -= interface_energies;
1034  delta_energy *= factor;
1035  //delta_energy -= etable_energy;
1036 
1038  EnergyMap new_interface_energy;
1039  intersubunit_hbond_energy(pose,new_interface_energy);
1040  delta_energy += new_interface_energy;
1041  }
1042 
1044  EnergyMap interchain_contact_energy;
1045  interchain_contact_energy[interchain_contact] = pose.energies().finalized_energies()[interchain_contact];
1046  delta_energy += interchain_contact_energy;
1047  }
1048 
1049  // whole structure energy correction
1050  for ( WS_MethodIterator iter=ws_methods_begin(),
1051  iter_end = ws_methods_end(); iter != iter_end; ++iter ) {
1052  ScoreTypes type_i = (*iter)->score_types();
1053  for ( Size j=1; j<=type_i.size(); ++j) {
1054  EnergyMap deldel_energy;
1055  deldel_energy[ type_i[j] ] = pose.energies().finalized_energies()[ type_i[j] ]*factor;
1056  delta_energy -= deldel_energy;
1057  }
1058  }
1059 
1060  pose.energies().finalized_energies() -= interface_energies;
1061  pose.energies().finalized_energies() += delta_energy;
1062 
1063 }
1064 
1065 } // symmetry
1066 } // namespace scoring
1067 } // namespace core