Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
StepWiseProteinLoopBridger.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 StepWiseProteinLoopBridger
11 /// @brief Makes a list of (phi, psi, omega) at moving_residues that
12 /// could be useful for full-atom packing
13 /// @detailed
14 /// @author Rhiju Das
15 
16 
17 //////////////////////////////////
21 // AUTO-REMOVED #include <protocols/swa/InputStreamWithResidueInfo.hh>
22 
23 //////////////////////////////////
24 #include <core/types.hh>
28 #include <core/pose/Pose.hh>
30 #include <basic/Tracer.hh>
31 #include <core/kinematics/Jump.hh>
32 
33 #include <protocols/loops/Loop.hh>
34 #include <numeric/kinematic_closure/bridgeObjects.hh>
35 
36 #include <ObjexxFCL/format.hh>
37 #include <ObjexxFCL/string.functions.hh>
38 #include <ObjexxFCL/FArray1D.hh>
39 
40 #include <numeric/conversions.hh>
41 
42 #include <utility/exit.hh>
43 
44 #ifdef WIN32
45 #include <time.h>
46 #endif
47 
48 #include <string>
49 
50 //Auto Headers
52 #include <core/id/TorsionID.hh>
55 #include <utility/vector1.hh>
56 
57 
58 using namespace core;
59 using core::Real;
60 
61 //////////////////////////////////////////////////////////////////////////
62 // Good ol' kinematic loop closure. Applied to loops whose N-terminal
63 // and C-terminal segment have been modeled in, e.g., different silent
64 // files.
65 //////////////////////////////////////////////////////////////////////////
66 
67 static basic::Tracer TR( "protocols.swa.protein.stepwise_loop_bridger" ) ;
68 
69 namespace protocols {
70 namespace swa {
71 namespace protein {
72 
73 
74 
75  //////////////////////////////////////////////////////////////////////////
76  //constructor!
77  StepWiseProteinLoopBridger::StepWiseProteinLoopBridger( StepWisePoseSampleGeneratorOP sample_generator,
78  StepWiseJobParametersOP job_parameters ):
79  sample_generator_( sample_generator ),
80  working_bridge_res_( job_parameters->working_bridge_res() ),
81  is_pre_proline_( job_parameters->is_pre_proline() ),
82  num_perturb_steps_( 0 ), // perturbations of 'takeoff' psi and phi -- currently disabled.
83  perturb_torsion_( 20.0 ),
84  idl_CA_C_N_(116.2), // taken from hard-coded numbers in KIC code.
85  idl_C_N_CA_(121.7), // taken from hard-coded numbers in KIC code.
86  idl_C_N_(1.32869), // taken from hard-coded numbers in KIC code.
87  OMEGA_MEAN_(179.8), // taken from hard-coded numbers in KIC code.
88  use_icoor_geometry_( false ), //this would supercede above vals with ICOOR values (actually they're very similar)
89  verbose_( false )
90  {
91 
92  if ( working_bridge_res_.size() != 3 ) utility_exit_with_message( "Must supply three bridge residues that are covered by -sample_res, -input_res1, and -input_res2!");
93  initialize_is_fixed_res( job_parameters->working_fixed_res(), job_parameters->working_sequence() );
94 
95  }
96 
97  //////////////////////////////////////////////////////////////////////////
98  //destructor
100  {}
101 /////////////////////
104 return "StepWiseProteinLoopBridger";
105 }
106 
107 
108  //////////////////////////////////////////////////////////////////////////
109  //////////////////////////////////////////////////////////////////////
110  void
112  {
113 
114  clock_t const time_start( clock() );
115 
116  Pose pose_save = pose;
117 
118  setup_torsions( pose );
119 
120  figure_out_loop( pose );
121 
122  sample_generator_->reset();
123  pose_count_ = 0;
124 
125  while ( sample_generator_->has_another_sample() ){
126 
127  sample_generator_->get_next_sample( pose );
129 
130  }
131 
132  // Kind of silly -- should have at least one output.
134 
135  std::cout << "Total time in StepWiseProteinLoopBridger: " <<
136  static_cast<Real>(clock() - time_start) / CLOCKS_PER_SEC << std::endl;
137 
138  pose = pose_save;
139 
140  }
141 
142 
143  ///////////////////////////////////////////////////////////////////////////
144  // Should just do the KIC loop closure, but added the option of perturbing
145  // the takeoff psi (at the N-terminal end of the loop) and landing phi (at the
146  // the C-terminal end of the loop ).
147  void
149 
150  if ( num_perturb_steps_ == 0 ){
151  std::cout << "Loop combination " << pose_count_++ << ". " ;
152  KIC_loop_close( pose );
153  return;
154  }
155 
156 
157  Size const pre_loop_res = working_bridge_res_[1] - 1;
158  Size const post_loop_res = working_bridge_res_[3] + 1 ;
159  Real const psi_start = pose.psi( pre_loop_res );
160  Real const phi_start = pose.phi( post_loop_res );
161 
162  for ( int offset1 = -1 * num_perturb_steps_; offset1 <= num_perturb_steps_; offset1++ ) {
163 
164  Real const psi_perturb = psi_start + Real( offset1 ) * perturb_torsion_;
165  pose.set_psi( pre_loop_res, psi_perturb );
166 
167  for ( int offset2 = -1 * num_perturb_steps_; offset2 <= num_perturb_steps_; offset2++ ) {
168 
169  Real const phi_perturb = phi_start + Real(offset2) * perturb_torsion_ ;
170  pose.set_phi( post_loop_res, phi_perturb );
171 
172  //std::cout << "Psi of pre_loop_res " << pre_loop_res << " is " << psi_perturb << std::endl;
173  //std::cout << "Phi of post_loop_res " << post_loop_res << " is " << phi_perturb << std::endl;
174 
175  std::cout << "Loop combination " << pose_count_++ << ". " ;
176  //pose.dump_pdb( "S_" + ObjexxFCL::string_of( pose_count_ ) + ".pdb" );
177 
178  // Do it!
179  KIC_loop_close( pose );
180 
181 
182  }
183  }
184  }
185 
186 
187  //////////////////////////////////////////////////////////////////////////////////////////////
188  void
190 
191  using namespace protocols::loops;
192  using namespace core::chemical;
193 
194  Size const & middle_bridge_res = working_bridge_res_[ 2 ];
195  assert( working_bridge_res_[ 1 ] = middle_bridge_res - 1 );
196  assert( working_bridge_res_[ 3 ] = middle_bridge_res + 1 );
197 
198  // consistency checks.
199  if ( middle_bridge_res == 0 ) {
200  utility_exit_with_message( "Is there a bridge residue that is not an input residue?" );
201  }
202 
203  // Check that there is a cutpoint in here.
204  std::cout << "Found bridge residue: " << middle_bridge_res << std::endl;
205  std::cout << pose.fold_tree() << std::endl;
206  std::cout << pose.annotated_sequence( true ) << std::endl;
207  Size cutpoint_ = 0;
208  for ( int offset = -2; offset < 1; offset++ ) {
209  Size const test_res = static_cast<int>( middle_bridge_res ) + offset;
210  if ( test_res >= 1 && test_res <= pose.total_residue() ){
211  if ( pose.fold_tree().is_cutpoint( test_res ) ){
212  cutpoint_ = test_res;
213  if ( !pose.residue_type( cutpoint_ ).has_variant_type( CUTPOINT_LOWER ) ||
214  !pose.residue_type( cutpoint_+1 ).has_variant_type( CUTPOINT_UPPER ) ){
215  std::cout << " cutpoint res? " << cutpoint_ << std::endl;
216  utility_exit_with_message( "cutpoints not set up properly at cutpoint residue" );
217  }
218  }
219  }
220  }
221  if ( cutpoint_ == 0 ) utility_exit_with_message( "could not find cutpoint!" );
222  std::cout << "Found cutpoint residue: " << cutpoint_ << std::endl;
223 
224  loop_ = Loop( middle_bridge_res-1 /*start*/, middle_bridge_res+1 /*end*/, cutpoint_ /*cutpoint?*/ );
225 
226  }
227 
228  //////////////////////////////////////////////////////////////////////////////////////////////
229  void
231 
232  // Need to fill torsions for moving and bridge residues.
233 
234  using namespace core::id;
235  which_torsions_.clear();
236  for ( Size n = 1; n <= pose.total_residue(); n++ ){
237 
238  if ( !is_fixed_res_[ n ] ) {
239 
240  // loop residues.
241  for ( Size k = 1; k <= 3; k++ ) which_torsions_.push_back( TorsionID( n, BB, k ) );
242 
243  } else if ( n < pose.total_residue() && !is_fixed_res_[ n+1 ] ) {
244 
245  // psi,omega of 'takeoff' residues
246  //for ( Size k = 2; k <= 3; k++ ) which_torsions_.push_back( TorsionID( n, BB, k ) );
247  for ( Size k = 1; k <= 3; k++ ) which_torsions_.push_back( TorsionID( n, BB, k ) );
248 
249  } else if ( n > 1 && !is_fixed_res_[ n-1 ] ) {
250 
251  // phi of 'landing' residues
252  //for ( Size k = 1; k <= 1; k++ ) which_torsions_.push_back( TorsionID( n, BB, k ) );
253  for ( Size k = 1; k <= 3; k++ ) which_torsions_.push_back( TorsionID( n, BB, k ) );
254 
255  }
256 
257  }
258 
259  }
260 
261 
262  //////////////////////////////////////////////////////////////////////////
263  void
265 
266  utility::vector1< Real > main_chain_torsion_set_for_moving_residues;
267  for ( Size n = 1; n <= which_torsions_.size(); n++ ) {
268  main_chain_torsion_set_for_moving_residues.push_back( pose.torsion( which_torsions_[ n ] ) );
269  std::cout << ' ' << pose.torsion( which_torsions_[ n ] );
270  }
271  std::cout << ' ' << std::endl;
272 
273  main_chain_torsion_sets_for_moving_residues_.push_back( main_chain_torsion_set_for_moving_residues );
274 
275  }
276 
277  //////////////////////////////////////////////////////////////////////////
280  {
282  }
283 
284  //////////////////////////////////////////////////////////////////////////
287  {
288  return which_torsions_;
289  }
290 
291 
292  ///////////////////////////////////////////////////////////////////////////
293  void
295  utility::vector1< core::Real > const & db_ang,
296  utility::vector1< core::Real > const & db_len ) const {
297 
298  std::cout << "------ chainTORS output ---- " << std::endl;
299  for (Size i = 1; i <= ( dt_ang.size()/3) ; i++) {
300 
301  std::cout << "TORSIONS: ";
302  for (Size j = 1; j <= 3; j++) std::cout << ObjexxFCL::fmt::F(8,3,dt_ang[ 3*(i-1)+ j ]) << " ";
303 
304  std::cout << " BOND_ANGLES: ";
305  for (Size j = 1; j <= 3; j++) std::cout << ObjexxFCL::fmt::F(8,3,db_ang[ 3*(i-1)+ j ]) << " ";
306 
307  std::cout << " BOND_LENGTHS: ";
308  for (Size j = 1; j <= 3; j++) std::cout << ObjexxFCL::fmt::F(8,3,db_len[ 3*(i-1)+ j ]) << " ";
309 
310  std::cout << std::endl;
311 
312  }
313  }
314 
315 
316 
317 /////////////////////////////////////////////////////////////////////////////////////
318  void
321  utility::vector1<Real> & dt_ang,
322  utility::vector1<Real> & db_ang,
323  utility::vector1<Real> & db_len,
324  Size const & start_res_ ,
325  Size const & end_res_ ) const {
326 
327  using namespace numeric::kinematic_closure;
328 
329  if ( verbose_ ) std::cout << "About to run chainTORS" << std::endl;
330  Size ind = 1;
331  for (Size i = start_res_ - 1; i <= end_res_ + 1; i++) {
332  if (verbose_ ) std::cout << "Filling residue " << i << std::endl;
333  conformation::Residue res = pose.residue(i);
334  for (Size j=1; j<=3; j++) { // DJM: just keeping N, CA, C atoms. We assume these are always the first 3. BAD -- PROTEIN ONLY ASSUMPTION -- How about metal ions with only 1 atom?
335  atoms[ind].resize(3);
336  atoms[ind][1] = static_cast<Real> (res.xyz(j).x());
337  atoms[ind][2] = static_cast<Real> (res.xyz(j).y());
338  atoms[ind][3] = static_cast<Real> (res.xyz(j).z());
339  ind++;
340  }
341  }
342 
344  utility::vector1<Real> R0 (3);
345 
346  chainTORS(atoms.size(), atoms, dt_ang, db_ang, db_len, R0, Q0);
347 
348  if ( verbose_ ) output_chainTORS( dt_ang, db_ang, db_len );
349 
350  }
351 
352  ///////////////////////////////////////////////////////////////////////////////////////
353  void
355 
356  using namespace core::kinematics;
357  using namespace protocols::loops;
358  using namespace numeric::kinematic_closure;
359 
360  ///// kinematic loop close.
361  // Following copied from, e.g., KinematicMover.cc. Need to elaborate for terminal residues!
362  // inputs to loop closure
364  utility::vector1<Size> pivots (3), order (3);
365  // for eliminating identical solutions
366  utility::vector1<Real> dt_ang, db_len, db_ang, save_t_ang, save_b_len, save_b_ang;
367  utility::vector1<Real> dummy_t_ang, dummy_b_ang, dummy_b_len;
369 
370  start_res_ = loop_.start();
371  middle_res_ = loop_.start() + 1;
372  end_res_ = loop_.stop();
373  middle_offset_ = middle_res_ - start_res_; // is used to set central pivot atom
374  seg_len_ = end_res_ - start_res_ + 1;
375  atoms.resize( (seg_len_ + 2) * 3); // one extra residue on each side to establish the geometric frame
376 
377  fill_chainTORS_info( pose, atoms, dt_ang, db_ang, db_len, start_res_, end_res_ );
378 
379  order[1]=1;
380  order[2]=2;
381  order[3]=3;
382 
383  // Set the pivot atoms
384  Size pvatom1=5; // second C-alpha
385  Size pvatom2=5 + (3 * middle_offset_); // middle res C-alpha
386  Size pvatom3=(3 * (seg_len_+1)) - 1; // second-to-last C-alpha
387  pivots[1]=pvatom1;
388  pivots[2]=pvatom2;
389  pivots[3]=pvatom3;
390 
391  // Need to fix bond lengths and angles at cutpoint
392  Size const cut_offset_ = loop_.cut() - start_res_;
393  dt_ang[ 3 + 3*cut_offset_ + 3 ] = OMEGA_MEAN_;
394  db_len[ 3 + 3*cut_offset_ + 3 ] = idl_C_N_;
395  db_ang[ 3 + 3*cut_offset_ + 3 ] = idl_CA_C_N_;
396  db_ang[ 3 + 3*cut_offset_ + 4 ] = idl_C_N_CA_;
397 
398  if ( use_icoor_geometry_ ) {
399  Size cutpoint = loop_.cut();
400  Real const bond_angle1( pose.residue( cutpoint ).upper_connect().icoor().theta() );// CA-C=N bond angle
401  Real const bond_angle2( pose.residue( cutpoint+1 ).lower_connect().icoor().theta() ); // C=N-CA bond angle
402  Real const bond_length( pose.residue( cutpoint+1 ).lower_connect().icoor().d() ); // C=N distance
403  dt_ang[ 3 + 3*cut_offset_ + 3 ] = 180.0;
404  db_len[ 3 + 3*cut_offset_ + 3 ] = bond_length;
405  db_ang[ 3 + 3*cut_offset_ + 3 ] = 180.0 - numeric::conversions::degrees(bond_angle1);
406  db_ang[ 3 + 3*cut_offset_ + 4 ] = 180.0 - numeric::conversions::degrees(bond_angle2);
407  }
408 
409 
410  if ( verbose_ ){
411  std::cout << "After setting desired geometry at cutpoint, relative to loop_start " << cut_offset_ << std::endl;
412  output_chainTORS( dt_ang, db_ang, db_len );
413  }
414 
415  ///////////////////////////////////
416  // Perform loop closure
417  ///////////////////////////////////
418  // outputs from loop closure
419  sample_omega_recursively( pose, -1, atoms, dt_ang, db_ang, db_len, pivots, order );
420 
421  // just for output.
422  if ( verbose_ ) fill_chainTORS_info( pose, atoms, dt_ang, db_ang, db_len, start_res_, end_res_ );
423  }
424 
425 
426  /////////////////////////////////////////////////////////////////////////////////
427  void
429  pose::Pose & pose,
430  int const offset,
432  utility::vector1<Real> & dt_ang,
433  utility::vector1<Real> & db_ang,
434  utility::vector1<Real> & db_len,
435  utility::vector1< Size > const & pivots,
437 
438  using namespace numeric::kinematic_closure;
439  if ( offset == 2 ){
440  /* hardwired!! -- check cis-omega at residue before bridge residue (offset = 0 ),
441  and at bridge residue ( offset = 1 ), and that's it */
442  utility::vector1<utility::vector1<Real> > t_ang, b_ang, b_len;
443  int nsol=0;
444 
445  if ( verbose_ ) std::cout << "About to run bridgeObjects" << std::endl;
446  bridgeObjects(atoms, dt_ang, db_ang, db_len, pivots, order, t_ang, b_ang, b_len, nsol);
447  if ( verbose_ ) std::cout << "Finished bridgeObjects" << std::endl;
448 
449  Size const num_solutions = t_ang.size();
450  std::cout << "Kinematic loop closure found this many solutions: " << num_solutions << std::endl;
451 
452  for (Size i = 1; i <= num_solutions; i++) {
453 
454  for ( core::Size res = 0; res < seg_len_; res++ ){
455  pose.set_phi ( start_res_ + res, t_ang[ i ][ (3*(res+1)) + 1 ] );
456  pose.set_psi ( start_res_ + res, t_ang[ i ][ (3*(res+1)) + 2 ] );
457  pose.set_omega( start_res_ + res, t_ang[ i ][ (3*(res+1)) + 3 ] );
458  }
459 
461 
462  if ( verbose_ ) pose.dump_pdb( "KIC_"+ ObjexxFCL::string_of( i )+".pdb" );
463 
464  // readout for checking.
465  fill_chainTORS_info( pose, atoms, dt_ang, db_ang, db_len, start_res_, end_res_ );
466  }
467 
468  } else {
469 
470  dt_ang[ 3 + 3*offset + 3 ] = OMEGA_MEAN_;
471  sample_omega_recursively( pose, offset + 1, atoms, dt_ang, db_ang, db_len, pivots, order );
472 
473  // std::cout << "RES " << pose.sequence()[ start_res_ + offset - 1 ] << " " << pose.sequence()[ start_res_ + offset ] << " " << job_parameters_->is_pre_proline( start_res_+ offset ) << std::endl;
474 
475  if ( is_pre_proline_[ start_res_ + offset ] ) {
476  // std::cout << " sample cis omega: " << start_res_ + offset;
477  dt_ang[ 3 + 3*offset + 3 ] = 0.0 /*OMEGA_MEAN_*/;
478  sample_omega_recursively( pose, offset + 1, atoms, dt_ang, db_ang, db_len, pivots, order );
479  }
480  }
481  }
482 
483  //////////////////////////////////////////////////////////////////////////
484  void
486 
487  is_fixed_res_.clear();
488  for ( Size n = 1; n <= working_sequence.size(); n++ ) is_fixed_res_.push_back( false );
489 
490  for ( Size i = 1; i <= fixed_res.size(); i++ ){
491  is_fixed_res_[ fixed_res[i] ] = true;
492  }
493 
494  }
495 
496 
497 
498 }
499 }
500 }