Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SymmOnTheFlyInteractionGraph.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/pack/interaction_graph/SymmOnTheFlyInteractionGraph.hh
11 /// @brief
12 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com)
13 
14 // Unit headers
16 
17 // Package headers
20 
21 // Project headers
25 #include <core/pose/Pose.hh>
27 #include <core/scoring/util.hh>
29 
30 // Utility headers
31 #include <basic/Tracer.hh>
32 
33 #include <iostream>
34 
35 #include <utility/vector1.hh>
36 
37 
38 namespace core {
39 namespace pack {
40 namespace interaction_graph {
41 
42 bool const debug = { false };
43 static basic::Tracer T("core.pack.interaction_graph.otf_ig", basic::t_error );
44 
45 /// @brief main constructor, no default or copy constructors
46 ///
47 /// @detailed
49  InteractionGraphBase * owner,
50  int node_id,
51  int num_states
52 ) :
53  FixedBBNode( owner, node_id, num_states ),
54  rotamer_set_( 0 ),
55  rotamers_( num_states ),
56  sc_bounding_spheres_( num_states, std::make_pair( Vector( 0.0 ), Real( 0.0 ) ) ),
57  bb_bounding_sphere_( std::make_pair( Vector( 0.0 ), Real( 0.0 ) )),
58  num_res_types_( 0 ), // wait until rotamers are set
59  num_restype_groups_( 0 ), // wait until rotamer are set
60  //sparse_mat_info_for_state_( num_states ),
61  one_body_energies_( num_states, 0.0 ),
62  distinguish_backbone_and_sidechain_( false ) // by default, do not
63 {
64 
65 }
66 
67 /// @details
69 {}
70 
71 /// @details avoid polymorphic lookup later by nabbing rotamers now.
72 void
75 )
76 {
77  num_res_types_ = rotamers->get_n_residue_types();
78  num_restype_groups_ = rotamers->get_n_residue_groups();
79 
82 
83  assert( rotamers->num_rotamers() == (Size) get_num_states() );
84  rotamer_set_ = rotamers;
85  for ( Size ii = 1; ii <= rotamer_set_->num_rotamers(); ++ii ) {
86  rotamers_[ ii ] = rotamer_set_->rotamer( ii );
87  if ( ii == 1 ) {
90  }
93  }
94 
95  Size const nsubunits = get_on_the_fly_owner()->symm_info()->subunits();
96  Size const nres_asu = get_on_the_fly_owner()->symm_info()->num_independent_residues();
97  core::pose::Pose const & pose = get_on_the_fly_owner()->pose();
98  rotamer_representatives_.resize( nsubunits );
99  for ( Size ii = 1; ii <= nsubunits; ++ii ) {
100  state_offset_for_restype_group_[ ii ] = rotamers->get_residue_type_begin( ii ) - 1;
101 
103  for ( int jj = 1; jj <= num_res_types_; ++jj ) {
104  rotamer_representatives_[ ii ][ jj ] = rotamers->rotamer( rotamers->get_residue_type_begin( jj ) )->clone();
105  rotamer_representatives_[ ii ][ jj ]->seqpos( rotamers->resid() + (ii-1)*nres_asu );
106  rotamer_representatives_[ ii ][ jj ]->copy_residue_connections_from( pose.residue( rotamer_representatives_[ ii ][ jj ]->seqpos() ) );
107  }
108  }
109 
110  // figure out which residue-type group each rotamer is a member of
111  Size curr_restype_group = 1;
112  Size count_for_restype_group = 1;
113  Size const num_restype_groups = rotamers->get_n_residue_groups();
114  for ( Size ii = 1; ii <= rotamers_.size(); ++ii ) {
115 
116  //sparse_mat_info_for_state_[ ii ].set_aa_type( curr_restype_group );
117  //sparse_mat_info_for_state_[ ii ].set_state_ind_for_this_aa_type( count_for_restype_group );
118  ++count_for_restype_group;
119  while ( count_for_restype_group > rotamers->get_n_rotamers_for_residue_group( curr_restype_group )) {
120  // increment curr_restype_group and skip over restypes with 0 rotamers
121  ++curr_restype_group;
122  count_for_restype_group = 1;
123  if ( curr_restype_group > num_restype_groups ) break;
124  //state_offset_for_aatype_[ curr_restype_group ] = ii;
125  }
126  }
127 }
128 
129 void
131 {
132  if ( get_num_incident_edges() != 0 ) {
133  utility_exit_with_message( "ERROR:: Must set distinguish_backbone_and_sidechain before adding edges" );
134  }
136 }
137 
138 
139 void
141 {
142  std::fill( one_body_energies_.begin(), one_body_energies_.end(), 0.0f );
143 }
144 
145 void
146 SymmOnTheFlyNode::add_to_one_body_energies( ObjexxFCL::FArray1_float & energy1b )
147 {
148  for ( Size ii = 1; ii <= one_body_energies_.size(); ++ii ) {
149  one_body_energies_[ ii ] += energy1b( ii );
150  }
151 }
152 
153 void
155 {
156  one_body_energies_[ state ] = energy;
157 }
158 
159 
160 /// @details sets one body energies for a given state
161 void
163 {
164  one_body_energies_[ state ] = energy;
165 }
166 
167 /// @details increments one body energies for a given state
168 void
170 {
171  one_body_energies_[ state ] += energy;
172 }
173 
174 
175 
176 void
178 {
179  one_body_energies_[ state ] = 0;
180 }
181 
182 /// @details reports the amount of dynamic memory this node allocates
183 /// recursing to its base class
184 unsigned int
186 {
187  unsigned int total_memory = NodeBase::count_dynamic_memory();
188 
189  total_memory += rotamers_.size() * sizeof ( conformation::ResidueCOP );
190  //total_memory += num_states_for_aatype_.size() * sizeof( int );
191  //total_memory += state_offset_for_aatype_.size() * sizeof( int );
192  //total_memory += sparse_mat_info_for_state_.size() * sizeof( SparseMatrixIndex );
193  total_memory += one_body_energies_.size() * sizeof( core::PackerEnergy );
194 
195  return total_memory;
196 }
197 
198 
199 /// @details Compute all the energies that are appropriately two body energies for
200 /// this edge. In the outter loop, pick one of the two nodes on this edge and consider
201 /// its rotamer as having originated from the asymmetric unit. In the inner loop,
202 /// iterate across all subunits, considering each subunit as the origination of the
203 /// rotamer for the other node (that is, if ii == 1, then "this" node is treated as
204 /// if its rotamer is originating from the asymmetric unit, and the "other" node
205 /// takes its rotamer from subunit jj -- which may very well be the asymmetric unit.
206 /// If however, ii == 2, then the "other" node is treated as if its rotamer is originating
207 /// from the asymmetric unit and the "this" node's rotamer is taken from jj).
208 /// Now, inside this inner loop, with ii and jj known, first, ask the edge whether
209 /// given ii, jj, and the amino acid types of the two rotamers, the two rotamers
210 /// implied by ii and jj should have their interaction energies calculated. If not, continue.
211 /// If so, then ask each edge for a representative rotamer, telling each node which
212 /// subunit that rotamer should come from. This may likely require rotating and translating the
213 /// rotamers from the asymmetric unit into the appropriate symmetric clone
216  int edge_making_energy_request,
217  int state_this,
218  int state_other
219 ) const
220 {
221  using namespace scoring;
222  using namespace scoring::methods;
223 
224  Size const asu_index = 1; // OK will it always be the case that the asymmetic unit is the first subunit? I'm assuming it always will be.
225 
226  core::PackerEnergy esum( 0.0 );
227 
228  SymmOnTheFlyEdge const & spanning_edge( * get_incident_otf_edge( edge_making_energy_request ) );
229  SymmOnTheFlyNode const & neighbor( * get_adjacent_otf_node( edge_making_energy_request ) );
230 
232 
233  Size nsubunits = get_on_the_fly_owner()->symm_info()->subunits();
234  Size this_restype_group = rotamer_set_->get_residue_group_index_for_rotamer( state_this );
235  Size other_restype_group = neighbor.rotamer_set_->get_residue_group_index_for_rotamer( state_other );
236 
237  EnergyMap tbody_emap;
238 
239  for ( Size ii = 1; ii <= 2; ++ii ) {
240  bool which_way_is_up = (ii == 1) == (get_node_index() < neighbor.get_node_index());
241  Size ii_restype_group = which_way_is_up ? this_restype_group : other_restype_group;
242  Size jj_restype_group = which_way_is_up ? other_restype_group : this_restype_group;
243 
244  for ( Size jj = 1; jj <= nsubunits; ++jj ) {
245 
246  tbody_emap.zero();
247 
248  /// iijj_score_multiply does double duty:
249  /// 1 ) it indicates whether a pair of amino acids on certain subunits are adjacent
250  /// 2 ) it gives the symmetry multiplication factor for the subunit pair
251  /// It does not, however, indicate what the multiplication factor should be for long-range two body
252  /// interactions if the amino acids are not close enough to qualify for short-range interactionsm
253  unsigned char iijj_score_multiply = spanning_edge.residues_adjacent_for_subunit_pair( ii, jj, ii_restype_group, jj_restype_group );
254 
255  if ( iijj_score_multiply == 0 && ! spanning_edge.long_range_interactions_exist() ) continue;
256 
257  Size this_subunit = ii == 1 ? asu_index : jj;
258  Size other_subunit = ii == 1 ? jj : asu_index;
259 
260  core::conformation::Residue const & this_rotamer( get_rotamer( state_this, this_subunit ));
261  core::conformation::Residue const & other_rotamer( neighbor.get_rotamer( state_other, other_subunit ));
262 
263  BoundingSphere this_sc_bounding_sphere = sc_bounding_sphere( state_this, this_subunit );
264  BoundingSphere other_sc_bounding_sphere = neighbor.sc_bounding_sphere( state_other, other_subunit );
265  BoundingSphere this_bb_bounding_sphere = bb_bounding_sphere( this_subunit );
266  BoundingSphere other_bb_bounding_sphere = neighbor.bb_bounding_sphere( other_subunit );
267 
268  // evaluate short-ranged interactions for this pair, if appropriate
269  if ( iijj_score_multiply != 0 && spanning_edge.short_range_interactions_exist() ) {
270 
271  switch ( spanning_edge.eval_type( get_node_index() )) {
272  case ( sc_sc ) :
274  this_rotamer, other_rotamer,
275  this_sc_bounding_sphere.first, other_sc_bounding_sphere.first,
276  this_sc_bounding_sphere.second, other_sc_bounding_sphere.second,
277  get_on_the_fly_owner()->pose(), get_on_the_fly_owner()->score_function(),
278  tbody_emap );
279 
280  /*get_on_the_fly_owner()->score_function().eval_ci_2b_sc_sc(
281  get_rotamer( state_this ),
282  neighbor.get_rotamer( state_other ),
283  get_on_the_fly_owner()->pose(),
284  tbody_emap );
285 
286  get_on_the_fly_owner()->score_function().eval_cd_2b_sc_sc(
287  get_rotamer( state_this ),
288  neighbor.get_rotamer( state_other ),
289  get_on_the_fly_owner()->pose(),
290  tbody_emap
291  );*/
292 
293  break;
294  case ( sc_whole ) :
296  this_rotamer,
297  other_rotamer,
298  get_on_the_fly_owner()->pose(),
299  tbody_emap );
300 
302  this_rotamer,
303  other_rotamer,
304  get_on_the_fly_owner()->pose(),
305  tbody_emap
306  );
307  /// Also evaluate the bb/sc energy between other/this
309  other_rotamer,
310  this_rotamer,
311  get_on_the_fly_owner()->pose(),
312  tbody_emap );
313 
315  other_rotamer,
316  this_rotamer,
317  get_on_the_fly_owner()->pose(),
318  tbody_emap
319  );
320 
321  break;
322  case ( whole_sc ) :
324  this_rotamer,
325  other_rotamer,
326  get_on_the_fly_owner()->pose(),
327  tbody_emap );
328 
330  this_rotamer,
331  other_rotamer,
332  get_on_the_fly_owner()->pose(),
333  tbody_emap
334  );
335  /// Also evaluate the bb/sc energy between this/other
337  this_rotamer,
338  other_rotamer,
339  get_on_the_fly_owner()->pose(),
340  tbody_emap );
341 
343  this_rotamer,
344  other_rotamer,
345  get_on_the_fly_owner()->pose(),
346  tbody_emap
347  );
348 
349 
350  break;
351  case ( whole_whole ) :
352 
354  this_rotamer,
355  other_rotamer,
356  get_on_the_fly_owner()->pose(),
357  tbody_emap );
358 
360  this_rotamer,
361  other_rotamer,
362  get_on_the_fly_owner()->pose(),
363  tbody_emap
364  );
365 
366  break;
367  }
368 
369  if ( false ) {
370  std::cout << get_node_index() << " " << neighbor.get_node_index() << " ii: " << ii << " jj: " << jj << " " << (int) iijj_score_multiply << " * " << static_cast< core::PackerEnergy > ( get_on_the_fly_owner()->score_function().weights().dot( tbody_emap ) ) << " = " << iijj_score_multiply * static_cast< core::PackerEnergy > ( get_on_the_fly_owner()->score_function().weights().dot( tbody_emap ) )<< std::endl;
371  std::cout << "this cbeta: " << this_rotamer.xyz( "CB" ).x() << " " << this_rotamer.xyz( "CB" ).y() << " " << this_rotamer.xyz( "CB" ).z();
372  std::cout << "; other cbeta: " << other_rotamer.xyz( "CB" ).x() << " " << other_rotamer.xyz( "CB" ).y() << " " << other_rotamer.xyz( "CB" ).z() << std::endl;;
373  }
374  esum += iijj_score_multiply * static_cast< core::PackerEnergy >
375  ( get_on_the_fly_owner()->score_function().weights().dot( tbody_emap ) );
376  }
377 
378  /// Long range interaction energies for this rotamer pair
379  if ( spanning_edge.long_range_interactions_exist() ) {
380  EnergyMap emap;
381  Size lr_iijj_score_multiply( iijj_score_multiply );
382  if ( lr_iijj_score_multiply == 0 ) {
383  lr_iijj_score_multiply = get_on_the_fly_owner()->symm_info()->score_multiply(
384  this_rotamer.seqpos(), other_rotamer.seqpos() );
385  }
386  if ( lr_iijj_score_multiply != 0 ) {
390  iter != iter_end; ++iter ) {
391  (*iter)->residue_pair_energy(
392  this_rotamer, other_rotamer,
393  get_on_the_fly_owner()->pose(),
394  get_on_the_fly_owner()->score_function(),
395  emap );
396  }
397  esum += lr_iijj_score_multiply * static_cast< core::PackerEnergy >
398  ( get_on_the_fly_owner()->score_function().weights().dot( emap ) );
399  }
400  }
401  }
402  }
403 
404 
405  if ( get_adjacent_otf_node( edge_making_energy_request )->get_rotamer( state_other, 1 ).aa() == chemical::aa_pro ) {
406  esum += get_incident_otf_edge( edge_making_energy_request )->
407  get_proline_correction_for_node( get_node_index(), state_this );
408  //std::cout << "adding proline correction 1: " << get_incident_otf_edge( edge_making_energy_request )->
409  // get_proline_correction_for_node( get_node_index(), state_this ) << std::endl;
410  }
411  if ( get_rotamer( state_this, 1 ).aa() == chemical::aa_pro ) {
412  esum += get_incident_otf_edge( edge_making_energy_request )->
413  get_proline_correction_for_node( get_index_of_adjacent_node( edge_making_energy_request ),
414  state_other
415  );
416  //std::cout << "adding proline correction 2: " << get_incident_otf_edge( edge_making_energy_request )->
417  // get_proline_correction_for_node( get_index_of_adjacent_node( edge_making_energy_request ), state_other ) << std::endl;
418  }
419 
420  return get_incident_edge( edge_making_energy_request )->edge_weight() * esum;
421 }
422 
423 
424 /// @brief Returns a reference to the rotamer object in the requested subunit. This reference
425 /// is valid only until the next call to get_rotamer, and which point, the coordinates inside
426 /// the requested rotamer may change.
427 conformation::Residue const &
428 SymmOnTheFlyNode::get_rotamer( int state, int subunit ) const
429 {
430  /// ASSUMPTION: the asymmetric unit is subunit #1
431  if ( subunit == 1 ) {
432  return *rotamers_[ state ];
433  }
434 
435  int state_aa = rotamer_set_->get_residue_type_index_for_rotamer( state );
436  //if ( rotamers_currently_reprsented_[ subunit ][ state_aa ] == state ) {
437  // return *rotamer_representatives_[ subunit ][ state_aa ];
438  //}
439  //rotamers_currently_represented_[ subunit ][ state_aa ] = state;
440 
441  conformation::Residue & rotamer = *rotamer_representatives_[ subunit ][ state_aa ];
442  conformation::Residue const & asymm_rotamer = *rotamers_[ state ];
443  assert( &rotamer.type() == & asymm_rotamer.type() );
444 
445  // copy torsions
446  rotamer.mainchain_torsions() = asymm_rotamer.mainchain_torsions();
447  rotamer.chi() = asymm_rotamer.chi();
448 
449  // rotate coordinates
451  for ( Size ii = 1, iiend = rotamer.natoms(); ii <= iiend; ++ii ) {
452  rotamer.set_xyz( ii, transform * asymm_rotamer.xyz( ii ) );
453  }
454 
455  // rotate the act_coord
456  rotamer.actcoord() = transform * asymm_rotamer.actcoord();
457 
458  // orbital rotation would happen here, too, I think
459 
460  return rotamer;
461 }
462 
463 /// @brief Returns a bounding sphere for the sidechain of a given state on a particular subunit.
465 SymmOnTheFlyNode::sc_bounding_sphere( int state, int subunit ) const
466 {
467  BoundingSphere transformed_bs = sc_bounding_spheres_[ state ];
468  transformed_bs.first = get_on_the_fly_owner()->symmetric_transform( subunit ) * transformed_bs.first;
469  return transformed_bs;
470 }
471 
472 /// @brief Returns a bounding sphere for the backbone on a particular subunit.
475 {
476  BoundingSphere transformed_bs = bb_bounding_sphere_;
477  transformed_bs.first = get_on_the_fly_owner()->symmetric_transform( subunit ) * transformed_bs.first;
478  return transformed_bs;
479 }
480 
481 
482 //-------------------------------------------------------------//
483 
485  InteractionGraphBase * owner,
486  int first_node_ind,
487  int second_node_ind
488 )
489 :
490  FixedBBEdge( owner, first_node_ind, second_node_ind ),
491  restypegroup_adjacency_(
492  get_otf_owner()->get_num_restype_groups(),
493  get_otf_owner()->get_num_restype_groups(),
494  get_otf_owner()->symm_info()->subunits(),
495  2,
496  (unsigned char) 0 // initial value -- set everything to "false"
497  ),
498  long_range_interactions_exist_( false ),
499  short_range_interactions_exist_( false )
500 {
501  bool distinguish_sc_bb[ 2 ];
502  for ( int ii = 0; ii < 2; ++ii) {
503  proline_corrections_[ ii ].resize( get_num_states_for_node( ii ) );
504  std::fill( proline_corrections_[ ii ].begin(), proline_corrections_[ ii ].end(), 0.0f );
505  distinguish_sc_bb[ ii ] = get_otf_node( ii )->distinguish_backbone_and_sidechain();
506  }
507 
508  if ( distinguish_sc_bb[ 0 ] && distinguish_sc_bb[ 1 ] ) {
509  eval_types_[ 0 ] = eval_types_[ 1 ] = sc_sc;
510  } else if ( ! distinguish_sc_bb[ 0 ] && distinguish_sc_bb[ 1 ] ) {
511  eval_types_[ 0 ] = whole_sc;
512  eval_types_[ 1 ] = sc_whole;
513  } else if ( distinguish_sc_bb[ 0 ] && ! distinguish_sc_bb[ 1 ] ) {
514  eval_types_[ 1 ] = whole_sc;
515  eval_types_[ 0 ] = sc_whole;
516  } else {
517  eval_types_[ 1 ] = eval_types_[ 0 ] = whole_whole;
518  }
519 }
520 
521 
523 
524 void
526  int node_not_necessarily_proline,
527  int state,
528  core::PackerEnergy bb_nonprobb_E,
529  core::PackerEnergy bb_probb_E,
530  core::PackerEnergy sc_nonprobb_E,
531  core::PackerEnergy sc_probb_E
532 )
533 {
534  int const which_node = node_not_necessarily_proline == get_node_index( 0 ) ? 0 : 1;
535 
536  //std::cout << " SymmOnTheFlyEdge::add_ProCorrection_values" << get_first_node_ind() << " " << get_second_node_ind() << " " << node_not_necessarily_proline << " " << state << " : " << sc_probb_E + 0.5 * bb_probb_E - (sc_nonprobb_E + 0.5 * bb_nonprobb_E) << std::endl;
537 
538  proline_corrections_[ which_node ][ state ] +=
539  sc_probb_E + 0.5 * bb_probb_E -
540  (sc_nonprobb_E + 0.5 * bb_nonprobb_E);
541 }
542 
543 
544 unsigned int
546 {
547  unsigned int total_memory_usage = EdgeBase::count_dynamic_memory();
548 
549  total_memory_usage += proline_corrections_[ 0 ].size() * sizeof( core::PackerEnergy );
550  total_memory_usage += proline_corrections_[ 1 ].size() * sizeof( core::PackerEnergy );
551 
552  return total_memory_usage;
553 }
554 
555 void
557  int asu_node_index,
558  int other_node_subunit
559 )
560 {
561  if ( asu_node_index == 2 && other_node_subunit == 1 ) return;
562 
563  //std::cout << "SymmOnTheFlyEdge " << get_first_node_ind() << " " << get_second_node_ind() << " set_residues_adjacent_for_subunit_pair " << asu_node_index << " " << other_node_subunit << std::endl;
564 
565  int const asu_index = 1; // ASSUMPTION, the asymmetric unit is unit 1!
566  int const nres_asu = get_otf_owner()->symm_info()->num_independent_residues();
567  Size const score_multiply = get_otf_owner()->symm_info()->score_multiply( 1, (other_node_subunit-1)*nres_asu + 1 );
568  if ( score_multiply == 0 ) return;
569 
570  // OK: now iterate across the rotamer representatives for this pair and figure out their cbeta distances
571  // and ask whether they should be considered adjacent
572 
573  int other_node_index = ( asu_node_index == 1 ) ? 2 : 1;
574  SymmOnTheFlyNode const * asu_node = get_otf_node( asu_node_index - 1 );
575  SymmOnTheFlyNode const * other_node = get_otf_node( other_node_index - 1 );
577  for ( int ii = 1; ii <= asu_node->get_num_restype_groups(); ++ii ) {
578  int iistate = asu_node->get_state_offset_for_restype_group( ii ) + 1;
579  core::conformation::Residue const & iires = asu_node->get_rotamer( iistate, asu_index );
580  for ( int jj = 1; jj <= other_node->get_num_restype_groups(); ++jj ) {
581  int jjstate = other_node->get_state_offset_for_restype_group( jj ) + 1;
582  core::conformation::Residue const & jjres = other_node->get_rotamer( jjstate, other_node_subunit );
583  Real ii_jj_radii_sum = iires.nbr_radius() + jjres.nbr_radius();
584  Real d2 = iires.xyz( iires.nbr_atom() ).distance_squared( jjres.xyz( jjres.nbr_atom() ));
585  //std::cout << "ii: " << ii << " " << iires.name() << " jj: " << jj << " " << jjres.name() << " d2: " << d2 << " sfxn_reach: " << sfxn_reach << " ii_jj_radii_sum: " << ii_jj_radii_sum << ", squared: " << (sfxn_reach + ii_jj_radii_sum )*(sfxn_reach + ii_jj_radii_sum ) << std::endl;
586  if ( d2 < (sfxn_reach + ii_jj_radii_sum )*(sfxn_reach + ii_jj_radii_sum ) ) {
587  //std::cout << "declared neighbors: " << get_otf_owner()->symm_info()->score_multiply( 1, (other_node_subunit-1)*nres_asu + 1 ) << std::endl;
588  restypegroup_adjacency_( jj, ii, other_node_subunit, asu_node_index ) = score_multiply;
589  }
590  }
591  }
592 
593 }
594 
595 unsigned char
597  int which_node, // 1 or 2
598  int other_node_subunit, // subunit for othernode
599  int whichnode_restypegroup, // restype group for first node
600  int othernode_restypegroup // restype group for the other node
601 ) const
602 {
603  return restypegroup_adjacency_( othernode_restypegroup, whichnode_restypegroup, other_node_subunit, which_node );
604 }
605 
606 //-------------------------------------------------------------//
607 
609 :
610  FixedBBInteractionGraph( num_nodes ),
611  num_restype_groups_( 0 )
612 {}
613 
615 {}
616 
617 bool
619 {
621 }
622 
623 void
625 {
627 }
628 
629 
630 void
632  rotamer_set::RotamerSetsBase const & rot_sets_base
633 )
634 {
635  rotamer_set::RotamerSets const & rot_sets( static_cast< rotamer_set::RotamerSets const & > (rot_sets_base) );
636 
637  // determine max # of residue types
638  Size max_nrestypes = 0;
639  for ( Size ii = 1; ii <= rot_sets.nmoltenres(); ++ii ) {
640  Size ii_nrestypes = rot_sets.rotamer_set_for_moltenresidue( ii )->get_n_residue_types();
641  if ( ii_nrestypes > max_nrestypes ) max_nrestypes = ii_nrestypes;
642  }
643 
644  //"aa types" means "distinct groups of rotamers" -- this ig has no idea
645  // what an amino acid is or why they might be different from one another
646  num_restype_groups_ = max_nrestypes;
647 
648  for ( Size ii = 1; ii <= rot_sets.nmoltenres(); ++ii ) {
649  Size const ii_num_states = rot_sets.rotamer_set_for_moltenresidue( ii )->num_rotamers();
650  set_num_states_for_node( ii, ii_num_states );
652  }
653 
654 }
655 
656 void
658 {
659  score_function_ = sfxn.clone();
660  if ( pose_ ) (*score_function_)(*pose_); // rescore the pose with the input score function
661 }
662 
663 void
665 {
666  pose_ = new pose::Pose( pose );
667  if ( score_function_ ) (*score_function_)(*pose_);
668 
670  using id::AtomID;
671 
672  SymmetricConformation & symm_conf ( dynamic_cast<SymmetricConformation &> ( pose_->conformation()) );
673  symm_info_ = symm_conf.Symmetry_Info();
674 
675  // ok, now figure out the HTs to translate from the reference frame to all of
676  // symmetric clone frames
677  Size const nsubunits = symm_info_->subunits();
678  Size const asu_size = symm_info_->num_independent_residues();
679  assert( nsubunits > 0 );
680  symmetric_transforms_.resize( nsubunits );
681  symmetric_transforms_[1].set_identity();
682 
683  // 1. find a residue with at least three atoms
684  Size orientation_residue = 0;
685  for ( Size ii = 1; ii <= asu_size; ++ii ) {
686  if ( pose.residue( ii ).natoms() >= 3 ) {
687  orientation_residue = ii;
688  break;
689  }
690  }
691  if ( orientation_residue == 0 ) {
692  /// there are other residues that could be used to generate these
693  /// orientation, but that requires a better understanding of the fold tree
694  utility_exit_with_message( "Failed to find a residue in the pose with at least three atoms" );
695  }
696 
697  HTReal frame1(
698  pose.xyz( AtomID( 1, orientation_residue )),
699  pose.xyz( AtomID( 2, orientation_residue )),
700  pose.xyz( AtomID( 3, orientation_residue )) );
701  HTReal invframe1 = frame1.inverse();
702  for ( Size ii = 2; ii <= nsubunits; ++ii ) {
703  Size iiresidue = orientation_residue + (ii-1)*asu_size;
704  HTReal iiframe(
705  pose.xyz( AtomID( 1, iiresidue )),
706  pose.xyz( AtomID( 2, iiresidue )),
707  pose.xyz( AtomID( 3, iiresidue )) );
708  symmetric_transforms_[ ii ] = iiframe * invframe1;
709  }
710 
711 }
712 
715  return symm_info_;
716 }
717 
718 
719 void
721  int node_ind,
722  int state
723 )
724 {
725  get_on_the_fly_node( node_ind )->zero_one_body_energy( state );
726 }
727 
728 void
730  int node_ind,
731  int state,
732  core::PackerEnergy one_body_energy
733 )
734 {
735  get_on_the_fly_node( node_ind )->add_to_one_body_energy( state, one_body_energy);
736 }
737 
738 void
740  int node_ind,
741  int state,
742  core::PackerEnergy one_body_energy
743 )
744 {
745  get_on_the_fly_node( node_ind )->set_one_body_energy( state, one_body_energy);
746 }
747 
748 
751 {
752  return get_on_the_fly_node( node )->get_one_body_energy( state );
753 }
754 
755 void
757  int node1,
758  int node2,
759  int asu_node_index,
760  int other_node_subunit
761 )
762 {
763  SymmOnTheFlyEdge * edge = static_cast< SymmOnTheFlyEdge * > ( find_edge( node1, node2 ) );
764  if ( edge ) {
765  edge->set_residues_adjacent_for_subunit_pair( asu_node_index, other_node_subunit );
766  }
767 }
768 
769 void
771 {
772  num_rpe_calcs_ = 0;
773 }
774 
775 
776 Size
778 {
779  return num_rpe_calcs_;
780 }
781 
782 
783 //void
784 //SymmOnTheFlyInteractionGraph::set_sparse_aa_info_for_edge(
785 // int node1,
786 // int node2,
787 // FArray2_bool const & sparse_conn_info
788 //)
789 //{
790 // SymmOnTheFlyEdge* edge = (SymmOnTheFlyEdge*) find_edge( node1, node2 );
791 // if (edge != 0) {
792 // edge->set_sparse_aa_info( sparse_conn_info );
793 // }
794 //}
795 
796 void
798  int node1,
799  int node2,
800  int node_not_neccessarily_proline,
801  int state,
802  core::PackerEnergy bb_nonprobb_E,
803  core::PackerEnergy bb_probb_E,
804  core::PackerEnergy sc_nonprobb_E,
805  core::PackerEnergy sc_probb_E
806 )
807 {
808  SymmOnTheFlyEdge* edge = (SymmOnTheFlyEdge*) find_edge( node1, node2 );
809  if (edge != 0)
810  {
812  node_not_neccessarily_proline, state,
813  bb_nonprobb_E, bb_probb_E, sc_nonprobb_E, sc_probb_E );
814  }
815 }
816 
817 void
819  int node1,
820  int node2
821 )
822 {
823  SymmOnTheFlyEdge* edge = (SymmOnTheFlyEdge*) find_edge( node1, node2 );
824  if (edge != 0) {
826  }
827 }
828 
829 void
831  int node1,
832  int node2
833 )
834 {
835  SymmOnTheFlyEdge* edge = (SymmOnTheFlyEdge*) find_edge( node1, node2 );
836  if (edge != 0) {
838  }
839 }
840 
841 
842 unsigned int
844 {
845  unsigned int total_memory = InteractionGraphBase::count_dynamic_memory();
846  return total_memory;
847 }
848 
849 } // namespace interaction_graph
850 } // namespace pack
851 } // namespace core