Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Loops.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/loops/Loops.cc
11 /// @brief
12 /// @author Chu Wang
13 /// @author Mike Tyka
14 
15 // Unit header
16 #include <protocols/loops/Loops.hh>
17 
18 // Package headers
19 #include <protocols/loops/Loop.hh>
21 
22 // Project Headers
23 #include <core/types.hh>
24 #include <core/id/NamedAtomID.hh>
26 #include <core/pose/Pose.hh>
27 
28 // Utility Headers
29 #include <basic/Tracer.hh>
30 #include <basic/options/option.hh>
31 #include <basic/options/keys/loops.OptionKeys.gen.hh>
32 #include <numeric/xyzVector.hh>
33 #include <numeric/random/random.fwd.hh>
34 #include <numeric/random/random.hh>
35 #include <utility/exit.hh>
36 #include <utility/io/ozstream.hh>
37 #include <utility/string_util.hh>
38 #include <utility/vector1.hh>
39 
40 // C++ Headers
41 #include <iostream>
42 #include <string>
43 
44 
45 
46 namespace protocols {
47 namespace loops {
48 
49 using namespace core;
50 using namespace ObjexxFCL;
51 
52 static basic::Tracer tr("loops");
53 static numeric::random::RandomGenerator RG(430); // <- Magic number, do not change it (and dont try and use it anywhere else)
54 
55 Loops::Loops() : utility::pointer::ReferenceCount()
56 {
57  init( LoopList() );
58 }
59 
60 Loops::Loops( const Loops & src ) : utility::pointer::ReferenceCount()
61 {
62  init( src.loops() );
63 }
64 
66 {
67  init( setup_loops_from_data( src ) );
68 }
69 
70 Loops::Loops( std::string const & loop_file_name )
71 {
72  init( LoopList(), false, loop_file_name );
73 }
74 
75 Loops::Loops( bool setup_loops_from_options_system )
76 {
77  init( LoopList(), setup_loops_from_options_system );
78 }
79 
80 // destructor
82 
84  LoopList const & loops_in,
85  bool const read_loop_file_from_options,
86  std::string const & passed_in_filename
87 )
88 {
89  loops_ = loops_in;
90 
91  if ( read_loop_file_from_options ) {
93  return;
94  }
95  if ( passed_in_filename.compare( "" ) != 0 )
96  {
97  set_loop_file_name_and_reset( passed_in_filename );
98  return;
99  }
100  loop_filename_ = "";
101 }
102 
104 {
105  using namespace basic::options;
106  if ( option[ OptionKeys::loops::loop_file ].user() ) {
107  utility::vector1< std::string > loop_files = option[ OptionKeys::loops::loop_file]();
108  if( loop_files.size() == 1 )
109  {
110  set_loop_file_name_and_reset( loop_files[ 1 ] );
111  return;
112  }
113  core::Size choice = core::Size( RG.random_range(1,( loop_files.size() ) ));
114  // Why is this tr.Error and not like... tr.Info?
115  tr.Error << "Loop choice: " << loop_files[ choice ] << " " << choice << std::endl;
116  set_loop_file_name_and_reset( loop_files[ choice ] );
117  return;
118  }
119  loop_filename_ = "";
120 }
121 
122 bool Loops::empty() const { return num_loop() == 0; }
123 core::Size Loops::num_loop() const { return loops_.size(); }
124 Loops::const_iterator Loops::begin() const { return loops_.begin(); }
125 Loops::const_iterator Loops::end() const { return loops_.end(); }
126 Loops::iterator Loops::v_begin() { return loops_.begin(); }
128 
130  numeric::xyzVector<core::Real>* center) const {
131  using core::Real;
132  using core::Size;
133  using core::id::NamedAtomID;
134 
135  assert(center);
136  center->zero();
137 
138  Real count = 0;
139  for (const_iterator i = begin(); i != end(); ++i) {
140  for (Size j = i->start(); j <= i->stop(); ++j) {
141  (*center) += pose.xyz(NamedAtomID("CA", j));
142  ++count;
143  }
144  }
145 
146  (*center) /= count;
147 }
148 
149 /// @brief switch DOF_Type for residues in loop. id::CHI, id::BB --- don't use
150 /// with id::JUMP
151 void
153  kinematics::MoveMap& movemap,
154  id::TorsionType id,
155  bool allow_moves
156 ) const {
157  for ( Loops::const_iterator it = begin(), eit = end(); it != eit; ++it ) {
158  it->switch_movemap( movemap, id, allow_moves );
159  }
160 }
161 
162 
163 //////////////////////////////////////////////////////////////////////
164 std::ostream & operator<< ( std::ostream & os, const Loops & loops ) {
165  os << "LOOP begin end cut skip_rate extended" << std::endl;
166  for ( Loops::const_iterator it = loops.begin(), it_end = loops.end();
167  it != it_end; ++it ) {
168  os << *it << std::endl;
169  }
170  return os;
171 }
172 
173 
174 void
176  std::string const & filename,
177  std::string token
178 ) const
179 {
180 
181  utility::io::ozstream data;
182  data.open( filename );
183  if ( !data ) {
184  utility_exit_with_message( "Couldn't write loops to file: "+filename );
185  }
186 
187  write_loops_to_stream( data, token );
188 
189  data.close();
190  data.clear();
191 }
192 
193 void
195  std::ostream& data,
196  std::string token
197 ) const
198 {
199 
200  for( Loops::const_iterator it= this->begin(), it_end=this->end();
201  it != it_end; ++it ) {
202  data << token << " " << it->start() << " " << it->stop() << " " << it->cut() << " "
203  << it->skip_rate() << " " << it->is_extended() << std::endl;
204  }
205 }
206 
207 
208 
209 void
210 Loops::add_loop( loops::Loop loop, core::Size minimal_gap ) {
211  Size const start( loop.start() );
212  Size const stop( loop.stop() );
213  Size const cut( loop.cut() );
214  tr.Trace << "adding loop " << loop << std::endl;
215  if ( ( cut == 0 || ( cut>=start-1 && cut <= stop )) && start <= stop ) {
216  for( iterator it = loops_.begin(), it_end = loops_.end();
217  it != it_end; ++it ) {
218  // check for conflicts
219  if( stop+minimal_gap >= it->start() && start <= it->stop() + minimal_gap ) {
220  Loop new_loop( std::min( (int) start, (int) it->start() ), std::max( (int) it->stop(), (int) stop ), it->cut(), it->skip_rate() );
221  loops_.erase( it );
222  tr.Trace << "overlapping loop found: " << loop << " overlaps with " << *it << " create new loop " << new_loop << std::endl;
223  add_loop( new_loop );
224  return;
225  // std::string msg;
226 // msg += "Loops::add_loop error -- overlapping loop regions\n";
227 // msg += "existing loop begin/end: " + string_of( it->start() ) + "/";
228 // msg += string_of( it->stop() ) + "\n";
229 // msg += "new loop begin/end: " + string_of(start) + "/" + string_of(stop);
230 // utility_exit_with_message( msg );
231  }
232  } // no overlaps
233  loops_.push_back( loop );
234  } else {
235  std::string msg;
236  msg += "Loops::add_loop error -- bad loop definition\n";
237  msg += "begin/end/cut: " + string_of(start) + "/" + string_of(stop) + "/";
238  msg += string_of(cut) + "\n";
239 
240  // runtime_assert( false );
241  utility_exit_with_message( msg );
242  }
243 }
244 
245 //////////////////////////////////////////////////////////////////////
246 void
248  Size const start,
249  Size const stop,
250  Size const cut,
252  bool const extended
253 )
254 {
255  add_loop( Loop( start, stop, cut, skip_rate, extended ));
256 }
257 /////////////////////////////////////////////////////////////////////////////
258 void
260  add_loop( it->start(), it->stop(), it->cut(),
261  it->skip_rate(), it->is_extended() );
262 }
263 /////////////////////////////////////////////////////////////////////////////
264 void
266  add_loop( it->start(), it->stop(), it->cut(),
267  it->skip_rate(), it->is_extended() );
268 }
269 /////////////////////////////////////////////////////////////////////////////
270 void
272  add_loop( loop );
273 }
274 /////////////////////////////////////////////////////////////////////////////
275 void
277  core::Size const start,
278  core::Size const stop,
279  core::Size const cut,
281  bool const extended ) {
282  add_loop( start, stop, cut, skip_rate, extended );
283 }
284 /////////////////////////////////////////////////////////////////////////////
285 void
287  for( Loops::const_iterator it = loops.begin(), it_end = loops.end();
288  it != it_end; ++it ) {
289  add_overlap_loop( *it );
290  }
291 }
292 /////////////////////////////////////////////////////////////////////////////
293 void
295 
296  // if ( loop.cut() >=loop.start()-1 && loop.cut() <= loop.stop() && loop.start() < loop.stop() ) {
297  Size temp_start = loop.start();
298  Size temp_stop = loop.stop();
299  Size temp_cut = loop.cut();
300  std::vector<Size> loops_to_delete_start;
301  std::vector<Size> loops_to_delete_stop;
302  for( const_iterator it = loops_.begin(), it_end = loops_.end();
303  it != it_end; ++it ) {
304  // check for conflicts
305  if( temp_stop >= it->start() && temp_stop <= it->stop() ){
306  temp_stop = it->stop();
307  if( std::find( loops_to_delete_start.begin(), loops_to_delete_start.end(),
308  it->start() ) == loops_to_delete_start.end() )
309  {
310  loops_to_delete_start.push_back( it->start() );
311  loops_to_delete_stop.push_back( it->stop() );
312  }
313  }
314  if( temp_start <= it->stop() && temp_start >= it->start()) {
315  temp_start = it->start();
316  if( std::find( loops_to_delete_start.begin(), loops_to_delete_start.end(),
317  it->start() ) == loops_to_delete_start.end() )
318  {
319  loops_to_delete_start.push_back( it->start() );
320  loops_to_delete_stop.push_back( it->stop() );
321  }
322  }
323  if( temp_start <= it->start() && temp_stop >= it->stop() ){// include an existing loop
324  if( std::find( loops_to_delete_start.begin(), loops_to_delete_start.end(),
325  it->start() ) == loops_to_delete_start.end() )
326  {
327  loops_to_delete_start.push_back( it->start() );
328  loops_to_delete_stop.push_back( it->stop() );
329  }
330  }
331  }
332  for( Size d = 0; d < loops_to_delete_start.size(); ++d )
333  delete_loop(loops_to_delete_start[d], loops_to_delete_stop[d] );
334  loops_.push_back( Loop( temp_start, temp_stop, temp_cut, loop.skip_rate(), loop.is_extended() ) );
335 
336  // } else {
337  // std::cerr << "Loops::add_loop error -- bad loop definition\n"
338  // << "begin/cut/end: " << loop.start() << "/" << loop.stop() << "/"
339  // << loop.cut() << std::endl;
340  // runtime_assert( false );
341  // utility::exit( EXIT_FAILURE, __FILE__, __LINE__);
342  // }
343 }
344 
345 /////////////////////////////////////////////////////////////////////////////
346 void
348  Size const start,
349  Size const stop
350 )
351 {
352  runtime_assert( start < stop );
353 
354  for( iterator it=loops_.begin(), it_end=loops_.end();
355  it != it_end; ++it ) {
356  if ( start == it->start() && stop == it->stop() ) {
357  loops_.erase( it );
358  break;
359  }
360  }
361 }
362 /////////////////////////////////////////////////////////////////////////////
365  Size const size = loops_.size();
366  runtime_assert( size > 0 );
367  Size index =0;
368  Size const end = static_cast< Size >( numeric::random::uniform()*size );
369  const_iterator it = loops_.begin();
370  while( index != end ) { ++index; ++it; }
371  return it;
372 }
373 /////////////////////////////////////////////////////////////////////////////
374 Size
376  Size const num
377 ) const {
378  runtime_assert( num > 0 && num <= loops_.size() );
379  return loops_[num].size();
380 }
381 /////////////////////////////////////////////////////////////////////////////
382 Size
384  Size size = 0;
385  for( const_iterator it=loops_.begin(), it_end=loops_.end();
386  it != it_end; ++it ) {
387  size += it->size();
388  }
389  return size;
390 }
391 /////////////////////////////////////////////////////////////////////////////
393  return loops_.size();
394 }
395 /////////////////////////////////////////////////////////////////////////////
397  return loop_size();
398 }
399 /////////////////////////////////////////////////////////////////////////////
400 bool
401 Loops::is_loop_residue( Size const seqpos, int const offset ) const
402 {
403  for( const_iterator it=loops_.begin(), it_end=loops_.end(); it != it_end; ++it ) {
404  if ( seqpos >= (it->start()+offset) && seqpos <= (it->stop()-offset) ) return true;
405  }
406  return false;
407 }
408 
409 bool
410 Loops::loop_of_residue( core::Size const seqpos, Loop& loop ) const {
411  for ( const_iterator it=loops_.begin(), it_end=loops_.end(); it != it_end; ++it ) {
412  if ( seqpos >= it->start() && seqpos <= it->stop() ) {
413  loop = *it;
414  return true;
415  }
416  }
417  return false;
418 }
419 
420 Size
422  Size ct( 1 );
423  for ( const_iterator it=loops_.begin(), it_end=loops_.end(); it != it_end; ++it,++ct ) {
424  if ( seqpos >= it->start() && seqpos <= it->stop() ) {
425  return ct;
426  }
427  }
428  return 0;
429 }
430 
431 void
433  LoopList new_loops_;
434  iterator it_begin = loops_.begin();
435  for ( const_iterator it = it_begin, it_end = loops_.end();
436  it != it_end; ++it ) {
437  if ( !it->is_terminal( pose ) ){
438  new_loops_.push_back( *it );
439  }
440  }
441  loops_ = new_loops_;
442 }
443 
444 /////////////////////////////////////////////////////////////////////////////
446  std::sort(loops_.begin(), loops_.end(), RationalLoopComparator());
447 }
448 //////////////////////////////////////////////////////////////////////
449 void
451  loops_.clear();
452 }
453 
454 Loops::LoopList const & Loops::loops() const { return loops_; }
455 
457 {
458  if ( !loop_file_reader_ )
459  {
461  }
462  return loop_file_reader_;
463 }
464 
466 {
467  LoopList tmp_loops;
468  for( SerializedLoopList::const_iterator it=loop_data.begin(), it_end=loop_data.end(); it != it_end; ++it ) {
469  tmp_loops.push_back( Loop( *it ) );
470  }
471  // sort by start residue
472  std::sort( tmp_loops.begin(), tmp_loops.end(), Loop_lt() );
473  return tmp_loops;
474 }
475 
476 /// @details Soon to be deprecated.
478 {
479  clear();
480 
481  tr << "Loops object initializing itself from pose-numbered loop file named " << loop_file_name() << ". This functionality is soon to be deprecated." << std::endl;
482  std::ifstream loopfile( loop_file_name().c_str() );
485 
486  // TODO: Update these warnings/move them to the reader.
487  tr.Warning << "LOOP formats were recently reconciled - with *some* backwards compatibility. Please check your definition files!" << std::endl;
488  tr.Warning << "Please check that this is what you intended to read in: " << std::endl;
489  tr.Warning << *this;
490 }
491 
492 /// @detail Given the total number of residues, inverts this set of loops.
493 /// Note: the inline comments are geared toward comparative modeling, but
494 /// are not specific to it. Think of "unaligned" as this, "aligned" as its
495 /// inverse.
496 Loops Loops::invert(core::Size num_residues) const {
497  Loops inv;
498 
499  // no unaligned regions
500  if (!num_loop()) {
501  inv.add_loop(1, num_residues);
502  return inv;
503  }
504 
505  Loops copy = *this;
506 
507  // aligned region preceding first unaligned region
508  const Loop& first = copy[1];
509  if (first.start() != 1) {
510  inv.add_loop(Loop(1, first.start() - 1));
511  }
512 
513  // aligned region following last unaligned region
514  const Loop& last = copy[copy.num_loop()];
515  if (last.stop() != num_residues) {
516  inv.add_loop(Loop(last.stop() + 1, num_residues));
517  }
518 
519  // aligned regions in between unaligned regions
520  for (unsigned i = 2; i <= copy.num_loop(); ++i) {
521  const Loop& prev = copy[i - 1];
522  const Loop& curr = copy[i];
523  inv.add_loop(Loop(prev.stop() + 1, curr.start() - 1));
524  }
525 
526  inv.sequential_order();
527  return inv;
528 }
529 
530 bool Loops::has( core::Size const seqpos, int const offset ) const {
531  return is_loop_residue( seqpos, offset );
532 }
533 
534 void Loops::set_extended( bool input ) {
535  for( Loops::iterator it=v_begin(), it_end=v_end(); it != it_end; ++it ) {
536  it->set_extended( input );
537  }
538 }
539 
541  for( Loops::iterator it=v_begin(), it_end=v_end(); it != it_end; ++it ) {
542  it->auto_choose_cutpoint( pose );
543  }
544 }
545 
547  for( Loops::iterator it=v_begin(), it_end=v_end(); it != it_end; ++it ) {
548  it->choose_cutpoint( pose );
549  }
550 }
551 
552 // @Check loops are compatible with pose.
553 void Loops::verify_against( core::pose::Pose const & pose ) const {
554  using core::Size;
555  Size nres = pose.total_residue();
556 
557  for( Loops::const_iterator it=begin(), it_end=end(); it != it_end; ++it ) {
558  if ( it->start() <= 0 ){
559  tr.Error << "ERROR invalid loop " << it->start() << " " << it->stop() << " " << it->cut() << ": Beginning less than 1" << std::endl;
560  utility_exit_with_message("LoopRebuild::ERROR Loop definition out of boundary \n" );
561  }
562  if ( it->stop() > nres ){
563  tr.Error << "ERROR invalid loop " << it->start() << " " << it->stop() << " " << it->cut() << ": End more than nres(" << nres << ")" << std::endl;
564  utility_exit_with_message("LoopRebuild::ERROR Loop definition out of boundary \n" );
565  }
566  Size loopbegin_i = std::min( it->start() , (Size)1 );
567  Size loopend_i = std::max( it->stop() , nres );
568  Size cutpt_i = it->cut();
569  if ( cutpt_i != 0 && ( cutpt_i > loopend_i || cutpt_i < loopbegin_i ) ) {
570  tr.Error << "ERROR invalid loop " << loopbegin_i << " " << loopend_i << " " << cutpt_i << std::endl;
571  utility_exit_with_message("LoopRebuild::ERROR Loop definition out of boundary \n" );
572  }
573  }
574 }
575 
576 // @brief Extend a loop .. don't extend across cutpoints in the pose
577 void Loops::grow_all_loops( core::pose::Pose const & pose, core::Real magnitude ) {
578  Loops &loops_ = *this;
579  for ( core::Size i=1; i <= loops_.size(); i++ ) {
580  grow_loop( pose, loops_[i], magnitude);
581  }
582 }
583 
584 // @brief Extend a loop
585 void Loops::grow_all_loops( core::Size nres, core::Real magnitude ) {
586  Loops &loops_ = *this;
587  for ( core::Size i=1; i <= loops_.size(); i++ ) {
588  grow_loop( nres, loops_[i], magnitude);
589  }
590 }
591 
592 /// @brief Extend a loop .. don't extend across cutpoints in the pose
594  core::pose::Pose const & pose,
595  Loop & loop,
596  core::Real magnitude
597 ) {
598  //fpd don't grow across chainbreaks
599  //fpd do this by adjusting magnitude in both directions
600  core::Real magL=magnitude, magR=magnitude;
601  for (int i=0; i<=magnitude; ++i)
602  if ( pose.fold_tree().is_cutpoint( loop.start()-i-1 ) ) {
603  magL=i; break;
604  }
605  for (int i=0; i<=magnitude; ++i)
606  if ( pose.fold_tree().is_cutpoint( loop.stop()+i ) ) {
607  magR=i; break;
608  }
609 
610  grow_loop( pose.total_residue(), loop, magL, magR );
611 }
612 
614  core::pose::Pose const & pose,
615  Loop & loop,
616  core::Real magnitude
617 ) {
618  //fpd don't grow across chainbreaks
619  //fpd do this by adjusting magnitude in both directions
620  //adds a layer that if possible does not grow the loop into beta sheets
621  //I allow growth into helices because sometimes
622  //there are 2 or 3 residues helices in the middle of loops
623  core::Real magL=magnitude, magR=magnitude;
624  for (int i=0; i<=magnitude; ++i)
625  if (( pose.fold_tree().is_cutpoint( loop.start()-i-1 ) ) || (pose.secstruct(loop.start()-i-1) == 'E')) {
626  magL=i; break;
627  }
628  for (int i=0; i<=magnitude; ++i)
629  if (( pose.fold_tree().is_cutpoint( loop.stop()+i ) ) || (pose.secstruct(loop.start()+i) == 'E')){
630  magR=i; break;
631  }
632  //if both sides hit extended structure than default to the cutpoint behavior
633  if((magR == 0) && (magL == 0)){
634  for (int i=0; i<=magnitude; ++i)
635  if ( pose.fold_tree().is_cutpoint( loop.start()-i-1 ) ) {
636  magL=i; break;
637  }
638  for (int i=0; i<=magnitude; ++i)
639  if ( pose.fold_tree().is_cutpoint( loop.stop()+i ) ) {
640  magR=i; break;
641  }
642  }
643  grow_loop( pose.total_residue(), loop, magL, magR );
644 }
645 
646 
647 
648 /// @brief Extend a loop
650  core::Size nres,
651  Loop & loop,
652  core::Real magnitude
653 ) {
654  grow_loop(nres,loop,magnitude,magnitude);
655 }
656 
657 /// @brief Extend a loop
659  core::Size nres,
660  Loop & loop,
661  core::Real magL,
662  core::Real magR
663 ) {
664  Loop originalloop = loop;
665 
666  Loops &loops_ = *this;
667 
668  tr.Debug << "GrowLoop: " << loop << std::endl;
669 
670  core::Size extend_start = static_cast< core::Size >(
671  numeric::random::uniform() * magL
672  );
673  core::Size extend_stop = static_cast< core::Size >(
674  numeric::random::uniform() * magR
675  );
676 
677  if ( ( extend_start == 0 ) && ( extend_stop == 0 ) ) {
678  if ( numeric::random::uniform() > 0.5 && magL > 0)
679  extend_start = 1;
680  else if (magR > 0)
681  extend_stop = 1;
682  else // magR = magL = 0
683  return;
684  }
685 
686  Loop newloop( loop );
687  core::Size new_start = static_cast< core::Size > (
688  std::max( 1, (int)loop.start() - (int)extend_start )
689  );
690  core::Size new_stop = static_cast< core::Size > (
691  std::min( (int)nres, (int)loop.stop() + (int)extend_stop )
692  );
693 
694  tr.Debug << "NewLoop before loop check: " << new_start << " " << new_stop << std::endl;
695 
696  //grow loops to the start of previous or next loop
697  for ( Loops::iterator it=loops_.v_begin(), it_end=loops_.v_end();
698  it != it_end; ++it ) {
699  if((*it) != originalloop ){
700  //case where the start has grown into the previous loop
701  if ((new_start >= it->start())&&(new_start <= it->stop())){
702  new_start = it->start();
703  tr.Warning << "Tried growing loop into previous loop:" << *it << " " << new_start << " " << new_stop << std::endl;
704  }
705  //case where the stop has grown into the next loop
706  if ((new_stop <= it->stop())&&(new_stop >= it->start())){
707  new_stop = it->stop();
708  tr.Warning << "Tried growing loop into next loop:" << *it << " " << new_start << " " << new_stop << std::endl;
709  }
710  }
711  }
712 
713  tr.Debug << "NewLoop after loop check: " << new_start << " " << new_stop << std::endl;
714 
715  if ( new_stop < loop.stop() ) {
716  tr.Info << "Loop stops earlier than before ???" << std::endl;
717  new_stop = loop.stop();
718  }
719  if ( new_start > loop.start() ) {
720  tr.Info << "Loop starts later than before ???" << std::endl;
721  new_start = loop.start();
722  }
723 
724 
725  // make sure loop length is greater than 3
726  //fpd don't extend across chainbreaks!!
727  if ( new_stop - new_start < 2 && new_start != 1 && new_stop != nres ) {
728  if (magL>0) new_start -= 1;
729  if (magR>0) new_stop += 1;
730  }
731 
732  int final_extend_start = loop.start()-new_start;
733  int final_extend_stop = new_stop-loop.stop();
734 
735  loop.set_start( new_start );
736  loop.set_stop( new_stop );
737  tr.Info << "Extended: (-" << final_extend_start << ",+" << final_extend_stop
738  << ") " << loop << std::endl;
739 }
740 
742  selection.clear();
743  for ( const_iterator it = loops_.begin(); it != loops_.end(); ++it ) {
744  it->get_residues( selection );
745  }
746 }
748 {
749  return loop_filename_;
750 }
752 {
753  loop_filename_ = loop_filename;
754  read_loop_file();
755 }
756 
758 {
760 }
761 
762 void Loops::set_strict_looprelax_checks( bool const check )
763 {
765 }
766 
768 {
769  return file_reading_token_;
770 }
771 
773 {
774  file_reading_token_ = token;
775 }
776 
777 const Loop & Loops::operator[] ( core::Size const i ) const
778 {
779  return loops_[i];
780 }
781 
783 {
784  return loops_[i];
785 }
786 
787 Loops & Loops::operator =( Loops const & src )
788 {
789  loops_ = src.loops_;
790  return *this;
791 }
792 
793 bool Loops::operator== ( Loops const& other ) const
794 {
795  if ( other.size() != size() ) return false;
796  const_iterator other_it = other.loops_.begin();
797  for ( const_iterator it = loops_.begin(); it != loops_.end(); ++it, ++other_it ) {
798  if ( *other_it != *it ) return false;
799  }
800  return true;
801 }
802 
803 bool Loops::operator!=( Loops const& other ) const
804 {
805  return !( *this == other);
806 }
807 
808 void
810 {
811  for ( Loops::iterator it = v_begin(), it_end = v_end();
812  it != it_end; ++it ) {
813  it->set_start( core::Size( it->start() + shift ) );
814  it->set_stop( it->stop() + shift );
815  it->set_cut( it->cut() + shift );
816  }
817 }
818 
819 } // namespace loops
820 } // namespace protocols