Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PlaceStubMover.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 sw=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 protocols/protein_interface_design/movers/PlaceStubMover.cc
11 /// @brief
12 /// @author Sarel Fleishman (sarelf@u.washington.edu), Jacob Corn (jecorn@u.washington.edu), Eva-Maria Strauch (evas01@u.washington.edu)
13 
14 // Unit headers
17 #include <boost/foreach.hpp>
18 #define foreach BOOST_FOREACH
19 
20 // Project Headers
21 #include <utility/tag/Tag.hh>
22 #include <core/types.hh>
23 #include <core/pose/Pose.hh>
25 #include <core/id/AtomID.hh>
26 #include <core/chemical/AA.hh>
27 #include <numeric/xyzVector.hh>
31 #include <protocols/moves/ResId.hh>
32 
35 // AUTO-REMOVED #include <core/scoring/constraints/XYZ_Func.hh>
36 
41 
46 
47 #include <protocols/moves/Mover.hh>
51 
54 #include <core/pose/selection.hh>
55 
56 // Utility Headers
57 #include <utility/exit.hh>
58 #include <protocols/jd2/Job.hh>
60 
61 // Unit Headers
65 // AUTO-REMOVED #include <protocols/protein_interface_design/util.hh>
67 
68 #include <numeric/random/random.hh>
69 #include <numeric/random/random_permutation.hh>
70 
71 #include <basic/options/option.hh>
72 #include <basic/options/keys/packing.OptionKeys.gen.hh>
73 #include <basic/options/keys/hotspot.OptionKeys.gen.hh>
75 
76 // C++ headers
77 #include <map>
78 #include <algorithm>
79 
81 #include <core/pose/util.hh>
82 #include <utility/vector0.hh>
83 #include <utility/vector1.hh>
84 #include <numeric/NumericTraits.hh>
85 #include <basic/Tracer.hh>
86 
87 //Auto Headers
92 using namespace core::scoring;
93 
94 static basic::Tracer TR( "protocols.protein_interface_design.movers.PlaceStubMover" );
95 static basic::Tracer stats_TR( "STATS.PlaceStubMover" );
96 static basic::Tracer TR_debug( "DEBUG.PlaceStubMover" );
97 
98 static numeric::random::RandomGenerator RG( 10101979 ); // <- Magic number, do not change it!!!
99 
100 namespace protocols {
101 namespace protein_interface_design {
102 namespace movers {
103 
104 using namespace protocols::moves;
105 using namespace core;
106 
108 PlaceStubMoverCreator::keyname() const
109 {
110  return PlaceStubMoverCreator::mover_name();
111 }
112 
114 PlaceStubMoverCreator::create_mover() const {
115  return new PlaceStubMover;
116 }
117 
119 PlaceStubMoverCreator::mover_name()
120 {
121  return "PlaceStub";
122 }
123 
124 PlaceStubMover::PlaceStubMover() :
125  simple_moves::DesignRepackMover( PlaceStubMoverCreator::mover_name() ),
126  score_threshold_( 0.0 ),
127  host_chain_( 2 ),
128  stub_set_( NULL ),
129  add_constraints_( false ),
130  after_placement_filter_( NULL ),
131  final_filter_( NULL ),
132  coord_cst_func_( NULL ),
133  default_fold_tree_( NULL ),
134  leave_coord_csts_after_placement_( false ),
135  place_scaffold_( false ),
136  max_cb_cb_dist_( 4.0 ),
137  hurry_( true ),
138  triage_positions_( true ),
139  stub_energy_threshold_( 1.0 ),
140  residue_level_tasks_for_placed_hotspots_( NULL ),
141  residue_numbers_( NULL )
142 {
143  coord_cst_std_.clear();
144  disallowed_host_pos_.clear();
145  stub_minimize_movers_.clear();
146  design_movers_.clear();
147  placed_stubs_.clear();
150  saved_bb_constraints_.clear();
151  saved_placed_stubs_.clear();
152 }
153 
156  core::Real score_threshold,
157  core::Size const host_chain,
158  protocols::filters::FilterOP final_filter,
159  bool const hurry/*=false*/,
160  bool const triage_positions/*=true*/,
161  core::Real stub_energy_threshold /*= 1.0*/
162 ) :
163  simple_moves::DesignRepackMover( PlaceStubMoverCreator::mover_name() ),
164  score_threshold_( score_threshold ),
165  host_chain_( host_chain ),
166  hurry_(hurry),
167  triage_positions_(triage_positions),
168  stub_energy_threshold_(stub_energy_threshold)
169 {
170  if( stub_set ) stub_set_ = new protocols::hotspot_hashing::HotspotStubSet( *stub_set );
171  final_filter_ = final_filter->clone();
172 }
173 
175 
178  return( protocols::moves::MoverOP( new PlaceStubMover( *this ) ) );
179 }
180 
181 
182 /// @detailed utility function that places a stub at an acceptor position and cleans up the pose
183 void
185 {
186  runtime_assert( res_num <= pose.total_residue() );
187  core::Size const chain_begin( pose.conformation().chain_begin( host_chain_ ) );
188  core::Size const chain_end ( pose.conformation().chain_end ( host_chain_ ) );
189 /// Using a default fold tree, rather than the existing atom tree, b/c the atom
190 /// tree might assume the existence of sidechain atoms that will no longer be available
191 /// after the residue replacement.
192  pose.fold_tree( *default_fold_tree_ );
193  std::pair< core::Size, bool > const res_cst( std::make_pair( res_num, add_constraints_ ) );
194  placed_stubs_.push_back( res_cst );
195  pose.replace_residue( res_num, res_stub, true );
196  using namespace core::chemical;
197 //removing variant types can only be done if the residue would still be connected to the chain
198  if( res_num < chain_end )
200  if( res_num > chain_begin )
202  pose.conformation().update_polymeric_connection( res_num ); // o/w residues connections mess up
203  if( res_num > chain_begin )
204  pose.conformation().update_polymeric_connection( res_num - 1 );
205 /// return to stub_based atom tree
206  if( place_scaffold_ ){
207  // currently only supports host being on chain2
208  // we append the stub residue to the target by jump and then impose that jump
209  // on the target-scaffold complex
210  runtime_assert( host_chain_==2 );// other options not supported yet
211 
212  core::pose::Pose partner_chain( pose.split_by_chain( 1 ) );
213  TR_debug<<"foldtree before append: "<<partner_chain.fold_tree()<<std::endl;
214  partner_chain.append_residue_by_jump( res_stub, 1 );
215  TR_debug<<"foldtree after append: "<<partner_chain.fold_tree()<<std::endl;
216  core::kinematics::Jump const saved_jump( partner_chain.jump( partner_chain.num_jump() ) );
217 
218  core::kinematics::FoldTree pose_stub_tree;
219  core::Size const rb_jump( 1 );
220  {//setup pose-stub ft
221  pose_stub_tree.clear();
222  using namespace core::kinematics;
223  pose_stub_tree.add_edge( 1, partner_chain.total_residue()-1, Edge::PEPTIDE );
224  pose_stub_tree.add_edge( 1, partner_chain.total_residue(), rb_jump );
225  pose_stub_tree.set_jump_atoms( rb_jump, partner_chain.residue( 1 ).atom_type( partner_chain.residue( 1 ).nbr_atom()).element(), "CB" );
226  partner_chain.fold_tree( pose_stub_tree );
227  TR_debug<<"pose stub tree: "<<partner_chain.fold_tree()<<std::endl;
228  }//pose stub ft
229  core::kinematics::Jump const pose_stub_jump( partner_chain.jump( rb_jump ) );
231  {//setup new ft for target-scaffold
232  core::Size const host_chain_begin( pose.conformation().chain_begin( host_chain_ ) );
233  core::Size const host_chain_end ( pose.conformation().chain_end ( host_chain_ ) );
234  new_ft.clear();
235  core::Size const jump_pos1( 1 );
236  core::Size const jump_pos2( res_num );
237  new_ft.clear();
238  new_ft.add_edge( jump_pos1, jump_pos2, rb_jump );
239  new_ft.add_edge( jump_pos1, pose.conformation().chain_end( 1 ), kinematics::Edge::PEPTIDE );
240  if( jump_pos2 > host_chain_begin )
241  new_ft.add_edge( pose.conformation().chain_begin( 2 ), jump_pos2, kinematics::Edge::PEPTIDE );
242  if( jump_pos2 < host_chain_end )
243  new_ft.add_edge( jump_pos2, pose.total_residue(), kinematics::Edge::PEPTIDE );
244  new_ft.set_jump_atoms( rb_jump, pose.residue( 1 ).atom_type( pose.residue( 1 ).nbr_atom()).element(), "CB" );
245  new_ft.reorder( 1 );
246  new_ft.delete_self_edges();
247  TR_debug<<"pose fold tree before imposing new jump "<<pose.fold_tree()<<std::endl;
248  pose.fold_tree( new_ft );
249  TR_debug<<"pose fold tree after imposing new jump "<<pose.fold_tree()<<std::endl;
250  }//new ft
251  pose.set_jump( 1, pose_stub_jump );
252  }
253  stub_based_atom_tree( pose, res_stub, 0.5/*cst_sdev*/ );
255 }
256 
257 /// @details minimize the rb orientation in the presence of a strong bb_stub_constraint potential, while reducing
258 /// all other attractive scores. fa_sol is also reduced to avoid blowing up the structure. Returns false if current
259 /// pose has no backbone_stub_constraint score. Removes stub constraints after minimization.
260 /// If more than one stub has already been placed then the jumps are held rigid during minimization
261 /// If a stub is specified, then a custom-made hotspot constraint is used
262 bool
263 PlaceStubMover::StubMinimize( core::pose::Pose & pose, protocols::hotspot_hashing::HotspotStubCOP stub/* = NULL*/, core::Size const host_residue/*= 0*/, bool const hurry /*=false*/ ){
264  core::Size fixed_res(1);
265  if( host_chain_ == 1 ) fixed_res = pose.total_residue();
266  core::id::AtomID const fixed_atom_id = core::id::AtomID( pose.residue(fixed_res).atom_index("CA"), fixed_res );
267  core::pack::task::PackerTaskOP stub_task = stub_set_->prepare_hashing_packer_task_( pose, host_chain_ );
268  core::Size const host_chain_begin( pose.conformation().chain_begin( host_chain_ ) );
269  core::Size const host_chain_end ( pose.conformation().chain_end ( host_chain_ ) );
270 
271  using namespace core::scoring::constraints;
272  ConstraintCOPs const csts_before_min = pose.constraint_set()->get_all_constraints();
273  core::Size const num_csts_before_min( csts_before_min.size() );
274 
275  using namespace core::scoring;
277  ScoreFunctionOP stub_scorefxn( new ScoreFunction( *score12 ));
278  if( hurry ) {
279  TR << "Speeding up StubMinimize..." << std::endl;
280  stub_scorefxn->reset();
281  stub_scorefxn->set_weight( backbone_stub_constraint, 10.0 );//is getting reset, if stub minimize mover is specified
282  stub_scorefxn->set_weight( fa_rep, 0.44 );
283  stub_scorefxn->set_weight( fa_dun, 0.56 );
284  stub_scorefxn->set_weight( coordinate_constraint, 1.0 );
285  //adding additional score types to ensure proper backbone parameters
286  }
287  else {stub_scorefxn->set_weight( fa_atr, 0.01 );
288  stub_scorefxn->set_weight( backbone_stub_constraint, 10.0 );//is getting reset, if stub minimize mover is specified
289  stub_scorefxn->set_weight( fa_sol, 0.01 );
290  stub_scorefxn->set_weight( fa_pair, 0.01 );
291  stub_scorefxn->set_weight( hbond_lr_bb, 0.01 );
292  stub_scorefxn->set_weight( hbond_sr_bb, 0.01 );
293  stub_scorefxn->set_weight( hbond_bb_sc, 0.01 );
294  stub_scorefxn->set_weight( hbond_sc, 0.01 );
295  stub_scorefxn->set_weight( coordinate_constraint, 1.0 );
296  }
297  using namespace protocols::hotspot_hashing;
299  if( stub() != NULL ){ //one stub-based constraint
300  runtime_assert( host_residue );
301  core::conformation::Residue const host_res( pose.conformation().residue( host_residue ) );
302  core::Real dummy1, dummy2;
303  if( !test_res_res_aln( host_res, *stub->residue(), dummy1, dummy2 ) ){
304  TR_debug<<"Not minimizing towards this stub, b/c of large orientational discrepancy\n";
305  return( false );
306  }
307  // setup the constraint based on a single stub <-> single host residue.
308  // The cb force is computed analytically so as to (almost) maximise the steepness
309  // of the potential while ascertaining that the potential is felt by the host residue
310  // at the distance where it is positioned to begin with.
311  TR<<"making single-stub based constraint\n";
312  core::Real const distance( pose.residue( host_residue ).xyz( "CB" ).distance( stub->residue()->xyz( "CB" ) ) );
313  core::Real const bonus( stub->bonus_value() );
314  //I'm capping the value of cb_force to [0.05 .. 10.0]
315  core::Real const cb_force( std::max( std::min( 10.0, -bonus / (distance * distance) - 0.05 ), 0.05 ) );
316  TR << "Cb force: "<<cb_force<<std::endl;
317  // I'm circumventing add_hotspot_constraints to pose and adding the constraint directly
318  // since there's no ambiguity here and no need to switch to ala pose etc. And I don't
319  // want all the quality control machinery to be applied to this stub; I know it's good.
320  stub_constraints.push_back( new BackboneStubConstraint( pose, host_residue, fixed_atom_id, host_res, bonus, cb_force ) );
321  stub_constraints = pose.add_constraints( stub_constraints );
322  }// stub() != NULL
323  else{ //multiple stubs
324  /// Now circumventing add_hotspot_constraints b/c of the huge computational load of
325  /// computing sasa etc.
326  using namespace core::scoring::constraints;
327  if( stub_set_->constraints().empty() ){
328  for( core::Size resi=host_chain_begin; resi<=host_chain_end; ++resi )
329  if( std::find( prevent_repacking_.begin(), prevent_repacking_.end(),resi ) != prevent_repacking_.end() )
330  stub_task->nonconst_residue_task( resi ).prevent_repacking();
331  TR<<"adding multiple stub constraints to pose\n";
332  stub_set_->add_hotspot_constraints_to_pose( pose, fixed_atom_id, stub_task, stub_set_, 0.7/*cb force*/, 0/*worst allowed stub bonus*/, false/*apply self energies*/, 10.0/*bump cutoff*/, true/*apply ambiguous constraints*/ );
333  (*stub_scorefxn)(pose);//for ->active_constraint to be set below.
334  }
335  else{//constraints not empty
336  ConstraintCOPs constraints;
337  constraints = pose.add_constraints( stub_set_->constraints() );
338  core::Size const constraint_num( constraints.size() );
339  TR<<"adding "<<constraint_num<<" stub constraints to pose"<<std::endl;
340  (*stub_scorefxn)(pose);//for ->active_constraint to be set below.
341  if( !prevent_repacking_.empty() ){
342  ConstraintCOPs to_be_removed;
343  for( ConstraintCOPs::const_iterator it = constraints.begin(); it != constraints.end(); ++it ){
344  AmbiguousConstraintCOP cst = dynamic_cast< AmbiguousConstraint const * >( (*it).get() );
345  runtime_assert( cst );
346 
347  using namespace core::scoring::constraints;
348  ConstraintCOP active_constraint = cst->active_constraint();
349 
350  if( active_constraint->type() == "BackboneStub" ){
351  BackboneStubConstraintCOP bb_cst = dynamic_cast< BackboneStubConstraint const * >( active_constraint() );
352  runtime_assert( bb_cst );
353  if( std::find( prevent_repacking_.begin(), prevent_repacking_.end(), bb_cst->seqpos() ) != prevent_repacking_.end() )
354  to_be_removed.push_back( *it ); //remove the entire ambiguous constraint, if the active constraint points to a non-repackable residue
355  }
356  }
357  if( !to_be_removed.empty() ){
358  pose.remove_constraints( to_be_removed );
359  TR<<"removed "<<to_be_removed.size()<<" constraints\n";
360  }
361  }//!prevent_repacking_.empty()
362  }//constraints not empty
363  }//multiple stubs
364 
365  using namespace core::scoring;
366  core::Size num_rigid_jumps( 0 );
367  for( utility::vector1< std::pair< core::Size, bool > >::const_iterator it=placed_stubs_.begin(), end=placed_stubs_.end(); it!=end; ++it )
368  if( !it->second ) num_rigid_jumps++;
369  if( num_rigid_jumps > 1 ){
370  TR<<"****WARNING WARNING**** Activating chainbreak weight, implying two rigid jumps.\n";
371  TR<<"Not fully supported by PlaceStub\n";
372  stub_scorefxn->set_weight( chainbreak, 1.0 ); //***** Is this the correct chainbreak weight to activate here?
373  }
374  //currently we only support one rigid jump. The remainder have to be set
375  //by constraints. There are no explicit checks in the code for this and
376  //it is up to the user to make sure that all's well...
377 
378  simple_filters::ScoreTypeFilter const stf( stub_scorefxn, backbone_stub_constraint, 1.0 );
379  core::Real const before_min( stf.compute( pose ) );
380  if( before_min >= -0.0001 ){
381  if( stub() != NULL ){
382  TR<<"no bb stub constraint score even though I computed it analytically! Ask Sarel what's wrong here."<<std::endl;;
383  runtime_assert( stub() != NULL );
384  }
386  TR<<"removing stub constraints from pose\n";
387  return false;
388  }
389  //for minimization (rb and sc of previous placed stubs)
390  utility::vector1< bool > sc_min( pose.total_residue(), false );
391  utility::vector1< bool > const no_min( pose.total_residue(), false );
392  utility::vector1< core::Size > const no_targets;
393  // minimize the sc of all placed stubs
394  for( utility::vector1< std::pair< core::Size, bool > >::const_iterator iter=placed_stubs_.begin(), end=placed_stubs_.end(); iter!=end; ++iter ) sc_min[ iter->first ] = true;
395  //getting angle alignments, CB distances and CB force
396  using namespace protocols::hotspot_hashing;
397  core::Real C_N_angle_before_minmize_mover(0);
398  core::Real CB_CA_angle_before_minmize_mover(0);
399  core::Real before_min_distance(0);
400  core::Real curr_bonus(0);
401  core::Size before_apply_stub_minimize_mover(0);
402  core::Real before_min_cb_force(0);
403 
404  if( stub() != NULL ){
405  before_min_distance = pose.residue( host_residue ).xyz( "CB" ).distance( stub->residue()->xyz( "CB" ) );
406  curr_bonus = stub->bonus_value();
407  before_apply_stub_minimize_mover = pose.constraint_set()->get_all_constraints().size();//coordinate constraint shouldnt change
408  before_min_cb_force = -curr_bonus / (before_min_distance *before_min_distance );
409 
410  //scoring the pose before testing the alignment to get the angles....
411  test_res_res_aln( pose.residue( host_residue ), *stub->residue(), C_N_angle_before_minmize_mover, CB_CA_angle_before_minmize_mover );
412  (*stub_scorefxn )( pose ); //to update values
413 
414  //minimizing stub using user-defined movers or a default minimization (rb and sc of placed stubs)
415  typedef std::pair< simple_moves::DesignRepackMoverOP, core::Real > DesignMoverRealPair;
416  if ( stub_minimize_movers_.size() ){
417  TR<<"entering movers for stub minimization....\n";
418  //minimize rb and sc of previous place
419  TR<<"performing an initial rb minimization as well as sc minimization of previously placed stubs (if present) \n";
420  MinimizeInterface( pose, stub_scorefxn, no_min/*bb*/, sc_min, min_rb()/*rb*/, false /*optimize foldtree*/, no_targets, true/*simultaneous optimization*/);
421  //starting mover list
423  simple_moves::DesignRepackMoverOP const curr_mover( it->first );
424  core::Real const bb_cst_weight( it->second );
425  TR<<"applying mover: "<<curr_mover->get_name()<<'\n';
426  //restricting movers for stub minimization
427  curr_mover->prevent_repacking( prevent_repacking() );
428  curr_mover->optimize_foldtree( false );
429  curr_mover->design( false ); //we dont want any design to take place within any mover for stub minimization
430  TR<<" design and repacking during stub minimization is prevented" << std::endl;
431  TR<<"using weight: "<<bb_cst_weight<<" for the stub bb constraints "<<std::endl;
432  ScoreFunctionOP minimize_mover_scorefxn_repack( curr_mover->scorefxn_repack() );
433  if( minimize_mover_scorefxn_repack )
434  minimize_mover_scorefxn_repack->set_weight( backbone_stub_constraint, bb_cst_weight );
435  ScoreFunctionOP minimize_mover_scorefxn_minimize( curr_mover->scorefxn_minimize() );
436  if( minimize_mover_scorefxn_minimize )
437  minimize_mover_scorefxn_minimize->set_weight( backbone_stub_constraint, bb_cst_weight );
438  curr_mover->apply( pose );
439  } //end of user movers
440  MinimizeInterface( pose, stub_scorefxn, no_min/*bb*/, sc_min, min_rb()/*rb*/, false /*optimize foldtree*/, no_targets, true/*simultaneous optimization*/ );
441  utility::vector1< bool > min_host( pose.total_residue(), false );
442  for( core::Size i=host_chain_begin; i<=host_chain_end; ++i ) min_host[ i ] = true;
443  utility::vector1< bool > const no_min_rb( pose.num_jump(), false );
444  MinimizeInterface( pose, score12, min_host/*bb*/, sc_min, no_min_rb/*rb*/, false /*optimize foldtree*/, no_targets, true/*simultaneous optimization*/ );
445  }//size()
446  else{
447  TR<<"Doing rb minimization towards the stub and sc minimization of placed stubs" <<std::endl;
448  MinimizeInterface( pose, stub_scorefxn, no_min/*bb*/, sc_min, min_rb()/*rb*/, false /*optimize foldtree*/, no_targets, true/*simultaneous optimization*/ );
449  }
450  //Reporting statistics for single-stub minimization
451  //getting angle alignments, CB distances and CB force
452  core::Real C_N_angle_after_minmize_mover;
453  core::Real CB_CA_angle_after_minmize_mover;
454  test_res_res_aln( pose.residue( host_residue ), *(stub->residue()), C_N_angle_after_minmize_mover, CB_CA_angle_after_minmize_mover );
455  //get distances and cb-force -- this is not the applied one, this is just for stats
456  core::Real const after_min_distance( pose.residue( host_residue ).xyz( "CB" ).distance( stub->residue()->xyz( "CB" ) ) );
457  Real const pi(numeric::NumericTraits<Real>::pi());
458  core::Real const curr_bonus( stub->bonus_value() );
459  core::Real const after_min_cb_force( -curr_bonus / (after_min_distance * after_min_distance) );
460  stats_TR<<"CB distances, before minimize movers: "<<before_min_distance<<" and after: "<<after_min_distance<<'\n';
461  stats_TR<<"C_N angle alignment, before minimization: "<<( C_N_angle_before_minmize_mover *180 )/pi<<" and after: "<<( C_N_angle_after_minmize_mover *180 )/pi<<'\n';
462  stats_TR<<"CB_CA angle alignment, before minimization: "<<( CB_CA_angle_before_minmize_mover *180 )/pi<<" and after: "<<( CB_CA_angle_after_minmize_mover *180 )/pi<<'\n';
463  stats_TR<<"cb force, before minimization: "<<"before entering minimize movers: "<<before_min_cb_force <<" and after minimization: "<<after_min_cb_force<<'\n';
464  //quality checks
465  core::Size const after_apply_stub_minimize_mover( pose.constraint_set()->get_all_constraints().size() );
466  TR_debug<<"before applying stub minimization mover "<<before_apply_stub_minimize_mover<<" constraints. After: "<<after_apply_stub_minimize_mover<<std::endl;
467  if( before_apply_stub_minimize_mover != after_apply_stub_minimize_mover ){
468  TR<<" ***ERROR: stub minimization has changed the number of constraints on the pose. Before: "<< before_apply_stub_minimize_mover<<" after: "<<after_apply_stub_minimize_mover<<". This behaviour is unsupported."<<std::endl;
469  runtime_assert( before_apply_stub_minimize_mover != after_apply_stub_minimize_mover );
470  }
471  }//stub!=NULL
472  else{
473  TR<<"Doing rb minimization towards the stub and sc minimization of placed stubs" <<std::endl;
474  MinimizeInterface( pose, stub_scorefxn, no_min/*bb*/, sc_min, min_rb()/*rb*/, false /*optimize foldtree*/, no_targets, true/*simultaneous optimization*/ );
475  }
476 
477  ////now completly done with minimization, checking that nothign unwanted has changed and clean up
478  core::Real const after_min( stf.compute( pose ) );
479  TR<<"backbone_stub_constraint score changed from "<<before_min<<" to "<<after_min<<" during minimization\n";
480  TR<<"removing hotspot constraints from pose" <<std::endl;
482 
483  ConstraintCOPs const csts_after_min = pose.constraint_set()->get_all_constraints();
484  core::Size const num_csts_after_min( csts_after_min.size() );
485  TR_debug<<"Csts before min "<<num_csts_before_min<<" after min "<<num_csts_after_min<<std::endl;
486  runtime_assert( num_csts_after_min == num_csts_before_min );//constraints shouldnt have changed
487 
488  TR<<"removed all hotspot constraints\n";
489 
490  if( after_min >= -0.0001 ){
491  TR<<"bb stub constraint score too high. Skipping this stub\n";
492 
493  return false;
494  }
495  return true;
496 }
497 
498 /// @details selects stubs by iterating over the stub_set_. Returns the status of stub selection
499 bool
500 PlaceStubMover::SelectStubIteratively( protocols::hotspot_hashing::HotspotStubSet::Hs_vec::const_iterator stub_it ) {
501  using namespace protocols::hotspot_hashing;
502 
503  bool accepted;
504  do {
505  if( stub_it == stub_set_->end() )
506  return false;
507  HotspotStubOP stub = stub_it->second.second;
508  core::Real const bonus( stub->bonus_value() );
509  TR<<"trying stub of bonus "<<bonus<<'\n';
510  accepted = bonus <= score_threshold_;
511  if( !accepted ){
512  TR<<"failed this stub\n";
513  ++stub_it;
514  }
515  } while( !accepted );
516  return true;
517 }
518 
519 /// @details remove all coordinate constraints from pose and then reapply them, changing
520 /// the HarmonicFunc's sdev to a new value
521 /// Nov09 Changing of previous logic. Now, only changing the sdev associated with the
522 /// coordinate constraints.
523 void
525 {
526 // remove_coordinate_constraints_from_pose( pose );
527  coord_cst_func_->sd( sdev );
528 // previous_coordinate_constraints_ = pose.add_constraints( previous_coordinate_constraints_ );
529 // curr_coordinate_constraints_ = pose.add_constraints( curr_coordinate_constraints_ );
530 }
531 
532 /// @details Placing a stub in the context of a complex by putting a stub on top of
533 /// the scaffold. The following steps are taken:
534 ///0. minimization of rb dofs in a bb_stub_constraint-dominated force field. Only the
535 /// constraints implied by the stubset associated with this placestub mover will be
536 /// applied.
537 ///1. stub selection, by iterating over a randomly shuffled stubset.
538 ///2. finding a residue on the host chain where the stub may be placed (distance cutoff).
539 ///3. testing the stub's repulsive energy on that residue in the context of a poly-alanine host chain.
540 ///4. repack/minimize the rb orientation of the pose (plus a little bb minimization around the stub, but no repacking of host_chain_).
541 ///5. testing the stub's total_score in the context of the full pose.
542 ///6. a vector of user-defined movers derived from DesignRepackMover. These may
543 /// include further placestub movers. If this is the case, these movers can be constrained
544 /// with coordinate constraints that are placed on the functional groups of the stub
545 /// sidechain. These movers can also define the force constant of these harmonic constraints.
546 /// Notice that this design should in
547 /// principle be fully extensible to as many stub placement and design movers as the
548 /// user chooses. If any of the user defined design movers (including subsequent stub
549 /// placement) fail, another stub placement is attempted and the user defined movers are
550 /// called again.
551 ///7. user_defined final_filter_ is called. If the pose does not pass this, place stub return to iterate over another stub. If all stubs fail, the mover signals failure and exits.
552 void
554 {
555  using namespace protocols::hotspot_hashing;
556 
559  // rescore the pose to ensure that backbone stub cst's are populated
561  bbcst_scorefxn->reset();
562  bbcst_scorefxn->set_weight( core::scoring::backbone_stub_constraint, 1.0 );
563  (*bbcst_scorefxn)( pose );
564 
565  // Remove old hotspot constraints from pose
566  core::Size count_two_sided( 0 );
567  core::Size const before_removal( pose.constraint_set()->get_all_constraints().size() );
569 
570  core::Size const after_removal( pose.constraint_set()->get_all_constraints().size() );
571  core::Size const bb_constraints_size( saved_bb_constraints_.size() );
572  if( bb_constraints_size > 0 ){
573  TR_debug<<"removed "<<bb_constraints_size<<" bb constraints from pose\n";
574  TR_debug<<"before removal "<<before_removal<<" after removal "<<after_removal<<'\n';
575  }
576 
577  core::Size const host_chain_begin( pose.conformation().chain_begin( host_chain_ ));
578  core::Size const host_chain_end( pose.conformation().chain_end( host_chain_ ));
579  if( !default_fold_tree_ )
581 
582  // change all interface residues on host_chain_ to ala, except for those that
583  // might already contain stubs or that are prevented from repacking for some other reason.
584  {// change to ala pose
585  // Switch to Ala unless we are doing place scaffold as a replacement for docking
586  if( !(place_scaffold_ && !triage_positions_) ){
587  BuildAlaPose toAla( host_chain_ == 1/*partner1*/, host_chain_ == 2 /*partner2*/ );
589  if( !prevent_repacking().empty() ) no_repack = prevent_repacking();
590  if( !placed_stubs_.empty() ){
591  for( utility::vector1< std::pair< core::Size, bool > >::const_iterator it=placed_stubs_.begin(), end=placed_stubs_.end(); it!=end; ++it )
592  no_repack.push_back( it->first );
593  }
594  if( !no_repack.empty() ){
595  std::sort( no_repack.begin(), no_repack.end() );
596  std::unique( no_repack.begin(), no_repack.end() );
597  toAla.prevent_repacking( no_repack );
598  }
599 
600  TR<<"switching interface to alanine\n";
601  toAla.apply( pose );
602  bool const minimization_status( StubMinimize( pose, NULL/*HotspotStubCOP*/, 0/*host_res*/, hurry_ ) );
603 
604  // Optional Triaging
605  if( triage_positions_ ) {
606  if( !minimization_status ){ // requires partners to already be placed correctly
607  TR<<"constraint score evaluates to 0 in this pose. Failing\n";
609  final_cleanup( pose );
610  return;
611  }
612  }
613  // End Triaging
614  }
615  }//change to ala pose
616 
619 
620  core::pose::Pose const saved_pose( pose ); //saved after minimization
623  numeric::random::random_permutation( stub_set_->begin(), stub_set_->end(), RG );// randomly shuffling stubs so that the selection doesn't repeat the same stub order each time
624  HotspotStubSet::Hs_vec::iterator stub_it( stub_set_->begin() );
625  std::vector< core::Size > host_positions;
626  if( task_factory() ){
627  utility::vector1< core::Size > const designable( protocols::rosetta_scripts::residue_packer_states( pose, task_factory(), true/*designable*/, false/*packable*/ ) );
628  foreach( core::Size const d, designable )
629  host_positions.push_back( d );
630  }
631  else{
632  for( core::Size i=host_chain_begin+1; i<=host_chain_end-1; ++i ) // avoid placements on chain termini
633  host_positions.push_back( i );
634  }
635 
636  do { // for each two sided trial
637  //select a stub
638  if( !SelectStubIteratively( stub_it ) ){
639  TR<<"Stub selection failed" <<std::endl;
641  final_cleanup( pose );
642  return;
643  }
644  HotspotStubOP stub( stub_it->second.second );
645  ++stub_it;
646 
647  // next, place the stub on a position in the host chain that is close enough
648  // randomize the order of placement on host residues to encourage diversity
649  numeric::random::random_permutation( host_positions.begin(), host_positions.end(), RG );
650  for( std::vector< core::Size >::const_iterator host_pos_it = host_positions.begin(); host_pos_it!=host_positions.end(); ++host_pos_it) {
651  using namespace core::conformation;
652  core::Size const res( *host_pos_it );
653  Residue const res_host( pose.residue( res ) );
654  Residue const res_stub( *stub->residue() );
655 
656  // Obligatory Triaging
657  if( res_host.aa() != chemical::aa_ala ) continue; // position already designed
658  if( res_host.aa() == chemical::aa_gly
659  || ( res_host.aa() == chemical::aa_pro && !basic::options::option[basic::options::OptionKeys::hotspot::allow_proline] )
660  || res_host.type().name() == "CYD" )
661  continue; // disallowed host amino acids
662  if( !prevent_repacking().empty()
663  && std::find( prevent_repacking().begin(), prevent_repacking().end(), res ) != prevent_repacking().end() )
664  continue; //not allowed to repack
665  if( !disallowed_host_pos_.empty()
666  && std::find( disallowed_host_pos_.begin(), disallowed_host_pos_.end(), res ) != disallowed_host_pos_.end() )
667  continue; //not allowed to be a stub
668 
669  core::Real const distance( res_host.xyz( "CB" ).distance( res_stub.xyz( "CB" ) ) );
670 
671  // Optional Triaging of residues too far away
672  if( triage_positions_ ) {
673  // triage based on distance
674  if( distance >= max_cb_cb_dist_ ) continue; // too far to be productive
675  core::Real dummy1, dummy2;
676  if( !test_res_res_aln( res_host, *stub->residue(), dummy1, dummy2 ) ){
677  TR_debug<<"stub failed placement due to alignment"<<std::endl;
678  continue; // stub not aligned properly to position
679  }
680  }
681  // End Triaging
682 
683  TR << "Trying host position " << res << std::endl;
684 
686  res, soft_rep, core::scoring::fa_rep, 20.0 );
687  stub_set_->filter( rep_filter );
688  stub->set_filter( rep_filter );
689  bool const self_energy_pass( stub->get_scaffold_status( res ) );
690  if( self_energy_pass ){
691 
692  // the following two lines make sure that t//he pose is at the
693  // starting line before each stub placement. These lines belong
694  // wherever the pose first changes after minimization.
695  pose=saved_pose; // to make sure that we've come back to the beginning
696  cst_cleanup( pose );
697 
698  ++count_two_sided;
699  place_stub( pose, res_stub, res );
700  { // build ala pose scope
701  BuildAlaPose toAla( host_chain_ == 1/*partner1*/, host_chain_ == 2 /*partner2*/ );
703 
704  if( !prevent_repacking().empty() )
705  no_repack = prevent_repacking();
706 
707  for( utility::vector1< std::pair< core::Size, bool > >::const_iterator
708  it=placed_stubs_.begin(), end=placed_stubs_.end();
709  it!=end; ++it ) {
710  no_repack.push_back( it->first );
711  }
712  //place_stub should have inserted the stub into placed_stubs
713  assert( std::find(no_repack.begin(), no_repack.end(), res) != no_repack.end() );
714 
715  std::sort( no_repack.begin(), no_repack.end() );
716  std::unique( no_repack.begin(), no_repack.end() );
717  toAla.prevent_repacking( no_repack );
718 
719  TR<<"switching interface to alanine\n";
720  toAla.apply( pose );
721  }
722 
723  stats_TR << "Stub of energy "<<stub->bonus_value()
724  <<" and type "<<pose.residue( res ).name3()
725  <<" placed on residue "<<res
726  <<". The distance between stub's Cb and the residue's is "
727  <<distance<<"A. Passing rep filter"<<std::endl;
728 
729  { // minimize around hs
730  // this will minimize the rb orientation (+ the stub's sc) with a bb constraint based solely on the relevant stub
731  core::Size const before_min( pose.constraint_set()->get_all_constraints().size() );
732  StubMinimize( pose, stub, res, hurry_ );
733  core::Size const after_min( pose.constraint_set()->get_all_constraints().size() );
734  TR_debug <<"DEBUG: before minimize around hs we had "<<before_min<<" constraints. after: "<<after_min<<std::endl;
735  Residue const res_host_after_min( pose.residue( res ) );
736  core::Real const dist_after_min_threshold( 2.0 );
737  core::Real const distance_after_min( res_host_after_min.xyz( "CB" ).distance( res_stub.xyz( "CB" ) ) );
738  stats_TR<<"stub - host residue Cb distance after stub-based minimization is "<<distance_after_min<<std::endl;
739  if( distance_after_min >= dist_after_min_threshold ){
740  stats_TR<<"Distance too large. failing stub\n";
741  pose = saved_pose;
742  cst_cleanup( pose );
743  continue;
744  }
745  /// modify after-placement filter to contain the stub's residue information
746  protocols::filters::FilterOP modified_after_placement_filter( after_placement_filter_->clone() );
747  protocols::moves::modify_ResId_based_object( modified_after_placement_filter, res );
748  bool const pass_after_placement( modified_after_placement_filter->apply( pose ) );
749  if( pass_after_placement )
750  stats_TR<<"Passed after placement filter"<<std::endl;
751  else{
752  stats_TR<<"failed after placement filter"<<std::endl;
753  pose = saved_pose;
754  cst_cleanup( pose );
755  continue;
756  }
757  }//end minimization scope
758  kinematics::FoldTree const stub_ft( pose.fold_tree() );
759  core::Size const before_remove( pose.constraint_set()->get_all_constraints().size() );
760 // remove_coordinate_constraints_from_pose( pose );
761  core::Size const after_remove( pose.constraint_set()->get_all_constraints().size() );
762  TR_debug <<"DEBUG: before remove coord constraints we had "<<before_remove<<" constraints. after: "<<after_remove<<std::endl;
763 
764  // this is to make sure that nothing awful has happened during stub-based minimization.
766  bool const interface_energy_pass( total_energy_filter->apply( pose ) );
767  if( interface_energy_pass ){
768  //If a subsequent placement fails, try placing the stub on another position or
769  //iterate over more stubs
770  bool subsequent_stub_placement_failure( false );
771  TR<<"redesigning remainder of interface with user defined design movers\n";
772  prevent_repacking_.push_back( res );
773  if( residue_numbers_ ){
774  TR<<"Pushing residue number "<<res<<" to residue_numbers_ object"<<std::endl;
775  residue_numbers_->obj.clear();
776  residue_numbers_->obj.push_back( res ); // in principle should push the number to the stack, but that keeps memory of past placements. Need to find a better way to deal with that.
777  }
779  runtime_assert( coord_cst_std_.size() == design_movers_.size() );
781  for( utility::vector1< DesignMoverFoldTreePair >::iterator it=design_movers_.begin(); it!=design_movers_.end() && !subsequent_stub_placement_failure; ++it ){
782  TR<<"applying design mover "<<it->first->get_name()<<'\n';
783  bool const use_constraints( it->second );
784  if( use_constraints ){
785  TR<<"using coordinate constraints with sdev "<<*it_sdev<<'\n';
786  core::Size const before_refresh( pose.constraint_set()->get_all_constraints().size() );
787  refresh_coordinate_constraints( pose, *it_sdev );
788  core::Size const after_refresh( pose.constraint_set()->get_all_constraints().size() );
789  TR_debug<<"before refreshing coord cst "<<before_refresh<<" constraints. after: "<<after_refresh<<std::endl;
790  }//use constraints
791  else
792  TR<<"no constraints applied\n";
793  core::Size const before_apply_design_mover( pose.constraint_set()->get_all_constraints().size() );
794  it->first->prevent_repacking( prevent_repacking() );
795  it->first->optimize_foldtree( false );
796  if( it->first->get_name() == "PlaceStub" ){ //special treatment to place stub movers
797  // We want the child place stub movers to contain all the information
798  // obtained up to now, including, which residues harbour stubs, where
799  // repacking is disallowed, the ft and what were the native sidechains. In some
800  // cases, we might want the child placestub movers to remain pristine, so
801  // we modify and apply clones of these movers.
802  movers::PlaceStubMoverOP modified_place_stub( dynamic_cast< PlaceStubMover *>( it->first->clone().get() ) );
803  runtime_assert( modified_place_stub );
804  modified_place_stub->placed_stubs_ = placed_stubs_;
806  for( utility::vector1< std::pair< core::Size, bool > >::const_iterator it=placed_stubs_.begin(), end=placed_stubs_.end(); it!=end; ++it )
807  new_prev_repack.push_back( it->first );
808 
809  modified_place_stub->prevent_repacking( new_prev_repack );
810  modified_place_stub->default_fold_tree_ = default_fold_tree_;
811  modified_place_stub->previous_coordinate_constraints_ = curr_coordinate_constraints_;
812  modified_place_stub->coord_cst_func_ = coord_cst_func_;
813  modified_place_stub->apply( pose );
814  if( modified_place_stub->get_last_move_status() == protocols::moves::FAIL_RETRY ){
815  stats_TR<<"Subsequent stub placement failed. Trying another stub placement"<<std::endl;
816  subsequent_stub_placement_failure = true;
817  break;
818  }
819  } //a place stub mover
820  else{ // other design movers
821  TR_debug<<"setting coordinate constraint weights to 1.0 in design movers"<<std::endl;
822  core::scoring::ScoreFunctionOP scorefxn_rep( it->first->scorefxn_repack() );
823  core::scoring::ScoreFunctionOP scorefxn_min( it->first->scorefxn_minimize() );
824  core::Real const coord_cst_weight( use_constraints ? 1 : 0 );
825  if( scorefxn_rep ) scorefxn_rep->set_weight( coordinate_constraint, coord_cst_weight );
826  if( scorefxn_min ) scorefxn_min->set_weight( coordinate_constraint, coord_cst_weight );
827  it->first->apply( pose );
828  }
829  ++it_sdev;
830  core::Size const after_apply_design_mover( pose.constraint_set()->get_all_constraints().size() );
831  TR_debug<<"before applying design mover "<<before_apply_design_mover<<" constraints. After: "<<after_apply_design_mover<<std::endl;
832  if( before_apply_design_mover != after_apply_design_mover ){
833  TR<<"ERROR: This design mover changed the number of constraints on the pose. Before: "<< before_apply_design_mover<<" after: "<<after_apply_design_mover<<". This behaviour is unsupported."<<std::endl;
834  runtime_assert( before_apply_design_mover != after_apply_design_mover );
835  }
836 // TR<<"removing coordinate constraints\n";
837 // remove_coordinate_constraints_from_pose( pose );
838  }//Design movers
839  if( subsequent_stub_placement_failure ){
840  cst_cleanup( pose );
841  break;
842  }
843  core::Size const before_final_filter( pose.constraint_set()->get_all_constraints().size() );
844  TR_debug<<"before final filter "<<before_final_filter<<" constraints"<<std::endl;
845  /// modify final filter to contain the stub's residue information
846  protocols::filters::FilterOP modified_final_filter( final_filter_->clone() );
847  protocols::moves::modify_ResId_based_object( modified_final_filter, res );
848  bool const final_filter_pass( modified_final_filter->apply( pose ) );
849  if( final_filter_pass ) {
850  stats_TR<<"SUCCESS: Stub passed final filter and placed at position "<<res<<". after "<<count_two_sided<<" two sided evaluations."<< std::endl;
852  TR_debug<<"Adding taskawareness to taskaware design movers\n";
853  core::Size const size_before_adding( residue_level_tasks_for_placed_hotspots_->size() );
854  for( utility::vector1< std::pair< core::Size, bool > >::const_iterator placed_stub( placed_stubs_.begin()); placed_stub!=placed_stubs_.end(); ++placed_stub ){
855  using namespace core::pack::task::operation;
857  pr->include_residue( placed_stub->first );
859  }//for placed_stubs_
860  core::Size const size_after_adding( residue_level_tasks_for_placed_hotspots_->size() );
861  TR_debug<<"Before adding we had "<<size_before_adding<<" task operations. Now we have "<<size_after_adding<<std::endl;
862  }//fi residue_level_tasks
864  final_cleanup( pose );
865  core::Size const after_success( pose.constraint_set()->get_all_constraints().size() );
866  TR_debug<<"after success "<<after_success<<" constraints"<<std::endl;
867  TR.flush();
868 
869  // Experimental: add residue position of successful stub placement to the score.sc file
871  //std::string column_header = this->get_user_defined_name();
872 
873  //convert residue number into a string
874  std::ostringstream convert;
875  convert << res;
876 
877  // set column name
878  //std::string column_header = "hotspot_" + convert.str();
879  std::string column_header = user_defined_name_;
880 
881  //job->add_string_real_pair(column_header, res);
882  job->add_string_string_pair(column_header, convert.str());
883 
884  return;
885  }//final_filter_pass
886  else{
887  pose = saved_pose;
888  cst_cleanup( pose );
889  stats_TR<<"Stub at position "<<res<<" failed final filter"<<std::endl;
890  }
891  }//interface energy filter
892  else
893  stats_TR<<"Stub at position "<<res<<" failed interface energy filter"<<std::endl;
894  }//self_energy pass
895  else
896  stats_TR<<"Stub failed self-energy filter"<<std::endl;
897  pose = saved_pose; // revert to beginning
898  cst_cleanup( pose );
899  TR.flush();
900  } //loop over host chain residues
901  } while( count_two_sided <= stub_set_->size() ); // this condition will never be violated here b/c SelectStubIteratively above has the same condition. Nevertheless, better have this check to ensure we don't launch an infinite loop
902  stats_TR<<"Stub placement failed after "<<count_two_sided<<" two-sided_trials."<<std::endl;
903  TR.flush();
904  pose = saved_pose;
905  final_cleanup( pose );
907 }
908 
912 }
913 
914 /// @details reapply saved coord constraints and refresh placed_stubs and prevent_repacking
915 /// Nov09 changed logic: curr_coordinate constraints are removed only
916 void
918 {
919  core::Size const crd_cst_size( curr_coordinate_constraints_.size() );
920  if( crd_cst_size > 0 ){
921  TR<<"removed "<<crd_cst_size<<" coordinate constraints"<<std::endl;
923 // remove_coordinate_constraints_from_pose( pose );
925 // previous_coordinate_constraints_ = pose.add_constraints( previous_coordinate_constraints_ );
926  }
930 }
931 
932 /// @details This should be called before exiting placestub.
933 void
935 {
938  runtime_assert( post_placement_sdev_ >= 0.0 );
939  TR<<"Cleaning up after successful stubplacement, but NOT removing coordinate constraints\n";
941  }
942  else
943  cst_cleanup( pose );
944  if( !saved_bb_constraints_.empty() ){
945  core::Size const bb_constraints_size( saved_bb_constraints_.size() );
946  if( bb_constraints_size > 0 ){
948  TR<<"reapplied "<<bb_constraints_size<<" bb constraints to pose"<<std::endl;
949  }
950  }
951 
952  //don't accumulate state between ntrials
953  placed_stubs_.clear();
954  prevent_repacking_.clear();
955  restrict_to_repacking_.clear();
958 // commenting out fold tree reseting b/c downstream movers would want to use it
959 // pose.fold_tree( *default_fold_tree_ );//this is important for allowing further centroid-based moves/filters on the pose
960 }
961 
962 /// @details changes the pose's fold-tree to connect
963 /// the nearest residue on the target to the stub on the scaffold. The foldtree connects the last carbon atom before the
964 /// stub's functional group. That can be useful in minimization of the pose, b/c the stub's interaction with the target will
965 /// not be lost due to minimization. Notice that the pose's fold tree changes in the process and so it is usually a good idea to
966 /// save the old foldtree and reinstate it after minimization.
967 /// Can work with multiple stubs. In that case, rb jumps are introduced between the target and each of the stubs
968 /// and a cutpoint is introduced in the putative circle that has just been formed in the fold tree.
969 /// Alternatively, if the current stub is to be added via a constraint, then a coordinate
970 /// constraint is set up for this stub
971 void
973 {
974 // protocols::loops::remove_cutpoint_variants( pose, true/*force*/ );
975 // core::Size const before_removing_coord_cst( pose.constraint_set()->get_all_constraints().size() );
976 // remove_coordinate_constraints_from_pose( pose );
977 // core::Size const after_removing_coord_cst( pose.constraint_set()->get_all_constraints().size() );
978 // TR_debug<<"before removing coordinate cst "<<before_removing_coord_cst<<" constraints. after "<<after_removing_coord_cst<<std::endl;
979 
980 /// Add constraints pertaining to the last placed stub
981  core::Size const curr_stub_resnum( placed_stubs_[ placed_stubs_.size() ].first );
982  bool const add_constraints( placed_stubs_[ placed_stubs_.size() ].second );
983  if( add_constraints )
984  curr_coordinate_constraints_ = add_coordinate_constraints( pose, res_stub, host_chain_, curr_stub_resnum, cst_sdev, coord_cst_func_ );
985 /// Set atom tree according to the first placed stub.
987  core::Size const host_residue_num( placed_stubs_.begin()->first );
988  pose.fold_tree( *sat.create_atom_tree( pose, host_chain_, host_residue_num ) );
989  TR<<"Stub based atom tree: "<<pose.fold_tree()<<std::endl;
990 }
991 
992 void
994  DataMap & data,
995  protocols::filters::Filters_map const &filters,
996  Movers_map const &movers,
997  core::pose::Pose const & pose )
998 {
999  using namespace protocols::hotspot_hashing;
1000 
1001  TR<<"Parsing PlaceStubMover----"<<std::endl;
1002 
1003  if( tag->hasOption( "name" ) ){
1004  // Experimental
1005  user_defined_name_ = tag->getOption< std::string >( "name" );
1006  }
1007 
1008  if( tag->hasOption( "residue_numbers_setter" ) ){
1009  std::string const residue_numbers_name( tag->getOption( "residue_numbers", tag->getOption< std::string >( "residue_numbers_setter" ) ) );
1010  residue_numbers_ = protocols::moves::get_set_from_datamap< protocols::moves::DataMapObj< utility::vector1< core::Size > > >( "residue_numbers", residue_numbers_name, data );
1011  }
1012 
1013  if( tag->hasOption( "task_operations" ) ){
1014  if( task_factory() )
1015  TR<<"*****WARNING: ERASING existing task_factory, b/c of specifications for new task operations in\n"<<tag<<std::endl;
1017  }
1018  host_chain_ = tag->getOption<core::Size>( "chain_to_design", 2 );
1019  score_threshold_ = tag->getOption<core::Real>( "score_threshold", 0 );
1020  hurry_ = tag->getOption<bool>( "hurry", 0 );
1021  triage_positions_ = tag-> getOption<bool>( "triage_positions", 1 );
1022  stub_energy_threshold_ = tag-> getOption<core::Real>( "stub_energy_threshold", 1.0 );
1023 
1024  if( tag->hasOption( "stubfile" ) ) { //assigning a unique stubset
1025  std::string const stub_fname = tag->getOption<std::string>( "stubfile" ); // Experimental: stub file name
1027  if( data.has( "hotspot_library", stub_fname ) ){
1028  stub_set_ = data.get< protocols::hotspot_hashing::HotspotStubSet * >( "hotspot_library", stub_fname );
1029  TR<<"Associated mover with an already read stubset named "<<stub_fname<<std::endl;
1030  }
1031  else
1032  stub_set_->read_data( stub_fname );
1033  }
1034  else { //assigning the stubset taken from the constraints setup
1035  std::string const hs( "hotspot_stubset" );
1036  stub_set_ = data.get< HotspotStubSet * >( "constraints", hs );
1037  }
1038 
1039  bool const minimize_rb( tag->getOption< bool >( "minimize_rb", 0 ) );
1040  min_rb( minimize_rb );
1041 
1042  std::string const after_placement_filter_name( tag->getOption<std::string>( "after_placement_filter", "true_filter" ) );
1043  protocols::filters::Filters_map::const_iterator find_ap_filter( filters.find( after_placement_filter_name ));
1044 
1045  bool const ap_filter_found( find_ap_filter != filters.end() );
1046  if( ap_filter_found )
1047  after_placement_filter_ = find_ap_filter->second->clone();
1048  else {
1049  if( after_placement_filter_name != "true_filter" ){
1050  TR<<"***WARNING WARNING! Filter defined for PlaceStubMover not found in filter_list!!!! Defaulting to truefilter***"<<std::endl;
1051  runtime_assert( ap_filter_found );
1052  }
1053  else
1055  }
1056 
1057  std::string const final_filter_name( tag->getOption<std::string>( "final_filter", "true_filter" ) );
1058  protocols::filters::Filters_map::const_iterator find_filter( filters.find( final_filter_name ));
1059 
1060  bool const filter_found( find_filter != filters.end() );
1061  if( filter_found )
1062  final_filter_ = find_filter->second->clone();
1063  else {
1064  if( final_filter_name != "true_filter" ){
1065  TR<<"***WARNING WARNING! Filter defined for PlaceStubMover not found in filter_list!!!! Defaulting to truefilter***"<<std::endl;
1066  runtime_assert( filter_found );
1067  }
1068  else
1070  }
1071 
1072  //parse allowed residues
1073  disallowed_host_pos_.clear();
1074  if( tag->hasOption("allowed_host_res") ) {
1075  utility::vector1<Size> allowed_host_pos(
1077  tag, "allowed_host_res", pose ));
1078  //disallowed is the set complement of allowed
1079 
1080  core::Size const host_chain_begin( pose.conformation().chain_begin( host_chain_ ));
1081  core::Size const host_chain_end( pose.conformation().chain_end( host_chain_ ));
1082 
1083  for(Size host_pos( host_chain_begin); host_pos <= host_chain_end; ++host_pos )
1084  {
1085  if( std::find( allowed_host_pos.begin(), allowed_host_pos.end(), host_pos)
1086  == allowed_host_pos.end() )
1087  {
1088  // not allowed
1089  disallowed_host_pos_.push_back(host_pos);
1090  }
1091  }
1092  TR.Debug<<"Disallowing "<<disallowed_host_pos_.size()
1093  <<" of "<<host_chain_end - host_chain_begin + 1
1094  <<" host positions."<<std::endl;
1095  }
1096 
1097  //parsing stub minimize movers and design movers for place stub
1098  utility::vector0< TagPtr > const branch_tags( tag->getTags() );
1099  for( utility::vector0< TagPtr >::const_iterator btag=branch_tags.begin(); btag!=branch_tags.end(); ++btag ) {
1100  if( (*btag)->getName() == "StubMinimize" ){
1101  utility::vector0< TagPtr > const stub_min_tags( (*btag)->getTags() );
1102  for( utility::vector0< TagPtr >::const_iterator stub_m_tag=stub_min_tags.begin(); stub_m_tag!=stub_min_tags.end(); ++stub_m_tag ) {
1103  std::string const stub_mover_name( (*stub_m_tag)->getOption<std::string>( "mover_name" ) );
1104  core::Real const bb_stub_constraint_weight( (*stub_m_tag)->getOption< core::Real > ( "bb_cst_weight", 10.0 ) );
1105  std::map< std::string const, MoverOP >::const_iterator find_mover( movers.find( stub_mover_name ));
1106  bool const stub_mover_found( find_mover != movers.end() );
1107  if( stub_mover_found ){
1108  simple_moves::DesignRepackMoverOP drSOP = dynamic_cast< simple_moves::DesignRepackMover * >( find_mover->second->clone().get() );
1109  if( !drSOP ){
1110  TR<<"dynamic cast failed in tag "<<tag<<". Make sure that the mover is derived from DesignRepackMover"<<std::endl;
1111  runtime_assert( drSOP );
1112  }//done cast check
1113  stub_minimize_movers_.push_back( std::make_pair( drSOP, bb_stub_constraint_weight) );
1114  TR<<"added stub minimize mover "<<stub_mover_name<<" to minimize towards the stub. Using this weight for the bb stub constraints: "<< bb_stub_constraint_weight<<'\n';
1115  }
1116  }
1117  }
1118  else if( (*btag)->getName() == "DesignMovers" ){
1119  utility::vector0< TagPtr > const design_tags( (*btag)->getTags() );
1120  for( utility::vector0< TagPtr >::const_iterator m_it=design_tags.begin(); m_it!=design_tags.end(); ++m_it ) {
1121  TagPtr const m_tag_ptr = *m_it;
1122  std::string const mover_name( m_tag_ptr->getOption< std::string >( "mover_name" ) );
1123  bool const apply_coord_constraints( m_tag_ptr->getOption< bool >( "use_constraints", 1 ) );
1124  core::Real const coord_cst_std( m_tag_ptr->getOption< core::Real >( "coord_cst_std", 0.5 ) );
1125 
1126  std::map< std::string const, MoverOP >::const_iterator find_mover( movers.find( mover_name ));
1127  bool const mover_found( find_mover != movers.end() );
1128  if( mover_found ){
1129  simple_moves::DesignRepackMoverOP drOP = dynamic_cast< simple_moves::DesignRepackMover * >( find_mover->second->clone().get() );
1130  if( !drOP ){
1131  TR<<"dynamic cast failed in tag "<<tag<<". Make sure that the mover is derived from DesignRepackMover"<<std::endl;
1132  runtime_assert( drOP );
1133  }
1134  design_movers_.push_back( std::make_pair( drOP, apply_coord_constraints ) );
1135  coord_cst_std_.push_back( coord_cst_std );
1136  TR<<"added design mover "<<mover_name<<" to place stub with apply_coord_constraints switched to "<< apply_coord_constraints<<" with std "<< coord_cst_std<< " and hurry=" << hurry_ << '\n';
1137  }
1138  else{
1139  TR<<"***WARNING WARNING! Mover defined for PlaceStubMover not found in mover_list. EXITING ***"<<std::endl;
1140  runtime_assert( mover_found );
1141  }
1142  }
1143  }
1144  else if( (*btag)->getName() != "NotifyMovers" )
1145  utility_exit_with_message( "ERROR: tag in PlaceStub not defined\n" );
1147  }
1148  if( stub_minimize_movers_.size() == 0 )
1149  TR<<"No StubMinimize movers defined by user, defaulting to minimize_rb and _sc of stubs only\n";
1150 
1151  add_constraints_ = tag->getOption< bool >( "add_constraints", 1 );
1152 
1153 
1154  { // pair stubset with an ala_pose scope
1155  //we want the stubset to be aware of the host chain. This way, when we
1156  //ask a stub set whether a stub can be placed on a particular position
1157  //in terms of its self-energy, it can cache this information and return
1158  //it to us at a later point if we ask for that stub again. Since we
1159  //expect the host_chain to be redesignable, we switch all residues
1160  //(other than gly/pro) to ala before pairing.
1161  core::pose::PoseOP ala_pose = new core::pose::Pose( pose );
1162  pack::task::PackerTaskOP task( pack::task::TaskFactory::create_packer_task( *ala_pose ));
1163  task->initialize_from_command_line().or_include_current( true );
1164 
1166  allowed_aas[ chemical::aa_ala ] = true;
1167 
1168  core::Size const chain_begin( ala_pose->conformation().chain_begin( host_chain_ ) );
1169  core::Size const chain_end( ala_pose->conformation().chain_end( host_chain_ ) );
1170 
1171  for ( core::Size i = 1; i <= pose.total_residue(); i++) {
1172  if ( !pose.residue(i).is_protein() ) continue;
1173  if( i >= chain_begin && i <=chain_end ) {
1174  core::Size const restype( ala_pose->residue(i).aa() );
1175  if( (restype == chemical::aa_pro && !basic::options::option[basic::options::OptionKeys::hotspot::allow_proline] ) || restype == chemical::aa_gly )
1176  task->nonconst_residue_task(i).prevent_repacking();
1177  else
1178  task->nonconst_residue_task(i).restrict_absent_canonical_aas( allowed_aas );
1179  }
1180  else {
1181  task->nonconst_residue_task( i ).prevent_repacking();
1182  }
1183  }
1184  if( basic::options::option[basic::options::OptionKeys::packing::resfile].user() )
1185  core::pack::task::parse_resfile(pose, *task);
1186 
1188  pack::pack_rotamers( *ala_pose, *scorefxn, task);
1189  (*scorefxn)( *ala_pose );
1190  stub_set_->pair_with_scaffold( *ala_pose, host_chain_, new protocols::filters::TrueFilter );
1191  }// pair stubset scope
1192 
1193  max_cb_cb_dist_ = tag->getOption< core::Real >( "max_cb_dist", 4.0 );
1194  leave_coord_csts_after_placement_ = tag->getOption< bool >( "leave_coord_csts", 0 );
1196  post_placement_sdev_ = tag->getOption< core::Real >("post_placement_sdev", 1.0 );
1197  TR<<"leaving constraints on after successful placement\n";
1198  }
1199  else
1200  post_placement_sdev_ = -1.0; // this will assert later on
1201  TR<<"max cb cb distance set to "<<max_cb_cb_dist_<<'\n';
1202  place_scaffold_ = tag->getOption< bool >( "place_scaffold", 0 );
1203  TR<<"place stub mover on chain "<<host_chain_<<" with score threshold of "<<score_threshold_<<" minimize_rb to "<<minimize_rb<<" final filter "<<final_filter_name<<" and place scaffold="<<place_scaffold_<<std::endl;
1204 }
1205 
1206 } //movers
1207 } //protein_interface_design
1208 } //protocols
1209