Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
StepWiseUtil.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 StepWiseRNAResidueSampler
11 /// @brief Not particularly fancy, just minimizes a list of poses.
12 /// @detailed
13 /// @author Rhiju Das
14 
15 
16 //////////////////////////////////
20 
21 //////////////////////////////////
22 #include <core/types.hh>
27 #include <basic/options/option.hh>
28 #include <basic/options/keys/in.OptionKeys.gen.hh>
29 #include <core/pose/Pose.hh>
30 
31 #include <core/pose/util.hh>
32 #include <core/id/AtomID.hh>
33 #include <core/id/AtomID_Map.hh>
34 #include <core/pose/util.tmpl.hh>
40 #include <numeric/conversions.hh>
41 #include <numeric/xyz.functions.hh>
42 #include <numeric/xyzMatrix.hh>
43 #include <utility/tools/make_vector1.hh>
44 #include <utility/io/izstream.hh>
45 
46 #include <iostream>
47 #include <fstream>
48 #include <sstream>
49 #include <ObjexxFCL/format.hh>
50 #include <set>
51 
52 
53 //Auto Headers
55 #include <utility/vector1.hh>
56 using namespace core;
57 using numeric::conversions::degrees;
58 using numeric::conversions::radians;
59 
60 
61 namespace protocols {
62 namespace swa {
63 
64  //////////////////////////////////////////////////////////////////////////
65  Size
66  make_cut_at_moving_suite( pose::Pose & pose, Size const & moving_suite ){
67 
69  // Size jump_at_moving_suite( 0 );
70  f.new_jump( moving_suite, moving_suite+1, moving_suite );
71  pose.fold_tree( f );
72 
73  int const i( moving_suite ), j( moving_suite+1 );
74  for ( Size n = 1; n <= f.num_jump(); n++ ) {
75  if ( f.upstream_jump_residue(n) == i && f.downstream_jump_residue(n) == j ) return n;
76  if ( f.upstream_jump_residue(n) == j && f.downstream_jump_residue(n) == i ) return n;
77  }
78 
79  utility_exit_with_message( "Problem with jump number" );
80 
81  return 0; // we never get here.
82  }
83 
84  ///////////////////////////////////////////////////////////////////////////////////////
85  bool
87 
88  for(Size seq_num = 1; seq_num <= pose.total_residue(); seq_num++) {
89 
90  if ( !pose.residue( seq_num ).has_variant_type( chemical::CUTPOINT_LOWER ) ) continue;
91  if ( !pose.residue( seq_num+1 ).has_variant_type( chemical::CUTPOINT_UPPER ) ) continue;
92 
93  return true;
94  }
95  return false;
96  }
97 
98  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
99  bool
100  Contain_seq_num(Size const & seq_num, utility::vector1< core::Size > const & residue_list){
101  for(Size j=1; j<=residue_list.size(); j++){
102  if(seq_num==residue_list[j]) {
103  return true;
104  }
105  }
106  return false;
107  }
108 
109  //////////////////////////////////////////////////////////////////////////////////////////////////////
110  void
111  Output_boolean(std::string const & tag, bool boolean){
112 
113  using namespace ObjexxFCL;
114  using namespace ObjexxFCL::fmt;
115  std::cout << tag;
116 
117  if(boolean==true){
118  std::cout << A(4,"T");
119  } else {
120  std::cout << A(4,"F");
121  }
122  }
123 
124  //////////////////////////////////////////////////////////////////////////////////////////////////////
125  void
126  Output_boolean(bool boolean){
127 
128  using namespace ObjexxFCL;
129  using namespace ObjexxFCL::fmt;
130 
131  if(boolean==true){
132  std::cout << A(4,"T");
133  } else {
134  std::cout << A(4,"F");
135  }
136  }
137 
138  //////////////////////////////////////////////////////////////////////////////////////////////////////
139  void
140  Output_movemap(kinematics::MoveMap const & mm, Size const total_residue){
141 
142  using namespace ObjexxFCL;
143  using namespace ObjexxFCL::fmt;
144  using namespace core::kinematics;
145  using namespace core::id;
146  Size spacing=10;
147 
148  std::cout << "Movemap (in term of partial_pose seq_num): " << std::endl;
149  std::cout << A(spacing,"res_num") << A(spacing,"alpha") << A(spacing,"beta") << A(8,"gamma") << A(8,"delta") <<A(8,"eplison") <<A(8,"zeta");
150  std::cout << A(spacing,"chi_1") << A(spacing,"nu_2") << A(spacing,"nu_1") << A(8,"chi_O2") << std::endl;
151 
152  for(Size n=1; n<= total_residue; n++){
153 
154  std::cout << I(spacing, 3 , n);
155  Output_boolean(mm.get(TorsionID( n , id::BB, 1 ))); A(spacing-4, "");
156  Output_boolean(mm.get(TorsionID( n , id::BB, 2 ))); A(spacing-4, "");
157  Output_boolean(mm.get(TorsionID( n , id::BB, 3 ))); A(spacing-4, "");
158  Output_boolean(mm.get(TorsionID( n , id::BB, 4 ))); A(spacing-4, "");
159  Output_boolean(mm.get(TorsionID( n , id::BB, 5 ))); A(spacing-4, "");
160  Output_boolean(mm.get(TorsionID( n , id::BB, 6 ))); A(spacing-4, "");
161  Output_boolean(mm.get(TorsionID( n , id::CHI, 1 ))); A(spacing-4, "");
162  Output_boolean(mm.get(TorsionID( n , id::CHI, 2 ))); A(spacing-4, "");
163  Output_boolean(mm.get(TorsionID( n , id::CHI, 3 ))); A(spacing-4, "");
164  Output_boolean(mm.get(TorsionID( n , id::CHI, 4 ))); A(spacing-4, "");
165  std::cout << std::endl;
166  }
167  }
168 
169  ////////////////////////////////////////////////////////////////////////////////////
170  // This is similar to code in RNA_Minimizer.cc
171  void
173  utility::vector1< core::Size > const & fixed_res,
174  bool const move_takeoff_torsions,
175  bool const move_jumps_between_chains
176  )
177  {
178 
179  using namespace core::id;
180 
181  Size const nres( pose.total_residue() );
182 
183  ObjexxFCL::FArray1D< bool > allow_insert( nres, true );
184  for (Size i = 1; i <= fixed_res.size(); i++ ) allow_insert( fixed_res[ i ] ) = false;
185  for (Size n = 1; n <= pose.total_residue(); n++ ){
186  if ( pose.residue( n ).has_variant_type( "VIRTUAL_RESIDUE" ) ) allow_insert( n ) = false;
187  }
188 
189  mm.set_bb( false );
190  mm.set_chi( false );
191  mm.set_jump( false );
192 
193  std::cout << "ALLOWING BB TO MOVE: ";
194  for (Size i = 1; i <= nres; i++ ) {
195 
196  //std::cout << "ALLOW INSERT " << i << " " << allow_insert(i) << std::endl;
197  if ( !move_takeoff_torsions && !allow_insert(i) ) continue; // don't allow, e.g., psi/omega of residue before loop to move.
198 
199  utility::vector1< TorsionID > torsion_ids;
200 
201  for ( Size torsion_number = 1; torsion_number <= pose.residue( i ).mainchain_torsions().size(); torsion_number++ ) {
202  torsion_ids.push_back( TorsionID( i, id::BB, torsion_number ) );
203  }
204  for ( Size torsion_number = 1; torsion_number <= pose.residue( i ).nchi(); torsion_number++ ) {
205  torsion_ids.push_back( TorsionID( i, id::CHI, torsion_number ) );
206  }
207 
208 
209  for ( Size n = 1; n <= torsion_ids.size(); n++ ) {
210 
211  TorsionID const & torsion_id = torsion_ids[ n ];
212 
213  id::AtomID id1,id2,id3,id4;
214  bool fail = pose.conformation().get_torsion_angle_atom_ids( torsion_id, id1, id2, id3, id4 );
215  if (fail) continue;
216 
217  // If there's any atom that is in a moving residue by this torsion, let the torsion move.
218  // should we handle a special case for cutpoint atoms? I kind of want those all to move.
219  if ( !allow_insert( id1.rsd() ) && !allow_insert( id2.rsd() ) && !allow_insert( id3.rsd() ) && !allow_insert( id4.rsd() ) ) continue;
220  mm.set( torsion_id, true );
221 
222  if ( n == 1 ) std::cout << ' ' << i;
223 
224  }
225 
226  }
227  std::cout << std::endl;
228 
229  utility::vector1< Size > chain_index;
230  Size chain_number( 0 );
231  for (Size n = 1; n <= pose.total_residue(); n++ ){
232  if ( pose.residue_type( n ).is_lower_terminus() && !pose.residue_type( n ).has_variant_type( chemical::N_ACETYLATION ) ) chain_number++;
233  chain_index.push_back( chain_number );
234  }
235 
236  // for (Size n = 1; n <= pose.total_residue(); n++ ) std::cout << "CHAIN "<< n << ' ' << chain_index[ n ] << std::endl;
237 
238  for (Size n = 1; n <= pose.fold_tree().num_jump(); n++ ){
239  Size const jump_pos1( pose.fold_tree().upstream_jump_residue( n ) );
240  Size const jump_pos2( pose.fold_tree().downstream_jump_residue( n ) );
241 
242  if ( allow_insert( jump_pos1 ) || allow_insert( jump_pos2 ) ) {
243  mm.set_jump( n, true );
244  std::cout << "allow_insert ALLOWING JUMP " << n << " to move. It connects " << jump_pos1 << " and " << jump_pos2 << "." << std::endl;
245  }
246 
247  if ( move_jumps_between_chains ){
248  if ( chain_index[ jump_pos1 ] != chain_index[ jump_pos2 ] ){
249  std::cout << "move_jumps_between_chains ALLOWING JUMP " << n << " to move. It connects " << jump_pos1 << " and " << jump_pos2 << "." << std::endl;
250  }
251  }
252 
253  }
254 
255  }
256 
257  ///////////////////////////////////////////////////////////////////////////////
258 
259  ///////////////////////////////////////////////////////////////////////////////
260  void
262  core::pose::Pose const & pose,
263  utility::vector1< core::Size > const & slice_res )
264  {
265  using namespace core::pose;
266  using namespace core::chemical;
267  using namespace core::conformation;
268  using namespace core::scoring::rna;
269 
270  new_pose.clear();
271 
272  for ( Size i = 1; i <= slice_res.size(); i++ ) {
273 
274  ResidueOP residue_to_add = pose.residue( slice_res[ i ] ).clone() ;
275 
276  if ( (i > 1 && ( slice_res[i] != slice_res[i-1] + 1 )) /*new segment*/ || residue_to_add->is_lower_terminus() || residue_to_add->has_variant_type( "N_ACETYLATION") || (i>1 && pose.fold_tree().is_cutpoint( slice_res[i-1] ) ) ){
277  if( residue_to_add->is_RNA() && (i>1) && new_pose.residue_type(i-1).is_RNA() ){
278 
279  new_pose.append_residue_by_jump( *residue_to_add, i-1,
280  chi1_torsion_atom( new_pose.residue(i-1) ),
281  chi1_torsion_atom( *residue_to_add ), true /*new chain*/ );
282  } else {
283 
284  new_pose.append_residue_by_jump( *residue_to_add, i-1, "", "", true /*new chain*/ );
285  }
286  } else {
287 
288  new_pose.append_residue_by_bond( *residue_to_add ) ;
289  }
290  }
291 
292  // //how about a new fold tree?
293  // core::kinematics::FoldTree f( new_pose.total_residue() );
294  // for ( Size i = 1; i < slice_res.size(); i++ ) {
295  // if ( slice_res[i+1] > (slice_res[i]+1) ){
296  // f.new_jump( i, i+1, i);
297  // }
298  // }
299  // new_pose.fold_tree( f );
300 
301  }
302 
303  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
304  void
306  utility::vector1< core::Size > const & slice_res ){
307 
308  pose::Pose mini_pose;
309  pdbslice( mini_pose, pose, slice_res );
310  pose = mini_pose;
311 
312  }
313 
314  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
317  pose::Pose const & ref_pose,
318  utility::vector1< core::Size > const & superimpose_res ){
319 
320  std::map< core::Size, core::Size > res_map;
321 
322  // if( ref_pose.sequence()!=mod_pose.sequence() ){
323  // utility_exit_with_message( "ref_pose.sequence()!=mod_pose.sequence()");
324  // }
325 
326  for ( Size seq_num = 1; seq_num <= mod_pose.total_residue(); ++seq_num ) {
327  if ( !Contain_seq_num(seq_num, superimpose_res ) ) continue;
328  res_map[ seq_num ] = seq_num;
329  }
330 
331  return create_alignment_id_map( mod_pose, ref_pose, res_map );
332  }
333 
334  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
337  pose::Pose const & ref_pose,
338  std::map< core::Size, core::Size > res_map ){
339 
340  using namespace chemical;
341  using namespace protocols::swa::protein;
342  using namespace protocols::swa::rna;
343  using namespace core::id;
344 
345  AtomID_Map< AtomID > atom_ID_map;
346  pose::initialize_atomid_map( atom_ID_map, mod_pose, BOGUS_ATOM_ID );
347 
348  for ( Size seq_num = 1; seq_num <= mod_pose.total_residue(); ++seq_num ) {
349 
350  if ( mod_pose.residue( seq_num ).is_RNA() && res_map.find( seq_num ) != res_map.end() && res_map[ seq_num ] > 0) {
351  // Parin please update this function!!! Can't we just superimpose over C4*?
352  setup_suite_atom_id_map( mod_pose, ref_pose, seq_num, res_map[ seq_num ], atom_ID_map);
353 
354  } else if ( mod_pose.residue( seq_num ).is_protein() ){ // superimpose over CA.
355  setup_protein_backbone_atom_id_map( mod_pose, ref_pose, seq_num, res_map[ seq_num ], atom_ID_map); // This will superimpose over N, C-alpha, C
356  }
357 
358  }
359 
360  return atom_ID_map;
361 
362  }
363 
364 
365 
366  //////////////////////////////////////////////////////////////////////////////////////
369  utility::vector1< Size > const & working_res
370  ) {
371 
372  if ( res_vector.size() == 0 ) return res_vector;
373 
374  if ( working_res.size() == 0 ) return res_vector;
375 
376  std::map< Size, Size > full_to_sub;
377  for ( Size i = 1; i <= working_res.size(); i++ ) {
378  full_to_sub[ working_res[ i ] ] = i;
379  }
380 
381  utility::vector1< Size > convert_res_vector;
382 
383  for ( Size i = 1; i <= res_vector.size(); i++ ) {
384  if ( full_to_sub.find( res_vector[ i ] ) == full_to_sub.end() ) continue;
385  convert_res_vector.push_back( full_to_sub[ res_vector[ i ] ] );
386  }
387 
388  return convert_res_vector;
389 
390  }
391 
392 
393  ///////////////////////////////////////////////////////////////////////////////
394  // Currently only handles atom pair constraints.
395  ///////////////////////////////////////////////////////////////////////////////
398  utility::vector1< core::Size > const & slice_res,
399  pose::Pose const & pose,
400  pose::Pose const & full_pose )
401  {
402 
403  using namespace core::scoring;
404  using namespace core::scoring::constraints;
405  using namespace core::id;
406 
408 
409  ConstraintCOPs csts( cst_set->get_all_constraints() );
410 
411  // std::map< Size, Size > slice_map;
412  // for (Size i = 1; i <= slice_res.size(); i++) slice_map[ slice_res[ i ] ] = i;
413  utility::vector1< Size > mapping( full_pose.total_residue(), 0);
414  for (Size i = 1; i <= slice_res.size(); i++) mapping[ slice_res[ i ] ] = i;
415  SequenceMappingOP smap = new SequenceMapping( mapping );
416 
417  for ( Size n = 1; n <= csts.size(); n++ ) {
418 
419  ConstraintCOP const & cst( csts[n] );
420  ConstraintOP cst_new = cst->remapped_clone( full_pose, pose, smap );
421  if ( cst_new ) {
422  cst_set_new->add_constraint( cst_new );
423  // std::cout << "HEY CONSTRAINTS!!! "
424  // << cst_new->atom(1).rsd() << " " << pose.residue_type( cst_new->atom(1).rsd() ).atom_name( cst_new->atom(1).atomno() )
425  // << " to "
426  // << cst_new->atom(2).rsd() << " " << pose.residue_type( cst_new->atom(2).rsd() ).atom_name( cst_new->atom(2).atomno() ) << std::endl;
427  }
428 
429  // currently only defined for pairwise distance constraints,
430  // and coordinate constraints
431  // if ( cst->score_type() == atom_pair_constraint) {
432 
433 // Size const i = cst->atom( 1 ).rsd();
434 // Size const j = cst->atom( 2 ).rsd();
435 // // Size const dist( shortest_path_in_fold_tree.dist( i , j ) );
436 // // if ( dist > separation_cutoff ) continue;
437 
438 // if ( slice_map.find( i ) == slice_map.end() ) continue;
439 // if ( slice_map.find( j ) == slice_map.end() ) continue;
440 
441 // std::cout << "CST MAP: " << i << " " << slice_map[ i] << " " << j << " " << slice_map[ j ] << std::endl;
442 
443 // std::string const & atom_name1 = full_pose.residue_type( i ).atom_name( cst->atom(1).atomno() );
444 // std::string const & atom_name2 = full_pose.residue_type( j ).atom_name( cst->atom(2).atomno() );
445 
446 // AtomID atom1_new( named_atom_id_to_atom_id( NamedAtomID( atom_name1, slice_map[ i ] ), pose );
447 // AtomID atom2_new( named_atom_id_to_atom_id( NamedAtomID( atom_name2, slice_map[ j ] ), pose );
448 
449 // ConstraintOP cst_new = new AtomPairConstraint( atom1_new, atom2_new,
450 // cst->get_func().clone() /*is this defined?*/, cst->score_type() );
451 
452 // if ( cst_new ) cst_set_new->add_constraint( cst_new );
453 
454 
455  // } else if ( cst->score_type() == coordinate_constraint) {
456 
457 
458 
459 
460  }
461 
462 
463  std::cout << "NUM CONSTRAINTS " << cst_set_new->get_all_constraints().size() << " out of " <<
464  csts.size() << std::endl;
465 
466  return cst_set_new;
467  }
468 
469 
470  ////////////////////////////////////////////////////////
471  // Move ths out of stepwise_protein_test.cc!!
472  ////////////////////////////////////////////////////////
473  /////////////////////////////////////////////////
475  {
476  using basic::options::option;
477  using utility::vector1;
478  using namespace basic::options::OptionKeys;
479 
480  // concatenate -s and -l flags together to get total list of PDB files
481  vector1< std::string > pdb_file_names;
482  if ( option[ in::file::s ].active() ) {
483  pdb_file_names = option[ in::file::s ]().vector(); // make a copy (-s)
484  }
485 
486  vector1< std::string > list_file_names;
487  if ( option[ in::file::l ].active() )
488  list_file_names = option[ in::file::l ]().vector(); // make a copy (-l)
489  if ( option[ in::file::list ].active() ){
490  vector1< std::string > better_list_file_names;
491  better_list_file_names= option[in::file::list ]().vector(); // make a copy (-list)
492  for(vector1< std::string >::iterator i = better_list_file_names.begin(), i_end = better_list_file_names.end(); i != i_end; ++i) {
493  list_file_names.push_back(*i); // make a copy (-l)
494  }
495  }
496 
497  for(vector1< std::string >::iterator i = list_file_names.begin(), i_end = list_file_names.end(); i != i_end; ++i) {
498  std::string filename( *i );
499  utility::io::izstream data( filename.c_str() );
500  if ( !data.good() ) {
501  utility_exit_with_message( "Unable to open file: " + filename + '\n' );
502  }
503  std::string line;
504  while( getline(data, line) ) {
505  pdb_file_names.push_back( std::string(line) );
506  }
507  data.close();
508  }
509 
510  return pdb_file_names;
511  }
512 
513 
514  ///////////////////////////////////////////////////////////////////////
516  get_file_name( std::string const & silent_file, std::string const & tag )
517  {
518  Size pos( silent_file.find( ".out" ) );
519  std::string silent_file_sample( silent_file );
520  silent_file_sample.replace( pos, 4, tag+".out" );
521  return silent_file_sample;
522 
523  }
524 
525  ///////////////////////////////////////////////////////////////////////
526  void
528  core::scoring::ScoreFunctionOP & scorefxn ){
529 
530  using namespace core::scoring;
531 
532  if ( pose.constraint_set()->has_constraints() ) {
533  if ( scorefxn->has_zero_weight( atom_pair_constraint ) ||
534  scorefxn->has_zero_weight( coordinate_constraint ) ) {
535  utility_exit_with_message( "Since we want constraints, need to use a scorefunction with non-zero atom_pair_constraint and coordinate_constraint weight");
536  }
537  }
538 
539  }
540 
541 
542  ///////////////////////////////////////////////////////////////////////
545  utility::vector1< Size > const & vec2 ){
546 
547  std::map< Size, bool > silly_map;
548  for ( Size n = 1; n <= vec1.size(); n++ ) silly_map[ vec1[n] ] = true;
549  for ( Size n = 1; n <= vec2.size(); n++ ) silly_map[ vec2[n] ] = true;
550 
551  utility::vector1< Size > merged_vec;
552  for ( std::map<Size,bool>::iterator it = silly_map.begin(); it != silly_map.end(); it++ ){
553  merged_vec.push_back( it->first );
554  }
555  return merged_vec;
556 
557  }
558 
559  ///////////////////////////////////////////////////////////////////////
560  void
562  Matrix & M,
563  Real const & alpha,
564  Real const & beta,
565  Real const & gamma,
566  Vector const & /* axis1 not actually used*/,
567  Vector const & axis2,
568  Vector const & axis3
569  )
570  {
571  // Z-axis assumed to be long axis.
572  Matrix M1 = numeric::rotation_matrix( axis3, Real( radians( alpha ) ) );
573  Matrix M2 = numeric::rotation_matrix( axis2, Real( radians( beta ) ) );
574  Matrix M3 = numeric::rotation_matrix( axis3, Real( radians( gamma ) ) );
575 
576  M = M3 * M2 * M1;
577  }
578 
579  ///////////////////////////////////////////////////////////////////////
580  void
582  Matrix & M,
583  Real const & alpha,
584  Real const & beta,
585  Real const & gamma )
586  {
587  static Vector const axis1( 1.0, 0.0, 0.0 );
588  static Vector const axis2( 0.0, 1.0, 0.0 );
589  static Vector const axis3( 0.0, 0.0, 1.0 );
590  create_euler_rotation( M, alpha, beta, gamma, axis1, axis2, axis3 );
591  }
592 
593  //////////////////////////////////////////////////////////////////////////////////
594  void
595  get_euler_angles( Real & alpha, Real & beta, Real & gamma, Matrix M1, Matrix M2, bool const verbose /*=true*/ ){
596 
597  Matrix M_test = M2;
598 
599  // Figure out what axis system2 looks like in axis system1.
600  M2 = M1.transposed() * M2;
601 
602  // First figure out how to backrotate z rotation.
603  Vector z_vec = M2.col_z();
604  Real const gamma_radians = std::atan2( z_vec(2), z_vec(1) );
605  gamma = degrees( gamma_radians );
606 
607  M2 = rotation_matrix( Vector( 0.0, 0.0, 1.0 ), -1.0 * gamma_radians ) * M2;
608  z_vec = M2.col_z();
609  if ( verbose ) std::cout << "This better have a zero in y position " << z_vec(1) << ' ' << z_vec(2) << ' ' << z_vec(3) << std::endl;
610 
611  // Then figure out how to backrotate y rotation.
612  Real const beta_radians = std::atan2( z_vec(1), z_vec(3) );
613  beta = degrees( beta_radians );
614 
615  M2 = rotation_matrix( Vector( 0.0, 1.0, 0.0 ), -1.0 * beta_radians ) * M2;
616  z_vec = M2.col_z();
617  if ( verbose ) std::cout << "This better have a zero in x and y position " << z_vec(1) << ' ' << z_vec(2) << ' ' << z_vec(3) << std::endl;
618 
619  // Finally, backrotate z rotation.
620  Vector x_vec = M2.col_x();
621  Real const alpha_radians = std::atan2( x_vec(2), x_vec(1) );
622  alpha = degrees( alpha_radians );
623 
624  M2 = rotation_matrix( Vector( 0.0, 0.0, 1.0 ), -1.0 * alpha_radians ) * M2;
625  x_vec = M2.col_x();
626  if ( verbose ) std::cout << "This better have a zero in y and z position " << x_vec(1) << ' ' << x_vec(2) << ' ' << x_vec(3) << std::endl;
627 
628  // Oh come on, testing basic matrix algebra here.
629 
630  // std::cout << "M1: " << std::endl;
631  // std::cout << M1(1,1) << ' ' << M1(1,2) << ' ' << M1(1,3) << std::endl;
632  // std::cout << M1(2,1) << ' ' << M1(2,2) << ' ' << M1(2,3) << std::endl;
633  // std::cout << M1(3,1) << ' ' << M1(3,2) << ' ' << M1(3,3) << std::endl;
634  // std::cout << "x: " << xaxis1(1) << " " << xaxis1(2) << " " << xaxis1(3) << std::endl;
635  // std::cout << "y: " << yaxis1(1) << " " << yaxis1(2) << " " << yaxis1(3) << std::endl;
636  // std::cout << "z: " << zaxis1(1) << " " << zaxis1(2) << " " << zaxis1(3) << std::endl;
637 
638  if ( verbose ){
639  Matrix M;
640 
641  Vector const xaxis1 = M1.col_x();
642  Vector const yaxis1 = M1.col_y();
643  Vector const zaxis1 = M1.col_z();
644  create_euler_rotation( M, alpha, beta, gamma, xaxis1, yaxis1, zaxis1 );
645 
646  // Matrix M_test;
647  // create_euler_rotation( M_test, alpha, beta, gamma, Vector( 1.0,0.0,0.0), Vector( 0.0,1.0,0.0), Vector(0.0,0.0,1.0) );
648  // M_test = M1 * M_test * M1.transposed();
649  // M_test = M1.transposed() * M_test * M1; // Can we rotate M1 into M2?
650  M = M * M1;
651 
652  std::cout << "These better match: " << std::endl;
653  std::cout << M(1,1) << ' ' << M(1,2) << ' ' << M(1,3) << std::endl;
654  std::cout << M(2,1) << ' ' << M(2,2) << ' ' << M(2,3) << std::endl;
655  std::cout << M(3,1) << ' ' << M(3,2) << ' ' << M(3,3) << std::endl;
656  std::cout << std::endl;
657  std::cout << M_test(1,1) << ' ' << M_test(1,2) << ' ' << M_test(1,3) << std::endl;
658  std::cout << M_test(2,1) << ' ' << M_test(2,2) << ' ' << M_test(2,3) << std::endl;
659  std::cout << M_test(3,1) << ' ' << M_test(3,2) << ' ' << M_test(3,3) << std::endl;
660  }
661 
662  }
663 
664 ///////////////////////////////////////////////////////////////////////
665 void
666 translate( pose::Pose & pose, Vector const shift,
667  pose::Pose const & ref_pose,
668  utility::vector1< Size > const & moving_res ){
669 
670  using namespace core::id;
671 
672  for ( Size n = 1; n <= moving_res.size(); n++ ) {
673  Size const i = moving_res[ n ];
674 
675  for ( Size m = 1; m <= pose.residue_type( i ).natoms(); m++ ) {
676  pose.set_xyz( AtomID(m,i), ref_pose.xyz( AtomID(m,i) ) + shift );
677  }
678 
679  }
680 
681 }
682 
683 
684 ///////////////////////////////////////////////////////////////////////
685 void
686 rotate( pose::Pose & pose, Matrix const M,
687  pose::Pose const & ref_pose,
688  utility::vector1< Size > const & moving_res,
689  Vector const & centroid ){
690 
691  using namespace core::id;
692 
693  for ( Size n = 1; n <= moving_res.size(); n++ ) {
694  Size const i = moving_res[ n ];
695 
696  for ( Size m = 1; m <= pose.residue_type( i ).natoms(); m++ ) {
697  pose.set_xyz( AtomID(m,i), M * ( ref_pose.xyz( AtomID(m,i) ) - centroid ) + centroid );
698  // std::cout << "ROTATE " << m << " " << i << " " << pose.xyz( AtomID(m,i) )(1) << " " << ref_pose.xyz( AtomID(m,i) )(1) << std::endl;
699  }
700  }
701 
702 }
703 
704 //////////////////////////////////////////////////////////////////
705 void
706 rotate( pose::Pose & pose, Matrix const M,
707  pose::Pose const & ref_pose,
708  utility::vector1< Size > const & moving_res ){
709 
710  Vector centroid( 0.0, 0.0, 0.0 );
711  rotate( pose, M, ref_pose, moving_res, centroid );
712 }
713 
714  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
715  void
716  get_base_centroid_and_rotation_matrix( pose::Pose const & pose, Size const i, Vector & centroid, Matrix & M ){
717 
718  using namespace scoring::rna;
719  using namespace kinematics;
720  static RNA_CentroidInfo rna_centroid_info;
721 
722  centroid = rna_centroid_info.get_base_centroid( pose.residue( i ) );
723  Stub s = rna_centroid_info.get_base_coordinate_system( pose.residue( i ), centroid );
724  M = s.M;
725  }
726 
727  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
728  void
729  translate_and_rotate_residue_to_origin( pose::Pose & pose, Size const i, utility::vector1< Size > const moving_res, bool const do_not_rotate ){
730  using namespace protocols::swa;
731 
732  Vector centroid;
733  Matrix M;
734  get_base_centroid_and_rotation_matrix( pose, i, centroid, M);
735 
736  translate( pose, -centroid, pose, moving_res);
737  if ( !do_not_rotate ) rotate( pose, M.transposed(), pose, moving_res);
738 
739  }
740 
741  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
742  void
744  translate_and_rotate_residue_to_origin( pose, i, utility::tools::make_vector1( i ) );
745  }
746 
747 
748 
749 }
750 }