Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
IndependentLoopMover.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/loops/loop_mover/IndependentLoopMover.cc
11 /// @brief loop mover base class
12 /// @author Mike Tyka
13 /// @author James Thompson
14 
15 /// Unit headers
17 
18 // Package headers
19 #include <protocols/loops/Loop.hh>
20 #include <protocols/loops/Loops.hh>
23 
24 // Project headers
26 #include <core/pose/Pose.hh>
29 
30 // Basic headers
31 #include <basic/Tracer.hh> // tracer output
32 #include <basic/options/option.hh>
33 #include <basic/options/keys/loops.OptionKeys.gen.hh>
34 
35 // Utility headers
36 #include <utility/vector1.hh>
37 
38 // Numeric headers
39 #include <numeric/random/random.fwd.hh>
40 #include <numeric/random/random_permutation.hh>
41 
42 /// ObjexxFCL headers
43 #include <ObjexxFCL/string.functions.hh>
44 #include <ObjexxFCL/format.hh>
45 
46 // C++ Headers
47 #include <iostream>
48 #include <map>
49 #include <string>
50 #if defined(WIN32) || defined(__CYGWIN__)
51  #include <ctime>
52 #endif
53 
54 
55 namespace protocols {
56 namespace loops {
57 namespace loop_mover {
58 
59 static numeric::random::RandomGenerator RG(47537); // <- Magic number, do not change it!!!
60 
61 ///////////////////////////////////////////////////////////////////////////////
62 using namespace core;
63 using namespace ObjexxFCL;
64 using namespace ObjexxFCL::fmt;
65 
67  LoopMover()
68 {
69  Mover::type("IndependentLoopMover");
70  set_defaults();
71 }
72 
75 ) : LoopMover( loops_in )
76 {
77  Mover::type("IndependentLoopMover");
78  set_defaults();
79 }
80 
83 ) : LoopMover( lfd )
84 {
85  Mover::type("IndependentLoopMover");
86  set_defaults();
87 }
88 
90  GuardedLoopsFromFileOP guarded_loops
91 ) : LoopMover( guarded_loops )
92 {
93  Mover::type("IndependentLoopMover");
94  set_defaults();
95 }
96 
97 // destructor
99 
101  using namespace basic::options;
102  using namespace basic::options::OptionKeys;
103  build_attempts_ = option[ OptionKeys::loops::build_attempts ](); // 3
104  grow_attempts_ = option[ OptionKeys::loops::grow_attempts ](); // 7
105  accept_aborted_loops_ = option[ OptionKeys::loops::accept_aborted_loops](); //false
106  strict_loops_ = option[ OptionKeys::loops::strict_loops ](); //false
107  random_order_ = option[ OptionKeys::loops::random_order ](); //false
108  build_all_loops_ = option[ OptionKeys::loops::build_all_loops ](); //false
109  loop_combine_rate_ = option[ OptionKeys::loops::combine_rate ](); // 0.0
110 }
111 
112 /// @brief Apply the loop-build protocol to the input pose
114  using namespace basic::options;
115  using namespace basic::options::OptionKeys;
116 
117  resolve_loop_indices( pose );
118 
119  // Select Loops to be built
120  all_loops_closed_ = true;
121  tr().Info << "ALL_LOOPS:" << *loops() << std::endl;
122 
123  Loops selected_loops;
124  select_loops( selected_loops );
125  tr().Info << "SELECTEDLOOPS:" << selected_loops << std::endl;
126 
127 
128  kinematics::FoldTree f_orig=pose.fold_tree();
129  Size lcount=0;
130 
131  core::pose::Pose pose_initial = pose;
132 
133 
134  int select_best_loop_from = option[ OptionKeys::loops::select_best_loop_from ]();
135 
136  LoopResult result_of_loopModel;
137 
138  for ( Loops::iterator it=selected_loops.v_begin(), it_end=selected_loops.v_end();
139  it != it_end; ++it ) {
140  lcount++;
141  // Make loal copy of loop to be build
142  Loop buildloop( *it );
143 
144  // either extend or at least idealize the loop (just in case).
145  if ( buildloop.is_extended() ){
146  // store starting fold tree and cut pose_initial
147  set_single_loop_fold_tree( pose_initial, buildloop );
148  tr().Info << "Setting extended torsions: " << buildloop << std::endl;
149  if ( option[ OptionKeys::loops::debug ]() ) pose_initial.dump_pdb("just_before_set_extended_torsions.pdb");
150  set_extended_torsions( pose_initial, buildloop );
151  if ( option[ OptionKeys::loops::debug ]() ) pose_initial.dump_pdb("just_after_set_extended_torsions.pdb");
152  pose_initial.fold_tree( f_orig );
153  }
154 
155  // statistics:
156  int time_start = time(NULL);
157  Size nfailure = 0;
158  //Size nrmsfail = 0;
159 
160  tr().Info << "Building Loop: " << buildloop << std::endl;
161  result_of_loopModel = Failure;
162 
163  pose::Pose best_pose = pose_initial;
164  Real best_score = 10000000.0;
165  Size best_count = 0;
166  // code below goes for grow_attempts + 1 ...
167  for ( int extension_attempt = 0; extension_attempt <= grow_attempts_; extension_attempt ++ ){
168 
169  if ( !strict_loops_ && extension_attempt > 0 ){
170  loops()->grow_loop_away_from_sheets( pose, buildloop, 1.0 );
171  }
172  for ( int build_attempt = 0; build_attempt < build_attempts_; build_attempt ++ ){
173  tr().Info << "Building Loop attempt: " << build_attempt << std::endl;
174  pose = pose_initial;
175 
176  if ( option[ OptionKeys::loops::debug ]() ) pose.dump_pdb("just_before_rebuild.pdb");
177 
178  std::string checkname = "loop_" + string_of( lcount ) + "_" + string_of( extension_attempt ) + "_" + string_of( build_attempt );
179 
180  std::string curr_job_tag = get_current_tag();
181  bool checkpoint_recovery = false;
182 
183  if ( get_checkpoints()->recover_checkpoint( pose, curr_job_tag, checkname + "_S", pose.is_fullatom(), true) ) {
184  checkpoint_recovery = true;
185  result_of_loopModel = Success;
186  } else if ( get_checkpoints()->recover_checkpoint( pose, curr_job_tag, checkname + "_C", pose.is_fullatom(), true) ) {
187  checkpoint_recovery = true;
188  result_of_loopModel = CriticalFailure;
189  } else if ( get_checkpoints()->recover_checkpoint( pose, curr_job_tag, checkname + "_F", pose.is_fullatom(), true) ) {
190  checkpoint_recovery = true;
191  result_of_loopModel = Failure;
192  } else {
193  // this should have been called before here, but there are
194  // some cases where loop-building is attempted with a cut
195  // of zero.
196  buildloop.auto_choose_cutpoint( pose );
197  /// Main loop modeling call here. Derived classes override the "model_loop" function"
198  result_of_loopModel = model_loop( pose, buildloop );
199  }
200 
201  // If the loop bas built and closed ok.
202  if ( result_of_loopModel == Success || accept_aborted_loops_ ){
203  if ( ! checkpoint_recovery ){
204  get_checkpoints()->checkpoint( pose, curr_job_tag, checkname + "_S", true );
205  }
206 
207  // briefly score the pose with whatever scorefunction is being used.
208  core::Real pose_score;
209  if ( scorefxn() ) pose_score = (*scorefxn())(pose);
210  else pose_score = 0;
211 
212  get_checkpoints()->debug( curr_job_tag, checkname, pose_score);
213 
214  // compare to previous score - if better "accept"
215  if ( pose_score < best_score || best_count == 0 ){
216  best_pose = pose;
217  best_score = pose_score;
218  best_count ++;
219  tr().Debug << "Adding a " << best_score << std::endl;
220  }
221  if ( best_count >= (Size)select_best_loop_from ) break;
222  continue;
223  }
224  nfailure++;
225 
226  //fpd if we have strict loops on, keep trying rather than immediately failing
227  if ( result_of_loopModel == ExtendFailure && !strict_loops_ ){ // means extend loop immediately!
228  if ( ! checkpoint_recovery ){
229  get_checkpoints()->checkpoint( pose, curr_job_tag, checkname + "_F", true );
230  }
231  get_checkpoints()->debug( curr_job_tag, checkname, -1);
232  break;
233  }
234 
235  if ( result_of_loopModel == CriticalFailure ){
236  if ( ! checkpoint_recovery ){
237  get_checkpoints()->checkpoint( pose, curr_job_tag, checkname + "_C", true );
238  }
239  get_checkpoints()->debug( curr_job_tag, checkname, -2);
240  tr().Error << "Unable to build this loop - a critical error occured. Moving on .. " << std::endl;
241  break;
242  }
243  } // for build_attempts
244 
245  // If we have a sufficient number of loop successses, break (by
246  // default this means 1 closed loop)
247  if ( best_count >= (Size)select_best_loop_from ) break;
248  // If we can't build this loop due to some major fundamental failure
249  if ( result_of_loopModel == CriticalFailure ) break;
250  // or if we're still unsuccessful (i.e. best_count == 0) and growing the loop isnt an option (because strict_loops is set) then also give up.
251  if ( strict_loops_ ) break;
252  }
253 
254  tr().Info << "result of loop closure:0 success, 3 failure " << result_of_loopModel << std::endl;
255  if(result_of_loopModel != Success){
256  all_loops_closed_ = false;
257  break; //no need to check the rest of the loops if one can't be closed the result will be an open structure.
258  }
259 
260  if ( (best_count > 0) || accept_aborted_loops_ ){
261  pose_initial = best_pose;
262  pose = best_pose;
263  }
264 
265 
266  // Print statistics:
267  int time_end = time(NULL);
268  float time_per_build = float(time_end - time_start) / float(nfailure+1);
269 
270  tr().Info << "Loopstat: "
271  << " " << I(3,it->start())
272  << " " << I(3,it->stop())
273  << " " << I(3,buildloop.start() )
274  << " " << I(3,buildloop.stop() )
275  << " " << I(3,buildloop.size())
276  << " time " << F(5,1,time_per_build )
277  << " " << I(3,nfailure)
278  << " time " << F(5,1,time_per_build * nfailure )
279  << " " << best_score
280  << " " << ( it->is_extended() ? std::string(" ext ") : std::string(" noext ")) << std::endl;
281 
282  }
283 
285  pose.fold_tree( f_orig );
286 }
287 
288 void IndependentLoopMover::select_loops( Loops & selected_loops ){
289  using namespace basic::options;
290  using namespace basic::options::OptionKeys;
291 
292  Loops temp_loops;
293  Loops comb_loops;
294 
295  if ( option[ OptionKeys::loops::build_specific_loops ].user() ) {
296  // Choose loops by user
297  utility::vector1<int> loop_numbers(
298  option[ OptionKeys::loops::build_specific_loops ]
299  );
300 
301  for ( Size i = 1; i <= loop_numbers.size(); ++i ) {
302  if ( loop_numbers[i] <= 0 ){
303  utility_exit_with_message( "Specified loop numbers is 0 or below.");
304  }
305  if ( (Size)loop_numbers[i] > loops()->size() ){
306  utility_exit_with_message( "Specified loop number is greater than the number of loops in the loop file itself.");
307  }
308  temp_loops.add_loop( ( *loops() )[ loop_numbers[i] ] );
309  }
310 
311  } else {
312  // Choose loops by skiprate
313  for ( Loops::const_iterator it=loops()->begin(), it_end=loops()->end(); it != it_end; ++it ) {
314  if ( build_all_loops_ ||
315  ( numeric::random::uniform() >= it->skip_rate() )
316  ) {
317  temp_loops.add_loop( *it );
318  }
319  }
320  }
321 
322  // combine loops sing combine_rate
323  std::sort( temp_loops.v_begin(), temp_loops.v_end(), Loop_lt() ); // necessary
324 
325  for ( Size l=1; l <= temp_loops.size(); l++ ) {
326  if ( ( l == temp_loops.size() ) ||
327  ( numeric::random::uniform() >= loop_combine_rate_ )
328  ) {
329  comb_loops.add_loop( temp_loops[ l ] );
330  } else {
331  Loop combined_loop(
332  temp_loops[ l ].start(),
333  temp_loops[ l+1 ].stop(),
334  temp_loops[ l ].cut(),
335  temp_loops[ l ].skip_rate() * temp_loops[ l+1 ].skip_rate(),
336  temp_loops[ l ].is_extended() || temp_loops[ l+1 ].is_extended()
337  );
338 
339  comb_loops.add_loop( combined_loop );
340  l++; // skip next loop;
341  }
342  }
343 
344  // randomize order if required
345  if ( random_order_ ) {
346  //std::random__shuffle( comb_loops.v_begin(), comb_loops.v_end() );
347  numeric::random::random_permutation( comb_loops.v_begin(), comb_loops.v_end(), RG);
348  }
349 
350  selected_loops = comb_loops;
351 } // IndependentLoopMover::select_loops()
352 
355  return "IndependentLoopMover";
356 }
357 
358 } // namepsace loop_mover
359 } // namespace loops
360 } // namespace protocols