Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BuildInstruction.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/forge/components/instructions/BuildInstruction.cc
11 /// @brief tracks modifications to be made and is capable of residue length changes on a Pose
12 /// @author Yih-En Andrew Ban (yab@u.washington.edu)
13 
14 // unit headers
16 
17 // project headers
21 #include <core/pose/Pose.hh>
22 #include <core/scoring/Energies.hh>
23 #include <basic/Tracer.hh>
24 
25 // utility headers
26 #include <utility/signals/Link.hh>
27 
28 // C++ headers
29 #include <algorithm>
30 
31 #ifdef WIN32
32 #include <iterator>
33 #endif
34 
35 #include <utility/vector0.hh>
36 #include <utility/vector1.hh>
37 
38 
39 
40 namespace protocols {
41 namespace forge {
42 namespace build {
43 
44 
45 // Tracer instance for this file
46 // Named after the original location of this code
47 static basic::Tracer TR( "protocols.forge.build.BuildInstruction" );
48 
49 
50 /// @brief default constructor
52  Super(),
53  state_( BuildInstructionState::READY ),
54  original_interval_( Interval( 0, 0 ) ),
55  detach_after_modify_( true )
56 {}
57 
58 
59 /// @brief interval constructor
60 /// @param[in] i the residue range to operate on
61 /// @param[in] rts the residue type set to use, default FA_STANDARD
63  Interval const & i,
65 ) :
66  Super(),
67  state_( BuildInstructionState::READY ),
68  original_interval_( i ),
69  rts_( rts ),
70  detach_after_modify_( true )
71 {}
72 
73 
74 /// @brief copy constructor
76  Super( rval ),
77  state_( rval.state_ ),
78  original_interval_( rval.original_interval_ ),
79  rts_( rval.rts_ ),
80  detach_after_modify_( rval.detach_after_modify_ )
81 {
82  // length_obs_link_ not copied!
83  // dependencies_ not copied! See comments in header.
84 }
85 
86 
87 /// @brief default destructor
89  detach_from();
90 }
91 
92 
93 /// @brief copy assignment
95  if ( this != &rval ) {
96  Super::operator =( rval );
97  state_ = rval.state_;
99  rts_ = rval.rts_;
100  // length_obs_link_ not copied on purpose!
102  // dependencies_ not copied on purpose! See comments in header.
103  }
104  return *this;
105 }
106 
107 
108 /// @brief modify this pose
110  // Can't call modify() more than once without invoking reset_accounting().
111  // Can consider replacing this with a call to reset_accounting() itself...
112  runtime_assert( !modify_was_successful() );
113 
114  // Before doing anything, check to make sure the necessary dependencies
115  // are satisfied so that the BuildInstruction has the information it
116  // needs to complete successfully.
117  if ( !dependencies_satisfied() ) {
119  return state_;
120  }
121 
122  // we're mangling the structure so must fully clear Energies, otherwise
123  // things may break in users' protocols
124  pose.energies().clear();
125 
126  attach_to( pose );
127 
128  // do the actual work
129  modify_impl( pose );
130 
131  if ( detach_after_modify_ ) {
132  detach_from();
133  }
134 
135  // mark state
137 
138  return state_;
139 }
140 
141 
142 /// @brief Is the BuildInstruction's state at <em>READY</em>?
143 /// @remarks <em>READY</em> indicates the BuildInstruction has been reset
144 /// and is ready to modify a Pose.
147 }
148 
149 
150 /// @brief Is the BuildInstruction's state at <em>WAITING_ON_DEPENDENCIES</em>?
151 /// @remarks <em>WAITING_ON_DEPENDENCIES</em> indicates
152 /// the BuildInstruction is waiting for its dependencies to be satisfied
153 /// before allowing modifications to proceed.
156 }
157 
158 
159 /// @brief Is the BuildInstruction's state at <em>MODIFY_WAS_SUCCESSFUL</em>?
160 /// @remarks <em>MODIFY_WAS_SUCCESSFUL</em> indicates the BuildInstruction has
161 /// finished modifications to the Pose, and its residue indexing is now
162 /// consistent with the newly modified Pose.
165 }
166 
167 
168 /// @brief attach to a Pose's conformation
170  detach_from();
172 }
173 
174 
175 /// @brief detach from a Pose's conformation
177  length_obs_link_.invalidate();
178 }
179 
180 
181 /// @brief update any indexing wrt length change to Pose/Conformation being watched
183  switch ( event.tag ) {
184  case ( LengthEvent::INVALIDATE ) : {
185  detach_from();
186  break;
187  }
188  case ( LengthEvent::RESIDUE_APPEND ) : {
189  on_residue_append( event );
190  break;
191  }
192  case ( LengthEvent::RESIDUE_PREPEND ) : {
193  on_residue_prepend( event );
194  break;
195  }
196  case ( LengthEvent::RESIDUE_DELETE ) : {
197  on_residue_delete( event );
198  break;
199  }
200  default : { // do nothing, fall through
201  break;
202  }
203  }
204 }
205 
206 
207 /// @brief Reset intervals, positions, etc to initial state and drop
208 /// observers. State set to READY.
210  detach_from();
213 }
214 
215 
216 /// @brief are dependencies satisfied so that modify_impl() can complete
217 /// successfully?
218 /// @return True if modify_impl() can be called, False otherwise.
219 /// @remarks This function will automatically be checked within modify()
220 /// prior to running modify_impl().
222  for ( BuildInstructionCAPs::const_iterator i = dependencies_.begin(), ie = dependencies_.end(); i != ie; ++i ) {
223  if ( !(**i).modify_was_successful() ) { // some instruction has not completed yet
224  return false;
225  }
226  }
227 
228  // all instructions have completed, everything ok
229  return true;
230 }
231 
232 
233 /// @brief add an instruction to this BuildInstruction's dependency list
234 /// @remarks before this instruction's modify() may complete properly, all
235 /// instructions in the dependency list must have completed modify() first
237  if ( !dependent_on( i ) ) {
238  dependencies_.push_back( i.get() );
239  }
240 }
241 
242 
243 /// @brief is this instruction dependent upon the given instruction?
245  return std::find( dependencies_.begin(), dependencies_.end(), i ) != dependencies_.end();
246 }
247 
248 
249 /// @brief compares fixed and mutable positions to determine compatibility with
250 /// another instruction
251 /// @remarks override this to obtain custom compatibility check
253  using std::insert_iterator;
254  using std::inserter;
255 
256  // First check residue type sets are equivalent via their names.
257  // This check should be performed unless mixing-matching of different
258  // residue type sets within a Conformation is implemented.
259  if ( rts_->name() != rval.rts_->name() ) {
260  TR.Error << "ResidueTypeSet incompatibility!" << std::endl;
261  return false;
262  }
263 
266 
267  Positions rval_fixed = rval.original_fixed_positions();
268  Positions rval_muta = rval.original_mutable_positions();
269 
270  Positions iset; // holds the intersections of two sets
271 
272  // check mutable regions do not overlap
273  set_intersection( muta.begin(), muta.end(), rval_muta.begin(), rval_muta.end(),
274  inserter( iset, iset.begin() ) );
275  if ( !iset.empty() ) {
276  TR.Error << "mutable regions intersect; incompatibility!" << std::endl;
277  return false;
278  }
279  iset.clear();
280 
281  // check fixed region and mutable region from right does not overlap
282  set_intersection( fixed.begin(), fixed.end(), rval_muta.begin(), rval_muta.end(),
283  inserter( iset, iset.begin() ) );
284  if ( !iset.empty() ) {
285  TR.Error << "fixed and mutable regions intersect; incompatibility!" << std::endl;
286  return false;
287  }
288  iset.clear();
289 
290  // check fixed regions from right and mutable region does not overlap
291  set_intersection( rval_fixed.begin(), rval_fixed.end(), muta.begin(), muta.end(),
292  inserter( iset, iset.begin() ) );
293  if ( !iset.empty() ) {
294  TR.Error << "mutable and fixed regions intersect; incompatibility!" << std::endl;
295  return false;
296  }
297  iset.clear();
298 
299  return true;
300 }
301 
302 
303 } // namespace build
304 } // namespace forge
305 } // namespace protocols