Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SecondaryMatcherToUpstreamResidue.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 // :noTabs=false:tabSize=4:indentSize=4:
4 //
5 // (c) Copyright Rosetta Commons Member Institutions.
6 // (c) This file is part of the Rosetta software suite and is made available under license.
7 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
8 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
9 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
10 
11 /// @file protocols/match/downstream/SecondaryMatcherToUpstreamResidue.cc
12 /// @brief Class implementation for secondary matcher that generates upstream-only hits
13 /// matching the geometry of one upstream residue with another upstream residue
14 /// generated in a previous round.
15 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com)
16 /// @author Florian Richter (flosopher@gmail.com)
17 
18 
19 // Unit headers
21 
22 // Package headers
24 #include <protocols/match/Hit.hh>
26 // AUTO-REMOVED #include <protocols/match/downstream/LigandConformer.hh> // REQUIRED FOR WINDOWS
27 // AUTO-REMOVED #include <protocols/match/downstream/LigandConformerBuilder.hh>
28 // AUTO-REMOVED #include <protocols/match/downstream/RigidLigandBuilder.hh>
32 // AUTO-REMOVED #include <protocols/match/upstream/ProteinUpstreamBuilder.hh>
33 
34 // Project headers
37 
38 #include <basic/Tracer.hh>
39 
40 // Utility headers
41 #include <utility/pointer/ReferenceCount.hh>
42 
43 // C++ headers
44 #include <list>
45 #include <string>
46 
47 // Boost headers
48 #include <boost/unordered_map.hpp>
49 
50 #include <utility/OrderedTuple.hh>
51 #include <utility/vector1.hh>
52 
53 
54 namespace protocols {
55 namespace match {
56 namespace downstream {
57 
58 static basic::Tracer TR( "protocols.match.downstream.SecondaryMatcherToUpstreamResidue" );
59 
61 {
63  return ( 271 * uphit.data()[ 1 ] + uphit.data()[ 2 ] ) % 1699;
64  }
65 };
66 
67 
69  Size geom_cst_id
70 ) :
71  parent( geom_cst_id ),
72  target_geomcst_id_( 0 ),
73  count_rotamers_per_target_restype_( false ),
74  last_seen_restype_index_( 0 ),
75  count_rotamer_for_lastseen_restype_( 0 ),
76  n_viable_target_hits_since_last_pruning_( 0 )
77 {
78 }
79 
81 
84 {
85  return new SecondaryMatcherToUpstreamResidue( *this );
86 }
87 
88 /// @details This DownstreamAlgorithm structures it's iteration over the target hits
89 /// from previous rounds as follows:
90 /// for i = 1:n_build_positions
91 /// recover_rotamer_coordinates_from_previous_round( hits_for_build_point_i );
92 /// initialize rotcoord data for all downstream algorithms with the same geom_cst_id
93 /// #omp parallel for /// All class access below this point is const and parallelizable
94 /// for j = 1:n_build_positions
95 /// /// call this function to start k loop: matcher.upstream_builder[ geom_cst_id() ]->build( j )
96 /// for k = 1:n_rotamers_j
97 /// /// call to start l loop: downstream_algorithm->build( j, k, rotamer_k ) )
98 /// for l = 1:n_rotamers_from_build_point_i
99 /// if ( respair_evaluator_->evaluate_residues( rotamer_k, rotamer_l )
100 /// hit_list.append( Hit( j, k, ... ));
101 /// return hit_list
102 /// There are two important consequences to this hit-generation layout.
103 /// 1. The coordinates for rotamer_k are computed n_build_position times.
104 /// 2. Only a single build-position i has it's hit coordinates in memory at any point in time.
105 /// This is a clear trade-off between performance and memory with a few caveats:
106 /// A. It is very easy to bound the volume of space where build-point i's rotamers lie,
107 /// so it should be easy to prune rotamer building, so rotamer k will be build many fewer than
108 /// n_build_position times.
109 /// B. By not trying to store all rotamers in memory at once, we do not impose any undue restrictions
110 /// on the number of rotamers that can be enumerated. This is especially important if we're
111 /// using backbone flexibility to search a wider region of conformation space.
112 std::list< Hit >
114  Matcher & matcher
115 )
116 {
117  prepare_for_hit_generation( matcher );
118 
119  //kui 102109
120  //smUR_pose_build_resids_ = matcher.get_pose_build_resids();
121 
122  /// nab the launch points for both my target and myself
123  utility::vector1< upstream::ScaffoldBuildPointCOP > const & target_build_points
126  ( matcher.per_constraint_build_points( geom_cst_id() ) );
127 
128  utility::vector1< std::list< Hit > > hits( my_build_points.size() );
129 
130  for ( Size ii = 1; ii <= target_build_points.size(); ++ii ) {
131  if ( ! prepare_for_hit_generation_at_target_build_point( matcher, *target_build_points[ ii ] )) {
132  continue;
133  }
134 
135  //TR << "Secondary matching against geomcst " << target_geomcst_id_ << " hits from build point " << target_build_points[ ii ]->index() << std::endl;
136  //TR << "Secondary matching against geomcst " << target_geomcst_id_ << " hits from protein build point " << target_build_points[ ii ]->original_insertion_point() << std::endl;
137 
138  Size ii_total_found_matches( 0 );
139  #pragma omp parallel for reduction( + : ii_total_found_matches )
140  for ( Size jj = 1; jj <= my_build_points.size(); ++jj ) {
141  //Most of the time we don't want to build residue at the same point
142  //as the target build point, but in the case of backbone matching
143  //if ( target_build_points[ ii ]->index() != my_build_points[ jj ]->index() ) {
144  ///TR << " Building sec. match res on protein build point: " << my_build_points[ jj ]->original_insertion_point() << std::endl;
145  std::list< Hit > jj_hits = matcher.upstream_builder( geom_cst_id() )->build( * my_build_points[ jj ] );
146  ii_total_found_matches += jj_hits.size();
147  hits[ jj ].splice( hits[ jj ].end(), jj_hits );
148  //}
149  }
150  TR << "Secondary matching against geomcst " << target_geomcst_id_ << " hits from protein build point " << target_build_points[ ii ]->original_insertion_point() << " produced " << ii_total_found_matches << " hits " << std::endl;
151  }
152 
153  std::list< Hit > all_hits;
155  for ( Size ii = 1; ii <= my_build_points.size(); ++ii ) {
156  hits[ ii ].sort( compare );
157  all_hits.splice( all_hits.end(), hits[ ii ] );
158  }
159 
160  return all_hits;
161 
162 }
163 
164 
165 /// @brief Prune hits away from the target_geomcst's hit list following a change to the
166 /// hits for my geom_cst_id(). Pruning hits from the target_geomcst's hit list will
167 /// trigger a round of peripheral-hitlist-change responses.
168 void
170  Matcher & matcher,
171  Size /*round_just_completed*/
172 )
173 {
174 
175  boost::unordered_map< Size2Tuple, bool, hash_upstream_hit > targets_hits_matched;
176  Matcher::HitList const & my_hits = matcher.hits( geom_cst_id() );
177  for ( Matcher::HitListConstIterator iter = my_hits.begin(), iter_end = my_hits.end();
178  iter != iter_end; ++iter ) {
179  Size2 target_hit;
180  target_hit[ 1 ] = static_cast< Size > ( iter->second()[ 1 ] );
181  target_hit[ 2 ] = static_cast< Size > ( iter->second()[ 2 ] );
182  boost::unordered_map< Size2Tuple, bool, hash_upstream_hit >::const_iterator
183  hash_iter = targets_hits_matched.find( target_hit );
184  if ( hash_iter == targets_hits_matched.end() ) {
185  targets_hits_matched[ target_hit ] = true;
186  }
187  }
188 
189  Matcher::HitListIterator target_hit_iter = matcher.hit_list_begin( target_geomcst_id_ );
190  Matcher::HitListIterator target_hit_iter_end = matcher.hit_list_end( target_geomcst_id_ );
191 
192  Size drop_count( 0 );
193  while ( target_hit_iter != target_hit_iter_end ) {
194  Matcher::HitListIterator target_hit_iter_next = target_hit_iter;
195  ++target_hit_iter_next;
196 
197  Size2 target_hit;
198  target_hit[ 1 ] = static_cast< Size > ( target_hit_iter->first()[ 1 ] );
199  target_hit[ 2 ] = static_cast< Size > ( target_hit_iter->first()[ 2 ] );
200  boost::unordered_map< Size2Tuple, bool, hash_upstream_hit >::const_iterator
201  hash_iter = targets_hits_matched.find( target_hit );
202  if ( hash_iter == targets_hits_matched.end() ) {
203  matcher.erase_hit( *this, target_geomcst_id_, target_hit_iter );
204  ++drop_count;
205  }
206 
207  target_hit_iter = target_hit_iter_next;
208  }
209 
211 
212  TR << "Erased " << drop_count << " round " << target_geomcst_id_;
213  TR << " hits with ";
214  TR << n_viable_target_hits_since_last_pruning_ << " hits remaining." << std::endl;
215 }
216 
217 
218 /// @brief Remove my hits if my target_geomcst's hit list has been shortened. This
219 /// will not trigger a round of peripheral-hitlist-change responses.
220 void
222  Matcher & matcher
223 )
224 {
226  == matcher.hits( target_geomcst_id_ ).size() ) {
227  return;
228  }
229 
230  boost::unordered_map< Size2Tuple, bool, hash_upstream_hit > target_hit_hash;
231  Matcher::HitList const & target_hits( matcher.hits( target_geomcst_id_ ));
232  for ( Matcher::HitListConstIterator iter = target_hits.begin(), iter_end = target_hits.end();
233  iter != iter_end; ++iter ) {
234  Size2 target_hit;
235  target_hit[ 1 ] = iter->first()[ 1 ];
236  target_hit[ 2 ] = iter->first()[ 2 ];
237  boost::unordered_map< Size2Tuple, bool, hash_upstream_hit >::const_iterator
238  hash_iter = target_hit_hash.find( target_hit );
239  if ( hash_iter == target_hit_hash.end() ) {
240  target_hit_hash[ target_hit ] = true;
241  }
242  }
243 
244  Matcher::HitListIterator hit_iter = matcher.hit_list_begin( geom_cst_id() );
245  Matcher::HitListIterator hit_iter_end = matcher.hit_list_end( geom_cst_id() );
246 
247  Size drop_count( 0 );
248  while ( hit_iter != hit_iter_end ) {
249  Matcher::HitListIterator hit_iter_next = hit_iter;
250  ++hit_iter_next;
251 
252  Size2 target_hit;
253  target_hit[ 1 ] = static_cast< Size > ( hit_iter->second()[ 1 ] );
254  target_hit[ 2 ] = static_cast< Size > ( hit_iter->second()[ 2 ] );
255  boost::unordered_map< Size2Tuple, bool, hash_upstream_hit >::const_iterator
256  hash_iter = target_hit_hash.find( target_hit );
257  if ( hash_iter == target_hit_hash.end() ) {
258  matcher.erase_hit( *this, geom_cst_id(), hit_iter );
259  ++drop_count;
260  }
261 
262  hit_iter = hit_iter_next;
263  }
264 
266 
267  TR << "Erased " << drop_count << " round " << geom_cst_id();
268  TR << " hits with ";
269  TR << matcher.hits( geom_cst_id() ).size() << " hits remaining." << std::endl;
270 
271 }
272 
273 
274 /// @brief Iterate across the hits from a particular upstream build point i
275 /// that were generated in a previous round, and see if the geometry of the
276 /// input upstream_residue has "satisfactory interactions" with the
277 /// hits from upstream-build-point i; if so, it appends a Hit to the hitlist
278 /// returned at the end of the method. (Also, see comments for the
279 /// build_at_all_positions method.)
280 std::list< Hit >
282  Size const scaffold_build_point_id,
283  Size const upstream_conf_id,
284  core::conformation::Residue const & upstream_residue
285 ) const
286 {
287  std::list< Hit > hits;
288  for ( Size ii = 1; ii <= target_geomcst_coords_->n_restypes(); ++ii ) {
289  core::conformation::Residue target_residue( *target_geomcst_coords_->restype( ii ), false );
290  Size const ii_natoms = target_geomcst_coords_->n_atoms_for_restype( ii );
291  core::chemical::ResidueTypeCOP us_res_type = & upstream_residue.type();
292  //TR << " sec. matched residue type: " << us_res_type->name() << std::endl;
293 
294  for ( Size jj = 1; jj <= target_geomcst_coords_->n_rotamers_for_restype( ii ); ++jj ) {
295  //TR << "number of rotamers for restype " << target_geomcst_coords_->n_rotamers_for_restype( ii ) << std::endl;
296 
297 
298  target_residue.seqpos(smUR_pose_build_resids_[target_geomcst_coords_->hit( ii, jj ).scaffold_build_id()]);
299  /// Set the coordinates for only the atoms that I need to give to the evaluator
300  for ( Size kk = 1; kk <= ii_natoms; ++kk ) {
301  target_residue.set_xyz(
302  target_geomcst_coords_->restype_atomno( ii, kk ),
303  target_geomcst_coords_->coord( ii, jj, kk ));
304  }
305 
306  for ( EvaluatorSet::const_iterator eval_iter = respair_evaluators_[ ii ].begin(),
307  eval_iter_end = respair_evaluators_[ ii ].end();
308  eval_iter != eval_iter_end; ++eval_iter ) {
309 
310  if ( eval_iter->first->evaluate_residues( upstream_residue, target_residue ) ) {
311  //Do a clash check by passing the current hit, upstream residue
312  //and a dsbuilder that contains the clash info between the
313  //upstream restype and the downstream residue
314  //if ( ! are_colliding( target_geomcst_coords_->hit(ii,jj), upstream_residue, dsbuilders_.find( us_res_type->name() )->second ) ){
315  Hit hit;
316  hit.first()[ 1 ] = scaffold_build_point_id;
317  hit.first()[ 2 ] = upstream_conf_id;
318  hit.first()[ 3 ] = eval_iter->second; // mcfi ID
319  hit.first()[ 4 ] = 1;
320  hit.second()[ 1 ] = target_geomcst_coords_->hit( ii, jj ).scaffold_build_id();
321  hit.second()[ 2 ] = target_geomcst_coords_->hit( ii, jj ).upstream_conf_id();
322  hit.second()[ 3 ] = target_geomcst_coords_->hit( ii, jj ).external_geom_id();
323  hit.second()[ 4 ] = 0.0;
324  hit.second()[ 5 ] = 0.0;
325  hit.second()[ 6 ] = 0.0;
326  hits.push_back( hit );
327  //TR << " ADDING A HIT! " << "rotamers for restype " << jj << std::endl;
328  //}
329  }
330  }
331  }
332  }
333  return hits;
334 }
335 
336 bool
338 {
339  return true;
340 }
341 
342 bool
344 {
345  return false;
346 }
347 
348 
349 /// @brief Prepare a map between upstream hits of the target-geomcst and
350 /// a list of Hit const *'s of this geom_cst_id(). This map will be used
351 /// in the function hits_to_include_with_partial_match.
352 void
354 {
356  Matcher::HitList const & hits( matcher.hits( geom_cst_id() ));
357  for ( Matcher::HitListConstIterator iter = hits.begin(), iter_end = hits.end();
358  iter != iter_end; ++iter ) {
359  Size2 target_hit;
360  target_hit[ 1 ] = static_cast< Size > ( iter->second()[ 1 ] );
361  target_hit[ 2 ] = static_cast< Size > ( iter->second()[ 2 ] );
362  std::map< Size2Tuple, HitPtrListOP >::const_iterator list_iter =
363  my_hits_for_target_hit_map_.find( target_hit );
364  if ( list_iter == my_hits_for_target_hit_map_.end() ) {
365  my_hits_for_target_hit_map_[ target_hit ] = new HitPtrList;
366  list_iter = my_hits_for_target_hit_map_.find( target_hit );
367  //std::cout << "add to map " << target_hit[ 1 ] << " " << target_hit[ 2 ] << std::endl;
368  }
369  list_iter->second->val().push_back( & (*iter ) ); /// add a pointer to the matcher's hit
370  }
371 }
372 
373 /// @brief Return the set of hits to be iterated across
376  match_dspos1 const & m
377 ) const
378 {
379  HitPtrListCOP hitptrlist( 0 );
380  Size2 target_hit;
381  target_hit[ 1 ] = static_cast< Size > ( m.upstream_hits[ target_geomcst_id_ ].scaffold_build_id() );
382  target_hit[ 2 ] = static_cast< Size > ( m.upstream_hits[ target_geomcst_id_ ].upstream_conf_id() );
383  std::map< Size2Tuple, HitPtrListOP >::const_iterator list_iter =
384  my_hits_for_target_hit_map_.find( target_hit );
385  if ( list_iter != my_hits_for_target_hit_map_.end() ) {
386  hitptrlist = list_iter->second;
387  } else {
388  std::cerr << "fetch failed! " << target_hit[ 1 ] << " " << target_hit[ 2 ] << std::endl;
389  std::cerr << "something weird happened!" << std::endl;
390  }
391  return hitptrlist;
392 }
393 
396 {
397  return target_geomcst_coords_->n_rots_total();
398 }
399 
400 //void
401 //SecondaryMatcherToUpstreamResidue::set_match_restype( core::chemical::ResidueTypeCOP match_restype )
402 //{
403 //
404 //}
405 
406 void
408 {
409  target_geomcst_id_ = target_geomcst_id;
410 }
411 
412 void
414 {
415  if( target_restype_index_map_.find( target_restype ) == target_restype_index_map_.end() ){
416  target_restypes_.push_back( target_restype );
417  target_restype_index_map_[ target_restype ] = target_restypes_.size();
418  }
419 }
420 
421 void
423  core::chemical::ResidueTypeCOP target_restype,
425  Size mcfi_id_for_evaluator
426 )
427 {
428  runtime_assert( target_restype_index_map_.find( target_restype ) != target_restype_index_map_.end() );
429  if ( target_restypes_.size() > respair_evaluators_.size() ) {
430  respair_evaluators_.resize( target_restypes_.size() );
431  }
432  respair_evaluators_[ target_restype_index_map_[ target_restype ] ].push_back(
433  std::make_pair( evaluator, mcfi_id_for_evaluator ));
434 }
435 
436 void
438  Hit const & hit,
439  core::conformation::Residue const & upstream_conformation
440 )
441 {
443  count_rotamer( upstream_conformation );
444  } else {
445  store_rotamer_coords( hit, upstream_conformation );
446  }
447 }
448 
449 void
451  Matcher & matcher
452 )
453 {
454  TR << "Preparing for hit generation" << std::endl;
457  target_hits_end_ = matcher.hits( target_geomcst_id_ ).end();
458 
459  /// Initialize the target_geomcst_coords_ object;
462 
463  Size n_target_restypes = usbuilder->n_restypes_to_build();
464  target_geomcst_coords_->set_num_restypes( n_target_restypes );
465  n_rotamers_per_target_restype_.resize( n_target_restypes );
466 
467  std::list< DownstreamAlgorithmOP > const & dsalgs = matcher.nonconst_downstream_algorithms( geom_cst_id() );
468  std::list< SecondaryMatcherToUpstreamResidueOP > secmatch_algs;
469  for ( std::list< DownstreamAlgorithmOP >::const_iterator iter = dsalgs.begin(),
470  iter_end = dsalgs.end(); iter != iter_end; ++iter ) {
472  dynamic_cast< SecondaryMatcherToUpstreamResidue * > ( iter->get() );
473  runtime_assert( secmatcher );
474  secmatcher->smUR_pose_build_resids_ = matcher.get_pose_build_resids();
475  secmatch_algs.push_back( secmatcher );
476  secmatcher->reorder_restypes( *usbuilder );
477  }
478 
479  for ( Size ii = 1; ii <= n_target_restypes; ++ii ) {
480  core::chemical::ResidueTypeCOP iirestype = usbuilder->restype( ii );
481  target_geomcst_coords_->set_restype( ii, iirestype );
482  utility::vector1< bool > atom_required( iirestype->natoms(), false );
483 
484  bool any_evaluator_requires_all_atoms( false );
485  for ( std::list< SecondaryMatcherToUpstreamResidueOP >::const_iterator iter = secmatch_algs.begin(),
486  iter_end = secmatch_algs.end(); iter != iter_end; ++iter ) {
487 
488  for ( EvaluatorSet::const_iterator eval_iter = (*iter)->respair_evaluators_[ ii ].begin(),
489  eval_iter_end = (*iter)->respair_evaluators_[ ii ].end();
490  eval_iter != eval_iter_end; ++eval_iter ) {
491  if ( eval_iter->first->require_all_target_residue_atom_coordinates() ) {
492  any_evaluator_requires_all_atoms = true;
493  break;
494  }
495  }
496  if ( any_evaluator_requires_all_atoms ) break;
497  }
498  if ( any_evaluator_requires_all_atoms ) {
499  std::fill( atom_required.begin(), atom_required.end(), true );
500  } else {
501  for ( Size jj = 1; jj <= iirestype->natoms(); ++jj ) {
502  for ( std::list< SecondaryMatcherToUpstreamResidueOP >::const_iterator iter = secmatch_algs.begin(),
503  iter_end = secmatch_algs.end(); iter != iter_end; ++iter ) {
504 
505  for ( EvaluatorSet::const_iterator eval_iter = (*iter)->respair_evaluators_[ ii ].begin(),
506  eval_iter_end = (*iter)->respair_evaluators_[ ii ].end();
507  eval_iter != eval_iter_end; ++eval_iter ) {
508 
509  if ( eval_iter->first->require_target_atom_coordinate( jj ) ) {
510  atom_required[ jj ] = true;
511  break;
512  }
513  }
514  if ( atom_required[ jj ] ) break;
515  }
516  }
517  }
518  target_geomcst_coords_->set_required_atoms( ii, atom_required );
519  }
520 }
521 
522 bool
524  Matcher & matcher,
525  upstream::ScaffoldBuildPoint const & target_build_point
526 )
527 {
528  TR << "Preparing to examine geomcst-" << target_geomcst_id_ << "'s hits built from scaffold build point " << target_build_point.original_insertion_point() << std::endl;
529 
530  Size target_build_id = target_build_point.index();
531 
532  /// Find the range of iterators that cover the hits for the upstream matcher
534  if ( target_hits_for_focused_build_point_begin_->scaffold_build_id() == target_build_id ) {
535  break;
536  } else if ( target_hits_for_focused_build_point_begin_->scaffold_build_id() > target_build_id ) {
537  break;
538  }
540  }
542  Size count_target_hits( 0 );
544  if ( target_hits_for_focused_build_point_end_->scaffold_build_id() != target_build_id ) {
545  break;
546  }
548  ++count_target_hits;
549  }
550 
552  TR << "No geomcst-" << target_geomcst_id_ << " hits built from scaffold build point " << target_build_point.original_insertion_point() << std::endl;
553  return false;
554  }
555 
556  std::list< Hit > unique_upstream_hits;
557  Size last_conf_id( 0 );
559  iter != target_hits_for_focused_build_point_end_; ++iter ) {
560  //get_all_hits_for_clash_cheicking
561  if ( last_conf_id != iter->upstream_conf_id() ) {
562  unique_upstream_hits.push_back( *iter );
563  last_conf_id = iter->upstream_conf_id();
564  }
565  }
566 
567  /// first pass over the hits; count the number of hits per residue type.
571  std::fill( n_rotamers_per_target_restype_.begin(), n_rotamers_per_target_restype_.end(), 0 );
573  matcher.upstream_builder( target_geomcst_id_ )->recover_hits(
574  unique_upstream_hits.begin(), unique_upstream_hits.end(),
575  target_build_point, proc );
576 
577  target_geomcst_coords_->set_num_target_rotamers( n_rotamers_per_target_restype_ );
578 
579  /// second pass over the hits; store the rotamers in the TargetRotamerCoords object
584  matcher.upstream_builder( target_geomcst_id_ )->recover_hits(
585  unique_upstream_hits.begin(), unique_upstream_hits.end(),
586  target_build_point, proc );
587 
588  /// Now update all of the downstream-algorithms for this geom_cst_id() so that they're all pointing
589  /// to the same TargetRotamerCoords object.
590 
591  std::list< DownstreamAlgorithmOP > const & dsalgs = matcher.nonconst_downstream_algorithms( geom_cst_id() );
592  for ( std::list< DownstreamAlgorithmOP >::const_iterator
593  iter = dsalgs.begin(), iter_end = dsalgs.end();
594  iter != iter_end; ++iter ) {
595  if ( iter->get() != this ) {
597  ( iter->get() );
598  runtime_assert( other );
599  //TR << "SecondaryMatcherToUpstreamResidue * other" << other << std::endl;
600  other->set_target_rotamer_coords( target_geomcst_coords_ );
601  }
602  }
603 
604  /// This would also be the appropriate time to initialize a pruning object to
605  /// quickly reject rotamers in the UpstreamBuilder.
606  TR << "Examining " << count_target_hits << " hits built from scaffold build point "
607  << target_build_point.original_insertion_point() << " representing " << target_geomcst_coords_->n_rots_total()
608  << " unique upstream rotamers" << std::endl;
609 
610  return true;
611 }
612 
613 void
615  TargetRotamerCoordsOP target_geomcst_coords
616 )
617 {
618  target_geomcst_coords_ = target_geomcst_coords;
619 }
620 
621 void
623  core::conformation::Residue const & upstream_conformation
624 )
625 {
626  //std::cout << "count_rotamer: " << upstream_conformation.name() << std::endl;
627  if ( & upstream_conformation.type() != last_seen_restype_.get() ) {
629  while ( last_seen_restype_index_ <= target_restypes_.size() ) {
630  if ( target_restypes_[ last_seen_restype_index_ ].get() == & upstream_conformation.type() ) break;
632  }
633  runtime_assert( last_seen_restype_index_ <= target_restypes_.size() );
634  last_seen_restype_ = & upstream_conformation.type();
635  }
637 }
638 
639 void
641  Hit const & hit,
642  core::conformation::Residue const & upstream_conformation
643 )
644 {
645  //std::cout << "store_rotamer_coords: " << upstream_conformation.name() << std::endl;
646  if ( & upstream_conformation.type() == last_seen_restype_.get() ) {
649  } else {
651  while ( last_seen_restype_index_ <= target_restypes_.size() ) {
652  if ( target_restypes_[ last_seen_restype_index_ ].get() == & upstream_conformation.type() ) break;
654  }
655  runtime_assert( last_seen_restype_index_ <= target_restypes_.size() );
656  last_seen_restype_ = & upstream_conformation.type();
658 
659  }
660 
661  target_geomcst_coords_->set_coordinates_for_rotamer(
663  hit, upstream_conformation );
664 }
665 
667  upstream::UpstreamBuilder const & usbuilder
668 )
669 {
670  utility::vector1< Size > old_2_new( target_restypes_.size(), 0 );
671  //TR << "TARGET RESTYPES: "<< target_restypes_.size() << "UPSTREAMBUILDER RESTYPES: " <<usbuilder.n_restypes_to_build() << std::endl;
672  runtime_assert( target_restypes_.size() == usbuilder.n_restypes_to_build() );
673  for ( Size ii = 1; ii <= usbuilder.n_restypes_to_build(); ++ii ) {
674  std::map< core::chemical::ResidueTypeCOP, Size >::const_iterator
675  olditer = target_restype_index_map_.find( usbuilder.restype( ii ) );
676  //TR << "TARGET RESTYPES: " << usbuilder.restype( ii )->name() << std::endl;
677  runtime_assert( olditer != target_restype_index_map_.end() );
678  old_2_new[ olditer->second ] = ii;
679  }
680  for ( Size ii = 1; ii <= usbuilder.n_restypes_to_build(); ++ii ) {
681  runtime_assert( old_2_new[ ii ] != 0 );
682  }
683 
685  utility::vector1< EvaluatorSet > old_respair_evaluators( respair_evaluators_ );
686 
687  for ( Size ii = 1; ii <= usbuilder.n_restypes_to_build(); ++ii ) {
688  target_restypes_[ old_2_new[ ii ] ] = old_target_restypes[ ii ];
689  respair_evaluators_[ old_2_new[ ii ] ] = old_respair_evaluators[ ii ];
690  target_restype_index_map_[ target_restypes_[ old_2_new[ ii ] ] ] = old_2_new[ ii ];
691  }
692 
693 }
694 
695 // TargetRotamerCoords class
697  n_rots_total_( 0 )
698 {
699 }
700 
702 
704 {
705  target_restypes_.resize( n_restypes );
706  atom_ids_for_coordinates_.resize( n_restypes );
707  coords_.resize( n_restypes );
708  hit_data_.resize( n_restypes );
709 }
710 
712  Size restype_index,
714 {
715  target_restypes_[ restype_index ] = restype;
716 }
717 
719  Size restype_index,
720  utility::vector1< bool > const & atom_required
721 )
722 {
723  Size count_required( 0 );
724  runtime_assert( atom_required.size() == target_restypes_[ restype_index ]->natoms() );
725 
726  for ( Size ii = 1; ii <= atom_required.size(); ++ii ) if ( atom_required[ ii ] ) ++count_required;
727  atom_ids_for_coordinates_[ restype_index ].resize( count_required );
728  count_required = 0;
729  for ( Size ii = 1; ii <= atom_required.size(); ++ii ) {
730  if ( atom_required[ ii ] ) {
731  ++count_required;
732  atom_ids_for_coordinates_[ restype_index ][ count_required ] = ii;
733  //std::cout << "Requiring atom " << target_restypes_[ restype_index ]->atom_name( ii ) << std::endl;
734  }
735  }
736 }
737 
739  utility::vector1< Size > const & n_rotamers_per_target_restype
740 )
741 {
742  runtime_assert( n_rotamers_per_target_restype.size() == target_restypes_.size() );
743  n_rots_total_ = 0;
744  for ( Size ii = 1; ii <= n_rotamers_per_target_restype.size(); ++ii ) {
745  n_rots_total_ += n_rotamers_per_target_restype[ ii ];
746  if ( n_rotamers_per_target_restype[ ii ] != 0 ) {
747  //std::cout << "Setting n_rotamers for " << target_restypes_[ ii ]->name() << " " << atom_ids_for_coordinates_[ ii ].size() << " " << n_rotamers_per_target_restype[ ii ] << std::endl;
748  coords_[ ii ].dimension( atom_ids_for_coordinates_[ ii ].size(), n_rotamers_per_target_restype[ ii ] );
749  hit_data_[ ii ].resize( n_rotamers_per_target_restype[ ii ] );
750  } else {
751  coords_[ ii ].clear();
752  hit_data_[ ii ].clear();
753  }
754  }
755 }
756 
757 
759  Size target_restype_id,
760  Size n_rotamers
761 )
762 {
763 
764  if ( coords_.size() == 1 && target_restype_id == 1 ) {
765  n_rots_total_ = n_rotamers;
766  }
767  if ( n_rotamers != 0 ) {
768  //std::cout << "Setting n_rotamers for " << target_restypes_[ ii ]->name() << " " << atom_ids_for_coordinates_[ ii ].size() << " " << n_rotamers_per_target_restype[ ii ] << std::endl;
769  coords_[ target_restype_id ].dimension( atom_ids_for_coordinates_[ target_restype_id ].size(), n_rotamers );
770  hit_data_[ target_restype_id ].resize( n_rotamers );
771  } else {
772  coords_[ target_restype_id ].clear();
773  hit_data_[ target_restype_id ].clear();
774  }
775 
776 }
777 
778 
780  Size restype_index,
781  Size rotamer_index,
782  Hit const & hit,
783  core::conformation::Residue const & rescoords
784 )
785 {
786  for ( Size ii = 1, ii_end = n_atoms_for_restype( restype_index ); ii <= ii_end; ++ii ) {
787  coords_[ restype_index ]( ii, rotamer_index ) = rescoords.xyz( atom_ids_for_coordinates_[ restype_index ][ ii ] );
788  /*std::cout << "Coord: " << rescoords.name() << " " << ii << " " << rescoords.atom_name( atom_ids_for_coordinates_[ restype_index ][ ii ] );
789  std::cout << " " << coords_[ restype_index ]( ii, rotamer_index ).x();
790  std::cout << " " << coords_[ restype_index ]( ii, rotamer_index ).y();
791  std::cout << " " << coords_[ restype_index ]( ii, rotamer_index ).z() << std::endl;*/
792  }
793  hit_data_[ restype_index ][ rotamer_index ] = hit;
794 }
795 
798 ) :
799  sec_matcher_( sec_matcher )
800 {}
801 
802 void
804  Hit const & hit,
805  core::conformation::Residue const & upstream_conformation
806 )
807 {
808  sec_matcher_.process_hit( hit, upstream_conformation );
809 }
810 
811 
812 }
813 }
814 }