Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DisulfPairingLibrary.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 /// @brief
11 /// @detailed
12 ///
13 ///
14 ///
15 /// @author Bjorn Wallner
16 
17 // Unit Headers
19 
20 
21 // Package Headers
23 
24 // Project Headers
25 // AUTO-REMOVED #include <core/pose/Pose.hh>
26 #include <core/types.hh>
27 // AUTO-REMOVED #include <core/conformation/Conformation.hh>
28 #include <core/kinematics/Jump.hh>
30 #include <core/kinematics/Stub.hh>
31 // AUTO-REMOVED #include <core/id/NamedStubID.hh>
32 
33 #ifdef WIN32
34 #include <core/fragment/FragID.hh>
35 #endif
37 #include <core/fragment/FragSet.hh>
42 
43 #include <basic/database/open.hh>
44 // AUTO-REMOVED #include <core/io/pdb/pose_io.hh>
45 
46 // ObjexxFCL Headers
47 #include <ObjexxFCL/FArray2A.hh>
48 
49 // Utility headers
50 #include <utility/vector1.fwd.hh>
51 #include <utility/io/izstream.hh>
52 // #include <utility/io/ozstream.hh>
53 // #include <numeric/numeric.functions.hh>
54 
55 #include <basic/Tracer.hh>
56 // #include <basic/options/option.hh>
57 // #include <basic/options/keys/OptionKeys.hh>
58 
59 // numeric headers
60 #include <numeric/random/random.hh>
61 
62 // AUTO-REMOVED #include <numeric/xyzMatrix.io.hh>
63 // AUTO-REMOVED #include <numeric/xyzVector.io.hh>
64 
65 #include <numeric/xyzMatrix.hh>
66 #include <numeric/xyzMatrix.fwd.hh>
67 //// C++ headers
68 #include <cstdlib>
69 #include <string>
70 // AUTO-REMOVED #include <ctime>
71 
73 #include <utility/vector1.hh>
74 #include <numeric/xyz.functions.hh>
75 
76 
77 static basic::Tracer tr("protocols.jumping");
78 
79 using core::Real;
80 using namespace core;
81 using namespace basic;
82 using namespace ObjexxFCL;
83 //using namespace basic::options;
84 
85 namespace protocols {
86 namespace jumping {
87 
88 /// @details Auto-generated virtual destructor
89 BaseDisulfPairingLibrary::~BaseDisulfPairingLibrary() {}
90 
91 static numeric::random::RandomGenerator RG(12345); // <- Magic number, do not change it, huaah hah ha!
92  // P.S. I GOT DIBBS ON 12345 SO IT IS ALL MINE - Robert
93 
94 //------------------------------------------------------------------------------
95 // the x-axis of this coordinate system is along the p(*,2) -> p(*,1) bond vector
96 // the y-axis is in the p(*,*) plane, with positive dot product to p(*,2) -> p(*,3) vector
97 
98 // m(*,1) is the x-axis unit vector of this new coord system expressed in
99 // the absolute coordinates defining the positions p(*,j)
100 // this corresponds to a column in the matrix m (non-CHarlie convention)
101 //
102 // thus multiplication by m can be interpreted as taking a vector in the
103 // local coordinate system defined by m and expressing it in the absolute
104 // coordinate system in which the coords p are defined
105 //
106 // by multiplication I mean non-charlie multiplication (row,col) indexing
107 //
108 // likewise, multiplication by m^t = m inverse can be thought of
109 // as expressing a vector given in absolute coords in terms of the
110 // local coordinate system defined by m
111 //
112 
113 void
115  numeric::xyzMatrix_double const & p, //FArray2A_double p, // input
116  numeric::xyzMatrix_double & m //FArray2A_double m // output
117 )
118 {
119  using namespace numeric;
120 
121  xyzVector_double a1 = p.col_x() - p.col_y();
122  xyzVector_double a2 = p.col_z() - p.col_y();
123  a1.normalize();
124  xyzVector_double a3 = cross( a1, a2 );
125  a3.normalize();
126  a2 = cross( a3, a1 );
127 
128  m = xyzMatrix_double::cols( a1, a2, a3 );
129 }
130 
131 void
133  FArray2A_float pos,
134  numeric::xyzMatrix_double & p
135 )
136 {
137  pos.dimension( 3, 5 );
138  using namespace numeric;
139 
140  xyzVector_double n( &pos(1,1) );
141  xyzVector_double ca( &pos(1,2) );
142  xyzVector_double c( &pos(1,4) );
143 
144  p = xyzMatrix_double::cols( n, ca, c );
145 
146 }
147 
148 numeric::xyzMatrix_double
149 dis_get_ncac ( FArray2A_float pos )
150 {
151  pos.dimension( 3, 5 );
152  using namespace numeric;
153 
154  xyzVector_double n( &pos(1,1) );
155  xyzVector_double ca( &pos(1,2) );
156  xyzVector_double c( &pos(1,4) );
157 
158  return xyzMatrix_double::cols( n, ca, c );
159 }
160 
161 
162 //helper code to make an RT from two Epos
163 // does this live somewhere else in mini, haven't found it !
165 RT dis_RT_from_epos( FArray2A_float Epos1, FArray2A_float Epos2)
166 {
167  /// rotation matrix, written in stub1 frame
168  RT::Matrix rotation( 0.0 ); // 3x3
169  /// tranlsation vector, written in stub1 frame
170  RT::Vector translation( 0.0 ); // 3
171 
172  Size const MAX_POS( 5 ); // param::MAX_POS
173  Epos1.dimension(3,MAX_POS);
174  Epos2.dimension(3,MAX_POS);
175 
176  //bool const local_debug ( false );
177 
178  numeric::xyzMatrix_double p1, p2, m1, m2;
179 
180  // get coordinate systems from both residues
181  dis_get_ncac(Epos1,p1);
182  dis_get_ncac(Epos2,p2);
185 
186  // consider this: |xx xy xz|
187  // coordinate frame M = |yx yy yz|
188  // |zx zy zz|
189  // each column is a unit vector written in genuine frame.
190  //
191  // vector A in frame M can be rewritten as B in genuine frame
192  // by the formula B = M x A, thus A = M^T x B
193  // a simple example of this would be: the unit vector (1,0,0) in frame M
194  // is actually (xx,yx,zx) in genuine frame. mathematically,
195  // |xx| |xx xy xz| |1|
196  // |yx| = |yx yy yz| x |0| ==> B = M x A
197  // |zx| |zx zy zz| |0|
198  //
199  // the above formula has another layer of meaning: rotation
200  // keeping the genuine frame fixed, a vector can be rotated by applying
201  // matrix M onto it, e.g., (1,0,0) rotated to (xx,yx,zx)
202 
203  numeric::xyzVector_double e1( &Epos1(1,2) );
204  numeric::xyzVector_double e2( &Epos2(1,2) );
205 
206  // ( e2 - e1 ) is the vector in genuine frame,
207  // translation is the vector in m1 frame. so m1^T is multiplied.
208  translation = m1.transposed() * ( e2 - e1 );
209 
210  // let's look at the rotation matrix
211  // A, B, C are three vectors in genuine frame and are related by rotation
212  // B = M1 x A; C = M2 x A;
213  // ==> A = M1^T x B = M2^T x C
214  // ==> C = M2 x M1^T x B
215  // but note that C and B are both in genuine frame and we want a rotation
216  // matrix to be applied onto a vector in M1 frame, so comes another step of
217  // conversion -- left-multiply M1^T on both sides:
218  // M1^T x C = M1^T x M2 x M1^T x B
219  // C' = M1^T x M2 x B', as C' and B' are written in M1 frame.
220  // so we get the rotation matrix as M1^T x M2.
221  // but wait a minute, what Phil orginally got below is M2^T x M1 and it is
222  // impossible for that to be wrong, then what happens?
223 
224  // It turns out when this rotation matrix is further applied to a vector,
225  // it uses Charlies' (col,row) convention (see Dvect_multiply()
226  // in RT::make_jump) which means there is one more transpose to do.
227  // Now an agreement is reached:
228  // (M2^T x M1)^T = M1^T x (M2^T)^T = M1^T x M2
229  // since xyzMatrix uses the normal (row,col) convention, we will switch to
230  // rotation = M1^T x M2
231 
232  rotation = m1.transposed() * m2;
233  /************************Phil's legacy code *********************/
234  // rotation(j,*) is the j-th unit vector of 2nd coord sys written in 1st coord-sys
235  // for ( int i=1; i<=3; ++i ) {
236  // for ( int j=1; j<=3; ++j ) {
237  // // DANGER: not sure about the order... ////////////////////////
238  // // should sync with make_jump
239  // rotation(j,i) = Ddotprod( m1(1,i), m2(1,j) ); // 2nd guess
240  // //rotation(j,i) = Ddotprod( m1(1,j), m2(1,i) ); // 1st guess
241  // }
242  // }
243  /************************Phil's legacy code ********************/
244  RT rt;
245  rt.set_translation( translation );
246  rt.set_rotation( rotation );
247 
248  return rt;
249 #if 0
250  if (local_debug ) {
251  std::cout << " p1:\n" << p1 << std::endl;
252  std::cout << " p2:\n" << p2 << std::endl;
253  std::cout << " m1:\n" << m2 << std::endl;
254  std::cout << " m2:\n" << m2 << std::endl;
255  std::cout << " translation:\n" << translation << std::endl;
256  std::cout << " rotation:\n" << rotation << std::endl;
257  // debug building: ////////////////
258  FArray2D_float tmp_pos1(3,MAX_POS), tmp_pos2(3,MAX_POS);
259 
260  for ( int i=1; i<= MAX_POS; ++i ) {
261  for ( int j=1; j<= 3; ++j ) {
262  tmp_pos1(j,i) = Epos1(j,i);
263  tmp_pos2(j,i) = Epos2(j,i);
264  }
265  }
266 
267  double forward_dev(0), forward_dev2(0), backward_dev(0);
268 
269  // first: make the jump forward
270  make_jump( tmp_pos1, tmp_pos2 );
271  std::cout << "tmp_pos1:\n" << tmp_pos1 << std::endl;
272  std::cout << "tmp_pos2:\n" << tmp_pos2 << std::endl;
273  for ( int i=1; i<= MAX_POS; ++i ) {
274  if ( i==1 || i==2 || i == 4 ) {
275  for ( int j=1; j<= 3; ++j ) {
276  forward_dev += std::abs( Epos2(j,i) - tmp_pos2(j,i) );
277  }
278  }
279  }
280 
281  // now make backward:
282  reverse();
283  make_jump( tmp_pos2, tmp_pos1 );
284  std::cout << "tmp_pos1:\n" << tmp_pos1 << std::endl;
285  std::cout << "tmp_pos2:\n" << tmp_pos2 << std::endl;
286  for ( int i=1; i<= MAX_POS; ++i ) {
287  if ( i==1 || i==2 || i == 4 ) {
288  for ( int j=1; j<= 3; ++j ) {
289  backward_dev += std::abs( Epos1(j,i) - tmp_pos1(j,i) );
290  }
291  }
292  }
293 
294  //restore original direction
295  reverse();
296 
297  // final sanity check:
298  make_jump( tmp_pos1, tmp_pos2 );
299  std::cout << "tmp_pos1:\n" << tmp_pos1 << std::endl;
300  std::cout << "tmp_pos2:\n" << tmp_pos2 << std::endl;
301  for ( int i=1; i<= MAX_POS; ++i ) {
302  if ( i==1 || i==2 || i == 4 ) {
303  for ( int j=1; j<= 3; ++j ) {
304  forward_dev2 += std::abs( Epos2(j,i) - tmp_pos2(j,i) );
305  }
306  }
307  }
308 
309  std::cout << "RT::RT: debug make_jump:"
310  << " fdev= " << F(9,6,forward_dev)
311  << " bdev= " << F(9,6,backward_dev)
312  << " fdev2= " << F(9,6,forward_dev2) << std::endl;
313  } // if (local_debug )
314 #endif
315 }
316 
317 
318 DisulfTemplate::DisulfTemplate ( std::string const& s1, std::string const& s2, std::string const& s3 ) :
319  phi ( 2, 0.0 ),
320  psi ( 2, 0.0 ),
321  omega( 2, 0.0 ),
322  secstruct(2,'H')
323 {
324  atoms_downstream_.reserve(3);
325  atoms_downstream_.push_back( s1 );
326  atoms_downstream_.push_back( s2 );
327  atoms_downstream_.push_back( s3 );
329 }
330 
331 DisulfTemplate::DisulfTemplate ( std::string const& c, std::string const& s1, std::string const& s2, std::string const& s3 ) :
332  phi ( 2, 0.0 ),
333  psi ( 2, 0.0 ),
334  omega( 2, 0.0 ),
335  secstruct(2,'H')
336 {
337  atoms_downstream_.reserve(4);
338  atoms_downstream_.push_back( c );
339  atoms_downstream_.push_back( s1 );
340  atoms_downstream_.push_back( s2 );
341  atoms_downstream_.push_back( s3 );
343 }
344 
345 
346 
347 
348 
349 ///////////////////////////////////////////////////////////////////////////////
350 void
352 {
353  //const float MAX_NO_DIST ( 3.1 );
354  std::string line,res1,res2;
355  std::string tag,filename;
356  int pos1,pos2,seq_sep;
357  char ss1, ss2;
358  //float o,p1,p2,mn_dist,mx_dist,
359  //phi1,psi1,omega1,phi2,psi2,omega2;
360  Size const MAX_POS( 5 ); // param::MAX_POS
361  FArray2D_float Epos1(3,MAX_POS), Epos2(3,MAX_POS);
362  utility::io::izstream data( fn ); //or from database file
363 
364  RT this_rt;
365 
366  while ( getline( data,line ) ) {
367  std::istringstream is( line );
368 
369 
370  is >> tag >> filename >> pos1 >> pos2 >> res1 >> res2 >>
371  ss1 >> ss2 >> seq_sep >> this_rt;
372 
373  if ( is.fail() || tag != "DISULF" ) continue;
374 
375  // fill in a new pairing template
376  protocols::jumping::DisulfTemplate t("CA","N","CA","C");
377  t.rt_ = this_rt;
378 
379  //ANGLES NOT CURRENTLY DEFINED IN LIBRARY
380  //TAKE THEM OUT OF TEMPLATE?
381 
382  //t.phi (1) = phi1;
383  //t.phi (2) = phi2;
384  //t.psi (1) = psi1;
385  //t.psi (2) = psi2;
386  //t.omega (1) = omega1;
387  //t.omega (2) = omega2;
388 
389  all_pairings_.push_back( t );
390 
391  pairings_[ std::make_pair( 1, 1 ) ].push_back( t );
392 
394  }
395 }
396 
397 /// @details puts all jump-geometries that fit the orientation and pleating into
398 /// list of FragData's. Try to reuse these FragData for different Frames that have same orientation and pleating
400  bool bWithTorsion,
402 ) const {
403  using namespace core::fragment;
404 
405  // read_jump_templates(); // self-initializing
406  runtime_assert( all_pairings_.size() > 0 );
407 
408  const DisulfTemplateList & templates
409  ( all_pairings_ );
410 
411  const int ntemplates ( templates.size() );
412  const int iStart( 1 ); // in templates start residue is number 1
413  const int iStop ( 2 ); // in templates stop residue is number 2
414  frags.reserve( ntemplates );
415  for ( DisulfTemplateList::const_iterator it=templates.begin(), eit=templates.end();
416  it!=eit; ++it ) {
417  frags.push_back( new FragData );
418  if ( bWithTorsion ) {
419  BBTorsionSRFDOP start = new BBTorsionSRFD( 3, 'E', 'X' );
420  start->set_torsion( 1, it->phi( iStart ) );
421  start->set_torsion( 2, it->psi( iStart ) );
422  start->set_torsion( 3, it->omega( iStart ) );
423 
424  frags.back()->add_residue( start );
425  }
426 
427  frags.back()->add_residue( new UpJumpSRFD() );
428  frags.back()->add_residue( new DownJumpSRFD( it->rt_, it->atoms_downstream_, it->atoms_upstream_, 'X' ) );
429 
430  if ( bWithTorsion ) {
431  BBTorsionSRFDOP stop = new BBTorsionSRFD( 3, 'E', 'X' );
432  stop->set_torsion( 1, it->phi( iStop ) );
433  stop->set_torsion( 2, it->psi( iStop ) );
434  stop->set_torsion( 3, it->omega( iStop ) );
435 
436  frags.back()->add_residue( stop );
437  }
438  frags.back()->set_valid(); // yes there is data in this Fragment
439  } // for-loop
440 } // create_jump_fragments
441 
442 void
444  DisulfPairingsList const& pairings,
445  kinematics::MoveMap const& mm,
446  bool bWithTorsion,
447  core::fragment::FragSet& frags_accumulator
448 ) {
449 
450  fragment::FragDataList frag_data;
451  create_jump_fragments( bWithTorsion, frag_data );
452 
453  for ( Size jump_nr = 1; jump_nr <= pairings.size(); ++jump_nr) {
454 
455  //int const jump_nr ( jump_nr );
456  int const startpos( pairings[ jump_nr ].pos1 );
457  int const endpos( pairings[ jump_nr ].pos2 );
458 
459  if ( mm.get_bb( startpos ) && mm.get_bb( endpos ) ) {
460  Size const length( bWithTorsion ? 4 : 2 );
461  runtime_assert( length == frag_data.front()->size() );
462  fragment::JumpingFrameOP frame = generate_empty_jump_frame( startpos, endpos, length );
463  frame->add_fragment( frag_data );
464  frags_accumulator.add( frame );
465  } else {
466  utility_exit_with_message("need to implement this: make ss-library fragments that only contain those torsions for residues\
467  that can move according to movemap -- call this function with \
468  bWithTorsions = false ... and it works for now");
469  }
470  }
471 } // method
472 
473 
474 
476 
478  if ( instance_ == NULL ) {
479  instance_ = new StandardDisulfPairingLibrary();
480  std::cout << "READING START" << std::endl;
481  instance_->read_from_file( basic::database::full_name("sampling/disulfide_jump_database_wip.dat") );
482  std::cout << "READING END" << std::endl;
483  };
484  return instance_;
485 }
486 
487 } // jumping
488 } // protocols