Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FragmentMover.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 /// @brief Inserts a Fragment into a Pose, similar to old Rosetta++ main_frag_trial algorithm.
11 /// @author Oliver Lange
12 
13 // Unit Headers
15 
16 // Package Headers
17 
18 // Project Headers
19 #include <core/fragment/Frame.hh>
20 #include <core/fragment/FragSet.hh>
22 #include <basic/options/option.hh>
23 #include <core/pose/Pose.hh>
25 
27 
28 // Utility headers
29 #include <numeric/random/random.hh>
30 #include <basic/prof.hh>
31 #include <basic/Tracer.hh>
33 // AUTO-REMOVED #include <core/conformation/symmetry/util.hh>
34 
36 
37 // ObjexxFCL Headers
38 
39 // option key includes
40 
41 #include <basic/options/keys/run.OptionKeys.gen.hh>
42 
43 #include <utility/vector1.hh>
44 #include <ObjexxFCL/format.hh>
45 
46 
47 
48 
49 // C++ headers
50 
51 namespace protocols {
52 namespace simple_moves {
53 
54 static numeric::random::RandomGenerator RG(489); // <- Magic number, do not change it!
55 
56 using namespace core;
57 using namespace fragment;
58 using namespace basic;
59 
60 static basic::Tracer tr("protocols.simple_moves.FragmentMover");
61 
63 
66  std::string type
67 ) :
68  fragset_( fragset )
69  // movemap_( movemap )//,
70  //bValidInsertMap_ ( false )
71 {
73  movemap->set_bb( true ); //standard movemap
77 }
78 
79 
80 ///@brief constructor
84  std::string type
85 ) :
86  fragset_( fragset ),
87  movemap_( movemap )//,
88  //bValidInsertMap_ ( false )
89 {
92 }
93 
96  return "FragmentMover";
97 }
98 
100  Size ct( 0 );
101  for ( InsertMap::const_iterator it = insert_map().begin(), eit = insert_map().end(); it != eit; ++it ) {
102  FrameList frames;
103  if ( !fragset_->frames( *it, frames ) ) continue;
104  for ( FrameList::const_iterator fit = frames.begin(); fit != frames.end(); ++fit ) {
105  FrameList one_frame;
106  one_frame.push_back( *fit );
107  apply_frames( pose, one_frame );
108  }
109  // ct += apply( pose, *it );
110  }
111  return ct;
112 }
113 
114 ///@brief accessor to the fragment set
116  return fragset_;
117 }
118 
119 ///@brief setter for the fragment set
120 void
122  fragset_ = new_frags_;
124 }
125 
126 ///@brief setter for the movemap
127 void
129  movemap_ = movemap;
131 }
132 
135  return movemap_;
136 }
137 
138 void
140  // if ( !bValidInsertMap_ ) {
141  fragset_->generate_insert_map( *movemap_, insert_map_, insert_size_ );
142  // bValidInsertMap_ = true;
143  // }
144 }
145 
146 
147 
148 ///@constructor
151 ) : FragmentMover( fragset, "ClassicFragmentMover" )
152 {
153  set_defaults();
154 }
155 
156 
157 ///@constructor
161 ) : FragmentMover( fragset, movemap, "ClassicFragmentMover" )
162 {
163  set_defaults();
164 }
165 
166 
167 ///@constructor Temp work around for PyRosetta code, until we found a way how to handle owning pointers in this case
170  core::kinematics::MoveMap const & movemap
171 ) : FragmentMover(fragset.clone(), new core::kinematics::MoveMap(movemap), "ClassicFragmentMover" )
172 {
173  set_defaults();
174 }
175 
177 {}
178 
179 ///@brief alternative Constructor to be used by derived classes
183  std::string type
184 ) : FragmentMover( fragset, movemap, type )
185 {
186  set_defaults();
187 }
188 
189 ///@brief alternative Constructor to be used by derived classes
192  std::string type
193 ) : FragmentMover( fragset, type )
194 {
195  set_defaults();
196 }
197 
200  return "ClassicFragmentMover";
201 }
202 
203 //return a fragnum for given Frame, overload to make other choices
205  FrameList const& frames,
206  pose::Pose const&,
207  Size& frame_num,
208  Size& frag_num
209 ) const {
210  // classically: choose randomly
211  runtime_assert( frames.size() );
212  for ( Size nfail = 1; nfail <= 100; nfail ++ ) {
213 
214  //choose frame
215  frame_num = static_cast< int >( RG.uniform() * frames.size() ) + 1;
216  Size N ( frames[ frame_num ]->nr_frags() );
217 
218  //choose frag_num in frame
219  if ( N >= 1 ) { // nr_frags is indexed starting at 1
220  frag_num = static_cast< int >( RG.uniform() * N ) + 1;
221  return true;
222  }
223  }
224  return false;
225 }
226 
227 void
229  using namespace basic::options;
230  check_ss_ = !option[ basic::options::OptionKeys::run::remove_ss_length_screen ]();
231 
232  bApplyEndBias_ = true;
233  end_bias_ = 30.0; //classic is 60 // pose_simple_moves is 30
234  min_overlap_ = 0;
235  min_frag_length_ = 0;
237 }
238 
239 /// accept with probability 1 if the fragment window is centered on the center of the protein.
240 /// accept with probability .3677 if the fragment window is centered end-bias residues away from
241 /// the center of the protein
242 // if ( total_insert+frag_length != pose.total_residue() || r <= std::exp( -( end_dist / end_bias ) ) ) {
243 // the question of total_insert+frag_length == pose.total_residue() doesn't make sense if different frag_lengths are involved
244 //
246  Real r = RG.uniform();
247  // classic bias
248  // Real const end_bias ( 60.0 );
249  // Real end_dist = std::abs( begin - ( pose.total_residue() / 2.0 ) );
250  // return r <= std::exp( -( end_dist / end_bias ) );
251  runtime_assert( begin > 0 && begin <= insert_size_.size() );
252  Size size = insert_size_[ begin ];
253 
254  // the following assertion can happen if non-continuous (eg. Jump) fragments are inserted with bias-check, switch it off!
255 
256  if ( ( begin + size - 1 ) > pose.total_residue() ){
257  tr.Error << "BEGIN: " << begin << " SIZE: " << size << " TOTAL_RES: " << pose.total_residue() << std::endl;
258  tr.Error << "Are the fragments compatible with the fasta or the input PDB used to extract the folding sequence ? " << std::endl;
259  tr.Error << "It appears that the fragments go up to residue " << begin + size - 1 << " while the pose only has " << pose.total_residue() << " residues!" << std::endl;
260  utility_exit_with_message("Assertion failure: runtime_assert( ( begin + size - 1 ) <= pose.total_residue() ); " );
261  }
262 
263 
264  Size min_fixed_residues;
265 
266 
267  // THIS HAS TO TAKE MOVEMAP INTO ACCOUNT: if the core around jumps is fixed... basically no moves are accepted...
268  Size const fixed_residues =
269  pose.fold_tree().count_fixed_residues( begin, size, min_fixed_residues );
270 
271 //if symmetric, we just consider a single subunit;
272  Real factor ( 1.0 );
273  if( core::pose::symmetry::is_symmetric( pose ) ) {
274  factor = 1.0 / (Real) core::pose::symmetry::symmetry_info(pose)->subunits();
275  }
276 
277  Real bias = std::exp( factor * ( (Real) min_fixed_residues - fixed_residues ) / end_bias() );
278  // tr.Trace << "biascheck: " << begin << " " << size << " " << factor << " " << min_fixed_residues << " " << fixed_residues << " " << end_bias() << " ("<<bias
279  // << " => " << r << ")" << std::endl;
280  return ( r <= bias );
281 }
282 
283 void
286  predefined_window_start_ = window_start;
287  return;
288 }
289 
290 
291 bool ClassicFragmentMover::choose_window_start( pose::Pose const& pose, Size, Size &begin ) const {
292 
293  Size const total_insert ( insert_map_.size() );
294 
295  for ( Size i = 1; i<=total_insert; i++ ) tr.Trace << " " << insert_map_[ i ];
296 
297  if ( tr.Trace.visible() ) {
298  tr.Trace << "size of insertmap: " << total_insert << " -- ";
299  tr.Trace << "insert_size: ";
300  if ( total_insert ) for ( Size i = 1; i<=insert_map_[ total_insert ]; i++ ) tr.Trace << " " << insert_size_[ i ];
301  tr.Trace << std::endl;
302  }
303 
304  if ( !total_insert ) {
305  tr.Warning << "empty insert map ... no fragment insertion attempted" << std::endl;
306  return false;
307  }
308 
309  Size nfail ( 0 );
310  while ( nfail < 100 ) {
311 
312  begin = insert_map_[ static_cast< int >( RG.uniform() * total_insert ) + 1 ];
313  //tr.Trace << "window start " << begin << std::endl;
314  /// apl -- distance that the center of the fragment window is from the center of the protein
315  /// apl -- SOON
316  //Real end_dist = std::abs( (begin + frag_length / 2.0 ) - ( pose.total_residue() / 2.0 ) );
317  if ( !bApplyEndBias_ || end_bias_check( pose, begin ) ) {
318  return true;
319  }
320  //tr.Trace << "bias check failed for begin=" << begin << " " << std::endl;
321  ++nfail;
322  }
323  return false;
324 }
325 
327  Frame const & frame,
328  Size frag_num,
330  pose::Pose & pose
331 ) const {
332  return frame.apply( movemap, frag_num, pose );
333 }
334 
335 
338  return "LoggedFragmentMover";
339 }
340 
341 bool
343  core::fragment::Frame const& frame,
344  Size frag_num,
346  core::pose::Pose &pose
347 ) const {
348  bool success = Parent::apply_fragment( frame, frag_num, movemap, pose );
349  if ( success ) {
350  logs_.push_back( Item( frame.start(), frag_num ) );
351  }
352  return success;
353 }
354 
355 void
356 LoggedFragmentMover::show( std::ostream& out ) const {
357  using namespace ObjexxFCL::fmt;
358  for ( Storage::const_iterator it=logs_.begin(), eit=logs_.end(); it!=eit; ++it) {
359  out << RJ(5, it->frame_pos) << ' ' << RJ(5, it->frag_num) << std::endl;
360  }
361 }
362 
363 void
365  logs_.clear();
366 }
367 
368 /// @brief DONT ALLOW HELICES OF LESS THAN 3 OR STRANDS OF LESS THAN 2
369 /// Fix this: inserting length two helices at the chain end is allowed
370 /// as is inserting length 1 strands... For the moment, preserving r++'s
371 /// incorrect behavior
372 bool ClassicFragmentMover::valid_ss( std::string const & new_ss ) const {
373  bool valid = true;
374  Size helix_len = 0;
375  Size strand_len = 0;
376  for ( Size i = 1; i < new_ss.size(); ++i ) {
377  if ( new_ss[i-1] == 'H' ) ++helix_len;
378  if ( new_ss[i-1] == 'E' ) ++strand_len;
379  if ( new_ss[i-1] != new_ss[i] ) {
380  if ( helix_len != 0 && helix_len < 3 ) {
381  tr.Trace << "short helix_len" << std::endl;
382  valid = false;
383  break;
384  }
385  if ( strand_len != 0 && strand_len < 2 ) {
386  tr.Trace << "short strand_len" << std::endl;
387  valid = false;
388  break;
389  }
390  helix_len = 0;
391  strand_len = 0;
392  } // if ( new_ss[i] != new_ss[i+1] )
393  } // for ( Size i = 1; i < new_ss.length(); ++i )
394  return valid;
395 }
396 
397 
398 /// @brief choose and insert a Fragment from the protocols::moves::Movers Fragment-Set into a Pose.
400  PROF_START( basic::FRAGMENT_MOVER );
401  // update_insert_map( ); // checks if bValidInsertMap == false
402 
403  // If the insert map is empty dont attempt fragment insertions
404  // to avoid corrupting the pose, memory and/or your grandmother.
405  if( insert_size_.size() == 0 ){
406  return;
407  }
408 
409  // find a fragment
410  bool success ( false );
411 
412  // since we have an OP of the movemap it might be changed from the outside:
413  // this means the insertmap has to be regenerated... do this at most once
414  bool insert_map_definitely_right( false );
415 
416  Size nfail = 0;
417  while ( !success && ( nfail < 100 ) ) {
418  Size frag_begin;
419  Size window_length;
420  FrameList frames;
421  while ( nfail < 100 && frames.size() == 0 ) {
422  // choose a fragment length
423  if ( !choose_window_length( pose, window_length ) ) {
424  nfail++;
425  continue;
426  }
427 
428 
429  // choose an insertion point
431  frag_begin = predefined_window_start_;
432  else if ( !choose_window_start( pose, window_length, frag_begin ) ) {
433  nfail++;
434  continue;
435  }
436 
437  // retrieve fragments for this position
438  if ( !fragset_->region( *movemap(), frag_begin, frag_begin + window_length - 1,
439  min_overlap_, min_frag_length_, frames ) ) {
440  // if we are here, we couldn't find fragments at this position --- maybe recompute insert_map
441  if ( !insert_map_definitely_right ) {
442  insert_map_definitely_right = true;
443  tr.Debug << "didn't find fragment at predicted position ==> update_insert_map() " << std::endl;
445  } else {
446  utility_exit_with_message(" couldn't find fragments --- inconsistency in the insert map " );
447  }
448  nfail++;
449  continue;
450  } // if fragset_->region
451  } // while ( frames.size() == 0 )
452  // if ssblock or random_frag only a subset of fragments was there to choose from, this decision could be made
453  // outside of this code by supplying a Subset of the frag_set. Alternatively, we could do weight-based sampling
454  // like the original design of mini fragments and just set some weights to zero.
455 
456  if ( frames.size() ) { // we got fragments
457  success = apply_frames( pose, frames );
458  //poss. reason for failure: ss-check, jump not present in fold-tree
459  }
460  } // while ( !success );
461 
462  if ( !success ) {
463  tr.Error << "couldn't find fragment to insert!!" << std::endl;
464  return;
465  }
466  PROF_STOP( basic::FRAGMENT_MOVER );
467 
468 } // apply
469 
470 bool ClassicFragmentMover::apply_frames( pose::Pose &pose, FrameList const& frames ) const {
471  Size frame_num;
472  Size frag_num;
473  bool success( false );
474  if ( !choose_fragment( frames, pose, frame_num /*output*/, frag_num /*output*/ ) ) return false;
475  if ( tr.Trace.visible() ) tr.Trace
476  << "frag (" << frames[ frame_num ]->start() << ","
477  << frag_num << ","
478  << frames[ frame_num ]->nr_res_affected( *movemap_ )
479  << ")" << std::endl;
480  if ( !check_ss() ) return apply_fragment( *frames[ frame_num ], frag_num, *movemap_, pose );
481 
482  // now do the ss-check!
483  // tr.Trace << "now do the ss-check!"<< std::endl;
484  // get actual ss from pose
485  std::string proposed_ss;
486  proposed_ss.reserve( pose.total_residue() );
487  proposed_ss = pose.secstruct();
488 
489  std::string old_ss = proposed_ss;
490 
491  // check if old ss is valid
492  bool valid = !valid_ss( old_ss ); // if old_ss is not valid we can apply the fragment anyway
493 
494  // if old ss was fine ---> check fragments effect on ss
495  if ( !valid ) { // if old_ss was valid we check if proposed_ss is still valid.
496  frames[ frame_num ]->apply_ss( *movemap_, frag_num, proposed_ss );
497  // tr.Trace << !valid << " old_ss: " << old_ss << std::endl;
498  valid = valid_ss( proposed_ss );
499  // tr.Trace << valid << "new_ss: " << proposed_ss << std::endl;
500  }
501  // tr.Trace << "finished the ss-check! : " << valid << std::endl;
502  if ( valid ) {
503  success = apply_fragment( *frames[ frame_num ], frag_num, *movemap_, pose );
504  } else {
505  // tr.Trace << "dissallow insertion due to short helix/strand " << std::endl;
506  }
507  return success;
508 }
509 
510 std::ostream &operator<< ( std::ostream &os, ClassicFragmentMover const &cfmover )
511 {
512  moves::operator<<(os, cfmover);
513  os << "-------------------Settings--------------------" << std::endl;
514  os << "End bias: " << cfmover.end_bias_ << std::endl <<
515  "Min overlap: " << cfmover.min_overlap_ << std::endl <<
516  "Min fragment length: " << cfmover.min_frag_length_ << std::endl <<
517  "Check ss: " << ( (cfmover.check_ss_) ? "True" : "False" ) << std::endl <<
518  "bApplyEndBias: " << ( ( cfmover.bApplyEndBias_ ) ? "True" : "False" ) << std::endl <<
519  "Use predefined window start: " << ( (cfmover.use_predefined_window_start_) ? "True": "False" ) << std::endl <<
520  "Predefined window start: " << cfmover.predefined_window_start_ << std::endl;
521  os << "-----------------------------------------------" << std::endl;
522  os << "Movemap: " << std::endl;
523  cfmover.movemap()->show();
524  os << "**Unless a movemap is specified above, all backbone torsion angles are set to TRUE**" << std::endl;
525  return os;
526 }
527 
528 bool FragmentMover::apply( pose::Pose & pose, Size pos ) const {
529  FrameList frames;
530  if ( !fragset_->frames( pos, frames ) ) return false;
531  return apply_frames( pose, frames );
532 }
533 
537 ) : ClassicFragmentMover( fragset, movemap, "ClassicFragmentMover" )
538 {}
539 
541 {}
542 
543 } // simple_moves
544 } // protocols