Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
StepWiseRNA_FloatingBase_Sampler_Util.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 StepWiseRNA_Dinculeotide_Sampler_Util
11 /// @brief Not particularly fancy, just minimizes a list of poses.
12 /// @detailed
13 /// @author Parin Sripakdeevong
14 
15 
16 //////////////////////////////////
29 
32 #include <core/id/TorsionID.hh>
33 //////////////////////////////////
34 #include <basic/Tracer.hh>
35 #include <core/types.hh>
37 #include <core/chemical/util.hh>
40 #include <core/chemical/AtomType.hh>
43 #include <core/pose/Pose.hh>
44 #include <core/io/pdb/pose_io.hh>
60 #include <set>
61 #include <numeric/conversions.hh>
62 #include <numeric/NumericTraits.hh>
63 #include <iostream>
64 #include <fstream>
65 #include <sstream>
66 #include <ObjexxFCL/format.hh>
67 #include <ObjexxFCL/string.functions.hh>
69 #include <core/scoring/Energies.hh>
72 
73 
74 using namespace core;
75 
76 static basic::Tracer TR( "protocols.swa.rna.stepwise_rna_floating_base_sampler_util" ) ;
77 
78 namespace protocols {
79 namespace swa {
80 namespace rna {
81 
82  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
83  bool
84  Is_base_stack(core::kinematics::Stub const & moving_res_base,
85  utility::vector1 < core::kinematics::Stub > const & other_residues_base_list,
86  core::Real const base_axis_CUTOFF,
87  core::Real const base_planarity_CUTOFF){
88 
89  //std::cout << "ENTER Is_base_stack base_axis_CUTOFF= " << base_axis_CUTOFF << " base_planarity_CUTOFF= " << base_planarity_CUTOFF << std::endl;
90 
91  core::Real const small_offset=0.000001; //0.0001;
92 
93  //std::cout << "small_offset= " << small_offset << std::endl;
94 
95  for(Size i=1; i<=other_residues_base_list.size(); i++){
96 
97  //std::cout << std::endl;
98 
99  //std::cout << "Is_base_stacking i= " << i << std::endl;
100 
101  core::kinematics::Stub const & base_info=other_residues_base_list[i];
102  numeric::xyzVector<Real> const other_z_vector=base_info.M.col_z();
103  numeric::xyzVector<Real> const rebuild_z_vector=moving_res_base.M.col_z();
104 
105  numeric::xyzVector<Real> centroid_diff;
106  subtract( moving_res_base.v, base_info.v, centroid_diff);
107  Real const centroid_distance=centroid_diff.length();
108 
109  //std::cout << " centroid_distance= " << centroid_distance;
110 
111  if( centroid_distance>(6.3640+small_offset) ) continue;
112 
113  Real const base_z_offset_one=std::abs(dot( centroid_diff, other_z_vector));
114  Real const base_z_offset_two=std::abs(dot( centroid_diff, rebuild_z_vector));
115 
116  //std::cout << " base_z_offset_one= " << base_z_offset_one << " base_z_offset_two= " << base_z_offset_two;
117 
118  if( (base_z_offset_one>(4.5000+small_offset) || base_z_offset_one<(2.5000-small_offset)) && (base_z_offset_two>(4.5000+small_offset) || base_z_offset_two<(2.5000-small_offset)) ) continue;
119 
120  Real const base_axis_one=base_z_offset_one/centroid_distance;
121  Real const base_axis_two=base_z_offset_two/centroid_distance;
122 
123  //std::cout << " base_axis_one= " << base_axis_one << " base_axis_two= " << base_axis_two;
124 
125  if( base_axis_one<(base_axis_CUTOFF-small_offset) && base_axis_two<(base_axis_CUTOFF-small_offset) ) continue;
126 
127  Real const base_planarity=std::abs(dot( other_z_vector, rebuild_z_vector));
128 
129  //std::cout << " base_planarity= " << base_planarity;
130 
131  if( base_planarity<(base_planarity_CUTOFF-small_offset) ) continue;
132 
133  //std::cout << " PASS_BASE_STACKING_SCREEN i= " << i << std::endl;
134 
135  return true; //If reach this point means success!
136  }
137  //std::cout << std::endl;
138 
139  return false;
140  }
141 
142  bool
143  Is_base_pair(core::kinematics::Stub const & moving_res_base,
144  utility::vector1 < core::kinematics::Stub > const & other_residues_base_list,
145  core::Real const base_axis_CUTOFF,
146  core::Real const base_planarity_CUTOFF){
147 
148  //std::cout << "ENTER Is_base_pair base_axis_CUTOFF= " << base_axis_CUTOFF << " base_planarity_CUTOFF= " << base_planarity_CUTOFF << std::endl;
149 
150  core::Real const small_offset=0.000001; //0.0001;
151 
152  //std::cout << "small_offset= " << small_offset << std::endl;
153 
154  for(Size i=1; i<=other_residues_base_list.size(); i++){
155 
156  //std::cout << std::endl;
157 
158  //std::cout << "Is_base_pair i= " << i << std::endl;
159 
160  core::kinematics::Stub const & base_info=other_residues_base_list[i];
161  numeric::xyzVector<Real> const other_z_vector=base_info.M.col_z();
162  numeric::xyzVector<Real> const rebuild_z_vector=moving_res_base.M.col_z();
163 
164  numeric::xyzVector<Real> centroid_diff;
165  subtract( moving_res_base.v, base_info.v, centroid_diff);
166 
167  Real const centroid_distance=centroid_diff.length();
168 
169  //std::cout << " centroid_distance= " << centroid_distance;
170 
171  //if(centroid_distance>(12.0000+small_offset) ) continue; Test on Feb 23, 2011.
172 
173  if(centroid_distance<(5.0000-small_offset) || centroid_distance>(12.0000+small_offset) ) continue;
174 
175  Real const base_z_offset_one=std::abs(dot( centroid_diff, other_z_vector));
176  Real const base_z_offset_two=std::abs(dot( centroid_diff, rebuild_z_vector));
177 
178  //std::cout << " base_z_offset_one= " << base_z_offset_one << " base_z_offset_two= " << base_z_offset_two;
179 
180  if(base_z_offset_one>(3.0000+small_offset) && base_z_offset_two>(3.0000+small_offset) ) continue;
181 
182  Real const base_axis_one=base_z_offset_one/centroid_distance;
183  Real const base_axis_two=base_z_offset_two/centroid_distance;
184 
185  //std::cout << " base_axis_one= " << base_axis_one << " base_axis_two= " << base_axis_two;
186 
187  if(base_axis_one>(base_axis_CUTOFF+small_offset) && base_axis_two>(base_axis_CUTOFF+small_offset) ) continue; //This is a stronger condition compare to baze_z_off_set check
188 
189  Real const base_planarity=std::abs(dot( rebuild_z_vector, other_z_vector));
190 
191  //std::cout << " base_planarity= " << base_planarity;
192 
193  if( base_planarity<(base_planarity_CUTOFF-small_offset) ) continue;
194 
195  numeric::xyzVector<Real> const centroid_diff_parallel_one=dot( centroid_diff, other_z_vector)*other_z_vector; //messed with this on Jan 16, 2010 Parin S.
196  numeric::xyzVector<Real> const centroid_diff_perpendicular_one= centroid_diff-centroid_diff_parallel_one;
197  Real const rho_one=centroid_diff_perpendicular_one.length(); //length along xy plane
198 
199  numeric::xyzVector<Real> const centroid_diff_parallel_two=dot( centroid_diff, rebuild_z_vector)*rebuild_z_vector;
200  numeric::xyzVector<Real> const centroid_diff_perpendicular_two= centroid_diff-centroid_diff_parallel_two;
201  Real const rho_two=centroid_diff_perpendicular_two.length();
202 
203  //std::cout << " rho_one= " << rho_one << " rho_two= " << rho_two;
204 
205  //if( ( rho_one>(10.0000+small_offset) ) && (rho_two>(10.0000+small_offset) ) ) continue; Test on Feb 23, 2011.
206 
207  if((rho_one<(5.0000-small_offset) || rho_one>(10.0000+small_offset) ) && (rho_two<(5.0000-small_offset) || rho_two>(10.0000+small_offset) )) continue;
208 
209  //std::cout << " PASS_BASE_PAIR_SCREEN i= " << i << std::endl;
210 
211  return true; //If reach this point means success!
212  }
213 
214  //std::cout << std::endl;
215 
216  return false;
217  }
218 
219  bool
220  Is_strong_base_stack(core::kinematics::Stub const & moving_res_base, utility::vector1 < core::kinematics::Stub > const & other_residues_base_list){
221 
222  Real const base_axis_CUTOFF=0.9000;
223  Real const base_planarity_CUTOFF=0.9000;
224 
225  //std::cout << "ENTER Is_strong_base_stack " << std::endl;
226 
227  return Is_base_stack(moving_res_base, other_residues_base_list, base_axis_CUTOFF, base_planarity_CUTOFF);
228 
229  }
230 
231  bool
233 
234  //std::cout << "ENTER Is_medium_base_stack_and_medium_base_pair" << std::endl;
235 
236  bool base_stack = Is_base_stack(moving_res_base, other_residues_base_list, 0.7070 /*base_axis_CUTOFF*/, 0.7070 /*base_planarity_CUTOFF*/);
237 
238  bool base_pair = Is_base_pair(moving_res_base, other_residues_base_list, 0.5000 /*base_axis_CUTOFF*/, 0.7070 /*base_planarity_CUTOFF*/);
239  //value in Base_screener_class is 0.866 Sept 16 2010, Parin S.
240 
241  //std::cout << "EXIT Is_medium_base_stack_and_medium_base_pair" << std::endl;
242 
243  return (base_stack && base_pair);
244 
245  }
246 
247 
248  //CALLED ONLY IN the floating base mode!
249  bool
250  Base_centroid_screening(core::kinematics::Stub const & moving_res_base, utility::vector1 < core::kinematics::Stub > const & other_residues_base_list, Size const num_nucleotides, SillyCountStruct & count_data, bool const allow_base_pair_only_screen){
251 
252  if(num_nucleotides>2) utility_exit_with_message( "Error: num_nucleotides>2!" );
253 
254  if(num_nucleotides==2){ //Dinucleotide.
255 
256  bool const strong_stack_base = Is_strong_base_stack(moving_res_base, other_residues_base_list);
257 
258  if ( strong_stack_base ) count_data.base_stack_count++;
259 
260  bool const medium_base_stack_and_medium_base_pair = Is_medium_base_stack_and_medium_base_pair(moving_res_base, other_residues_base_list);
261  if ( medium_base_stack_and_medium_base_pair) count_data.base_pairing_count++;
262 
263 
264  bool strict_base_pair=false;
265  if(allow_base_pair_only_screen){
266 // strict_base_pair= Is_base_pair(moving_res_base, other_residues_base_list, 0.52588 /*base_axis_CUTOFF*/ , 0.8660 /*base_planarity_CUTOFF*/ ); //Human Mistake!
267  strict_base_pair= Is_base_pair(moving_res_base, other_residues_base_list, 0.2588 /*base_axis_CUTOFF*/ , 0.8660 /*base_planarity_CUTOFF*/ );
268 // strict_base_pair= Is_base_pair(moving_res_base, other_residues_base_list, 0.1736 /*base_axis_CUTOFF*/ , 0.9659 /*base_planarity_CUTOFF*/ );
269 
270  if(strict_base_pair) count_data.strict_base_pairing_count++;
271  }
272 
273  if ( strong_stack_base || medium_base_stack_and_medium_base_pair || (allow_base_pair_only_screen && strict_base_pair) ){
274  count_data.pass_base_centroid_screen++;
275 
276  //std::cout << "test_count_one=" << count_data.test_count_one << " test_count_two=" << count_data.test_count_two;
277  //std::cout << " base_stack_count= " << count_data.base_stack_count << " count_data.base_pairing_count= " << count_data.base_pairing_count;
278  //Output_boolean(" strong_stack_base= ", strong_stack_base); Output_boolean(" medium_bs_and_bp= ", medium_base_stack_and_medium_base_pair); std::cout << std::endl;
279 
280 
281  return true;
282  }
283 
284  return false;
285 
286  }else{ //num_nucleotides==1, implement in Sept 16, 2010 Parin S.
287 
288  bool const regular_base_stack = Is_base_stack(moving_res_base, other_residues_base_list, 0.707 /*base_axis_CUTOFF*/, 0.707 /*base_planarity_CUTOFF*/ );
289 
290  if ( regular_base_stack ) count_data.base_stack_count++;
291 
292  bool const regular_base_pair = Is_base_pair(moving_res_base, other_residues_base_list, 0.5 /*base_axis_CUTOFF*/, 0.866 /*base_planarity_CUTOFF*/);
293 
294  if ( regular_base_pair ) count_data.base_pairing_count++;
295 
296  if( regular_base_stack || regular_base_pair){
297  count_data.pass_base_centroid_screen++;
298  return true;
299  }
300 
301  return false;
302  }
303 
304  }
305 
306 
307 
308  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
309 
311  Get_ribose_stub(conformation::Residue const & rsd, bool const Is_prepend, bool const verbose){
312 
313  using namespace chemical;
314 
315 
316  std::string const center_atom = (Is_prepend) ? " C4*" : " C3*";
317  std::string const x_axis_atom = (Is_prepend) ? " H4*" : " C2*";
318  std::string const y_axis_atom = (Is_prepend) ? " C5*" : " H3*";
319 
320  if(verbose){
321  std::cout << "Get_ribose_stub function: ";
322  Output_boolean("Is prepend= ", Is_prepend);
323  std::cout << " center_atom= " << center_atom << " x_axis_atom= " << x_axis_atom << " y_axis_atom= " << y_axis_atom << std::endl;
324  }
325 
326  core::kinematics::Stub anchor_ribose_stub;
327 
328  assert( rsd.is_RNA() );
329 
330  Vector x,y,z;
331 
332  Vector const origin=rsd.xyz(center_atom);
333 
334  Vector const x_axis_coord =rsd.xyz(x_axis_atom);
335  x = x_axis_coord - origin;
336  x.normalize();
337 
338  Vector const y_axis_coord =rsd.xyz(y_axis_atom);
339  y = y_axis_coord - origin; //not orthonormal yet...
340  z = cross(x, y); //Can cross here even though y is not orthogonal to x since the component of y that is parallel to x dissapear when crossed with x since cross(x, x)=0
341  z.normalize(); //Choosen H4 and C5 atom specifically so that z will be roughly parallel with the helical axis.
342 
343  y = cross(z, x); //Now y is orthonormal
344  y.normalize(); //not necessary but doesn't hurt.
345 
346  anchor_ribose_stub.v =origin ;
347  anchor_ribose_stub.M=Matrix::cols( x, y, z );
348 
349  return anchor_ribose_stub;
350 
351  }
352 
353  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
354 
355  Base_bin
356  Get_euler_stub_bin(numeric::xyzVector<core::Real> const & centriod, Euler_angles const & euler_angles){
357 
358 // using namespace Bin_size;
359 
360  Base_bin base_bin;
361  base_bin.centroid_x=int(centriod[0]/centroid_bin_size);
362  base_bin.centroid_y=int(centriod[1]/centroid_bin_size);
363  base_bin.centroid_z=int(centriod[2]/centroid_bin_size);
364 
365  base_bin.euler_alpha=int(euler_angles.alpha/euler_angle_bin_size);
366  base_bin.euler_gamma=int(euler_angles.gamma/euler_angle_bin_size);
367  base_bin.euler_z=int(euler_angles.z/euler_z_bin_size);
368 
369 
370  if(centriod[0]<0) base_bin.centroid_x--;
371  if(centriod[1]<0) base_bin.centroid_y--;
372  if(centriod[2]<0) base_bin.centroid_z--;
373  if(euler_angles.alpha<0) base_bin.euler_alpha--;
374  if(euler_angles.gamma<0) base_bin.euler_gamma--;
375  if(euler_angles.z<0) base_bin.euler_z--;
376 
377  return base_bin;
378  }
379 
380  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
381 
382  int
383  DOF_bin_value(std::map<Base_bin , int , compare_base_bin>::const_iterator const & base_bin_it, std::string const & DOF){
384 
385  if(DOF=="x"){
386  return base_bin_it->first.centroid_x;
387  }else if(DOF=="y"){
388  return base_bin_it->first.centroid_y;
389  }else if(DOF=="z"){
390  return base_bin_it->first.centroid_z;
391  }else if(DOF=="alpha"){
392  return base_bin_it->first.euler_alpha;
393  }else if(DOF=="euler_z"){
394  return base_bin_it->first.euler_z;
395  }else if(DOF=="gamma"){
396  return base_bin_it->first.euler_gamma;
397  }else{
398  utility_exit_with_message( "Invalid DOF= " + DOF);
399  exit(1); //prevent compiler warning
400  }
401  }
402 
403  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
404 
405  Real
406  DOF_bin_size(std::string const & DOF){
407 
408  if(DOF=="x" || DOF=="y" || DOF=="z"){
409  return centroid_bin_size;
410  }else if(DOF=="alpha" || DOF=="gamma"){
411  return euler_angle_bin_size;
412  }else if(DOF=="euler_z"){
413  return euler_z_bin_size;
414  }else{
415  utility_exit_with_message( "Invalid DOF= " + DOF);
416  exit(1); //prevent compiler warning
417  }
418  }
419 
420  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
421 
422  void
423  Analyze_base_bin_map(std::map<Base_bin , int , compare_base_bin> const & base_bin_map, std::string const & DOF_one, std::string const & DOF_two, std::string const foldername){
424 
425  std::map<std::pair<int, int> , int , compare_int_pair> count_density_map;
426  std::map<std::pair<int, int> , int , compare_int_pair>::iterator count_density_it;
427 
428  std::map<Base_bin , int , compare_base_bin>::const_iterator base_bin_it;
429 
430  int total_count=0;
431  int total_occupied_bin=0;
432 
433  for (base_bin_it=base_bin_map.begin(); base_bin_it!=base_bin_map.end(); base_bin_it++ ){
434 
435  total_occupied_bin++;
436  total_count=total_count+base_bin_it->second;
437 
438  std::pair< int, int > const & DOF_pair=std::make_pair(DOF_bin_value(base_bin_it, DOF_one), DOF_bin_value(base_bin_it, DOF_two));
439 
440  count_density_it=count_density_map.find(DOF_pair);
441 
442  if(count_density_it==count_density_map.end()){
443  count_density_map[DOF_pair]=1;
444  }else{
445  count_density_it->second++;
446  }
447  }
448 
449  //////////////////////Output data/////////////////////////////////////////////////////////////////////////////
450  std::ofstream outfile;
451  std::string filename=foldername + "Bin_" + DOF_one + "_" + DOF_two + ".txt";
452  outfile.open(filename.c_str());
453  Size const spacing=14;
454 
455  outfile << std::setw(spacing) << DOF_one;
456  outfile << std::setw(spacing) << DOF_two;
457  outfile << std::setw(30) << "occupied_bin_count";
458  outfile << "\n";
459 
460  int DOF_one_bin_max=0;
461  int DOF_one_bin_min=0;
462  int DOF_two_bin_max=0;
463  int DOF_two_bin_min=0;
464 
465  for (count_density_it=count_density_map.begin(); count_density_it!=count_density_map.end(); count_density_it++ ){
466  int const & DOF_one_bin_value=count_density_it->first.first;
467  int const & DOF_two_bin_value=count_density_it->first.second;
468 
469  if(DOF_one_bin_value>DOF_one_bin_max) DOF_one_bin_max=DOF_one_bin_value;
470  if(DOF_two_bin_value>DOF_two_bin_max) DOF_two_bin_max=DOF_two_bin_value;
471  if(DOF_one_bin_value<DOF_one_bin_min) DOF_one_bin_min=DOF_one_bin_value;
472  if(DOF_two_bin_value<DOF_two_bin_min) DOF_two_bin_min=DOF_two_bin_value;
473 
474  }
475 
476  for(int DOF_one_bin_value=(DOF_one_bin_min-5); DOF_one_bin_value<(DOF_one_bin_max+5); DOF_one_bin_value++){
477  for(int DOF_two_bin_value=(DOF_two_bin_min-5); DOF_two_bin_value<(DOF_two_bin_max+5); DOF_two_bin_value++){
478 
479  Real const DOF_one_value=DOF_one_bin_value*DOF_bin_size(DOF_one);
480  Real const DOF_two_value=DOF_two_bin_value*DOF_bin_size(DOF_two);
481 
482  int occupied_bin_count;
483  std::pair< int, int > const & DOF_pair=std::make_pair(DOF_one_bin_value, DOF_two_bin_value);
484  count_density_it=count_density_map.find(DOF_pair);
485 
486  if(count_density_it==count_density_map.end()){
487  occupied_bin_count=0;
488  }else{
489  occupied_bin_count=count_density_it->second;
490  }
491 
492  outfile << std::setw(spacing) << DOF_one_value;
493  outfile << std::setw(spacing) << DOF_two_value;
494  outfile << std::setw(spacing) << occupied_bin_count;
495  outfile << "\n";
496  }
497  }
498  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
499 
500  std::cout << std::setw(50) << std::left << "Analysis " + DOF_one + "_" + DOF_two;
501  std::cout << " tot_count = " << std::setw(15) << std::left << total_count << " tot_occ= " << std::setw(15) << std::left << total_occupied_bin;
502  std::cout << " tot_count/tot_occ_bin= " << std::setw(5) << std::left << (double(total_count)/double(total_occupied_bin)) << std::endl;
503 
504 
505  }
506 
507  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
508 
509  void
510  Analyze_base_bin_map(std::map<Base_bin , int , compare_base_bin> const & base_bin_map, std::string const foldername){
511 
512  // const Real DEGS_PER_RAD = 180. / numeric::NumericTraits<Real>::pi(); // Unused variable causes warning.
513 
514  Analyze_base_bin_map(base_bin_map, "x", "y", foldername);
515  Analyze_base_bin_map(base_bin_map, "x", "z", foldername);
516  Analyze_base_bin_map(base_bin_map, "x", "alpha", foldername);
517  Analyze_base_bin_map(base_bin_map, "x", "euler_z", foldername);
518  Analyze_base_bin_map(base_bin_map, "x", "gamma", foldername);
519 
520  Analyze_base_bin_map(base_bin_map, "y", "z", foldername);
521  Analyze_base_bin_map(base_bin_map, "y", "alpha", foldername);
522  Analyze_base_bin_map(base_bin_map, "y", "euler_z", foldername);
523  Analyze_base_bin_map(base_bin_map, "y", "gamma", foldername);
524 
525  Analyze_base_bin_map(base_bin_map, "z", "alpha", foldername);
526  Analyze_base_bin_map(base_bin_map, "z", "euler_z", foldername);
527  Analyze_base_bin_map(base_bin_map, "z", "gamma", foldername);
528 
529  Analyze_base_bin_map(base_bin_map, "alpha", "euler_z", foldername);
530  Analyze_base_bin_map(base_bin_map, "alpha", "gamma", foldername);
531 
532  Analyze_base_bin_map(base_bin_map, "euler_z", "gamma", foldername);
533 
534 // std::cout << "Is_dinucleotide= " << Is_dinucleotide << std::endl;
535  std::cout << "centroid_bin_size= " << centroid_bin_size << " euler_angle_bin_size= " << euler_angle_bin_size << " euler_z_bin_size= " << euler_z_bin_size << std::endl;
536 
537 
538  }
539 
540  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
541 
542  //Actually deleted this function since it was no longer in use......On May 2, copied back a version of this function from a Mar 28 Desktop mini src.
543  Euler_angles
545 
546  numeric::xyzMatrix< core::Real > const & M = coordinate_matrix;
547  const Real DEGS_PER_RAD = 180. / numeric::NumericTraits<Real>::pi();
548 
549  Euler_angles euler_angles;
550  euler_angles.alpha= atan2(M.xz(),-M.yz()) * DEGS_PER_RAD;
551  euler_angles.z= M.zz();
552  euler_angles.gamma= atan2(M.zx(), M.zy()) * DEGS_PER_RAD ; //tan2(y,x)=gamma
553 
554 // float atan2 ( float y, float x );
555 //principal arc tangent of y/x, in the interval [-pi,+pi] radians.
556 
557  //Implement a check here to make sure that the euler_angles are be used to recalculate the coordiante May 2, 2010....
558 
559 /* Defination of rotation matrix at mathworld is actually the inverse of the rotation matrix....also did not correctly input the coefficient of arctan2
560  euler_angles.alpha = (-1)* atan2(M.zy(), M.zx()) * DEGS_PER_RAD; //Is this correct?? Ambuiguity with the minus sign...return in the [-Pi, Pi] range. atan2(y-value, x-value)
561  euler_angles.beta = acos(M.zz()) * DEGS_PER_RAD; // rerun in the [0,Pi] range
562  euler_angles.z= M.zz(); //Use z instead of beta to make space uniform
563  euler_angles.gamma = atan2(M.yz(), M.xz()) * DEGS_PER_RAD; //return in the [-Pi, Pi] range. atan2(y-value, x-value)
564 */
565 
566  return euler_angles;
567  }
568 
569  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
570 
571 
572  void
574 
575  //Probably could save time if determine x and y and take cross product to determine z
576  //Should determine using both ways and check for consistency
577 
578  coordinate_matrix.xx( cos(E.alpha)*cos(E.gamma) - sin(E.alpha)*cos(E.beta)*sin(E.gamma));
579  coordinate_matrix.xy(-cos(E.alpha)*sin(E.gamma) - sin(E.alpha)*cos(E.beta)*cos(E.gamma));
580  coordinate_matrix.xz( sin(E.alpha)*sin(E.beta));
581  coordinate_matrix.yx( sin(E.alpha)*cos(E.gamma) + cos(E.alpha)*cos(E.beta)*sin(E.gamma));
582  coordinate_matrix.yy(-sin(E.alpha)*sin(E.gamma) + cos(E.alpha)*cos(E.beta)*cos(E.gamma)); //Found bug on Feb 13, 2010...previously had cos(E.gamma) instead of sin(E.gamma)
583  coordinate_matrix.yz(-cos(E.alpha)*sin(E.beta));
584  coordinate_matrix.zx( sin(E.beta) *sin(E.gamma));
585  coordinate_matrix.zy( sin(E.beta) *cos(E.gamma));
586  coordinate_matrix.zz( cos(E.beta));
587 
588  Real determinant=coordinate_matrix.det();
589  //if(determinant>1.00000000000001 || determinant<0.99999999999999){ //Feb 12, 2012 This might lead to server-test error at R47200
590  if(determinant>1.000001 || determinant<0.999999){ //Feb 12, 2012 This might lead to server-test error at R47200
591  utility_exit_with_message( "determinant != 1.00 !!!" );
592  }
593 
594 // std::cout << "determinant= " << determinant << std::endl;
595 
596 /*
597  xx_( m.xx_ ), xy_( m.xy_ ), xz_( m.xz_ ),
598  yx_( m.yx_ ), yy_( m.yy_ ), yz_( m.yz_ ),
599  zx_( m.zx_ ), zy_( m.zy_ ), zz_( m.zz_ )
600 */
601 
602  }
603 
604 /*
605  numeric::xyzMatrix< core::Real >
606  convert_euler_to_coordinate_matrix(Euler_angles const & E){
607 
608  numeric::xyzMatrix< core::Real > coordinate_matrix;
609  convert_euler_to_coordinate_matrix(E, coordinate_matrix);
610  return coordinate_matrix;
611  }
612 */
613  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
614 /*
615  void
616  set_ribose_to_origin(pose::Pose & pose, core::Size const seq_num, bool const Is_prepend, bool const verbose){
617 
618  using namespace core::chemical;
619  using namespace core::scoring;
620  using namespace core::pose;
621 
622  }
623 */
624 
625  void
627 
628  using namespace core::id;
629  using namespace core::pose;
630 
631 
632  for(Size seq_num=1; seq_num<=pose.total_residue(); seq_num++){
633 
634  conformation::Residue const & rsd(pose.residue(seq_num));
635 
636  for( Size at = 1; at <= rsd.natoms(); at++){
637  std::string const & atom_name=rsd.type().atom_name(at);
638  if(verbose) std::cout << "seq_num= " << seq_num << " atom_name= " << atom_name << std::endl;
639 
640  id::AtomID const id( at, seq_num);
641 
642  pose.set_xyz( id, pose.xyz( id) + vector );
643  pose.set_xyz( id, matrix * pose.xyz(id));
644  }
645  }
646  }
647 
648 
649  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
650 
651 
652  //Set sets the base to the origin....
653  void
654  set_to_origin(pose::Pose & pose, Size const seq_num, bool verbose){
655 
656  using namespace core::chemical;
657  using namespace core::scoring;
658  using namespace core::pose;
659  using namespace core::io::silent;
660  using namespace core::id;
661 
662  conformation::Residue const & rsd(pose.residue(seq_num));
663 
665 
667 
668  numeric::xyzMatrix< core::Real > invert_coordinate_matrix= inverse(base_coordinate_matrix);
669 
670  // Size count=0; // Unused variable causes warning.
671  for( Size at = 1; at <= rsd.natoms(); at++){
672  // std::string const & atom_name=rsd.type().atom_name(at); // Unused variable causes warning.
673 // std::cout << "atom_name= " << atom_name << std::endl;
674 // AtomID id( j, i )
675  id::AtomID const id( at, seq_num);
676 
677 // AtomID & id= AtomID( at, seq_num )
678  pose.set_xyz( id, pose.xyz( id) - centroid );//I think the order here does matter. Translate centroid to origin.
679  pose.set_xyz( id, invert_coordinate_matrix * pose.xyz(id)); //I think the order here does matter. Rotate coordinate so that it equal to Roseeta internal reference frame
680 
681  }
682  }
683 
684  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
685 
686 
687  //Find the " O3*" atom coordinate (prepend), " C5*" atom coordinate (append)
688  void
691  core::conformation::Residue const & rsd_at_origin,
692  core::kinematics::Stub const & moving_res_base_stub){
693 
694  numeric::xyzVector<core::Real> const & new_centroid=moving_res_base_stub.v;
695  numeric::xyzMatrix< core::Real > const & new_coordinate_matrix=moving_res_base_stub.M;
696 
697  //STILL NEED TO CHECK THAT THIS NEW IMPLEMENTATION WORK!! Apr 10, 2010 Parin
698  atom_pos= new_coordinate_matrix * rsd_at_origin.xyz(atom_name); //I think the order here does matter.
699  atom_pos= atom_pos + new_centroid; //I think the order here does matter.
700 
701  }
702 
703  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
704 
705  core::Real
707 
708  using namespace core::conformation;
709 
710  if(rsd_at_origin_list.size()<1){
711  utility_exit_with_message( "rsd_at_origin_list.size()<1!!" );
712  }
713 
714  Real max_distance=0;
715 
716  for(Size n=1; n<=rsd_at_origin_list.size(); n++){
717  Residue const & rsd_at_origin= (*rsd_at_origin_list[n]);
718  numeric::xyzVector<core::Real> const centroid=core::scoring::rna::get_rna_base_centroid(rsd_at_origin, false); //optimize by returning this by reference? Apr 10, 2010
719 
720  Real const distance =( rsd_at_origin.xyz(atom_name) - centroid ).length();
721 
722  if(max_distance< distance) max_distance=distance;
723  std::cout << " sugar/base conformation num: " << n << " distance = " << distance << std::endl;
724  }
725 
726  std::cout << "max_centroid_to_atom_distance for atom: " << atom_name << " base " << name_from_aa((*rsd_at_origin_list[1]).aa()) << ": " << max_distance << std::endl;
727 
728  return max_distance;
729  }
730  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
731 
733  setup_residue_at_origin_list(pose::Pose const & pose, Size const & moving_res, bool const extra_anti_chi_rotamer, bool const extra_syn_chi_rotamer, std::string const pose_name){
734 
735  using namespace ObjexxFCL;
736  using namespace ObjexxFCL::fmt;
737  using namespace core::id;
738  using namespace core::chemical;
739  using namespace core::conformation;
740  using namespace core::scoring::rna;
741 
742  std::cout << "-------setup_residue_at_origin_list (various sugar rotamers) for pose: " << pose_name << "-------" << std::endl;
743  Output_boolean("extra_anti_chi_rotamer= " , extra_anti_chi_rotamer); std::cout << std::endl;
744  Output_boolean("extra_syn_chi_rotamer= " , extra_syn_chi_rotamer); std::cout << std::endl;
745 
746  BaseState base_state = (core::scoring::rna::is_purine( pose.residue( moving_res ) )) ? BOTH: ANTI;
747 
748  PuckerState pucker_state=ALL;
749  core::scoring::rna::RNA_FittedTorsionInfo rna_fitted_torsion_info;
750 
751  StepWiseRNA_Base_Sugar_RotamerOP base_sugar_rotamer = new StepWiseRNA_Base_Sugar_Rotamer( base_state, pucker_state, rna_fitted_torsion_info);
752  base_sugar_rotamer->set_extra_anti_chi(extra_anti_chi_rotamer);
753  base_sugar_rotamer->set_extra_syn_chi(extra_syn_chi_rotamer);
754 
756 
757  Size count=0;
758 
759  while(base_sugar_rotamer->get_next_rotamer()){
760  count++;
761 
762  std::cout << " delta1= " << F(8, 3, base_sugar_rotamer->delta()) << " chi_1= " << F(8, 3, base_sugar_rotamer->chi());
763  std::cout << " nu2_1= " << F(8, 3, base_sugar_rotamer->nu2()) << " nu1_1= " << F(8, 3, base_sugar_rotamer->nu1());
764  std::cout << std::endl;
765 
766  pose::Pose pose_at_origin = pose; //This make sure that it is not possible to link different rsd in the generated list to the same pose Apr 10, 2010 Parin
767 
768  pose_at_origin.set_torsion( TorsionID( moving_res , id::BB, 4 ) , base_sugar_rotamer->delta());
769  pose_at_origin.set_torsion( TorsionID( moving_res , id::CHI, 1 ) , base_sugar_rotamer->chi());
770  pose_at_origin.set_torsion( TorsionID( moving_res , id::CHI, 2 ) , base_sugar_rotamer->nu2());
771  pose_at_origin.set_torsion( TorsionID( moving_res , id::CHI, 3 ) , base_sugar_rotamer->nu1());
772 
773 
774 // pose_at_origin.dump_pdb( "before_set_to_origin"+ string_of(count) + ".pdb" );
775 
776  set_to_origin(pose_at_origin, moving_res, false);
777 
778  ResidueOP rsd_at_origin = pose_at_origin.residue( moving_res ).clone();
779 
780  rsd_at_origin_list.push_back(rsd_at_origin); //Does this work?, what I am afraid is that the residue is still linked to the same pose Apr 10, 2010 Parin
781 
782 // pose_at_origin.dump_pdb( "res_at_origin"+ string_of(count) + ".pdb" );
783  }
784 
785  std::cout << "--------------------------------" << std::endl;
786  return rsd_at_origin_list;
787  }
788  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
789 
790  bool
793  utility::vector1 <core::conformation::ResidueOP> const & rsd_at_origin_list,
794  core::kinematics::Stub const & moving_res_base_stub,
795  bool const Is_prepend,
796  core::Size const gap_size){
797 
798  using namespace core::conformation;
799 
800  for(Size n=1; n<=rsd_at_origin_list.size(); n++){
801 
802  Residue const & rsd_at_origin=(*rsd_at_origin_list[n]);
803 
804  std::string const moving_atom_name= (Is_prepend) ? "O3*" : " C5*";
805  std::string const reference_atom_name= (Is_prepend) ? " C5*" : "O3*";
806 
807  numeric::xyzVector<core::Real> atom_coordinate;
808 
809  get_specific_atom_coordinate( moving_atom_name, atom_coordinate, rsd_at_origin, moving_res_base_stub);
810 
811  for(Size sugar_ID=1; sugar_ID<=pose_data_list.size(); sugar_ID++){
812 
813  pose::Pose const & pose = (*pose_data_list[sugar_ID].pose_OP);
814 
815  if(Check_chain_closable(atom_coordinate, pose.residue(reference_res).xyz(reference_atom_name), gap_size)) return true;
816 
817  }
818 
819  }
820 
821  return false;
822 
823 
824  }
825 
826  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
827 
828  //Could make this call the pose_data_list version (right above)
829  bool
831  core::pose::Pose const & pose,
832  utility::vector1 <core::conformation::ResidueOP> const & rsd_at_origin_list, //this one correspond to the moving_base
833  core::kinematics::Stub const & moving_res_base_stub,
834  bool const Is_prepend,
835  Size const gap_size){
836 
837  using namespace core::conformation;
838 
839  for(Size n=1; n<=rsd_at_origin_list.size(); n++){
840 
841  Residue const & rsd_at_origin=(*rsd_at_origin_list[n]);
842 
843  std::string const moving_atom_name= (Is_prepend) ? "O3*" : " C5*";
844  std::string const reference_atom_name= (Is_prepend) ? " C5*" : "O3*";
845 
846  numeric::xyzVector<core::Real> atom_coordinate;
847 
848  get_specific_atom_coordinate( moving_atom_name, atom_coordinate, rsd_at_origin, moving_res_base_stub);
849 
850 
851  if(Check_chain_closable(atom_coordinate, pose.residue(reference_res).xyz(reference_atom_name), gap_size)) return true;
852  }
853 
854  return false;
855 
856  }
857 
858 
859  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
860 
861  void
862  set_base_coordinate_frame(pose::Pose & pose, Size const & seq_num, core::conformation::Residue const & rsd_at_origin, core::kinematics::Stub const & moving_res_base_stub){
863 
865  get_atom_coordinates(xyz_list, seq_num, rsd_at_origin, moving_res_base_stub);
866 
867  for( Size n=1; n<=xyz_list.size(); n++){
868  pose.set_xyz(xyz_list[n].first, xyz_list[n].second);
869  }
870 
871  }
872  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
873 
874 
875  ////////////////////////////////////MOD THIS OUT AFTER TESTING TO OPTIMIZE CODE SPEED/////////////////////////////////////////////////////
876  /*
877  //Consistency check
878  conformation::Residue const & actual_rsd= pose.residue(seq_num);
879 
880  if(xyz_list.size()!=actual_rsd.natoms()) utility_exit_with_message("xyz_list.size()!=actual_rsd.natoms()");
881 
882  if(rsd_at_origin.natoms()!=actual_rsd.natoms()) utility_exit_with_message("rsd_at_origin.natoms()!=actual_rsd.natoms()");
883 
884  for(Size atomno=1; atomno<=actual_rsd.natoms(); atomno++){
885 
886  if( actual_rsd.type().atom_name(atomno)!=rsd_at_origin.type().atom_name(atomno) ){
887  print_individual_atom_info(actual_rsd, atomno, "actual_rsd");
888  print_individual_atom_info(rsd_at_origin, atomno, "rsd_at_origin");
889  utility_exit_with_message("actual_rsd.type().atom_name(atomno)!=rsd_at_origin.type().atom_name(atomno)");
890  }
891 
892  if( actual_rsd.atom_type(atomno).name()!=rsd_at_origin.atom_type(atomno).name() ){
893  print_individual_atom_info(actual_rsd, atomno, "actual_rsd");
894  print_individual_atom_info(rsd_at_origin, atomno, "rsd_at_origin");
895  utility_exit_with_message("actual_rsd.atom_type(atomno).name()!=rsd_at_origin.atom_type(atomno).name()");
896  }
897 
898  if( actual_rsd.atom_type(atomno).element()!=rsd_at_origin.atom_type(atomno).element() ){
899  print_individual_atom_info(actual_rsd, atomno, "actual_rsd");
900  print_individual_atom_info(rsd_at_origin, atomno, "rsd_at_origin");
901  utility_exit_with_message("actual_rsd.atom_type(atomno).element()!=rsd_at_origin.atom_type(atomno).element() ");
902  }
903 
904  }
905  */
906  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
907 
908 
909 
910 
911 }
912 }
913 }