Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RemodelLoopMover.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/forge/remodel/RemodelLoopMover.cc
11 /// @brief Loop modeling protocol based on routines from Remodel and EpiGraft
12 /// packages in Rosetta++.
13 /// @author Yih-En Andrew Ban (yab@u.washington.edu)
14 /// @author Possu Huang (possu@u.washington.edu)
15 
16 // unit headers
19 
20 // package headers
24 
25 // project headers
28 #include <core/io/pdb/file_data.hh>
29 // AUTO-REMOVED #include <core/chemical/ResidueTypeSet.hh>
30 // AUTO-REMOVED #include <core/chemical/VariantType.hh>
31 #include <core/id/TorsionID.hh>
32 #include <core/fragment/FragSet.hh>
34 #include <core/pose/Pose.hh>
35 #include <core/pose/util.hh>
37 #include <core/scoring/Energies.hh>
39 
42 // AUTO-REMOVED #include <core/conformation/symmetry/util.hh>
46 #include <basic/Tracer.hh>
52 //#include <protocols/simple_moves/symmetry/SetupNCSMover.hh>
53 #include <basic/options/option.hh>
54 #include <basic/options/keys/remodel.OptionKeys.gen.hh>
55 #include <basic/options/keys/constraints.OptionKeys.gen.hh>
56 
57 //loophash
62 
63 
64 //#include <basic/options/keys/Remodel.OptionKeys.gen.hh>
67 
68 // numeric headers
69 #include <numeric/random/random.hh>
70 #include <numeric/random/random_permutation.hh>
71 
72 // boost headers
73 #include <boost/format.hpp>
74 
75 // C++ headers
76 #include <algorithm>
77 #include <set>
78 #include <sstream>
79 #include <utility>
80 
82 #include <utility/vector0.hh>
83 #include <utility/vector1.hh>
84 #include <utility/tag/Tag.hh>
85 #include <boost/lexical_cast.hpp>
86 
87 //Auto Headers
89 #include <utility/string_util.hh>
90 
91 
92 namespace protocols {
93 namespace forge {
94 namespace remodel {
95 
96 
97 // Tracer instance for this file
98 // Named after the original location of this code
99 static basic::Tracer TR( "protocols.forge.remodel.RemodelLoopMover" );
100 
101 // RNG
102 static numeric::random::RandomGenerator RG( 9788221 ); // magic number, don't change
103 
106 {
108 }
109 
112  return new RemodelLoopMover;
113 }
114 
117 {
118  return "RemodelLoop";
119 }
120 
121 
122 /// @brief default constructor
124  Super( "RemodelLoop" ),
125  sfx_( core::scoring::ScoreFunctionFactory::create_score_function( "remodel_cen" ) ),
126  max_linear_chainbreak_( 0.07 ),
127  randomize_loops_( true ),
128  allowed_closure_attempts_( 1 ), //switched from 3 so no accumulation
129  loophash_cycles_( 8 ),
130  simultaneous_cycles_( 2 ),
131  independent_cycles_( 8 ),
132  user_provided_movers_apply_cycle_(3),
133  boost_closure_cycles_( 30 ),
134  temperature_( 2.0 ),
135  keep_input_foldtree_( false )
136 {
138 }
139 
140 
141 /// @brief loops constructor
143  Super( "RemodelLoop" ),
144  sfx_( core::scoring::ScoreFunctionFactory::create_score_function( "remodel_cen" ) ),
145  loops_( loops ),
146  max_linear_chainbreak_( 0.07 ),
147  randomize_loops_( true ),
148  allowed_closure_attempts_( 1 ),
149  loophash_cycles_( 8 ),
150  simultaneous_cycles_( 2 ),
151  independent_cycles_( 8 ),
152  user_provided_movers_apply_cycle_(3),
153  boost_closure_cycles_( 30 ),
154  temperature_( 2.0 ),
155  keep_input_foldtree_( false )
156 {
158 }
159 
160 
161 /// @brief copy constructor
163  //utility::pointer::ReferenceCount(),
164  Super( rval ),
165  sfx_( rval.sfx_ ),
166  false_movemap_( rval.false_movemap_ ),
167  loops_( rval.loops_ ),
168  max_linear_chainbreak_( rval.max_linear_chainbreak_ ),
169  randomize_loops_( rval.randomize_loops_ ),
170  allowed_closure_attempts_( rval.allowed_closure_attempts_ ),
171  loophash_cycles_( rval.loophash_cycles_ ),
172  simultaneous_cycles_( rval.simultaneous_cycles_ ),
173  independent_cycles_( rval.independent_cycles_ ),
174  user_provided_movers_(rval.user_provided_movers_),
175  user_provided_movers_apply_cycle_(rval.user_provided_movers_apply_cycle_),
176  boost_closure_cycles_( rval.boost_closure_cycles_ ),
177  temperature_( rval.temperature_ ),
178  fragsets_( rval.fragsets_ ),
179  keep_input_foldtree_(rval.keep_input_foldtree_)
180 {}
181 
182 
183 /// @brief default destructor
185 
186 
187 /// @brief clone this object
189  return new RemodelLoopMover( *this );
190 }
191 
192 
193 /// @brief create this type of object
195  return new RemodelLoopMover();
196 }
197 
198 
199 /// @brief set parameters from options
201  using namespace basic::options;
202  using namespace OptionKeys::remodel;
203  if( option[ OptionKeys::remodel::RemodelLoopMover::max_linear_chainbreak ].user() ) max_linear_chainbreak_ = option[ OptionKeys::remodel::RemodelLoopMover::max_linear_chainbreak ].value();
204  if( option[ OptionKeys::remodel::RemodelLoopMover::randomize_loops ].user() ) randomize_loops_ = option[ OptionKeys::remodel::RemodelLoopMover::randomize_loops ].value();
205  if( option[ OptionKeys::remodel::RemodelLoopMover::allowed_closure_attempts ].user() ) allowed_closure_attempts_ = option[ OptionKeys::remodel::RemodelLoopMover::allowed_closure_attempts ].value();
206  if( option[ OptionKeys::remodel::RemodelLoopMover::loophash_cycles ].user() ) loophash_cycles_ = option[ OptionKeys::remodel::RemodelLoopMover::loophash_cycles ].value();
207  if( option[ OptionKeys::remodel::RemodelLoopMover::simultaneous_cycles ].user() ) simultaneous_cycles_ = option[ OptionKeys::remodel::RemodelLoopMover::simultaneous_cycles ].value();
208  if( option[ OptionKeys::remodel::RemodelLoopMover::independent_cycles ].user() ) independent_cycles_ = option[ OptionKeys::remodel::RemodelLoopMover::independent_cycles ].value();
209  if( option[ OptionKeys::remodel::RemodelLoopMover::boost_closure_cycles ].user() ) boost_closure_cycles_ = option[ OptionKeys::remodel::RemodelLoopMover::boost_closure_cycles ].value();
210  if( option[ OptionKeys::remodel::RemodelLoopMover::temperature ].user() ) temperature_ = option[ OptionKeys::remodel::RemodelLoopMover::temperature ].value();
211  // flo may '12 the below option is different bc it's
212  // replacing the way it was used in the code until now,
213  // where the check for the user didn't happen
214  keep_input_foldtree_ = option[OptionKeys::remodel::no_jumps];
215 }
216 
217 /// @registere options
219  using namespace basic::options;
220  using namespace basic::options::OptionKeys;
221  option.add_relevant( OptionKeys::remodel::RemodelLoopMover::max_linear_chainbreak );
222  option.add_relevant( OptionKeys::remodel::RemodelLoopMover::randomize_loops );
223  option.add_relevant( OptionKeys::remodel::RemodelLoopMover::allowed_closure_attempts );
224  option.add_relevant( OptionKeys::remodel::RemodelLoopMover::loophash_cycles );
225  option.add_relevant( OptionKeys::remodel::RemodelLoopMover::simultaneous_cycles );
226  option.add_relevant( OptionKeys::remodel::RemodelLoopMover::independent_cycles );
227  option.add_relevant( OptionKeys::remodel::RemodelLoopMover::boost_closure_cycles );
228  option.add_relevant( OptionKeys::remodel::RemodelLoopMover::temperature );
229 }
230 
231 /// @brief the ScoreFunction to use during modeling;
233  return *sfx_;
234 }
235 
236 
237 /// @brief the ScoreFunction to use during modeling
239  //sfx_ = new ScoreFunction( sfx );
240  sfx_ = sfx.clone();
241 }
242 
243 void
245 {
246  user_provided_movers_.clear();
247  user_provided_movers_ = movers;
248 }
249 
250 
251 /// @brief add a fragment set
253  if ( fragset->size() > 0 ) {
254  fragsets_.push_back( fragset->clone() );
255  }
256 }
257 
258 
259 /// @brief clear all fragment sets
261  fragsets_.clear();
262 }
263 
265 {
266  using namespace core::pose;
267  using core::Size;
268  using namespace basic::options;
269 
270  //testing repeat units
271  //two pose symmetry strategy
272 
273  core::pose::Pose non_terminal_pose(pose);
274 
275  if (option[ OptionKeys::remodel::repeat_structure].user()){
276 
277  //remove the extra tail from pose, but still use the pose with tail to build
278  Size tail_count = repeat_tail_length_;
279  while ( tail_count ){
280  non_terminal_pose.conformation().delete_residue_slow(non_terminal_pose.total_residue());
281  tail_count--;
282  }
283 
284  Real jxnl_phi = pose.phi(non_terminal_pose.total_residue()-1);
285  Real jxnl_psi = pose.psi(non_terminal_pose.total_residue()-1);
286  Real jxnl_omega = pose.omega(non_terminal_pose.total_residue()-1);
287  Real jxn_phi = pose.phi(non_terminal_pose.total_residue());
288  Real jxn_psi = pose.psi(non_terminal_pose.total_residue());
289  Real jxn_omega = pose.omega(non_terminal_pose.total_residue());
290  Real jxnh_phi = pose.phi(non_terminal_pose.total_residue()+1);
291  Real jxnh_psi = pose.psi(non_terminal_pose.total_residue()+1);
292  Real jxnh_omega = pose.omega(non_terminal_pose.total_residue()+1);
293 
294  repeat_pose=non_terminal_pose;
295 
296  //reset foldtree and simply depend on coordinates for appendage
297  core::kinematics::FoldTree ft = repeat_pose.fold_tree();
298  ft.simple_tree(repeat_pose.total_residue());
299  repeat_pose.fold_tree(ft);
301 
302  Size repeatFactor = option[ OptionKeys::remodel::repeat_structure];
303  Size count = 1;
304 
305  while ( repeatFactor !=1){ // the argument should be total number of copies
306  for (Size rsd = 1; rsd <= non_terminal_pose.total_residue(); rsd++){
307  //intentially insert behind the last residue, this way blueprint definition will cover the junction with fragments
308  if (rsd == non_terminal_pose.total_residue()){
309  repeat_pose.conformation().safely_append_polymer_residue_after_seqpos( non_terminal_pose.residue(rsd),repeat_pose.total_residue(), false);
310  } else {
311  repeat_pose.conformation().safely_append_polymer_residue_after_seqpos( non_terminal_pose.residue(rsd),repeat_pose.total_residue(), false);
312  /*
313  for (int i =1; i<= repeat_pose.total_residue(); i++){
314  std::cout << "repeat_pose Phi: "<< repeat_pose.phi(i) << " psi: " << repeat_pose.psi(i) << " omega: " << repeat_pose.omega(i) << " at " << i << std::endl;
315  } */
316  }
317  }
318 
319 
320 
321  Size junction = (non_terminal_pose.total_residue())* count;
322  repeat_pose.conformation().insert_ideal_geometry_at_polymer_bond(junction);
323  /*
324  //std::cout << "junction " << junction << std::endl;
325  repeat_pose.set_phi(junction+1,-150);
326  repeat_pose.set_psi(junction,150);
327  repeat_pose.set_omega(junction,180);
328  */
329  //std::cout << "junction " << junction << std::endl;
330  repeat_pose.set_phi(junction-1, jxnl_phi);
331  repeat_pose.set_psi(junction-1, jxnl_psi);
332  repeat_pose.set_omega(junction-1, jxnl_omega);
333  repeat_pose.set_phi(junction, jxn_phi);
334  repeat_pose.set_psi(junction, jxn_psi);
335  repeat_pose.set_omega(junction, jxn_omega);
336  repeat_pose.set_phi(junction+1, jxnh_phi);
337  repeat_pose.set_psi(junction+1, jxnh_psi);
338  repeat_pose.set_omega(junction+1,jxnh_omega);
339  //std::cout << "repeat Factor : " << repeatFactor << std::endl;
340  count++;
341  repeatFactor--;
342  }
343  //terminus residue check
344  for (Size res=2; res< repeat_pose.total_residue(); res++){
345  if (repeat_pose.residue(res).is_terminus()){
346  // std::cout<< "FIX TERMINUS " << res << std::endl;
349  }
350  }
351  using namespace protocols::loops;
352  using namespace core::kinematics;
353 
354  Size repeat_number = basic::options::option[ OptionKeys::remodel::repeat_structure];
355  Size segment_length = (repeat_pose.n_residue())/repeat_number;
356  //std::cout << "DEBUG: segment lenght = " << segment_length << std::endl;
357 
358  //propagate jumps
359 
361 
362  LoopsOP repeat_loops = new Loops();
363 
364  std::set< Size > lower_termini;
365  std::set< Size > upper_termini;
366  for ( Size i = 1, ie = pose.conformation().num_chains(); i <= ie; ++i ) {
367  lower_termini.insert( pose.conformation().chain_begin( i ) );
368  upper_termini.insert( pose.conformation().chain_end( i ) );
369  }
370 
371  for ( Loops::iterator l = loops_->v_begin(), le = loops_->v_end(); l != le; ++l ) {
372  Loop & loop = *l;
373  if (loop.start() == 1 && loop.stop() == segment_length){
374  break; //don't need to do anything about foldtree if fully de novo
375  } else {
376 
377  repeat_loops->push_back(loop); //load the first guy
378  //TR << loop.start() << " " << loop.stop() << " " << loop.cut() << std::endl;
379 
380  //math to figure out the different segments
381  for (Size rep = 0; rep < repeat_number; rep++){
382 
383  //find equals iterator end means not found. If the loops is internal, increment by repeats
384  if ( lower_termini.find( loop.start() ) == lower_termini.end() && upper_termini.find( loop.stop() ) == upper_termini.end()){
385  Size tempStart = loop.start()+(segment_length*rep);
386  Size tempStop = loop.stop()+(segment_length*rep);
387  Size tempCut = loop.cut()+(segment_length*rep);
388  if (tempStop > repeat_pose.total_residue()){
389  tempStop = repeat_pose.total_residue();
390  if ( tempCut > tempStop ){
391  tempCut = tempStop;
392  }
393  }
394  LoopOP newLoop = new Loop( tempStart, tempStop , tempCut);
395  //TR << "adding loop in repeat propagation: " << tempStart << " " << tempStop << " " << tempCut << std::endl;
396  repeat_loops->push_back(*newLoop);
397  }
398  else {
399  LoopOP newLoop = new Loop(loop.start(), loop.stop(), loop.cut());
400  repeat_loops->push_back(*newLoop);
401  }
402  }
403  }
404  }
405  if (!repeat_loops->empty()){
406  f = protocols::forge::methods::fold_tree_from_loops(repeat_pose, *repeat_loops);
407  } else {
408  f.simple_tree(repeat_pose.total_residue());
409  }
410  FoldTree PFT = pose.fold_tree();
411  PFT.reorder(1);
412  pose.fold_tree(PFT);
413  f.reorder(1);
414  repeat_pose.fold_tree(f);
415  TR << repeat_pose.fold_tree() << std::endl;
416 
417  for ( Loops::iterator l = repeat_loops->v_begin(), le = repeat_loops->v_end(); l != le; ++l ) {
418  Loop & loop = *l;
419  for (Size jxn=loop.start(); jxn <=loop.stop(); jxn++){
420  //std::cout << "GEN fix junction at " << jxn << std::endl;
421  if (jxn != repeat_pose.total_residue()){ // shouldn't happen because definition on repeat1, but for safety
423  }
424  }
425  }
426 
427  if (option[OptionKeys::remodel::no_jumps].user()){
428  remove_cutpoint_variants( pose );
429  remove_cutpoint_variants( repeat_pose );
430  FoldTree FT;
431  FT.simple_tree(repeat_pose.total_residue());
432  repeat_pose.fold_tree(FT);
433 
434  FoldTree PFT;
435  PFT.simple_tree(pose.total_residue());
436  pose.fold_tree(PFT);
437 
438  return;
439  }
440 
441  //take the jumps and set repeating RT
442  //Size jump_offset = pose.num_jump(); //pose at this stage should at most have only one jump;
443  //for (Size rep = 1; rep < repeat_number; rep++){
444  for (Size i = 1; i<= repeat_pose.num_jump();){
445  for (Size j = 1; j<= pose.num_jump(); j++,i++){
446  if (i > repeat_pose.num_jump()){
447  break;
448  }
449  FoldTree FT = repeat_pose.fold_tree();
450  FT.renumber_jumps();
451 
454  TR << "pose FT: " << pose.fold_tree() << std::endl;
455  TR << "rpps FT: " << repeat_pose.fold_tree() << std::endl;
456  TR << "set ROT-TRANS from " << j << " to " << i << std::endl;
457 
459  repeat_pose.fold_tree(FT);
460 
461  Jump tempJump = repeat_pose.jump(i);
462  tempJump.set_rotation( Rot );
463  tempJump.set_translation( Trx );
464  repeat_pose.conformation().set_jump_now( i, tempJump );
465  }
466  }
467 
468 
469  //}
470  //check tree:
471  //TR << f << std::endl;
472 /*
473  //debugging
474  for ( Loops::iterator l = loops_->v_begin(), le = loops_->v_end(); l != le; ++l ) {
475  Loop & loop = *l;
476  for (int i = loop.start(); i<= loop.stop(); i++){
477  for (Size rep = 0; rep < repeat_number; rep++){
478  repeat_pose.set_phi( i+(segment_length*rep), RG.uniform());
479  repeat_pose.set_psi( i+(segment_length*rep), RG.uniform());
480  }
481  }
482  }
483 */
484 
485 /*
486 
487  //take care of foldtree
488  core::kinematics::FoldTree f;
489  f.simple_tree(repeat_pose.total_residue());
490  repeat_pose.fold_tree(f);
491 */
492  /*
493  for (int i =1; i<= repeat_pose.total_residue(); i++){
494  std::cout << "repeat_pose Phi: "<< repeat_pose.phi(i) << " psi: " << repeat_pose.psi(i) << " omega: " << repeat_pose.omega(i) << " at " << i << std::endl;
495  }
496  // pose = repeat_pose;
497  // std::cout << repeat_pose.fold_tree()<< std::endl;
498 */
499  }
500 }
501 
502 
504 {
505  using namespace core::pose;
506  using core::Size;
507  using namespace basic::options;
508  //testing repeat units
509  //two pose symmetry strategy
510 
511  core::pose::Pose non_terminal_pose(pose);
512  //core::pose::Pose repeat_pose;
513  if (option[ OptionKeys::remodel::repeat_structure].user()){
514  repeat_pose=non_terminal_pose;
515 
516  //reset foldtree and simply depend on coordinates for appendage
517  core::kinematics::FoldTree ft = repeat_pose.fold_tree();
518  ft.simple_tree(repeat_pose.total_residue());
519  repeat_pose.fold_tree(ft);
521 
522 
524 
525  Size repeatFactor = option[ OptionKeys::remodel::repeat_structure];
526  Size count = 1;
527  while ( repeatFactor !=1){ // the argument should be total number of copies
528  for (Size rsd = 1; rsd <= non_terminal_pose.total_residue(); rsd++){
529  //intentially insert behind the last residue, this way blueprint definition will cover the junction with fragments
530  if (rsd == non_terminal_pose.total_residue()){
531  repeat_pose.conformation().safely_append_polymer_residue_after_seqpos( non_terminal_pose.residue(rsd),repeat_pose.total_residue(),true);
532  }else {
533  repeat_pose.conformation().safely_append_polymer_residue_after_seqpos( non_terminal_pose.residue(rsd),repeat_pose.total_residue(),false);
534  }
535  }
536  Size junction = (non_terminal_pose.total_residue())* count;
537  repeat_pose.conformation().insert_ideal_geometry_at_polymer_bond(junction);
538  repeat_pose.set_omega(junction,180);
539  //std::cout << "repeat Factor : " << repeatFactor << std::endl;
540  count++;
541  repeatFactor--;
542  }
543  //terminus residue check
544  for (Size res=2; res< repeat_pose.total_residue(); res++){
545  if (repeat_pose.residue(res).is_terminus()){
546  //std::cout<< "FIX TERMINUS " << res << std::endl;
549  }
550  }
551  using namespace protocols::loops;
552  using namespace core::kinematics;
553 
554  Size repeat_number = basic::options::option[ OptionKeys::remodel::repeat_structure];
555  Size segment_length = (repeat_pose.n_residue())/repeat_number;
556  //std::cout << "DEBUG: segment lenght = " << segment_length << std::endl;
557 
558  //propagate jumps
559 
561 
562  LoopsOP repeat_loops = new Loops();
563  std::set< Size > lower_termini;
564  std::set< Size > upper_termini;
565  for ( Size i = 1, ie = pose.conformation().num_chains(); i <= ie; ++i ) {
566  lower_termini.insert( pose.conformation().chain_begin( i ) );
567  upper_termini.insert( pose.conformation().chain_end( i ) );
568  }
569 
570  for ( Loops::iterator l = loops_->v_begin(), le = loops_->v_end(); l != le; ++l ) {
571  Loop & loop = *l;
572  if (loop.start() == 1 && loop.stop() == segment_length){
573  break; //don't need to do anything about foldtree if fully de novo
574  } else {
575 
576  repeat_loops->push_back(loop); //load the first guy
577  //TR << loop.start() << " " << loop.stop() << " " << loop.cut() << std::endl;
578 
579  //math to figure out the different segments
580  for (Size rep = 0; rep < repeat_number; rep++){
581 
582  //find equals iterator end means not found. If the loops is internal, increment by repeats
583  if ( lower_termini.find( loop.start() ) == lower_termini.end() && upper_termini.find( loop.stop() ) == upper_termini.end()){
584  Size tempStart = loop.start()+(segment_length*rep);
585  Size tempStop = loop.stop()+(segment_length*rep);
586  Size tempCut = loop.cut()+(segment_length*rep);
587  if (tempStop > repeat_pose.total_residue()){
588  tempStop = repeat_pose.total_residue();
589  if ( tempCut > tempStop ){
590  tempCut = tempStop;
591  }
592  }
593  LoopOP newLoop = new Loop( tempStart, tempStop , tempCut);
594  //TR << "adding loop in repeat propagation: " << tempStart << " " << tempStop << " " << tempCut << std::endl;
595  repeat_loops->push_back(*newLoop);
596  }
597  else {
598  LoopOP newLoop = new Loop(loop.start(), loop.stop(), loop.cut());
599  repeat_loops->push_back(*newLoop);
600  }
601  }
602  }
603  }
604 /*
605  for ( Loops::iterator l = loops_->v_begin(), le = loops_->v_end(); l != le; ++l ) {
606  Loop & loop = *l;
607  if (loop.start() == 1 && loop.stop() == segment_length){
608  break; //don't need to do anything about foldtree if fully de novo
609  } else {
610 
611  repeat_loops->push_back(loop); //load the first guy
612  TR << loop.start() << " " << loop.stop() << " " << loop.cut() << std::endl;
613 
614  //math to figure out the different segments
615  for (Size rep = 0; rep < repeat_number; rep++){
616  LoopOP newLoop = new Loop(loop.start()+(segment_length*rep), loop.stop()+(segment_length*rep),loop.cut()+(segment_length*rep));
617  TR << "adding loop in repeat propagation: " << loop.start()+(segment_length*rep) << std::endl;
618  repeat_loops->push_back(*newLoop);
619  }
620  }
621  }
622 */
623  if (!repeat_loops->empty()){
624  f = protocols::forge::methods::fold_tree_from_loops(repeat_pose, *repeat_loops);
625  } else {
626  f.simple_tree(repeat_pose.total_residue());
627  }
628 
629 
630  repeat_pose.fold_tree(f);
631 
632  //fix geometry for junction
633 
634  for ( Loops::iterator l = repeat_loops->v_begin(), le = repeat_loops->v_end(); l != le; ++l ) {
635  Loop & loop = *l;
636  for (Size jxn=loop.start(); jxn <=loop.stop(); jxn++){
637  //std::cout << "fix junction at " << jxn << std::endl;
638  if (jxn != repeat_pose.total_residue()){ //safety
640  }
641  }
642  }
643 
644  //take the jumps and set repeating RT
645  Size jump_offset = pose.num_jump();
646  for (Size rep = 1; rep < repeat_number; rep++){
647  for (Size i = 1; i<= pose.num_jump(); i++){
650  // TR << "set ROT-TRANS from " << i << " to " << i+jump_offset*rep << std::endl;
651  Jump tempJump = repeat_pose.jump(i+(jump_offset*rep));
652  tempJump.set_rotation( Rot );
653  tempJump.set_translation( Trx );
654  repeat_pose.conformation().set_jump( i+(jump_offset*rep), tempJump );
655  }
656  }
657 
658 
659 
660  //check tree:
661  //TR << f << std::endl;
662 
663 /*
664  //take care of foldtree
665  core::kinematics::FoldTree f;
666  f.simple_tree(repeat_pose.total_residue());
667  repeat_pose.fold_tree(f);
668  //repeat_pose.dump_pdb("repeat.pdb");
669  // pose = repeat_pose;
670  // std::cout << repeat_pose.fold_tree()<< std::endl;
671 */
672  }
673 }
674 
675 void RemodelLoopMover::repeat_sync( //utility function
676  core::pose::Pose & repeat_pose,
677  core::Size repeat_number
678 )
679 {
680  using core::Size;
681  using namespace protocols::loops;
682  using namespace core::kinematics;
683 
684  //repeat_pose.dump_pdb("repeatPose_in_rep_propagate.pdb");
685 
686  Size segment_length = (repeat_pose.n_residue())/repeat_number;
687  //std::cout << "DEBUG: segment lenght = " << segment_length << std::endl;
688 
689  //propagate jumps
690 
692 
693  LoopsOP repeat_loops = new Loops();
694 
695  utility::vector1<Size> linkPositions;
696 
697  for ( Loops::iterator l = loops_->v_begin(), le = loops_->v_end(); l != le; ++l ) {
698  Loop & loop = *l;
699 
700  //collect the movable positions
701  for (Size i = loop.start(); i<=loop.stop(); i++ ){
702  linkPositions.push_back(i);
703  }
704 
705  for ( Size i = 1; i<= linkPositions.size(); i++){
706 
707  Size res = linkPositions[i];
708  Real loop_phi = 0;
709  Real loop_psi = 0;
710  Real loop_omega = 0;
711 
712  if (res <= segment_length ){ // should already be, just to be sure
713 
714  if (res == 1){ //if the first and last positions are involved, loop around
715  loop_phi = repeat_pose.phi(segment_length+1);
716  loop_psi = repeat_pose.psi(segment_length+1);
717  loop_omega = repeat_pose.omega(segment_length+1);
718  repeat_pose.set_phi( 1, loop_phi);
719  repeat_pose.set_psi( 1, loop_psi);
720  repeat_pose.set_omega( 1, loop_omega);
721  } else {
722  loop_phi = repeat_pose.phi(res);
723  loop_psi = repeat_pose.psi(res);
724  loop_omega = repeat_pose.omega(res);
725  }
726 
727  for (Size rep = 1; rep < repeat_number; rep++){
728  repeat_pose.set_phi(res+( segment_length*rep), loop_phi );
729  repeat_pose.set_psi(res+( segment_length*rep), loop_psi );
730  repeat_pose.set_omega( res+(segment_length*rep),loop_omega );
731  }
732  }
733  else if (res > segment_length ){ //for spanning builds
734 
735  //spanning, update the equivalent copy in the first section with
736  //new first
737  repeat_pose.set_phi(res-segment_length, repeat_pose.phi(res));
738  repeat_pose.set_psi(res-segment_length, repeat_pose.psi(res));
739  repeat_pose.set_omega(res-segment_length, repeat_pose.omega(res));
740 
741  //then propagate
742  loop_phi = repeat_pose.phi(res-segment_length);
743  loop_psi = repeat_pose.psi(res-segment_length);
744  loop_omega = repeat_pose.omega(res-segment_length);
745  for (Size rep = 1; rep < repeat_number; rep++){
746  if (res+( segment_length*rep)<= repeat_pose.total_residue()){
747  repeat_pose.set_phi(res+( segment_length*rep), loop_phi );
748  repeat_pose.set_psi(res+( segment_length*rep), loop_psi );
749  repeat_pose.set_omega( res+(segment_length*rep),loop_omega );
750  }
751  }
752 
753  }
754  else {
755  TR << "ERROR in collecting positions: res: " << res << std::endl;
756  }
757  }
758  }
759  //repeat_pose.dump_pdb("rep_test.pdb");
760 }
761 
762 void RemodelLoopMover::repeat_propagation( //utility function
763  core::pose::Pose & pose,
764  core::pose::Pose & repeat_pose,
765  core::Size repeat_number
766 )
767 {
768  using core::Size;
769  using namespace protocols::loops;
770  using namespace core::kinematics;
771 
772  //repeat_pose.dump_pdb("repeatPose_in_rep_propagate.pdb");
773 
774  Size segment_length = (repeat_pose.n_residue())/repeat_number;
775  //std::cout << "DEBUG: segment lenght = " << segment_length << std::endl;
776 
777  //propagate jumps
778 
780 
781  bool build_across_jxn = false;
782  Size residues_beyond_jxn = 0;
783 
784  LoopsOP repeat_loops = new Loops();
785  std::set< Size > lower_termini;
786  std::set< Size > upper_termini;
787  for ( Size i = 1, ie = pose.conformation().num_chains(); i <= ie; ++i ) {
788  lower_termini.insert( pose.conformation().chain_begin( i ) );
789  upper_termini.insert( pose.conformation().chain_end( i ) );
790  }
791 
792  for ( Loops::iterator l = loops_->v_begin(), le = loops_->v_end(); l != le; ++l ) {
793  Loop & loop = *l;
794  if (loop.start() == 1 && loop.stop() == segment_length){
795  break; //don't need to do anything about foldtree if fully de novo
796  } else {
797 
798  // if any of the loops build go beyond the junction, keep track of it and
799  // update the first segment accordingly
800  if (loop.start() <= segment_length && loop.stop() > segment_length){
801  //std::cout << "build across jxn: " << loop.start() << " " << loop.stop() << std::endl;
802  build_across_jxn = true;
803  residues_beyond_jxn = loop.stop() - segment_length;
804  //std::cout << "build across jxn leftover: " << residues_beyond_jxn << std::endl;
805  }
806 
807  repeat_loops->push_back(loop); //load the first guy
808  //TR << loop.start() << " " << loop.stop() << " " << loop.cut() << std::endl;
809 
810  //math to figure out the different segments
811  for (Size rep = 0; rep < repeat_number; rep++){
812 
813  //find equals iterator end means not found. If the loops is internal, increment by repeats
814  if ( lower_termini.find( loop.start() ) == lower_termini.end() && upper_termini.find( loop.stop() ) == upper_termini.end()){
815  Size tempStart = loop.start()+(segment_length*rep);
816  Size tempStop = loop.stop()+(segment_length*rep);
817  Size tempCut = loop.cut()+(segment_length*rep);
818  if (tempStop > repeat_pose.total_residue()){
819  tempStop = repeat_pose.total_residue();
820  if ( tempCut > tempStop ){
821  tempCut = tempStop;
822  }
823  }
824  LoopOP newLoop = new Loop( tempStart, tempStop , tempCut);
825  //TR << "adding loop in repeat propagation: " << tempStart << " " << tempStop << " " << tempCut << std::endl;
826  repeat_loops->push_back(*newLoop);
827  }
828  else {
829  LoopOP newLoop = new Loop(loop.start(), loop.stop(), loop.cut());
830  repeat_loops->push_back(*newLoop);
831  }
832  }
833  }
834  }
835 /*
836  for ( Loops::iterator l = loops_->v_begin(), le = loops_->v_end(); l != le; ++l ) {
837  Loop & loop = *l;
838  if (loop.start() == 1 && loop.stop() == segment_length){
839  break; //don't need to do anything about foldtree if fully de novo
840  } else {
841 
842  repeat_loops->push_back(loop); //load the first guy
843  // TR << loop.start() << " " << loop.stop() << " " << loop.cut() << std::endl;
844 
845  //math to figure out the different segments
846  for (Size rep = 0; rep < repeat_number; rep++){
847  LoopOP newLoop = new Loop(loop.start()+(segment_length*rep), loop.stop()+(segment_length*rep),loop.cut()+(segment_length*rep));
848  // TR << "adding loop in repeat propagation: " << loop.start()+(segment_length*rep) << std::endl;
849  repeat_loops->push_back(*newLoop);
850  }
851  }
852  }
853 */
854  if (!repeat_loops->empty() && !basic::options::option[basic::options::OptionKeys::remodel::no_jumps].user()){
855  f = protocols::forge::methods::fold_tree_from_loops(repeat_pose, *repeat_loops);
856  } else {
857  f.simple_tree(repeat_pose.total_residue());
858  }
859 
860  repeat_pose.fold_tree(f);
861 
862  for ( Loops::iterator l = repeat_loops->v_begin(), le = repeat_loops->v_end(); l != le; ++l ) {
863  Loop & loop = *l;
864  for (Size jxn=loop.start(); jxn <=loop.stop(); jxn++){
865  //std::cout << "fix junction at " << jxn << std::endl;
866  if (jxn != repeat_pose.total_residue()){
868  }
869  }
870  }
871 
872  //repeat_pose.dump_pdb("repeatPose_in_rep_propagate_setTree.pdb");
873 /* // repeat_generation sets up the foldtree correctly, even changin cutpoint
874  * in foldtree doesn't require jump update
875  //take the jumps and set repeating RT
876  Size jump_offset = pose.num_jump();
877  for (Size rep = 1; rep < repeat_number; rep++){
878  for (Size i = 1; i<= pose.num_jump(); i++){
879  numeric::xyzMatrix< Real > Rot = pose.jump(i).get_rotation();
880  numeric::xyzVector< Real > Trx = pose.jump(i).get_translation();
881  // TR << "set ROT-TRANS from " << i << " to " << i+jump_offset*rep << std::endl;
882  Jump tempJump = repeat_pose.jump(i+(jump_offset*rep));
883  tempJump.set_rotation( Rot );
884  tempJump.set_translation( Trx );
885  repeat_pose.conformation().set_jump( i+(jump_offset*rep), tempJump );
886  }
887  }
888  //check tree:
889  //TR << f << std::endl;
890 */
891  //repeat_pose.dump_pdb("repeatPose_in_rep_propagate_setJump.pdb");
892 
893  //take care of the start if build across jxn
894  if (build_across_jxn){
895  while (residues_beyond_jxn){
896  pose.set_phi(residues_beyond_jxn, pose.phi(residues_beyond_jxn+segment_length));
897  pose.set_psi(residues_beyond_jxn, pose.psi(residues_beyond_jxn+segment_length));
898  pose.set_omega(residues_beyond_jxn, pose.omega(residues_beyond_jxn+segment_length));
899  residues_beyond_jxn--;
900  }
901  }
902 
903 
904  for (Size rep = 0; rep < repeat_number; rep++){
905  for (Size res = 1; res <= segment_length; res++){
906  //std::cout << "DEBUG: res+segmentlength*rep = " << res+(segment_length*rep) << std::endl;
907  Real loop_phi = 0;
908  Real loop_psi = 0;
909  if (res == 1 ){
910  loop_phi = pose.phi(segment_length+1);
911  loop_psi = pose.psi(segment_length+1);
912  } else {
913  loop_phi = pose.phi(res);
914  loop_psi = pose.psi(res);
915  }
916 
917  repeat_pose.set_phi(res+( segment_length*rep), loop_phi );
918  repeat_pose.set_psi(res+( segment_length*rep), loop_psi );
919  repeat_pose.set_omega( res+(segment_length*rep), pose.omega(res) );
920  }
921  }
922 
923  //repeat_pose.dump_pdb("repeatPose_in_rep_propagate_setAngle.pdb");
924  //loop over the tail fragment to the first fragment
925 
926 
927  //pose = repeat_pose;
928  //pose.dump_pdb("test_repeat1.pdb");
929  //repeat_pose.dump_pdb("repeat2.pdb");
930 /*
931  for (int i =1; i<= repeat_pose.total_residue(); i++){
932  std::cout << "repeat_pose Phi: "<< repeat_pose.phi(i) << " psi: " << repeat_pose.psi(i) << " omega: " << repeat_pose.omega(i) << " at " << i << std::endl;
933  } */
934 }
935 
936 
937 /// @brief apply defined moves to given Pose
938 /// @remarks Sets protocols::moves::MS_SUCCESS upon successful closure of
939 /// all loops, otherwise sets protocols::moves::FAIL_RETRY.
941 
942  using namespace basic::options;
943  using namespace core::scoring::constraints;
947 
948  // archive
949  FoldTree const archive_ft = pose.fold_tree();
950  //std::cout << "archived foldtree " << archive_ft << std::endl;
951 
952  FoldTree sealed_ft;
955  } else {
956  sealed_ft = fold_tree_from_pose( pose, pose.fold_tree().root(), MoveMap() ); // used during structure accumulation
957  }
958  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
960 
961  //take care of constraints:
962 
963  //user defined constraint from file, make sure to do this first as it
964  //replaces cst object in pose and that wipes out everything already set.
965 
966  //only use this type of cst file in this case
967  if (basic::options::option[ OptionKeys::constraints::cst_file ].user()){
968 
970  repeat_constraint->apply( repeat_pose_ );
971  }
972 /*
973  // ResidueTypeLinkingConstraints
974  Size repeat_number = basic::options::option[ OptionKeys::remodel::repeat_structure];
975  Real bonus = 10;
976  //std::cout << "RESIDUETYPELINKING CST" << std::endl;
977  Size segment_length = (repeat_pose_.n_residue())/repeat_number;
978  for (Size rep = 1; rep < repeat_number; rep++ ){ // from 1 since first segment don't need self-linking
979  for (Size res = 1; res <= segment_length; res++){
980  repeat_pose_.add_constraint( new ResidueTypeLinkingConstraint(repeat_pose_, res, res+(segment_length*rep), bonus));
981  // std::cout << res << " " << res+(segment_length*rep) << std::endl;
982  }
983  }
984  */
985 /*
986  std::stringstream templateRangeSS;
987  templateRangeSS << "1-" << segment_length;
988 
989  //Dihedral (NCS) Constraints
990  //std::cout << "NCS CST" << std::endl;
991  protocols::simple_moves::symmetry::SetupNCSMover setup_ncs;
992  for (Size rep = 1; rep < repeat_number; rep++){ // from 1 since first segment don't need self-linking
993  std::stringstream targetSS;
994  targetSS << 1+(segment_length*rep) << "-" << segment_length + (segment_length*rep);
995  // std::cout << templateRangeSS.str() << " " << targetSS.str() << std::endl;
996 
997  setup_ncs.add_group(templateRangeSS.str(), targetSS.str());
998  }
999 */
1000 
1001 /* If want cyclize peptide in frag insertion, uncomment here. But in
1002  * practice, it seems to screw up more than helping. So currently do
1003  * fragment insertion without cyclizing pose, and only enforce this in
1004  * refinement stage
1005 
1006  if (option[OptionKeys::remodel::RemodelLoopMover::cyclic_peptide].user()){
1007  protocols::forge::methods::cyclize_pose(repeat_pose_);
1008  }
1009 */
1010 
1011  }
1012 
1013  // for accumulation of closed structures (only return the best)
1014  std::multimap< Real, PoseOP > accumulator;
1015 
1016  // setup parameters -- linearly scale the chainbreak weight
1017  Real const final_standard_cbreak_weight = 5.0;
1018  Real const cbreak_increment = final_standard_cbreak_weight / total_standard_cycles();
1019 
1020  // currently no scaling during boost_closure
1021  Real const final_boost_closure_cbreak_weight = 5.0;
1022  Real const boost_closure_cbreak_increment = ( final_boost_closure_cbreak_weight - final_standard_cbreak_weight ) / boost_closure_cycles();
1023 
1024  assert( final_boost_closure_cbreak_weight >= final_standard_cbreak_weight );
1025 
1026  // mark linear chainbreak in scoring function; this will be incremented
1027  // within simultaneous and independent stages
1028  ScoreFunctionOP sfxOP = sfx_;
1029  sfxOP->set_weight( core::scoring::linear_chainbreak, 0.0 );
1030 
1031  //REPEAT TEST
1032  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1033  sfxOP->set_weight(core::scoring::atom_pair_constraint, 1.0 * basic::options::option[ OptionKeys::remodel::repeat_structure] );
1034  }
1035 
1036  // randomize loops
1037  if( randomize_loops_ ) {
1038  randomize_stage( pose );
1039  (*sfxOP)( pose );
1040  } else {
1041  TR << "Randomize stage was skipped " << std::endl;
1042  }
1043 
1044  // setup monte carlo
1045  Real const temp = temperature_;
1046  MonteCarlo mc( *sfxOP, temp ); // init without pose
1047  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1048  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1049  (*sfxOP)(repeat_pose_);
1050  mc.reset(repeat_pose_);
1051  }
1052  else {
1053  mc.reset(pose);
1054  }
1055 
1056 
1057 
1058  for ( Size attempt = 1; attempt <= allowed_closure_attempts_; ++attempt ) {
1059  TR << "* closure_attempt " << attempt << std::endl;
1060 
1061  // reset score function at the beginning of each attempt
1062  mc.score_function( *sfxOP );
1063  if (basic::options::option[ OptionKeys::remodel::RemodelLoopMover::use_loop_hash].user()) {
1064  loophash_stage(pose, mc, cbreak_increment );
1065  }
1066 
1067  // simultaneous loop movements using fragment + ccd_move (default 20% of the time)
1068  simultaneous_stage( pose, mc, cbreak_increment );
1069 
1070  // closure is hard, so attempt closure for each loop independently using
1071  // fragment + ccd_move (default 80% of the time)
1072  independent_stage( pose, mc, cbreak_increment );
1073 
1074  // "boost": if any loops are not closed but within a chainbreak interval, attempt
1075  // to close them with 1-mer + ccd_move.
1076  boost_closure_stage( pose, mc, boost_closure_cbreak_increment );
1077 
1078  //pose.dump_pdb("test.pdb");
1079 
1080  // check to see if all loops closed, if so rescore w/out chainbreak
1081  // and store in accumulator
1082  if ( check_closure_criteria( pose ) ) {
1083  //make a pointer copy for storage, for REPEATs, store only the monomer
1084  //pose
1085  PoseOP pose_prime = new Pose( pose );
1086  pose_prime->fold_tree( sealed_ft );
1087 
1088  //this is for scoring in repeat context
1089  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1090  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1091  (*sfxOP)(repeat_pose_);
1092 
1093  //this has to be set because when copying to pose_prime, it lost the
1094  //first phi angle
1095  pose_prime->set_phi(1, repeat_pose_.phi(1));
1096 
1097  accumulator.insert( std::make_pair( repeat_pose_.energies().total_energy(), pose_prime ) );
1098  } else {
1099  (*sfxOP)( *pose_prime );
1100  accumulator.insert( std::make_pair( pose_prime->energies().total_energy(), pose_prime ) );
1101  }
1102 
1103  // now randomize the loops again for a new starting point
1104  if ( attempt < allowed_closure_attempts_ ) {
1105  randomize_stage( pose );
1106  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1107  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1108  (*sfxOP)(repeat_pose_);
1109  mc.reset( repeat_pose_ );
1110  } else{
1111  mc.reset( pose);
1112  }
1113  }
1114  } else {
1115  // Still broken, so perform a random smallest-mer insertion into each
1116  // loop before cycling again, otherwise too easy for the trajectory to
1117  // get trapped.
1118 
1119  insert_random_smallestmer_per_loop( pose, true );
1120  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1121  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1122  (*sfxOP)(repeat_pose_);
1123  mc.reset( repeat_pose_ );
1124  } else{
1125  mc.reset( pose);
1126  }
1127  }
1128 
1129 // std::ostringstream ss;
1130 // ss << "rlm." << attempt << ".";
1131 // JobDistributor::get_instance()->job_outputter()->other_pose(
1132 // JobDistributor::get_instance()->current_job(),
1133 // pose,
1134 // ss.str()
1135 // );
1136  }
1137 
1138  TR << "* " << accumulator.size() << " / " << allowed_closure_attempts_ << " closed / attempts " << std::endl;
1139 
1140  // return the best structure if available, otherwise mark failure
1141  if ( !accumulator.empty() ) {
1142  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1143  pose = *( accumulator.begin()->second );
1144  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1145  (*sfxOP)(repeat_pose_);
1146  pose = repeat_pose_;
1147  } else {
1148  pose = *( accumulator.begin()->second );
1149  }
1150 
1152  } else {
1153 
1154  // if use bypass_closure flag, all failure is passed as success. the
1155  // problem is that the subsequent restore_sidechain function won't know if
1156  // it's fail or success. although it doesn't matter if simply
1157  // bypass_closure, it is a problem when we use lh_filter for testing the
1158  // likeliness of a backbone structure. In this case, a failed criteria
1159  // should exit. otherwise the length would all be messed up. Since masking pose
1160  // as built successfully, pass it on as a repeat, not a monomer in this
1161  // case
1162 
1163  //but hold on.. the filter failure should be the only reason monomer is
1164  //passed on. so maybe we don't need to grow it afterall
1165  /*
1166  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user() && basic::options::option[ OptionKeys::remodel::bypass_closure].user()){
1167  pose = *( accumulator.begin()->second );
1168  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1169  (*sfxOP)(repeat_pose_);
1170  pose = repeat_pose_;
1171  }
1172  */
1174  if (basic::options::option[ OptionKeys::remodel::RemodelLoopMover::bypass_closure].user() &&
1175  basic::options::option[ OptionKeys::remodel::lh_filter_string].user()){
1176  //activates lh_filter for plausible backbone, in this case, a failed
1177  //loop should exit.
1178  TR << "fail in loop building: EXIT " << std::endl;
1179  exit(0);
1180  }
1181  }
1182 
1183  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1184  //do nothing?
1185  } else {
1186  // set original topology
1187  pose.fold_tree( archive_ft );
1188  }
1189 
1190 }
1191 
1194  return "RemodelLoopMover";
1195 }
1196 
1197 /// @brief randomize loops
1199 
1201 
1202  TR << "** randomize_stage" << std::endl;
1203 
1204  // archive
1205  FoldTree const archive_ft = pose.fold_tree();
1206 
1207  // simul movemap -- all loops moveable
1208  MoveMap movemap;
1209  mark_loops_moveable( loops_, movemap, true );
1210  enforce_false_movemap( movemap );
1211 
1212  // set appropriate topology
1213  if ( keep_input_foldtree_ ){
1214  }
1215  else {
1216  if ( core::pose::symmetry::is_symmetric( pose ) ) {
1219  pose.fold_tree( f_new );
1220  } else {
1222  }
1223  }
1224 
1225  // init fragment mover for each fragment set
1226  FragmentMoverOPs frag_movers = create_fragment_movers( movemap );
1227 
1228  Size const n_moveable = count_moveable_residues( movemap, 1, pose.n_residue() );
1229 
1230  // insert random number of fragments = n_frag_movers * moveable_residues
1231  for ( FragmentMoverOPs::iterator i = frag_movers.begin(), ie = frag_movers.end(); i != ie; ++i ) {
1232  for ( Size j = 0; j < n_moveable; ++j ) {
1233  (*i)->apply( pose );
1234  }
1235  }
1236 
1237  check_closure_criteria( pose, true );
1238 
1239  //return original foldtree
1240  pose.fold_tree(archive_ft);
1241 }
1242 
1243 
1244 /// @brief find the smallest fragment size and insert a single such
1245 /// smallmer into each loop; for breaking up trapped trajectories
1246 /// @param[in,out] pose The pose to modify.
1247 /// @param[in] only_broken_loop If true, only insert into broken loops,
1248 /// otherwise insert into all. (default true)
1250  Pose & pose,
1251  bool const only_broken_loops
1252 )
1253 {
1255  using namespace basic::options;
1256 
1257  // determine the right set of loops to insert fragments
1258  loops::LoopsOP loops_to_model = new loops::Loops();
1259 
1260  if ( only_broken_loops ) {
1261  loops_to_model = determine_loops_to_model( pose );
1262  } else {
1263  loops_to_model = loops_;
1264  }
1265 
1266  // set appropriate topology
1267  if ( keep_input_foldtree_ ){
1268  }
1269  else {
1270  if ( core::pose::symmetry::is_symmetric( pose ) ) {
1272  protocols::loops::fold_tree_from_loops( pose, *loops_to_model, f_new );
1273  pose.fold_tree( f_new );
1274  } else {
1275  pose.fold_tree( protocols::forge::methods::fold_tree_from_loops( pose, *loops_to_model ) );
1276  }
1277  }
1278  // find the size of the smallest fragments
1279  Size smallestmer_size = ( *fragsets_.begin() )->max_frag_length();
1280  for ( FragSetOPs::const_iterator f = fragsets_.begin(), fe = fragsets_.end(); f != fe; ++f ) {
1281  smallestmer_size = std::min( smallestmer_size, (*f)->max_frag_length() );
1282  }
1283 
1284  // insert fragments
1285  FragmentMoverOPs frag_movers = create_per_loop_fragment_movers( loops_to_model, smallestmer_size );
1286 
1287  for ( FragmentMoverOPs::iterator i = frag_movers.begin(), ie = frag_movers.end(); i != ie; ++i ) {
1288  (*i)->apply( pose );
1289  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1290  //Pose temp_pose(pose);
1291  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1292  //pose = temp_pose;
1293  }
1294  }
1295 }
1296 
1297 
1298 //check for clashes based on atom distances
1299 //only check atoms in AtomID vector
1300 //should be way faster than calculating entire score
1301 bool
1303  core::pose::Pose const & pose,
1304  utility::vector1< core::id::AtomID > const check_atids,
1305  core::Real const clash_dist_cut
1306 )
1307 {
1308  using namespace core;
1309  Real const clash_dist2_cut( clash_dist_cut * clash_dist_cut );
1310  for( Size iatid = 1; iatid <= check_atids.size(); ++iatid ){
1311  Vector const at1_xyz( pose.xyz( check_atids[ iatid ] ) );
1312  for( Size res2 = 1; res2 <= pose.total_residue(); ++res2 ){
1313  for( Size at2 = 1; at2 <= pose.residue( res2 ).natoms(); ++at2 ){
1314  //skip virtual atoms!
1315  if( pose.residue( res2 ).atom_type( at2 ).lj_wdepth() == 0.0 ) continue;
1316  id::AtomID atid2( at2, res2 );
1317  //skip if atid2 is in check_atids
1318  bool skip_at2( false );
1319  for( Size jatid = 1; jatid <= check_atids.size(); ++jatid ){
1320  if( atid2 == check_atids[ jatid ] ){ skip_at2 = true; break; }
1321  }
1322  if( skip_at2 ) continue;
1323  Real const dist2( at1_xyz.distance_squared( pose.xyz( atid2 ) ) );
1324  if( dist2 < clash_dist2_cut ){
1325  //TR_unsat << "CLASH!: " << check_atids[ iatid ] << " - " << atid2 <<
1326  // " = " << dist2 << std::endl;
1327  return true;
1328  }
1329  }
1330  }
1331  }
1332  return false;
1333 }
1334 
1335 
1336 
1337 
1338 /// @brief independent stage: single loop movement prior to MC accept/reject
1340  Pose & pose,
1341  MonteCarlo & mc,
1342  Real const cbreak_increment
1343 )
1344 {
1347  using namespace basic::options;
1348  using namespace OptionKeys::remodel;
1349  using namespace protocols::loophash;
1350  using namespace numeric::geometry::hashing;
1353 
1354  TR << "** LoopHash_stage" << std::endl;
1355 
1356  Pose const constantPose(pose); //needed this because get_rt function for loophash doesn't honor the cut positions needed to build the loop.
1357 
1358  utility::vector1< std::string > filter_target = basic::options::option[ OptionKeys::remodel::lh_filter_string];
1359 
1360  // setup loops
1361  loops::LoopsOP loops_to_model = new loops::Loops();
1362 
1363  //find terminal loops and skip them; loophash can't handle terminal loops
1364  for ( Loops::const_iterator l = loops_->begin(), le = loops_->end(); l != le; ++l ) {
1365  bool skip_loop = false;
1366  if ( l->is_terminal( pose ) || l->start() == 1 ) {
1367  skip_loop = true;
1368  }
1369  if ( !skip_loop ) {
1370  loops_to_model->add_loop( *l );
1371  }
1372  }
1373 
1374  TR << " n_loops = " << loops_to_model->size() << std::endl;
1375 
1376  // if filter is used, make sure the number of strings specified agree with
1377  // num loops.
1378  if (basic::options::option[ OptionKeys::remodel::lh_filter_string].user()){
1379  runtime_assert(filter_target.size() == loops_to_model->size());
1380  }
1381 
1382  if ( loops_to_model->size() == 0 ) { // nothing to do...
1383  return;
1384  }
1385 
1386  utility::vector1<core::Size> loopsizes;
1387 
1388  //find the loopsize
1389 
1390  for ( Loops::iterator l = loops_to_model->v_begin(), le = loops_to_model->v_end(); l != le; ++l ) {
1391  Loop & loop = *l;
1392  Size db_to_use = loop.stop() - loop.start() + 2; // +2 for the strange way loophash RT is setup.
1393  loopsizes.push_back(db_to_use);
1394  }
1395 
1396  //test loophashing
1397  LoopHashLibraryOP loop_hash_library = new LoopHashLibrary ( loopsizes, 1, 0 );
1398 
1399  // parameters
1400  //Size const n_standard_cycles = total_standard_cycles();
1401  // Size const n_standard_cycles = 3;
1402  Size const max_outer_cycles = loophash_cycles();
1403  // Size const max_outer_cycles = 1;
1404 
1405  // per-loop frag + ccd_move
1406 
1407  Size loop_number = 1; // for lh_filter_string index
1408 
1409  for ( Loops::iterator l = loops_to_model->v_begin(), le = loops_to_model->v_end(); l != le; ++l, loop_number++ ) {
1410  Loop & loop = *l;
1411 
1412 
1413  //special: just for loophashing
1414  //loop.set_cut(loop.stop());
1415 /*
1416  //also need to update the private variable loops to the same cutpoint, otherwise the rest of the procedule will break
1417  // modify loops_ object with new cuts for loophasing modeling
1418  for ( Loops::iterator i = loops_->v_begin(), ie = loops_->v_end(); i != ie; ++i ) {
1419  Loop & private_loop = *i;
1420 
1421  if ( private_loop.start() == loop.start() && private_loop.stop() == loop.stop()) { //the matching loop
1422  private_loop.set_cut(loop.stop());
1423  }
1424  }
1425 */
1426  // alter cutpoint to one before the end of the loop (either direction,
1427  // based on option) if closure is bypassed. this is already set in VLB,
1428  // but reenforce here.
1429  if (option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
1430  // if (option[OptionKeys::remodel::RemodelLoopMover::force_cutting_N].user()){
1431  // loop.set_cut(loop.start()+1); //1 because remodel needs one residue flanking
1432  // }
1433  // else {
1434  // }
1435  }
1436 
1437  // movemap
1438  MoveMap movemap;
1439  mark_loop_moveable( loop, movemap, true );
1440  enforce_false_movemap( movemap );
1441 
1442  // fragment movers
1443  FragmentMoverOPs frag_movers = create_fragment_movers( movemap );
1444  assert( !frag_movers.empty() );
1445 
1446  // parameters
1447  //Size const n_moveable = count_moveable_residues( movemap, loop.start(), loop.stop() );
1448  //currently looping over all the hashed loops
1449  //Size const max_inner_cycles = std::max( static_cast< Size >( 50 ), 10 * n_moveable );
1450 
1451  // set appropriate topology
1452  if ( keep_input_foldtree_ ){
1453  }
1454  else {
1455  if ( core::pose::symmetry::is_symmetric( pose ) ) {
1457  } else {
1458  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1459  //do nothing. remake foldtree will destroy the pose when propagate across unconnected segments
1460  } else {
1462  }
1463  }
1464  }
1465 
1466  TR << pose.fold_tree() << std::endl;
1467 /*
1468 //save phi psi omega
1469  Real phi_temp = pose.phi(loop.stop()+1);
1470  Real psi_temp = pose.psi(loop.stop()+1);
1471  Real omega_temp = pose.omega(loop.stop()+1);
1472 
1473 
1474  //fix geometry for junction
1475  for (Size jxn=loop.start(); jxn <=loop.stop(); jxn++){
1476  // std::cout << "fix junction at " << jxn << std::endl;
1477  pose.conformation().insert_ideal_geometry_at_polymer_bond(jxn);
1478  }
1479 
1480  //set phi psi
1481 
1482  //fix phi psi at cut
1483  pose.set_phi(loop.stop(), phi_temp);
1484  pose.set_psi(loop.stop(), psi_temp);
1485  pose.set_omega(loop.stop(), omega_temp);
1486 
1487 */
1488 
1489  //pose.dump_pdb("fix_junction.pdb");
1490  // add cutpoint variants
1491  add_cutpoint_variants( pose );
1492  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1493  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1495  mc.reset(repeat_pose_);
1496  } else{
1497  mc.reset( pose );
1498  }
1499  // reset counters
1500  mc.reset_counters();
1501 
1502  Size loopsize = loopsizes[loop_number];
1503 
1504  loop_hash_library->load_mergeddb();
1505 
1506  //container for the actual fragments to use
1507  std::vector < BackboneSegment > bs_vec_;
1508 
1509  const BackboneDB & bbdb_ = loop_hash_library->backbone_database();
1510 
1511  Real6 loop_transform;
1512 
1513  PoseOP pose_for_rt = new Pose();
1514 
1515  // for a pose carrying ligand, find the last peptide edge and only use the
1516  // peptide part
1517  using namespace core::chemical;
1518 
1519  Size max_res = 0;
1520  for (core::Size i = 1; i<= constantPose.total_residue(); i++){
1521  if (!constantPose.residue_type(i).is_ligand()){ //if not ligand, and assume ligand is always at the end!
1522  max_res = i;
1523  }
1524  }
1525  utility::vector1< core::Size > residue_indices;
1526  for(core::Size i = 1; i <= max_res; ++i){
1527  residue_indices.push_back(i);
1528  }
1529  ResidueTypeSetCAP residue_set(
1530  ChemicalManager::get_instance()->residue_type_set( CENTROID )
1531  );
1532  core::io::pdb::pose_from_pose(*pose_for_rt, constantPose, *residue_set, residue_indices);
1533 
1535  f.simple_tree(pose_for_rt->total_residue());
1536  pose_for_rt->fold_tree(f);
1537 
1538  //potentially throwing error if this step below doesn't pass
1539  //std::cout << "start " << loop.start() << " stop " << loop.stop() << std::endl;
1540  TR << "loophashing from " << loop.start()-1 << " to " << loop.stop()+1 << " using " << loop.stop()+1 - (loop.start()-1) << " residue loops." << std::endl;
1541 
1542  get_rt_over_leap_fast( *pose_for_rt, loop.start()-1, loop.stop()+1, loop_transform);
1543 
1544 /*
1545  std::cout << sqrt((loop_transform[1]* loop_transform[1]) + (loop_transform[2]*loop_transform[2]) + (loop_transform[3]*loop_transform[3])) << std::endl;
1546  std::cout << loop_transform[1] << std::endl;
1547  std::cout << loop_transform[2] << std::endl;
1548  std::cout << loop_transform[3] << std::endl;
1549  std::cout << loop_transform[4] << std::endl;
1550  std::cout << loop_transform[5] << std::endl;
1551  std::cout << loop_transform[6] << std::endl;
1552 */
1553 
1554 
1555  BackboneSegment backbone_;
1556  LoopHashMap &hashmap = loop_hash_library->gethash(loopsize);
1557 
1558  Size lh_ex_limit = basic::options::option[ OptionKeys::remodel::lh_ex_limit];
1559  std::vector < core::Size > leap_index_list;
1560 
1561  TR << "radius = ";
1562  for (Size radius = 0; radius <= lh_ex_limit ; radius++ ){
1563  hashmap.radial_lookup( radius, loop_transform, leap_index_list );
1564  TR << radius << "... " << leap_index_list.size() << std::endl;
1565  if (leap_index_list.size() < 1000){ //making sure at least harvest one segment to build.
1566  continue;
1567  } else {
1568  break;
1569  }
1570  }
1571  TR << std::endl;
1572 
1573  //not doing shuffle for now
1574  //numeric::random::random_permutation( leap_index_list.begin(), leap_index_list.end(), RG );
1575 
1576  TR << "collected " << leap_index_list.size() << " fragments." << std::endl;
1577  Size lh_frag_count = leap_index_list.size();
1578  if (leap_index_list.size() == 0){
1579  exit(0);
1580  }
1581 
1582  for( std::vector < core::Size >::const_iterator itx = leap_index_list.begin(); itx != leap_index_list.end(); ++itx ){
1583  core::Size bb_index = *itx;
1584  LeapIndex cp = hashmap.get_peptide( bb_index );
1585  bbdb_.get_backbone_segment( cp.index, cp.offset , loopsize , backbone_ );
1586  bs_vec_.push_back( backbone_ );
1587  }
1588 
1589  if( bs_vec_.size() == 0 ) {
1590  TR << "No frags matched" << std::endl;
1591  }
1592  else {
1593  //output_pdb(bs_vec_, loopsize, out_path, utility::to_string(key[i]) + ".");
1594  }
1595 
1596  // do closure
1597  for ( Size outer = 1; outer <= max_outer_cycles; ++outer ) {
1598 
1599  // increment the chainbreak weight
1600  ScoreFunctionOP sfxOP = mc.score_function().clone();
1601  sfxOP->set_weight(
1603  sfxOP->get_weight( core::scoring::linear_chainbreak ) + cbreak_increment
1604  //sfxOP->get_weight( core::scoring::linear_chainbreak ) + 1
1605  );
1606 
1607  if (option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
1608  sfxOP->set_weight( core::scoring::linear_chainbreak, 0);
1609  }
1610 
1611  if (option[OptionKeys::remodel::RemodelLoopMover::cyclic_peptide].user()){
1612  sfxOP->set_weight(
1614  sfxOP->get_weight( core::scoring::atom_pair_constraint) + cbreak_increment
1615  );
1616  }
1617 
1618  if (option[OptionKeys::remodel::lh_cbreak_selection].user()){
1619  sfxOP->set_weight( core::scoring::linear_chainbreak, option[OptionKeys::remodel::lh_cbreak_selection]);
1620  }
1621 
1622  mc.score_function( *sfxOP );
1623 
1624  // recover low
1625  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1626  Size copy_size =0;
1627  if (basic::options::option[ OptionKeys::remodel::repeat_structure] == 1){
1628  copy_size = pose.total_residue()-1;
1629  } else {
1630  copy_size = pose.total_residue();
1631  }
1632  for (Size res = 1; res<=copy_size; res++){
1633  pose.set_phi(res,mc.lowest_score_pose().phi(res));
1634  pose.set_psi(res,mc.lowest_score_pose().psi(res));
1635  pose.set_omega(res,mc.lowest_score_pose().omega(res));
1636  }
1637  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1638  }
1639  else{
1640  pose = mc.lowest_score_pose();
1641  }
1642 
1643  // currently it seems the collection of loops aren't too many. So run through them all, or whatever cycle defined by n_standard_cycles
1644  //for ( Size inner = 1; inner <= 1; ++inner ) {
1645 
1646  // fragments
1647  for ( std::vector< BackboneSegment >::iterator i = bs_vec_.begin(), ie = bs_vec_.end(); i != ie; ++i) {
1648  //if ( loop.is_terminal( pose ) || RG.uniform() * n_standard_cycles > ( outer + simultaneous_cycles() ) || pose.fold_tree().num_cutpoint() == 0 ) {
1649 
1650  //again, no shuffling in early development stage
1651  //random_permutation( bs_vec_.begin(), bs_vec_.end(), RG );
1652 
1653  std::vector<core::Real> phi = (*i).phi();
1654  std::vector<core::Real> psi = (*i).psi();
1655  std::vector<core::Real> omega = (*i).omega();
1656  Size seg_length = (*i).length();
1657 
1658  //check sec. struct at stub.
1659  //Size idxresStart = (int)loop.start()-1; // this is terrible, due to the use of std:vector. i has to start from 0, but positions offset by 1.
1660  //Size idxresStop = (int)loop.start()-1+(seg_length-1); // this is terrible, due to the use of std:vector. i has to start from 0, but positions offset by 1.
1661  Size idxresStart = 0; // 0 means starting from the jump position!
1662  Size idxresStop = seg_length-1;
1663 
1664  //special case for DB's test
1666  std::string alphabet;
1667  std::string target = filter_target[loop_number];
1668  for (Size idx = idxresStart; idx <= idxresStop; idx++){
1669  alphabet += AM.index2symbol( AM.torsion2index(phi[idx],psi[idx], omega[idx],1));
1670  }
1671  runtime_assert(alphabet.length() == target.length());
1672  if ( alphabet.compare( target ) != 0 ){
1673  //std::cout << "lh frag at " << idxresStart << " and " << idxresStop << " not as " << target << ": " << alphabet << std::endl;
1674  lh_frag_count--;
1675  continue;
1676  }
1677 
1678 
1679 
1680  /*
1681  Pose test_segment;
1682  core::chemical::ResidueTypeSet const & rsd_set = (pose.residue(1).residue_type_set());
1683  core::conformation::ResidueOP new_rsd( core::conformation::ResidueFactory::create_residue( rsd_set.name_map("ALA") ) );
1684  for (Size i = 1; i<=14; i++){
1685  test_segment.append_residue_by_bond( *new_rsd, true );
1686  }
1687  for ( Size i = 1; i <= seg_length; i++){
1688  test_segment.set_phi( i, phi[i-1]);
1689  test_segment.set_psi( i, psi[i]);
1690  test_segment.set_omega( i, omega[i]);
1691  }
1692  (*i).apply_to_pose(test_segment,3);
1693  std::string name = "segment" + utility::to_string(j) + ".pdb";
1694  test_segment.dump_pdb(name);
1695  */
1696 
1697  //insert hashed loop segment: relic, in case insertion indexing should change.
1698  //pose.set_phi( loop.start()-1, phi[0]);
1699  //pose.set_psi( loop.start()-1, psi[0]);
1700  //pose.set_omega( loop.start()-1, omega[0]);
1701 
1702  for ( Size i = 0; i < seg_length; i++){
1703  Size ires = (int)loop.start()-1+i; // this is terrible, due to the use of std:vector. i has to start from 0, but positions offset by 1.
1704  if (ires > pose.total_residue() ) break;
1705  // std::cout << phi[i] << " " << psi[i] << " " << omega[i] << " " << ires << std::endl;
1706  pose.set_phi( ires, phi[i]);
1707  pose.set_psi( ires, psi[i]);
1708  pose.set_omega( ires, omega[i]);
1709  }
1710 /*
1711  //clash check ; currently don't do. not sure if this elimiates
1712  //valuable fragments
1713  utility::vector1< core::id::AtomID > clash_ids;
1714  for ( Size i = 1; i < seg_length-1; i++){ // this avoids the connecting res
1715  Size ires = (int)loop.start()-1+i;
1716  if (ires > pose.total_residue() ) break;
1717  for ( Size id = 1; id <= pose.residue(ires).natoms(); ++id){
1718  clash_ids.push_back( core::id::AtomID( id, ires));
1719  }
1720  }
1721 */
1722  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1723  // repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1724  // if (fast_clash_check( repeat_pose_, clash_ids, 2.0)){
1725  // continue;
1726  // }
1727  // else{
1728  // std::cout << "No clash!" << std::endl;
1729  for ( Size i = 0; i < seg_length; i++){
1730  Size ires = (int)loop.start()-1+i; // this is terrible, due to the use of std:vector. i has to start from 0, but positions offset by 1.
1731  if (ires > repeat_pose_.total_residue() ) break;
1732  // std::cout << phi[i] << " " << psi[i] << " " << omega[i] << " " << ires << std::endl;
1733  repeat_pose_.set_phi( ires, phi[i]);
1734  repeat_pose_.set_psi( ires, psi[i]);
1735  repeat_pose_.set_omega( ires, omega[i]);
1736  }
1737  repeat_sync( repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1738  //if (mc.boltzmann( repeat_pose_, "loophash" )){
1739 
1740  //pass every build through ccd for now
1741  if (!option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
1742  ccd_moves( 10, repeat_pose_, movemap, (int)loop.start(), (int)loop.stop(), (int)loop.cut() );
1743  }
1744  repeat_sync( repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1745  mc.boltzmann( repeat_pose_, "loop_hash-ccd");
1746  //} //if mc.boltzmann
1747  //}
1748  } else {
1749  for ( Size i = 0; i < seg_length; i++){
1750  Size ires = (int)loop.start()-1+i; // this is terrible, due to the use of std:vector. i has to start from 0, but positions offset by 1.
1751  if (ires > pose.total_residue() ) break;
1752  // std::cout << phi[i] << " " << psi[i] << " " << omega[i] << " " << ires << std::endl;
1753  pose.set_phi( ires, phi[i]);
1754  pose.set_psi( ires, psi[i]);
1755  pose.set_omega( ires, omega[i]);
1756  }
1757  //mc.boltzmann( pose, "loophash" );
1758  if (!option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
1759  ccd_moves( 10, pose, movemap, (int)loop.start(), (int)loop.stop(), (int)loop.cut() );
1760  }
1761  mc.boltzmann( pose, "loop_hash ccd");
1762  }
1763 
1764  } // inner_cycles hashed loops
1765  TR << "Sec struc filtered fragment count = " << lh_frag_count << std::endl;
1766  } // outer_cycles
1767 
1768  // recover low
1769  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1770  Size copy_size =0;
1771  if (basic::options::option[ OptionKeys::remodel::repeat_structure] == 1){
1772  copy_size = pose.total_residue()-1;
1773  } else {
1774  copy_size = pose.total_residue();
1775  }
1776  for (Size res = 1; res<=copy_size; res++){
1777  pose.set_phi(res,mc.lowest_score_pose().phi(res));
1778  pose.set_psi(res,mc.lowest_score_pose().psi(res));
1779  pose.set_omega(res,mc.lowest_score_pose().omega(res));
1780  //mc.lowest_score_pose().dump_pdb("independent_stage.pdb");
1781  }
1782  } else{
1783  pose = mc.lowest_score_pose();
1784  }
1785 
1786  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1787  mc.score_function().show( TR, repeat_pose_ );
1789  remove_cutpoint_variants( pose );
1790  } else {
1791  mc.score_function().show( TR, pose );
1792  remove_cutpoint_variants( pose );
1793  }
1794 
1795  TR << std::endl;
1796  mc.show_state();
1797 
1798  }// for each loop
1799  check_closure_criteria( pose, true );
1800 
1801 }
1802 
1803 
1804 /// @brief simultaneous stage: multiple loop movement prior to MC accept/reject
1806  Pose & pose,
1807  MonteCarlo & mc,
1808  Real const cbreak_increment
1809 )
1810 {
1812 
1813  using namespace basic::options;
1814  using namespace OptionKeys::remodel;
1818  using numeric::random::random_permutation;
1819 
1820  TR << "** simultaneous_stage" << std::endl;
1821 /*
1822  // setup loops
1823  loops::LoopsOP pre_loops_to_model = determine_loops_to_model( pose );
1824  loops::LoopsOP loops_to_model = new loops::Loops();
1825 
1826  // filter for non-terminal loops
1827  for ( Loops::const_iterator l = pre_loops_to_model->begin(), le = pre_loops_to_model->end(); l != le; ++l ) {
1828  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1829  //take out the terminal loop in repeat cases
1830  if ( !l->is_terminal( pose ) ) {
1831  loops_to_model->add_loop( *l );
1832  }
1833  }
1834  else {
1835  loops_to_model->add_loop( *l );
1836  }
1837  }
1838 */
1839  loops::LoopsOP loops_to_model = new loops::Loops(*loops_);
1840  TR << " n_loops = " << loops_to_model->size() << std::endl;
1841 
1842  if ( loops_to_model->size() == 0 ) { // nothing to do...
1843  return;
1844  }
1845 /*
1846  //as soon as the loops are determined. make sure they are geometrically sound
1847  for (Loops::iterator itr = loops_to_model->v_begin(), ie = loops_to_model->v_end(); itr!=ie; itr++){
1848  Loop &loop = *itr;
1849  for (Size jxn = loop.start(); jxn<=loop.stop(); jxn++){
1850  if (jxn != pose.total_residue()){ //can't get geometry at the end residue
1851  pose.conformation().insert_ideal_geometry_at_polymer_bond(jxn);
1852  }
1853  }
1854  }
1855 */
1856  //TR << "starting foldtree in SIMU stage " << pose.fold_tree() << std::endl;
1857 
1858  // Create fragment movers for each loop for each fragment set. We want
1859  // to allow an equal probability of movement per-loop, rather than
1860  // per-residue.
1861  FragmentMoverOPs frag_movers = create_per_loop_fragment_movers( loops_to_model );
1862  assert( !frag_movers.empty() );
1863 
1864  // set appropriate topology
1865  if ( keep_input_foldtree_ ){
1866  }
1867  else {
1868  if ( core::pose::symmetry::is_symmetric( pose ) ) {
1870  protocols::loops::fold_tree_from_loops( pose, *loops_to_model, f_new );
1871  pose.fold_tree( f_new );
1872  } else {
1873  pose.fold_tree( protocols::forge::methods::fold_tree_from_loops( pose, *loops_to_model ) );
1874  }
1875  }
1876 
1877  // add cutpoint variants
1878  if (pose.num_jump() >0){
1879  add_cutpoint_variants( pose );
1880  }
1881  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1882  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1883  if (repeat_pose_.num_jump()>0){
1885  }
1886  mc.reset(repeat_pose_);
1887  } else{
1888  mc.reset( pose );
1889  }
1890 
1891  // setup master movemap covering all loops -- used only for tracking purposes
1892  MoveMap movemap;
1893  mark_loops_moveable( loops_to_model, movemap, true );
1894  enforce_false_movemap( movemap );
1895 
1896  // parameters
1897  Size const n_moveable = count_moveable_residues( movemap, 1, pose.n_residue() );
1898  Size const n_standard_cycles = total_standard_cycles();
1899  Size const max_outer_cycles = simultaneous_cycles();
1900  Size const max_inner_cycles = std::max( 50 * loops_to_model->size(), 10 * n_moveable );
1901  bool apply_user_provided_movers( user_provided_movers_.size() != 0 );
1902 
1903  // reset counters
1904  mc.reset_counters();
1905 
1906  // simul frag + ccd_move
1907  for ( Size outer = 1; outer <= max_outer_cycles; ++outer ) {
1908  // increment the chainbreak weight
1909  ScoreFunctionOP sfxOP = mc.score_function().clone();
1910  sfxOP->set_weight(
1912  sfxOP->get_weight( core::scoring::linear_chainbreak ) + cbreak_increment
1913  );
1914 
1915  if (option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
1916  sfxOP->set_weight( core::scoring::linear_chainbreak, 0);
1917  }
1918  if (option[OptionKeys::remodel::RemodelLoopMover::cyclic_peptide].user()){
1919  // sfxOP->set_weight( core::scoring::linear_chainbreak, 0);
1920  sfxOP->set_weight( core::scoring::atom_pair_constraint, 0);//ramping from 0
1921  }
1922 
1923 
1924  mc.score_function( *sfxOP );
1925 
1926  // recover low
1927  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1928  Size copy_size =0;
1929  if (basic::options::option[ OptionKeys::remodel::repeat_structure] == 1){
1930  copy_size = pose.total_residue()-1;
1931  } else {
1932  copy_size = pose.total_residue();
1933  }
1934 
1935  for (Size res = 1; res<=copy_size; res++){
1936  pose.set_phi(res,mc.lowest_score_pose().phi(res));
1937  pose.set_psi(res,mc.lowest_score_pose().psi(res));
1938  pose.set_omega(res,mc.lowest_score_pose().omega(res));
1939  }
1940  }else{
1941  pose = mc.lowest_score_pose();
1942  }
1943 
1944  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1945  repeat_propagation( pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1946  }
1947 
1948  for ( Size inner = 1; inner <= max_inner_cycles; ++inner ) {
1949 
1950  if ( RG.uniform() * n_standard_cycles > outer || pose.fold_tree().num_cutpoint() == 0 ) {
1951  // fragments
1952  random_permutation( frag_movers.begin(), frag_movers.end(), RG );
1953  for ( FragmentMoverOPs::iterator i = frag_movers.begin(), ie = frag_movers.end(); i != ie; ++i ) {
1954  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1955  (*i)->apply( repeat_pose_ );
1956  repeat_sync( repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1957  mc.boltzmann( repeat_pose_, "simul_frag" );
1958  }else {
1959  (*i)->apply( pose );
1960  mc.boltzmann( pose, "simul_frag" );
1961  }
1962  }
1963  } else {
1964  // per-loop ccd
1965  random_permutation( loops_to_model->v_begin(), loops_to_model->v_end(), RG );
1966  for ( Loops::const_iterator l = loops_to_model->begin(), le = loops_to_model->end(); l != le; ++l ) {
1967  if ( !l->is_terminal( pose ) ) {
1968  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
1969  if (!option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
1970  ccd_moves( 10, repeat_pose_, movemap, (int)l->start(), (int)l->stop(), (int)l->cut() );
1971  }
1972  repeat_sync( repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
1973  mc.boltzmann( repeat_pose_, "ccd_move" );
1974  }else {
1975  if (!option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
1976  ccd_moves( 10, pose, movemap, (int)l->start(), (int)l->stop(), (int)l->cut() );
1977  }
1978  mc.boltzmann( pose, "ccd_move" );
1979  }
1980  }
1981  }
1982  }
1983 
1984  if( apply_user_provided_movers && ( inner % user_provided_movers_apply_cycle_ == 0 ) ){
1985  for( utility::vector1< moves::MoverOP >::iterator move_it( user_provided_movers_.begin() ); move_it != user_provided_movers_.end(); ++move_it ){
1986  (*move_it)->apply( pose );
1987  mc.boltzmann( pose, "user_provided_simul" );
1988  //if( inner % 50 == 0 ){
1989  // static Size simulposecount = 0;
1990  // simulposecount++;
1991  // pose.dump_pdb("simulstage"+utility::to_string( simulposecount )+".pdb" );
1992  //}
1993  }
1994  }
1995 
1996  } // inner_cycles
1997 
1998  } // outer_cycles
1999 
2000  // recover low
2001  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2002  Size copy_size =0;
2003  if (basic::options::option[ OptionKeys::remodel::repeat_structure] == 1){
2004  copy_size = pose.total_residue() - repeat_tail_length_;
2005  } else {
2006  copy_size = pose.total_residue();
2007  }
2008  for (Size res = 1; res<=copy_size; res++){
2009  pose.set_phi(res,mc.lowest_score_pose().phi(res));
2010  pose.set_psi(res,mc.lowest_score_pose().psi(res));
2011  pose.set_omega(res,mc.lowest_score_pose().omega(res));
2012  }
2013  }
2014  else{
2015  pose = mc.lowest_score_pose();
2016  }
2017 
2018  // report status
2019 // mc.score_function().show_line_headers( TR );
2020 // TR << std::endl;
2021 
2022  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2023 // mc.score_function().show_line( TR, repeat_pose_ );
2024  mc.score_function().show( TR, repeat_pose_ );
2026  TR << std::endl;
2027  mc.show_state();
2029  remove_cutpoint_variants( pose );
2030  } else {
2031  mc.score_function().show( TR, pose );
2032  TR << std::endl;
2033  mc.show_state();
2034  check_closure_criteria( pose, true );
2035  remove_cutpoint_variants( pose );
2036  }
2037 
2038 }
2039 
2040 
2041 /// @brief independent stage: single loop movement prior to MC accept/reject
2043  Pose & pose,
2044  MonteCarlo & mc,
2045  Real const cbreak_increment
2046 )
2047 {
2050  using namespace basic::options;
2051  using namespace OptionKeys::remodel;
2054 
2055  TR << "** independent_stage" << std::endl;
2056 
2057  // setup loops
2058  loops::LoopsOP pre_loops_to_model = determine_loops_to_model( pose );
2059  loops::LoopsOP loops_to_model = new loops::Loops();
2060 
2061  // filter for non-terminal loops
2062  for ( Loops::const_iterator l = pre_loops_to_model->begin(), le = pre_loops_to_model->end(); l != le; ++l ) {
2063  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2064  //take out the terminal loop in repeat cases
2065  if ( !l->is_terminal( pose ) ) {
2066  loops_to_model->add_loop( *l );
2067  }
2068  //however, need to address de novo building cases
2069  if (l->start() == 1 && l->stop() == pose.total_residue()){
2070  loops_to_model->add_loop( *l );
2071  }
2072  }
2073  else {
2074  loops_to_model->add_loop( *l );
2075  }
2076  }
2077 
2078  if (option[OptionKeys::remodel::no_jumps].user()){
2079  // if using no_jumps, chainbreak based loop determination will skip this stage, but we obviously wants to build something...
2080  loops_to_model = loops_;
2081  }
2082 /*
2083  //TEST 9/28/2012
2084  //find terminal loops and skip them; loophash can't handle terminal loops
2085  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2086  for ( Loops::const_iterator l = loops_->begin(), le = loops_->end(); l != le; ++l ) {
2087  bool skip_loop = false;
2088  if ( l->is_terminal( pose ) || l->start() == 1) {
2089  skip_loop = true;
2090  }
2091  if ( !skip_loop ) {
2092  loops_to_model->add_loop( *l );
2093  }
2094  }
2095  }
2096 */
2097  TR << " n_loops = " << loops_to_model->size() << std::endl;
2098 
2099  if ( loops_to_model->size() == 0 ) { // nothing to do...
2100  return;
2101  }
2102 
2103  // parameters
2104  Size const n_standard_cycles = total_standard_cycles();
2105  Size const max_outer_cycles = independent_cycles();
2106 
2107  // per-loop frag + ccd_move
2108  for ( Loops::iterator l = loops_to_model->v_begin(), le = loops_to_model->v_end(); l != le; ++l ) {
2109  Loop & loop = *l;
2110 
2111  // alter cutpoint to one before the end of the loop (either direction,
2112  // based on option) if closure is bypassed. this is already set in VLB,
2113  // but reenforce here.
2114  if (option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
2115  // if (option[OptionKeys::remodel::RemodelLoopMover::force_cutting_N].user()){
2116  // loop.set_cut(loop.start()+1); //1 because remodel needs one residue flanking
2117  // }
2118  // else {
2119  //loop.set_cut(loop.stop()-1); //1 because remodel needs one residue flanking
2120  // }
2121  }
2122 
2123  // movemap
2124  MoveMap movemap;
2125  mark_loop_moveable( loop, movemap, true );
2126  enforce_false_movemap( movemap );
2127 
2128  // fragment movers
2129  FragmentMoverOPs frag_movers = create_fragment_movers( movemap );
2130  assert( !frag_movers.empty() );
2131 
2132  // parameters
2133  Size const n_moveable = count_moveable_residues( movemap, loop.start(), loop.stop() );
2134  Size const max_inner_cycles = std::max( static_cast< Size >( 50 ), 10 * n_moveable );
2135  bool apply_user_provided_movers( user_provided_movers_.size() != 0 );
2136 
2137  // set appropriate topology
2138  if ( keep_input_foldtree_ ){
2139  }
2140  else {
2141  if ( core::pose::symmetry::is_symmetric( pose ) ) {
2143  } else {
2144  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2145  //do nothing. remake foldtree will destroy the pose when propagate across unconnected segments
2146  } else {
2148  }
2149  }
2150  }
2151 
2152  // add cutpoint variants
2153  add_cutpoint_variants( pose );
2154  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2155  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
2157  mc.reset(repeat_pose_);
2158  } else{
2159  mc.reset( pose );
2160  }
2161  // reset counters
2162  mc.reset_counters();
2163 
2164 
2165  // do closure
2166  for ( Size outer = 1; outer <= max_outer_cycles; ++outer ) {
2167  // increment the chainbreak weight
2168  ScoreFunctionOP sfxOP = mc.score_function().clone();
2169  sfxOP->set_weight(
2171  sfxOP->get_weight( core::scoring::linear_chainbreak ) + cbreak_increment
2172  );
2173 
2174  if (option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
2175  sfxOP->set_weight( core::scoring::linear_chainbreak, 0);
2176  }
2177 
2178  if (option[OptionKeys::remodel::no_jumps].user() && option[OptionKeys::remodel::two_chain_tree].user()){
2179  sfxOP->set_weight( core::scoring::linear_chainbreak, 0);
2180  }
2181 
2182  if (option[OptionKeys::remodel::RemodelLoopMover::cyclic_peptide].user()){
2183  // sfxOP->set_weight( core::scoring::linear_chainbreak, 0);
2184  sfxOP->set_weight(
2186  sfxOP->get_weight( core::scoring::atom_pair_constraint) + cbreak_increment
2187  );
2188  }
2189 
2190  mc.score_function( *sfxOP );
2191 
2192  // recover low
2193  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2194  Size copy_size =0;
2195  if (basic::options::option[ OptionKeys::remodel::repeat_structure] == 1){
2196  copy_size = pose.total_residue()-1;
2197  } else {
2198  copy_size = pose.total_residue();
2199  }
2200  for (Size res = 1; res<=copy_size; res++){
2201  pose.set_phi(res,mc.lowest_score_pose().phi(res));
2202  pose.set_psi(res,mc.lowest_score_pose().psi(res));
2203  pose.set_omega(res,mc.lowest_score_pose().omega(res));
2204  }
2205  }
2206  else{
2207  pose = mc.lowest_score_pose();
2208  }
2209 
2210  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2211  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]); }
2212 
2213  for ( Size inner = 1; inner <= max_inner_cycles; ++inner ) {
2214  // fragments
2215  if ( loop.is_terminal( pose ) || RG.uniform() * n_standard_cycles > ( outer + simultaneous_cycles() ) || pose.fold_tree().num_cutpoint() == 0 ) {
2216  random_permutation( frag_movers.begin(), frag_movers.end(), RG );
2217  for ( FragmentMoverOPs::iterator i = frag_movers.begin(), ie = frag_movers.end(); i != ie; ++i ) {
2218  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2219  (*i)->apply( repeat_pose_ );
2220  repeat_sync( repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
2221  mc.boltzmann( repeat_pose_, "frag" );
2222  }else {
2223  (*i)->apply( pose );
2224  mc.boltzmann( pose, "frag" );
2225  }
2226  }
2227  } else { // ccd
2228  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2229  if (!option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
2230  ccd_moves( 10, repeat_pose_, movemap, (int)loop.start(), (int)loop.stop(), (int)loop.cut() );
2231  }
2232  repeat_sync( repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
2233  mc.boltzmann( repeat_pose_, "ccd_move" );
2234  }else {
2235  if (!option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
2236  ccd_moves( 10, pose, movemap, (int)loop.start(), (int)loop.stop(), (int)loop.cut() );
2237  }
2238  mc.boltzmann( pose, "ccd_move" );
2239  }
2240  }
2241 
2242  if( apply_user_provided_movers && ( inner % user_provided_movers_apply_cycle_ == 0 ) ){
2243  for( utility::vector1< moves::MoverOP >::iterator move_it( user_provided_movers_.begin() ); move_it != user_provided_movers_.end(); ++move_it ){
2244  (*move_it)->apply( pose );
2245  mc.boltzmann( pose, "user_provided_indep" );
2246  //if( inner % 50 == 0 ){
2247  // static Size indepposecount = 0;
2248  // indepposecount++;
2249  // pose.dump_pdb("indepstage"+utility::to_string( indepposecount )+".pdb" );
2250  //}
2251  }
2252  }
2253 
2254  } // inner_cycles
2255 
2256  } // outer_cycles
2257 
2258  // recover low
2259  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2260  Size copy_size =0;
2261  if (basic::options::option[ OptionKeys::remodel::repeat_structure] == 1){
2262  copy_size = pose.total_residue()-1;
2263  } else {
2264  copy_size = pose.total_residue();
2265  }
2266  for (Size res = 1; res<=copy_size; res++){
2267  pose.set_phi(res,mc.lowest_score_pose().phi(res));
2268  pose.set_psi(res,mc.lowest_score_pose().psi(res));
2269  pose.set_omega(res,mc.lowest_score_pose().omega(res));
2270  }
2271  } else{
2272  pose = mc.lowest_score_pose();
2273  }
2274 
2275  // report status
2276  // mc.score_function().show_line_headers( TR );
2277 // TR << std::endl;
2278 
2279  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2280  // mc.score_function().show_line( TR, repeat_pose_ );
2281  mc.score_function().show( TR, repeat_pose_ );
2283  // repeat_pose_.dump_scored_pdb("checkRepeat2.pdb", mc.score_function());
2284  } else {
2285  mc.score_function().show( TR, pose );
2286  }
2287 
2288  TR << std::endl;
2289  mc.show_state();
2290 
2291  // remove cutpoints
2292  remove_cutpoint_variants( pose );
2293  }
2294 
2295  check_closure_criteria( pose, true );
2296 }
2297 
2298 
2299 /// @brief lock down stage: close loops within some threshold
2300 /// w/ smallest-mer (typically 1-mer) + ccd_move only
2301 /// @details This stage differs from simultaneous_stage() and independent_stage()
2302 /// in that once a loop is closed, it breaks out of the closure cycle and goes
2303 /// to the next one. The rationale is that once we hit the boost_closure_stage()
2304 /// we are desperate to close the loop, so we sacrifice diversity and instead
2305 /// just seek a closed solution.
2307  Pose & pose,
2308  MonteCarlo & mc,
2309  Real const cbreak_increment
2310 )
2311 {
2312  // Notes: the current implementation of boost_closure_stage() differs somewhat
2313  // from the equivalent, original "boost" stage within ++Remodel/EpiGraft.
2314  // In the old implementation, the boost cycles continued the
2315  // independent_stage(). As a result, the % time spent in fragment insertion
2316  // vs ccd continued to drop until the procedure was basically only doing
2317  // ccd when the total number of cycles reached 100. In addition, the
2318  // chainbreak weight continued to increment until it reached 50 (at total
2319  // cycle 100).
2321 
2324  using namespace basic::options;
2325  using namespace OptionKeys::remodel;
2328 
2329  TR << "** boost_closure_stage" << std::endl;
2330 
2331  // setup loops
2332  loops::LoopsOP pre_loops_to_model = determine_loops_to_model( pose );
2333  loops::LoopsOP loops_to_model = new loops::Loops();
2334 
2335  // filter for non-terminal loops that are within tolerance
2336  Real const cbreak_tolerance = 1.0;
2337  for ( Loops::const_iterator l = pre_loops_to_model->begin(), le = pre_loops_to_model->end(); l != le; ++l ) {
2338  if ( !l->is_terminal( pose ) || l->start() != 1 ) {
2339  Real const cbreak = linear_chainbreak( pose, l->cut() );
2340  if ( cbreak < cbreak_tolerance ) {
2341  loops_to_model->add_loop( *l );
2342  }
2343  else if (cbreak >= cbreak_tolerance ){
2344  TR << "at least one loop is beyond tolerance" << std::endl;
2345  return;
2346  }
2347  }
2348  }
2349 
2350  TR << " n_loops = " << loops_to_model->size() << std::endl;
2351  if ( loops_to_model->size() == 0 ) { // nothing to do...
2352  return;
2353  }
2354 
2355  // find the size of the smallest fragments
2356  Size smallestmer_size = ( *fragsets_.begin() )->max_frag_length();
2357  for ( FragSetOPs::const_iterator f = fragsets_.begin(), fe = fragsets_.end(); f != fe; ++f ) {
2358  smallestmer_size = std::min( smallestmer_size, (*f)->max_frag_length() );
2359  }
2360  TR << "** boost_closure stage: using fragment size = " << smallestmer_size << std::endl;
2361 
2362  // Parameters. Note that fragments often get rejected at this stage, so
2363  // recommend keeping the number of insertions low and the number of ccd_move
2364  // high.
2365  Size const max_outer_cycles = boost_closure_cycles();
2366  Real const frag_mover_probability = 0.25; // do 1-mer insertions only 25% of the time
2367 
2368  // 1-mer frag + ccd_move
2369  for ( Loops::const_iterator l = loops_to_model->begin(), le = loops_to_model->end(); l != le; ++l ) {
2370  Loop const & loop = *l;
2371 
2372  // movemap
2373  MoveMap movemap;
2374  mark_loop_moveable( loop, movemap, true );
2375  enforce_false_movemap( movemap );
2376 
2377  // prepare smallest-mer fragment movers
2378  FragmentMoverOPs frag1_movers = create_fragment_movers( movemap, smallestmer_size );
2379 
2380  // parameters
2381  Size const n_moveable = count_moveable_residues( movemap, loop.start(), loop.stop() );
2382  Size const max_inner_cycles = std::max( static_cast< Size >( 50 ), 10 * n_moveable );
2383 
2384  // set appropriate topology
2385  if ( keep_input_foldtree_){
2386  }
2387  else {
2388  if ( core::pose::symmetry::is_symmetric( pose ) ) {
2390  } else {
2391  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2392  //do nothing. remake foldtree will destroy the pose when propagate across unconnected segments
2393  } else {
2395  }
2396  }
2397  }
2398  // add cutpoint variants
2399  add_cutpoint_variants( pose );
2400  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2401  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
2403  mc.reset(repeat_pose_);
2404  } else{
2405  mc.reset( pose );
2406  }
2407 
2408  // reset counters
2409  mc.reset_counters();
2410 
2411 
2412  // do closure
2413  for ( Size outer = 1; outer <= max_outer_cycles; ++outer ) {
2414  // increment the chainbreak weight
2415  ScoreFunctionOP sfxOP = mc.score_function().clone();
2416  sfxOP->set_weight(
2418  sfxOP->get_weight( core::scoring::linear_chainbreak ) + cbreak_increment
2419  );
2420 
2421  if (option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
2422  sfxOP->set_weight( core::scoring::linear_chainbreak, 0);
2423  }
2424 
2425  if (option[OptionKeys::remodel::RemodelLoopMover::cyclic_peptide].user()){
2426  // sfxOP->set_weight( core::scoring::linear_chainbreak, 0);
2427  sfxOP->set_weight(
2429  sfxOP->get_weight( core::scoring::atom_pair_constraint) + cbreak_increment
2430  );
2431  }
2432 
2433  mc.score_function( *sfxOP );
2434 
2435  // recover low
2436  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2437  Size copy_size =0;
2438  if (basic::options::option[ OptionKeys::remodel::repeat_structure] == 1){
2439  copy_size = pose.total_residue()-1;
2440  } else {
2441  copy_size = pose.total_residue();
2442  }
2443  for (Size res = 1; res<=copy_size; res++){
2444  pose.set_phi(res,mc.lowest_score_pose().phi(res));
2445  pose.set_psi(res,mc.lowest_score_pose().psi(res));
2446  pose.set_omega(res,mc.lowest_score_pose().omega(res));
2447  }
2448  } else {
2449  pose = mc.lowest_score_pose();
2450  }
2451 
2452  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2453  repeat_propagation(pose, repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
2454  }
2455 
2456  // Going into the boost_closure stage implies we are "desperate" to close
2457  // the loop and don't care about diversity anymore, so continue to
2458  // cycle only until the loop is closed.
2459  if ( linear_chainbreak( pose, loop.cut() ) <= max_linear_chainbreak_ ) {
2460  break;
2461  }
2462 
2463  for ( Size inner = 1; inner <= max_inner_cycles; ++inner ) {
2464  if ( (!frag1_movers.empty() && RG.uniform() < frag_mover_probability) || pose.fold_tree().num_cutpoint() == 0 ) { // 1-mer insertions
2465 
2466  random_permutation( frag1_movers.begin(), frag1_movers.end(), RG );
2467  for ( FragmentMoverOPs::iterator i = frag1_movers.begin(), ie = frag1_movers.end(); i != ie; ++i ) {
2468  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2469  (*i)->apply( repeat_pose_ );
2470  repeat_sync(repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
2471  mc.boltzmann( repeat_pose_, "frag1" );
2472  }
2473  else{
2474  (*i)->apply( pose );
2475  mc.boltzmann( pose, "frag1" );
2476  }
2477  }
2478 
2479  } else { // ccd_move
2480  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2481  if (!option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
2482  ccd_moves( 10, repeat_pose_, movemap, (int)loop.start(), (int)loop.stop(), (int)loop.cut() );
2483  }
2484  repeat_sync( repeat_pose_, basic::options::option[ OptionKeys::remodel::repeat_structure]);
2485  mc.boltzmann( repeat_pose_, "frag1" );
2486  } else {
2487  if (!option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
2488  ccd_moves( 10, pose, movemap, (int)loop.start(), (int)loop.stop(), (int)loop.cut() );
2489  }
2490  mc.boltzmann( pose, "ccd_move" );
2491  }
2492  }
2493  } // inner_cycles
2494 
2495  } // outer_cycles
2496 
2497  // recover low
2498  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2499  Size copy_size =0;
2500  if (basic::options::option[ OptionKeys::remodel::repeat_structure] == 1){
2501  copy_size = pose.total_residue()-1;
2502  } else {
2503  copy_size = pose.total_residue();
2504  }
2505  for (Size res = 1; res<=copy_size; res++){
2506  pose.set_phi(res,mc.lowest_score_pose().phi(res));
2507  pose.set_psi(res,mc.lowest_score_pose().psi(res));
2508  pose.set_omega(res,mc.lowest_score_pose().omega(res));
2509  }
2510  } else{
2511  pose = mc.lowest_score_pose();
2512  }
2513 
2514 
2515  // report status
2516  // mc.score_function().show_line_headers( TR );
2517 // TR << std::endl;
2518 
2519  if (basic::options::option[ OptionKeys::remodel::repeat_structure].user()){
2520  // mc.score_function().show_line( TR, repeat_pose_ );
2521  mc.score_function().show( TR, repeat_pose_ );
2523  // repeat_pose_.dump_scored_pdb("checkRepeat3.pdb", mc.score_function());
2524  } else {
2525  mc.score_function().show( TR, pose );
2526  }
2527 
2528  TR << std::endl;
2529  mc.show_state();
2530 
2531  // remove cutpoint variants
2532  remove_cutpoint_variants( pose );
2533  }
2534 
2535  check_closure_criteria( pose, true );
2536 }
2537 
2538 
2539 /// @brief determine which loops need modeling wrt to given Pose
2540 /// @remarks Skips closed loops and shuffles the order of the remaining
2541 /// loops.
2544 
2545  loops::LoopsOP loops_to_model = new loops::Loops();
2546 
2547  for ( Loops::const_iterator l = loops_->begin(), le = loops_->end(); l != le; ++l ) {
2548  bool skip_loop = false;
2549  /*
2550  std::cout << "loop_ start " << l->start() << " loop_ end" << l->stop() << " loop_ cut " << l->cut() << std::endl;
2551  std::cout << "linear chainbreak " << linear_chainbreak( pose, l->cut() ) << std::endl;
2552  std::cout << "eval: linear_chainbreak( pose, l->cut() ) <= max_linear_chainbreak_ " << ( linear_chainbreak( pose, l->cut() ) <= max_linear_chainbreak_ ) << std::endl;
2553  */
2554  if ( !l->is_terminal( pose ) ) {
2555  skip_loop |= ( linear_chainbreak( pose, l->cut() ) <= max_linear_chainbreak_ ); // loop already closed?
2556  }
2557 
2558  if ( !skip_loop ) {
2559  loops_to_model->add_loop( *l );
2560  }
2561  }
2562 
2563  // shuffle the order
2564  random_permutation( loops_to_model->v_begin(), loops_to_model->v_end(), RG );
2565 
2566  return loops_to_model;
2567 }
2568 
2569 
2570 /// @brief check all loops for closure criteria
2571 /// @param[in] pose The pose being checked.
2572 /// @param[in] show_in_tracer Output state of each loop to tracer?
2573 /// @return true if all criteria pass, false otherwise
2575  Pose & pose,
2576  bool const show_in_tracer
2577 )
2578 {
2580  using namespace basic::options;
2581  using namespace OptionKeys::remodel;
2582 
2583  boost::format fmt( "%|5t|%1% %|5t|%2% %|5t|%3% %|8t|%4%" );
2584 
2585  //breakout case if we don't care if the loops are closed
2586  if (option[OptionKeys::remodel::RemodelLoopMover::bypass_closure].user()){
2587  //special case for DB, filtering on close RMS with loophash
2588  //only trigger if lh_closure_filter is used before evaluation
2589  if (option[OptionKeys::remodel::lh_closure_filter].user()){
2590  TR << "using cbreak filter under bypass_closure." << std::endl;
2591  bool all_loops_pass = true;
2592  for ( Loops::const_iterator l = loops_->begin(), le = loops_->end(); l != le; ++l ) {
2593  Real cbreak = 0.0;
2594  if ( !l->is_terminal( pose ) ) {
2595  cbreak = linear_chainbreak( pose, l->cut() );
2596  TR << "chain break " << cbreak << std::endl;
2597  all_loops_pass &= ( cbreak <= max_linear_chainbreak_ );
2598  }
2599 
2600  if ( show_in_tracer ) {
2601  TR << fmt % l->start() % l->stop() % l->cut() % cbreak << std::endl;
2602  }
2603  }
2604  return all_loops_pass;
2605  }
2606  else {
2607  return true;
2608  }
2609  }
2610 
2611  // boost::format here does not appear to be doing what I want it to do...
2612  // The format string is probably borked.
2613  if ( show_in_tracer ) {
2614  TR << fmt % "start" % "stop" % "cut" % "cbreak" << std::endl;
2615  }
2616 
2617  bool all_loops_pass = true;
2618 
2619  for ( Loops::const_iterator l = loops_->begin(), le = loops_->end(); l != le; ++l ) {
2620  Real cbreak = 0.0;
2621  if ( !l->is_terminal( pose ) ) {
2622  cbreak = linear_chainbreak( pose, l->cut() );
2623  all_loops_pass &= ( cbreak <= max_linear_chainbreak_ );
2624  }
2625 
2626  if ( show_in_tracer ) {
2627  TR << fmt % l->start() % l->stop() % l->cut() % cbreak << std::endl;
2628  }
2629  }
2630 
2631  return all_loops_pass;
2632 }
2633 
2634 
2635 /// @brief return fragment movers for the list of internally kept fragment sets
2636 /// @param[in] movemap Use this movemap when initializing fragment movers.
2637 /// @param[in] largest_frag_size Only use fragment sets whose largest fragment
2638 /// size is this number. If zero, uses all fragment sets.
2641  MoveMap const & movemap,
2642  Size const largest_frag_size
2643 )
2644 {
2646 
2647  FragmentMoverOPs frag_movers;
2648  for ( FragSetOPs::const_iterator f = fragsets_.begin(), fe = fragsets_.end(); f != fe; ++f ) {
2649 
2650  if ( largest_frag_size == 0 || (*f)->max_frag_length() <= largest_frag_size ) {
2651  ClassicFragmentMoverOP cfm = new ClassicFragmentMover( *f, movemap.clone() );
2652  cfm->set_check_ss( false );
2653  cfm->enable_end_bias_check( false );
2654  frag_movers.push_back( cfm );
2655  }
2656 
2657  }
2658 
2659  return frag_movers;
2660 }
2661 
2662 
2663 /// @brief append fragment movers for the list of internally kept fragment sets
2664 /// @param[in] movemap Use this movemap when initializing fragment movers.
2665 /// @param[out] frag_movers Append fragment movers to this list.
2666 /// @param[in] largest_frag_size Only use fragment sets whose largest fragment
2667 /// size is this number. If zero, uses all fragment sets.
2669  MoveMap const & movemap,
2670  FragmentMoverOPs & frag_movers,
2671  Size const largest_frag_size
2672 ) {
2674 
2675  for ( FragSetOPs::const_iterator f = fragsets_.begin(), fe = fragsets_.end(); f != fe; ++f ) {
2676 
2677  if ( largest_frag_size == 0 || (*f)->max_frag_length() <= largest_frag_size ) {
2678  ClassicFragmentMoverOP cfm = new ClassicFragmentMover( *f, movemap.clone() );
2679  cfm->set_check_ss( false );
2680  cfm->enable_end_bias_check( false );
2681  frag_movers.push_back( cfm );
2682  }
2683 
2684  }
2685 }
2686 
2687 
2688 /// @brief create per-loop fragment movers: 1 fragment mover for each loop (uses
2689 /// movemaps to lock down non-loop residues)
2690 /// @param[in] loops The loops to use.
2691 /// @param[in] largest_frag_size Only use fragment sets whose largest fragment
2692 /// size is this number. If zero, uses all fragment sets.
2694  loops::LoopsOP const loops,
2695  Size const largest_frag_size
2696 )
2697 {
2698  // Create fragment movers for each loop for each fragment set. Here we
2699  // want to allow an equal probability of movement per-loop, rather than
2700  // per-residue.
2701  FragmentMoverOPs frag_movers;
2702  for ( Loops::const_iterator l = loops->begin(), le = loops->end(); l != le; ++l ) {
2703  MoveMap mm;
2704  mark_loop_moveable( *l, mm, true );
2705  enforce_false_movemap( mm );
2706  create_fragment_movers( mm, frag_movers, largest_frag_size );
2707  }
2708 
2709  return frag_movers;
2710 }
2711 
2712 
2713 /// @brief enforce settings in the false movemap
2715  // enforce everything in the false movemap
2716  movemap.import_false( false_movemap_ );
2717 }
2718 
2719 
2720 /// @brief mark bb/chi torsions of multiple loops moveable in a movemap
2721 /// @param[in] loops The loops to use.
2722 /// @param[out] movemap The movemap to modify.
2723 /// @param[in] allow_omega Allow bb omega to move? (should be yes when
2724 /// doing either fragment insertion or scoring function has omega
2725 /// tether, otherwise should probably be no)
2727  loops::LoopsOP const loops,
2728  MoveMap & movemap,
2729  bool const allow_omega
2730 )
2731 {
2732  for ( Loops::const_iterator l = loops->begin(), le = loops->end(); l != le; ++l ) {
2733  mark_loop_moveable( *l, movemap, allow_omega );
2734  }
2735 }
2736 
2737 
2738 /// @brief mark bb/chi torsion of a single loop moveable in movemap
2739 /// @param[in] loops The loop to use.
2740 /// @param[out] movemap The movemap to modify.
2741 /// @param[in] allow_omega Allow bb omega to move? (should be yes when
2742 /// doing either fragment insertion or scoring function has omega
2743 /// tether, otherwise should probably be no)
2745  Loop const & loop,
2746  MoveMap & movemap,
2747  bool const allow_omega
2748 )
2749 {
2750  using core::id::BB;
2752  using core::id::TorsionID;
2753 
2754  for ( Size i = loop.start(), ie = loop.stop(); i <= ie; ++i ) {
2755  movemap.set_bb( i, true );
2756  movemap.set_chi( i, true );
2757 
2758  if ( !allow_omega ) {
2759  movemap.set( TorsionID( i, BB, omega_torsion ), false );
2760  }
2761  }
2762 }
2763 
2764 
2765 /// @brief count number of residues with moveable backbone torsions in the
2766 /// given range [left, right]
2768  MoveMap const & movemap,
2769  Size const left,
2770  Size const right
2771 )
2772 {
2773  Size n_moveable = 0;
2774 
2775  // Count total number of residues w/ moveable backbone in movemap.
2776  // Depending on types of fragments (possible non-backbone?) consider
2777  // changing this in the future to check chi/other dof as well.
2778  for ( Size i = left; i <= right; ++i ) {
2779  if ( movemap.get_bb( i ) ) {
2780  ++n_moveable;
2781  }
2782  }
2783 
2784  return n_moveable;
2785 }
2786 
2787 /// @brief parse xml
2788 void
2790  TagPtr const tag,
2791  DataMap & data,
2792  Filters_map const &,
2793  Movers_map const &,
2794  Pose const & pose )
2795 {
2796  typedef utility::vector1< String > StringVec;
2797  using utility::string_split;
2799 
2800  // set score function
2801  String const sfxn ( tag->getOption<String>( "scorefxn", "" ) );
2802  if( sfxn != "" ) {
2803  sfx_ = data.get< ScoreFunction * >( "scorefxns", sfxn );
2804  TR << "score function, " << sfxn << ", is used. " << std::endl;
2805  }
2806 
2807  // set loops
2808  String const loops_string ( tag->getOption<String>( "loops", "" ) );
2809  runtime_assert( loops_string != "" );
2810 
2811  // Loop definition is given by begin-end.cutpoint, or begin-end.
2812  // For example, 10-23.15 indicates that the beginning(end) residue of a loop is 10(23) and
2813  // 15 is the cutpoint. If you omit a cutpoint input, it is given randomly between begin and end residues.
2814  Size num( 0 );
2815  StringVec loops ( string_split( loops_string, ',' ) );
2816  for ( StringVec::const_iterator loop( loops.begin() ), end( loops.end() ); loop!=end; ++loop ) {
2817  StringVec elements ( string_split( *loop, '.' ) );
2818  runtime_assert( elements.size() == 2 || elements.size() == 1 );
2819  Size cutpoint( 0 );
2820  StringVec interval ( string_split( elements[1], '-' ) );
2821  Size left = boost::lexical_cast<Size>( interval[1] );
2822  Size right = boost::lexical_cast<Size>( interval[2] );
2823  runtime_assert( left < right && interval.size() == 2 );
2824 
2825  // if begin or end residues are termini, there is no cutpoint
2826  if ( pose.residue( left ).is_lower_terminus() || pose.residue( right ).is_upper_terminus() ||
2827  pose.residue( left ).is_upper_terminus() || pose.residue( right ).is_lower_terminus() ){
2828  cutpoint = 0;
2829  } else {
2830  if ( elements.size() == 2 ){ // if there is a input of cutpoint
2831  cutpoint = boost::lexical_cast<Size>( elements[2] );
2832  } else { // if there is no input of cutpoint
2833  cutpoint = RG.random_range( 1, right - left ) + left;
2834  }
2835  }
2836  TR << "Modelling loop " << ++num << ": left=" << left << ",right=" << right << ",cutpoint=" << cutpoint << std::endl;
2837  // add a loop
2838  loops_->add_loop( Loop( left, right, cutpoint, 0.0, true ) );
2839  }
2840 
2841  // set fragsets
2842  FragSetOP fsop;
2843  String const fsets_string ( tag->getOption<String>( "fragsets", "" ) );
2844  runtime_assert( ! fsets_string.empty() );
2845  StringVec const fsets( string_split( fsets_string, ',' ) );
2846  for ( StringVec::const_iterator it( fsets.begin() ), end( fsets.end() ); it!= end; ++it ) {
2847  if ( data.has( "fragsets", *it ) ) {
2848  fsop = data.get< FragSet* >( "fragsets", *it );
2849  } else {
2850  utility_exit_with_message("fragsets " + *it + " not found in DataMap.");
2851  }
2852  add_fragments( fsop );
2853  }
2854 
2855  // set other parameters
2856  max_linear_chainbreak_ = tag->getOption<Real>( "max_linear_chainbreak", 0.07 );
2857  randomize_loops_ = tag->getOption<bool>( "randomize_loops", true );
2858  allowed_closure_attempts_ = tag->getOption<Size>( "allowed_closure_attempts", 1 );
2859  loophash_cycles_ = tag->getOption<Size>( "loophash_cycles", 8 );
2860  simultaneous_cycles_ = tag->getOption<Size>( "simultaneous_cycles", 2 );
2861  independent_cycles_ = tag->getOption<Size>( "independent_cycles", 8 );
2862  boost_closure_cycles_ = tag->getOption<Size>( "boost_closure_cycles", 30 );
2863  temperature_ = tag->getOption<Real>( "temperature", 2.0 );
2864 
2865 }
2866 
2867 
2868 } // remodel
2869 } // forge
2870 } // protocols
2871