Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JumpAtom.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 core/kinematics/tree/JumpAtom.cc
11 /// @brief Jump atom
12 /// @author Phil Bradley
13 
14 
15 // Unit headers
17 
18 // Package headers
20 
21 // Project headers
22 #include <core/id/AtomID_Map.hh>
23 #include <core/id/DOF_ID.hh>
24 // AUTO-REMOVED #include <core/id/DOF_ID_Mask.hh>
25 
26 // Numeric headers
27 #include <numeric/xyz.functions.hh>
28 
29 // Utility headers
30 #include <utility/exit.hh>
31 
32 // C++ headers
33 #include <cassert>
34 #include <iostream>
35 
36 #include <core/id/DOF_ID_Map.hh>
37 #include <utility/vector1.hh>
38 
39 
40 
41 namespace core {
42 namespace kinematics {
43 namespace tree {
44 
45 
46 /////////////////////////////////////////////////////////////////////////////
47 /// @details the root jump is not flexible (currently)
48 bool
50  DOF_Type const //type
51 ) const
52 {
53  // the root jump is not flexible (currently)
54  return ( parent() == 0 );
55 }
56 
57 /////////////////////////////////////////////////////////////////////////////
58 /// @note along n2c direction
59 Real
61  DOF_Type const type
62 ) const
63 {
64  int const n2c(1);
65  int const rb_no( get_rb_number( type ) );
66  if ( rb_no == 0 ) {
67  std::cerr << "bad torsion type for JumpAtom: " << type << std::endl;
68  utility_exit();
69  }
70  return jump_.get_rb_delta( rb_no, n2c );
71 }
72 
73 /// @details Invokes Atom_ dfs function (which visits the subtree routed at this node).
74 /// No younger siblings are effected by a DOF change at a JumpAtom.
75 void
77  AtomDOFChangeSet & changeset,
78  ResidueCoordinateChangeList & res_change_list,
79  Size const start_atom_index
80 ) const
81 {
82  Atom_::dfs( changeset, res_change_list, start_atom_index );
83 }
84 
85 /////////////////////////////////////////////////////////////////////////////
86 ///@note along n2c direction
87 void
89  DOF_Type const type,
90  Real const value
91 )
92 {
93  assert( parent() );
94  int const n2c(1);
95  int const rb_no( get_rb_number( type ) );
96  if ( rb_no == 0 ) {
97  std::cerr << "bad torsion type for JumpAtom: " << type << std::endl;
98  utility_exit();
99  }
100  jump_.set_rb_delta( rb_no, n2c, value );
101 }
102 
103 /// @details calls set_dof non-polymorphically: assumption is that JumpAtom is not subclassed,
104 /// or, that if it is, that the derived class implements this overloaded set_dof function.
105 void
107  DOF_Type const type,
108  Real const value,
109  AtomDOFChangeSet & set
110 )
111 {
112  JumpAtom::set_dof( type, value );
113  Atom_::note_dof_change( set );
114 }
115 
116 /////////////////////////////////////////////////////////////////////////////
117 Jump const &
119 {
120  return jump_;
121 }
122 
123 /////////////////////////////////////////////////////////////////////////////
124 void
125 JumpAtom::jump( Jump const & jump_in )
126 {
127  jump_ = jump_in;
128 }
129 
130 /////////////////////////////////////////////////////////////////////////////
131 void
133  Jump const & jump_in,
134  AtomDOFChangeSet & set
135 )
136 {
137  jump_ = jump_in; // could invoke 1-argument jump() method to avoid duplication...
138  Atom_::note_dof_change( set );
139 }
140 
141 
142 /////////////////////////////////////////////////////////////////////////////
143 /// @details copy DOFs, xyz's.
144 /// this asserts equal topology.
145 /// do recursively to copy for all its children
146 void
148  Atom const & src
149 )
150 {
151  jump_ = src.jump();
152 
153  // copy xyz as well as the dof_change_index_
154  Super::operator= ( static_cast< Atom_ const & > ( src ));
155 
156  if ( id() != src.id() || n_children() != src.n_children() ) {
157  std::cerr << "JumpAtom:: copy_coords: topology_mismatch!" <<
158  id() << ' ' << src.id() << ' ' << n_children() << ' ' <<
159  src.n_children() << std::endl;
160  utility_exit();
161  }
162 
163  int i(0);
164  for ( Atoms_Iterator it= atoms_begin(), it_end= atoms_end();
165  it != it_end; ++it, ++i ) {
166  (*it)->copy_coords( *(src.child(i) ) );
167  }
168 }
169 
170 /// @details Relies on get_input_stub, which will use the coordinates of this atom's ancestors to
171 /// build a stub. If this function has been invoked by AtomTree update_xyz_coords(), then these
172 /// coordinates are guaranteed correct, since this atom is the root of a tree which needs to be
173 /// refolded. Ergo, nothing in the tree above this atom needs to be refolded.
174 void
176 {
177  Stub stub( get_input_stub() );
179 }
180 
181 /////////////////////////////////////////////////////////////////////////////
182 /// @details call make_jump to "jump" from parent to this atom.
183 /// Will recursively update xyz positions for all its offspring atoms.
184 /// @note the input stub is not changed
185 void
187  Stub & stub // in fact is const
188 )
189 {
190  assert( stub.is_orthogonal( 1e-3 ) );
191 
192  Stub new_stub;
193  jump_.make_jump( stub, new_stub );
194  position( new_stub.v );
195 
196  //std::cout << "input_stub: " << stub << std::endl;
197  //std::cout << "jump: " << jump_ << std::endl;
198  //std::cout << "stub: " << new_stub << std::endl;
199 
200  for ( Atoms_Iterator it= atoms_begin(), it_end= atoms_end();
201  it != it_end; ++it ) {
202  (*it)->update_xyz_coords( new_stub );
203  }
205 }
206 
207 /////////////////////////////////////////////////////////////////////////////
208 /// @details update the jump from the input stub and this atom's own stub. If defined,
209 /// will recursively update internal coords for all its offspring atoms.
210 /// @note the input stub is not changed
211 void
213  Stub & stub,
214  bool const recursive // = true
215 )
216 {
217  assert( stub.is_orthogonal( 1e-3 ) );
218 
219  Stub new_stub( get_stub() );
220 
221  // fill in my jump data
222  jump_.from_stubs( stub, new_stub );
223 
224  //std::cout << "input_stub: " << stub << std::endl;
225  //std::cout << "jump: " << jump_ << std::endl;
226  //std::cout << "stub: " << new_stub << std::endl;
227 
228 
229  if ( recursive ) {
230  for ( Atoms_Iterator it= atoms_begin(), it_end= atoms_end();
231  it != it_end; ++it ) {
232  (*it)->update_internal_coords( new_stub );
233  }
234  }
235 }
236 
237 /////////////////////////////////////////////////////////////////////////////
238 /// @note this will recursively clone all this atom's offspring atoms
239 AtomOP
240 JumpAtom::clone( AtomAP parent_in, AtomPointer2D & atom_pointer ) const
241 {
242 
243  JumpAtomOP new_me = new JumpAtom(*this);
244  new_me->set_weak_ptr_to_self( new_me() );
245 
246  atom_pointer[ id() ] = new_me;
247 
248  new_me->id( id() );
249  new_me->parent( parent_in );
250 
251  // copy DOFs
252  new_me->jump_ = jump_;
253 
254  // copy coords
255  new_me->position( position() );
256 
257  // copy atoms
258  for ( Atoms_ConstIterator it= atoms_begin(), it_end= atoms_end();
259  it != it_end; ++it ) {
260  new_me->append_atom( (*it)->clone( new_me(), atom_pointer ) );
261  }
262 
263  return new_me;
264 }
265 
266 
267 
268 
269 /////////////////////////////////////////////////////////////////////////////
270 ///@details last torsion is the torsion( Phi for BondedAtom and RB for JumpAtom) of the
271 /// parent atom or the previous bonded sibling. Since unlike BondedAtom, JumpAtom's RB is independent from
272 /// other sibling atoms, this will not modify last_torsion, unlike Atom::setup_min_map.
273 /// recursively done all its offspring
274 void
276  DOF_ID & last_torsion, // const!!!
277  DOF_ID_Mask const & allow_move,
278  MinimizerMapBase & min_map
279 ) const
280 {
281  DOF_ID last_torsion_local( last_torsion );
282 
283  for ( int k=1; k<=6; ++k ) {
284  DOF_Type const & type( id::get_rb_type(k) );
285  DOF_ID rb_torsion( id(), type );
286  if ( allow_move[ rb_torsion ] && !keep_dof_fixed( type ) ) {
287  assert( parent() ); // root DOFs don't move
288  min_map.add_torsion( rb_torsion, last_torsion_local );
289  last_torsion_local = rb_torsion;
290  }
291  }
292 
293  // add me to the min_map
294  min_map.add_atom( id(), last_torsion_local );
295 
296  for ( Atoms_ConstIterator it= atoms_begin(), it_end= atoms_end();
297  it != it_end; ++it ) {
298  (*it)->setup_min_map( last_torsion_local, allow_move, min_map );
299  }
300 }
301 
302 
303 /////////////////////////////////////////////////////////////////////////////
304 ///@li axis is the unit vector along the rotation axis for that DOF(Eab).
305 ///2li end_pos is the ending point of this unit vector(Vb).
306 ///
307 ///@details RB1, RB2 and RB3 are translation along x, y and z axis in the jump_start
308 ///(input_stub) frame, which are input_stub.col(1), input_stub.col(2) and
309 ///input_stub.col(3).\n
310 ///RB4, RB5 and RB6 are rotations along x, y and z axis in the input_stub frame, and
311 ///the rotation is applied around the point of "rb_center" written in the jump_end
312 ///(my_stub) frame. So "end_pos"for these 3 DOFs is the rb_center rewritten in xyz
313 ///frame, which is my_stub.V+my_stub.M*rb_center. The axis is not simply x, y and z
314 ///in the input_stub because these 3 DOFs are not independently applied. Here are how
315 ///they are derived (by me and there might be other smarter way to think of it):
316 ///
317 ///@li the jump rotation matrix is R = Rz(RB6) * Ry(RB5) * Rx(RB4) * rt.rotation.
318 ///
319 ///@li if RB6 is perturbed by "d", the new rotation matrix is R' = Rz(d+RB6) * Ry(RB5) * Rx(RB4) * rt.rotation
320 /// = Rz(d) * Rz(RB6) * Ry(RB5) * Rx(RB4) * rt.rotation = Rz(d) * R. This is to say perturbing RB6 by d is equivalent
321 /// to making an extra rotation around Z axis in the input_stub frame and therefore the axis is just input_stub.col(3).
322 ///
323 ///@li if RB5 is perturbed by "d", the new rotation matrix is R' = Rz(RB6) * Ry(d+RB5) * Rx(RB4) * rt.rotation
324 /// = Rz(RB6) * Ry(d) * Ry(RB5) * Rx(RB4) * rt.rotation = Rz(RB6) * Ry(d) * Rz(RB6)^ * R. This is to say perturbing
325 /// RB5 by d is equivalent to making an extra rotation Rz(RB6) * Ry(d) * Rz(RB6)^ in the input_stub frame and
326 /// the axis of rotation is the one we try to get. what is it? Remember this rotation matrix is in the context of
327 /// the input_stub frame M, so rewritting it in the xyz lab frame results in M * Rz(RB6) * Ry(d) * Rz(RB6)^ * M^. Since
328 /// for matrices (A*B)^ = B^ * A^, we get (M *Rz(RB6)) * Ry(d) * (M * Rz(RB6))^ and this is eqivanelent to making
329 /// a rotation around y axis in the frame of (M *Rz(RB6)) and therefore the axis is (input_stub.M * Z_rotation ).col(2)
330 ///
331 ///@li similarly, one can the axis for a perturbation to RB4 DOF.
332 void
334  Vector & axis,
335  Position & end_pos,
336  DOF_Type const type
337 ) const
338 {
339  using numeric::y_rotation_matrix_degrees;
340  using numeric::z_rotation_matrix_degrees;
341 
342  Stub input_stub( get_input_stub() );
343  int const rb_no( get_rb_number( type ) );
344  if ( rb_no <= 3 ) {
345  axis = input_stub.M.col( rb_no );
346  } else {
347  Stub my_stub( get_stub() );
348 
349  int const n2c( 1 );
350  utility::vector1< Real > const & rb_delta( jump_.get_rb_delta( n2c ) );
351  numeric::xyzVector< Real > const & rb_center( jump_.get_rb_center( n2c ));
352 
353  end_pos = my_stub.v + my_stub.M * rb_center;
354 
355  if ( type == id::RB6 ) {
356  axis = input_stub.M.col(3);
357  } else if ( type == id::RB5 ) {
358  Real const theta_z = rb_delta[6];
359  axis = ( input_stub.M * z_rotation_matrix_degrees( theta_z ) ).col(2);
360  } else if ( type == id::RB4 ) {
361  Real const theta_z = rb_delta[6], theta_y = rb_delta[5];
362  axis = ( input_stub.M * z_rotation_matrix_degrees( theta_z ) *
363  y_rotation_matrix_degrees( theta_y ) ).col(1);
364  } else {
365  std::cerr << "Bad torsion type for Atom" << type << std::endl;
366  utility_exit();
367  }
368  }
369 }
370 
371 
372 }
373 } // namespace kinematics
374 } // namespace core