Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Jump.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/Jump.cc
11 /// @brief Kinematics Jump class
12 /// @author Phil Bradley
13 
14 
15 // Unit headers
16 #include <core/kinematics/Jump.hh>
17 
18 // Package headers
19 #include <core/kinematics/Stub.hh>
20 
21 // AUTO-REMOVED #include <basic/Tracer.hh>
22 
23 // Rosetta Headers
24 // #include "jump_classes.h"
25 // #include "angles.h"
26 // #include "FArray_xyz_functions.h"
27 // #include "jumping_util.h"
28 // #include "param.h"
29 // #include "pose.h"
30 // #include "random_numbers.h"
31 // #include "util_vector.h" // Ddotprod, etc
32 
33 // Numeric Headers
34 #include <numeric/conversions.hh>
35 #include <numeric/random/random.hh>
36 #include <numeric/trig.functions.hh>
37 #include <numeric/xyz.functions.hh>
38 // AUTO-REMOVED #include <numeric/xyzVector.io.hh>
39 
40 // C++ Headers
41 #include <iostream>
42 #include <string>
43 
44 #include <utility/vector1.hh>
45 
46 
47 
48 namespace core {
49 namespace kinematics {
50 
51 static numeric::random::RandomGenerator jump_RG(62454); // <- Magic number, do not change it!!!
52 
53 //static const utility::vector1<double> ZERO( 6, 0.0 );
54 
55 ///////////////////////////////////////////////////////////////////////////////
56 // reset
57 void
59 {
60  rt_.reset();
61  rb_delta[1] = rb_delta[2] = ZERO;
62  rb_center[1] = rb_center[2] = Vector(0.0);
63 }
64 
65 
66 ///////////////////////////////////////////////////////////////////////////////
67 bool
69 {
70  return rt_.ortho_check();
71 }
72 
73 
74 ///////////////////////////////////////////////////////////////////////////////
75 void
77 {
78  // n2c
80  rt_.reverse();
81 
82  // c2n
84  rt_.reverse();
85 
86  rb_delta[1] = rb_delta[2] = ZERO;
87 }
88 ///////////////////////////////////////////////////////////////////////////////
89 /// @details stub defines the local reference frame for the corresponding direction
90 /// of the jump (forward == folding direction, backward = reverse)
91 /// by which to transform center\n
92 /// center is an xyz position in the absolute (protein) reference frame\n
93 /// the column vectors of stub are unit vectors defined in the
94 /// absolute reference frame( the frame in which center is defined)\n
95 /// so left-multiplying by stub.M.transposed() puts an absolute ref
96 /// frame vector (like center) into the local jump reference frame\n
97 /// dir is the direction through the jump,
98 /// 1 == forward == folding order,
99 /// -1 == backward == reverse folding order\n
100 /// if dir == 1, the stub should be the stub for the downstream
101 /// jump atom, (eg returned by "folder.downstream_jump_stub( jump_number )" or
102 /// "downstream_jump_atom.get_stub()" )
103 /// and the center is the center of rotation for the
104 /// downstream segment (ie the segment which is built later during folding).
105 /// The center determines how the forward rb_deltas
106 /// are interpreted, and is the center for rigid-body rotation during
107 /// minimization.\n
108 /// if dir == -1, the stub should be the stub for the upstream
109 /// jump atom, (eg returned by folder.upstream_jump_stub( jump_number ) )
110 /// and the center is the center of rotation for the
111 /// upstream segment. The center determines how the reverse rb_deltas
112 /// are interpreted, eg in perturbation moves when we modify the
113 /// reverse rb-deltas directly, eg in the call
114 /// "Jump::gaussian_move(-1,tmag,rmag)"\n
115 ///
116 void
118  const int dir,
119  Stub const & stub,
120  Vector const & center
121 )
122 {
124  int const index( dir == 1 ? 1 : 2 );
125  rb_center[index] = stub.M.transposed() * ( center - stub.v );
126 }
127 ///////////////////////////////////////////////////////////////////////////////
128 bool
130 {
131  const Real tol(1.0e-3);
132  Real sum(0.0);
133  for ( int i=1; i<=2; ++i ) {
134  for ( int j=1; j<= 6; ++j ) {
135  sum += std::abs( rb_delta[i][j] );
136  }
137  }
138  return ( sum > tol );
139 }
140 
141 
142 ///////////////////////////////////////////////////////////////////////////////
143 /// @details choose a random unit vector as the direction of translation,
144 /// by selecting its spherical coordinates phi(0-180) and theta(0-360)
145 /// then move dist_in along that direction
146 void
147 Jump::random_trans( const float dist_in )
148 {
149 
150  using numeric::y_rotation_matrix_degrees;
151  using numeric::z_rotation_matrix_degrees;
152  using numeric::conversions::degrees;
153  using numeric::sin_cos_range;
154 
155  const Real theta( 360.0 * jump_RG.uniform());
156  const Real phi( degrees( std::acos(sin_cos_range(1.0-2.0*jump_RG.uniform()))));
157  const Real dist( dist_in );
158 
160  rt_.set_translation( dist * (
161  y_rotation_matrix_degrees(phi) *
162  z_rotation_matrix_degrees(theta) ).col_z() );
163 }
164 
165 ///////////////////////////////////////////////////////////////////////////////
166 /// @details clear existing rb_delta first if any and then apply the gaussian move
167 /// Return the move that was applied.
169 Jump::gaussian_move(int const dir, float const trans_mag, float const rot_mag) {
170  fold_in_rb_deltas(); // clear rb_delta
171  for ( int i = 1; i <= 3; ++i ) {
172  set_rb_delta( i, dir, Real( trans_mag * jump_RG.gaussian() ) );
173  set_rb_delta( i+3, dir, Real( rot_mag * jump_RG.gaussian() ) );
174  }
175  utility::vector1<Real> this_rb_delta = get_rb_delta(dir);
177  return this_rb_delta;
178 }
179 
180 /// @details do a gaussian move along a certain rb direction
181 void
183  int const dir,
184  float const mag,
185  int rb
186 )
187 {
188  fold_in_rb_deltas(); // clear rb_delta
189  set_rb_delta( rb, dir, Real( mag * jump_RG.gaussian() ) );
191 }
192 
193 ///////////////////////////////////////////////////////////////////////////////
194 // set rb_delta
195 void
197  int const rb_no,
198  int const dir,
199  Real const value
200 )
201 {
202  rb_delta[ rb_index(dir) ][rb_no] = value;
203 }
204 
205 /// @brief set rb_deltas by direction
206 void
207 Jump::set_rb_deltas( int const dir, utility::vector1<Real> const & rb_deltas){
208  rb_delta[ rb_index(dir) ] = rb_deltas;
209 }
210 
211 
212 ///////////////////////////////////////////////////////////////////////////////
213 void
215  Matrix const & R
216 )
217 {
218  fold_in_rb_deltas(); // clear rb_delta
219  rt_.set_rotation( R );
220 }
221 
222 
223 ///////////////////////////////////////////////////////////////////////////////
224 void
226  Vector const & t
227 )
228 {
229  fold_in_rb_deltas(); // clear rb_delta
230  rt_.set_translation( t );
231 }
232 
233 
234 ///////////////////////////////////////////////////////////////////////////////
235 /// @details stub should be the Stub of the upstream jump.
236 /// This routine has the effect (I think) of rotating the downstream stub
237 /// by the rotation "matrix" about the center "center", both of which are written
238 /// in xyz lab frame.
239 void
241  Stub const & stub,
242  Vector const & center, //in xyz (absolute- or protein-reference-) frame
243  Matrix const & matrix //in xyz frame
244 )
245 {
246  fold_in_rb_deltas(); // clear rb_delta
247 
248  Matrix const & m( stub.M );
249 
250  // find the rotation center in jump coordinate system
251  Vector new_center = m.transposed() * ( center - stub.v);
252 
253  // find the operator matrix when transofrmed to jump coord system
254  Matrix new_matrix = m.transposed() * ( matrix * m );
255 
256  // new translation vector after applying matrix in jump coord system
257  rt_.set_translation( new_center + new_matrix * ( rt_.get_translation() -
258  new_center ) );
259 
260  // new rotation after applying matrix in jump coord system
261  rt_.set_rotation( new_matrix * rt_.get_rotation() );
262 }
263 
264 ////////////////////////////////////////////////////////////////////////////////
265 /// @details stub should be the Stub of the upstream jump.
266 /// this does a rotation by alpha degrees around the specified
267 /// the axis and center, both of which are written in xyz frame
268 void
270  Stub const & stub,
271  Vector const & axis,
272  Vector const & center, //in xyz frame
273  float const alpha ///< degrees
274 )
275 {
276  using numeric::conversions::radians;
277 
279  Matrix mat = numeric::rotation_matrix( axis, Real( radians( alpha ) ) );
280  rotation_by_matrix( stub, center, mat );
281 }
282 
283 
284 ///////////////////////////////////////////////////////////////////////////////
285 /// @details stub should be the Stub of the upstream jump.
286 /// this does a translation along the axis by dist.
287 /// the axis is written in xyz frame
288 
289 void
291  Stub const & stub,
292  Vector const & axis, //in xyz frame
293  float const dist // in angstrom
294 )
295 {
297  Vector new_trans( Real(dist) * axis.normalized() );
298  rt_.set_translation( rt_.get_translation() + stub.M.transposed()*new_trans );
299 }
300 
301 
302 ///////////////////////////////////////////////////////////////////////////////
303 ///
304 void
306 {
308  rt_.reverse();
309 }
310 
311 ///////////////////////////////////////////////////////////////////////////////
312 ///
313 Jump
315 {
316  Jump ret_val( *this );
317  ret_val.fold_in_rb_deltas();
318  ret_val.reverse();
319  return ret_val;
320 }
321 
322 ///////////////////////////////////////////////////////////////////////////////
323 void
325 {
326  rb_delta[1] = rb_delta[2] = ZERO;
327  rb_center[1] = rb_center[2] = Vector(0.0);
329 }
330 
331 
332 ///////////////////////////////////////////////////////////////////////////////
333 /// @details fold all the rb_delta first and then make the jump.
334 /// make jump with stubs instead of FArrays
335 void
337  Stub const & stub1,
338  Stub & stub2
339 ) const
340 {
341  // make temporary local copy of our rotation-translation
342  RT tmp_rt(rt_);
343 
344  // n2c
345  tmp_rt.fold_in_rb_deltas( rb_delta[1], rb_center[1] );
346  tmp_rt.reverse();
347 
348  // c2n
349  tmp_rt.fold_in_rb_deltas( rb_delta[2], rb_center[2] );
350 
351  // back to original direction
352  tmp_rt.reverse();
353 
354  tmp_rt.make_jump( stub1, stub2 );
355 }
356 
357 
358 ///////////////////////////////////////////////////////////////////////////////
359 ///@note: we dont reset rb_center!!!!!!!!!
360 void
362  Stub const & stub1,
363  Stub const & stub2
364 )
365 {
366  rt_.from_stubs( stub1, stub2 );
367  rb_delta[1] = rb_delta[2] = ZERO;
368 }
369 
370 ///////////////////////////////////////////////////////////////////////////////
371 ///@details this function translate a virtual bond type constraints into jump
372 ///transformation.
373 ///in atoms vector, A1, A2, A3, B1, B2, B3,
374 ///and A1-B1 forms the virtual bond, like A3-A2-A1---B1-B2-B3
375 ///in csts vector, disAB, angleA and B, didedral A, AB and B.
376 ///B1, B2 and B3 are moved given cst definition.
377 void
380  utility::vector1< Real > const & csts
381 )
382 {
383  assert( atoms.size() == 6 && csts.size() == 6 );
384  // make sure A3-A2-A1 or B3-B2-B1 is not linear (i.e., a stub can be defined)
385  Stub stubA(atoms[1], atoms[2], atoms[3]); // a1, a2, a3
386  Stub stubB(atoms[4], atoms[5], atoms[6]); // b1, b2, b3
387  assert( stubA.is_orthogonal(1e-3) && stubB.is_orthogonal(1e-3) );
388  // udpate B1, B2, B3 positions
389  Vector b1 = stubA.spherical( csts[4]/*dihedralA*/, csts[2]/*angleA*/, csts[1]/*disAB*/ );
390  Stub stub_b1( b1, atoms[1], atoms[2]); // b1, a1, a2
391  assert(stub_b1.is_orthogonal(1e-3));
392  Vector b2 = stub_b1.spherical( csts[5]/*dihedralAB*/, csts[3]/*angleB*/, atoms[4].distance(atoms[5]) );
393  Stub stub_b2( b2, b1, atoms[1]); // b2, b1, a1
394  assert(stub_b2.is_orthogonal(1e-3));
395  Vector b3 = stub_b2.spherical( csts[6]/*dihedralB*/, angle_of(atoms[4], atoms[5], atoms[6]), atoms[5].distance( atoms[6] ) );
396  // update new b1, b2, b3 and get new RT
397  Stub new_stubB(b1,b2,b3);
398  assert( new_stubB.is_orthogonal(1e-3) );
399  rt_.from_stubs( stubA, new_stubB );
400  rb_delta[1] = rb_delta[2] = ZERO;
401  atoms[4] = b1;
402  atoms[5] = b2;
403  atoms[6] = b3;
404  return;
405 }
406 ///////////////////////////////////////////////////////////////////////////////
407 // input
408 std::istream &
410  std::istream & is,
411  Jump & jump
412 )
413 {
414  is >> jump.rt_;
415  jump.rb_delta[1] = jump.rb_delta[2] = ZERO;
416  jump.rb_center[1] = jump.rb_center[2] = Jump::Vector( 0.0 );
417  return is;
418 }
419 
420 
421 ///////////////////////////////////////////////////////////////////////////////
422 // stream output:
423 std::ostream&
425  std::ostream & os,
426  const Jump & jump
427 )
428 {
429  if ( jump.nonzero_deltas() ) {
430  // old-style verbose output
431  os << "Jump:: nonzero_deltas= " << jump.nonzero_deltas() << '\n';
432  os << jump.rt_;
433  for ( int i = 1; i <= 2; ++i ) {
434  std::string tag ( (i==1) ? "n2c" : "c2n" );
435  os << "rb_delta " << tag;
436  for ( int j = 1; j <= 6; ++j ) {
437  //os << F(9,3,jump.rb_delta(j,i));
438  os << jump.rb_delta[i][j] << ' '; //chu -- more digits for precision
439  }
440  os << '\n';
441  os << "rb_center " << tag;
442  for ( int j = 1; j <= 3; ++j ) {
443  os << jump.rb_center[i][j] << ' ';
444  }
445  os << '\n';
446  }
447  } else {
448  //
449  os << jump.rt_;
450  }
451  return os;
452 }
453 
454 ///////////////////////////////////////////////////////////////////////////////
455 Real
457  Jump const & a_in,
458  Jump const & b_in
459 )
460 {
461 
462  Jump a( a_in ), b( b_in );
463 
464  a.fold_in_rb_deltas();
465  b.fold_in_rb_deltas();
466 
467  return distance( a.rt_, b.rt_ );
468 }
469 
470 
471 ///////////////////////////////////////////////////////////////////////////////
472 void
474  Jump const & a_in,
475  Jump const & b_in,
476  Real & dist,
477  Real & theta
478 )
479 {
480 
481  Jump a( a_in ), b( b_in );
482 
483  a.fold_in_rb_deltas();
484  b.fold_in_rb_deltas();
485 
486  Jump::Matrix A( a.get_rotation() );
487  Jump::Vector v( a.get_translation() );
488 
489  Jump::Matrix B( b.get_rotation() );
490  Jump::Vector w( b.get_translation() );
491 
492  //Real theta; // in radians
493  // A * B^-1 = rotation to make A==B.
494  rotation_axis( A * B.transposed(), theta );
495 
496  dist = v.distance(w);
497 
498  //return distance( v, w ) + theta;
499 }
500 
501 RT Jump::rt() const {
502  if ( !nonzero_deltas() ) {
503  return rt_;
504  } else {
505  Jump tmp( *this );
506  tmp.fold_in_rb_deltas();
507  return tmp.rt_;
508  }
509 }
510 
511 } // namespace kinematics
512 } // namespace core