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 
2 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
3 // vi: set ts=2 noet:
4 //
5 // (c) Copyright Rosetta Commons Member Institutions.
6 // (c) This file is part of the Rosetta software suite and is made available under license.
7 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
8 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
9 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
10 
11 /// @file
12 /// @brief
13 /// @detailed
14 /// @author Oliver Lange
15 ///
16 
17 
18 // Unit Headers
21 
22 // Package Headers
23 // AUTO-REMOVED #include <protocols/Protocol.hh>
24 // Project Headers
25 #include <core/pose/Pose.hh>
26 // AUTO-REMOVED #include <core/pose/util.hh>
27 
30 #include <core/kinematics/util.hh>
32 #include <core/fragment/Frame.hh>
38 
41 
44 
46 
47 #ifdef WIN32
49 #endif
50 
51 //
52 
53 // ObjexxFCL Headers
54 // AUTO-REMOVED #include <ObjexxFCL/format.hh>
55 
56 // Utility headers
57 #include <basic/Tracer.hh>
58 
59 //numeric headers
60 
61 //// C++ headers
62 // #include <string>
63 #include <list>
64 
66 #include <utility/vector1.hh>
67 #include <ObjexxFCL/string.functions.hh>
68 
69 
70 namespace protocols {
71 namespace jumping {
72 using namespace core;
73 using namespace pose;
74 using namespace kinematics;
75 
76 
77 static basic::Tracer tr("protocols.jumping");
78 
79 
80 // if false pose does still contain jumps in the fold-tree
81 void
84  Pose& open_pose,
86  const std::string &decoy_tag,
87  core::kinematics::FoldTree const& final_fold_tree_in /*default empty fold-tree */
88 )
89 {
90  core::kinematics::FoldTree final_fold_tree;
91  kinematics::MoveMap const& movemap = closure_protocol->movemap();
92  if ( !final_fold_tree_in.nres() ) { //empty fold-tree
93  final_fold_tree.simple_tree( open_pose.total_residue() );
94  } else if ( core::pose::symmetry::is_symmetric( open_pose ) ){
96  open_pose.fold_tree(), *core::pose::symmetry::symmetry_info( open_pose ),
97  final_fold_tree_in );
98  } else {
99  final_fold_tree = final_fold_tree_in;
100  }
101  //some sanity checks
102  runtime_assert( closure_protocol );
103  //runtime_assert that all cut-points in final_fold_tree are also contained the actual fold_tree
104  for ( Size ncut = 1; ncut <= (Size)final_fold_tree.num_cutpoint(); ncut++ ) {
105  if( !open_pose.fold_tree().is_cutpoint( final_fold_tree.cutpoint( ncut ) ) ){
106  throw( loops::EXCN_Loop_not_closed( "Foldtree mismatch." ) );
107  }
108  }
109  tr.Debug << "close chainbreaks until final fold-tree is reached\n";
110  simple_visualize_fold_tree( final_fold_tree, tr.Debug );
111  //close cuts that have a lot of freedom to move first
112  //since removal of some jumps might make other cuts removable
113  //hence we first get a list sorted by their max-loop-length
114  //after each cut removal we recompute this list.
115  //do this until all cuts that are not in final_fold_tree are removed
116  Pose pose = open_pose;
117 
118  Size close_count = 0;
119  while ( pose.fold_tree().num_cutpoint() > final_fold_tree.num_cutpoint() ) {
120  close_count++;
121  //make list of all cutpoints that need removal, list of std::pairs: first: max-loop-size; second: cutpoint
122  std::list< std::pair< Size, Size > > cuts;
123  for ( Size ncut = 1; ncut <= (Size) pose.fold_tree().num_cutpoint(); ncut++ ) {
124  Size cutpoint = pose.fold_tree().cutpoint( ncut );
125  if ( !final_fold_tree.is_cutpoint( cutpoint ) ) {
126 
127  // compute max_loop_size...
128  // extend loop from cutpoint away until either a jump-residue or an unmovable bb-torsion is found
129  Size min_loop_begin ( cutpoint + 1 );
130  Size max_loop_end ( cutpoint );
131  while (
132  min_loop_begin > 1
133  && !pose.fold_tree().is_jump_point( min_loop_begin - 1 )
134  && movemap.get_bb( min_loop_begin - 1 )
135  ) --min_loop_begin;
136  while (
137  max_loop_end < pose.total_residue()
138  && !pose.fold_tree().is_jump_point( max_loop_end + 1 )
139  && movemap.get_bb( max_loop_end + 1)
140  ) ++max_loop_end;
141  if ( max_loop_end > min_loop_begin ) { // put in list
142  cuts.push_back( std::make_pair( max_loop_end - min_loop_begin, cutpoint ) );
143  }
144  }
145  }
146  cuts.sort();
147 
148  if ( tr.Debug.visible() ) {
149  for ( std::list< std::pair< Size, Size > >::iterator it = cuts.begin(), eit = cuts.end();
150  it != eit; ++it ) {
151  tr.Debug << "cut " << it->second << " max_loop_size " << it->first << std::endl;
152  }
153  }
154  if ( cuts.size() == 0 ) {
155  throw( loops::EXCN_Loop_not_closed( "no moveable piece to close loop" ) );
156  }
157 
158  Size const cutpoint( cuts.back().second ); //largest is last... so take last element
159  tr.Info << "close chainbreak at position " << cutpoint << "..." << std::endl;
160 
161  // TODO need to also save foldtree here ! Use binary silent file format!
162  const bool checkpoint_foldtree=true;
163 
164 
165  if ( ! checkpoint.recover_checkpoint(
166  open_pose, NULL, decoy_tag, "_lc_" + ObjexxFCL::string_of( close_count ), false, checkpoint_foldtree ) ) {
167  if ( remove_cut( cutpoint, pose, final_fold_tree ) ) {
168  if ( tr.Debug.visible() ) {
169  tr.Debug << "current fold-trees " << std::endl;
170  simple_visualize_fold_tree_and_movemap( open_pose.fold_tree(), movemap, tr.Debug );
171  simple_visualize_fold_tree_and_movemap( pose.fold_tree(), movemap, tr.Debug );
172  tr.Debug << std::endl;
173  }
174  closure_protocol->set_loop( closure_protocol->determine_loop( open_pose, pose ) );
175  closure_protocol->apply( open_pose, pose );
176  if ( closure_protocol->bIdealLoopClosing() ) {
177  open_pose = pose;
178  } else {
179  //the best closing fragment is already applied to open_pose, now fix the fold-tree leaving an unideal residue at the chainbreak.
180  open_pose.fold_tree( pose.fold_tree() );
181  }
182  }
183  checkpoint.checkpoint( open_pose, NULL, decoy_tag, "_lc_" + ObjexxFCL::string_of( close_count ), checkpoint_foldtree );
184  } else {
185  // make sure the two poses have the same foldtree brefore removing one of the cuts in
186  // the closed pose. (this is not necessary when checkpointing is not active, but since only the
187  // open_pose is recovered, this is necessary here.
188  pose = open_pose;
189  }
190  }
191 }
192 
193 bool
194 remove_cut( Size cutpoint, Pose& pose, FoldTree const& final_fold_tree /*default empty fold-tree */) {
195  FoldTree new_fold_tree = pose.fold_tree();
196  bool success( remove_cut( cutpoint, new_fold_tree, final_fold_tree ) );
197  if ( success ) {
198  // pose.dump_pdb("tt_old_f.pdb");
199  tr.Debug << "set new fold-tree " << new_fold_tree << std::endl;
200  pose.fold_tree( new_fold_tree );
201  tr.Debug << "idealize positions " << std::endl;
202  conformation::idealize_position( cutpoint, pose.conformation() );
203  conformation::idealize_position( cutpoint+1, pose.conformation() );
204  }
205  return success;
206 }
207 
208 bool
209 remove_cut( Size cutpoint, FoldTree &new_fold_tree, FoldTree const& final_fold_tree /*default empty fold-tree */ )
210 {
211  tr.Info << "close-loops: remove cuts until fold-tree is : " << final_fold_tree << std::endl;
212  // construct the new tree formed when we glue this cutpoint and
213  // delete a single jump
214  FoldTree old_fold_tree( new_fold_tree );
215  FoldTree const& f ( old_fold_tree );
216  runtime_assert( f.is_cutpoint( cutpoint ) );
217 
218  //find enclosing jump points
219  Size jump_pos1( cutpoint );
220  Size jump_pos2( cutpoint + 1 );
221  while ( jump_pos1 > 1 && !f.is_jump_point( jump_pos1 ) )
222  --jump_pos1;
223  while ( jump_pos2 < f.nres() && !f.is_jump_point( jump_pos2 ) )
224  ++jump_pos2;
225  runtime_assert( jump_pos1 <= jump_pos2 );
226 
227  tr.Info << "remove cutpoint: " << cutpoint << " between " << jump_pos1 << " " << jump_pos2 << " in " << std::endl;
228  new_fold_tree.reorder( 1 );
229  tr.Info << new_fold_tree << std::endl;
230 
231 
232  if ( jump_pos1 < cutpoint ) {
233  new_fold_tree.delete_unordered_edge( jump_pos1, cutpoint, -1);
234  }
235  if ( cutpoint+1 < jump_pos2 ) {
236  new_fold_tree.delete_unordered_edge( cutpoint+1, jump_pos2, -1);
237  }
238  new_fold_tree.add_edge( jump_pos1, jump_pos2, -1 );
239  // I think there may be more than one jump which
240  // we could delete. This just chooses the first one
241  for ( Size i=1; i<= f.num_jump(); ++i ) {
242  // mark as "deleted" for the purposes of connectivity checking
243  bool in_final( false );
244  for ( Size nf = 1; !in_final && nf<= final_fold_tree.num_jump(); nf ++ ) {
245  in_final = ( final_fold_tree.jump_point(1, nf) == f.jump_point(1,i) && final_fold_tree.jump_point(2, nf) == f.jump_point(2,i) )
246  || ( final_fold_tree.jump_point(1, nf) == f.jump_point(2,i) && final_fold_tree.jump_point(2, nf) == f.jump_point(1,i) );
247  }
248  if ( !in_final ) {
249  new_fold_tree.update_edge_label( f.jump_point(1,i), f.jump_point(2,i), i, 0 ); // label with 0
250  if ( new_fold_tree.connected() ) {
251  // safe to cut this edge
252  new_fold_tree.delete_unordered_edge( f.jump_point(1,i), f.jump_point(2,i), 0 );
253  } else {
254  // dont cut this edge after all
255  new_fold_tree.update_edge_label( f.jump_point(1,i), f.jump_point(2,i), 0, i );
256  }
257  }
258  }
259  tr.Debug << "new_fold_tree: " << new_fold_tree << std::endl;
260  if ( new_fold_tree.connected() ) {
261  // we deleted a jump so the jump label numbers may be screwed up
262  // note that this will screw up the jump_transform mapping
263  new_fold_tree.renumber_jumps();
264  tr.Debug << "new_fold_tree renumbered: " << new_fold_tree << std::endl;
265  // plus, there may be vertices in the tree which are not jumps and
266  // not at a break
267  new_fold_tree.delete_extra_vertices();
268  tr.Debug << "new_fold_tree deleted_extra_vertices: " << new_fold_tree << std::endl;
269  new_fold_tree.reorder( 1 );
270  tr.Debug << "new_fold_tree reordered to 1 " << new_fold_tree << std::endl;
271  // fold_tree = new_fold_tree;
272  Size new_root = 1;
273  if ( new_fold_tree.num_jump() > 0 ) {
274  new_root = new_fold_tree.jump_point( 1, 1 );
275  }
276  new_fold_tree.reorder( new_root );
277  tr.Debug << "new_fold_tree reordered to " << new_root << " " << new_fold_tree << std::endl;
278  return true;
279  }
280  return false;
281 }
282 
283 
284 void safe_secstruct( pose::Pose& pose ) {
285  kinematics::FoldTree const& fold_tree( pose.fold_tree() );
286 
287  Size const num_jump ( fold_tree.num_jump() );
288  Size const nres( pose.total_residue() );
289 
290  for ( Size i = 1; i <= num_jump; ++i ) {
291  for ( Size j = 1; j <= 2; ++j ) {
292  Size const pos ( j==1 ? fold_tree.jump_edge( i ).start() : fold_tree.jump_edge( i ).stop() );
293  char const ss( pose.secstruct( pos ) );
294  if ( ss != 'L' ) {
295  for ( Size k = std::max( (Size) 1, pos-2 ), ke = std::min( nres, pos+2 );
296  k <= ke; ++k ) {
297  if ( pose.secstruct(k) != ss ) {
298  pose.set_secstruct( k, ss );
299  }
300  }
301  }
302  }
303  }
304 }
305 
307  using namespace core::fragment;
308  JumpingFrameOP frame = new JumpingFrame( startpos, endpos, length );
309  if ( length <= 1 || length > 4 ) utility_exit_with_message("called generate_jump_frame with inappropriate length argument");
310  Size pos = 1;
311  if ( length == 4 ) frame->set_pos( pos++, startpos );
312  frame->set_pos( pos++, startpos );
313  frame->set_pos( pos++, endpos );
314  if ( length >=3 ) frame->set_pos( pos, endpos );
315  return frame;
316 }
317 
318 core::fragment::JumpingFrameOP generate_jump_frame( Size startpos, Size endpos, bool bWithTorsion ) {
319  using namespace core::fragment;
320  FragDataOP frag_data = new FragData;
321  if ( bWithTorsion ) {
322  BBTorsionSRFDOP start = new BBTorsionSRFD( 3, 'E', 'X' );
323  frag_data->add_residue( start );
324  }
325  frag_data->add_residue( new UpJumpSRFD );
326  frag_data->add_residue( new DownJumpSRFD );
327 
328  if ( bWithTorsion ) {
329  BBTorsionSRFDOP stop = new BBTorsionSRFD( 3, 'E', 'X' );
330  frag_data->add_residue( stop );
331  }
332  JumpingFrameOP frame = generate_empty_jump_frame( startpos, endpos, frag_data->size() ); //see above
333  frame->add_fragment( frag_data );
334  return frame;
335 }
336 
337 ///////////////////////////////////////////////////////////////////////////////
338 //// some legacy code
339 ///
341 
342 void
344  PointList const & ca1, // pass by reference, so no tricks:: 3x3
345  PointList const & ca2, // pass by reference, so no tricks:: 3x3
346  Vector & a,
347  Vector & b,
348  Vector & c
349 )
350 {
351  /* a goes from c-alpha #1 to c-alpha #3 */
352  a = ca1[3]-ca1[1];
353  a.normalize();
354 
355  /* b gives direction of pleat for ca1 c-alphas */
356  Vector b1 = ca1[2] - ca1[1];
357  Vector b2 = ca1[2] - ca1[3];
358  b = b1 + b2 ;
359  b.normalize();
360 
361  /* c goes from ca1 triple to ca2 triple (central alpha-carbons) */
362  c = ca2[2] - ca1[2];
363  c.normalize();
364 }
365 
366 void
368  pose::Pose const& pose,
369  Size const res1,
370  Size const res2,
371  Real& orientation,
372  Real& pleating1,
373  Real& pleating2
374 )
375 {
376  runtime_assert( res1>1 && res1 < pose.total_residue() &&
377  res2 > res1 && res2 < pose.total_residue() );
378 
379 chemical::ResidueType const& rt1 ( pose.residue_type ( res1 ) );
380 chemical::ResidueType const& rt2 ( pose.residue_type ( res2 ) );
381 
382 PointList pCA1(3); //space for 3 CAs positions
383 PointList pCA2(3);
384 
385 // read CAs of 3 consecutive residues
386 for ( int i = -1 ; i<=1 ; i++ ) {
387  id::AtomID CA1( rt1.atom_index ("CA") , res1+i );
388  id::AtomID CA2( rt2.atom_index ("CA") , res2+i );
389  pCA1[ i+2 ] = pose.xyz( CA1 );
390  pCA2[ i+2 ] = pose.xyz( CA2 );
391  };
392 
393 Vector dCaCa = pCA1[ 2 ] - pCA2[ 2 ];
394 if ( dCaCa.length() > 10.5 ) {
395  tr.Warning << "the CA-CA distance for pairing " << res1 << " " << res2 << " is " << dCaCa.length() << std::endl;
396  // I put this in because I had this case once, and such an exit would have saved me time.
397  //If you have longer distances you probably don't want to choose pleating and orientation based on the native structure
398  // --- which is a temporary convenience hack anyway.
399  // utility_exit_with_message(" the CA-CA distance for the chosen pairing is more than 10.5 A check your pairings!!! ");
400  }
401 
402 
403 Vector a1,b1,c1;
404 Vector a2,b2,c2;
405 get_CA_vectors( pCA1, pCA2, a1,b1,c1 );
406 get_CA_vectors( pCA2, pCA1, a2,b2,c2 );
407 
408 orientation = dot_product( a1, a2 );
409 
410 Vector ab1,ab2;
411 cross(a1,b1,ab1);
412 cross(a2,b2,ab2);
413 
414 Real const d1 = dot_product(ab1,c1);
415 Real const d2 = dot_product(ab2,c2);
416 
417 pleating1 = d1;
418 
419 if ( orientation < 0 ) {
420  pleating2 = d2; // antiparallel
421  } else {
422  pleating2 = -d2;
423  }
424 }
425 
426  void
428  pose::Pose const& pose,
429  Size const pos1,
430  Size const pos2,
431  Size &orientation,
432  Size &pleating
433  )
434  {
435 
436  //Why did this have to get so complicated?
437  // Its actually a pretty simple concept!
438  //
439  // For some reasons, get_pairing_geometry flips
440  // pleating2 depending on the orientation --
441  // in ideal strand pairs, pleating1 and pleating2 then have the same sign.
442  //
443  // But for some twisted strand pairs (see, e.g, 22,48 in 1brs.pdb),
444  // the numbers get a little crazy...
445  //
446 
447  Real forientation, pleating1, pleating2;
448  if ( pos1 < pos2 ) {
449  get_pairing_geometry( pose, pos1, pos2, forientation,pleating1,pleating2);
450 
451  //This isn't always quite true...
452  // runtime_assert( pleating1 * pleating2 > 0.0 );
453  pleating = ( (pleating1+pleating2) < 0 ? 1 : 2 );
454  } else {
455  get_pairing_geometry( pose, pos2, pos1, forientation,pleating1,pleating2);
456 
457 
458  //This isn't always quite true...
459  // runtime_assert( pleating1 * pleating2 > 0.0 );
460 
461  if ( forientation < 0 ) {
462  // pleating for anti-parallel pairings is preserved when we
463  // interchange positions
464  pleating = ( (pleating1+pleating2) < 0 ? 1 : 2 );
465  } else {
466  // pleating for parallel pairings is reversed when we
467  // interchange positions
468  pleating = ( (pleating1+pleating2) < 0 ? 2 : 1 );
469  }
470  }
471  tr.Debug << " orientation " << forientation << " pleating " << pleating << std::endl;
472  orientation = forientation < 0 ? 1 : 2;
473  }
474 
476  core::scoring::dssp::Dssp dssp( pose );
477  dssp.insert_ss_into_pose( pose );
478 }
479 
480 } // jumping
481 } // protocols
482