Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 core/pose/carbohydrates/util.cc
11 /// @brief Utility function definitions for carbohydrate-containing poses..
12 /// @author labonte
13 
14 // Unit headers
16 #include <core/pose/Pose.hh>
17 
18 // Package headers
20 
21 // Project headers
22 #include <core/id/TorsionID.hh>
23 #include <core/types.hh>
24 
25 // Utility headers
26 //#include <utility/excn/Exceptions.hh>
27 
28 // Basic headers
29 #include <basic/Tracer.hh>
30 
31 // Numeric headers
32 #include <numeric/xyz.functions.hh>
33 
34 
35 // Construct tracer.
36 static basic::Tracer TR("core.pose.carbohydrates.util");
37 
38 
39 namespace core {
40 namespace pose {
41 namespace carbohydrates {
42 
43 using namespace std;
44 using namespace core;
45 
46 
47 // Calculate and return the phi angle between a saccharide residue of the given pose and the previous residue.
48 /// @details This special-case function for carbohydrate phis is necessary, because of the following:\n
49 /// For aldopyranoses, phi is defined as O5(n)-C1(n)-OX(n-1)-CX(n-1),
50 /// where X is the position of the glycosidic linkage.\n
51 /// For aldofuranoses, phi is defined as O4(n)-C1(n)-OX(n-1)-CX(n-1).\n
52 /// For 2-ketopyranoses, phi is defined as O6(n)-C2(n)-OX(n-1)-CX(n-1).\n
53 /// For 2-ketofuranoses, phi is defined as O5(n)-C2(n)-OX(n-1)-CX(n-1).\n
54 /// Et cetera...\n
55 /// However, for aldopyranoses, BB X+1 is defined as: CX-OX-UPPER1-UPPER2.\n
56 /// CHI 1 is O5-C1-O1-HO1, which for an internal residue with virtual atoms for O1 and HO1, is the same as phi(n),
57 /// provided the virtual atoms are made to move with any rotation of BB X+1. The same concept holds for aldo-
58 /// furanoses; however, ketoses are more complicated. The cyclic oxygen must be the reference for phi, yet CHI 2 at
59 /// the anomeric position is defined with C1 as the reference atom, not the cyclic oxygen (O5 for furanoses, O6 for
60 /// pyranoses). To complicate matters further, two virtual atoms in a row in a CHI gives NAN, so CHI angles cannot be
61 /// used after all. Thus, we have to use vector calculus to calculate phi....
63 calculate_carbohydrate_phi(Pose const & pose, uint const sequence_position) {
64  using namespace numeric;
65  using namespace conformation;
66 
67  if (sequence_position == 1) { // TODO: It's not sequence position 1 that is the problem....
68  bool is_1st_residue_of_branch = false; // TEMP
69  if (is_1st_residue_of_branch) {
70  // TODO: When branching is implemented, this must return the 1st torsion angle back to the main chain.
71  return 180.0; // TEMP
72  } else {
73  TR.Warning << "Phi is undefined for polysaccharide residue 1 unless part of a branch; "
74  "returning 0.0." << endl;
75  return 0.0;
76  }
77  }
78 
79  // Get two residues of interest.
80  ResidueCAP res_n = & pose.residue(sequence_position);
81  ResidueCAP res_n_minus_1 = & pose.residue(sequence_position - 1);
82 
83  // Get reference atom numbers.
84  uint cyclic_O_num;
85  if (res_n->carbohydrate_info()->is_aldose()) {
86  cyclic_O_num = res_n->carbohydrate_info()->ring_size() - 1;
87  } else /*is ketose*/ {
88  cyclic_O_num = res_n->carbohydrate_info()->ring_size();
89  }
90  uint anomeric_C_num = res_n->carbohydrate_info()->anomeric_carbon();
91  uint x = res_n_minus_1->carbohydrate_info()->mainchain_glycosidic_bond_acceptor();
92 
93  // Set the atom names of the four reference atoms.
94  string O_cyclic = "O" + string(1, cyclic_O_num + '0');
95  string C_anomeric = "C" + string(1, anomeric_C_num + '0');
96  string OX = "O" + string(1, x + '0');
97  string CX = "C" + string(1, x + '0');
98 
99  // Obtain the position vectors (a, b, c, d) of the four reference atoms.
100  Vector a = res_n->xyz(O_cyclic);
101  Vector b = res_n->xyz(C_anomeric);
102  Vector c = res_n_minus_1->xyz(OX);
103  Vector d = res_n_minus_1->xyz(CX);
104 
105  return dihedral_degrees(a, b, c, d);
106 }
107 
108 // Return the number of degrees by which the phi angle between a saccharide residue of the given pose and the previous
109 // residue differs from the BB torsion used by Rosetta.
110 /// @remarks See the details for calculate_carbohydrate_phi() for an explanation on why this method is necessary.
112 carbohydrate_phi_offset_from_BB(Pose const & pose, uint const sequence_position)
113 {
114  using namespace id;
115 
116  // Get the actual value of phi.
117  Angle actual_phi = calculate_carbohydrate_phi(pose, sequence_position);
118 
119  // Get the appropriate BB torsion (found on the previous residue).
120  uint x = pose.residue_type(sequence_position - 1).carbohydrate_info()->mainchain_glycosidic_bond_acceptor();
121  Angle bb_torsion = pose.torsion(TorsionID(sequence_position - 1, BB, x + 1));
122 
123  // Return the difference.
124  return actual_phi - bb_torsion;
125 }
126 
127 } // namespace carbohydrates
128 } // namespace pose
129 } // namespace core