Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SecondaryMatcherToDownstreamResidue.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/SecondaryMatcherToDownstreamResidue.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>
29 // AUTO-REMOVED #include <protocols/match/downstream/LigandConformerBuilder.hh>
30 // AUTO-REMOVED #include <protocols/match/downstream/RigidLigandBuilder.hh>
34 // AUTO-REMOVED #include <protocols/match/upstream/ProteinUpstreamBuilder.hh>
36 // AUTO-REMOVED #include <protocols/match/BumpGrid.hh>
37 #include <core/pose/Pose.hh>
38 
39 // Project headers
42 
43 #include <basic/Tracer.hh>
44 
45 // Utility headers
46 #include <utility/pointer/ReferenceCount.hh>
47 #include <numeric/xyzVector.hh>
48 
49 // C++ headers
50 #include <list>
51 #include <string>
52 
53 #include <utility/vector1.hh>
54 
55 
56 
57 namespace protocols {
58 namespace match {
59 namespace downstream {
60 
61 static basic::Tracer TR( "protocols.match.downstream.SecondaryMatcherToDownstreamResidue" );
62 
64  core::pose::PoseCOP upstream_pose,
65  Size geom_cst_id
66 ) :
67  parent( geom_cst_id ),
68  upstream_pose_(upstream_pose)
69 {
70  for( core::Size ii=1; ii<=4; ++ii ){ catalytic_atoms_.push_back(0); }
71 }
72 
74 
77 {
78  return new SecondaryMatcherToDownstreamResidue( *this );
79 }
80 
81 
82 std::list< Hit >
84  Matcher & matcher
85 )
86 {
87  prepare_for_hit_generation( matcher );
88 
91  utility::vector1< std::list< Hit > > hits( my_build_points.size() );
92 
93  for ( Size ii = 1; ii <= geom_cst_id() - 1; ++ii ) {
94 
95  if ( ! matcher.representative_downstream_algorithm( ii )->generates_primary_hits() ) continue;
96 
98 
99  /// nab the launch points for my target
100  utility::vector1< upstream::ScaffoldBuildPointCOP > const & target_build_points
102 
103  for ( Size jj = 1; jj <= target_build_points.size(); ++jj ) {
104  if ( ! prepare_for_hit_generation_at_target_build_point( matcher, ii, *target_build_points[ jj ] )) {
105  continue;
106  }
107  TR << "Secondary matching against geomcst " << ii << " hits from build point " << target_build_points[ jj ]->original_insertion_point() << std::endl;
108  /// Parallelize here.
109  #pragma omp parallel for
110  for ( Size kk = 1; kk <= my_build_points.size(); ++kk ) {
111  //Most of the time we don't want to build residue at the same point
112  //as the target build point, but in the case of backbone matching
113  //if ( target_build_points[ jj ]->index() != my_build_points[ kk ]->index() ) {
114  //std::cout << "APL DEBUG build points SecondaryMatcherToDownstreamResidue::build_hits_at_all_positions " << kk << " matcher.upstream_builder: " << matcher.upstream_builder( geom_cst_id() )() << std::endl;
115  std::list< Hit > kk_hits = matcher.upstream_builder( geom_cst_id() )->build( * my_build_points[ kk ] );
116  hits[ kk ].splice( hits[ kk ].end(), kk_hits );
117  //}
118  }
119  }
120  }
121 
122  std::list< Hit > all_hits;
124  for ( Size ii = 1; ii <= my_build_points.size(); ++ii ) {
125  hits[ ii ].sort( compare );
126  all_hits.splice( all_hits.end(), hits[ ii ] );
127  }
128 
129  return all_hits;
130 
131 }
132 
133 void
135  Matcher & matcher,
136  Size round_just_completed
137 )
138 {
139  OccupiedSpaceHashOP occspace = matcher.occ_space_hash();
140 
141  if ( geom_cst_id() == round_just_completed ) {
142  TR << "Finished round " << geom_cst_id() << " with " << matcher.hits( geom_cst_id() ).size();
143  TR << " hits." << std::endl;
144  }
145 
146 
147  if ( geom_cst_id() != round_just_completed ) {
148  TR << "Updating the occupied space grid with " << matcher.hits( geom_cst_id() ).size();
149  TR << " hits from geometric constraint # " << geom_cst_id() << std::endl;
150  }
151 
152  occspace->prepare_to_note_hits_for_completed_round();
153 
154  /// Prepare to clear the cobwebs. Note which voxels in the occ_space_hash_
155  /// could lead to matches, and which voxels could not possibly lead to matches.
157  iter = matcher.hits( geom_cst_id() ).begin(),
158  iter_end = matcher.hits( geom_cst_id() ).end();
159  iter != iter_end; ++iter ) {
160  occspace->note_hit_geometry( iter->second() );
161  }
162 
163  occspace->drop_unsatisfied_voxels();
164 
165  occspace_rev_id_at_last_update_ = occspace->revision_id();
166 
167 }
168 
169 
170 /// @details Drop hits that had previously seemed viable after another round completed;
171 /// during that round, certain previously occupied regions of 6D were not filled
172 /// with new hits. Any previously-generated hit that falls into a region of 6D which is
173 /// no longer occupied should be elminated since it could not ever result in a match;
174 /// it is inviable.
175 void
177  Matcher & matcher
178 )
179 {
180  OccupiedSpaceHashOP occspace = matcher.occ_space_hash();
181  if ( occspace_rev_id_at_last_update_ == occspace->revision_id() ) {
182  /// Nothing about the occupied space hash has changed since I last pruned
183  /// my non-viable hits. There are no more non-viable hits that need pruning.
184  return;
185  }
186 
188  Matcher::HitListIterator iter_end = matcher.hit_list_end( geom_cst_id() );
189 
190  Size drop_count( 0 );
191 
192  while ( iter != iter_end ) {
193  Matcher::HitListIterator iter_next = iter;
194  ++iter_next;
195  if ( ! occspace->previous_round_geometry_still_matchable( iter->second() ) ) {
196  matcher.erase_hit( *this, geom_cst_id(), iter );
197  ++drop_count;
198  }
199  iter = iter_next;
200  }
201 
202  TR << "Erased " << drop_count << " round " << geom_cst_id();
203  TR << " hits with ";
204  TR << matcher.hits( geom_cst_id() ).size() << " hits remaining." << std::endl;
205 
206  occspace_rev_id_at_last_update_ = occspace->revision_id();
207 
208 }
209 
210 
211 /// @brief Iterate across the hits from a particular upstream build point i
212 /// that were generated in a previous round, and see if the geometry of the
213 /// input upstream_residue has "satisfactory interactions" with the
214 /// hits from upstream-build-point i; if so, it appends a Hit to the hitlist
215 /// returned at the end of the method. (Also, see comments for the
216 /// build_at_all_positions method.)
217 std::list< Hit >
219  Size const scaffold_build_point_id,
220  Size const upstream_conf_id,
221  core::conformation::Residue const & upstream_residue
222 ) const
223 {
224  std::list< Hit > hits;
225  Size const downstream_natoms = target_downstream_coords_->n_atoms_for_restype( 1 );
226  core::conformation::Residue target_residue( *downstream_restype_, false );
227  core::conformation::Residue target_residue_clash_check( *downstream_restype_, false );
228  utility::vector1< core::Vector > ds_coords( ( target_downstream_coords_->get_ds_atom_ids_needed() ).size() );
229 
230  // flo oct 09: moderate hack assuming that the ligand will always be last
231  target_residue.seqpos( upstream_pose_->total_residue() + 1);
232 
233  for ( Size ii = 1; ii <= target_downstream_coords_->n_rotamers_for_restype( 1 ); ++ii ) {
234  /// Set the coordinates for only the atoms that I need to give to the evaluator
235  for ( Size kk = 1; kk <= downstream_natoms; ++kk ) {
236  target_residue.set_xyz(
237  target_downstream_coords_->restype_atomno( 1, kk ),
238  target_downstream_coords_->coord( 1, ii, kk ));
239  }
240 
241  for ( EvaluatorSet::const_iterator eval_iter = respair_evaluators_.begin(),
242  eval_iter_end = respair_evaluators_.end();
243  eval_iter != eval_iter_end; ++eval_iter ) {
244 
245  if ( eval_iter->first->evaluate_residues( upstream_residue, target_residue ) ) {
246  //detect collision between downstream evaluator atoms
247  //and heavy sidechain atoms
248  if ( ! are_colliding( upstream_residue, target_residue, downstream_atom_coordinates_needed_, catalytic_atoms_ ) ) {
249 
250  //get coordinates from the downstream otherwise build and store them
251  if ( target_downstream_coords_->get_clash_checking( ii ) ) {
252  ds_coords = target_downstream_coords_->get_coords_for_clash_check( ii );
253  } else {
254  get_dsbuilder()->coordinates_from_hit( target_downstream_coords_->hit(1,ii), target_downstream_coords_->get_ds_atom_ids_needed(), ds_coords );
255  target_downstream_coords_->set_coords_for_clash_check( ii, ds_coords );
256  target_downstream_coords_->set_clash_checking( ii );
257  }
258  //fills downstream residue with coordinates for clash checking atoms
259  for ( Size ll = 1; ll <= ( target_downstream_coords_->get_ds_atom_ids_needed() ).size(); ++ll ) {
260  target_residue_clash_check.set_xyz( target_downstream_coords_->get_ds_atom_ids_needed()[ ll ].atomno(), ds_coords[ ll ] );
261  }
262 
263  if ( ! are_colliding( upstream_residue, target_residue_clash_check, target_downstream_coords_->get_ds_atom_ids_needed(), catalytic_atoms_ ) ) {
264  Hit hit;
265  hit.first()[ 1 ] = scaffold_build_point_id;
266  hit.first()[ 2 ] = upstream_conf_id;
267  hit.first()[ 3 ] = eval_iter->second;
268  hit.first()[ 4 ] = 1; // do not store the downstream rotamer id or the focused_geomcst_id_; we never try to recover this placement
269  hit.second() = target_downstream_coords_->hit( 1, ii ).second(); // downstream coordinate from previous round
270  hits.push_back( hit );
271  }
272  }
273  }
274  }
275  }
276  return hits;
277 }
278 
279 bool
281 {
282  return false;
283 }
284 
285 bool
287 {
288  return false;
289 }
290 
291 
294 {
295  HitPtrListCOP empty;
296  utility_exit_with_message( "Cannot invoke SecondaryMatcherToDownstreamResidue::hits_to_include_with_partial_match()" );
297  return empty;
298 }
299 
302 {
303  return target_downstream_coords_->n_rots_total();
304 }
305 
306 
307 void
309 {
310  downstream_restype_ = downstream_restype;
311 }
312 
313 
314 void
316 {
317  focused_geomcst_id_ = focused_geomcst_id;
318 }
319 
320 void
323  Size mcfi_id
324 )
325 {
326  respair_evaluators_.push_back( std::make_pair( evaluator, mcfi_id ) );
327 }
328 
329 
330 void
332  Matcher & matcher
333 )
334 {
335  TR << "Preparing for hit generation" << std::endl;
336 
337  /// Initialize the target_geomcst_coords_ object;
339  Size n_target_restypes = 1;
340  target_downstream_coords_->set_num_restypes( n_target_restypes );
341  target_downstream_coords_->set_restype( n_target_restypes, downstream_restype_ );
342 
343  /// Initialize the other downstream algorithms for this geometric constraint
344  /// so that they point all point to the same target_downstream_coords_ object
345  std::list< DownstreamAlgorithmOP > const & dsalgs = matcher.nonconst_downstream_algorithms( geom_cst_id() );
346  std::list< SecondaryMatcherToDownstreamResidueOP > secmatchers;
347  for ( std::list< DownstreamAlgorithmOP >::const_iterator iter = dsalgs.begin(),
348  iter_end = dsalgs.end(); iter != iter_end; ++iter ) {
350  dynamic_cast< SecondaryMatcherToDownstreamResidue * > ( iter->get() );
351  runtime_assert( secmatcher );
352  if ( secmatcher != this ) {
353  secmatcher->set_target_rotamer_coords( target_downstream_coords_ );
354  }
355  secmatchers.push_back( secmatcher );
356  }
357 
358  utility::vector1< bool > atom_required( downstream_restype_->natoms(), false );
360 
361  bool any_evaluators_require_all_coords( false );
362  for ( std::list< SecondaryMatcherToDownstreamResidueOP >::const_iterator
363  secmatch_iter = secmatchers.begin(), secmatch_iter_end = secmatchers.end();
364  secmatch_iter != secmatch_iter_end; ++secmatch_iter ) {
365 
366  for ( EvaluatorSet::const_iterator eval_iter = (*secmatch_iter)->respair_evaluators_.begin(),
367  eval_iter_end = (*secmatch_iter)->respair_evaluators_.end();
368  eval_iter != eval_iter_end; ++eval_iter ) {
369 
370  if ( eval_iter->first->require_all_target_residue_atom_coordinates() ) {
371  any_evaluators_require_all_coords = true;
372  break;
373  }
374  }
375  if ( any_evaluators_require_all_coords ) break;
376  }
377 
378  if ( any_evaluators_require_all_coords ) {
379  std::fill( atom_required.begin(), atom_required.end(), true );
380  } else {
381  for ( Size ii = 1; ii <= downstream_restype_->natoms(); ++ii ) {
382 
383  for ( std::list< SecondaryMatcherToDownstreamResidueOP >::const_iterator
384  secmatch_iter = secmatchers.begin(), secmatch_iter_end = secmatchers.end();
385  secmatch_iter != secmatch_iter_end; ++secmatch_iter ) {
386 
387  for ( EvaluatorSet::const_iterator eval_iter = (*secmatch_iter)->respair_evaluators_.begin(),
388  eval_iter_end = (*secmatch_iter)->respair_evaluators_.end();
389  eval_iter != eval_iter_end; ++eval_iter ) {
390 
391  if ( eval_iter->first->require_target_atom_coordinate( ii ) ) {
392  atom_required[ ii ] = true;
393  break;
394  }
395  }
396  if ( atom_required[ ii ] ) break;
397  }
398  } // for ii
399  }
400 
401  target_downstream_coords_->set_required_atoms( 1, atom_required );
402  for ( Size ii = 1; ii <= downstream_restype_->natoms(); ++ii ) {
403  if ( atom_required[ ii ] ) downstream_atom_coordinates_needed_.push_back( core::id::AtomID( ii, 1 ) );
404  }
405 
407 }
408 
409 void
411  Matcher & matcher,
412  Size target_geomcst_id
413 )
414 {
415  focused_geomcst_id_ = target_geomcst_id;
417 
421 
422  /// Make sure all the downstream algorithms for this geom_cst_id()
423  /// know which geomcst is the source for this next batch of hits.
424  std::list< DownstreamAlgorithmOP > const & dsalgs = matcher.nonconst_downstream_algorithms( geom_cst_id() );
425  for ( std::list< DownstreamAlgorithmOP >::const_iterator
426  iter = dsalgs.begin(), iter_end = dsalgs.end();
427  iter != iter_end; ++iter ) {
428  if ( iter->get() != this ) {
429  SecondaryMatcherToDownstreamResidueOP other = dynamic_cast< SecondaryMatcherToDownstreamResidue * > ( iter->get() );
430  runtime_assert( other );
431  other->set_focused_geomcst_id( focused_geomcst_id_ );
432  //set downstram atom coords needed for all downstream algorithms
433  //and also downstreambuilders that are needed to get coordinates
434  //clash checking
435  other->set_ds_coords_needed( downstream_atom_coordinates_needed_);
436  other->set_dsbuilder( matcher.downstream_builder( focused_geomcst_id_ ) );
437  }
438  }
439 
441  utility::vector1< core::id::AtomID > downstream_atoms_for_clash_checking;
442 
443  for ( Size natoms_ds = 1; natoms_ds <= lig_confs.n_collision_check_atoms(); ++natoms_ds ) {
444  Size id = lig_confs.collision_check_id_2_restype_id( natoms_ds );
445  if ( ! ds_atom_present(id) )
446  downstream_atoms_for_clash_checking.push_back( core::id::AtomID(id,1) );
447  }
448 
449  target_downstream_coords_->set_ds_atom_ids_needed(downstream_atoms_for_clash_checking);
450 
451 }
452 
453 bool
455  Size index
456 ) const {
457  for ( Size ii = 1; ii <= downstream_atom_coordinates_needed_.size(); ++ii ){
458  if ( index == downstream_atom_coordinates_needed_[ii].atomno() ) return true;
459  }
460  return false;
461 }
462 
463 bool
465  Matcher & /*matcher*/,
466  Size target_geomcst_id,
467  upstream::ScaffoldBuildPoint const & target_build_point
468 )
469 {
470  TR << "Preparing to examine geomcst-" << target_geomcst_id << "'s hits built from scaffold build point " << target_build_point.original_insertion_point() << std::endl;
471 
472 
473  Size target_build_id = target_build_point.index();
474 
475  /// Find the range of iterators that cover the hits for the upstream matcher
477  if ( hits_for_focused_geomcst_and_build_point_begin_->scaffold_build_id() == target_build_id ) {
478  break;
479  } else if ( hits_for_focused_geomcst_and_build_point_begin_->scaffold_build_id() > target_build_id ) {
480  break;
481  }
483  }
485  Size count_target_hits( 0 );
487  if ( hits_for_focused_geomcst_and_build_point_end_->scaffold_build_id() != target_build_id ) {
488  break;
489  }
491  ++count_target_hits;
492  }
493 
495  TR << "No geomcst-" << focused_geomcst_id_ << " hits built from scaffold build point " << target_build_point.original_insertion_point() << std::endl;
496  return false;
497  }
498 
499  /// Now rebuild the coordinates for the hits that have been selected.
500  target_downstream_coords_->set_num_target_rotamers( 1, count_target_hits );
501  target_downstream_coords_->set_clash_check_types( count_target_hits );
502 
503 // DownstreamBuilderOP dsbuilder = matcher.downstream_builder( focused_geomcst_id_ );
504  //set_dsbuilder( matcher.downstream_builder( focused_geomcst_id_ ) );
505  runtime_assert( get_dsbuilder() );
506 
507  core::conformation::Residue dsrescoords( *downstream_restype_, false );
509 
510  Size count_ds_hits( 0 );
512  iter_end = hits_for_focused_geomcst_and_build_point_end_; iter != iter_end; ++iter ) {
513  ++count_ds_hits;
514  get_dsbuilder()->coordinates_from_hit( *iter, downstream_atom_coordinates_needed_, coords );
515  for ( Size ii = 1; ii <= downstream_atom_coordinates_needed_.size(); ++ii ) {
516  dsrescoords.set_xyz( downstream_atom_coordinates_needed_[ ii ].atomno(), coords[ ii ] );
517  }
518  target_downstream_coords_->set_coordinates_for_rotamer(
519  1, count_ds_hits,
520  *iter, dsrescoords );
521  }
522 
523  /// This would also be the appropriate time to initialize a pruning object to
524  /// quickly reject rotamers in the UpstreamBuilder.
525  TR << "Examining " << count_target_hits << " hits built from scaffold build point "
526  << target_build_point.original_insertion_point() << " representing " << target_downstream_coords_->n_rots_total()
527  << " unique upstream rotamers" << std::endl;
528 
529  return true;
530 }
531 
532 void
534  TargetRotamerCoordsOP target_downstream_coords
535 )
536 {
537  target_downstream_coords_ = target_downstream_coords;
538 }
539 
540 }
541 }
542 }