Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
KinematicWrapper.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_closure/kinematic_closure/KinematicWrapper.cc
11 /// @brief KinematicWrapper methods implemented - this is a mover which simplifies use of KinematicMover loop modeling
12 /// @author Steven Lewis
13 
14 // Unit Headers
17 
18 // Package Headers
19 
20 // Project Headers
21 // AUTO-REMOVED #include <core/pose/Pose.hh>
22 
23 // AUTO-REMOVED #include <protocols/loops/Loops.hh>
24 
26 
27 // Utility Headers
28 #include <basic/options/option.hh>
29 #include <basic/Tracer.hh>
30 #include <core/types.hh>
31 #include <utility/exit.hh>
32 #include <numeric/random/random.hh>
33 //#include <utility/vector1.hh>
34 
35 // option key includes
36 #include <basic/options/keys/loops.OptionKeys.gen.hh>
37 
38 #include <protocols/loops/Loop.hh>
39 #include <utility/vector1.hh>
40 
41 //Auto Headers
42 
43 
44 
45 
46 // C++ Headers
47 
48 using basic::T;
49 using basic::Error;
50 using basic::Warning;
51 
52 static basic::Tracer TR( "protocols.loops.loop_closure.kinematic_closure.KinematicWrapper" );
53 static numeric::random::RandomGenerator RG(171528);
54 
55 namespace protocols {
56 namespace loops {
57 namespace loop_closure {
58 namespace kinematic_closure {
59 
60 /// @details the responsiblity of apply() is to use the underlying
61 /// KinematicMover to close the loop, taking care of moving the KinematicMover's
62 /// begin/middle/end and ensuring that closure does occur.
64 
65  core::Size counter(1);
66  core::Size alc_start(0), alc_middle(0), alc_end(0); // three pivot residues for kinematic loop closure
67  core::Size alc_end_in_vec(0), alc_start_in_vec(0); //alc_start's position in allowed_positions_ vector
68  core::Size const npos(allowed_positions_.size());
69 
70  runtime_assert(!(npos < 3)); //need at least three res for pivots
71 
72  for( /*counter*/; counter<=limit_; ++counter){
73  //pick new points for kinematic closure
74  // AS: the previous implementation had a "history bias" towards the N-terminus of the loop, as the start pivot can be anywhere between begin_loop and end_loop-2, while the choice of the end pivot depends on the start pivot
75  // note that this implementation does not consider length restrictions for the loop, so it probably shouldn't be used for whole-protein ensemble generation -- this should be incorporated before putting the KinematicWrapper in charge of all pivot selections, including those from refine/LoopMover_KIC
76  if ( basic::options::option[ basic::options::OptionKeys::loops::legacy_kic ]() || counter % 2 == 0 ) {
77  alc_start_in_vec = RG.random_range(1,npos-2); //choose a random spot in allowed vector, but not near the end
78  alc_start = allowed_positions_[alc_start_in_vec]; //store it as start
79  alc_end_in_vec = RG.random_range(alc_start_in_vec+2, npos); //chose a post-start spot in allowed vector
80  alc_end = allowed_positions_[alc_end_in_vec]; //store it as end
81  } else {
82  alc_end_in_vec = RG.random_range(3, npos); //chose a a random spot in allowed vector, but not near the start
83  alc_end = allowed_positions_[alc_end_in_vec]; //store it as end
84  alc_start_in_vec = RG.random_range(1,alc_end_in_vec-2); //choose a spot somewhere before the end position
85  alc_start = allowed_positions_[alc_start_in_vec]; //store it as start
86  }
87  core::Size middle_offset = (alc_end - alc_start) / 2; //pick the natural middle between the two
88  alc_middle = alc_start + middle_offset;
89 
90 
91  //must guaruntee alc_middle is in vector
92  bool ok(false);
93  core::Size i(alc_start_in_vec+1);
94  for( ; i<alc_end_in_vec; ++i){ //iterate through vector
95  if(alc_middle == allowed_positions_[i]){ //if a match is found, no problem, we're done, set flag
96  ok = true;
97  break;
98  } else if (alc_middle < allowed_positions_[i]) break; //if we overshot it, we have to fix it
99  }
100  if(!ok){ //if we didn't find an exact match, i points to the first element in allowed_positions_ larger than middle
101  //there is an edge case which we have to handle first: if (i-1) == alc_start_in_vec (alc_start == alc_middle) then we have to choose alc_middle == allowed_positions[i]
102  if( alc_start_in_vec == (i-1) ) alc_middle = allowed_positions_[i];
103  else {
104  core::Size const diff1(allowed_positions_[i] - alc_middle), diff2(alc_middle - allowed_positions_[i-1]);
105  alc_middle = (diff2 <= diff1 ? allowed_positions_[i-1] : allowed_positions_[i]);
106  //take whatever vector element is closest to the calculated middle
107  }
108  }
109 
110  //alc_middle = allowed_positions_[RG.random_range(alc_start_in_vec+1, alc_end_in_vec-1)]; //?what would this do?
111 
112  //TR << "cycle " << counter << " pivots begin/middle/end "
113  // << alc_start << '/' << alc_middle << '/' << alc_end << std::endl;
114 
115  kinmover_->set_pivots(alc_start, alc_middle, alc_end);
116  kinmover_->apply(pose);
117  if (kinmover_->last_move_succeeded() ) break; //we hope this will be the exit point
118  }//end for many cycles
119 
120  if( counter <= limit_ ){
121  TR << "KinematicMover closed in " << counter << " cycles; loop was begin/middle/end "
122  << alc_start << '/' << alc_middle << '/' << alc_end << std::endl;
124  }
125  else if( counter > limit_ ){
126  TR << "KinematicMover failed to close in " << limit_ << " cycles" << std::endl;
128  }
129  else {utility_exit_with_message("How did we get here? - KinematicWrapper");}
130 
131  return;
132 }//apply
133 
136  return "KinematicWrapper";
137 }
138 
139 ///@details this function compares positions in the allowed_positions vector with the movemap, and removes non-mobile positions
141 {
142  init_allowed_pos(); //reset the vector
143 
145  for(iter i(allowed_positions_.begin()); i!= allowed_positions_.end();) {
146  if(mm->get_bb(*i)) ++i;
147  else i = allowed_positions_.erase(i);
148  }
149 
150  TR << "respect_this_movemap has restricted loop pivots to these positions:";
151  for(iter i(allowed_positions_.begin()); i!= allowed_positions_.end(); ++i) TR << " " << *i;
152  TR << std::endl;
153 
154  return;
155 }
156 
157 using namespace basic::options;
158 ///@brief ctor with Loop
160  KinematicMoverOP kinmover_in,
161  protocols::loops::Loop loop_in,
162  core::Size cycles
163 ) : Mover(), kinmover_(kinmover_in), loop_begin_(loop_in.start()), loop_end_(loop_in.stop()),
164  limit_( (cycles == 0) ? option[OptionKeys::loops::kinematic_wrapper_cycles].value() : cycles) //option or parameter
165 {
166  ctor();
167 }
168 
169 ///@brief ctor with explicit loop begin/end
171  KinematicMoverOP kinmover_in,
172  core::Size loop_begin,
173  core::Size loop_end,
174  core::Size cycles
175 ) : Mover(), kinmover_(kinmover_in), loop_begin_(loop_begin), loop_end_(loop_end),
176  limit_( (cycles == 0) ? option[OptionKeys::loops::kinematic_wrapper_cycles].value() : cycles) //option or parameter
177 {
178  ctor();
179 }
180 
181 ///@details trivial wrapper around stuff needed in two ctors (de-duplicating the code)
183  Mover::type( "KinematicWrapper" );
184  runtime_assert((loop_end_ - loop_begin_ +1) >=3 );
185  //should we clone (deep copy?) kinmover instead of just copying the OP?
186  //NO, because that would complicate simulated annealing
188  return;
189 }
190 
191 ///@details initializes the allowed_positions vector with every position in the loop as an allowed pivot
193  allowed_positions_.clear();
195  for( core::Size i(loop_begin_); i <= loop_end_; ++i) allowed_positions_.push_back(i);
196  return;
197 }
198 
200 
201 } // namespace kinematic_closure
202 } // namespace loop_closure
203 } // namespace loops
204 } // namespace protocols
205