Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BBConRotMover.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 
12 //core
14 // AUTO-REMOVED #include <core/chemical/AtomTypeSet.hh>
15 // AUTO-REMOVED #include <core/chemical/ChemicalManager.hh>
17 // AUTO-REMOVED #include <core/chemical/ResidueTypeSet.hh>
18 
21 // AUTO-REMOVED #include <core/conformation/util.hh>
22 
23 #include <core/pose/Pose.hh>
24 #include <basic/basic.hh>
25 
26 #include <basic/options/option.hh>
27 // AUTO-REMOVED #include <basic/options/option_macros.hh>
28 #include <basic/options/keys/bbg.OptionKeys.gen.hh>
29 
30 // AUTO-REMOVED #include <core/id/DOF_ID_Range.hh>
31 // AUTO-REMOVED #include <core/kinematics/AtomTree.hh>
32 // AUTO-REMOVED #include <core/kinematics/MoveMap.hh>
33 // AUTO-REMOVED #include <core/kinematics/tree/Atom.hh>
34 #include <core/kinematics/Stub.hh>
35 
36 //util
37 #include <utility/exit.hh>
38 #include <basic/Tracer.hh>
39 #include <numeric/random/random.hh>
40 #include <numeric/xyz.functions.hh>
41 #include <numeric/xyzMatrix.hh>
42 #include <numeric/xyzVector.hh>
43 #include <numeric/constants.hh>
44 #include <numeric/internal/RowVectors.hh>
45 
46 #include <iostream>
47 // AUTO-REMOVED #include <fstream>
48 #include <sstream>
49 
50 #include <utility/vector1.hh>
51 
52 
53 using namespace std;
54 using namespace core;
55 using namespace core::pose;
56 using namespace utility;
57 using namespace numeric;
58 using namespace basic::options;
59 using namespace basic::options::OptionKeys;
60 
61 static basic::Tracer TR("protocols.simple_moves.BBConRotMover");
62 static numeric::random::RandomGenerator RG(19500606); //Magic Number
63 
64 namespace protocols {
65 namespace simple_moves {
66 
67 void BBConRotMover::factorA( core::Real const fA )
68 {
69  factorA_ = fA;
70 }
71 
72 void BBConRotMover::factorB( core::Real const fB )
73 {
74  factorB_ = fB;
75 }
76 
77 void BBConRotMover::factorC( core::Real const fC )
78 {
79  factorC_ = fC;
80 }
81 
82 BBConRotMover::BBConRotMover()
83 :BBGaussianMover(1,15,5),
84 dphi(utility::vector1<Real>(n_dof_angle_)),
85 oldphi(utility::vector1<Real>(n_dof_angle_))
86 {
87  using numeric::constants::d::pi;
88 
89  protocols::moves::Mover::type("BBConRotMover");
90 
91  //in bbg, set_phi(degree), 1 (A/2) ~ 57.3/2
92  //here, set_dof(rad)
93  //paper param: 50 (C1) ~ 0.87 -> A~1.74
94 
95  //init the ABC factor
96  //factorA_ = option[ bbg::factorA ]*180.0/pi;
97  factorA_ = option[ bbg::factorA ]*2.0; //the g() is (0,1), not (0,1/sqrt(2))
98  factorB_ = option[ bbg::factorB ];
99  factorC_ = 20.0;
100 }
101 
103 
105 {
106  return "BBConRotMover";
107 }
108 
110 {
111  Size iter=0;
112  while(make_move(pose))
113  {
114  if(iter++ > 100)break;
115  }
116  TR.Debug << "apply: iter=" << iter << std::endl;
117 }
118 
120 {
121  using basic::periodic_range;
122  using basic::unsigned_periodic_range;
123  using numeric::constants::d::pi;
124  using numeric::constants::d::pi_2;
125 
126  setup_list(pose);
127  int ndx=static_cast< int >( RG.uniform()*available_seg_list_.size()+1 );
128 
129  Size left = available_seg_list_[ ndx ].first;
130  resnum_ = available_seg_list_[ ndx ].second;
131  TR.Debug << "Pick: " << left << " <--> " << resnum_ << std::endl;
132  if (resnum_-left+1 < n_pert_res_)
133  {
134  //do random
135  TR.Debug << "Do random rot ... " << std::endl;
136  pivot_range_randomly(pose, left, resnum_);
137  return false;
138  }
139  assert(resnum_-left == n_pert_res_-1);
140 
141  Size nres(pose.n_residue());
142  Vector oldv(pose.residue(nres).atom("CA").xyz());
143 
144  //using whole pose
145  Vector r0(pose.residue(resnum_).atom("C").xyz());
146  Vector r1(pose.residue(resnum_).atom("CA").xyz());
147  Vector r2(pose.residue(resnum_).atom("N").xyz());
148  Vector r3(pose.residue(resnum_-1).atom("C").xyz());
149  Vector r4(pose.residue(resnum_-1).atom("CA").xyz());
150  Vector r5(pose.residue(resnum_-1).atom("N").xyz());
151  Vector r6(pose.residue(resnum_-2).atom("C").xyz());
152  Vector p1((r2-r1).length(),0.0,0.0);
153  Vector p2((r3-r2).length(),0.0,0.0);
154  Vector p3((r4-r3).length(),0.0,0.0);
155 
156  Real jac_new0 = calc_jacobian_cartesians(r5, r4, r3, r2, r1);
157  TR.Debug << "Jac_new0=" << jac_new0 << std::endl;
158 
159  bool failed = true;
160  //check jac>0
161  if (jac_new0>0) failed = false;
162 
163  if (!failed) {
164 
165  id::DOF_ID dih12( id::AtomID(pose.residue(resnum_ ).atom_index("C" ), resnum_ ), id::PHI );
166  id::DOF_ID dih11( id::AtomID(pose.residue(resnum_ ).atom_index("CA"), resnum_ ), id::PHI );
167  id::DOF_ID dih10( id::AtomID(pose.residue(resnum_ ).atom_index("N" ), resnum_ ), id::PHI );
168  id::DOF_ID dih9 ( id::AtomID(pose.residue(resnum_-1).atom_index("C" ), resnum_-1), id::PHI );
169  id::DOF_ID ang11( id::AtomID(pose.residue(resnum_ ).atom_index("CA"), resnum_ ), id::THETA );
170  id::DOF_ID ang10( id::AtomID(pose.residue(resnum_ ).atom_index("N" ), resnum_ ), id::THETA );
171  id::DOF_ID ang9 ( id::AtomID(pose.residue(resnum_-1).atom_index("C" ), resnum_-1), id::THETA );
172  Real theta1_old = pose.dof(dih12); //dih_12
173  Real theta2_old = pose.dof(dih11);; //dih_11
174  Real theta3_old = pose.dof(dih10); //dih_10
175  Real theta4_old = pose.dof(dih9); //dih_9
176  Real alpha1_old = pi - pose.dof(ang11); //ang_11
177  Real alpha2_old = pi - pose.dof(ang10); //ang_10
178  Real alpha3_old = pi - pose.dof(ang9); //ang_9
179 
180  //perturb forward
181  get_VdRdPhi(pose);
182  get_G();
183  get_A();
184  //TR.Debug << "perturb..." << std::endl;
185  Real W_old = get_L_move(pose);
186  //backward
187  get_VdRdPhi(pose);
188  get_G();
189  get_A();
190  Real W_new = get_L_prime();
191 
192  //proposal density
193  last_proposal_density_ratio_ = W_new / W_old;
194  TR.Debug << "W_old=" << W_old << " W_new=" << W_new << std::endl;
195  TR.Debug << "ratio=" << last_proposal_density_ratio_ << std::endl;
196 
197  //new r6, r5, r4
198  r4 = pose.residue(resnum_-1).atom("CA").xyz();
199  r5 = pose.residue(resnum_-1).atom("N").xyz();
200  r6 = pose.residue(resnum_-2).atom("C").xyz();
201 
202  //closure
203  Real theta1,theta2,theta3,theta4;
204  Real alpha1,alpha2,alpha3;
205 
206 
207  //TR<<"Closure..." << std::endl;
208  failed=true;
209 
210  if( !closure(
211  //Vector
212  r0,r1,r2,r3,r4,r5,r6,p1,p2,p3,
213  //old angle/dih
214  theta1_old,theta2_old,theta3_old,theta4_old,
215  alpha1_old,alpha2_old,alpha3_old,
216  //new angle/dih
217  theta1,theta2,theta3,theta4,
218  alpha1,alpha2,alpha3) )
219  {
220  //successfully close
221  Real jac_new1 = calc_jacobian_cartesians(r5, r4, r3, r2, r1);
222  TR.Debug << "Jac_new1=" << jac_new1 << std::endl;
223 
224  if (jac_new1>0)
225  {
226  last_proposal_density_ratio_ *= jac_new1 / jac_new0;
227  TR.Debug << "last_proposal=" << last_proposal_density_ratio_ << std::endl;
228 
229  //using whole pose
230  pose.set_dof(dih12, theta1); //dih_12
231  pose.set_dof(dih11, theta2); //dih_11
232  pose.set_dof(dih10, theta3); //dih_10
233  pose.set_dof(dih9, theta4); //dih_9
234  pose.set_dof(ang11, pi-alpha1); //ang_11
235  pose.set_dof(ang10, pi-alpha2); //ang_10
236  pose.set_dof(ang9, pi-alpha3); //ang_9
237 
238  //make sure the downstream didn't flip
239  core::Vector dd(pose.residue(nres).atom("CA").xyz()-oldv);
240  if (dd.length_squared()<1.0e-6)
241  {
242  failed=false;
243  TR.Debug << "Closure Success!" << std::endl;
244  }
245  }
246  }
247 
248  }//if (!failed)
249 
250  if (failed)
251  {
252  //false
253  //back
254  id::DOF_ID dih0( id::AtomID(pose.residue(resnum_-4).atom_index("C" ), resnum_-4), id::PHI );
255  id::DOF_ID dih1( id::AtomID(pose.residue(resnum_-3).atom_index("N" ), resnum_-3), id::PHI );
256  id::DOF_ID dih3( id::AtomID(pose.residue(resnum_-3).atom_index("C" ), resnum_-3), id::PHI );
257  id::DOF_ID dih4( id::AtomID(pose.residue(resnum_-2).atom_index("N" ), resnum_-2), id::PHI );
258  id::DOF_ID dih6( id::AtomID(pose.residue(resnum_-2).atom_index("C" ), resnum_-2), id::PHI );
259  id::DOF_ID dih7( id::AtomID(pose.residue(resnum_-1).atom_index("N" ), resnum_-1), id::PHI );
260  id::DOF_ID angle1( id::AtomID(pose.residue(resnum_-4).atom_index("C" ), resnum_-4), id::THETA );
261  id::DOF_ID angle2( id::AtomID(pose.residue(resnum_-3).atom_index("N" ), resnum_-3), id::THETA );
262  id::DOF_ID angle3( id::AtomID(pose.residue(resnum_-3).atom_index("CA"), resnum_-3), id::THETA );
263  id::DOF_ID angle4( id::AtomID(pose.residue(resnum_-3).atom_index("C" ), resnum_-3), id::THETA );
264  id::DOF_ID angle5( id::AtomID(pose.residue(resnum_-2).atom_index("N" ), resnum_-2), id::THETA );
265  id::DOF_ID angle6( id::AtomID(pose.residue(resnum_-2).atom_index("CA"), resnum_-2), id::THETA );
266  id::DOF_ID angle7( id::AtomID(pose.residue(resnum_-2).atom_index("C" ), resnum_-2), id::THETA );
267  id::DOF_ID angle8( id::AtomID(pose.residue(resnum_-1).atom_index("N" ), resnum_-1), id::THETA );
268  id::DOF_ID angle9( id::AtomID(pose.residue(resnum_-1).atom_index("CA"), resnum_-1), id::THETA );
269 
270  //TR<< "Rebuild ..." << std::endl;
271  pose.set_dof(dih0, oldphi[1]);
272  pose.set_dof(dih1, oldphi[2]);
273  pose.set_dof(dih3, oldphi[3]);
274  pose.set_dof(dih4, oldphi[4]);
275  pose.set_dof(dih6, oldphi[5]);
276  pose.set_dof(dih7, oldphi[6]);
277  pose.set_dof(angle1, oldphi[7]);
278  pose.set_dof(angle2, oldphi[8]);
279  pose.set_dof(angle3, oldphi[9]);
280  pose.set_dof(angle4, oldphi[10]);
281  pose.set_dof(angle5, oldphi[11]);
282  pose.set_dof(angle6, oldphi[12]);
283  pose.set_dof(angle7, oldphi[13]);
284  pose.set_dof(angle8, oldphi[14]);
285  pose.set_dof(angle9, oldphi[15]);
286 
288  TR.Debug << "Closure Failed!" << std::endl;
289  }
290 
291  return failed;
292 }
293 
294 void BBConRotMover::get_VdRdPhi(Pose const &segment)
295 {
296  Size nres=resnum_; //using the whole pose
297  conformation::Residue const & rsd0(segment.residue(nres-4));
298  conformation::Residue const & rsd1(segment.residue(nres-3));
299  conformation::Residue const & rsd2(segment.residue(nres-2));
300  conformation::Residue const & rsd3(segment.residue(nres-1));
301 
302  //the only end
303  Vector end_xyz = rsd3.atom("CA").xyz();
304 
305  ///////////////////
306  //dihedral x 6
307  ///////////////////
308  matrix_dRdPhi[1][1] = get_dRdPhi(
309  rsd0.atom("N").xyz(),
310  rsd0.atom("CA").xyz(),
311  end_xyz);
312 
313  matrix_dRdPhi[1][2] = get_dRdPhi(
314  rsd0.atom("CA").xyz(),
315  rsd0.atom("C").xyz(),
316  end_xyz);
317 
318  matrix_dRdPhi[1][3] = get_dRdPhi(
319  rsd1.atom("N").xyz(),
320  rsd1.atom("CA").xyz(),
321  end_xyz);
322 
323  matrix_dRdPhi[1][5] = get_dRdPhi(
324  rsd1.atom("CA").xyz(),
325  rsd1.atom("C").xyz(),
326  end_xyz);
327 
328  matrix_dRdPhi[1][5] = get_dRdPhi(
329  rsd2.atom("N").xyz(),
330  rsd2.atom("CA").xyz(),
331  end_xyz);
332 
333  matrix_dRdPhi[1][6] = get_dRdPhi(
334  rsd2.atom("CA").xyz(),
335  rsd2.atom("C").xyz(),
336  end_xyz);
337 
338  ////////////////////////
339  //bond angle x 9
340  ////////////////////////
341  matrix_dRdPhi[1][7] = get_dRdTheta(
342  rsd0.atom("N").xyz(),
343  rsd0.atom("CA").xyz(),
344  rsd0.atom("C").xyz(),
345  end_xyz);
346 
347  matrix_dRdPhi[1][8] = get_dRdTheta(
348  rsd0.atom("CA").xyz(),
349  rsd0.atom("C").xyz(),
350  rsd1.atom("N").xyz(),
351  end_xyz);
352 
353  matrix_dRdPhi[1][9] = get_dRdTheta(
354  rsd0.atom("C").xyz(),
355  rsd1.atom("N").xyz(),
356  rsd1.atom("CA").xyz(),
357  end_xyz);
358 
359  matrix_dRdPhi[1][10] = get_dRdTheta(
360  rsd1.atom("N").xyz(),
361  rsd1.atom("CA").xyz(),
362  rsd1.atom("C").xyz(),
363  end_xyz);
364 
365  matrix_dRdPhi[1][11] = get_dRdTheta(
366  rsd1.atom("CA").xyz(),
367  rsd1.atom("C").xyz(),
368  rsd2.atom("N").xyz(),
369  end_xyz);
370 
371  matrix_dRdPhi[1][12] = get_dRdTheta(
372  rsd1.atom("C").xyz(),
373  rsd2.atom("N").xyz(),
374  rsd2.atom("CA").xyz(),
375  end_xyz);
376 
377  matrix_dRdPhi[1][13] = get_dRdTheta(
378  rsd2.atom("N").xyz(),
379  rsd2.atom("CA").xyz(),
380  rsd2.atom("C").xyz(),
381  end_xyz);
382 
383  matrix_dRdPhi[1][14] = get_dRdTheta(
384  rsd2.atom("CA").xyz(),
385  rsd2.atom("C").xyz(),
386  rsd3.atom("N").xyz(),
387  end_xyz);
388 
389  matrix_dRdPhi[1][15] = get_dRdTheta(
390  rsd2.atom("C").xyz(),
391  rsd3.atom("N").xyz(),
392  rsd3.atom("CA").xyz(),
393  end_xyz);
394 }
395 
397 {
398  for (Size i=1; i<=n_dof_angle_; i++)
399  {
400  for (Size j=i; j<=n_dof_angle_; j++)
401  {
402  matrix_G[i][j] = matrix_dRdPhi[1][i].dot(matrix_dRdPhi[1][j]);
403  if (i<j) matrix_G[j][i]=matrix_G[i][j];
404  }
405  }
406 }
407 
409 {
410  //A = a(1+bG)
411  //A = L^-1 * L
412  //L(angle) -> c * L(angle)
413  for (Size i=1; i<=n_dof_angle_; i++)
414  {
415  for (Size j=i; j<=n_dof_angle_; j++)
416  {
417  matrix_A[i][j] = factorB_ * matrix_G[i][j];
418  if (i==j) matrix_A[i][j] += 1.0;
419  matrix_A[i][j] *= factorA_;
420 
421  if (i<j) matrix_A[j][i] = matrix_A[i][j];
422  }
423  }
424 }
425 
427 {
428  using basic::periodic_range;
429  using basic::unsigned_periodic_range;
430  using numeric::constants::d::pi;
431  using numeric::constants::d::pi_2;
432 
433  Size nres=resnum_; //using the whole pose
434  //Size nres=6; //using copy segment
435 
436  //gerate a Gaussian dx vector
438  for (Size i=1; i<=n_dof_angle_; i++) delta[i]=RG.gaussian();
439  //Debug: no angle changes
440  //for (Size i=7; i<=n_dof_angle_; i++) delta[i]=0;
441 
442  Real d2=0.0;
443  for (Size i=1; i<=n_dof_angle_; i++) d2+=delta[i]*delta[i];
444 
445  //cholesky, get L^t, L^-1
446  Real detL = cholesky_fw(matrix_A, n_dof_angle_, delta, dphi, 7, 15, factorC_);
447 
448  //should i use factorC here or in get_A?
449  Real W_old = detL*exp(-d2/2.0);
450 
451  //set the new phi, psi, theta
452  //res total: n_pert_res_+2, from 2 to n_pert_res_+1
453  id::DOF_ID dih0( id::AtomID(segment.residue(nres-4).atom_index("C" ), nres-4), id::PHI );
454  id::DOF_ID dih1( id::AtomID(segment.residue(nres-3).atom_index("N" ), nres-3), id::PHI );
455  id::DOF_ID dih3( id::AtomID(segment.residue(nres-3).atom_index("C" ), nres-3), id::PHI );
456  id::DOF_ID dih4( id::AtomID(segment.residue(nres-2).atom_index("N" ), nres-2), id::PHI );
457  id::DOF_ID dih6( id::AtomID(segment.residue(nres-2).atom_index("C" ), nres-2), id::PHI );
458  id::DOF_ID dih7( id::AtomID(segment.residue(nres-1).atom_index("N" ), nres-1), id::PHI );
459  id::DOF_ID angle1( id::AtomID(segment.residue(nres-4).atom_index("C" ), nres-4), id::THETA );
460  id::DOF_ID angle2( id::AtomID(segment.residue(nres-3).atom_index("N" ), nres-3), id::THETA );
461  id::DOF_ID angle3( id::AtomID(segment.residue(nres-3).atom_index("CA"), nres-3), id::THETA );
462  id::DOF_ID angle4( id::AtomID(segment.residue(nres-3).atom_index("C" ), nres-3), id::THETA );
463  id::DOF_ID angle5( id::AtomID(segment.residue(nres-2).atom_index("N" ), nres-2), id::THETA );
464  id::DOF_ID angle6( id::AtomID(segment.residue(nres-2).atom_index("CA"), nres-2), id::THETA );
465  id::DOF_ID angle7( id::AtomID(segment.residue(nres-2).atom_index("C" ), nres-2), id::THETA );
466  id::DOF_ID angle8( id::AtomID(segment.residue(nres-1).atom_index("N" ), nres-1), id::THETA );
467  id::DOF_ID angle9( id::AtomID(segment.residue(nres-1).atom_index("CA"), nres-1), id::THETA );
468 
469  oldphi[1]=segment.dof(dih0);
470  oldphi[2]=segment.dof(dih1);
471  oldphi[3]=segment.dof(dih3);
472  oldphi[4]=segment.dof(dih4);
473  oldphi[5]=segment.dof(dih6);
474  oldphi[6]=segment.dof(dih7);
475  oldphi[7]=segment.dof(angle1);
476  oldphi[8]=segment.dof(angle2);
477  oldphi[9]=segment.dof(angle3);
478  oldphi[10]=segment.dof(angle4);
479  oldphi[11]=segment.dof(angle5);
480  oldphi[12]=segment.dof(angle6);
481  oldphi[13]=segment.dof(angle7);
482  oldphi[14]=segment.dof(angle8);
483  oldphi[15]=segment.dof(angle9);
484 
485  segment.set_dof(dih0, periodic_range(segment.dof(dih0)+dphi[1],pi_2));
486  segment.set_dof(dih1, periodic_range(segment.dof(dih1)+dphi[2],pi_2));
487  segment.set_dof(dih3, periodic_range(segment.dof(dih3)+dphi[3],pi_2));
488  segment.set_dof(dih4, periodic_range(segment.dof(dih4)+dphi[4],pi_2));
489  segment.set_dof(dih6, periodic_range(segment.dof(dih6)+dphi[5],pi_2));
490  segment.set_dof(dih7, periodic_range(segment.dof(dih7)+dphi[6],pi_2));
491  segment.set_dof(angle1, unsigned_periodic_range(segment.dof(angle1)+dphi[7],pi));
492  segment.set_dof(angle2, unsigned_periodic_range(segment.dof(angle2)+dphi[8],pi));
493  segment.set_dof(angle3, unsigned_periodic_range(segment.dof(angle3)+dphi[9],pi));
494  segment.set_dof(angle4, unsigned_periodic_range(segment.dof(angle4)+dphi[10],pi));
495  segment.set_dof(angle5, unsigned_periodic_range(segment.dof(angle5)+dphi[11],pi));
496  segment.set_dof(angle6, unsigned_periodic_range(segment.dof(angle6)+dphi[12],pi));
497  segment.set_dof(angle7, unsigned_periodic_range(segment.dof(angle7)+dphi[13],pi));
498  segment.set_dof(angle8, unsigned_periodic_range(segment.dof(angle8)+dphi[14],pi));
499  segment.set_dof(angle9, unsigned_periodic_range(segment.dof(angle9)+dphi[15],pi));
500 
501  return W_old;
502 }
503 
505 {
507  Real detL = cholesky_bw(matrix_A, n_dof_angle_, dphi, delta, 7, 15, factorC_);
508  Real d2=0.0;
509  for (Size i=1; i<=n_dof_angle_; i++)d2+=delta[i]*delta[i];
510  return detL*exp(-d2/2.0);
511 }
512 
514  Vector const &a,
515  Vector const &b,
516  Vector const &c,
517  Vector &d,
518  Real distance,
519  Real theta,
520  Real phi
521 )
522 {
523  using numeric::x_rotation_matrix_radians;
524  using numeric::z_rotation_matrix_radians;
525  using numeric::constants::d::pi;
526  using namespace core::kinematics;
527 
528  Stub stub(c,b,a);
529  xyzMatrix M(stub.M * x_rotation_matrix_radians( phi ));
530  M *= z_rotation_matrix_radians( pi - theta );
531  //M *= z_rotation_matrix_radians( theta );
532  d = stub.v + distance * M.col_x();
533 }
534 
536  Vector const &v6,
537  Vector const &v7,
538  Vector const &v8,
539  Vector const &v9,
540  Vector const &v10
541 )
542 {
543  double A[5][5];
544 
545  Vector u1(v7-v6);
546  u1.normalize();
547  Vector u2(v8-v7);
548  u2.normalize();
549  Vector u3(v9-v8);
550  u3.normalize();
551  Vector u4(v10-v9);
552  u4.normalize();
553 
554  Vector s1(u2.cross(u1));
555  s1.normalize();
556  Vector s2(u3.cross(u2));
557  s2.normalize();
558  Vector s3(u4.cross(u3));
559  s3.normalize();
560 
561  Vector r42(v9-v7);
562  Vector r43(v9-v8);
563 
564  //build matrix
565  Vector b;
566 
567  b = (u1.cross(r42));
568  A[0][0] = b.x();
569  A[1][0] = b.y();
570  A[2][0] = b.z();
571  b = (u2.cross(r43));
572  A[0][1] = b.x();
573  A[1][1] = b.y();
574  A[2][1] = b.z();
575  b = (s1.cross(r42));
576  A[0][2] = b.x();
577  A[1][2] = b.y();
578  A[2][2] = b.z();
579  b = (s2.cross(r43));
580  A[0][3] = b.x();
581  A[1][3] = b.y();
582  A[2][3] = b.z();
583  // last element is 0
584  A[0][4] = 0;
585  A[1][4] = 0;
586  A[2][4] = 0;
587 
588  // lines 4, 5 of matrix
589  b = (u1.cross(u4));
590  A[3][0] = b.x();
591  A[4][0] = b.y();
592  b = (u2.cross(u4));
593  A[3][1] = b.x();
594  A[4][1] = b.y();
595  b = (s1.cross(u4));
596  A[3][2] = b.x();
597  A[4][2] = b.y();
598  b = (s2.cross(u4));
599  A[3][3] = b.x();
600  A[4][3] = b.y();
601  b= (s3.cross(u4));
602  A[3][4] = b.x();
603  A[4][4] = b.y();
604 
605  double det;
606  Real jacobian;
607  if (get_determinant( A, 5, det ))
608  {
609  jacobian = 1.0 / std::fabs(det);
610  }
611  else
612  {
613  jacobian = -1.0;
614  }
615  return jacobian;
616 }
617 
619  //before closure
620  Vector &r0,
621  Vector &r1,
622  Vector &r2,
623  Vector &r3,
624  Vector &r4,
625  Vector &r5,
626  Vector &r6,
627  //after closure
628  Vector &p1,
629  Vector &p2,
630  Vector &p3,
631  //old angle/dih
632  Real const theta1_old,
633  Real const theta2_old,
634  Real const theta3_old,
635  Real const theta4_old,
636  Real const alpha1_old,
637  Real const alpha2_old,
638  Real const alpha3_old,
639  //new angle/dih
640  Real &theta1,
641  Real &theta2,
642  Real &theta3,
643  Real &theta4,
644  Real &alpha1,
645  Real &alpha2,
646  Real &alpha3
647 )
648 {
649  //0 [ 1 2 3 4 (5) ] 6
650  //move 'C' of res4, close 4=5
651  using numeric::x_rotation_matrix_radians;
652  using numeric::z_rotation_matrix_radians;
653  using basic::periodic_range;
654  using numeric::constants::d::pi;
655  using numeric::constants::d::pi_2;
656 
657  Real sinA1, cosA1, sinA2, cosA2;
658  Real sinO1, cosO1, /*sinO2,*/ cosO2;
659  //Real a[3],b[3],c[3],d[3],k[3],j[3],n[3],v[3];
660  Vector a, b, c, d, k, j, n, v;
661  Real k_2, j_2, v_2, va;
662  Real w, w_2, h, h_2, g, p1_2, p2_2, p3_2;
663  //Real R2[3][3], R2t[3][3];
664  //Real T0[3][3], T0t[3][3], T1[3][3], T1t[3][3], T2[3][3], T2t[3][3];
665  //xyzMatrix R2, R2t;
666  //xyzMatrix T0, T0t, T1, T1t, T2, T2t;
667  static Real const MAXDIH2 = 50.0*pi/180.0;
668  static Real const MAXANG2 = 20.0*pi/180.0;
669 
670  bool crfailed = false;
671 
672  p1_2 = p1.x()*p1.x();
673  p2_2 = p2.x()*p2.x();
674  p3_2 = p3.x()*p3.x();
675 
676  /* construct T0 */
677  a = (r2 - r1).normalize();
678  b = (r1 - r0).normalize();
679  c = a.cross(b);
680  g = a.dot(b);
681  g = std::sqrt( 1.0 - g*g );
682  c *= 1.0/g;
683  d = c.cross(a);
684  xyzMatrix T0;
685  T0.col_x(a).col_y(d).col_z(c);
686  xyzMatrix T0t(T0);
687  T0t.transpose();
688 
689  k = r4 - r2; k_2 = k.length_squared();
690  j = r4 - r1; j_2 = j.length_squared();
691 
692  cosA2 = (k_2 - p2_2 - p3_2) / (2.0*p2.x()*p3.x());
693  if (std::fabs(cosA2)>1.0)
694  {
695  //bad case
696  TR.Debug <<"can't close" << std::endl;
697  return true;
698  }
699  sinA2 = -std::sqrt( 1.0 - cosA2*cosA2 );
700  //set_rotation_matrix_Z( cosA2, sinA2, T2, T2t );
701  //sin -> minus?
702  //TR << "cos: " << cosA2 << std::endl;
703  //TR << "sin: " << sinA2 << std::endl;
704  //TR << "atan2: " << std::atan2(sinA2, cosA2)*180/pi << std::endl;
705  //TR << "acos:" << std::acos(cosA2)*180/pi << std::endl;
706  xyzMatrix T2(z_rotation_matrix_radians( std::atan2(sinA2, cosA2) ));
707  a = T2 * p3;
708  k = a + p2;
709  cosO2 = cos( theta2_old );
710  //sinO2 = sin( theta2_old ); // set but never used ~Labonte
711  //set_rotation_matrix_X( cosO2, sinO2, R2, R2t );
712  xyzMatrix R2(x_rotation_matrix_radians(theta2_old));
713  v = R2 * k;
714  v_2 = v.length_squared();
715 
716  w = (j_2 - p1_2 - v_2) / (2.0 * p1.x());
717  w_2 = w*w;
718  va = v.x()*v.x() + v.y()*v.y();
719  h_2 = va - w_2;
720 
721  if (h_2 < 0)
722  {
723  TR.Debug << "h_2=" << h_2 << std::endl;
724  crfailed = true;
725 
726  TR.Debug <<"can't close" << std::endl;
727  }
728  else
729  {
730  // do 1st branch
731  h = std::sqrt(h_2);
732  cosA1 = ( w * v.x() - v.y() * h ) / va;
733  sinA1 = -( w * v.y() + v.x() * h ) / va;
734  //set_rotation_matrix_Z( cosA1, sinA1, T1, T1t );
735  xyzMatrix T1(z_rotation_matrix_radians( std::atan2(sinA1, cosA1) ));
736 
737  a = T1 * v;
738  j = a + p1;
739 
740  a = r4 - r1;
741  n = T0t * a;
742 
743  cosO1 = ( j.z()*n.z() + j.y()*n.y() ) / (j.y()*j.y() + j.z()*j.z() );
744  sinO1 = ( j.y()*n.z() - j.z()*n.y() ) / (j.y()*j.y() + j.z()*j.z() );
745 
746  alpha1 = std::atan2( sinA1, cosA1 );
747  alpha1 += alpha1<0 ? pi : 0;
748  theta1 = std::atan2( sinO1, cosO1 );
749  alpha2 = std::atan2( sinA2, cosA2 );
750  alpha2 += alpha2<0 ? pi : 0;
751  theta2 = theta2_old;
752 
753  if (alpha1 != alpha1 || theta1 != theta1)
754  {
755  //something wrong of param calculation
756  TR.Debug << "ERROR COS SIN" << std::endl;
757  TR.Debug << "DB: A1 " << sinA1 << " " << cosA1 << std::endl;
758  TR.Debug << "DB: A2 " << sinA2 << " " << cosA2 << std::endl;
759  TR.Debug << "DB: O1 " << sinO1 << " " << cosO2 << std::endl;
760  }
761 
762  TR.Debug << "alpha1=" << alpha1*180.0/pi << " alpha2=" << alpha2*180.0/pi << std::endl;
763  //calc_cartesian2( p2[0], *alpha1, *theta1, r0, r1, r2, r3 );
764  get_xyz(r0, r1, r2, r3, p2.x(), alpha1, theta1);
765  alpha3 = numeric::angle_radians( r3, r4, r5 );
766  theta3 = numeric::dihedral_radians( r2, r3, r4, r5 );
767  theta4 = numeric::dihedral_radians( r3, r4, r5, r6 );
768 
769  //TR << "dihs: " << theta1 << " " << theta2 << " " << theta3 << " " << theta4 << std::endl;
770  //TR << "angs: " << alpha1 << " " << alpha2 << " " << alpha3 << std::endl;
771 
772  if (
773  (std::fabs(periodic_range( theta1_old-theta1, pi_2 )) > MAXDIH2) ||
774  (std::fabs(periodic_range( theta2_old-theta2, pi_2 )) > MAXDIH2) ||
775  (std::fabs(periodic_range( theta3_old-theta3, pi_2 )) > MAXDIH2) ||
776  (std::fabs(periodic_range( theta4_old-theta4, pi_2 )) > MAXDIH2) ||
777  (std::fabs(periodic_range( alpha1_old-alpha1, pi_2 )) > MAXANG2) ||
778  (std::fabs(periodic_range( alpha2_old-alpha2, pi_2 )) > MAXANG2) ||
779  (std::fabs(periodic_range( alpha3_old-alpha3, pi_2 )) > MAXANG2) ||
780  alpha1<0.017 || alpha1>3.124
781  )
782  {
783  //printf("in 2nd branch\n");
784  // do 2nd branch
785  h = std::sqrt(h_2);
786  cosA1 = ( w * v.x() + v.y() * h ) / va;
787  sinA1 = -( w * v.y() - v.x() * h ) / va; //+/-
788 
789  //set_rotation_matrix_Z( cosA1, sinA1, T1, T1t );
790  xyzMatrix T1(z_rotation_matrix_radians( std::atan2(sinA1, cosA1) ));
791  a = T1 * v;
792  j = a + p1;
793 
794  a = r4 - r1;
795  n = T0t * a;
796  cosO1 = ( j.z()*n.z() + j.y()*n.y() ) / (j.y()*j.y() + j.z()*j.z() );
797  sinO1 = ( j.y()*n.z() - j.z()*n.y() ) / (j.y()*j.y() + j.z()*j.z() );
798 
799  alpha1 = std::atan2( sinA1, cosA1 );
800  alpha1 += alpha1<0 ? pi : 0;
801  theta1 = std::atan2( sinO1, cosO1 );
802  alpha2 = std::atan2( sinA2, cosA2 );
803  alpha2 += alpha2<0 ? pi : 0;
804  theta2 = theta2_old;
805 
806  TR.Debug << "alpha1=" << alpha1*180.0/pi << " alpha2=" << alpha2*180.0/pi << std::endl;
807 
808  //calc_cartesian2( p2.x(), *alpha1, *theta1, r0, r1, r2, r3 );
809  get_xyz(r0, r1, r2, r3, p2.x(), alpha1, theta1);
810  alpha3 = numeric::angle_radians( r3, r4, r5 );
811  theta3 = numeric::dihedral_radians( r2, r3, r4, r5 );
812  theta4 = numeric::dihedral_radians( r3, r4, r5, r6 );
813 
814  //TR << "dihs: " << theta1 << " " << theta2 << " " << theta3 << " " << theta4 << std::endl;
815  //TR << "angs: " << alpha1 << " " << alpha2 << " " << alpha3 << std::endl;
816 
817  if (
818  (std::fabs(periodic_range( theta1_old-theta1, pi_2 )) > MAXDIH2) ||
819  (std::fabs(periodic_range( theta2_old-theta2, pi_2 )) > MAXDIH2) ||
820  (std::fabs(periodic_range( theta3_old-theta3, pi_2 )) > MAXDIH2) ||
821  (std::fabs(periodic_range( theta4_old-theta4, pi_2 )) > MAXDIH2) ||
822  (std::fabs(periodic_range( alpha1_old-alpha1, pi_2 )) > MAXANG2) ||
823  (std::fabs(periodic_range( alpha2_old-alpha2, pi_2 )) > MAXANG2) ||
824  (std::fabs(periodic_range( alpha3_old-alpha3, pi_2 )) > MAXANG2) ||
825  alpha1<0.017 || alpha1>3.124
826  )
827  {
828  crfailed = true;
829  }
830  }
831  }
832 
833  return crfailed;
834 }
835 
836 bool BBConRotMover::get_determinant(double a[5][5], int n, double &d)
837 {
838  int i,imax=0,j,k;
839  double big,dum,sum,temp;
840  double vv[10];
841  //int indx[10];
842 
843  d=1.0;
844  for (i=0;i<n;i++) {
845  big=0.0;
846  for (j=0;j<n;j++)
847  if ((temp=fabs(a[i][j])) > big) big=temp;
848  if (big == 0.0)
849  { //printf("Singular matrix in routine get_determinant\n");
850  //exit(1);
851  TR.Warning << "Singular matrix in routine get_determinant" << std::endl;
852  return false;
853  }
854  vv[i]=1.0/big;
855  }
856  for (j=0;j<n;j++) {
857  for (i=0;i<j;i++) {
858  sum=a[i][j];
859  for (k=0;k<i;k++) sum -= a[i][k]*a[k][j];
860  a[i][j]=sum;
861  }
862  big=0.0;
863  for (i=j;i<n;i++) {
864  sum=a[i][j];
865  for (k=0;k<j;k++)
866  sum -= a[i][k]*a[k][j];
867  a[i][j]=sum;
868  if ( (dum=vv[i]*fabs(sum)) >= big) {
869  big=dum;
870  imax=i;
871  }
872  }
873  if (j != imax) {
874  for (k=0;k<n;k++) {
875  dum=a[imax][k];
876  a[imax][k]=a[j][k];
877  a[j][k]=dum;
878  }
879  d = -(d);
880  vv[imax]=vv[j];
881  }
882  //indx[j]=imax; // set but never used ~Labonte
883  if (a[j][j] == 0.0) a[j][j]=1.0e-20;
884  if (j != (n-1)) {
885  dum=1.0/(a[j][j]);
886  for (i=j+1;i<n;i++) a[i][j] *= dum;
887  }
888  }
889 
890  for ( j = 0; j < n; j++ ) d *= a[j][j];
891 
892  return(true);
893 }
894 
895 }
896 }
897