Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
HelixBundleFeatures.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/features/helixAssembly/HelixBundleFeatures.cc
12 /// @brief Search through a pose for sets of 3 helices and generate RMSD calculations between all pairs of them
13 /// @author Tim Jacobs
14 
15 //Core
16 #include <core/types.hh>
19 #include <core/scoring/sasa.hh>
20 #include <core/pose/util.hh>
21 
22 //External
23 #include <boost/uuid/uuid.hpp>
24 
25 //Devel
28 
29 //Utility
30 #include <utility/sql_database/DatabaseSessionManager.hh>
31 #include <utility/tag/Tag.hh>
32 #include <utility/LexicographicalIterator.hh>
33 
34 //Core
38 #include <core/scoring/Energies.hh>
40 #include <core/graph/Graph.hh>
41 
42 //C++
43 #include <string>
44 #include <math.h>
45 
46 //External Headers
47 #include <cppdb/frontend.h>
48 
49 //Basic
50 #include <basic/database/sql_utils.hh>
51 #include <basic/Tracer.hh>
52 #include <basic/options/util.hh>
53 #include <basic/options/keys/helixAssembly.OptionKeys.gen.hh>
54 #include <basic/database/schema_generator/PrimaryKey.hh>
55 #include <basic/database/schema_generator/ForeignKey.hh>
56 #include <basic/database/schema_generator/Column.hh>
57 #include <basic/database/schema_generator/Schema.hh>
58 #include <basic/database/schema_generator/Constraint.hh>
59 
60 //Numeric
61 #include <numeric/PCA.hh>
62 #include <numeric/xyz.functions.hh>
63 #include <numeric/xyzVector.hh>
64 
65 static basic::Tracer TR("protocols.features.helixAssembly.HelixBundleFeatures");
66 
67 namespace protocols {
68 namespace features {
69 namespace helixAssembly {
70 
71 using namespace std;
72 using namespace core;
73 using core::pose::Pose;
74 using utility::vector1;
75 using utility::sql_database::sessionOP;
76 using cppdb::statement;
77 using cppdb::result;
78 
80  helix_cap_dist_cutoff_(12.0),
81  bundle_size_(3),
82  helix_size_(14)
83 {
85 }
86 
89 {
90  utility::vector1<std::string> dependencies;
91  dependencies.push_back("ResidueFeatures");
92  dependencies.push_back("ProteinResidueConformationFeatures");
93  dependencies.push_back("ResidueSecondaryStructureFeatures");
94  dependencies.push_back("SecondaryStructureSegmentFeatures");
95  return dependencies;
96 }
97 
98 void
99 HelixBundleFeatures::write_schema_to_db(utility::sql_database::sessionOP db_session) const
100 {
101  using namespace basic::database::schema_generator;
102 
103  Column struct_id("struct_id", new DbUUID(), false /*not null*/, false /*don't autoincrement*/);
104 
105  /******helix_bundles******/
106  Column bundle_id("bundle_id", new DbInteger(), false /*not null*/, false /*autoincrement*/);
107 // Column bundle_id("bundle_id", new DbInteger(), false /*not null*/, true /*autoincrement*/);
108  Column bundle_size("bundle_size", new DbInteger(), false, false);
109  Column helix_size("helix_size", new DbInteger(), false, false);
110 
111  utility::vector1<Column> helix_bundle_pkey_cols;
112  helix_bundle_pkey_cols.push_back(struct_id);
113  helix_bundle_pkey_cols.push_back(bundle_id);
114 
115  Schema helix_bundles("helix_bundles", helix_bundle_pkey_cols);
116  helix_bundles.add_column(bundle_size);
117  helix_bundles.add_column(helix_size);
118  helix_bundles.add_foreign_key(ForeignKey(struct_id, "structures", "struct_id", true /*defer*/));
119 
120  helix_bundles.write(db_session);
121 
122  /******bundle_helices******/
123  Column helix_id("helix_id", new DbInteger(), false /*not null*/, false /*autoincrement*/);
124 // Column helix_id("helix_id", new DbInteger(), false /*not null*/, true /*autoincrement*/);
125  Column flipped("flipped", new DbInteger());
126  Column sasa("sasa", new DbReal());
127 
128  Column residue_begin("residue_begin", new DbInteger());
129  Column residue_end("residue_end", new DbInteger());
130 
131  utility::vector1<Column> bundle_helix_pkey_cols;
132  bundle_helix_pkey_cols.push_back(struct_id);
133  bundle_helix_pkey_cols.push_back(helix_id);
134 
135  utility::vector1<std::string> fkey_res_reference_cols;
136  fkey_res_reference_cols.push_back("struct_id");
137  fkey_res_reference_cols.push_back("resNum");
138 
139  utility::vector1<Column> fkey_cols_begin;
140  fkey_cols_begin.push_back(struct_id);
141  fkey_cols_begin.push_back(residue_begin);
142 
143  utility::vector1<Column> fkey_cols_end;
144  fkey_cols_end.push_back(struct_id);
145  fkey_cols_end.push_back(residue_end);
146 
147  utility::vector1<std::string> fkey_bundle_reference_cols;
148  fkey_bundle_reference_cols.push_back("struct_id");
149  fkey_bundle_reference_cols.push_back("bundle_id");
150 
151  utility::vector1<Column> fkey_bundle_cols;
152  fkey_bundle_cols.push_back(struct_id);
153  fkey_bundle_cols.push_back(bundle_id);
154 
155 
156  Schema bundle_helices("bundle_helices", bundle_helix_pkey_cols);
157  bundle_helices.add_foreign_key(ForeignKey(fkey_bundle_cols, "helix_bundles", fkey_bundle_reference_cols, true /*defer*/));
158  bundle_helices.add_foreign_key(ForeignKey(fkey_cols_begin, "residues", fkey_res_reference_cols, true /*defer*/));
159  bundle_helices.add_foreign_key(ForeignKey(fkey_cols_end, "residues", fkey_res_reference_cols, true /*defer*/));
160  bundle_helices.add_column(struct_id);
161  bundle_helices.add_column(flipped);
162  bundle_helices.add_column(sasa);
163 
164  bundle_helices.write(db_session);
165 
166  /******helix_pairs******/
167  Column pair_id("pair_id", new DbInteger(), false /*not null*/, false /*autoincrement*/);
168 // Column pair_id("pair_id", new DbInteger(), false /*not null*/, true /*autoincrement*/);
169  Column helix_id_1("helix_id_1", new DbInteger(), false, false);
170  Column helix_id_2("helix_id_2", new DbInteger(), false, false);
171  Column shared_fa_atr("shared_fa_atr", new DbReal(), false, false);
172  Column interacting_fraction("interacting_fraction", new DbReal(), false, false);
173  Column crossing_angle("crossing_angle", new DbReal(), false, false);
174  Column end_1_distance("end_1_distance", new DbReal(), false, false);
175  Column end_2_distance("end_2_distance", new DbReal(), false, false);
176 
177  utility::vector1<Column> helix_pair_pkey_cols;
178  helix_pair_pkey_cols.push_back(struct_id);
179  helix_pair_pkey_cols.push_back(pair_id);
180 
181  utility::vector1<std::string> fkey_ref_helix;
182  fkey_ref_helix.push_back("struct_id");
183  fkey_ref_helix.push_back("helix_id");
184 
185  utility::vector1<Column> fkey_cols_helix_1;
186  fkey_cols_helix_1.push_back(struct_id);
187  fkey_cols_helix_1.push_back(helix_id_1);
188 
189  utility::vector1<Column> fkey_cols_helix_2;
190  fkey_cols_helix_2.push_back(struct_id);
191  fkey_cols_helix_2.push_back(helix_id_2);
192 
193  Schema helix_pairs("helix_pairs", helix_pair_pkey_cols);
194  helix_pairs.add_column(helix_id_1);
195  helix_pairs.add_column(helix_id_2);
196  helix_pairs.add_column(shared_fa_atr);
197  helix_pairs.add_column(interacting_fraction);
198  helix_pairs.add_column(crossing_angle);
199  helix_pairs.add_column(end_1_distance);
200  helix_pairs.add_column(end_2_distance);
201  helix_pairs.add_foreign_key(ForeignKey(struct_id, "structures", "struct_id", true /*defer*/));
202  helix_pairs.add_foreign_key(ForeignKey(fkey_bundle_cols, "helix_bundles", fkey_bundle_reference_cols, true /*defer*/));
203  helix_pairs.add_foreign_key(ForeignKey(fkey_cols_helix_1, "bundle_helices", fkey_ref_helix, true /*defer*/));
204  helix_pairs.add_foreign_key(ForeignKey(fkey_cols_helix_2, "bundle_helices", fkey_ref_helix, true /*defer*/));
205 
206  helix_pairs.write(db_session);
207 }
208 
209 //Select all helical segments reported by the ResidueSecondaryStructureFeatures and save them in a vector
210 utility::vector1<HelicalFragmentOP> HelixBundleFeatures::get_helix_fragments(boost::uuids::uuid struct_id, sessionOP db_session)
211 {
212  std::string select_string =
213  "SELECT\n"
214  " residue_begin,\n"
215  " residue_end\n"
216  "FROM\n"
217  " secondary_structure_segments\n"
218  "WHERE\n"
219  " struct_id = ?\n AND "
220  " dssp = 'H'\n"
221  "ORDER BY residue_begin;";
222 
223  statement select_statement(basic::database::safely_prepare_statement(select_string,db_session));
224  select_statement.bind(1,struct_id);
225  result res(basic::database::safely_read_from_database(select_statement));
226 
228 
229  core::Size prev_residue_begin;
230  core::Size prev_residue_end;
231  while(res.next())
232  {
233  Size residue_begin, residue_end;
234  res >> residue_begin >> residue_end;
235 
236  if(residue_begin - prev_residue_end == 2 && all_helices.size() > 0)
237  {
238  all_helices.pop_back();
239  all_helices.push_back(new HelicalFragment(prev_residue_begin, residue_end));
240  TR << "combining helix segments: " << prev_residue_begin << "-" << prev_residue_end
241  << " and " << residue_begin << "-" << residue_end << std::endl;
242  }
243  else
244  {
245  all_helices.push_back(new HelicalFragment(residue_begin, residue_end));
246  }
247  prev_residue_begin=residue_begin;
248  prev_residue_end=residue_end;
249  }
250 
251  TR << "number of uninterrupted helix_segments: " << all_helices.size() << std::endl;
252  utility::vector1<HelicalFragmentOP> all_helix_fragments;
253  for(core::Size i=1; i<=all_helices.size(); ++i)
254  {
255  HelicalFragmentOP cur_helix=all_helices[i];
256 
257  if(cur_helix->end() >= helix_size_)
258  {
259  for(core::Size start_res=cur_helix->start();
260  start_res<=cur_helix->end()-helix_size_+1;
261  ++start_res)
262  {
263 
264  core::Size end_res = start_res+helix_size_-1;
265 
266  HelicalFragmentOP frag_1 = new HelicalFragment(start_res, end_res);//normal direction
267  HelicalFragmentOP frag_2 = new HelicalFragment(end_res, start_res);//reversed
268 
269  all_helix_fragments.push_back(frag_1);
270  all_helix_fragments.push_back(frag_2);
271  }
272  }
273  }
274 
275  return all_helix_fragments;
276 }
277 
280  core::pose::Pose const & pose,
282 ){
283  core::Real dist_sq_cutoff = pow(helix_cap_dist_cutoff_, 2);
284 
285  utility::vector1<FragmentPair> helix_pairs;
286  for(core::Size i=1; i<=helix_fragments.size(); ++i)
287  {
288  for(core::Size j=i+1; j<=helix_fragments.size(); ++j)
289  {
290  //ensure pairs don't contain overlapping fragments
291  if((helix_fragments[i]->seq_start() >= helix_fragments[j]->seq_start() &&
292  helix_fragments[i]->seq_start() <= helix_fragments[j]->seq_end()) ||
293 
294  (helix_fragments[i]->seq_end() >= helix_fragments[j]->seq_start() &&
295  helix_fragments[i]->seq_end() <= helix_fragments[j]->seq_end()))
296  {
297  continue;
298  }
299 
300  FragmentPair helix_pair(helix_fragments[i], helix_fragments[j]);
301 
302  //check to see if com's of the two fragments are within cutoff
303 // core::Real com_dist_sq = helix_pair.fragment_1->com().distance_squared(
304 // helix_pair.fragment_2->com());
305 // if(com_dist_sq > dist_sq_cutoff)
306 // {
307 // continue;
308 // }
309 // helix_pair.com_distance = std::sqrt(com_dist_sq);
310 
311  core::Real end_1_dist_sq = pose.residue(helix_pair.fragment_1->start()).atom("CA").xyz().distance_squared(
312  pose.residue(helix_pair.fragment_2->start()).atom("CA").xyz());
313 
314  core::Real end_2_dist_sq = pose.residue(helix_pair.fragment_1->end()).atom("CA").xyz().distance_squared(
315  pose.residue(helix_pair.fragment_2->end()).atom("CA").xyz());
316 
317  if(end_1_dist_sq > dist_sq_cutoff || end_2_dist_sq > dist_sq_cutoff)
318  {
319  continue;
320  }
321  helix_pair.end_1_distance = std::sqrt(end_1_dist_sq);
322  helix_pair.end_2_distance = std::sqrt(end_2_dist_sq);
323 
324  TR << "end 1 distance (" << helix_pair.fragment_1->start() << "," << helix_pair.fragment_2->start()
325  << "): " << helix_pair.end_1_distance << std::endl;
326 
327  TR << "end 2 distance (" << helix_pair.fragment_1->end() << "," << helix_pair.fragment_2->end()
328  << "): " << helix_pair.end_2_distance << std::endl;
329 
330  //check to see per-residue fa_attr and percentage of interacting residues are within cutoff
331  calc_fa_energy(pose, helix_pair);
332  if( helix_pair.fa_attr > -(min_per_residue_fa_attr_) ||
334  ){
335  continue;
336  }
337 
338  //ensure crossing angle is within cutoff
339  calc_crossing_angles(pose, helix_pair);
340 // if((helix_pair.crossing_angle < 0 && helix_pair.crossing_angle > (-180+max_degrees_off_parallel_) ) ||
341 // helix_pair.crossing_angle > max_degrees_off_parallel_)
342 // {
343 // continue;
344 // }
345 
346  helix_pairs.push_back(helix_pair);
347  }
348  }
349  return helix_pairs;
350 }
351 
352 ///@brief calculate the shared fa_attr for each pair of helices
353 /// in the bundle
354 void
356  core::pose::Pose const & pose,
357  FragmentPair & helix_pair
358 ){
359  HelicalFragmentOP frag_1=helix_pair.fragment_1;
360  HelicalFragmentOP frag_2=helix_pair.fragment_2;
361 
362  core::Real helix_pair_fa_attr=0;
363  std::set<core::Size> interacting_residues; //residues that make favorable inter-fragment contacts (negative fa_attr)
364  for(core::Size ii=frag_1->seq_start(); ii<=frag_1->seq_end(); ++ii)
365  {
366  //iterate through interaction graph of current residue and add any fa_attr
367  //between this residue and any of the residues from fragment j
368  core::scoring::EnergyGraph const & eg =
369  pose.energies().energy_graph();
371  iter = eg.get_node(ii)->const_upper_edge_list_begin(),
372  iter_end = eg.get_node(ii)->const_upper_edge_list_end();
373  iter != iter_end; ++iter )
374  {
375  core::Size jj = (*iter)->get_other_ind(ii);
376  if(jj >= frag_2->seq_start() && jj <= frag_2->seq_end())
377  {
378  const core::scoring::EnergyEdge* ee =
379  dynamic_cast< const core::scoring::EnergyEdge* > (*iter);
380  helix_pair_fa_attr += (*ee)[core::scoring::fa_atr];
381  if((*ee)[core::scoring::fa_atr] < 0)
382  {
383  interacting_residues.insert(ii);
384  interacting_residues.insert(jj);
385  }
386  }
387  }
388  }
389 
390  //normalize fragment pair fa attr by number of residues and check for per-residue threshold
391  helix_pair.fa_fraction = interacting_residues.size()/(helix_size_*2.0);
392  helix_pair.fa_attr = helix_pair_fa_attr/(helix_size_*2.0);
393 
394 // TR << "residue-normalized FA attractive between: " << (*frag_1)
395 // << " " << (*frag_2) << ": " << per_residue_fa_attr << std::endl;
396 //
397 // TR << "interacting set fraction: " << (*frag_1)
398 // << " " << (*frag_2) << ": " << interacting_set_fraction << std::endl;
399 }
400 
401 
402 ///@brief calculate the crossing angles of the helix fragment in the bundle set
403 void
405  core::pose::Pose const & pose,
406  FragmentPair & helix_pair
407 ){
408  HelicalFragmentOP frag_1=helix_pair.fragment_1;
409  HelicalFragmentOP frag_2=helix_pair.fragment_2;
410 
411  //populate coms and principal components
412  calc_pc_and_com(pose, frag_1);
413  calc_pc_and_com(pose, frag_2);
414 
415  //Find the closest residues between fragments i and j
416 // std::pair<core::Size,core::Size> closest_residues;
417 // core::Real min_dist_sq=1000000;
418 // for(core::Size ii=frag_1->seq_start(); ii<=frag_1->seq_end(); ++ii)
419 // {
420 // for(core::Size jj=frag_2->seq_start(); jj<=frag_2->seq_end(); ++jj)
421 // {
422 // core::Real dist_sq = pose.residue(ii).atom("CA").xyz().distance_squared(
423 // pose.residue(jj).atom("CA").xyz());
424 // if(dist_sq < min_dist_sq)
425 // {
426 // min_dist_sq=dist_sq;
427 // closest_residues=std::make_pair(ii,jj);
428 // }
429 // }
430 // }
431 
432 // numeric::xyzVector<core::Real> p0 =
433 // closest_point_on_line(frag_1->com(), frag_1->principal_component(),
434 // pose.residue(frag_1->seq_start()).atom("N").xyz());
435 //
436 // numeric::xyzVector<core::Real> p1 =
437 // closest_point_on_line(frag_1->com(), frag_1->principal_component(),
438 // pose.residue(closest_residues.first).atom("CA").xyz());
439 //
440 // numeric::xyzVector<core::Real> p2 =
441 // closest_point_on_line(frag_2->com(), frag_2->principal_component(),
442 // pose.residue(closest_residues.second).atom("CA").xyz());
443 //
444 // numeric::xyzVector<core::Real> p3 =
445 // closest_point_on_line(frag_2->com(), frag_2->principal_component(),
446 // pose.residue(frag_2->seq_start()).atom("N").xyz());
447 
449  closest_point_on_line(frag_1->com(), frag_1->principal_component(),
450  pose.residue(frag_1->start()).atom("N").xyz());
451 
452  TR << "P0: " << p0.x() << "," << p0.y() << "," << p0.z() << endl;
453 
455  closest_point_on_line(frag_1->com(), frag_1->principal_component(),
456  pose.residue(frag_1->end()).atom("CA").xyz());
457 
458  TR << "P1: " << p1.x() << "," << p1.y() << "," << p1.z() << endl;
459 
461  closest_point_on_line(frag_2->com(), frag_2->principal_component(),
462  pose.residue(frag_2->end()).atom("CA").xyz());
463 
464  TR << "P2: " << p2.x() << "," << p2.y() << "," << p2.z() << endl;
465 
467  closest_point_on_line(frag_2->com(), frag_2->principal_component(),
468  pose.residue(frag_2->start()).atom("N").xyz());
469 
470  TR << "P3: " << p3.x() << "," << p3.y() << "," << p3.z() << endl;
471 
472  helix_pair.crossing_angle =
473  numeric::dihedral_degrees(p0,p1,p2,p3);
474 
475 // TR << "crossing angle between: " << (*frag_1)
476 // << " " << (*frag_2) << ": " << crossing_angle << std::endl;
477 }
478 
479 
480 ///@brief create a bundle-pose from the combination of fragments
481 /// and record the "interface" SASA for each helix against the
482 /// rest of the bundle
483 void
485  core::pose::Pose const & /*pose*/,
486  std::set<HelicalFragmentOP> const & /*frag_set*/
487 ){
488 // utility::vector1<core::Size> positions;
489 // utility::vector1< std::pair<core::Size, core::Size> > helix_ends;
490 // core::Size prev_end=0;
491 // for(core::Size i=1; i<=frag_set.size(); ++i)
492 // {
493 // //Record residues from the starting pose for this bundle
494 // for(core::Size cur_res=frag_set[i]->seq_start();
495 // cur_res<=frag_set[i]->seq_end();
496 // ++cur_res)
497 // {
498 // positions.push_back(cur_res);
499 // }
500 //
501 // //Get the ends of each helix in the new bundle
502 // core::Size new_start=prev_end+1;
503 // core::Size new_end=new_start+helix_size_-1;
504 // helix_ends.push_back(std::make_pair(new_start, new_end));
505 // prev_end=new_end;
506 // }
507 //
508 // assert(helix_ends.size()==frag_set.size());
509 //
510 // core::pose::Pose bundle_pose;
511 // for(core::Size j=1; j<=helix_ends.size(); ++j)
512 // {
513 // kinematics::FoldTree ft;
514 // core::Size jump_counter=1;
515 // if(j!=1)
516 // {
517 // //peptide edge from 1->residue before helix to be separated
518 // ft.add_edge(1, helix_ends[j-1].second, kinematics::Edge::PEPTIDE);
519 //
520 // //jump from 1 to the edge to be separated
521 // ft.add_edge(1, helix_ends[j].first, jump_counter);
522 // jump_counter++;
523 // }
524 //
525 // //peptide edge for the helix to be separated
526 // ft.add_edge(helix_ends[j].first, helix_ends[j].second, kinematics::Edge::PEPTIDE);
527 //
528 // //add jump and peptide edge for the remainder of the bundle if the helix to be separated isn't the last one
529 // if(j!=helix_ends.size())
530 // {
531 // ft.add_edge(1, helix_ends[j+1].first, jump_counter);
532 // ft.add_edge(helix_ends[j+1].first, helix_ends[helix_ends.size()].second, kinematics::Edge::PEPTIDE);
533 // }
534 //
535 // ft.reorder(1);
536 // TR << "Fold tree " << j << ": " << ft << std::endl;
537 //
538 // //Only make the pose the first time, otherwise just change the fold tree
539 // if(j==1)
540 // {
541 // core::pose::create_subpose(pose, positions, ft, bundle_pose);
542 // }
543 // else
544 // {
545 // bundle_pose.fold_tree(ft);
546 // }
547 //
548 // sasa_filter_.jump(1);
549 // core::Real dSasa = sasa_filter_.compute(bundle_pose);
550 // frag_set[j]->sasa(dSasa);
551 // }
552 }
553 
554 ///@brief ensure that the set of fragments does not contain
555 ///overlapping residues.
556 bool
558  std::set<HelicalFragmentOP> const & frag_set
559 ){
560 // if(frag_set[1]->reversed())
561 // {
562 // return false;
563 // }
564 
565  for(std::set<HelicalFragmentOP>::const_iterator it_i=frag_set.begin();
566  it_i != frag_set.end(); ++it_i)
567  {
568  for(std::set<HelicalFragmentOP>::const_iterator it_j=it_i;
569  ++it_j != frag_set.end(); /**/)
570  {
571  if(((*it_i)->seq_start() >= (*it_j)->seq_start() &&
572  (*it_i)->seq_start() <= (*it_j)->seq_end()) ||
573 
574  ((*it_i)->seq_end() >= (*it_j)->seq_start() &&
575  (*it_i)->seq_end() <= (*it_j)->seq_end()))
576  {
577  return false;
578  }
579  }
580  }
581  return true;
582 }
583 
584 
585 bool
587  core::pose::Pose const & pose,
588  utility::vector1<HelicalFragmentOP> const & frag_set
589 ){
590  core::Real dist_sq_cutoff = pow(helix_cap_dist_cutoff_, 2);
591  for(core::Size i=1; i<=frag_set.size(); ++i){
592 
593  for(core::Size j=i+1; j<=frag_set.size(); ++j){
594 
595  core::Real helix_start_dist_sq = pose.residue(frag_set[i]->start()).atom("CA").xyz().distance_squared(
596  pose.residue(frag_set[j]->start()).atom("CA").xyz());
597 
598  core::Real helix_end_dist_sq = pose.residue(frag_set[i]->end()).atom("CA").xyz().distance_squared(
599  pose.residue(frag_set[j]->end()).atom("CA").xyz());
600 
601  if(helix_start_dist_sq > dist_sq_cutoff || helix_end_dist_sq > dist_sq_cutoff){
602  return false;
603  }
604  }
605  }
606 
607  for(core::Size i=1; i<=frag_set.size(); ++i){
608 
609  for(core::Size j=i+1; j<=frag_set.size(); ++j){
610 
611  core::Real helix_start_dist_sq = pose.residue(frag_set[i]->start()).atom("CA").xyz().distance_squared(
612  pose.residue(frag_set[j]->start()).atom("CA").xyz());
613 
614  core::Real helix_end_dist_sq = pose.residue(frag_set[i]->end()).atom("CA").xyz().distance_squared(
615  pose.residue(frag_set[j]->end()).atom("CA").xyz());
616 
617  if(helix_start_dist_sq > dist_sq_cutoff || helix_end_dist_sq > dist_sq_cutoff){
618  return false;
619  }
620  }
621  }
622 
623  return true;
624 }
625 
626 void
628  core::pose::Pose const & pose,
629  HelicalFragmentOP fragment
630 ){
632  for(core::Size cur_res=fragment->seq_start(); cur_res<=fragment->seq_end(); ++cur_res)
633  {
634  fragment_coords.push_back(pose.residue(cur_res).atom("N").xyz());
635  fragment_coords.push_back(pose.residue(cur_res).atom("CA").xyz());
636  fragment_coords.push_back(pose.residue(cur_res).atom("C").xyz());
637  fragment_coords.push_back(pose.residue(cur_res).atom("O").xyz());
638  }
639 
641  fragment->com(com);
642  fragment->principal_component(numeric::first_principal_component(fragment_coords) + com);
643 }
644 
645 void
647  utility::tag::TagPtr const tag,
648  protocols::moves::DataMap & /*data*/,
649  protocols::filters::Filters_map const & /*filters*/,
650  protocols::moves::Movers_map const & /*movers*/,
651  core::pose::Pose const & /*pose*/
652 ){
653  runtime_assert(tag->getOption<string>("name") == type_name());
654 
655  bundle_size_ = tag->getOption<core::Size>("bundle_size", 3);
656  helix_size_ = tag->getOption<core::Size>("helix_size", 12);
657  helix_cap_dist_cutoff_ = tag->getOption<core::Real>("helix_cap_dist_cutoff", 18);
658 
659  min_per_residue_fa_attr_ = tag->getOption<core::Real>("min_per_residue_fa_attr", 0.2);
660  min_interacting_set_fraction_ = tag->getOption<core::Real>("min_interacting_set_fraction", 0.4);
661  max_degrees_off_parallel_ = tag->getOption<core::Real>("max_degrees_off_parallel", 40);
662 
663 }
664 
667  core::pose::Pose const & pose,
668  utility::vector1<bool> const &,
669  boost::uuids::uuid struct_id,
670  utility::sql_database::sessionOP db_session
671 ){
672  utility::vector1<HelicalFragmentOP> all_helix_fragments = get_helix_fragments(struct_id, db_session);
673  if(all_helix_fragments.size()<bundle_size_)
674  return 0;
675  TR << "Total helical fragments of size " << helix_size_ << ": " << all_helix_fragments.size() << std::endl;
676 
677  //Non-const pose to score
678  core::pose::Pose pose_copy(pose);
679  scorefxn_->score(pose_copy);
680 
681  utility::vector1<FragmentPair> helix_pairs = get_helix_pairs(pose_copy, all_helix_fragments);
682  if(helix_pairs.size()==0)
683  return 0;
684 
685  TR << "Total valid fragment pairs: " << helix_pairs.size() << std::endl;
686 
687 
688  //Insert statements
689  string bundle_insert =
690 // "INSERT INTO helix_bundles (struct_id, bundle_size, helix_size) VALUES (?, ?, ?);";
691  "INSERT INTO helix_bundles (bundle_id, struct_id, bundle_size, helix_size) VALUES (?, ?, ?, ?);";
692  statement bundle_insert_stmt(basic::database::safely_prepare_statement(bundle_insert,db_session));
693 
694  string helix_insert =
695 // "INSERT INTO bundle_helices (bundle_id, struct_id, residue_begin, residue_end, flipped, sasa) VALUES (?,?,?,?,?,?);";
696  "INSERT INTO bundle_helices (helix_id, bundle_id, struct_id, residue_begin, residue_end, flipped, sasa) VALUES (?,?,?,?,?,?,?);";
697  statement helix_insert_stmt(basic::database::safely_prepare_statement(helix_insert,db_session));
698 
699  string pair_insert =
700 // "INSERT INTO helix_pairs (struct_id, bundle_id, helix_id_1, helix_id_2, shared_fa_atr, interacting_fraction, crossing_angle, end_1_distance, end_2_distance)\n"
701 // "VALUES (?,?,?,?,?,?,?,?,?)";
702  "INSERT INTO helix_pairs (pair_id, struct_id, bundle_id, helix_id_1, helix_id_2, shared_fa_atr, interacting_fraction, crossing_angle, end_1_distance, end_2_distance)\n"
703  "VALUES (?,?,?,?,?,?,?,?,?,?)";
704  statement pair_insert_stmt(basic::database::safely_prepare_statement(pair_insert, db_session));
705 
706  //number of pairs we need is bundle size choose 2
707  core::Size num_factorial=1;
708  core::Size denom_factorial=1;
709  for(core::Size temp=bundle_size_; temp > 1; temp--)
710  {
711  num_factorial=num_factorial*temp;
712  if(temp <= bundle_size_-2)
713  {
714  denom_factorial=denom_factorial*temp;
715  }
716  }
717  core::Size n_dims = num_factorial/(2*denom_factorial);
718 
719  utility::vector1<core::Size> dim_sizes(n_dims, helix_pairs.size());
720  core::Size bundle_counter=0;
721  core::Size helix_counter=0;
722  core::Size pair_counter=0;
723  for ( utility::LexicographicalIterator lex( dim_sizes ); ! lex.at_end(); ++lex )
724  {
725  //Only evaluate when lex[i] < lex[i+1] to avoid double counting
726  for(core::Size i=2; i<=n_dims; ++i)
727  {
728  while(lex[i-1] >= lex[i])
729  {
730  if(lex.at_end())
731  {
732  return 0; //we are done
733  }
734  lex.continue_at_dimension(i);
735  }
736  }
737 
738  utility::vector1<FragmentPair> cur_frag_pairs;
739  std::set<HelicalFragmentOP> cur_frag_set;
740  for(core::Size i=1; i<=bundle_size_; ++i)
741  {
742  FragmentPair cur_frag_pair = helix_pairs [ lex[i] ];
743  cur_frag_pairs.push_back(cur_frag_pair);
744  cur_frag_set.insert(cur_frag_pair.fragment_1);
745  cur_frag_set.insert(cur_frag_pair.fragment_2);
746  }
747 
748  if(valid_frag_set(cur_frag_set))
749  {
750  ++bundle_counter;
751  //record the dSasa for each helix
752 // record_helix_sasas(pose, cur_frag_set);
753 
754  bundle_insert_stmt.bind(1,bundle_counter);
755  bundle_insert_stmt.bind(2,struct_id);
756  bundle_insert_stmt.bind(3,bundle_size_);
757  bundle_insert_stmt.bind(4,helix_size_);
758 
759 // bundle_insert_stmt.bind(1,struct_id);
760 // bundle_insert_stmt.bind(2,bundle_size_);
761 // bundle_insert_stmt.bind(3,helix_size_);
762  basic::database::safely_write_to_database(bundle_insert_stmt);
763 
764  //core::Size bundle_id(bundle_insert_stmt.sequence_last("helix_bundles_bundle_id_seq"));
765 
766  std::map<HelicalFragmentOP, core::Size> helix_ids;
767  for(std::set<HelicalFragmentOP>::const_iterator it=cur_frag_set.begin(); it != cur_frag_set.end();
768  ++it)
769  {
770  ++helix_counter;
771  helix_insert_stmt.bind(1,helix_counter);
772  helix_insert_stmt.bind(2,bundle_counter);
773  helix_insert_stmt.bind(3,struct_id);
774  helix_insert_stmt.bind(4,(*it)->seq_start());
775  helix_insert_stmt.bind(5,(*it)->seq_end());
776  helix_insert_stmt.bind(6,(*it)->reversed());
777  helix_insert_stmt.bind(7,(*it)->sasa());
778 
779 // helix_insert_stmt.bind(1,bundle_id);
780 // helix_insert_stmt.bind(2,struct_id);
781 // helix_insert_stmt.bind(3,(*it)->seq_start());
782 // helix_insert_stmt.bind(4,(*it)->seq_end());
783 // helix_insert_stmt.bind(5,(*it)->reversed());
784 // helix_insert_stmt.bind(6,(*it)->sasa());
785  basic::database::safely_write_to_database(helix_insert_stmt);
786 
787  core::Size helix_id(bundle_insert_stmt.sequence_last("bundle_helices_helix_id_seq"));
788  helix_ids.insert(std::make_pair(*it, helix_id));
789  }
790 
791  for(utility::vector1<FragmentPair>::const_iterator it=cur_frag_pairs.begin(); it!=cur_frag_pairs.end(); ++it)
792  {
793  ++pair_counter;
794 
795  core::Size frag_1_id = helix_ids[it->fragment_1];
796  core::Size frag_2_id = helix_ids[it->fragment_2];
797 
798  pair_insert_stmt.bind(1,pair_counter);
799  pair_insert_stmt.bind(2,struct_id);
800  pair_insert_stmt.bind(3,bundle_counter);
801  pair_insert_stmt.bind(4,frag_1_id);
802  pair_insert_stmt.bind(5,frag_2_id);
803  pair_insert_stmt.bind(6,it->fa_attr);
804  pair_insert_stmt.bind(7,it->fa_fraction);
805  pair_insert_stmt.bind(8,it->crossing_angle);
806  pair_insert_stmt.bind(9,it->end_1_distance);
807  pair_insert_stmt.bind(10,it->end_2_distance);
808 
809 // pair_insert_stmt.bind(1,struct_id);
810 // pair_insert_stmt.bind(2,bundle_id);
811 // pair_insert_stmt.bind(3,frag_1_id);
812 // pair_insert_stmt.bind(4,frag_2_id);
813 // pair_insert_stmt.bind(5,it->fa_attr);
814 // pair_insert_stmt.bind(6,it->fa_fraction);
815 // pair_insert_stmt.bind(7,it->crossing_angle);
816 // pair_insert_stmt.bind(8,it->end_1_distance);
817 // pair_insert_stmt.bind(9,it->end_2_distance);
818  basic::database::safely_write_to_database(pair_insert_stmt);
819  }
820  }
821  }
822  TR << "Found " << bundle_counter << "total bundles";
823  return 0;
824 }
825 
826 } //namespace helixAssembly
827 } //namespace features
828 } //namespace protocols