Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
util.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file protocols/protein_interface_design/util.cc
11 /// @brief
12 /// @author Sarel Fleishman (sarelf@u.washington.edu), Jacob Corn (jecorn@u.washington.edu)
13 
14 // Unit Headers
16 
17 // Package Headers
18 
19 
20 // Project Headers
22 #include <core/types.hh>
23 #include <core/pose/Pose.hh>
24 // AUTO-REMOVED #include <core/pose/PDBPoseMap.hh>
25 // AUTO-REMOVED #include <core/pose/PDBInfo.hh>
30 // AUTO-REMOVED #include <core/scoring/constraints/XYZ_Func.hh>
31 #include <core/scoring/Energies.hh>
36 #include <boost/foreach.hpp>
37 #define foreach BOOST_FOREACH
38 // AUTO-REMOVED #include <core/pack/task/operation/TaskOperation.hh>
39 // AUTO-REMOVED #include <core/pack/task/TaskFactory.hh>
40 // AUTO-REMOVED #include <protocols/moves/DataMap.hh>
42 
44 #include <utility/vector0.hh>
45 #include <utility/vector1.hh>
46 #include <basic/Tracer.hh>
47 
48 //Auto Headers
50 
51 
52 static basic::Tracer TR( "protocols.protein_interface_design.util" );
53 
54 namespace protocols {
55 namespace protein_interface_design {
56 
57 using namespace core::scoring;
58 using namespace protocols::moves;
59 using namespace core;
60 using namespace std;
61 using utility::vector1;
62 
63 /// @brief generate a star fold tree (originating at residue 1)
66 {
67  kinematics::FoldTree linear_ft;
68  linear_ft.clear();
69  core::Size const chain_num( pose.conformation().num_chains() );
70  core::Size jump_num( 1 );
71  for( core::Size c=1; c<=chain_num; ++c ) {
72  core::Size const chain_begin( pose.conformation().chain_begin( c ) );
73  core::Size const chain_end( pose.conformation().chain_end( c ) );
74 
75  if( !pose.residue( chain_end ).is_polymer() ){ //ligand
76  linear_ft.add_edge( chain_end-1, chain_end, jump_num );
77  ++jump_num;
78  }
79  else{
80  linear_ft.add_edge( chain_begin, chain_end, kinematics::Edge::PEPTIDE );
81  if( c > 1 ){
82  linear_ft.add_edge( 1,chain_begin, jump_num );
83  ++jump_num;
84  }
85  }
86  }
87  linear_ft.reorder( 1 );
88  TR<<linear_ft<<std::endl;
89  pose.fold_tree( linear_ft );
91  return( linear_ft );
92 }
93 
94 // @details Connecting to the last carbon atom before the residue's action centre will allow // mimization to sample the residue's sidechain dofs without harming the interaction // the stub with the target chain
96 optimal_connection_point( std::string const residue_type ){
97  std::string connect_to( "CB" ); // to which atom to hook up the atom tree
98  if( residue_type == "GLN" || residue_type == "GLU" )
99  connect_to = "CD";
100  if( residue_type == "ARG" )
101  connect_to = "CZ";
102  if( residue_type == "MET" )
103  connect_to = "SD";
104  if( residue_type == "LEU" || residue_type == "PHE" || residue_type == "TRP" || residue_type == "TYR" || residue_type == "ASN" || residue_type == "ASP" )
105  connect_to = "CG";
106  if( residue_type == "LYS" )
107  connect_to = "NZ";
108  if( residue_type == "GLY" )
109  connect_to = "CA";
110 
111  return( connect_to );
112 }
113 
114 /// @details generate a fold tree that connects each hotspot residue through its optimal connection point to
115 /// the nearest atom on chain 1
118 {
119  using namespace core::chemical;
120  using namespace core::kinematics;
121  FoldTree ft;
122  ft.clear();
123 
124  utility::vector1< core::Size > connection_points;
125  for ( core::Size jump( 1 ); jump<=pose.num_jump(); ++jump ) {
126  core::Size const resi( pose.conformation().chain_begin( jump + 1) );
127  std::string const residue_type( pose.residue( resi ).name3() );
128  std::string const connect_to( optimal_connection_point( residue_type ) );
129  core::Size const nearest_resi_on_target( find_nearest_residue( pose, 1/*target_chain*/, resi, connect_to ) );
130  ft.add_edge( nearest_resi_on_target, resi, jump );
131  ft.set_jump_atoms( jump, pose.residue( nearest_resi_on_target ).atom_type( pose.residue( nearest_resi_on_target ).nbr_atom() ).element(), connect_to );
132  connection_points.push_back( nearest_resi_on_target );
133  }
134  std::sort( connection_points.begin(), connection_points.end() );
135  std::unique( connection_points.begin(), connection_points.end() );
136  core::Size upstream_position( 1 );
137  foreach( core::Size const con, connection_points ){
138  ft.add_edge( upstream_position, con, Edge::PEPTIDE );
139  upstream_position = con;
140  }
141  ft.add_edge( connection_points[ connection_points.size() ], pose.conformation().chain_end( 1 ), Edge::PEPTIDE );
142  ft.delete_self_edges();
143  ft.reorder( 1 );
144  return( ft );
145 }
146 
148 get_bbcsts( core::pose::Pose const & pose ) {
149  using namespace core::scoring;
150  using namespace core::scoring::constraints;
151 
152  ScoreFunctionOP scorefxn( new ScoreFunction );
153  scorefxn->set_weight( backbone_stub_constraint, 1.0 );
154  core::pose::Pose nonconst_pose = pose;
155  // pre-score to get the active cst's
156  (*scorefxn)(nonconst_pose);
157  /// Now handled automatically. scorefxn->accumulate_residue_total_energies( nonconst_pose );
158 
159  // sort through pose's constraint set and pull out only active bbcst's
160  ConstraintCOPs original_csts = nonconst_pose.constraint_set()->get_all_constraints();
161  ConstraintCOPs new_csts;
162  for( ConstraintCOPs::const_iterator it = original_csts.begin(), end = original_csts.end(); it != end; ++it ) {
163  ConstraintCOP cst( *it );
164  if( cst->type() == "AmbiguousConstraint" ) {
165  AmbiguousConstraintCOP ambiguous_cst = AmbiguousConstraintCOP( dynamic_cast<AmbiguousConstraint const *>( cst() ) ); //downcast to derived ambiguous constraint
166  if( ambiguous_cst) { // safety check for downcasting
167  if( ambiguous_cst->active_constraint()->type() == "BackboneStub" ) {
168  new_csts.push_back( ambiguous_cst->active_constraint() );
169  }
170  }
171  }
172  }
173  return new_csts;
174 }
175 
176 /// @detailed a utility function to evaluate backbone_stub_constraints for each residue in a chain and return a vector with the top n_return residue numbers by cst score
177 /// note that this function is NOT guaranteed to return n_return residues! It will return the best n<=n_return
179 best_bbcst_residues( core::pose::Pose const & pose, core::Size const chain, core::Size const n_return )
180 {
181  using namespace core::scoring;
182  using namespace core::scoring::constraints;
183  core::pose::Pose nonconst_pose = pose;
184  utility::vector1< std::pair<core::Real, core::Size> > all_residues; // score, seqpos
185  utility::vector1< core::Size > best_residues;
186 
187  // scorefxn containing only the constraint energy
188  ScoreFunctionOP scorefxn( new ScoreFunction );
189  scorefxn->set_weight( backbone_stub_constraint, 1.0 );
190 
191  // score to make sure that the cst energies are current
192  (*scorefxn)(nonconst_pose);
193  /// Now handled automatically. scorefxn->accumulate_residue_total_energies( nonconst_pose );
194 
195  // get pairs of residue number and weighted cst energy
196  for( core::Size i=nonconst_pose.conformation().chain_begin( chain ); i<=nonconst_pose.conformation().chain_end( chain ); ++i ){
197  core::Real const score( nonconst_pose.energies().residue_total_energies( i )[ backbone_stub_constraint ] );
198  core::Real const weight( (*scorefxn)[ backbone_stub_constraint ] );
199  core::Real const curr_energy( weight * score );
200  all_residues.push_back(std::make_pair( curr_energy, i ));
201  }
202  sort( all_residues.begin(), all_residues.end() );
203  for( core::Size i=1; i<=n_return; ++i ) {
204  // only use it if the cst actually evaluates
205  if( all_residues[i].first < 0 ) best_residues.push_back( all_residues[i].second );
206  }
207  assert( best_residues.size() <= n_return );
208  return best_residues;
209 }
210 
211 void
212 find_lowest_constraint_energy_residue( core::pose::Pose const & pose, core::Size const chain, core::Size & resi, core::Real & lowest_energy )
213 {
214  using namespace core::scoring;
216 
217  resi = 0;
218  lowest_energy = 100000.0;
219  for( core::Size i=pose.conformation().chain_begin( chain ); i<=pose.conformation().chain_end( chain ); ++i ){
220  using namespace core::scoring;
221  simple_filters::EnergyPerResidueFilter const eprf( i, scorefxn, backbone_stub_constraint, 10000.0/*dummy threshold*/ );
222  core::Real const curr_energy( eprf.compute( pose ) );
223  if( curr_energy<=lowest_energy ){
224  lowest_energy = curr_energy;
225  resi = i;
226  }
227  }
228 }
229 
230 /// @details a utility function for removing ALL coordinate constraints from a pose.
231 /// returns the constraints that were removed
234 {
235  using namespace core::scoring::constraints;
236 
237  ConstraintCOPs original_csts = pose.constraint_set()->get_all_constraints() ;
238  ConstraintCOPs crd_csts;
239  for( ConstraintCOPs::const_iterator it = original_csts.begin(), end = original_csts.end(); it != end; ++it ) {
240  ConstraintCOP cst( *it );
241  if( cst->type() == "CoordinateConstraint" ) {
242  ConstraintCOP crd_cst = dynamic_cast< CoordinateConstraint const *>( cst() ); //downcast to derived ambiguous constraint
243  if( crd_cst) { // safety check for downcasting
244  crd_csts.push_back( cst ); // add the entire ambiguous cst, since it contained a bbcst
245  }
246  }
247  }
248  pose.remove_constraints( crd_csts ); // remove all the ambigcsts that contain a bbcst
249  return( crd_csts );
250 }
251 
252 
253 /// @details utility function for stub_based_atom_tree. tries to find an optimal cutpoint in a pose given two different boundaries. First looks for a 3-res loop stretch on the downstream partner and returns the middle residue. Then, does the same for the upstream chain. Then, becomes desperate and tries to find any loop residue on downstream chain, and then on upstream chain. Finally, if no success, returns 0 which means that no break was found
255 best_cutpoint( core::pose::Pose & pose, core::Size const prev_u, core::Size const prev_d, core::Size const u, core::Size const d )
256 {
257  // if the pose is all loops (mini default), then run dssp
258  // this logic may cause a problem for miniproteins that are indeed all loop. But for now it's certainly OK
259  for( core::Size i=1; i<=pose.total_residue(); ++i ) {
260  char const ss = pose.secstruct( i );
261  if( ss == 'H' || ss == 'S' ) break;
262  if( i == pose.total_residue() ) {
263  core::scoring::dssp::Dssp dssp( pose );
264  dssp.insert_ss_into_pose( pose );
265  }
266  }
267 
268  for( core::Size res = prev_d; res <= d-1; ++res ){
269  if( pose.secstruct( res ) == 'L' ){
270  if( pose.secstruct( res + 1 ) == 'L' && pose.secstruct( res + 2 ) == 'L' ) return res;
271  }
272  }
273  for( core::Size res = prev_u; res <= u-1; ++res ){
274  if( pose.secstruct( res ) == 'L' ){
275  if( pose.secstruct( res + 1 ) == 'L' && pose.secstruct( res + 2 ) == 'L' ) return res;
276  }
277  }
278  for( core::Size res = prev_d; res <= d; ++res ){
279  if( pose.secstruct( res ) == 'L' ) return res;
280  }
281  for( core::Size res = prev_u; res <= u-1; ++res ){
282  if( pose.secstruct( res ) == 'L' ) return res;
283  }
284  return 0; // sign of trouble
285 }
286 
287 /// @details find the nearest residue on the target chain to res
289 find_nearest_residue( core::pose::Pose const & pose, core::Size const target_chain, core::Size const res, std::string const atom/*=="CA"*/ )
290 {
291  core::Size nearest_resi( 0 );
292  core::Real nearest_dist( 100000.0 );
293  for( core::Size resi( pose.conformation().chain_begin( target_chain ) ); resi<=pose.conformation().chain_end( target_chain ); ++resi ){
294  core::Real const distance( pose.residue(resi).xyz( pose.residue(resi).nbr_atom() ).distance( pose.residue( res ).xyz( atom ) ) );
295  if( distance<=nearest_dist ){
296  nearest_resi = resi;
297  nearest_dist = distance;
298  }
299  }
300  runtime_assert( nearest_resi );
301  return( nearest_resi );
302 }
303 
304 
305 } //protein_interface_design
306 } //protocols