Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LoopAnchorFeatures.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/LoopAnchorFeatures.cc
11 /// @brief report loop anchor features to a features database
12 /// @author Matthew O'Meara (mattjomeara@gmail.com)
13 /// @author Brian Weitzner
14 
15 // Unit Headers
17 
18 // Project Headers
19 #include <core/pose/Pose.hh>
21 
22 //External
23 #include <boost/uuid/uuid.hpp>
24 #include <boost/uuid/uuid_io.hpp>
25 
26 // Utility Headers
27 #include <numeric/HomogeneousTransform.hh>
28  #include <utility/exit.hh>
29 #include <utility/sql_database/DatabaseSessionManager.hh>
30 #include <utility/tag/Tag.hh>
31 #include <utility/vector1.hh>
32 
33 // Basic Headers
34 #include <basic/database/sql_utils.hh>
35 #include <basic/options/option.hh>
36 #include <basic/options/keys/inout.OptionKeys.gen.hh>
37 #include <basic/Tracer.hh>
38 #include <basic/database/schema_generator/PrimaryKey.hh>
39 #include <basic/database/schema_generator/ForeignKey.hh>
40 #include <basic/database/schema_generator/Column.hh>
41 #include <basic/database/schema_generator/Schema.hh>
42 
43 // External Headers
44 #include <cppdb/frontend.h>
45 
46 // C++ Headers
47 #include <utility/excn/Exceptions.hh>
48 #include <sstream>
49 
50 namespace protocols{
51 namespace features{
52 
53 using std::string;
54 using basic::database::safely_write_to_database;
55 using basic::database::safely_prepare_statement;
56 using core::Size;
57 using core::SSize;
58 using core::Real;
59 using core::pose::Pose;
60 using numeric::HomogeneousTransform;
61 using numeric::xyzVector;
62 using utility::sql_database::sessionOP;
63 using utility::vector1;
64 using cppdb::statement;
65 using cppdb::result;
66 
67 static basic::Tracer TR( "protocols.features.LoopAnchorFeatures" );
68 
71  use_single_residue_to_define_anchor_transfrom_(true),
72  min_loop_length_(5),
73  max_loop_length_(30)
74 {}
75 
78  use_single_residue_to_define_anchor_transfrom_(src.use_single_residue_to_define_anchor_transfrom_),
79  min_loop_length_(src.min_loop_length_),
80  max_loop_length_(src.max_loop_length_)
81 {}
82 
84 
85 string
86 LoopAnchorFeatures::type_name() const { return "LoopAnchorFeatures"; }
87 
88 void
90  sessionOP db_session
91 ) const {
95 }
96 
97 void
99  sessionOP db_session
100 ) const {
101  using namespace basic::database::schema_generator;
102 
103  Column struct_id("struct_id", new DbUUID());
104  Column residue_begin("residue_begin", new DbInteger());
105  Column residue_end("residue_end", new DbInteger());
106 
107  Columns primary_key_columns;
108  primary_key_columns.push_back(struct_id);
109  primary_key_columns.push_back(residue_begin);
110  primary_key_columns.push_back(residue_end);
111  PrimaryKey primary_key(primary_key_columns);
112 
113  Columns foreign_key_columns1;
114  foreign_key_columns1.push_back(struct_id);
115  foreign_key_columns1.push_back(residue_begin);
116  vector1< std::string > reference_columns1;
117  reference_columns1.push_back("struct_id");
118  reference_columns1.push_back("resNum");
119  ForeignKey foreign_key1(foreign_key_columns1, "residues", reference_columns1, true);
120 
121  Columns foreign_key_columns2;
122  foreign_key_columns2.push_back(struct_id);
123  foreign_key_columns2.push_back(residue_end);
124  vector1< std::string > reference_columns2;
125  reference_columns2.push_back("struct_id");
126  reference_columns2.push_back("resNum");
127  ForeignKey foreign_key2(foreign_key_columns2, "residues", reference_columns2, true);
128 
129  Schema table("loop_anchors", primary_key);
130  table.add_foreign_key(foreign_key1);
131  table.add_foreign_key(foreign_key2);
132 
133  table.write(db_session);
134 }
135 
136 void
138  sessionOP db_session
139 ) const {
140  using namespace basic::database::schema_generator;
141 
142  Column struct_id("struct_id", new DbUUID());
143  Column residue_begin("residue_begin", new DbInteger());
144  Column residue_end("residue_end", new DbInteger());
145  Column x("x", new DbReal());
146  Column y("y", new DbReal());
147  Column z("z", new DbReal());
148  Column phi("phi", new DbReal());
149  Column psi("psi", new DbReal());
150  Column theta("theta", new DbReal());
151  Column alpha("alpha", new DbReal());
152  Column omega("omega", new DbReal());
153 
154  Columns primary_key_columns;
155  primary_key_columns.push_back(struct_id);
156  primary_key_columns.push_back(residue_begin);
157  primary_key_columns.push_back(residue_end);
158  PrimaryKey primary_key(primary_key_columns);
159 
160  Columns foreign_key_columns;
161  foreign_key_columns.push_back(struct_id);
162  foreign_key_columns.push_back(residue_begin);
163  foreign_key_columns.push_back(residue_end);
164  vector1< std::string > reference_columns;
165  reference_columns.push_back("struct_id");
166  reference_columns.push_back("residue_begin");
167  reference_columns.push_back("residue_end");
168  ForeignKey foreign_key(foreign_key_columns, "loop_anchors", reference_columns, true);
169 
170  Schema table("loop_anchor_transforms", primary_key);
171  table.add_foreign_key(foreign_key);
172  table.add_column(x);
173  table.add_column(y);
174  table.add_column(z);
175  table.add_column(phi);
176  table.add_column(psi);
177  table.add_column(theta);
178  table.add_column(alpha);
179  table.add_column(omega);
180 
181  table.write(db_session);
182 }
183 
184 void
186  sessionOP db_session
187 ) const {
188  using namespace basic::database::schema_generator;
189 
190  Column struct_id("struct_id", new DbUUID());
191  Column residue_begin("residue_begin", new DbInteger());
192  Column residue_end("residue_end", new DbInteger());
193  Column x("x", new DbReal());
194  Column y("y", new DbReal());
195  Column z("z", new DbReal());
196  Column phi("phi", new DbReal());
197  Column psi("psi", new DbReal());
198  Column theta("theta", new DbReal());
199  Column alpha("alpha", new DbReal());
200  Column omega("omega", new DbReal());
201 
202  Columns primary_key_columns;
203  primary_key_columns.push_back(struct_id);
204  primary_key_columns.push_back(residue_begin);
205  primary_key_columns.push_back(residue_end);
206  PrimaryKey primary_key(primary_key_columns);
207 
208  Columns foreign_key_columns;
209  foreign_key_columns.push_back(struct_id);
210  foreign_key_columns.push_back(residue_begin);
211  foreign_key_columns.push_back(residue_end);
212  vector1< std::string > reference_columns;
213  reference_columns.push_back("struct_id");
214  reference_columns.push_back("residue_begin");
215  reference_columns.push_back("residue_end");
216  ForeignKey foreign_key(foreign_key_columns, "loop_anchors", reference_columns, true);
217 
218  Schema table("loop_anchor_transforms_three_res", primary_key);
219  table.add_foreign_key(foreign_key);
220  table.add_column(x);
221  table.add_column(y);
222  table.add_column(z);
223  table.add_column(phi);
224  table.add_column(psi);
225  table.add_column(theta);
226  table.add_column(alpha);
227  table.add_column(omega);
228 
229  table.write(db_session);
230 }
231 
234  utility::vector1<std::string> dependencies;
235  dependencies.push_back("ResidueFeatures");
236  return dependencies;
237 }
238 
239 void
241  utility::tag::TagPtr const tag,
242  protocols::moves::DataMap & /*data*/,
243  protocols::filters::Filters_map const & /*filters*/,
244  protocols::moves::Movers_map const & /*movers*/,
245  Pose const & /*pose*/
246 ) {
247  min_loop_length_ = tag->getOption<Size>("min_loop_length", 5);
248  max_loop_length_ = tag->getOption<Size>("max_loop_length", 30);
249 
250  set_use_relevant_residues_as_loop_length( tag->getOption<bool>("use_relevant_residues_as_loop_length", 0) );
251 
252  if(max_loop_length_ < min_loop_length_){
253  std::stringstream error_msg;
254  error_msg
255  << "The max_loop_length, '" << max_loop_length_ << "',"
256  << " must be longer than the min_loop_length, '" << min_loop_length_ << "'." << std::endl;
257  throw utility::excn::EXCN_RosettaScriptsOption(error_msg.str());
258  }
259 }
260 
261 /// @details
262 /// An anchor is a take off and landing for a loop.
263 /// Every residue in the loop must be relevant in order for the loop to be stored.
264 Size
266  Pose const & pose,
267  vector1< bool > const & relevant_residues,
268  boost::uuids::uuid struct_id,
269  sessionOP db_session
270 ){
271  string loop_anchors_stmt_string = "INSERT INTO loop_anchors (struct_id, residue_begin, residue_end) VALUES (?,?,?);";
272  statement loop_anchors_stmt(
273  safely_prepare_statement(loop_anchors_stmt_string, db_session));
274 
275  string loop_anchor_transforms_stmt_string =
276  "INSERT INTO loop_anchor_transforms (struct_id, residue_begin, residue_end, x, y, z, phi, psi, theta, alpha, omega) VALUES (?,?,?,?,?,?,?,?,?,?,?);";
277  statement loop_anchor_transforms_stmt(
278  safely_prepare_statement(loop_anchor_transforms_stmt_string, db_session));
279 
280  string loop_anchor_transforms_three_res_stmt_string =
281  "INSERT INTO loop_anchor_transforms_three_res (struct_id, residue_begin, residue_end, x, y, z, phi, psi, theta, alpha, omega) VALUES (?,?,?,?,?,?,?,?,?,?,?);";
282  statement loop_anchor_transforms_three_res_stmt(
283  safely_prepare_statement(loop_anchor_transforms_three_res_stmt_string, db_session));
284 
285  vector1<Size>::const_iterator chain_ending(pose.conformation().chain_endings().begin());
286  vector1<Size>::const_iterator chain_ending_end(pose.conformation().chain_endings().end());
287 
288  Size local_min_loop_length = min_loop_length( relevant_residues );
289  Size local_max_loop_length = max_loop_length( relevant_residues );
290 
291  for(SSize begin=1; begin <= SSize( pose.total_residue() - local_min_loop_length ); ++begin){
292 
293  for(Size end=begin;
294  (end <= begin + local_max_loop_length && end <= pose.total_residue());
295  ++end){
296 
297  bool bail_out = !relevant_residues[end];
298 
299  // Note chain_endings does not have the last residue in the pose
300  // in the chain endings vector. So handle this separately
301  if((chain_ending != chain_ending_end) && (end == *chain_ending))
302  {
303  ++chain_ending;
304  bail_out = true;
305  }
306  if ( bail_out )
307  {
308  if( (end - begin + 1) < local_min_loop_length){
309  begin = end;
310  }
311  break;
312  }
313 
314  if( (end - begin + 1) >= local_min_loop_length){
315  loop_anchors_stmt.bind(1,struct_id);
316  loop_anchors_stmt.bind(2,begin);
317  loop_anchors_stmt.bind(3,end);
318  basic::database::safely_write_to_database(loop_anchors_stmt);
319 
321  compute_transform_and_write_to_db(struct_id, begin, end, pose, loop_anchor_transforms_stmt);
322 
324  compute_transform_and_write_to_db(struct_id, begin, end, pose, loop_anchor_transforms_three_res_stmt);
325 
326  }
327  }
328  }
329  return 0;
330 }
331 
332 void LoopAnchorFeatures::set_use_relevant_residues_as_loop_length( bool const use_relevant_residues_as_loop_length )
333 {
334  use_relevant_residues_as_loop_length_ = use_relevant_residues_as_loop_length;
335 }
336 
337 void LoopAnchorFeatures::set_use_single_residue_to_define_anchor_transfrom( bool const use_single_residue_to_define_anchor_transfrom )
338 {
339  use_single_residue_to_define_anchor_transfrom_ = use_single_residue_to_define_anchor_transfrom;
340 }
341 
343 {
344  return determine_correct_length( relevant_residues, min_loop_length_ );
345 }
346 
348 {
349  return determine_correct_length( relevant_residues, max_loop_length_ );
350 }
351 
352 Size LoopAnchorFeatures::determine_correct_length( vector1< bool > const & relevant_residue, Size default_length )
353 {
355  {
356  Size number_of_residues = 0;
357  for ( vector1< bool >::const_iterator it = relevant_residue.begin(); it != relevant_residue.end(); ++it )
358  {
359  if ( *it ) ++number_of_residues;
360  }
361  return number_of_residues;
362  }
363  return default_length;
364 }
365 
368  vector1<Size> residue_vector;
370  residue_vector.push_back(resNo);
371  residue_vector.push_back(resNo);
372  residue_vector.push_back(resNo);
373  } else{
374  residue_vector.push_back(resNo);
375  residue_vector.push_back(resNo + 1);
376  residue_vector.push_back(resNo + 2);
377  }
378  return residue_vector;
379 }
380 
383  vector1<Size> residue_vector;
385  residue_vector.push_back(resNo);
386  residue_vector.push_back(resNo);
387  residue_vector.push_back(resNo);
388  } else{
389  residue_vector.push_back(resNo);
390  residue_vector.push_back(resNo - 1);
391  residue_vector.push_back(resNo - 2);
392  }
393  return residue_vector;
394 }
395 
398  vector1<Size> atom_vector;
399  // 1, 2, 3 corresponds to N, CA, C, respectively
401  atom_vector.push_back(1);
402  atom_vector.push_back(2);
403  atom_vector.push_back(3);
404  } else{
405  // Multiple residues being used to define transform - only use CA coordinates
406  atom_vector.push_back(2);
407  atom_vector.push_back(2);
408  atom_vector.push_back(2);
409  }
410  return atom_vector;
411 }
412 
413 
414 HomogeneousTransform<Real>
416  Pose const & pose,
417  vector1<Size> const & residue_begin,
418  vector1<Size> const & residue_end,
419  vector1<Size> const & atoms){
420 
421  runtime_assert_string_msg( (residue_begin.size() == atoms.size()) && (residue_begin.size() == residue_end.size()) &&
422  (residue_begin.size() == 3), "The length of the residues and atoms vectors must be exactly 3.");
423 
424  HomogeneousTransform<Real> take_off_frame(
425  pose.residue(residue_begin[1]).xyz(atoms[1]),
426  pose.residue(residue_begin[2]).xyz(atoms[2]),
427  pose.residue(residue_begin[3]).xyz(atoms[3]));
428 
429  HomogeneousTransform<Real> landing_frame(
430  pose.residue(residue_end[1]).xyz(atoms[1]),
431  pose.residue(residue_end[2]).xyz(atoms[2]),
432  pose.residue(residue_end[3]).xyz(atoms[3]));
433 
434  HomogeneousTransform<Real> anchor_transform(
435  take_off_frame.inverse() * landing_frame);
436 
437  return anchor_transform;
438 }
439 
440 void
442  boost::uuids::uuid struct_id,
443  Size begin,
444  Size end,
445  Pose const & pose,
446  statement & stmt){
447 
448  vector1<Size> start_res = start_residue(begin);
449  vector1<Size> end_res = end_residue(end);
450  vector1<Size> atom_set = atoms();
451 
452  HomogeneousTransform<Real> anchor_transform(
453  compute_anchor_transform(pose, start_res, end_res, atom_set));
454 
455  xyzVector<Real> t(anchor_transform.point());
456  xyzVector<Real> r(anchor_transform.euler_angles_rad());
457 
458  Real alpha = compute_atom_angles(pose, start_res, atom_set);
459  Real omega = compute_atom_angles(pose, end_res, atom_set);
460 
461  stmt.bind(1, struct_id);
462  stmt.bind(2, begin);
463  stmt.bind(3, end);
464  stmt.bind(4, t.x());
465  stmt.bind(5, t.y());
466  stmt.bind(6, t.z());
467  stmt.bind(7, r.x());
468  stmt.bind(8, r.y());
469  stmt.bind(9, r.z());
470  stmt.bind(10, alpha);
471  stmt.bind(11, omega);
472  basic::database::safely_write_to_database(stmt);
473 }
474 
475 Real
477  Pose const & pose,
478  vector1<Size> const & residues,
479  vector1<Size> const & atoms){
480 
481  runtime_assert_string_msg( residues.size() == atoms.size() && residues.size() == 3,
482  "The length of the residues and atoms vectors must be exactly 3.");
483 
484  xyzVector<Real> first_vector(
485  pose.residue(residues[1]).xyz(atoms[1]) - pose.residue(residues[2]).xyz(atoms[2]));
486  xyzVector<Real> second_vector(
487  pose.residue(residues[3]).xyz(atoms[3]) - pose.residue(residues[2]).xyz(atoms[2]));
488 
489  return numeric::arccos(first_vector.dot(second_vector)/(first_vector.norm() * second_vector.norm()));
490 }
491 
492 } //namesapce
493 } //namespace