Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ConnectRight.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/build/ConnectRight.cc
11 /// @brief instruction to connect one Pose onto the right side of another
12 /// @author Yih-En Andrew Ban (yab@u.washington.edu)
13 
14 // unit headers
16 
17 // package headers
20 
21 // rosetta headers
22 #include <core/id/AtomID.hh>
27 #include <core/pose/PDBInfo.hh>
28 #include <core/pose/util.hh>
29 
30 // C++ headers
31 #include <limits>
32 
33 #include <utility/vector1.hh>
34 
35 
36 
37 namespace protocols {
38 namespace forge {
39 namespace build {
40 
41 
42 /// @brief default constructor
44  Super( Interval( 0, 0 ) ),
45  left_position_( 0 ),
46  right_position_( 0 ),
47  use_rt_( false ),
48  interval_( 0, 0 )
49 {
50  init();
51 }
52 
53 
54 /// @brief position to position jump constructor
55 /// @param[in] left_position connect at this position on 'pose_left'
56 /// passed into modify()
57 /// @param[in] right_position connect at this position on 'pose_right'
58 /// @param[in] pose_right connect this pose to the right of pose_left when
59 /// modify( pose_left ) is called
60 /// @param[in] start_new_chain start new chain when connecting? does not
61 /// handle termini variants
63  Size const left_position,
64  Size const right_position,
65  Pose const & pose_right
66 ) :
67  Super( Interval( left_position, left_position ), &pose_right.residue( 1 ).residue_type_set() ),
68  left_position_( left_position ),
69  right_position_( right_position ),
70  pose_right_( pose_right ),
71  use_rt_( false ),
72  interval_( 1, pose_right.n_residue() )
73 {
74  init();
75 }
76 
77 
78 /// @brief copy constructor
80  Super( rval ),
81  left_position_( rval.left_position_ ),
82  right_position_( rval.right_position_ ),
83  pose_right_( rval.pose_right_ ),
84  use_rt_( rval.use_rt_ ),
85  left_stub_atoms_( rval.left_stub_atoms_ ),
86  right_stub_atoms_( rval.right_stub_atoms_ ),
87  rt_( rval.rt_ ),
88  interval_( rval.interval_ )
89 {}
90 
91 
92 /// @brief default destructor
94 
95 
96 /// @brief copy assignment
98  if ( this != &rval ) {
99  Super::operator =( rval );
100 
103  pose_right_ = rval.pose_right_;
104  use_rt_ = rval.use_rt_;
107  rt_ = rval.rt_;
108  interval_ = rval.interval_;
109  }
110  return *this;
111 }
112 
113 
114 /// @brief clone this object
116  return new ConnectRight( *this );
117 }
118 
119 
120 /// @brief connect this pose to the right of pose_left when modify( pose_left )
121 /// is called
123  return pose_right_;
124 }
125 
126 
127 /// @brief return a copy of the set of positions within the new region
128 /// that were pre-existing in the original Pose prior to modify()
129 /// @return An empty set -- no positions are pre-existing.
131  return Positions();
132 }
133 
134 
135 /// @brief return a copy of the set of positions that are "new" and did
136 /// not exist in the original Pose.
137 /// @return A set spanning the entire interval -- all positions are new.
140 
141  Interval const ival = interval();
142  return closed_range( ival.left, ival.right );
143 }
144 
145 
146 /// @brief return a copy of the set of positions within the newly modified
147 /// region that has a defined conformation. E.g. existing or copied residues.
148 /// @return A set spanning the entire interval -- all positions are defined.
149 /// @details This set can change wrt length changes in Pose/Conformation being
150 /// watched.
152  // for ConnectRight this is the same as the new positions
153  return new_positions();
154 }
155 
156 
157 /// @brief return a copy of the set of positions within the newly modified
158 /// region that has an undefined conformation. E.g. newly created residues.
159 /// @return An empty set -- no undefined positions.
160 /// @details This set can change wrt length changes in Pose/Conformation being
161 /// watched.
163  return Positions();
164 }
165 
166 
167 /// @brief return a copy of the MoveMap that defines the moveable/fixed
168 /// positions/dofs for this instruction
169 /// @return a MoveMap with [interval.left, interval.right] bb set to false
170 /// at the MoveMapTorsionID level
171 /// @details This set can change wrt length changes in Pose/Conformation being
172 /// watched.
174  MoveMap mm;
175 
176  Positions const newp = new_positions();
177  for ( Positions::const_iterator i = newp.begin(), ie = newp.end(); i != ie; ++i ) {
178  mm.set_bb( *i, false );
179  }
180 
181  return mm;
182 }
183 
184 
185 /// @brief extract appropriately computed transform between two stubs that
186 /// represent a jump in the given Pose between the two residues and set it
187 /// as the rt for this ConnectRight
188 /// @param[in] pose The Pose to use.
189 /// @param[in] jump_start_residue The starting residue of the jump.
190 /// This residue should be the equivalent of the jump position on pose_left.
191 /// @param[in] jump_stop-residue The stopping residue of the jump.
192 /// This residue should be the equivalent of the jump position on pose_right.
193 /// @remarks Uses left_stub_atoms() and right_stub_atoms() as the stub atoms
194 /// to compute the transform. Remember to set use_rt() to True after
195 /// calling this function if you want to actually use the transform
196 /// during modify().
198  Pose const & pose,
199  Size const jump_start_residue,
200  Size const jump_stop_residue
201 )
202 {
203  using core::id::StubID;
204 
205  assert( jump_start_residue != jump_stop_residue );
206  assert( jump_start_residue <= pose.n_residue() );
207  assert( jump_stop_residue <= pose.n_residue() );
208 
209  StubID left_stub_id( core::pose::named_stub_id_to_stub_id( left_named_stub_id( jump_start_residue ), pose ) );
210  StubID right_stub_id( core::pose::named_stub_id_to_stub_id( right_named_stub_id( jump_stop_residue ), pose ) );
211 
212  rt_ = pose.conformation().get_stub_transform( left_stub_id, right_stub_id );
213 }
214 
215 
216 /// @brief update indexing on residue append
218  if ( event.position < left_position_ ) {
219  //++left_position_;
220  left_position_ = left_position_ + event.length_change;
221  }
222 
223  if ( modify_was_successful() && event.position < interval_.left ) {
224  //++interval_.left;
225  //++interval_.right;
226  interval_.left = interval_.left + event.length_change;
227  interval_.right = interval_.right + event.length_change;
228  }
229 }
230 
231 
232 /// @brief update indexing on residue prepend
234  if ( event.position <= left_position_ ) {
235  //++left_position_;
236  left_position_ = left_position_ + event.length_change;
237  }
238 
239  if ( modify_was_successful() && event.position <= interval_.left ) {
240  //++interval_.left;
241  //++interval_.right;
242  interval_.left = interval_.left + event.length_change;
243  interval_.right = interval_.right + event.length_change;
244 
245  }
246 }
247 
248 
249 /// @brief update indexing on residue delete
251  assert( event.position != left_position_ );
252  if ( event.position < left_position_ ) {
253  //--left_position_;
254  if( int(left_position_) + event.length_change < int(event.position) ) left_position_ = event.position;
255  else left_position_ = left_position_ + event.length_change;
256  }
257 
258  if ( modify_was_successful() && event.position < interval_.left ) {
259  //--interval_.left;
260  //--interval_.right;
261  if( int(interval_.left) + event.length_change < int(event.position) ){
262  interval_.right = interval_.right - (interval_.left - event.position);
263  interval_.left = event.position;
264  }
265  else{
266  interval_.left = interval_.left + event.length_change;
267  interval_.right = interval_.right + event.length_change;
268  }
269  }
270 }
271 
272 
273 /// @brief return the set of positions within the original interval that
274 /// will be kept in this BuildInstruction
275 /// @return An empty set -- no positions are kept.
277  return Positions();
278 }
279 
280 
281 /// @brief return set of positions within the original interval that will
282 /// be deleted in this BuildInstruction
283 /// @return An empty set -- no positions are deleted.
285  return Positions();
286 }
287 
288 
289 /// @brief return set of any fixed positions necessary with respect to the original
290 /// interval and original Pose numbering
291 /// @remarks Used for ensuring build regions for instructions do not overlap and
292 /// so that jumps may be placed correctly.
293 /// @return empty set if no fixed positions
295  Positions fixed;
296  fixed.insert( original_interval().left );
297  return fixed;
298 }
299 
300 
301 /// @brief return set of any mutable positions necessary with respect to the original
302 /// interval and original Pose numbering
303 /// @remarks Used for ensuring build regions for instructions do not overlap and
304 /// so that jumps may be placed correctly.
305 /// @return empty set if no mutable positions
307  return Positions();
308 }
309 
310 
311 /// @brief do the actual work of modifying the Pose
312 void ConnectRight::modify_impl( Pose & pose_left ) {
313  using core::id::StubID;
316  using core::pose::PDBInfo;
318 
319  // cache data
320  Size const original_left_nres = pose_left.n_residue();
321 
322  // construct fold tree
323  FoldTree new_ft = merge( pose_left.fold_tree(), left_position_, pose_right_.fold_tree(), right_position_ );
324 
325  // BEGIN POSE MODIFY: after this point conformation of pose_left is modified
326 
327  // Create [pose_left, pose_right] by attaching all pose_right residues via jump.
328  core::Size current_chain = std::numeric_limits< int >::min();
329 
330  // if the last residue of pose_left is not an upper terminus and the first
331  // residue of pose_right is not a lower terminus, then assume that we're
332  // not starting a new chain
333  if (
334  !pose_left.residue( original_left_nres ).is_upper_terminus() &&
336  )
337  {
338  current_chain = pose_right_.residue( 1 ).chain();
339  }
340 
341  // Doing the copy with append_residue_by_jump currently appears to be pretty
342  // expensive. However, it's probably the safest way since we might be
343  // dealing with Poses that might be "non-standard/weird" vs regular
344  // polymeric (protein/dna/rna) Poses.
345  for ( Size i = 1, ie = pose_right_.n_residue(); i <= ie; ++i ) {
346  if ( pose_right_.residue( i ).chain() != current_chain ) {
347  current_chain = pose_right_.residue( i ).chain();
348  pose_left.append_residue_by_jump( pose_right_.residue( i ), pose_left.n_residue(), "", "", true );
349  } else {
350  pose_left.append_residue_by_jump( pose_right_.residue( i ), pose_left.n_residue(), "", "", false );
351  }
352  }
353 
354  // set correct topology
355  pose_left.fold_tree( new_ft );
356 
357  // MIDDLE POSE MODIFY: after this point non-conformation info of pose_left
358  // is modified
359 
360  // transfer sec.struct
361  for ( Size i = 1, ie = pose_right_.n_residue(); i <= ie; ++i ) {
362  pose_left.set_secstruct( i + original_left_nres, pose_right_.secstruct( i ) );
363  }
364 
365  // Handle PDBInfo separately. PDBInfo in pose_left
366  // should always be obsolete after leaving modify_impl()
367  // as a safety.
368  if ( pose_right_.pdb_info().get() != NULL ) {
369 
370  // if pose_left doesn't have PDBInfo, create it
371  if ( pose_left.pdb_info().get() == NULL ) {
372  pose_left.pdb_info( new PDBInfo( pose_left ) );
373  }
374 
375  // force obsolete
376  pose_left.pdb_info()->obsolete( true );
377 
378  // copy all residue information
379  pose_left.pdb_info()->copy( *pose_right_.pdb_info(), 1, pose_right_.n_residue(), original_left_nres + 1 );
380  }
381 
382  assert( pose_left.n_residue() == original_left_nres + pose_right_.n_residue() );
383 
384  // END POSE MODIFY: after this point pose_left is static
385 
386  // store correct interval_
387  interval_ = Interval( 1 + original_left_nres, pose_right_.n_residue() + original_left_nres );
388 
389  // set the jump only if requested
390  if ( use_rt_ ) {
391  pose_left.conformation().set_stub_transform(
393  StubID( core::pose::named_stub_id_to_stub_id( right_named_stub_id( right_position_ + original_left_nres ), pose_left ) ),
394  rt_
395  );
396  }
397 }
398 
399 
400 /// @brief do the actual reset of intervals, positions, etc to initial state
403  // right_position_ is never modified, so no reset necessary
405 }
406 
407 
408 /// @brief initialization on construction
410  left_stub_atoms_.push_back( "CA" );
411  left_stub_atoms_.push_back( "N" );
412  left_stub_atoms_.push_back( "CA" );
413  left_stub_atoms_.push_back( "C" );
414 
415  right_stub_atoms_.push_back( "CA" );
416  right_stub_atoms_.push_back( "N" );
417  right_stub_atoms_.push_back( "CA" );
418  right_stub_atoms_.push_back( "C" );
419 
420  assert( left_stub_atoms_.size() == 4 );
421  assert( right_stub_atoms_.size() == 4 );
422 }
423 
424 
425 } // namespace build
426 } // namespace forge
427 } // namespace protocols