Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LoopMover_KIC.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file protocols/loops/LoopMover_Perturb_KIC.cc
11 /// @brief kinematic loop closure main protocols
12 /// @author Chu Wang
13 /// @author Daniel J. Mandell
14 /// @author Mike Tyka
15 /// @author James Thompson
16 /// @author Amelie Stein, amelie.stein@ucsf.edu, Oct 2012 -- next-generation KIC
17 
18 
21 
22 //// Unit Headers
23 #include <protocols/loops/util.hh>
25 #include <protocols/loops/Loop.hh>
26 #include <protocols/loops/Loops.hh>
31 
32 //
33 //// Rosetta Headers
35 
36 #include <core/id/TorsionID.hh>
37 // AUTO-REMOVED #include <core/kinematics/FoldTree.hh>
41 #include <basic/options/option.hh>
42 #include <core/pose/Pose.hh>
43 // AUTO-REMOVED #include <core/scoring/Energies.hh>
45 
47 // AUTO-REMOVED #include <core/conformation/symmetry/util.hh>
48 
50 
56 
57 #include <basic/Tracer.hh>
58 
59 //Utility Headers
60 #include <numeric/random/random.hh>
61 
62 // C++ Headers
63 #include <iostream>
64 #include <map>
65 #include <string>
66 
67 // option key includes
68 
69 #include <basic/options/keys/out.OptionKeys.gen.hh>
70 #include <basic/options/keys/loops.OptionKeys.gen.hh>
71 #include <basic/options/keys/packing.OptionKeys.gen.hh>
72 #include <basic/options/keys/run.OptionKeys.gen.hh>
73 
74 #include <core/pose/util.hh>
76 #include <utility/vector0.hh>
77 #include <utility/vector1.hh>
78 // AUTO-REMOVED #include <ObjexxFCL/format.hh>
79 #include <fstream>
80 
81 //Auto Headers
82 
83 
84 //Auto using namespaces
85 namespace ObjexxFCL { } using namespace ObjexxFCL; // AUTO USING NS
86 //Auto using namespaces end
87 
88 
89 namespace protocols {
90 namespace loops {
91 namespace loop_mover {
92 namespace refine {
93 
94 ///////////////////////////////////////////////////////////////////////////////
95 using namespace core;
96 
97 static numeric::random::RandomGenerator RG(84888);
98 static basic::Tracer TR("protocols.loops.loop_mover.refine.LoopMover_Refine_KIC");
99 
100 LoopMover_Refine_KIC::LoopMover_Refine_KIC() : LoopMover()
101 {
102  init( get_fa_scorefxn() );
103 }
106 ) : LoopMover( loops_in )
107 {
108  init( get_fa_scorefxn() );
109 }
110 
112  protocols::loops::LoopsOP const loops_in,
114 ) : LoopMover( loops_in )
115 {
116  init( scorefxn );
117 }
118 
119 //destructor
121 
122 //clone
124  return new LoopMover_Refine_KIC(*this);
125  }
126 
128 {
129  set_scorefxn( scorefxn->clone() );
130  protocols::moves::Mover::type("LoopMover_Refine_KIC");
132 }
133 
134 void
136  using namespace core;
137  using namespace basic::options;
138 
139  fix_natsc_ = option[OptionKeys::loops::fix_natsc];
140  redesign_loop_ = false;
141  flank_residue_min_ = false; // by JQX
142  neighbor_dist_ = option[ OptionKeys::loops::neighbor_dist ]();
143  max_seglen_ = option[ OptionKeys::loops::kic_max_seglen ];
144  recover_low_ = ( ! option[ OptionKeys::loops::kic_recover_last ] );
145  min_after_repack_ = option[ OptionKeys::loops::kic_min_after_repack ];
147  option[ OptionKeys::loops::optimize_only_kic_region_sidechains_after_move ];
148 
149 }
150 
153 
154 
155 /// detailed
156 /// Refines the polypeptide segments in the LoopMover_Refine_KIC::loops_ class variable from their current conformations.
157 /// Uses Rosetta's all-atom respresentation and high-resolution scoring function (score12 with an upweighted chain
158 /// break term). At the beginning of this stage, unless the flag -loops:fix_natsc has been set, all residues within
159 /// the neighbor distance of a loop (defined by -loops:neighbor_dist) are repacked and then subject to rotamer trials.
160 /// The backbones of all loop residues, and the side-chains of all loop residues and neighbors are then subject to
161 /// DFPmin. If -loops:fix_natsc is set, only the loop residues (and not the neighbors) will be subject to repacking,
162 /// rotamer trials, and minimization. Consequently, if this stage has been preceeded by LoopMover_Perturb_KIC:model_loop,
163 /// and the -loops:fix_natsc flag is omitted, the side-chains surrounding the loop will be optimized for the
164 /// perturbed loop conformation, rather than the starting conformation that preceded the call to model_loop.
166  core::pose::Pose & pose
167 ){
168  static int cur_struct=0; // for movie output
169 
170  /// must be called once the Pose has become available.
171  resolve_loop_indices( pose );
172 
173  using namespace core;
174  using namespace optimization;
175  using namespace scoring;
176  using namespace basic::options;
177 
178  // Set the native pose if provided
179  core::pose::Pose native_pose;
180  if( get_native_pose() ){
181  native_pose = *get_native_pose();
182  }else{
183  native_pose = pose;
184  }
185 
186  // 'verbose' should be an option, or better yet Tracer's output filtering capabilities should be used instead
187  bool const verbose( true );
188  bool const local_debug( option[ OptionKeys::loops::debug ].user() );
189  bool const local_movie( false );
190  std::ofstream loop_outfile; // for movie
191 
192  // prepare for movie output if requested
193  if (local_movie) {
194  std::string outname_base = option[ OptionKeys::loops::output_pdb ]().name();
195  std::string outname_prefix = option[ OptionKeys::out::prefix ];
196  std::string outname = outname_prefix + outname_base + "_fullatom_movie_" +
197  right_string_of(cur_struct,4,'0') + ".pdb";
198  loop_outfile.open(outname.c_str(), std::ios::out | std::ios::binary);
199  }
200 
201  // set cutpoint variants for correct chainbreak scoring
202  Size const nres( pose.total_residue() );
203  utility::vector1< bool > is_loop( nres, false );
204 
205  for( Loops::const_iterator it=loops()->begin(), it_end=loops()->end();
206  it != it_end; ++it ) {
207  for ( Size i= it->start(); i<= it->stop(); ++i ) {
208  is_loop[i] = true;
209  }
210  Size const loop_cut(it->cut());
211 
212  if ( loop_cut != nres ) { //c-terminal loop
213  if ( ! pose.residue(loop_cut).has_variant_type(chemical::CUTPOINT_LOWER) )
215  if ( ! pose.residue(loop_cut+1).has_variant_type(chemical::CUTPOINT_UPPER) )
217  }
218  }
219 
220  // scheduler
221  int const fast = option[OptionKeys::loops::fast];
222  int outer_cycles(3);
223  if ( option[ OptionKeys::loops::outer_cycles ].user() ) {
224  outer_cycles = option[ OptionKeys::loops::outer_cycles ]();
225  }
226  if ( option[ OptionKeys::run::test_cycles ]() ) {
227  outer_cycles = 3;
228  }
229  int max_inner_cycles( 200 );
230  if ( option[ OptionKeys::loops::max_inner_cycles ].user() ) {
231  max_inner_cycles = option[ OptionKeys::loops::max_inner_cycles ]();
232  }
233  if ( option[ OptionKeys::run::test_cycles ]() ) {
234  max_inner_cycles = 3;
235  }
236 
237  int const inner_cycles = std::min( Size(max_inner_cycles), fast ? (int)loops()->loop_size() : 10 * (Size)( loops()->loop_size() ) );
238  int repack_period = 20; // should be an option
239  if ( option[ OptionKeys::loops::repack_period ].user() ) {
240  repack_period = option[ OptionKeys::loops::repack_period ]();
241  }
242 
243  // scorefxn
244  scoring::ScoreFunctionOP local_scorefxn;
245  scoring::ScoreFunctionOP min_scorefxn;
246  if ( scorefxn() != 0 ) local_scorefxn = scorefxn()->clone();
247  else {
248  local_scorefxn = get_fa_scorefxn();
249  }
250 
251  // For testing JK's new solvation term. The exact form isn't yet differentiable
252  min_scorefxn = local_scorefxn->clone();
253  if ( min_scorefxn->get_weight( core::scoring::occ_sol_exact ) > 0.0 ) {
254  min_scorefxn->set_weight( core::scoring::fa_sol, 0.65 );
255  min_scorefxn->set_weight( core::scoring::occ_sol_exact, 0.0 );
256  }
257 
258  //scoring::ScoreFunctionOP scorefxn( ScoreFunctionFactory::create_score_function(STANDARD_WTS, SCORE12_PATCH) );
259  //scorefxn->set_weight( chainbreak, 1.0 ); // confirm that chainbreak weight is set
260 
261  // scorefxn->set_weight( chainbreak, 1.0*10.0/3.0 ); // confirm that chainbreak weight is set
262  // min_scorefxn->set_weight( chainbreak, 1.0*10.0/3.0 ); // confirm that chainbreak weight is set
264  loop_mover::loops_set_chainbreak_weight( min_scorefxn, 1 );
265  //scorefxn->set_weight(core::scoring::mm_bend, 1.0);
266 
267  // AS: add rama2b weight in case we're sampling with rama2b
268  if ( option[ OptionKeys::loops::kic_rama2b ]() ) {
269  min_scorefxn->set_weight( rama2b, min_scorefxn->get_weight( rama ) );
270  min_scorefxn->set_weight( rama, 0);
271 
272  local_scorefxn->set_weight( rama2b, local_scorefxn->get_weight( rama ) );
273  local_scorefxn->set_weight( rama, 0);
274  }
275 
276 
277  // monte carlo
278  float const init_temp( option[ OptionKeys::loops::refine_init_temp ]() );
279  float const final_temp( option[ OptionKeys::loops::refine_final_temp ]() );
280  float const gamma = std::pow( (final_temp/init_temp), 1.0f/(outer_cycles*inner_cycles) );
281  float temperature = init_temp;
282  protocols::moves::MonteCarlo mc( pose, *local_scorefxn, temperature );
283 
284  // minimizer
285  AtomTreeMinimizerOP minimizer;
286  MinimizerOptions options( "dfpmin", 0.001, true /*use_nblist*/, false /*deriv_check*/ );
287  if ( core::pose::symmetry::is_symmetric( pose ) ) {
289  } else {
291  }
292 
293  // show temps
294  tr() << "refine init temp: " << init_temp << std::endl;
295  tr() << "refine final temp: " << final_temp << std::endl;
296 
297  // Set up the packer tasks: one for rotamer trials, one for repacking (with design if resfile supplied)
298  using namespace pack::task;
299  if ( task_factory == 0 ) {
300  task_factory = new TaskFactory;
301  // TaskOperations replace the following kind of code:
302  // base_packer_task->initialize_from_command_line().or_include_current( true );
303  task_factory->push_back( new operation::InitializeFromCommandline );
304  task_factory->push_back( new operation::IncludeCurrent );
305  if ( option[ OptionKeys::packing::resfile ].user() ) {
306  // Note - resfile is obeyed, so use NATAA as default to maintain protocol behavior
308  redesign_loop_ = true;
309  }
310  }
311 
312  PackerTaskOP repack_packer_task = task_factory->create_task_and_apply_taskoperations( pose );
313  repack_packer_task->set_bump_check( true );
314  pack::task::PackerTaskOP rottrials_packer_task;
315  if ( !option[ OptionKeys::packing::resfile ].user() && !redesign_loop_ ) {
316  // Not designing -- just repack
317  repack_packer_task->restrict_to_repacking();
318  tr() << "Not designing" << std::endl;
319  }
320  else tr() << "Activating design" << std::endl;
321 
322  // setting redes loop, but no resfile specified. all non-loop positions only repack. loop positions can design.
323  if( redesign_loop_ && !option[ OptionKeys::packing::resfile ].user() ) {
324  tr() << "Auto-setting loop design for residues:";
325  for( core::Size i = 1; i <= pose.total_residue(); ++i ) {
326  if( !is_loop[i] ) repack_packer_task->nonconst_residue_task( i ).restrict_to_repacking();
327  else tr() << " " << i;
328  }
329  tr() << std::endl;
330  }
331 
332  // setup kinematic mover
333  //protocols::loops::kinematic_closure::KinematicMover myKinematicMover( init_temp );
335 
336  // AS Oct 3, 2012: create appropriate perturber here, depending on input flags
337  // note that there currently is no taboo sampling in refinement, only in the perturb stage
338  if (option[ OptionKeys::loops::vicinity_sampling ]()) {
341  perturber->set_vary_ca_bond_angles( ! option[OptionKeys::loops::fix_ca_bond_angles ]() );
342  myKinematicMover.set_perturber( perturber );
343  perturber->set_degree_vicinity( option[ OptionKeys::loops::vicinity_degree ]() );
344  } else if ( basic::options::option[ basic::options::OptionKeys::loops::restrict_kic_sampling_to_torsion_string ].user() || basic::options::option[ basic::options::OptionKeys::loops::derive_torsion_string_from_native_pose ]() ) { // torsion-restricted sampling
345  std::string torsion_bins = basic::options::option[ basic::options::OptionKeys::loops::restrict_kic_sampling_to_torsion_string ]();
346 
347  // derive torsion string from native/input pose, if requested -- warning: this overwrites the externally provided one
348  if ( basic::options::option[ basic::options::OptionKeys::loops::derive_torsion_string_from_native_pose ]() )
349  torsion_bins = torsion_features_string( native_pose );
350  //runtime_assert(torsion_bins.size() != loop_end - loop_begin + 1); // loop boundaries are not available here -- maybe the perturber should check the length?
351 
353  perturber->set_vary_ca_bond_angles( ! option[ OptionKeys::loops::fix_ca_bond_angles ]() ); // to make the code cleaner this should really be a generic function, even though some classes may not use it
354  myKinematicMover.set_perturber( perturber );
355  } else if ( basic::options::option[ basic::options::OptionKeys::loops::kic_rama2b ]() ) { // neighbor-dependent phi/psi selection
357  perturber =
359  perturber->set_vary_ca_bond_angles( ! option[ OptionKeys::loops::fix_ca_bond_angles ]() );
360  myKinematicMover.set_perturber( perturber );
361  } else { // standard KIC
364  perturber->set_vary_ca_bond_angles( ! option[OptionKeys::loops::fix_ca_bond_angles ]() );
365  myKinematicMover.set_perturber( perturber );
366  }
367 
368  myKinematicMover.set_vary_bondangles( true ); // why is this hard-coded?
369  myKinematicMover.set_sample_nonpivot_torsions( option[ OptionKeys::loops::nonpivot_torsion_sampling ]());
370  myKinematicMover.set_rama_check( true );
371  Size kic_start, kic_middle, kic_end; // three pivot residues for kinematic loop closure
372 
373  // AS: adding option to change the number of rotamer trials -- just one (as in the current implementation) may be way too little
374  core::Size num_rot_trials = Size( option[ OptionKeys::loops::kic_num_rotamer_trials ]() );
375 
376  // AS: setting up weights for ramping rama[2b] and/or fa_rep
377  core::Real orig_local_fa_rep_weight = local_scorefxn->get_weight( fa_rep );
378  core::Real orig_min_fa_rep_weight = min_scorefxn->get_weight( fa_rep );
379 
380  core::Real orig_local_rama_weight = local_scorefxn->get_weight( rama );
381  core::Real orig_min_rama_weight = min_scorefxn->get_weight( rama );
382 
383  core::Real orig_local_rama2b_weight = local_scorefxn->get_weight( rama2b );
384  core::Real orig_min_rama2b_weight = min_scorefxn->get_weight( rama2b );
385 
386  if ( basic::options::option [ basic::options::OptionKeys::loops::ramp_fa_rep ]() ) {
387  local_scorefxn->set_weight( fa_rep, orig_local_fa_rep_weight/(outer_cycles + 1) );
388  min_scorefxn->set_weight( fa_rep, orig_min_fa_rep_weight/(outer_cycles + 1) );
389  }
390  //AS: ramp rama -- currently only in refine mode
391  if ( basic::options::option [ basic::options::OptionKeys::loops::ramp_rama ]() ) {
392  local_scorefxn->set_weight( rama, orig_local_rama_weight/(outer_cycles + 1) );
393  min_scorefxn->set_weight( rama, orig_min_rama_weight/(outer_cycles + 1) );
394 
395  // ramp rama2b instead if we're using that for sampling
396  if (option[ OptionKeys::loops::kic_rama2b ]() ) {
397  //TR << "ramp repulsive: rama2b set to " << orig_local_rama2b_weight/(outer_cycles + 1) << std::endl;
398  local_scorefxn->set_weight( rama2b, orig_local_rama2b_weight/(outer_cycles + 1) );
399  min_scorefxn->set_weight( rama2b, orig_min_rama2b_weight/(outer_cycles + 1) );
400  }
401  }
402 
403 
404 
405  // perform initial repack trial
406  utility::vector1<bool> allow_sc_move_all_loops( nres, false );
407  (*local_scorefxn)(pose); // update 10A nbr graph, silly way to do this
408  // here we'll optimize all side-chains within neighbor_dist_ of any loop (unless fix_natsc_ is true)
409  select_loop_residues( pose, *loops(), !fix_natsc_, allow_sc_move_all_loops, neighbor_dist_);
410  core::pose::symmetry::make_residue_mask_symmetric( pose, allow_sc_move_all_loops );
411  repack_packer_task->restrict_to_residues( allow_sc_move_all_loops );
412  core::pack::pack_rotamers( pose, *local_scorefxn, repack_packer_task );
413 
414  // setup rottrials packer task here to ensure we're using current sequence if design was active
415  rottrials_packer_task = task_factory->create_task_and_apply_taskoperations( pose );
416  rottrials_packer_task->restrict_to_repacking();
417  rottrials_packer_task->set_bump_check( true );
418  rottrials_packer_task->restrict_to_residues( allow_sc_move_all_loops );
419 
420  // minimize after initial repack
421  std::string move_type = "repack";
422  pose.update_residue_neighbors(); // to update 10A nbr graph
423  kinematics::MoveMap mm_all_loops; // DJM tmp
424  loops_set_move_map( pose, *loops(), fix_natsc_, mm_all_loops, neighbor_dist_);
425  if(flank_residue_min_){add_loop_flank_residues_bb_to_movemap(*loops(), mm_all_loops); } // added by JQX
426  minimizer->run( pose, mm_all_loops, *min_scorefxn, options ); // DJM tmp
427  mc.boltzmann( pose, move_type );
428  mc.show_scores();
429  if ( redesign_loop_ ) {
430  tr() << "Sequence after design step: "
431  << pose.sequence() << std::endl;
432  }
433 
434  // Get a vector of move_maps and allow_sc_move vectors, one for each loop. This way if we have multiple loops
435  // we can optimize only the side-chains around the loop selected in the inner_cycle
437  utility::vector1< utility::vector1< bool > > allow_sc_vectors ( loops()->size() );
438  update_movemap_vectors( pose, move_maps );
439  update_allow_sc_vectors( pose, allow_sc_vectors );
440 
441  if (local_movie) {
442  // this assumes there is only one loops_.
443  Loops::const_iterator one_loop( loops()->begin() );
444  Size begin_loop=one_loop->start();
445  Size end_loop=one_loop->stop();
446  loop_outfile << "MODEL" << std::endl;
447  utility::vector1<Size> indices(end_loop - begin_loop + 3);
448  for (Size i=begin_loop-1, j=1; i<=end_loop+1; i++, j++) {
449  indices[j]=i;
450  }
451  pose.dump_pdb(loop_outfile, indices, "initial_repack");
452  loop_outfile << "ENDMDL" << std::endl;
453  }
454 
455 
456  for (int i=1; i<=outer_cycles; ++i) {
457  // increase CHAINBREAK weight and update monte carlo
458  //scorefxn->set_weight( chainbreak, float(i)*10.0/3.0 );
459  //min_scorefxn->set_weight( chainbreak, float(i)*10.0/3.0 );
461  loop_mover::loops_set_chainbreak_weight( min_scorefxn, i );
462  //scorefxn->set_weight( chainbreak, float(i) );
463 
464  // AS: try ramping the fa_rep over the outer cycles
465  if ( option [ OptionKeys::loops::ramp_fa_rep ]() ) {
466  //TR << "ramp repulsive: fa_rep set to " << orig_local_fa_rep_weight/(outer_cycles - i + 1) << std::endl;
467  local_scorefxn->set_weight( fa_rep, orig_local_fa_rep_weight/(outer_cycles - i + 1) );
468  min_scorefxn->set_weight( fa_rep, orig_min_fa_rep_weight/(outer_cycles - i + 1) );
469  }
470 
471  if ( option [ OptionKeys::loops::ramp_rama ]() ) {
472  //TR << "ramp repulsive: rama set to " << orig_local_rama_weight/(outer_cycles - i + 1) << std::endl;
473  local_scorefxn->set_weight( rama, orig_local_rama_weight/(outer_cycles - i + 1) );
474  min_scorefxn->set_weight( rama, orig_min_rama_weight/(outer_cycles - i + 1) );
475 
476  if (option[ OptionKeys::loops::kic_rama2b ]() ) {
477  //TR << "ramp repulsive: rama2b set to " << orig_local_rama2b_weight/(outer_cycles - i + 1) << std::endl;
478  local_scorefxn->set_weight( rama2b, orig_local_rama2b_weight/(outer_cycles - i + 1) );
479  min_scorefxn->set_weight( rama2b, orig_min_rama2b_weight/(outer_cycles - i + 1) );
480 
481  }
482  }
483 
484 
485 
486 
487  mc.score_function( *local_scorefxn );
488  // recover low
489  if ( recover_low_ ) {
490  mc.recover_low( pose );
491  }
492  // score info
493  if ( verbose ) tr() << "cycle: " << i << " " << (*local_scorefxn)(pose) << std::endl;
494  //pose.energies().show( tr );
495  for ( int j=1; j<=inner_cycles; ++j ) {
496  temperature *= gamma;
497  mc.set_temperature( temperature );
498  if ( verbose ) tr() << "refinement cycle (outer/inner): "
499  << i << "/" << outer_cycles << " "
500  << j << "/" << inner_cycles << " "
501  << std::endl;
502 
503  // choose a random loop for both rounds
504  //Loops::const_iterator it( loops_.one_random_loop() );
505  Size loop_ind = RG.random_range(1, loops()->size());
506  Loops one_loop;
507  //one_loop.add_loop( it );
508  one_loop.add_loop( ( *loops() )[ loop_ind ] );
509  // get loop endpoints
510  Size begin_loop=one_loop.begin()->start();
511  Size end_loop=one_loop.begin()->stop();
512 
513  myKinematicMover.set_loop_begin_and_end( begin_loop, end_loop ); // AS -- for restricted torsion bin sampling, the mover needs to know about the start of the defined loop, not just the segment that is sampled in a given move
514 
515  // for Taboo Sampling we need to update the sequence here every time, in case it changes (e.g. when modeling multiple loops)
517  loop_sequence.resize(0); // make sure it is empty
518  for (core::Size cur_res = begin_loop; cur_res <= end_loop; cur_res++) {
519  loop_sequence.push_back(pose.aa(cur_res));
520  }
521  myKinematicMover.update_sequence( loop_sequence );
522 
523  // get the movemap for minimization and allowed side-chains for rottrials for this loop
524  kinematics::MoveMap cur_mm = move_maps[ loop_ind ];
525  utility::vector1<bool> cur_allow_sc_move = allow_sc_vectors[ loop_ind ];
526  rottrials_packer_task->restrict_to_residues( cur_allow_sc_move );
527 
528  // AS Thu Oct 25 19:41:14 PDT 2012
529  // rewriting the kinematic trials so that the 1st and 2nd round are handled by a loop instead of code duplication
530  // then incorporating the possibility to repack after each loop move (and before calling mc.boltzmann)
531 
532  core::Size num_kinematic_trials = 2;
533  for (core::Size kinematic_trial = 1; kinematic_trial <= num_kinematic_trials; kinematic_trial++) {
534  // AS: the previous implementation had a "history bias" towards the N-terminus of the loop, as the start pivot can be anywhere between begin_loop and end_loop-2, while the choice of the end pivot depends on the start pivot
535  if ( option[ OptionKeys::loops::legacy_kic ]() || j % 2 == 0 ) {
536  kic_start = RG.random_range(begin_loop,end_loop-2);
537  // choose a random end residue so the length is >= 3, <= min(loop_end, start+maxlen)
538  kic_end = RG.random_range(kic_start+2, std::min((kic_start+max_seglen_ - 1), end_loop));
539  Size middle_offset = (kic_end - kic_start) / 2;
540  kic_middle = kic_start + middle_offset;
541  } else {
542  kic_end = RG.random_range(begin_loop+2,end_loop);
543  kic_start = RG.random_range(std::max((kic_end - std::min(max_seglen_, kic_end) + 1), begin_loop), kic_end-2);
544  Size middle_offset = (kic_end - kic_start) / 2;
545  kic_middle = kic_start + middle_offset;
546  }
547 
548  myKinematicMover.set_pivots(kic_start, kic_middle, kic_end);
549  myKinematicMover.set_temperature(temperature);
550  myKinematicMover.apply( pose );
551 
552  if ( myKinematicMover.last_move_succeeded() ) {
553  // get the movemap and allowed side-chains for the current loop
554 
555  //fpd symmetrize mm_all_loops
556  if ( core::pose::symmetry::is_symmetric( pose ) ) {
557  core::pose::symmetry::make_residue_mask_symmetric( pose, cur_allow_sc_move );
558  }
559 
560  // do optimizations
562  set_rottrials_from_kic_segment( pose, rottrials_packer_task, kic_start, kic_end ); // for rottrials
563  set_movemap_from_kic_segment( pose, cur_mm, kic_start, kic_end ); // for minimization
564  }
565 
566  // AS Oct 25, 2012: considering the order of magnitude that full-scale KIC modeling can introduce, it may be very valuable to repack before testing for acceptance
567  // * note that this probably is much less relevant in vicinity sampling -- Rotamer Trials may be enough
568  // * also note that this allows for design, which we're not testing at the moment in the standard loop modeling benchmark -- it should be checked whether this leads to collapsing structures / strong preference for small residues, and in the latter case, perhaps this part of the code should only repack, but not design
569  if ( !option[ OptionKeys::loops::legacy_kic ]() && (j%repack_period)==0 ) {
570  // implementation copied from "main_repack_trial" below
571 
572  //tr() << " AS -- repacking after loop closure but before mc.boltzmann " << std::endl; // AS_DEBUG
573 
574  update_movemap_vectors( pose, move_maps );
575  update_allow_sc_vectors( pose, allow_sc_vectors );
576 
577  // the repack/design and subsequent minimization within this main_repack_trial block apply
578  // to all loops (and their neighbors, if requested)
579  loops_set_move_map( pose, *loops(), fix_natsc_, mm_all_loops, neighbor_dist_);
580  if(flank_residue_min_){add_loop_flank_residues_bb_to_movemap(*loops(), mm_all_loops); } // added by JQX
581  select_loop_residues( pose, *loops(), !fix_natsc_, allow_sc_move_all_loops, neighbor_dist_);
582 
583  core::pose::symmetry::make_residue_mask_symmetric( pose, allow_sc_move_all_loops ); //fpd symmetrize res mask -- does nothing if pose is not symm
584  repack_packer_task->restrict_to_residues( allow_sc_move_all_loops );
585  rottrials_packer_task->restrict_to_residues( allow_sc_move_all_loops );
586  pack::pack_rotamers( pose, *local_scorefxn, repack_packer_task ); // design here if resfile supplied
587  if ( verbose ) tr() << "energy after design: " << (*local_scorefxn)(pose) << std::endl; // DJM remove
588  if ( redesign_loop_ ) { // need to make new rottrials packer task with redesigned sequence
589  rottrials_packer_task = task_factory->create_task_and_apply_taskoperations( pose );
590  rottrials_packer_task->restrict_to_repacking();
591  rottrials_packer_task->set_bump_check( true );
592  rottrials_packer_task->restrict_to_residues( allow_sc_move_all_loops );
593  if ( verbose ) tr() << "energy after design repack: " << (*local_scorefxn)(pose) << std::endl; // DJM remove
594  }
595 
596  // minimize after repack if requested
597  // AS: note that this may not be necessary here, as we'll minimize after the rotamer trials step anyway
598  if ( min_after_repack_ ) {
599  if ( core::pose::symmetry::is_symmetric( pose ) ) {
600  //fpd minimizing with the reduced movemap seems to cause occasional problems
601  // in the symmetric case ... am looking into this
602  loops_set_move_map( pose, *loops(), fix_natsc_, mm_all_loops, neighbor_dist_ );
603  if(flank_residue_min_){add_loop_flank_residues_bb_to_movemap(*loops(), mm_all_loops); } // added by JQX
604  minimizer->run( pose, mm_all_loops, *min_scorefxn, options );
605  } else {
606  minimizer->run( pose, mm_all_loops, *min_scorefxn, options );
607  }
608  }
609 
610  std::string move_type;
611  if ( redesign_loop_ ) move_type = "repack+design";
612  else move_type = "repack";
613  mc.boltzmann( pose, move_type );
614  mc.show_scores();
615  if ( redesign_loop_ ) {
616  tr() << "Sequence after design step: "
617  << pose.sequence() << std::endl;
618  }
619  if ( verbose ) tr() << "energy after repack: " << (*local_scorefxn)(pose) << std::endl;
620  }
621 
622  // AS: first do repacking (if applicable), then rotamer trials -- we've shown that this increases recovery of native side chain conformations
623  for (Size i = 1; i <= num_rot_trials; i++) {
624  pack::rotamer_trials( pose, *local_scorefxn, rottrials_packer_task );
625  pose.update_residue_neighbors(); // to update 10A nbr graph
626  }
627  //pack::pack_rotamers_loop( pose, *local_scorefxn, rottrials_packer_task, num_rot_trials ); // can we use this instead? is this really RT, or actual packing?
628 
629 
630 
631  // AS: for non-legacy-KIC one might consider putting this into an ELSE branch -- however, min_after_repack_ defaults to false, in which case we wouldn't have minimization here, which could strongly affect the likelihood of acceptance
632  if ( core::pose::symmetry::is_symmetric( pose ) ) {
633  //fpd minimizing with the reduced movemap seems to cause occasional problems
634  // in the symmetric case ... am looking into this
635  minimizer->run( pose, cur_mm, *min_scorefxn, options );
636  } else {
637  //minimizer->run( pose, mm_all_loops, *min_scorefxn, options );
638  minimizer->run( pose, cur_mm, *min_scorefxn, options );
639  }
640 
641  // test for acceptance
642  std::stringstream k_trial;
643  k_trial << kinematic_trial;
644  std::string move_type = "kic_refine_r" + k_trial.str();
645  bool accepted = mc.boltzmann( pose, move_type );
646  if (accepted) {
647  tr() << "RMS to native after accepted kinematic round " << kinematic_trial << " move on loop "
648  << loops()->size() + 1 - loop_ind << ": " // reverse the order so it corresponds with the loop file
649  << loop_rmsd(pose, native_pose, *loops()) << std::endl;
650  //tr << "after accepted move res " << kic_start + 2 << " omega is " << pose.omega(kic_start+2) << std::endl;
651  if (local_movie) {
652  loop_outfile << "MODEL" << std::endl;
653  utility::vector1<Size> indices(end_loop - begin_loop + 3);
654  for (Size i=begin_loop-1, j=1; i<=end_loop+1; i++, j++) {
655  indices[j]=i;
656  }
657  pose.dump_pdb(loop_outfile, indices, "refine_r" + k_trial.str());
658  loop_outfile << "ENDMDL" << std::endl;
659  }
660  //tr << "temperature: " << temperature << std::endl;
661  //tr << "chainbreak: " << pose.energies().total_energies()[ scoring::chainbreak ] << std::endl;
662  if ( verbose ) tr() << "energy after accepted move: " << (*local_scorefxn)(pose) << std::endl;
663  }
664  //mc.show_scores();
665  }
666  }
667 
668  { //main_repack_trial
669  if ( ( option[ OptionKeys::loops::legacy_kic ]() && (j%repack_period)==0 ) || j==inner_cycles ) { // AS: always repack at the end of an outer cycle, to make sure the loop environment is repacked before returning from this function
670 
671  //tr() << " AS -- repacking after loop closure and mc.boltzmann (legacy KIC behavior) " << std::endl; // AS_DEBUG
672 
673  // repack trial
674  // DJM: we have found that updating the move maps and rottrials/repack sets once per repack period
675  // gives better performance than updating them after every move, so we do so here for
676  // subsequent cycles until the next repack period
677  update_movemap_vectors( pose, move_maps );
678  update_allow_sc_vectors( pose, allow_sc_vectors );
679 
680  // the repack/design and subsequent minimization within this main_repack_trial block apply
681  // to all loops (and their neighbors, if requested)
682  loops_set_move_map( pose, *loops(), fix_natsc_, mm_all_loops, neighbor_dist_);
683  if(flank_residue_min_){add_loop_flank_residues_bb_to_movemap(*loops(), mm_all_loops); } // added by JQX
684  select_loop_residues( pose, *loops(), !fix_natsc_, allow_sc_move_all_loops, neighbor_dist_);
685 
686  core::pose::symmetry::make_residue_mask_symmetric( pose, allow_sc_move_all_loops ); //fpd symmetrize res mask -- does nothing if pose is not symm
687  repack_packer_task->restrict_to_residues( allow_sc_move_all_loops );
688  rottrials_packer_task->restrict_to_residues( allow_sc_move_all_loops );
689  pack::pack_rotamers( pose, *local_scorefxn, repack_packer_task ); // design here if resfile supplied
690  if ( verbose ) tr() << "energy after design: " << (*local_scorefxn)(pose) << std::endl; // DJM remove
691  if ( redesign_loop_ ) { // need to make new rottrials packer task with redesigned sequence
692  rottrials_packer_task = task_factory->create_task_and_apply_taskoperations( pose );
693  rottrials_packer_task->restrict_to_repacking();
694  rottrials_packer_task->set_bump_check( true );
695  rottrials_packer_task->restrict_to_residues( allow_sc_move_all_loops );
696  if ( verbose ) tr() << "energy after design repack: " << (*local_scorefxn)(pose) << std::endl; // DJM remove
697  }
698 
699  // minimize after repack if requested
700  if ( min_after_repack_ ) {
701  if ( core::pose::symmetry::is_symmetric( pose ) ) {
702  //fpd minimizing with the reduced movemap seems to cause occasional problems
703  // in the symmetric case ... am looking into this
704  loops_set_move_map( pose, *loops(), fix_natsc_, mm_all_loops, neighbor_dist_ );
705  if(flank_residue_min_){add_loop_flank_residues_bb_to_movemap(*loops(), mm_all_loops); } // added by JQX
706  minimizer->run( pose, mm_all_loops, *min_scorefxn, options );
707  } else {
708  minimizer->run( pose, mm_all_loops, *min_scorefxn, options );
709  }
710  }
711 
712  std::string move_type;
713  if ( redesign_loop_ ) move_type = "repack+design";
714  else move_type = "repack";
715  mc.boltzmann( pose, move_type );
716  mc.show_scores();
717  if ( redesign_loop_ ) {
718  tr() << "Sequence after design step: "
719  << pose.sequence() << std::endl;
720  }
721  if ( verbose ) tr() << "energy after repack: " << (*local_scorefxn)(pose) << std::endl;
722  }
723  }
724  if ( verbose || local_debug ) tr() << std::flush;
725  } //inner_cycle
726  } //outer_cycle
727 
728  mc.show_counters();
729  if ( recover_low_ ) {
730  pose = mc.lowest_score_pose();
731  }
732  else {
733  pose = mc.last_accepted_pose();
734  }
735  if (local_movie) {
736  // this assumes there is only one loops_.
737  Loops::const_iterator one_loop( loops()->begin() );
738  Size begin_loop=one_loop->start();
739  Size end_loop=one_loop->stop();
740  loop_outfile << "MODEL" << std::endl;
741  utility::vector1<Size> indices(end_loop - begin_loop + 3);
742  for (Size i=begin_loop-1, j=1; i<=end_loop+1; i++, j++) {
743  indices[j]=i;
744  }
745  pose.dump_pdb(loop_outfile, indices, "final_refine");
746  loop_outfile << "ENDMDL" << std::endl;
747  }
748 
749 
750 }
751 
754  return "LoopMover_Refine_KIC";
755 }
756 
757 /// detailed
758 /// Update the MoveMaps that define, for each loop in loops_, which residues may be minimized.
759 /// Allows for minimization to apply only to the neighborhood around the segment that KIC moved, in cases
760 /// where multiple segments (loops) are defined.
761 void
763  core::pose::Pose & pose,
765 
766  for( Size i = 1; i <= loops()->size(); i++ ) {
767  protocols::loops::Loops cur_loop;
768  cur_loop.add_loop( ( *loops() )[ i ] );
770  loops_set_move_map( pose, cur_loop, fix_natsc_, cur_mm, neighbor_dist_ );
771  move_maps[ i ] = cur_mm;
772  }
773 }
774 
775 /// detailed
776 /// Update the allow_sc_vectors that define, for each loop in loops_, which residue side-chains may be subject to
777 /// rotamer trials. Allows for rotamer trials to apply only to the neighborhood around the segment that KIC moved,
778 /// in cases where multiple segments (loops) are defined.
779 void
781  core::pose::Pose & pose,
782  utility::vector1< utility::vector1< bool > > & allow_sc_vectors ) {
783 
784  for( Size i = 1; i <= loops()->size(); i++ ) {
785  protocols::loops::Loops cur_loop;
786  cur_loop.add_loop( ( *loops() )[ i ] );
787  utility::vector1<bool> cur_allow_sc_move( pose.total_residue(), false );
788  select_loop_residues( pose, cur_loop, !fix_natsc_, cur_allow_sc_move, neighbor_dist_);
789  allow_sc_vectors[ i ] = cur_allow_sc_move;
790  }
791 }
792 
793 /// detailed
794 /// Sets the rotamer trials packer task used in LoopMover_Refine_KIC::apply() to only rotamer trial the
795 /// neighborhood around KIC segment that moved. May slightly hurt performance in de novo loop reconstruction,
796 /// but may yield a speedup of 2X or more in cases of modeling very large or multiple segments (loop definitions),
797 /// in conjunction with set_movemap_from_kic_segment(), which are both used when
798 /// optimize_only_kic_region_sidechains_after_move_ is set to true.
799 void
801  core::pose::Pose & pose,
802  pack::task::PackerTaskOP & rottrials_packer_task,
803  Size kic_start,
804  Size kic_end ) {
805 
806  // we'll exploit the loops classes and the select_loop_residues() function to setup the PackerTask
807  protocols::loops::Loop kic_seg( kic_start, kic_end, kic_start );
808  utility::vector1<bool> to_trials( pose.total_residue(), false );
809  select_loop_residues( pose, kic_seg, true, to_trials, neighbor_dist_ );
810  rottrials_packer_task->restrict_to_residues( to_trials );
811 }
812 
813 /// detailed
814 /// Sets the MoveMap for minimization used in LoopMover_Refine_KIC::apply() to only minimize the
815 /// neighborhood around KIC segment that moved. May slightly hurt performance in de novo loop reconstruction,
816 /// but may yield a speedup of 2X or more in cases of modeling very large or multiple segments (loop definitions),
817 /// in conjunction with set_movemap_from_kic_segment(), which are both used when
818 /// optimize_only_kic_region_sidechains_after_move_ is set to true.
819 void
821  core::pose::Pose & pose,
822  kinematics::MoveMap & cur_mm,
823  Size kic_start,
824  Size kic_end ) {
825 
826  protocols::loops::Loops kic_seg;
827  kic_seg.add_loop( kic_start, kic_end, kic_start );
828  loops_set_move_map( pose, kic_seg, fix_natsc_, cur_mm, neighbor_dist_);
829 }
830 
831 basic::Tracer & LoopMover_Refine_KIC::tr() const
832 {
833  return TR;
834 }
835 
837 
839  return new LoopMover_Refine_KIC();
840 }
841 
843  return "LoopMover_Refine_KIC";
844 }
845 
846 } // namespace refine
847 } // namespace loop_mover
848 } // namespace loops
849 } // namespace protocols