Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SaltBridgeFeatures.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 protocols/features/SaltBridgeFeatures.cc
11 /// @brief report geometric solvation energy for each polar site to a features database
12 /// @author Matthew O'Meara
13 
14 // Unit Headers
16 
17 //External
18 #include <cppdb/frontend.h>
19 #include <boost/uuid/uuid.hpp>
20 #include <boost/uuid/uuid_io.hpp>
21 
22 // Platform Headers
23 #include <core/pose/Pose.hh>
24 #include <core/types.hh>
25 #include <core/chemical/AA.hh>
28 
29 // Basic Headers
30 #include <basic/options/option.hh>
31 #include <basic/options/keys/inout.OptionKeys.gen.hh>
32 #include <basic/database/sql_utils.hh>
33 
34 // Numeric Headers
35 #include <numeric/xyzVector.hh>
36 #include <numeric/xyz.functions.hh>
37 #include <numeric/sphericalVector.hh>
38 #include <core/kinematics/Stub.hh>
39 #include <numeric/constants.hh>
40 #include <basic/database/schema_generator/PrimaryKey.hh>
41 #include <basic/database/schema_generator/ForeignKey.hh>
42 #include <basic/database/schema_generator/Column.hh>
43 #include <basic/database/schema_generator/Schema.hh>
44 
45 
46 // Utility Headers
47 #include <utility/sql_database/DatabaseSessionManager.hh>
48 #include <utility/vector1.hh>
49 
50 // C++ Headers
51 #include <string>
52 #include <sstream>
53 
54 namespace protocols{
55 namespace features{
56 
57 using std::string;
58 using std::stringstream;
59 using std::endl;
60 using core::Size;
61 using core::Real;
62 using core::Vector;
63 using core::Length;
64 using core::Angle;
73 using core::pose::Pose;
74 using numeric::dihedral_radians;
75 using numeric::sphericalVector;
76 using numeric::xyz_to_spherical;
77 using numeric::constants::r::pi;
78 using numeric::constants::r::pi_over_2;
79 using numeric::constants::r::pi_over_180;
80 using utility::vector1;
81 using utility::sql_database::sessionOP;
82 using cppdb::statement;
83 using cppdb::result;
84 
87  distance_cutoff_(6)
88 {}
89 
91  Length distance_cutoff) :
93  distance_cutoff_(distance_cutoff)
94 {}
95 
97  SaltBridgeFeatures const & src ) :
99  distance_cutoff_(src.distance_cutoff_)
100 {}
101 
102 string
103 SaltBridgeFeatures::type_name() const { return "SaltBridgeFeatures"; }
104 
105 void
107  sessionOP db_session
108 ) const {
110 }
111 
112 void
114  sessionOP db_session
115 ) const {
116  using namespace basic::database::schema_generator;
117 
118  Column struct_id("struct_id", new DbUUID());
119  Column don_resNum("don_resNum", new DbInteger());
120  Column acc_id("acc_id", new DbInteger());
121  Column psi("psi", new DbReal());
122  Column theta("theta", new DbReal());
123  Column rho("rho", new DbReal());
124  Column orbital("orbital", new DbText());
125 
126  Columns primary_key_columns;
127  primary_key_columns.push_back(struct_id);
128  primary_key_columns.push_back(don_resNum);
129  primary_key_columns.push_back(acc_id);
130  PrimaryKey primary_key(primary_key_columns);
131 
132  Columns foreign_key_columns1;
133  foreign_key_columns1.push_back(struct_id);
134  foreign_key_columns1.push_back(don_resNum);
135  vector1< std::string > reference_columns1;
136  reference_columns1.push_back("struct_id");
137  reference_columns1.push_back("resNum");
138  ForeignKey foreign_key1(foreign_key_columns1, "residues", reference_columns1, true);
139 
140  Columns foreign_key_columns2;
141  foreign_key_columns2.push_back(struct_id);
142  foreign_key_columns2.push_back(acc_id);
143  vector1< std::string > reference_columns2;
144  reference_columns2.push_back("struct_id");
145  reference_columns2.push_back("site_id");
146  ForeignKey foreign_key2(foreign_key_columns2, "hbond_sites", reference_columns2, true);
147 
148  Schema table("salt_bridges", primary_key);
149  table.add_foreign_key(foreign_key1);
150  table.add_foreign_key(foreign_key2);
151  table.add_column(psi);
152  table.add_column(theta);
153  table.add_column(rho);
154  table.add_column(orbital);
155 
156  table.write(db_session);
157 }
158 
159 
162  utility::vector1<std::string> dependencies;
163  dependencies.push_back("ResidueFeatures");
164  dependencies.push_back("HBondFeatures");
165  return dependencies;
166 }
167 
168 
169 //Donald JE, Kulp DW, DeGrado WF. Salt bridges: Geometrically
170 //specific, designable interactions. Proteins: Structure, Function,
171 //and Bioinformatics. 2010
172 Size
174  Pose const & pose,
175  vector1< bool > const &,
176  boost::uuids::uuid struct_id,
177  sessionOP db_session
178 ){
179 
180  // locate candidate polar sites from the hbond_sites table
181 
182  // Note: these are all pairs of potential salt bridge sites, not
183  // just the ones involved in hydrogen bonds
184  std::string hbond_string =
185  "SELECT\n"
186  " acc.site_id, acc.resNum, acc.atmNum, don.resNum\n"
187  "FROM\n"
188  " hbond_sites AS acc, residues AS don\n"
189  "WHERE\n"
190  " don.struct_id = ? AND acc.struct_id = ? AND\n"
191  " (don.name3 = 'ARG' OR don.name3 = 'LYS' OR don.name3 = 'HIS') AND\n"
192  " (acc.HBChemType = 'hbacc_CXA' OR acc.HBChemType = 'hbacc_CXL');\n";
193  statement hbond_stmt(basic::database::safely_prepare_statement(hbond_string,db_session));
194  hbond_stmt.bind(1,struct_id);
195  hbond_stmt.bind(2,struct_id);
196 
197  result res(basic::database::safely_read_from_database(hbond_stmt));
198  Size acc_site_id, acc_resNum, acc_atmNum, don_resNum;
199  PointPosition bb, b, c, n, o_proj;
200  Stub don_frame;
201  sphericalVector<Real> local_o;
202  Angle psi(0), theta(0);
203  Length rho(0);
204  std::string salt_bridge_string = "INSERT INTO salt_bridges (struct_id, don_resNum, acc_id, psi, theta, rho, orbital) VALUES (?,?,?,?,?,?,?)";
205  statement salt_bridge_statement(basic::database::safely_prepare_statement(salt_bridge_string,db_session));
206 
207 
208  while(res.next()){
209  res >> acc_site_id >> acc_resNum >> acc_atmNum >> don_resNum;
210 
211  Residue const & d(pose.residue(don_resNum));
212  Residue const & a(pose.residue(acc_resNum));
213  PointPosition const & o = a.atom(acc_atmNum).xyz();
214 
215  //MJO NOTE: It is necessary to look up the atoms by name rather
216  //then using atom numbering directly because residue type patches
217  //can insert or delete atoms to modify atom numbering. For
218  //instance, the CtermProteinFull patch inserts the OXT atom after
219  //the O at position 5 for otherwise unmodified protein backbones.
220  switch(d.aa()){
221  case aa_lys:
222  n = d.atom(d.atom_index(" NZ ")).xyz();
223  c = d.atom(d.atom_index(" NZ ")).xyz();
224  rho = c.distance(o);
225  if(rho > distance_cutoff_) continue;
226 
227  bb = d.atom(d.atom_index(" CD ")).xyz();
228  b = d.atom(d.atom_index(" CE ")).xyz();
229 
230  psi = dihedral_radians(bb, b, c, o);
231  theta = angle_of(b, c, o) - pi/2;
232  break;
233  case aa_his:
234  n = d.atom(d.atom_index(" ND1")).xyz();
235 
236  c = (n + d.atom(d.atom_index(" NE2")).xyz())/2;
237  rho = c.distance(o);
238  if(rho > distance_cutoff_) continue;
239 
240  b = d.atom(d.atom_index(" CG ")).xyz();
241  don_frame.from_four_points(c,c,b,n);
242  local_o = xyz_to_spherical(don_frame.global2local(o));
243  psi = local_o.phi()*pi_over_180;
244  theta = local_o.theta()*pi_over_180 - pi_over_2;
245  break;
246  case aa_arg:
247  c = d.atom(d.atom_index(" CZ ")).xyz();
248  rho = c.distance(o);
249  if(rho > distance_cutoff_) continue;
250 
251  b = d.atom(d.atom_index(" NE ")).xyz();
252 
253  {
254  PointPosition const & n0(d.atom(d.atom_index(" NE ")).xyz());
255  PointPosition const & n1(d.atom(d.atom_index(" NH1")).xyz());
256  PointPosition const & n2(d.atom(d.atom_index(" NH2")).xyz());
257 
258  n = n0.distance(o) < n1.distance(o) ?
259  (n0.distance(o) < n2.distance(o) ? n0 : n2) :
260  (n1.distance(o) < n2.distance(o) ? n1 : n2);
261 
262  don_frame.from_four_points(c,c,b,n1);
263  }
264 
265  local_o = xyz_to_spherical(don_frame.global2local(o));
266  psi = local_o.phi()*pi_over_180;
267  theta = local_o.theta()*pi_over_180 - pi_over_2;
268  break;
269  default:
270  stringstream err_msg;
271  err_msg
272  << "Unrecognized salt bridging donor group on rsd: (" << d.name3() << ", " << don_resNum << ")" << endl;
273  utility_exit_with_message(err_msg.str());
274  }
275 
276  PointPosition const & ob = a.atom(a.atom_base(acc_atmNum)).xyz();
277  PointPosition const & obb = a.atom(a.atom_base(a.atom_base(acc_atmNum))).xyz();
278  Angle const hb_chi(dihedral_radians(obb, ob, o, n));
279  string const orbital((hb_chi < pi_over_2 && hb_chi > -pi_over_2) ? "anti" : "syn");
280 
281  salt_bridge_statement.bind(1,struct_id);
282  salt_bridge_statement.bind(2,don_resNum);
283  salt_bridge_statement.bind(3,acc_site_id);
284  salt_bridge_statement.bind(4,psi);
285  salt_bridge_statement.bind(5,theta);
286  salt_bridge_statement.bind(6,rho);
287  salt_bridge_statement.bind(7,orbital);
288  basic::database::safely_write_to_database(salt_bridge_statement);
289  }
290 
291  return 0;
292 }
293 
294 } //namesapce
295 } //namespace