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 /// @author Oliver Lange
11 /// @author Mike Tyka
12 
13 // Unit Headers
14 #include <protocols/loops/util.hh>
15 
16 // Package Headers
17 #include <protocols/loops/Loop.hh>
18 #include <protocols/loops/Loops.hh>
19 
20 // Project Headers
21 #include <core/pose/Pose.hh>
22 #include <core/pose/PDBInfo.hh>
23 #include <core/pose/util.tmpl.hh>
26 
28 #include <protocols/loops/loops_main.hh> //for getting ss from dssp
29 
31 // AUTO-REMOVED #include <core/scoring/constraints/util.hh>
34 // AUTO-REMOVED #include <core/conformation/Conformation.hh>
38 // AUTO-REMOVED #include <core/chemical/util.hh>
39 
40 // AUTO-REMOVED #include <core/chemical/ChemicalManager.hh>
42 
43 #include <core/conformation/util.hh> //idealize
44 #include <core/fragment/Frame.hh>
46 #include <core/fragment/FragSet.hh>
47 #ifdef WIN32
48 #include <core/fragment/FragID.hh>
49 #endif
50 #include <core/pose/util.hh>
51 #include <core/id/AtomID.hh>
52 #include <core/scoring/rms_util.hh>
53 
54 #include <basic/options/option.hh>
55 #include <basic/options/keys/loops.OptionKeys.gen.hh>
56 #include <basic/options/keys/evaluation.OptionKeys.gen.hh>
57 
58 // ObjexxFCL Headers
59 #include <ObjexxFCL/format.hh>
60 #include <ObjexxFCL/string.functions.hh>
61 
62 // Utility headers
63 #include <basic/Tracer.hh>
64 
65 //numeric headers
66 
67 //// C++ headers
68 #include <list>
69 
70 //Auto Headers
71 #include <utility/vector1.hh>
72 #define foreach BOOST_FOREACH
73 
74 //Auto Headers
75 #include <core/id/AtomID_Map.hh>
78 #include <core/pose/selection.hh>
79 #include <utility/string_util.hh>
80 #include <utility/vector1.hh>
81 #include <boost/foreach.hpp>
82 
83 //Auto using namespaces
84 namespace ObjexxFCL { namespace fmt { } } using namespace ObjexxFCL::fmt; // AUTO USING NS
85 
86 static basic::Tracer TR("protocols.loops.util");
87 
88 namespace protocols {
89 namespace loops {
90 
91 /// TODO(someone) so bad!
92 using namespace core;
93 using namespace pose;
94 using namespace kinematics;
95 
96 // Numeric constants
97 static const double EXT_PHI = -150;
98 static const double EXT_PSI = +150;
99 static const double EXT_OMG = 180;
100 
101 void
102 fix_with_coord_cst( Loops const& rigid, core::pose::Pose& pose, bool bCstAllAtom, utility::vector1< core::Real > &weights ) {
103  bool const bReadWeights = ( weights.size() >= pose.total_residue() );
104  if ( !bReadWeights ) {
105  weights.resize( pose.total_residue() );
106  }
107 
108  for ( Loops::const_iterator it = rigid.begin(), eit = rigid.end();
109  it!=eit; ++it ) {
110  for ( Size pos = it->start(); pos <= it->stop(); ++pos ) {
111  Size const seq_dist( std::min( (int) pos - it->start(), (int) it->stop() - pos ) + 1);
112  Real coord_sdev;
113  if ( bReadWeights ) {
114  coord_sdev = weights[ pos ];
115  } else {
116  coord_sdev = ( 1.0/seq_dist ); //or something else?
117  weights[ pos ] = coord_sdev;
118  }
119  conformation::Residue const & rsd( pose.residue( pos ) );
120  if ( bCstAllAtom ) {
121  for ( Size ii = 1; ii<= rsd.natoms(); ++ii ) {
123  id::AtomID( ii, pos),
124  id::AtomID( 1, pos ) /*this is completely ignored! */,
125  rsd.xyz( ii ),
126  new scoring::constraints::HarmonicFunc( 0.0, coord_sdev )
127  ) );
128  }
129  } else {
130  id::AtomID atomID( pose.residue_type(pos).atom_index("CA"), pos );
132  atomID,
133  id::AtomID( 1, pos ) /*this is completely ignored! */,
134  rsd.xyz( atomID.atomno() ),
135  new scoring::constraints::HarmonicFunc( 0.0, coord_sdev )
136  ) );
137  }
138  }
139  }
140 }
141 
142 ///@brief get frags that are fully within the Loop --- shorten(=true/false) frags that are close to the end of loops.
144  loops::Loops const& loops,
145  core::fragment::FragSet& source,
146  core::fragment::FragSet& loop_frags,
147  Size shorten
148 ) {
149  using namespace core::fragment;
150  //assuming backbone degrees of freedom are wanted by the loops.
151  // Jumps are filtered out
152  kinematics::MoveMap movemap;
153  movemap.set_bb( false );
154  loops.switch_movemap( movemap, id::BB, true );
155 
156 
157  InsertMap insert_map;
158  InsertSize insert_size;
159  source.generate_insert_map( movemap, insert_map, insert_size);
160 
161  { //debug
162  Size const total_insert = insert_map.size();
163  TR.Trace << "size of insertmap: " << total_insert << " -- ";
164  for ( Size i = 1; i<=total_insert; i++ ) TR.Trace << " " << insert_map[ i ];
165  TR.Trace << "insert_size: \nRESIDUES: ";
166  for ( Size i = 1; i<=insert_map[ total_insert ]; i++ ) TR.Trace << " " << RJ(3,i);
167  TR.Trace <<"\nINSERT: ";
168  for ( Size i = 1; i<=insert_map[ total_insert ]; i++ ) TR.Trace << " " << RJ(3,insert_size[ i ]);
169  TR.Trace << std::endl;
170  }
171 
172  Size const total_insert = insert_map.size();
173 
174  for ( Size i = 1; i<=total_insert; i++ ) {
175  Size const pos ( insert_map[ i ] );
176  Size const size ( insert_size[ pos ] );
177  FrameList copy_frames;
178  source.frames( pos, copy_frames );
179  for ( FrameList::iterator it = copy_frames.begin(), eit = copy_frames.end();
180  it!=eit; ++it ) {
181  TR.Trace << "add frame at pos " << pos << " " << (*it)->length() << " insert_size " << size << std::endl;
182  if ( (*it)->length() == size ) loop_frags.add( *it );
183  else if ( shorten && size > shorten ) loop_frags.add( (*it)->generate_sub_frame( size ) );
184  }
185  }
186 } //select_loop_frags
187 
189  core::pose::Pose* pose) {
190  if (loops.empty())
191  return;
192 
194 }
195 
197  using core::Size;
201 
202  // if no loops, we want to have extended structure everywhere.
203  // it is a by-value parameter -- as intenden the change is kept local
204  if (loops.empty())
205  loops.add_loop(1, pose.total_residue(), 0);
206 
207  TR.Debug << "extend structure for " << loops << std::endl;
208 
209  Conformation& conf = pose.conformation();
210  for (Loops::const_iterator i = loops.begin(); i != loops.end(); ++i) {
211  const Loop& loop = *i;
212 
213  for (Size j = loop.start(); j <= loop.stop(); ++j) {
215  pose.set_phi(j, EXT_PHI);
216  pose.set_psi(j, EXT_PSI);
217  pose.set_omega(j, EXT_OMG);
218  }
219  }
220 }
221 
223  core::pose::Pose & pose,
224  loops::Loops loops,
225  const core::scoring::ScoreFunction & scorefxn,
226  core::pose::Pose & native_pose,
227  core::Size nloops
228 ) {
229 
230  using namespace core;
231 
232  Size nres = pose.total_residue();
233  utility::vector1< core::Size > all_loop_list;
234  for( Size i = 1; i < nres; i ++ ){
235  if( loops.is_loop_residue(i) ) all_loop_list.push_back( i );
236  }
237  scorefxn(pose);
238  setPoseExtraScores( pose, "ScoreCore", scorefxn.get_sub_score_exclude_res( pose, all_loop_list ) );
239 
240  Real score = scorefxn(pose);
241 
242  for( Size l = 1; l <= nloops; l++ ){
243  if( l > loops.size() ){
244  setPoseExtraScores( pose, "ScoreLoopI" + ObjexxFCL::right_string_of(l,3,'0'), 0 );
245  setPoseExtraScores( pose, "ScoreLoopC" + ObjexxFCL::right_string_of(l,3,'0'), 0 );
246  setPoseExtraScores( pose, "ScoreLoopL" + ObjexxFCL::right_string_of(l,3,'0'), 0 );
247  continue;
248  }
250  utility::vector1< core::Size > non_loop_list;
251  for( Size i = 1; i < nres; i ++ ){
252  if( ( i < loops[l].start() ) || ( i > loops[l].stop() ) ){
253  loop_list.push_back( i );
254  }else{
255  non_loop_list.push_back( i );
256  }
257  }
258 
259  Real loopscore = scorefxn.get_sub_score_exclude_res( pose, loop_list );
260  Real nonloopscore = scorefxn.get_sub_score_exclude_res( pose, non_loop_list );
261  setPoseExtraScores( pose, "ScoreLoopI" + ObjexxFCL::right_string_of(l,3,'0'), loopscore );
262  setPoseExtraScores( pose, "ScoreLoopC" + ObjexxFCL::right_string_of(l,3,'0'), score - loopscore - nonloopscore );
263  setPoseExtraScores( pose, "ScoreLoopL" + ObjexxFCL::right_string_of(l,3,'0'), score - nonloopscore );
264  }
265 
266  // Work out RMS values too
267 
268  core::pose::Pose native_pose_super = native_pose;
270  core::pose::initialize_atomid_map( atom_map, native_pose_super, core::id::BOGUS_ATOM_ID );
271  for ( core::Size ir=1; ir <= native_pose.total_residue(); ++ir ) {
272  runtime_assert( ir <= pose.total_residue() );
273  runtime_assert( ir <= native_pose_super.total_residue() );
274  if( ( !loops.is_loop_residue( ir ) ) && pose.residue(ir).is_protein() ) {
275  id::AtomID const id1( native_pose_super.residue(ir).atom_index("CA"), ir );
276  id::AtomID const id2( pose.residue(ir).atom_index("CA"), ir );
277  atom_map.set(id1, id2);
278  }
279  }
280  core::scoring::superimpose_pose( native_pose_super, pose, atom_map );
281 
282  int corelength;
283  setPoseExtraScores( pose, "corerms", native_loop_core_CA_rmsd( native_pose, pose, loops, corelength ) );
284 
285  for( Size l = 1; l <= nloops; l++ ){
286  if( l > loops.size() ){
287  setPoseExtraScores( pose, "RMSLoop" + ObjexxFCL::right_string_of(l,3,'0'), 0 );
288  continue;
289  }
290  Loops temploops;
291  temploops.add_loop( loops[l] );
292  setPoseExtraScores( pose, "RMSLoop" + ObjexxFCL::right_string_of(l,3,'0'),
293  loops::loop_rmsd( native_pose_super, pose, temploops, true ) );
294  }
295 }
296 
298  core::Real max_loop_frac,
299  core::Size min_length,
301 ) {
302 
303  using core::Size;
304 
305  Size start( 0 );
306  Size last( 0 );
307  Size max_gap( 2 );
308  loops::Loops ss_regions;
309  for ( Size pos = 1; pos <= ss.total_residue(); ++pos ) {
310  if ( ss.loop_fraction( pos ) <= max_loop_frac ) {
311  if ( !start ) {
312  start = pos;
313  last = pos - 1;
314  }
315  if ( last + max_gap < pos ) {
316  if ( last - start >= min_length ) {
317  ss_regions.add_loop( start, last );
318  }
319  start=0;
320  }
321  last = pos;
322  }
323  }
324  return ss_regions;
325 }
326 
328  using namespace basic::options;
329  using namespace basic::options::OptionKeys;
330  std::string const weights( option[ OptionKeys::loops::cen_weights ]() ),
331  patch( option[ OptionKeys::loops::cen_patch ]() );
332  return scoring::ScoreFunctionFactory::create_score_function(
333  weights, patch
334  );
335 }
336 
339 }
340 
341 
342 void add_coordinate_constraints_to_pose( core::pose::Pose & pose, const core::pose::Pose &constraint_target_pose, protocols::loops::Loops &exclude_regions ){
343  using namespace conformation;
344  using namespace core;
345  using namespace core::scoring;
346  using namespace core::scoring::constraints;
347  using namespace id;
348  using namespace scoring::constraints;
349 
350  core::Size nnonvrt_cst_target = constraint_target_pose.total_residue();
351  core::Size nnonvrt_pose = pose.total_residue();
352 
353  while ( pose.residue( nnonvrt_pose ).aa() == core::chemical::aa_vrt ) { nnonvrt_pose--; }
354  while ( constraint_target_pose.residue( nnonvrt_cst_target ).aa() == core::chemical::aa_vrt ) { nnonvrt_cst_target--; }
355 
356  protocols::loops::Loops coordconstraint_segments;
357  coordconstraint_segments = exclude_regions.invert( nnonvrt_cst_target );
358 
359  //TR.Info << coordconstraint_segments << std::endl;
360 
361  if ( nnonvrt_pose != nnonvrt_cst_target ) {
362  TR.Error << "ERROR coord constraint pose length mismatch with input pose: " << nnonvrt_cst_target << " vs. " << nnonvrt_pose << std::endl;
363  utility_exit();
364  }
365 
366  if ( pose.residue( pose.fold_tree().root() ).aa() != core::chemical::aa_vrt ) {
368  ( *ResidueFactory::create_residue( pose.residue(1).residue_type_set().name_map( "VRT" ) ),
369  pose.total_residue()/2 );
370  }
371 
372 
373  Size nres = pose.total_residue();
374  Real const coord_sdev( 0.5 );
375  for ( Size i = 1; i<= (Size)nres; ++i ) {
376  if ( i==(Size)pose.fold_tree().root() ) continue;
377  if( coordconstraint_segments.is_loop_residue( i ) ) {
378  Residue const & nat_i_rsd( pose.residue(i) );
379  for ( Size ii = 1; ii<= nat_i_rsd.last_backbone_atom(); ++ii ) {
381  AtomID(ii,i), AtomID(1,nres), nat_i_rsd.xyz( ii ),
382  new HarmonicFunc( 0.0, coord_sdev ) ) );
383  }
384  }
385  }
386 
387 }
388 
389 LoopsOP
390 loops_from_string( std::string const loop_str, core::pose::Pose const & pose ){
391  utility::vector1< std::string > const loops_vec( utility::string_split( loop_str, ',' ) );
392 
393 // each loop should have the format loop_start:loop_end:cut
394 // if cut is not set then it's taken to be 0. Residue numbering can follow the
395 // pdb numbering
396  LoopsOP loops_from_tag = new Loops();
397  foreach( std::string const residue_pair, loops_vec ){
398  utility::vector1< std::string > const residues( utility::string_split( residue_pair, ':' ) );
399  if(residues.size() != 2 && residues.size() != 3){
400  utility_exit_with_message(
401  "To specify a loops string it must have the format "
402  "\"loop_start:loop_end:cut[,loop_start:loop_end:cut...]\". "
403  "If the cut is not set, then it is taken to be zero. "
404  "The residue numbering can use the pdb numbering.");
405  }
406  core::Size const loop_start( core::pose::parse_resnum( residues[ 1 ], pose ) );
407  core::Size const loop_stop( core::pose::parse_resnum( residues[ 2 ], pose ) );
408  core::Size loop_cut( 0 );
409  if( residues.size() == 3 )
410  loop_cut = core::pose::parse_resnum( residues[ 3 ], pose );
411  runtime_assert( loop_start <= loop_stop );
412  runtime_assert( loop_start >= 1 );
413  runtime_assert( loop_stop <= pose.total_residue() );
414  loops_from_tag->add_loop( loop_start, loop_stop, loop_cut );
415  }
416  return( loops_from_tag );
417 }
418 
421  protocols::loops::Loops& scored_core )
422 {
423  using namespace core;
424  using namespace basic::options;
425  // Size const max_loop_size( 3 );
426  // Size const max_short_helix( 5 );
427  Size const max_loop_size( option[ OptionKeys::evaluation::score_sscore_maxloop ]() );
428  Size const max_short_helix( option[ OptionKeys::evaluation::score_sscore_short_helix ]() );
429 
430  //find residues that are part of a short helix -- less than or equal to 5 residues
431  utility::vector1< bool > short_helix( ss_def.total_residue(), false );
432 
433  //selection of loop definitions...
434  //these loops define regions that are scored. Add all loops that are 4 residues or longer.
435  //subsequently add also helices that have fewer than 6 residues if they terminated a long loop (>=4)
436  loops::Loops unscored_loops;
437 
438  for ( Size pos=1; pos <= ss_def.total_residue(); pos++ ) {
439 
440  //detect loops
441  if ( ss_def.loop_fraction( pos ) > 0.1 ) {
442  //go to end of loop
443  Size lpos = 1;
444  for ( ; ( lpos+pos <= ss_def.total_residue() ) && ( ss_def.loop_fraction( pos+lpos ) > 0.1); ++lpos ) {}
445  if ( lpos > max_loop_size ) { //this loop has 4 or more residues
446  unscored_loops.add_loop( pos, pos+lpos-1 );
447  }
448  pos+=lpos-1;
449  } // have found a loop
450 
451  // look for short helices and store in short_helix
452  if ( ss_def.helix_fraction( pos ) > 0.1 ) {
453  Size hpos = 1;
454  for ( ; ( hpos+pos <= ss_def.total_residue() ) && ( ss_def.helix_fraction( pos+hpos ) > 0.1); ++hpos ) {}
455  if ( hpos <= max_short_helix ) { //this helix has 5 or fewer residues
456  for ( Size ipos = 0; ipos < hpos; ++ipos ) {
457  short_helix[ pos+ipos] = true;
458  }
459  }
460  }
461 
462  //finished parsing secondary structure definition
463  }
464 
465  //elongate loops if they are terminated by a short helix
466  loops::Loops removed_short_helices( unscored_loops );
467  for ( loops::Loops::const_iterator it=unscored_loops.begin(); it != unscored_loops.end(); ++it ) {
468  Size npos( it->stop() + 1 );
469  while ( short_helix[ npos ] ) {
470  removed_short_helices.add_loop( npos-1, npos );
471  npos++;
472  }
473  }
474 
475  scored_core = removed_short_helices.invert( ss_def.total_residue() );
476 }
477 
478 /// @brief Extract secondary structure chunks from the secondary structure
480  char const extracted_ss_type) {
481  using namespace core;
483  Loops secondary_structure_chunks;
484 
485  bool ss_chunk_started = false;
486  Size chunk_start_seqpos(0);
487  Size chunk_end_seqpos(0);
488 
489  for (core::Size ires = 1; ires <= pose.total_residue(); ++ires) {
490  if (!ss_chunk_started) {
491  if (pose.secstruct(ires) == extracted_ss_type) {
492  ss_chunk_started = true;
493  chunk_start_seqpos = ires;
494  }
495  }
496  else {
497  if (pose.secstruct(ires) != extracted_ss_type) {
498  ss_chunk_started = false;
499  chunk_end_seqpos = ires - 1;
500  secondary_structure_chunks.add_loop( chunk_start_seqpos, chunk_end_seqpos);
501  }
502  else if ( ! pose.residue_type(ires).is_protein() ) {
503  ss_chunk_started = false;
504  chunk_end_seqpos = ires - 1;
505  secondary_structure_chunks.add_loop( chunk_start_seqpos, chunk_end_seqpos);
506  }
507  }
508  }
509 
510  // if the input sequence ends with the last ss chunk
511  if (ss_chunk_started) {
512  chunk_end_seqpos = pose.total_residue();
513  secondary_structure_chunks.add_loop( chunk_start_seqpos, chunk_end_seqpos);
514  }
515  return secondary_structure_chunks;
516 }
517 
521  Loops chunks;
522 
523  Loop new_loop;
524  new_loop.set_start(1);
525  new_loop.set_stop(pose.total_residue());
526  chunks.add_loop(new_loop);
527 
528  chunks = split_by_resSeq(pose, chunks);
529  return chunks;
530 }
531 
533  Loops chunks;
534  Loop new_loop;
535  bool chunk_started = false;
536 
537  for (core::Size ires = 1; ires < pose.total_residue(); ++ires) {
538  if (pose.residue_type(ires).is_protein()) continue;
539  if (!chunk_started) {
540  new_loop.set_start(ires);
541  chunk_started = true;
542  }
543 
544  if (!pose.residue_type(ires).is_polymer() || pose.residue_type(ires).is_upper_terminus()) {
545  chunk_started = false;
546  new_loop.set_stop(ires);
547  chunks.add_loop(new_loop);
548  }
549  }
550  return chunks;
551 }
552 
554  protocols::loops::Loops const & input_chunks) {
557  Loops chunks;
558 
559  Loops::LoopList::const_iterator eit, it;
560  for ( it = input_chunks.begin(), eit = input_chunks.end();
561  it != eit; ++it ) {
562 
563  Loop new_loop(*it);
564 
565  for (core::Size ires = it->start(); ires < it->stop(); ++ires) {
566  if ( pose.pdb_info()->number(ires+1) - pose.pdb_info()->number(ires) != 1 ||
567  pose.pdb_info()->chain(ires+1) != pose.pdb_info()->chain(ires) ) {
568  new_loop.set_stop(ires);
569  chunks.add_loop(new_loop);
570 
571  new_loop.set_start(ires+1);
572  new_loop.set_stop(it->stop());
573  }
574  }
575  chunks.add_loop( new_loop );
576  }
577  return chunks;
578 
579 }
580 
582  protocols::loops::Loops const & input_chunks,
583  core::Real const CA_CA_distance_cutoff) {
586  Loops continuous_chunks;
587 
588  Loops::LoopList::const_iterator eit, it;
589  for ( it = input_chunks.begin(), eit = input_chunks.end();
590  it != eit; ++it ) {
591 
592  Loop new_loop(*it);
593 
594  for (core::Size ires = it->start(); ires < it->stop(); ++ires) {
595  if( ! pose.residue(ires).is_protein() ) continue;
596 
597  if( pose.residue(ires+1).is_protein() ) {
598  if ( pose.residue(ires).xyz("CA").distance(pose.residue(ires+1).xyz("CA")) > CA_CA_distance_cutoff ) {
599  new_loop.set_stop(ires);
600  continuous_chunks.add_loop(new_loop);
601 
602  new_loop.set_start(ires+1);
603  new_loop.set_stop(it->stop());
604  }
605  }
606  else {
607  new_loop.set_stop(ires);
608  continuous_chunks.add_loop(new_loop);
609 
610  new_loop.set_start(ires+1);
611  new_loop.set_stop(it->stop());
612  }
613  }
614  continuous_chunks.add_loop( new_loop );
615  }
616  return continuous_chunks;
617 }
618 
619 // gap_size- if two chunks are seperated by a gap of this size (or less), consider them one big chunk
623  Loops secondary_structure_chunks;
624 
625  // join ss_chunks seperated by a small gap
626  core::Size i_chunk = 1;
627  while (i_chunk <= input_chunks.num_loop()) {
628  Loop new_loop(input_chunks[i_chunk]);
629  while(i_chunk < input_chunks.num_loop()) {
630  const core::Size gap_length = input_chunks[i_chunk+1].start() - input_chunks[i_chunk].stop() - 1;
631  if (gap_length <= gap_size) {
632  new_loop.set_stop(input_chunks[i_chunk+1].stop());
633  ++i_chunk;
634  }
635  else {
636  break;
637  }
638  }
639  secondary_structure_chunks.add_loop(new_loop);
640  ++i_chunk;
641  }
642  return secondary_structure_chunks;
643 }
644 
645 protocols::loops::Loops remove_short_chunks(protocols::loops::Loops const & input_chunks, core::Size minimum_length_of_chunk) {
647  Loops secondary_structure_chunks;
648 
649  //remove short ss_chunks
650  Loops::LoopList::const_iterator eit, it;
651  for ( it = input_chunks.begin(), eit = input_chunks.end();
652  it != eit; ++it ) {
653  if (it->size() >= minimum_length_of_chunk) {
654  secondary_structure_chunks.add_loop(*it);
655  }
656  }
657  return secondary_structure_chunks;
658 }
659 
660 // gap_size- if two chunks are seperated by a gap of this size (or less), consider them one big chunk
662  std::string extracted_ss_types,
663  core::Size gap_size,
664  core::Size minimum_length_of_chunk_helix,
665  core::Size minimum_length_of_chunk_strand,
666  core::Real CA_CA_distance_cutoff) {
668  Loops secondary_structure_chunks;
669 
670  for (core::Size i_ss = 0; i_ss < extracted_ss_types.size(); ++i_ss) {
671  char ss = extracted_ss_types[i_ss];
672  Loops secondary_structure_chunks_this_ss;
673 
674  // this order might be the best to deal with chain breaks in the middle of secondary structure chunk
675  secondary_structure_chunks_this_ss = extract_secondary_structure_chunks(pose, ss);
676  secondary_structure_chunks_this_ss = remove_small_gaps(secondary_structure_chunks_this_ss, gap_size);
677  secondary_structure_chunks_this_ss = split_by_resSeq(pose, secondary_structure_chunks_this_ss);
678  secondary_structure_chunks_this_ss = split_by_ca_ca_dist(pose, secondary_structure_chunks_this_ss, CA_CA_distance_cutoff);
679  if (ss == 'H') {
680  secondary_structure_chunks_this_ss = remove_short_chunks(secondary_structure_chunks_this_ss, minimum_length_of_chunk_helix);
681  }
682  if (ss == 'E') {
683  secondary_structure_chunks_this_ss = remove_short_chunks(secondary_structure_chunks_this_ss, minimum_length_of_chunk_strand);
684  }
685 
686  Loops::LoopList::const_iterator eit, it;
687  for ( it = secondary_structure_chunks_this_ss.begin(), eit = secondary_structure_chunks_this_ss.end();
688  it != eit; ++it ) {
689  secondary_structure_chunks.add_loop(*it);
690  }
691  }
692 
693  // insert non protein chunks
694  /*
695  Loops non_prot_chunks = find_non_protein_chunks(pose);
696  Loops::LoopList::const_iterator eit, it;
697  for ( it = non_prot_chunks.begin(), eit = non_prot_chunks.end();
698  it != eit; ++it ) {
699  secondary_structure_chunks.add_loop(*it);
700  }
701  */
702  return secondary_structure_chunks;
703 }
704 
706  core::Size const minimum_size,
707  core::Real const CA_CA_distance_cutoff) {
708 
710  Loops chunks;
711  chunks = split_by_resSeq(pose);
712  chunks = split_by_ca_ca_dist(pose, chunks, CA_CA_distance_cutoff);
713  chunks = remove_short_chunks(chunks, minimum_size);
714  return chunks;
715 }
716 
717 } // loops
718 } // protocols