Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DetectSymmetryMover.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 // :noTabs=false:tabSize=4:indentSize=4:
4 //
5 // (c) Copyright Rosetta Commons Member Institutions.
6 // (c) This file is part of the Rosetta software suite and is made available under license.
7 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
8 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
9 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
10 
11 /// @file protocols/simple_moves/symmetry/DetectSymmetryMover.cc
12 /// @brief Automatical detection and setup of the symmetry machinery from an assymetric pose made of symmetric chains. Only works with cyclic simmetries.
13 /// @author Javier Castellanos ( javiercv@uw.edu )
14 
17 
18 #include <core/pose/Pose.hh>
19 #include <protocols/moves/Mover.hh>
21 #include <numeric/xyzMatrix.hh>
22 #include <numeric/xyzVector.hh>
23 #include <numeric/xyz.functions.hh>
24 #include <basic/database/open.hh>
27 #include <core/scoring/rms_util.hh>
28 #include <utility/tag/Tag.hh>
29 
30 // Utility headers
31 #include <boost/lexical_cast.hpp>
32 #include <utility/exit.hh>
33 #include <basic/Tracer.hh>
34 
35 
36 #include <basic/options/option.hh>
37 #include <basic/options/keys/symmetry.OptionKeys.gen.hh>
38 
39 
40 namespace protocols {
41 namespace simple_moves {
42 namespace symmetry {
43 
44 static basic::Tracer TR("protocols.simple_moves.symmetry.DetectSymmetry");
45 
46 // creators
50 }
51 
54  return new DetectSymmetry;
55 }
56 
59  return "DetectSymmetry";
60 }
61 
62 ////////////////////
64  subunit_tolerance_( 0.01),
65  plane_tolerance_( 1e-3 )
66 { }
67 
68 DetectSymmetry::DetectSymmetry(core::Real subunit_tolerance, core::Real plane_tolerance):
69  subunit_tolerance_( subunit_tolerance ),
70  plane_tolerance_( plane_tolerance )
71 {
72 }
73 
74 void
76  Size n_jumps = pose.num_jump();
77  if( n_jumps == 0 ) utility_exit_with_message("Only one chain! no posible symmetry.");
78  Size symmetric_type = n_jumps + 1;
79  TR << symmetric_type << " number of subunits found" << std::endl;
80  //check that the chains have the same sequence
81  std::string seq1 = pose.chain_sequence(1);
82  const Pose ref_pose( pose, 1, seq1.size() );
83  for(Size i = 1; i < symmetric_type; ++i){
84  if( seq1 != pose.chain_sequence(i) ) utility_exit_with_message("subunits have different sequence! structure can't be symmetric");
85  Pose test_pose( pose, i*seq1.size()+1 , (i + 1)*seq1.size() );
86  core::Real rms = core::scoring::CA_rmsd(ref_pose, test_pose);
87  TR.Debug << "rms chain " << i + 1 << " " << rms << std::endl;
88  if( rms > subunit_tolerance_ ) utility_exit_with_message("rmsd between subunits higher than subunit tolerance");
89 
90  }
91  TR << seq1.size() << " residues per subunit" << std::endl;
92 
93  // Translate the center of the mass of the pose to the origin
96  while( cm_pose[2] > plane_tolerance_) {
97  pose.apply_transform_Rx_plus_v(id_rot_mat, -1*cm_pose);
98  cm_pose = protocols::geometry::center_of_mass(pose, 1, pose.total_residue());
99  }
100 
101  // align the center of mass of chain A in the Y axis
102  // rotate around x to align the center of mass of chain a to the xy plane
103  xyzVector cm_chain_A = protocols::geometry::center_of_mass(pose, 1, seq1.size());
104  core::Real angle_cm_orig_x = numeric::angle_degrees(cm_chain_A, xyzVector(cm_chain_A[0],0,0), xyzVector(cm_chain_A[0],cm_chain_A[1], 0));
105  TR.Debug << "Angle between center of mass of chain A and x axis: " << angle_cm_orig_x << std::endl;
106  TR.Debug << "start - center of mass chain A " << cm_chain_A[0] << " " << cm_chain_A[1] << " " << cm_chain_A[2] << " " << std::endl;
107  xyzMatrix x_rot = numeric::x_rotation_matrix_degrees(angle_cm_orig_x * ((cm_chain_A[2] < 0.0)? -1 : 1) );
108  pose.apply_transform_Rx_plus_v(x_rot, xyzVector(0,0,0));
109  cm_chain_A = protocols::geometry::center_of_mass(pose, 1, seq1.size());
110  angle_cm_orig_x = numeric::angle_degrees(cm_chain_A, xyzVector(cm_chain_A[0],0,0), xyzVector(cm_chain_A[0],cm_chain_A[1], 0));
111  TR.Debug << "t1 - Angle between center of mass of chain A and x axis: " << angle_cm_orig_x << std::endl;
112  TR.Debug << "t1 - center of mass chain A " << cm_chain_A[0] << " " << cm_chain_A[1] << " " << cm_chain_A[2] << " " << std::endl;
113 
114  // rotate around z to move the center of mass of chain A to Y axis
115  core::Real angle_cm_orig_z = numeric::angle_degrees(cm_chain_A, xyzVector(0,0,0), xyzVector(0,1,0));
116  xyzMatrix z_rot = numeric::z_rotation_matrix_degrees(angle_cm_orig_z * ((cm_chain_A[0] < 0.0) ? -1 : 1) );
117  pose.apply_transform_Rx_plus_v(z_rot, xyzVector(0,0,0));
118  cm_chain_A = protocols::geometry::center_of_mass(pose, 1, seq1.size());
119  TR.Debug << "t2 - Angle between center of mass of chain A and y axis: " << angle_cm_orig_z << std::endl;
120  TR.Debug << "t2 - center of mass chain A " << cm_chain_A[0] << " " << cm_chain_A[1] << " " << cm_chain_A[2] << " " << std::endl;
121 
122  // rotate around y again to put the center of mass of the other subunits in the xy-plane
123  xyzVector cm_chain_B = protocols::geometry::center_of_mass(pose, seq1.size(), 2* seq1.size());
124  TR.Debug << "t4 - center of mass chain B " << cm_chain_B[0] << " " << cm_chain_B[1] << " " << cm_chain_B[2] << " " << std::endl;
125  core::Real angle_cm_orig_y = numeric::angle_degrees(cm_chain_B, xyzVector(0,cm_chain_B[1],0), xyzVector(cm_chain_B[0],cm_chain_B[1], 0));
126  xyzMatrix y_rot = numeric::y_rotation_matrix_degrees(angle_cm_orig_y * ((cm_chain_B[2] > 0.0) ? -1 : 1));
127  TR.Debug << "t4 - Angle between center of mass of chain B and y axis: " << angle_cm_orig_y << std::endl;
128  pose.apply_transform_Rx_plus_v(y_rot, xyzVector(0,0,0));
129  cm_chain_B = protocols::geometry::center_of_mass(pose, seq1.size(), 2* seq1.size());
130  TR.Debug << "t4 - center of mass chain B " << cm_chain_B[0] << " " << cm_chain_B[1] << " " << cm_chain_B[2] << " " << std::endl;
131 
132 
133 
134 
135  // check that the center of mass of all the subunits align close enough to the xy plane
136 // for(int i = 0; i < symmetric_type; i++){
137  // xyzVector cm_chain_i = protocols::geometry::center_of_mass( pose, (i == 0) ? 1 :i*seq1.size() , (i + 1)*seq1.size() );
138 // TR << "z-coordinate of the center of mass chain " << i + 1 << " = " << cm_chain_i[2] << std::endl;
139 // if( cm_chain_i[2] > plane_tolerance_ ) {
140  // utility_exit_with_message("the center of mass of the diferent subunits don't align properly to the xy-plane. Input structure might have a non-cyclic symmetry or couldn't be aligned properly to the plane");
141 // }
142 // }
143 
144 
145  // Now that chain A is properly oriented around the Z-axis copy it to a new pose.
146  Pose new_pose( pose, 1, seq1.size() );
147 
148  // set up for symmetry
149  std::string db_file = "symmetry/cyclic/C" + boost::lexical_cast< std::string >( symmetric_type ) + "_Z.sym";
150  std::string path_to_symdef = basic::database::full_name(db_file);
152  symmdef.read_symmetry_data_from_file( path_to_symdef );
153  // Turn symmetry hacks on
154  basic::options::option[basic::options::OptionKeys::symmetry::symmetry_definition].value( db_file );
155  core::pose::symmetry::make_symmetric_pose( new_pose, symmdef );
156  pose = new_pose;
157 
158 }
159 
160 
161 void
163  TagPtr const tag,
165  Filters_map const &,
167  Pose const &
168 )
169 {
170  subunit_tolerance_ = tag->getOption< core::Real >("subunit_tolerance", 0.01);
171  plane_tolerance_ = tag->getOption< core::Real >("plane_tolerance",1e-3);
172 }
173 
174 
175 } // symmetry
176 } // simple_moves
177 } // protocols