Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RBSegmentMover.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
11 /// @brief
12 /// @author Frank DiMaio
13 /// @author Srivatsan Raman
15 // AUTO-REMOVED #include <protocols/rbsegment_relax/util.hh>
16 
17 // Rosetta Headers
18 #include <core/pose/Pose.hh>
20 // AUTO-REMOVED #include <core/conformation/ResidueFactory.hh>
21 
22 // AUTO-REMOVED #include <core/kinematics/FoldTree.hh>
23 
24 // AUTO-REMOVED #include <core/scoring/constraints/Constraint.hh>
25 // AUTO-REMOVED #include <core/scoring/constraints/BoundConstraint.hh>
26 // AUTO-REMOVED #include <core/scoring/constraints/CoordinateConstraint.hh>
27 // AUTO-REMOVED #include <core/scoring/constraints/AmbiguousConstraint.hh>
28 // AUTO-REMOVED #include <core/scoring/constraints/ConstraintSet.hh>
30 // AUTO-REMOVED #include <core/chemical/ChemicalManager.hh>
31 // AUTO-REMOVED #include <core/chemical/ResidueTypeSet.hh>
32 // AUTO-REMOVED #include <core/kinematics/MoveMap.hh>
33 // AUTO-REMOVED #include <basic/basic.hh>
34 #include <basic/Tracer.hh>
35 
36 // Random number generator
37 // AUTO-REMOVED #include <numeric/xyzVector.io.hh>
38 #include <numeric/xyz.functions.hh>
39 #include <numeric/random/random.hh>
40 // AUTO-REMOVED #include <ObjexxFCL/FArray1D.hh>
41 
42 //
43 #include <string>
44 
45 #include <core/id/AtomID.hh>
46 #include <utility/vector1.hh>
47 
48 
49 namespace protocols {
50 namespace rbsegment_relax {
51 
52 using namespace core;
53 
54 static numeric::random::RandomGenerator rbseg_RG(18632);
55 static basic::Tracer TR("protocols::moves::RBSegmentMover");
56 
59  return "RBSegmentMover";
60 }
61 
63 
64 
65 /// @brief Helper function to get a coordinate transformation from 3 points:
66 /// the origin, a point specifying the +z axis, and a point specifying the x-z plane
70  numeric::xyzVector< Real > xzPlane ) {
71  numeric::xyzVector< Real > xDir, yDir, zDir;
73 
74  zDir = zAxis - ori;
75  zDir.normalize();
76 
77  xDir = xzPlane - ori;
78  xDir.project_normal(zDir);
79  xDir.normalize();
80 
81  yDir = zDir.cross(xDir);
82 
83  trans.col_x(xDir);
84  trans.col_y(yDir);
85  trans.col_z(zDir);
86 
87  return trans;
88 }
89 
91  numeric::xyzVector< Real > CoM( 0, 0, 0 );
92  int N = 0;
93 
94  for (Size i=1; i<=segment_.nContinuousSegments(); ++i) {
95  // apply to transformation to every atom in this segment
96  Size i_start = std::max(segment_[i].start(), (Size)1);
97  Size i_end = std::min(segment_[i].end(), pose.total_residue());
98 
99  for ( Size j = i_start; j <= i_end; ++j ) {
100  CoM += pose.residue(j).xyz("CA");
101  N++;
102  }
103  }
104  CoM = CoM * (1.0/N);
105 
106  return CoM;
107 }
108 
109 
110 
111 /// @brief Apply an arbitrary rotation specified by a rotation matrix
113  // get transformation
115  numeric::xyzMatrix< Real > local2global, global2local;
116 
117  getCoordinateTransformation( pose, origin, local2global);
118  global2local = numeric::inverse( local2global );
119 
122 
123  numeric::xyzVector< Real > localX, localRX, globalRX;
124  for (Size i=1; i<=segment_.nContinuousSegments(); ++i) {
125  // apply to transformation to every atom in this segment
126  Size i_start = std::max(segment_[i].start(), (Size)1);
127  Size i_end = std::min(segment_[i].end() , pose.total_residue());
128 
129  for ( Size j = i_start; j <= i_end; ++j ) {
130  for ( Size k = 1; k <= pose.residue(j).natoms(); ++k ) {
131  id::AtomID id( k, j );
132  localX = global2local * ( pose.xyz(id) - origin );
133  localRX = rotation * localX;
134  globalRX = local2global * localRX + origin;
135 
136  //pose.set_xyz( id, globalRX );
137  atm_ids.push_back( id );
138  atm_xyzs.push_back( globalRX );
139  }
140  }
141  }
142  pose.batch_set_xyz( atm_ids, atm_xyzs );
143 }
144 
145 /// @brief Apply an arbitrary translation
147  // get transformation
149  numeric::xyzMatrix< Real > local2global;
150 
151  getCoordinateTransformation( pose, origin, local2global);
152 
155 
156  numeric::xyzVector< Real > localX, localRX, globalRX;
157  for (Size i=1; i<=segment_.nContinuousSegments(); ++i) {
158  // apply to transformation to every atom in this segment
159  Size i_start = std::max(segment_[i].start(), (Size)1);
160  Size i_end = std::min(segment_[i].end(), pose.total_residue());
161 
162  for ( Size j = i_start; j <= i_end; ++j ) {
163  for ( Size k = 1; k <= pose.residue(j).natoms(); ++k ) {
164  id::AtomID id( k, j );
165  globalRX = pose.xyz(id) + local2global * translation;
166 
167  //pose.set_xyz( id, globalRX );
168  atm_ids.push_back( id );
169  atm_xyzs.push_back( globalRX );
170  }
171  }
172  }
173  pose.batch_set_xyz( atm_ids, atm_xyzs );
174 }
175 
176 /// @brief Apply a rotation followed by a translation (does not recompute coordinate transformation between the two!)
178  // get transformation
180  numeric::xyzMatrix< Real > local2global, global2local;
181 
182  getCoordinateTransformation( pose, origin, local2global);
183  global2local = numeric::inverse( local2global );
184 
187 
188  numeric::xyzVector< Real > localX, localRX, globalRX;
189  for (Size i=1; i<=segment_.nContinuousSegments(); ++i) {
190  // apply to transformation to every atom in this segment
191  Size i_start = std::max(segment_[i].start(), (Size)1);
192  Size i_end = std::min(segment_[i].end(), pose.total_residue());
193 
194  for ( Size j = i_start; j <= i_end; ++j ) {
195  for ( Size k = 1; k <= pose.residue(j).natoms(); ++k ) {
196  id::AtomID id( k, j );
197  localX = global2local * ( pose.xyz(id) - origin );
198  localRX = rotation * localX + translation;
199  globalRX = local2global * localRX + origin;
200 
201  //pose.set_xyz( id, globalRX );
202  atm_ids.push_back( id );
203  atm_xyzs.push_back( globalRX );
204  }
205  }
206  }
207  pose.batch_set_xyz( atm_ids, atm_xyzs );
208 }
209 
210 /// @brief Apply a spin of the specified angle (in degrees) about arbitrary axis
212  numeric::xyzMatrix< Real > rotation = numeric::rotation_matrix(rotationAxis, numeric::conversions::radians(degrees));
213  applyRotation( pose, rotation );
214 }
215 
216 /// @brief (re)set the starting and ending residues of this transform
218  segment_ = seg;
219 }
220 
221 /// @brief Get the the starting and ending residues of transform
223  return segment_;
224 }
225 
226 
227 ///////////////////////////////////////////
228 /// Apply a random rigid-body transformation to an arbitrary segment
229 ///////////////////////////////////////////
231  // random rotation ...
232  applyRotation( pose , sigma_rot*rbseg_RG.gaussian() , sigma_rot*rbseg_RG.gaussian() , sigma_rot*rbseg_RG.gaussian() );
233 
234  // ... and translation
235  numeric::xyzVector< Real > trans(sigma_trans*rbseg_RG.gaussian() , sigma_trans*rbseg_RG.gaussian() , sigma_trans*rbseg_RG.gaussian());
236  applyTranslation( pose , trans );
237 }
238 
241  return "GaussianRBSegmentMover";
242 }
243 
244 /// @brief Get the fragment center / matrix that rotates global coordinates into local fragment coordinates.
245 /// Defined such that +z points to the C-terminal end of the helix axis,
246 /// +x from the helix axis to the N-terminal residue
248  core::pose::Pose const & pose,
249  Vector &rotationCenter,
250  numeric::xyzMatrix< Real > &coordinateTransform
251  ) {
252  // rotate about center-of-mass
253  rotationCenter = getCoM( pose );
254 
255  // random rotation, so local coord frame irrelevant
256  coordinateTransform.clear();
257  coordinateTransform.xx(1);
258  coordinateTransform.yy(1);
259  coordinateTransform.zz(1);
260 }
261 
262 
263 
264 ///////////////////////////////////////////
265 /// Apply a "register shift" move to this fragment. Shift {-2,-1,1,2}
266 ///////////////////////////////////////////
268  // if the segment is not simple (i.e. contains >1 continuous segment) output error msg
269  if (!segment_.isSimple()) {
270  TR << "[ ERROR ] SequenceShiftMover::apply() called on compound segment!" << std::endl;
271  exit(1);
272  }
273 
274  // pick a direction at random
275  int dir = (rbseg_RG.random_range(0,1))? -1 : 1;
276  int mag = rbseg_RG.random_range(1,magnitude_);
277 
278  TR.Debug << "SequenceShiftMover::apply() [" << dir*mag << "]" << std::endl;
279 
280  // now apply to transformation to every atom in [startRes,endRes]
281  Size i_start = std::max(segment_[1].start(), (Size)1);
282  Size i_end = std::min(segment_[1].end(), pose.total_residue());
283  Size nres = i_end - i_start + 1;
284 
285  numeric::xyzVector< Real > C1,N1,C2,N2, CA1, CA2;
287 
288  // avoid compiler warning
289  R.xx(0.0);R.xy(0.0);R.xz(0.0);
290  R.yx(0.0);R.yy(0.0);R.yz(0.0);
291  R.zx(0.0);R.zy(0.0);R.zz(0.0);
292 
295 
296  for ( Size i = 0; i < nres-mag; ++i ) {
297  // "transform" r_i to r_j
298  Size r_i = (dir==1)? i_start+i : i_end-i;
299  Size r_j = r_i+dir*mag;
300 
301  CA1 = pose.residue(r_i).atom("CA").xyz();
302  C1 = pose.residue(r_i).atom("C").xyz() - CA1; // offset from CA
303  N1 = pose.residue(r_i).atom("N").xyz() - CA1; // offset from CA
304  CA2 = pose.residue(r_j).atom("CA").xyz();
305  C2 = pose.residue(r_j).atom("C").xyz() - CA2; // offset from CA
306  N2 = pose.residue(r_j).atom("N").xyz() - CA2; // offset from CA
307 
308  // get rotation from (i+dir) to i
309  R = numeric::alignVectorSets( C1,N1, C2,N2 );
310 
311  // apply transformation to every atom in this res
312  for ( Size a_i = 1; a_i<=pose.residue(r_i).natoms(); ++a_i ) {
313  id::AtomID id( a_i, r_i );
314  numeric::xyzVector< Real > newX = R * (pose.xyz(id) - CA1) + CA2;
315 
316  //pose.set_xyz( id, newX );
317  atm_ids.push_back( id );
318  atm_xyzs.push_back( newX );
319  }
320  }
321 
322  // final 'mag+1' residues have a single transformation applied
323  // just apply the final transformation to these "extra" residues
324  for ( Size i = 0; i < (Size)mag; ++i ) {
325  Size r_i = (dir==1)? i_end-i : i_start+i;
326  for ( Size a_i = 1; a_i<=pose.residue(r_i).natoms(); ++a_i ) {
327  id::AtomID id( a_i, r_i );
328  numeric::xyzVector< Real > newX = R * (pose.xyz(id) - CA1) + CA2;
329 
330  //pose.set_xyz( id, newX );
331  atm_ids.push_back( id );
332  atm_xyzs.push_back( newX );
333  }
334  }
335  pose.batch_set_xyz( atm_ids, atm_xyzs );
336 }
337 
338 
341  return "SequenceShiftMover";
342 }
343 
344 ////////////////////////////////////////////
345 /// Helical-axis segment movers
346 ////////////////////////////////////////////
348 {
349  // if the segment is not simple (i.e. contains >1 continuous segment) output error msg
350  Real displacement_Z( sigAxisT_*rbseg_RG.gaussian() );
351  Real displacement_X( sigOffAxisT_*rbseg_RG.gaussian() );
352  Real displacement_Y( sigOffAxisT_*rbseg_RG.gaussian() );
353 
354  Real displacement_alpha( sigAxisR_*rbseg_RG.gaussian() );
355  Real displacement_beta ( sigOffAxisR_*rbseg_RG.gaussian() );
356  Real displacement_gamma( sigOffAxisR_*rbseg_RG.gaussian() );
357 
358  TR.Debug << "HelicalGaussianMover::apply() ["
359  << displacement_X << "," << displacement_Y << "," << displacement_Z << ","
360  << displacement_alpha << "," << displacement_beta << "," << displacement_gamma << "]" << std::endl;
361  TR.Debug << " ["
362  << sigAxisT_ << "," << sigOffAxisT_ << "," << sigAxisR_ << "," << sigOffAxisR_ << "]" << std::endl;
363 
364 // TR << "HelixAxisGaussianTransMover::apply()" << std::endl;
365  if ( sigAxisT_ > 1e-6 || sigOffAxisT_ > 1e-6 ) {
366 // TR << " Translation w.r.t. Helical Axis [" << displacement_X << " , "
367 // << displacement_Y << " , "
368 // << displacement_Z << "]" << std::endl;
369  numeric::xyzVector< Real > trans( displacement_X, displacement_Y, displacement_Z );
370  applyTranslation( pose, trans );
371  }
372 
373  if ( sigAxisR_ > 1e-6 || sigOffAxisR_ > 1e-6 ) {
374 // TR << " Rotation w.r.t. Helical Axis [" << displacement_alpha << " , "
375 // << displacement_beta << " , "
376 // << displacement_gamma << "]" << std::endl;
377  applyRotation( pose, displacement_alpha, displacement_beta, displacement_gamma );
378  }
379 }
380 
383  return "HelicalGaussianMover";
384 }
385 
387  core::pose::Pose const & pose,
388  Vector &rotationCenter,
389  numeric::xyzMatrix< Real > &coordinateTransform
390  )
391 {
392  // if the segment is not simple (i.e. contains >1 continuous segment) output error msg
393  if (!segment_.isSimple()) {
394  TR << "[ ERROR ] HelicalGaussianMover::getCoordinateTransformationy() called on compound segment!" << std::endl;
395  exit(1);
396  }
397 
398  // the helix axis is defined based on the residues near the center of the helix
399  // if the helix is longer than 7 residues compare midPt-3..midPt with midPt..midPt+3
400  // otherwise compare start..start+3 with end-3..end
401  // undefined if helix is less than 4 residues
402  Vector helixAxisNterm(0,0,0), helixAxisCterm(0,0,0);
403  int startRes = segment_[1].start();
404  int endRes = segment_[1].end();
405  int nres = endRes - startRes + 1;
406 
407  if (nres < 4) {
408  TR << "[WARNING] Helical axis of helices less than four residues is not correctly computed" << std::endl;
409  rotationCenter = getCoM( pose );
410 
411  coordinateTransform.clear();
412  coordinateTransform.xx(1);
413  coordinateTransform.yy(1);
414  coordinateTransform.zz(1);
415  } else {
416  if (nres >= 7) {
417  int midRes = startRes + (nres-1)/2;
418  helixAxisNterm += ( 0.6/3.6 ) * pose.residue( midRes ).xyz( "CA" );
419  helixAxisNterm += ( 1.0/3.6 ) * pose.residue( midRes - 1 ).xyz( "CA" );
420  helixAxisNterm += ( 1.0/3.6 ) * pose.residue( midRes - 2 ).xyz( "CA" );
421  helixAxisNterm += ( 1.0/3.6 ) * pose.residue( midRes - 3 ).xyz( "CA" );
422  helixAxisCterm += ( 0.6/3.6 ) * pose.residue( midRes ).xyz( "CA" );
423  helixAxisCterm += ( 1.0/3.6 ) * pose.residue( midRes + 1 ).xyz( "CA" );
424  helixAxisCterm += ( 1.0/3.6 ) * pose.residue( midRes + 2 ).xyz( "CA" );
425  helixAxisCterm += ( 1.0/3.6 ) * pose.residue( midRes + 3 ).xyz( "CA" );
426  } else {
427  helixAxisNterm += (1.0/3.6) * pose.residue(startRes).xyz("CA");
428  helixAxisNterm += (1.0/3.6) * pose.residue(startRes+1).xyz("CA");
429  helixAxisNterm += (1.0/3.6) * pose.residue(startRes+2).xyz("CA");
430  helixAxisNterm += (0.6/3.6) * pose.residue(startRes+3).xyz("CA");
431  helixAxisCterm += (1.0/3.6) * pose.residue(endRes).xyz("CA");
432  helixAxisCterm += (1.0/3.6) * pose.residue(endRes-1).xyz("CA");
433  helixAxisCterm += (1.0/3.6) * pose.residue(endRes-2).xyz("CA");
434  helixAxisCterm += (0.6/3.6) * pose.residue(endRes-3).xyz("CA");
435  }
436 
437  rotationCenter = 0.5 * helixAxisNterm + 0.5 * helixAxisCterm;
438  coordinateTransform = coordTransformFromThreePoints(
439  rotationCenter,
440  helixAxisCterm,
441  pose.residue(startRes).xyz("CA") );
442  }
443 }
444 
445 
446 ////////////////////////
447 ////////////////////////
449 {
450  Real displacement_Z( sigAxisT_*rbseg_RG.gaussian() );
451  Real displacement_X( sigOffAxisT_*rbseg_RG.gaussian() );
452  Real displacement_Y( sigOffAxisT_*rbseg_RG.gaussian() );
453 
454  Real displacement_alpha( sigAxisR_*rbseg_RG.gaussian() );
455  Real displacement_beta ( sigOffAxisR_*rbseg_RG.gaussian() );
456  Real displacement_gamma( sigOffAxisR_*rbseg_RG.gaussian() );
457 
458  TR.Debug << "StrandTwistingMover::apply() ["
459  << displacement_X << "," << displacement_Y << "," << displacement_Z << ","
460  << displacement_alpha << "," << displacement_beta << "," << displacement_gamma << "]" << std::endl;
461 
462  if ( sigAxisT_ > 1e-6 || sigOffAxisT_ > 1e-6 ) {
463  numeric::xyzVector< Real > trans( displacement_X, displacement_Y, displacement_Z );
464  applyTranslation( pose, trans );
465  }
466 
467  if ( sigAxisR_ > 1e-6 || sigOffAxisR_ > 1e-6 ) {
468  applyRotation( pose, displacement_alpha, displacement_beta, displacement_gamma );
469  }
470 }
471 
474  return "StrandTwistingMover";
475 }
476 
478  core::pose::Pose const & pose,
479  Vector &rotationCenter,
480  numeric::xyzMatrix< Real > &coordinateTransform
481 )
482 {
483  // if the segment is not simple (i.e. contains >1 continuous segment) output error msg
484  if (!segment_.isSimple()) {
485  TR << "[ ERROR ] HelicalGaussianMover::getCoordinateTransformationy() called on compound segment!" << std::endl;
486  exit(1);
487  }
488 
489  // undefined if strand is less than 3 residues
490  Vector sAxisNterm(0,0,0), sAxisCterm(0,0,0);
491  int startRes = segment_[1].start();
492  int endRes = segment_[1].end();
493  int nres = endRes - startRes + 1;
494 
495  if (nres < 3) {
496  TR << "[WARNING] Strand axis of less than three residues is not correctly computed" << std::endl;
497  rotationCenter = getCoM( pose );
498 
499  coordinateTransform.clear();
500  coordinateTransform.xx(1);
501  coordinateTransform.yy(1);
502  coordinateTransform.zz(1);
503  } else {
504  sAxisNterm += (0.5) * pose.residue(startRes).xyz("CA");
505  sAxisNterm += (0.5) * pose.residue(startRes+1).xyz("CA");
506  sAxisCterm += (0.5) * pose.residue(endRes).xyz("CA");
507  sAxisCterm += (0.5) * pose.residue(endRes-1).xyz("CA");
508 
509  rotationCenter = 0.5 * sAxisNterm + 0.5 * sAxisCterm;
510  coordinateTransform = coordTransformFromThreePoints(
511  rotationCenter,
512  sAxisCterm,
513  pose.residue(startRes).xyz("CA") );
514  }
515 }
516 
517 }
518 }