Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PlaceUtils.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/PlaceUtils.cc
11 /// @brief a collection of utility functions for placement classes
12 /// @author Sarel Fleishman (sarelf@u.washington.edu)
14 
15 // Project Headers
16 #include <core/types.hh>
17 #include <core/pose/Pose.hh>
20 #include <core/id/AtomID.hh>
21 #include <core/chemical/AA.hh>
22 #include <numeric/xyzVector.hh>
24 
25 
30 //#include <core/pack/rotamer_trials.hh>
31 
36 
37 //#include <protocols/docking/DockingProtocol.hh>
38 #include <protocols/moves/Mover.hh>
40 //#include <protocols/moves/ResidueMover.hh>
42 #include <protocols/hotspot_hashing/HotspotStub.fwd.hh> // REQUIRED FOR WINDOWS
46 #include <utility/tag/Tag.hh>
47 #include <boost/foreach.hpp>
48 #define foreach BOOST_FOREACH
49 // Utility Headers
50 #include <utility/exit.hh>
51 
52 // Unit Headers
55 
56 #include <basic/options/option.hh>
57 #include <basic/options/keys/packing.OptionKeys.gen.hh>
58 #include <basic/options/keys/hotspot.OptionKeys.gen.hh>
59 #include <utility/vector1.hh>
60 
61 #include <basic/Tracer.hh>
62 
63 // C++ headers
64 #include <map>
65 #include <algorithm>
66 
67 #include <utility/vector0.hh>
68 
69 //Auto Headers
71 
72 
73 
74 using namespace core::scoring;
75 
76 static basic::Tracer TR( "protocols.protein_interface_design.movers.PlaceUtils" );
77 
78 namespace protocols {
79 namespace protein_interface_design {
80 namespace movers {
81 
82 using namespace protocols::moves;
83 using namespace core;
84 
85 /// @details a utility function that tests whether two residues are aligned properly.
86 /// Useful for testing whether a single stub should be placed at a given scaffold position
87 bool
88 test_res_res_aln( core::conformation::Residue const & res1, core::conformation::Residue const & res2, core::Real & C_N_angle, core::Real & CB_CA_angle )
89 {
90  using namespace numeric;
91 
92  core::Real const threshold( 0.5 );//what angular threshold to use in accepting a stub. 0 implies 90o, 0.5 implies 60o
93 
94  Vector const res1_CA = res1.xyz( "CA" );
95  Vector const res1_CB = res1.xyz( "CB" );
96  Vector const res1_N = res1.xyz( "N" );
97  Vector const res1_C = res1.xyz( "C" );
98 
99  Vector const res2_CA = res2.xyz( "CA" );
100  Vector const res2_CB = res2.xyz( "CB" );
101  Vector const res2_N = res2.xyz( "N" );
102  Vector const res2_C = res2.xyz( "C" );
103 
104  Vector const res1_CB_CA = (res1_CB - res1_CA);
105  Vector const res1_C_N = (res1_C - res1_N);
106 
107  Vector const res2_CB_CA = (res2_CB - res2_CA);
108  Vector const res2_C_N = (res2_C - res2_N);
109 
110  C_N_angle = angle_of( res2_C_N, res1_C_N );
111  CB_CA_angle = angle_of( res2_CB_CA, res1_CB_CA );
112 
113  if( cos_of( res1_C_N, res2_C_N ) <= threshold ||
114  cos_of( res1_CB_CA, res2_CB_CA ) <= threshold )
115  return( false );
116  return( true );
117 }
118 
121 {
122  using namespace core::scoring::constraints;
123 
124  ConstraintCOPs cst;
125 
126 
127  { // defining constraints scope
128  using namespace core::conformation;
129  using namespace core::chemical;
130 
131  ResidueType const & rsd_type( rsd_i.type() );
132  AA const aa = rsd_i.aa();
133  switch ( aa ){
134  using namespace core::id;
135  case( aa_phe ) :
136  case( aa_trp ) :
137  case( aa_tyr ) :
138  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CG" ), resnum ), anchor_atom, rsd_i.xyz( "CG" ),coord_cst_func));
139  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CD1" ), resnum ), anchor_atom, rsd_i.xyz( "CD1" ),coord_cst_func ));
140  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CD2" ), resnum ), anchor_atom, rsd_i.xyz( "CD2" ),coord_cst_func ));
141  break;
142  case( aa_gln ) :
143  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CD" ), resnum ), anchor_atom, rsd_i.xyz( "CD" ),coord_cst_func ));
144  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "OE1" ), resnum ), anchor_atom, rsd_i.xyz( "OE1" ),coord_cst_func ));
145  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "NE2" ), resnum ), anchor_atom, rsd_i.xyz( "NE2" ),coord_cst_func ));
146  break;
147  case( aa_glu ) :
148  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CD" ), resnum ), anchor_atom, rsd_i.xyz( "CD" ),coord_cst_func ) );
149  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "OE1" ), resnum ), anchor_atom, rsd_i.xyz( "OE1" ),coord_cst_func ) );
150  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "OE2" ), resnum ), anchor_atom, rsd_i.xyz( "OE2" ),coord_cst_func ) );
151  break;
152  case( aa_arg ) :
153  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "NH1" ), resnum ), anchor_atom, rsd_i.xyz( "NH1" ),coord_cst_func ) );
154  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "NE" ), resnum ), anchor_atom, rsd_i.xyz( "NE" ),coord_cst_func ) );
155  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "NH2" ), resnum ) , anchor_atom, rsd_i.xyz( "NH2" ),coord_cst_func ) );
156  break;
157  case( aa_lys ) :
158  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "NZ" ), resnum ), anchor_atom, rsd_i.xyz( "NZ" ),coord_cst_func ) );
159  break;
160  case( aa_asn ) :
161  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CG" ), resnum ), anchor_atom, rsd_i.xyz( "CG" ),coord_cst_func ) );
162  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "OD1" ), resnum ), anchor_atom, rsd_i.xyz( "OD1" ),coord_cst_func ) );
163  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "ND2" ), resnum ), anchor_atom, rsd_i.xyz( "ND2" ),coord_cst_func ) );
164  break;
165  case( aa_his ) :
166  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CG" ), resnum ), anchor_atom, rsd_i.xyz( "CG" ),coord_cst_func ));
167  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "ND1" ), resnum ) , anchor_atom, rsd_i.xyz( "ND1" ),coord_cst_func ) );
168  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "NE2" ), resnum ), anchor_atom, rsd_i.xyz( "NE2" ),coord_cst_func ) );
169  break;
170  case( aa_asp ) :
171  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CG" ), resnum ), anchor_atom, rsd_i.xyz( "CG" ),coord_cst_func ) );
172  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "OD1" ), resnum ), anchor_atom, rsd_i.xyz( "OD1" ),coord_cst_func ) );
173  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "OD2" ), resnum ), anchor_atom, rsd_i.xyz( "OD2" ),coord_cst_func ) );
174  break;
175  case( aa_met ) :
176  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "SD" ), resnum ), anchor_atom, rsd_i.xyz( "SD" ),coord_cst_func ) );
177  break;
178  case( aa_leu ):
179  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CG" ), resnum ), anchor_atom, rsd_i.xyz( "CG" ), coord_cst_func ) );
180  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CD1" ), resnum ), anchor_atom, rsd_i.xyz( "CD1" ), coord_cst_func ) );
181  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CD2" ), resnum ), anchor_atom, rsd_i.xyz( "CD2" ), coord_cst_func ) );
182  break;
183  case( aa_ile ):
184  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CG1" ), resnum ), anchor_atom, rsd_i.xyz( "CG1" ), coord_cst_func ) );
185  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CD1" ), resnum ), anchor_atom, rsd_i.xyz( "CD1" ), coord_cst_func ) );
186  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CG2" ), resnum ), anchor_atom, rsd_i.xyz( "CG2" ), coord_cst_func ) );
187  break;
188  case( aa_cys ):
189  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "SG" ), resnum ), anchor_atom, rsd_i.xyz( "SG" ), coord_cst_func ) );
190  // Preserve the CB, since the chi angle is important in disulfides
191  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CB" ), resnum ), anchor_atom, rsd_i.xyz( "CB" ), coord_cst_func ) );
192  break;
193  case( aa_thr ):
194  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CB" ), resnum ), anchor_atom, rsd_i.xyz( "CB" ), coord_cst_func ) );
195  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "OG1" ), resnum ), anchor_atom, rsd_i.xyz( "OG1" ), coord_cst_func ) );
196  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CG2" ), resnum ), anchor_atom, rsd_i.xyz( "CG2" ), coord_cst_func ) );
197  break;
198  case( aa_ala ):
199  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CB" ), resnum ), anchor_atom, rsd_i.xyz( "CB" ), coord_cst_func ) );
200  break;
201  case( aa_val ):
202  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CB" ), resnum ), anchor_atom, rsd_i.xyz( "CB" ), coord_cst_func ) );
203  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CG1" ), resnum ), anchor_atom, rsd_i.xyz( "CG1" ), coord_cst_func ) );
204  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "CG2" ), resnum ), anchor_atom, rsd_i.xyz( "CG2" ), coord_cst_func ) );
205  break;
206  case( aa_ser ):
207  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "HG" ), resnum ), anchor_atom, rsd_i.xyz( "HG" ), coord_cst_func ) );
208  cst.push_back( new CoordinateConstraint( AtomID( rsd_type.atom_index( "OG" ), resnum ), anchor_atom, rsd_i.xyz( "OG" ), coord_cst_func ) );
209  break;
210  default :
211  utility_exit_with_message( "ERROR: Residue not supported by Placement coordinate constraint machinery" );
212  }
213  }//defining constraints scope
214  TR<<"Constraining residue "<<pose.residue( resnum ).name()<<resnum<<std::endl;
215  cst = pose.add_constraints( cst );
216  return( cst );
217 }
218 
219 /// @details utility function for finding the nearest residue on a chain to
220 /// a given coordinate. Useful in finding the nearest residue on the host chain to
221 /// a coordinate constraint
224 {
225  core::Real min_dist( 1000000.0 );
226  core::Size nearest_res( 0 );
227  for( core::Size i( pose.conformation().chain_begin( host_chain ) ),
228  end( pose.conformation().chain_end ( host_chain ) );
229  i<=end; ++i ){
230  core::Real distance( pose.residue(i).xyz( pose.residue(i).nbr_atom() ).distance( coord ) );
231  if( distance <= min_dist ){
232  nearest_res = i;
233  min_dist = distance;
234  }
235  }
236  runtime_assert( nearest_res );
237  return( nearest_res );
238 }
239 
242 {
243  using namespace core::chemical;
244  AA const aa = residue.aa();
245  switch ( aa ){
246  using namespace core::id;
247  case( aa_phe ) :
248  case( aa_trp ) :
249  case( aa_asn ) :
250  case( aa_his ) :
251  case( aa_asp ) :
252  case( aa_leu ) :
253  case( aa_pro ) :
254  case( aa_tyr ) : return( "CG" );
255  case( aa_glu ) :
256  case( aa_gln ) : return( "CD" );
257  case( aa_arg ) : return( "NE" );
258  case( aa_lys ) : return( "NZ" );
259  case( aa_met ) : return( "SD" );
260  case( aa_ile ) : return( "CG1" );
261  case( aa_cys ) : return( "SG" );
262  case( aa_val ) :
263  case( aa_ala ) :
264  case( aa_thr ) : return( "CB" );
265  case( aa_ser ) : return( "HG" );
266  case( aa_gly ) : return( "CA" );
267  default :
268  utility_exit_with_message( "ERROR: Residue not supported by Placement coordinate constraint machinery" );
269  }
270  return("");
271 }
272 
274 add_coordinate_constraints( pose::Pose & pose, core::conformation::Residue const source, core::Size const host_chain, core::Size const resnum, core::Real const coord_sdev, core::scoring::constraints::HarmonicFuncOP & coord_cst_func )
275 {
276  using namespace core::scoring::constraints;
277 
278  ConstraintCOPs cst;
279 
280  core::Size const fixed_res( find_nearest_residue_to_coord( pose, source.xyz( nearest_atom_for_constraint( source ) ) ,host_chain == 2 ? 1 : 2 ));
281 // core::Size const fixed_res( host_chain == 1 ? pose.total_residue() : 1 );
282  TR<<"Anchor residue for the coordinate constraint is "<<fixed_res<<std::endl;
283  std::string atom_id( "CB" );
284  if( pose.residue( fixed_res ).aa() == core::chemical::aa_gly )
285  atom_id = "CA";
286  core::id::AtomID const anchor_atom( core::id::AtomID( pose.residue( fixed_res ).atom_index( atom_id ), fixed_res ) );
287 
288  if( !coord_cst_func ) coord_cst_func = new core::scoring::constraints::HarmonicFunc( 0.0, 0.0 );
289  coord_cst_func->sd( coord_sdev );
290  cst = add_coordinate_constraints( pose, resnum, source, coord_cst_func, anchor_atom );
291  return( cst );
292 }
293 
294 /// @details common function to both grafting protocols for parsing out the movers that need to be task aware. Returns an empty task factory. If the tag is labeled TaskAware, all of the DesignRepackMovers within it will be assigned
295 /// this task factory.
296 void
298  using namespace utility::tag;
299  using namespace core::pack::task;
300  if( !data.has( "TaskFactory", "placement" ) ){
301  task_factory = new core::pack::task::TaskFactory;
302  data.add( "TaskFactory", "placement", task_factory );
303  }
304  else
305  task_factory = data.get< TaskFactory * >( "TaskFactory", "placement" );
306  if( tag->getName() != "NotifyMovers" ) return;
307  utility::vector0< TagPtr > const ta_tags( tag->getTags() );
308  foreach( TagPtr const ta_tag, ta_tags ){
309  std::string const mover_name( ta_tag->getOption< std::string >( "mover_name" ) );
310  std::map< std::string const, MoverOP >::const_iterator find_mover( movers.find( mover_name ));
311  bool const mover_found( find_mover != movers.end() );
312  if( mover_found ){
313  simple_moves::DesignRepackMoverOP drOP = dynamic_cast< simple_moves::DesignRepackMover * >( find_mover->second.get() );
314  if( drOP ){// don't do anything with non-DesignRepackMovers
315  TR<<"Setting the task factory of mover "<<find_mover->first<<" to be aware of PlaceSimultaneously's rotamer and sidechain choices.\n";
316  drOP->task_factory( task_factory );
317  }//fi
318  }//fi mover-found
319  }// foreach ta_tag
320  TR.flush();
321 }
322 
323 /// @details utility function for setting up a scorefxn dominated by the stub constraints.
326  using namespace core::scoring;
327  ScoreFunctionOP stub_scorefxn = new ScoreFunction;
328  stub_scorefxn->reset();
329  stub_scorefxn->set_weight( backbone_stub_constraint, 10.0 );
330  stub_scorefxn->set_weight( fa_rep, 0.44 );
331  stub_scorefxn->set_weight( fa_dun, 0.56 );
332  stub_scorefxn->set_weight( coordinate_constraint, 1.0 );
333 
334  return( stub_scorefxn );
335 }
336 
339  using namespace utility::tag;
340  using namespace protocols::hotspot_hashing;
342 
343  stub_sets.clear();
344  bool contain_StubSet( false );
345  utility::vector0< utility::tag::TagPtr > const btags( tag->getTags() );
347  for( ; ss_tag != btags.end(); ++ss_tag ){
348  if( (*ss_tag)->getName() == "StubSets" ){
349  contain_StubSet = true;
350  break;
351  }
352  }//for stubset_tag
353  if( !contain_StubSet )
354  return stub_sets;
355  utility::vector0< utility::tag::TagPtr > const stubset_tags( (*ss_tag)->getTags() );
356  foreach( utility::tag::TagPtr const stubset_tag, stubset_tags ){
357  std::string const stub_fname = stubset_tag->getOption< std::string >( "stubfile" );
358  HotspotStubSetOP stubset = new HotspotStubSet;
359  if( data.has( "hotspot_library", stub_fname ) ){
360  stubset = data.get< protocols::hotspot_hashing::HotspotStubSet * >( "hotspot_library", stub_fname );
361  TR<<"Associated mover with an already read stubset named "<<stub_fname<<std::endl;
362  }
363  else{
364  TR<<"Associating mover with stub file "<<stub_fname<<std::endl;
365  stubset->read_data( stub_fname );
366  }
367  stub_sets.push_back(std::make_pair(stubset, std::make_pair(new HotspotStub(), 0))); // REQUIRED FOR WINDOWS
368  //stub_sets.push_back( PlaceSimultaneouslyMover::StubSetStubPos( stubset, std::pair< HotspotStubOP, core::Size >( 0, 0 ) ) );
369 
370  core::pose::PoseOP ala_pose = new core::pose::Pose( pose );
372  task->initialize_from_command_line().or_include_current( true );
373 
375  allowed_aas[ chemical::aa_ala ] = true;
376 
377  core::Size const chain_begin( ala_pose->conformation().chain_begin( host_chain ) );
378  core::Size const chain_end( ala_pose->conformation().chain_end( host_chain ) );
379 
380  for ( core::Size i = 1; i <= pose.total_residue(); i++) {
381  if ( !pose.residue(i).is_protein() ) continue;
382  if( i >= chain_begin && i <=chain_end ) {
383  core::Size const restype( ala_pose->residue(i).aa() );
384  if( ( restype == chemical::aa_pro && !basic::options::option[basic::options::OptionKeys::hotspot::allow_proline] )|| restype == chemical::aa_gly )
385  task->nonconst_residue_task(i).prevent_repacking();
386  else
387  task->nonconst_residue_task(i).restrict_absent_canonical_aas( allowed_aas );
388  }//fi
389  else {
390  task->nonconst_residue_task( i ).prevent_repacking();
391  }
392  }//for i
393  if( basic::options::option[basic::options::OptionKeys::packing::resfile].user() )
394  core::pack::task::parse_resfile(*ala_pose, *task);
395 
397  pack::pack_rotamers( *ala_pose, *scorefxn, task);
398  (*scorefxn)( *ala_pose );
399  stubset->pair_with_scaffold( *ala_pose, host_chain, new protocols::filters::TrueFilter );
400  }//foreach stubset_tag
401  return( stub_sets );
402 }
403 
404 
405 } //movers
406 } //protein_interface_design
407 } //protocols
408