Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JumpSample.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
11 /// @brief
12 /// @detailed
13 /// @author Oliver Lange
14 /// @author Christopher Miles (cmiles@uw.edu)
15 
16 // Unit Headers
18 
19 // Package Headers
22 
23 // Project Headers
24 #include <core/pose/Pose.hh>
28 #include <core/fragment/Frame.hh>
33 #include <core/kinematics/Jump.hh>
36 
37 // ObjexxFCL Headers
38 #include <ObjexxFCL/format.hh>
39 
40 // Utility headers
41 #include <basic/Tracer.hh>
42 #include <utility/io/ozstream.hh>
43 
44 // C++ headers
45 #include <cstdlib>
46 #include <string>
47 #include <fstream>
48 
53 #include <core/pose/util.hh>
55 #include <utility/vector1.hh>
56 
57 namespace core {
58 namespace scoring {
59 namespace constraints {
60 
61 using namespace ObjexxFCL::fmt;
62 
64 public:
65  ChainbreakDistFunc( Real const x0_in ): d2target_( x0_in*x0_in ){}
66 
67  FuncOP
68  clone() const { return new ChainbreakDistFunc( *this ); }
69 
70  Real func( Real const x ) const;
71  Real dfunc( Real const x ) const;
72 
73 private:
75 };
76 
78  return std::sqrt( std::abs( x*x - d2target_ ) );
79 }
80 
82  return std::sqrt( std::abs( x*x - d2target_ ) );
83 }
84 
85 }
86 }
87 } //namespaces
88 
89 
90 namespace protocols {
91 namespace jumping {
92 
93 using namespace core;
94 using namespace ObjexxFCL;
95 
96 static basic::Tracer tr("protocols.jumping");
97 
98 JumpSample::JumpSample( JumpSetup const& def ) :
99  total_residue_( def.total_residue() ),
100  njump_( def.size() ),
101  bValidTree_( false )
102 {
103  resize( def.size() );
104  int ct = 1;
105  for ( JumpSetup::const_iterator it=def.begin(), eit=def.end(); it!=eit; it++, ct++ ) {
106  jumps_( 1, ct ) = it->jump_.start_;
107  jumps_( 2, ct ) = it->jump_.end_;
108  jump_atoms_( 1, ct ) = "";
109  jump_atoms_( 2, ct ) = "";
110  Size const crs ( it->cut_reg_.start_ );
111  Size const cre ( it->cut_reg_.end_ );
112  cuts_( ct ) = crs+int( numeric::random::uniform()*( cre-crs ) + 0.5 );
113  }
115  jumps2pairings();
116  if ( !bValidTree_ && tr.Debug.visible() ) {
117  tr.Debug << "invalid FoldTree in JumpSample: " << (*this) << std::endl;
118  }
119 }
120 
121 JumpSample::JumpSample ( Size total_residue, Size njump, FArray2D_int jumps, FArray1D_int cuts, Size root ) :
122  total_residue_( total_residue ),
123  njump_( njump ),
124  jumps_ ( jumps ),
125  cuts_ ( cuts ),
126  bValidTree_( false )
127 {
128  jump_atoms_.redimension(2, njump, "");
130  jumps2pairings();
131 }
132 
133  JumpSample::JumpSample ( Size total_residue, Size njump, FArray2D_int jumps, FArray2D<std::string> jump_atoms, FArray1D_int cuts, Size root) :
134  total_residue_( total_residue ),
135  njump_( njump ),
136  jumps_ ( jumps ),
137  jump_atoms_ ( jump_atoms ),
138  cuts_ ( cuts ),
139  bValidTree_( false )
140 {
142  jumps2pairings();
143 }
144 
145 JumpSample::JumpSample ( Size total_residue, core::scoring::dssp::PairingsList const& jump_pairings, core::fragment::SecondaryStructure const& ssdef, Size root ) :
146  total_residue_( total_residue ),
147  jump_pairings_( jump_pairings ),
148  bValidTree_( false )
149 {
150  resize( jump_pairings.size() );
151 
152  // first fill jumps_ array:
153  njump_ = 0;
154  for ( core::scoring::dssp::PairingsList::const_iterator it = jump_pairings.begin(),
155  eit = jump_pairings.end(); it != eit; ++it ) {
156  njump_++;
157  jumps_(1,njump_) = it->Pos1();
158  jumps_(2,njump_) = it->Pos2();
159  jump_atoms_(1,njump_) = "";
160  jump_atoms_(2,njump_) = "";
161  }
162  runtime_assert( njump_ == jump_pairings.size() ); //kind of trivial but something odd was going on
163  if ( ssdef.total_residue() <= total_residue ) {
164  core::fragment::SecondaryStructure new_ssdef = ssdef;
165  new_ssdef.extend( total_residue );
166  generate_random_tree_from_jumps( new_ssdef.loop_fraction(), root );
167  } else {
169  }
170 }
171 
172 JumpSample::JumpSample ( Size total_residue, core::scoring::dssp::PairingsList const& jump_pairings, FArray1D_float const& cut_probability, Size root) :
173  total_residue_( total_residue ),
174  jump_pairings_( jump_pairings ),
175  bValidTree_( false )
176 {
177  resize( jump_pairings.size() );
178 
179  // first fill jumps_ array:
180  njump_ = 0;
181  for ( core::scoring::dssp::PairingsList::const_iterator it = jump_pairings.begin(),
182  eit = jump_pairings.end(); it != eit; ++it ) {
183  njump_++;
184  jumps_(1,njump_) = it->Pos1();
185  jumps_(2,njump_) = it->Pos2();
186  jump_atoms_(1,njump_) = "";
187  jump_atoms_(2,njump_) = "";
188  }
189  runtime_assert( njump_ == jump_pairings.size() ); //kind of trivial but something odd was going on
190  generate_random_tree_from_jumps( cut_probability, root );
191 }
192 
193 /// we want N-CA-C as the stub atoms for the jump
194 /// to achieve that we have to set the upstream jump atom
195 /// according to folding direction N2C --> JumpAtom C
196 /// C2N --> JumpAtom N
197 /// since the AtomTree automatically uses the parent and grand-parent as second and third stub atom
198 void
200  //this method could also live in the FoldTree
201  using namespace kinematics;
202  if ( !bValidTree_ ) return;
203  runtime_assert( fold_tree_ );
204  for ( Size i = 1; i <= njump_; ++i ) {
205  fold_tree_->set_jump_atoms( i, jump_atoms_(1,i), jump_atoms_(2,i) );
206  }
207  fold_tree_->put_jump_stubs_intra_residue();
208 }
209 
210 void
212  if ( total_residue_ == 0 ) total_residue_ = 2500; //don't make it too big.. it alloates an FArray1bool in fold-tree with this size
214  bValidTree_ = fold_tree_->tree_from_jumps_and_cuts( total_residue_, njump_, jumps_, cuts_, root, true /* verbose */ );
216 }
217 
218 void
220  jump_pairings_.clear();
221  for ( Size jump_nr = 1; jump_nr <= size(); jump_nr++ ) {
222  jump_pairings_.push_back( core::scoring::dssp::Pairing( jumps_(1, jump_nr ), jumps_(2, jump_nr), 0, 0 ) ); //initialized with 0 = unknown orientation/pleating
223  }
224 }
225 
226 void
227 JumpSample::generate_random_tree_from_jumps( FArray1D_float const& prob, Size root ) {
228  if ( total_residue_ == 0 ) total_residue_ = 2500;
230  bValidTree_ = false;
231  Size attempts( 10 );
232  while ( !bValidTree_ && attempts-- > 0 ) {
233  bValidTree_ =
234  fold_tree_->random_tree_from_jump_points( total_residue_, njump_, jumps_, prob, root, true /*yes we allow 1 nres jumps*/ );
235  if ( bValidTree_ ) {
236  cuts_.dimension( njump_ );
237  tr.Debug << "cut points ";// << std::endl;
238  for ( Size i = 1; i <= njump_; i++ ) {
239  cuts_( i ) = fold_tree_->cutpoint( i );
240  //don't except trees that cut at jump point
241  if ( fold_tree_->is_jump_point( cuts_( i ) ) ) {
242  bValidTree_ = false;
243  continue;
244  }
245  tr.Debug << cuts_( i ) << " ";
246  }
247  tr.Debug << std::endl;
248  } // tree was connected
249  } // while
251 }
252 
254  apply_to( new kinematics::FoldTree( f ) );
256 }
257 
259  apply_to( f );
261 }
262 
263 
265  fold_tree_ = pf;
268  total_residue_ = f.nres();
269  if ( bValidTree_ ) {
270  resize( f.num_jump() );
271 
272  // get jumps
273  for ( Size ct = 1; ct <= njump_; ct++ ) {
274  jumps_(1,ct) = f.upstream_jump_residue( ct );
275  jumps_(2,ct) = f.downstream_jump_residue( ct );
276  }
277 
278  // get cuts
279  for ( Size i = 1; i <= njump_; i++ ) {
280  cuts_( i ) = f.cutpoint( i );
281  }
282 
283  jumps2pairings();
284 
285  } // bValidTree_
286 }
287 
288 void
290  jumps_.redimension( 2, njump );
291  jump_atoms_.redimension(2, njump);
292  cuts_.redimension( njump );
293  jump_pairings_.resize( njump );
294  njump_=njump;
295 }
296 
297 void
299  runtime_assert( fold_tree_ );
300  runtime_assert( bValidTree_ );
301  pose.fold_tree( *fold_tree_ );
302 }
303 
304 void
306  runtime_assert( fold_tree_ );
307  runtime_assert( total_residue_ == pose.total_residue() );
308  runtime_assert( *fold_tree_ == pose.fold_tree() );
309 
310  Size const num_jump ( size() );
311  Size const nres( pose.total_residue() );
312 
313  for ( Size i = 1; i <= num_jump; ++i ) {
314  for ( Size j = 1; j <= 2; ++j ) {
315  Size const pos = jumps_(j,i);
316  char const ss( pose.secstruct( pos ) );
317  if ( ss != 'L' ) {
318  for ( Size k = std::max( (Size) 1, pos-2 ), ke = std::min( nres, pos+2 );
319  k <= ke; ++k ) {
320  if ( pose.secstruct(k) != ss ) {
321  pose.set_secstruct( k, ss );
322  }
323  }
324  }
325  }
326  }
327 }
328 
329 //@brief transfer native jump RT to poes, Sideeffect: changes fold-tree of native_pose.
330 void
332  runtime_assert( pose.fold_tree() == *fold_tree_ );
333  for ( Size i=1; i<=size(); i++) {
334  kinematics::Jump aJump = native_pose.jump( i );
335  tr.Info << "transfer jump " << i <<" " << aJump <<std::endl;
336  pose.set_jump( i, aJump );
337  }
338 }
339 
340 //@brief transfer native jump RT to poes, Sideeffect: changes fold-tree of pose.
341 void
343  core::pose::Pose &pose,
344  core::fragment::FrameIterator const& begin,
346 ) const {
347  using namespace core::fragment;
348  set_fold_tree_in_pose( pose );
349  for ( FrameIterator it = begin, eit = end;
350  it!=eit; ++it ) {
351  (*it)->steal( pose );
352  }
353 }
354 
355 
356 //@brief generate list of frames ( one for each jump ) and steal RT from pose
357 void
359  core::fragment::FrameList& all_frames,
360  kinematics::MoveMap const& mm,
361  bool bWithTorsion
362 ) const
363 {
364  all_frames.reserve( all_frames.size() + size() );// as many new frames as nr of jumps
365  // find out how many different kind of fragments are we interested in:
366  // max of four: A 1 , A 2, P 1, P 2
367 
368  for ( Size jump_nr = 1; jump_nr <= size(); jump_nr++ ) {
369  int const startpos( jumps_( 1, jump_nr ) );
370  int const endpos( jumps_( 2, jump_nr ) );
371 
372  tr.Debug << "jump " << jump_nr << " from: " << startpos << " --> " << endpos << std::endl;
373  tr.Debug << "downstream res " << fold_tree().downstream_jump_residue( jump_nr )
374  << " upstream " << fold_tree().upstream_jump_residue( jump_nr ) << std::endl;
375  // I assume that jump_nr never change, runtime_assert that this is indeed the case
376  int const down_jump_res( fold_tree().downstream_jump_residue( jump_nr ) );
377  int const up_jump_res( fold_tree().upstream_jump_residue( jump_nr ) );
378  runtime_assert( (down_jump_res == startpos) || (up_jump_res == startpos) );
379  runtime_assert( (down_jump_res == endpos ) || (up_jump_res == endpos ) );
380  runtime_assert( startpos != endpos );
381 
382  if ( mm.get_bb( up_jump_res ) || mm.get_bb( down_jump_res ) ) {
383  using namespace core::fragment;
384  FragDataOP frag_data = new FragData;
385 
386  if ( bWithTorsion && mm.get_bb( up_jump_res ) ) {
387  BBTorsionSRFDOP start = new BBTorsionSRFD( 3, 'E', 'X' );
388  frag_data->add_residue( start );
389  }
390  frag_data->add_residue( new UpJumpSRFD );
391  frag_data->add_residue( new DownJumpSRFD );
392 
393  if ( bWithTorsion && mm.get_bb( down_jump_res ) ) {
394  BBTorsionSRFDOP stop = new BBTorsionSRFD( 3, 'E', 'X' );
395  frag_data->add_residue( stop );
396  }
397 
398  JumpingFrameOP frame = new JumpingFrame( startpos, endpos, frag_data->size() );
399  Size pos = 1;
400  if ( bWithTorsion && mm.get_bb( up_jump_res ) ) frame->set_pos( pos++, startpos );
401  frame->set_pos( pos++, startpos );
402  frame->set_pos( pos++, endpos );
403  if ( bWithTorsion && mm.get_bb( down_jump_res ) ) frame->set_pos( pos++, endpos );
404  frame->add_fragment( frag_data );
405  runtime_assert( frame->nr_frags() ); //adding has worked?
406  all_frames.push_back( frame );
407  }
408  } // for Jumps iteration
409 } // method
410 
411 
412 void
414  for ( Size jump_nr=1; jump_nr<=size(); jump_nr++ ) {
415  // get native orientation to select the correct jump-geometries
417  tr.Info << "detect orientation and pleating for jump " << jump_nr <<" from " << p.Pos1() << " to " << p.Pos2() << std::endl;
418  //compute_orientation_and_pleating
419  core::Size orientation, pleating;
420  get_pleating( native_pose, p.Pos1(), p.Pos2(), orientation, pleating );
421  p.Orientation(orientation);
422  p.Pleating(pleating);
423  tr.Info << "orientation is " << p.Orientation() << " pleating is " << p.Pleating() << std::endl;
424  }
425 }
426 
429 }
430 
432 JumpSample::get_pairing( Size res1, Size res2 ) const {
433  runtime_assert ( has_orientation_and_pleating() );
434  for ( core::scoring::dssp::PairingsList::const_iterator it = jump_pairings_.begin(), eit = jump_pairings_.end();
435  it != eit; ++it ) {
436  if ( it->Pos1() == res1 && it->Pos2() == res2 ) return *it;
437  if ( it->Pos1() == res2 && it->Pos2() == res1 ) return it->generate_reversed();
438  }
439  return core::scoring::dssp::Pairing( 0, 0, 0, 0 );
440 }
441 
442 //@brief generate fragset with RTs from library, take orientation and pleating from native_pose
443 void
445  PairingLibrary const& lib,
446  kinematics::MoveMap const& mm,
447  bool bWithTorsion,
448  core::fragment::FrameList& all_frames
449 ) const {
450  using namespace core::fragment;
451 
452  all_frames.reserve( all_frames.size() + size() );// as many new frames as nr of jumps
453 
454  // find out how many different kind of fragments are we interested in:
455  // max of four: A 1 , A 2, P 1, P 2
456  runtime_assert( has_orientation_and_pleating() );
458  typedef std::map< std::pair< Size, Size >, JumpList > JumpOrientations;
459  JumpOrientations jump_kind;
460  Size jump_nr ( 1 );
461  for ( core::scoring::dssp::PairingsList::const_iterator it = jump_pairings_.begin(), eit = jump_pairings_.end();
462  it != eit; ++it ) {
463  Size o_key ( it->Orientation() ); // < 0 ? 1 : 2 );
464  Size p_key ( it->Pleating() ); // < 0 ? 1 : 2 );
465  jump_kind[ std::make_pair( o_key, p_key ) ].push_back( jump_nr++ );
466  }
467 
468  // now generate fragments for each of the maximum four JumpOrientations present
469  for ( JumpOrientations::const_iterator it=jump_kind.begin(), eit=jump_kind.end();
470  it!=eit;
471  ++it )
472  {
473  Size o_key( it->first.first ); //orientation
474  Size p_key( it->first.second ); //pleating ... believe me or not, it is in first.second
475  FragDataList frag_data;
476  lib.create_jump_fragments( o_key, p_key, bWithTorsion, frag_data );
477  for ( JumpList::const_iterator jit=it->second.begin(), ejit=it->second.end();
478  jit!=ejit; ++jit ) {
479  int const jump_nr ( *jit );
480  int const startpos( jumps_( 1, jump_nr ) );
481  int const endpos( jumps_( 2, jump_nr ) );
482 
483  runtime_assert( o_key == jump_pairings_[ jump_nr ].Orientation() );
484  runtime_assert( p_key == jump_pairings_[ jump_nr ].Pleating() );
485 
486  tr.Debug << "jump " << jump_nr << " from: " << startpos << " --> " << endpos << std::endl;
487  tr.Debug << "downstream res " << fold_tree().downstream_jump_residue( jump_nr )
488  << " upstream " << fold_tree().upstream_jump_residue( jump_nr ) << std::endl;
489 
490  // I assume that jump_nr never change, runtime_assert that this is indeed the case
491  int const down_jump_res( fold_tree().downstream_jump_residue( jump_nr ) );
492  int const up_jump_res( fold_tree().upstream_jump_residue( jump_nr ) );
493  runtime_assert( (down_jump_res == startpos) || (up_jump_res == startpos) );
494  runtime_assert( (down_jump_res == endpos ) || (up_jump_res == endpos ) );
495  runtime_assert( startpos != endpos );
496  if ( mm.get_bb( up_jump_res ) && mm.get_bb( down_jump_res ) ) {
497  Size const length( bWithTorsion ? 4 : 2 );
498  runtime_assert( length == frag_data.front()->size() );
499  JumpingFrameOP frame = generate_empty_jump_frame( up_jump_res, down_jump_res, length );
500  frame->add_fragment( frag_data );
501  all_frames.push_back( frame );
502  } else {
503  utility_exit_with_message("need to implement this: make ss-library fragments that only contain those torsions for residues\
504  that can move according to movemap -- call this function with\
505  bWithTorsions = false ... and it works for now");
506  }
507  } // for JumpList iteration
508  } // loop over orientations and pleatings
509 } // method
510 
511 void
513  for ( Size i = 1; i<= njump_; i++ ) {
514  if ( pose.residue_type( cuts_(i) ).has_variant_type( chemical::UPPER_TERMINUS ) ) continue;
515  if ( pose.residue_type( cuts_(i)+1 ).has_variant_type( chemical::LOWER_TERMINUS ) ) continue;
516  tr.Debug << "add chainbreak variant to residues " << cuts_(i) << " and " << cuts_(i)+1 << std::endl;
519  }
520 }
521 
522 void
524  //remove_chainbreaks( pose ); not necessary if max_dist is monotonoically increaseing
525  for ( Size i = 1; i<= njump_; i++ ) {
526  if ( sp.dist( cuts_(i), cuts_(i)+1 ) <= max_dist
527  && pose.residue( cuts_(i) ).is_polymer() && pose.residue( cuts_(i)+1 ).is_polymer() ) {
528  if ( pose.residue_type( cuts_(i) ).has_variant_type( chemical::UPPER_TERMINUS ) ) continue;
529  if ( pose.residue_type( cuts_(i)+1 ).has_variant_type( chemical::LOWER_TERMINUS ) ) continue;
530  tr.Debug << "add chainbreak variant to residues " << cuts_(i) << " and " << cuts_(i)+1 << std::endl;
533  }
534  }
535 }
536 
537 using namespace scoring::constraints;
538 void
540  for ( Size i = 1; i<= njump_; i++ ) {
541  pose.add_constraint(
542  new AtomPairConstraint(
543  id::AtomID( pose.residue(cuts_(i) ).atom_index("C"), cuts_(i) ),
544  id::AtomID( pose.residue(cuts_(i) + 1).atom_index("N"), cuts_(i) + 1),
545  new ChainbreakDistFunc( 1.7424 )
546  )
547  );
548  }
549 }
550 
551 void
553  pose::Pose &pose,
554  Size max_dist,
556 ) const {
557  //remove_chainbreaks( pose ); not necessary if max_dist is monotonoically increaseing
558  for ( Size i = 1; i<= njump_; i++ ) {
559  if ( sp.dist( cuts_(i), cuts_(i)+1 ) <= max_dist ) {
560  tr.Debug << "add chainbreak as distance constraint to residues " << cuts_(i) << " and " << cuts_(i)+1 << std::endl;
562  id::AtomID( pose.residue(cuts_(i) ).atom_index("C"), cuts_(i) ),
563  id::AtomID( pose.residue(cuts_(i) + 1).atom_index("N"), cuts_(i) + 1),
564  new ChainbreakDistFunc( 1.7424 )
565  ) );
566  }
567  }
568 }
569 
570 void
572  for ( Size i = 1; i<= njump_; i++ ) {
575  }
576 }
577 
578 std::ostream & operator <<(std::ostream & os, JumpSample const & t) {
579  for ( Size i=1; i<=t.size(); i++ ) {
580  os << RJ(4,t.jumps_(1,i)) << " " << RJ(4,t.jumps_(2,i)) << " | ";
581  }
582  os << "cuts:";
583  for ( Size i=1; i<=t.size(); i++ ) {
584  os << " " << RJ(4,t.cuts_(i));
585  }
586  return os;
587 }
588 
589 void
591  utility::io::ozstream out( fn );
592  if ( out ) {
593  out << "from pymol import cmd\n";
594  for ( Size i=1; i<=size(); i++ ) {
595  out << "cmd.select( \"jumps"<<i<<"\", \"resi "<<jumps_(1,i)<<"+"<<jumps_(2,i)<<"\");" << std::endl;
596  out << "cmd.show( \"sticks\", \"jumps"<<i<<"\");\n";
597  out << "cmd.select( \"cut"<<i<<"\", \"resi " <<cuts_(i)<<"\");\n";
598  out << "cmd.show( \"sphere\",\"cut"<<i<<"\");" << std::endl;
599  }
600  }
601 }
602 
603 } //jumping
604 } //protocols
605 
606