Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SidechainMover.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/simple_moves/sidechain_moves/SidechainMover.cc
11 /// @brief implementation of SidechainMover class and functions
12 /// @author Colin A. Smith (colin.smith@ucsf.edu)
13 
14 
17 
18 // Procols Headers
20 
21 // Core Headers
26 #include <core/id/DOF_ID_Range.hh>
27 #include <core/id/TorsionID.hh>
31 #include <core/pose/Pose.hh>
35 // AUTO-REMOVED #include <core/scoring/ScoringManager.hh>
36 #include <core/types.hh>
37 #include <basic/Tracer.hh>
38 #include <basic/basic.hh>
39 #include <basic/prof.hh>
40 
41 // Numeric Headers
42 #include <numeric/angle.functions.hh>
43 // AUTO-REMOVED #include <numeric/constants.hh>
44 #include <numeric/conversions.hh>
45 #include <numeric/random/random.hh>
46 
47 // Utility
48 #include <utility/string_util.hh>
49 #include <utility/tag/Tag.hh>
50 #include <utility/exit.hh>
51 
52 // C++ Headers
53 #include <sstream>
54 // AUTO-REMOVED #include <fstream>
55 #include <utility/fixedsizearray1.hh>
56 
58 #include <utility/vector0.hh>
59 #include <utility/excn/Exceptions.hh>
60 #include <utility/vector1.hh>
61 
62 using namespace core;
63 using namespace core::pose;
64 
65 static numeric::random::RandomGenerator RG(38627225);
66 static basic::Tracer TR("protocols.simple_moves.sidechain_moves.SidechainMover");
67 
68 namespace protocols {
69 namespace simple_moves {
70 namespace sidechain_moves {
71 
73 SidechainMoverCreator::keyname() const {
74  return SidechainMoverCreator::mover_name();
75 }
76 
78 SidechainMoverCreator::create_mover() const {
79  return new SidechainMover;
80 }
81 
83 SidechainMoverCreator::mover_name() {
84  return "Sidechain";
85 }
86 
87 SidechainMover::SidechainMover():
88  rotamer_library_( core::pack::dunbrack::RotamerLibrary::get_instance() ),
89  pose_(0),
90  prob_uniform_(0.1),
91  prob_withinrot_(0.0),
92  prob_random_pert_to_current_(0.0),
93  accept_according_to_dunbrack_(true),
94  sample_rotwells_unif_(false),
95  change_chi_without_replacing_residue_(false),
96  next_resnum_(0),
97  last_proposal_density_ratio_(1),
98  task_initialized_(false),
99  scratch_( new core::pack::dunbrack::RotamerLibraryScratchSpace ),
100  temperature0_(0.56),
101  sampling_temperature_(0.56)
102 {}
103 
105  core::pack::dunbrack::RotamerLibrary const & rotamer_library
106 ):
107  rotamer_library_(rotamer_library),
108  pose_(0),
109  prob_uniform_(0.1),
110  prob_withinrot_(0.0),
111  prob_random_pert_to_current_(0.0),
112  accept_according_to_dunbrack_(true),
113  sample_rotwells_unif_(false),
114  change_chi_without_replacing_residue_(false),
115  next_resnum_(0),
116  last_proposal_density_ratio_(1),
117  task_initialized_(false),
118  scratch_( new core::pack::dunbrack::RotamerLibraryScratchSpace ),
119  temperature0_(0.56),
120  sampling_temperature_(0.56)
121 {}
122 
124  SidechainMover const & mover
125 ) :
126  //utility::pointer::ReferenceCount(),
127  protocols::canonical_sampling::ThermodynamicMover(mover),
128  rotamer_library_(mover.rotamer_library_),
129  packed_residues_(mover.packed_residues_),
130  residue_packed_(mover.residue_packed_),
131  prob_uniform_(mover.prob_uniform_),
132  prob_withinrot_(mover.prob_withinrot_),
133  prob_random_pert_to_current_(mover.prob_random_pert_to_current_),
134  preserve_detailed_balance_(mover.preserve_detailed_balance_),
135  accept_according_to_dunbrack_(mover.accept_according_to_dunbrack_),
136  sample_rotwells_unif_(mover.sample_rotwells_unif_),
137  change_chi_without_replacing_residue_(mover.change_chi_without_replacing_residue_),
138  next_resnum_(mover.next_resnum_),
139  last_chi_angles_(mover.last_chi_angles_),
140  last_nchi_(mover.last_nchi_),
141  last_mutation_(mover.last_mutation_),
142  last_uniform_(mover.last_uniform_),
143  last_withinrot_(mover.last_withinrot_),
144  last_pertrot_(mover.last_pertrot_),
145  last_proposal_density_ratio_(mover.last_proposal_density_ratio_),
146  task_initialized_(mover.task_initialized_),
147  temperature0_(0.56),
148  sampling_temperature_(0.56)
149 {
151  if (mover.task_) task_ = mover.task_->clone();
152  if (mover.pose_) pose_ = new core::pose::Pose(*mover.pose_);
154 }
155 
157 
160 {
162 }
163 
164 void
166  utility::tag::TagPtr const tag,
168  protocols::filters::Filters_map const & /*filters*/,
169  protocols::moves::Movers_map const & /*movers*/,
170  core::pose::Pose const & /*pose*/
171 )
172 {
174 
175  if ( tag->hasOption("task_operations") ) {
176 
177  std::string const t_o_val( tag->getOption<std::string>("task_operations") );
178  typedef utility::vector1< std::string > StringVec;
179  StringVec const t_o_keys( utility::string_split( t_o_val, ',' ) );
180  for ( StringVec::const_iterator t_o_key( t_o_keys.begin() ), end( t_o_keys.end() );
181  t_o_key != end; ++t_o_key ) {
182  if ( data.has( "task_operations", *t_o_key ) ) {
183  new_task_factory->push_back( data.get< core::pack::task::operation::TaskOperation* >( "task_operations", *t_o_key ) );
184  } else {
185  throw utility::excn::EXCN_RosettaScriptsOption("TaskOperation " + *t_o_key + " not found in protocols::moves::DataMap.");
186  }
187  }
188 
189  } else {
190 
191  new_task_factory->push_back( new core::pack::task::operation::RestrictToRepacking );
192  }
193 
194  task_factory_ = new_task_factory;
195 
196  set_preserve_detailed_balance( tag->getOption<bool>( "preserve_detailed_balance", preserve_detailed_balance() ) );
197  set_prob_uniform( tag->getOption<core::Real>( "prob_uniform", prob_uniform() ) );
198  set_prob_withinrot( tag->getOption<core::Real>( "prob_withinrot", prob_withinrot() ) );
199  set_prob_random_pert_current( tag->getOption<core::Real>( "prob_random_pert_current", prob_random_pert_current() ) );
200  set_change_chi_without_replacing_residue( tag->getOption<core::Real>( "change_chi_without_replacing_residue", change_chi_without_replacing_residue() ) );
201 }
202 
203 /// @detailed
204 /// Check to make sure that a packer task exists and matches the numer of residues in
205 /// the given pose. If that isn't the case, create a new one with the task factory.
206 /// Exits with an error if no task factory exists.
207 void
209  core::pose::Pose const & pose
210 )
211 {
212  // check to see if a valid task already exists
213  if (!task_ || task_->total_residue() != pose.total_residue()) {
214  // if not, create one using the task factory
215  if (task_factory_) {
216  set_task(task_factory_->create_task_and_apply_taskoperations( pose ));
217  } else {
218  utility_exit_with_message("Cannot create task because no task factory is set");
219  }
220  }
221  /// apl -- is it reasonable to first check the task to see if infact we are designing?
222  /// copying a pose is expensive -- try to avoid it if possible.
223  if( !pose_ ){ //pose not initialized
224  pose_ = new core::pose::Pose( pose ); //need this in case we're designing as well. ek 4/28/10
225  }
226 
227 
228 }
229 
230 void
232  core::pose::Pose & pose,
233  protocols::canonical_sampling::MetropolisHastingsMover const&, /*metropolis_hastings_mover*/
234  core::Size /*cycle*/
235 )
236 {
237  idealize_sidechains(pose);
238 }
239 
240 void
242  numeric::random::RandomGenerator Rand,
243  core::Real max_deviation,
246 ){
247  new_chi.resize( old_chi.size() );
248  core::Real rand;
249  for(unsigned int chi_i = 1; chi_i <= old_chi.size(); chi_i++){
250  rand = Rand.uniform();
251  //int sign = Rand.random_range(0,1);
252  //if(sign == 0){
253  // sign = -1;
254  //}
255  //new_chi[ chi_i ] = basic::periodic_range( ((rand * max_deviation * sign) + old_chi[ chi_i ]) , 360.0 );
256  new_chi[ chi_i ] = basic::periodic_range( ( (2.0*rand-1.0)*max_deviation + old_chi[ chi_i ]) , 360.0 );
257  }
258 }
259 
260 bool
262  numeric::random::RandomGenerator & Rand,
264  utility::vector1<core::Real> const & previous_chi_angles,
265  utility::vector1<core::Real> const & new_chi_angles
266 )
267 {
268  core::Real rand = Rand.uniform();
269  //conformation::Residue copy(res); // APL: EXPENSIVE!
270  res.set_all_chi( previous_chi_angles );
271  core::Real prev_chi_angle_score = rotamer_library_.rotamer_energy( res, *scratch_);
272  res.set_all_chi( new_chi_angles );
273 
274  core::Real new_chi_angle_score = rotamer_library_.rotamer_energy( res, *scratch_);
275  if ( new_chi_angle_score > prev_chi_angle_score) {
276  //Real const boltz_factor = (prev_chi_angle_score - new_chi_angle_score)/1.0;
277  Real const boltz_factor = (prev_chi_angle_score - new_chi_angle_score)/sampling_temperature_*temperature0_;
278  //Real const probability = std::exp(std::max(Real(-40.0),boltz_factor));
279  Real const probability = std::exp(boltz_factor);
280  if ( rand >= probability ) {
281  return false;
282  }
283  }
284  return true;
285 }
286 
287 
290 {
291 
292  using numeric::conversions::degrees;
293  using numeric::conversions::radians;
294 
295  // reset the last move tracking information
296  last_mutation_ = false;
297  last_uniform_ = false;
298  last_withinrot_ = false;
299  last_pertrot_ = false;
300 
301  core::chemical::ResidueType const & previous_residue_type( input_residue->type() );
302  utility::vector1<core::Real> previous_chi_angles( input_residue->chi() );
303 
304  core::Size resnum = input_residue->seqpos();
305  core::pack::task::ResidueLevelTask const & residue_task(task_->residue_task(resnum));
306  core::pack::task::ResidueLevelTask::ResidueTypeCOPList const & residue_types(residue_task.allowed_residue_types());
307 
308  // select a residue type
309  core::chemical::ResidueTypeCOP residue_type;
310  do {
311  Size const restypenum(RG.random_range(1, residue_types.size()));
313  for (Size i = 1; i < restypenum; ++i) ++iter;
314  residue_type = *iter;
315  }
316  while (residue_type->aa() == core::chemical::aa_pro); // temporary hack to exlcude sampling of proline sidechains
317 
318  last_nchi_ = residue_type->nchi();
319 
320  ///code note: stl uses lazy resizes; if a vector doesn't have to allocate more space, it doesn't, it just
321  /// updates its end-of-memory pointer. By always performing the resize, the vector size() will reflect
322  /// the actual number of chi.
323  ///if (last_chi_angles_.size() < last_nchi_) last_chi_angles_.resize(last_nchi_);
324  last_chi_angles_.resize( last_nchi_ );
325 
326  if ( TR.visible( basic::t_debug )) {
327  TR.Debug << input_residue->name() << " " << resnum << " -> " << residue_type->name() << std::endl;
328  }
329 
330  if (residue_type->aa() != (input_residue->type()).aa()) last_mutation_ = true;
331 
333  rotamer_library_.get_rsd_library(*residue_type)
334  );
336  dynamic_cast< core::pack::dunbrack::SingleResidueDunbrackLibrary const * >(residue_rotamer_library.get())
337  );
338 
339  /// last_chi_angles_ holds degrees for a short period;
340  /// Apply uniform sampling to rotamers with a small probability, or with probability 1 if
341  /// the residue's library is not a dunbrack library. (Is this what we would want for pSer?).
342  /// At the moment, the ligand rotamer library does not respond to the assign_random_rotamer_with_bias
343  /// method, so this is an ok check.
344 
345  core::Real move_type_prob( RG.uniform() );
346  if ( move_type_prob > prob_uniform_ && residue_dunbrack_library) { //set up rotamer library stuff
347  //p_within_rot or p_jump_rots or p_random_pert_to_current
348  core::Real const phi( residue_dunbrack_library->get_phi_from_rsd( *input_residue ) );
349  core::Real const psi( residue_dunbrack_library->get_psi_from_rsd( *input_residue ) );
350 
351  /* //add in option to sample rotamers above a certain threshold uniformly
352  utility::vector1< core::pack::dunbrack::DunbrackRotamerSampleData > most_probable_rotamers;
353  Size itr_i = 1;
354  core::Real const probability_threshold = 0.01;
355  assert( rotamer_sample_data.size() > 0 );
356  if ( sample_rotwells_unif_ ){ //uniformly samples rotamer wells
357  while((itr_i <= rotamer_sample_data.size()) &&
358  (rotamer_sample_data[ itr_i ].probability() > probability_threshold)){
359  most_probable_rotamers.push_back( rotamer_sample_data[ itr_i ] );
360  itr_i++;
361  }
362  assert( most_probable_rotamers.size() > 0 );
363  rotamer_sample_data = most_probable_rotamers; //replace all rots with ones that pass a certain threshold (1%)
364  }*/
365 
368  residue_dunbrack_library->get_all_rotamer_samples(phi, psi)
369  );
370  make_rotwell_jump( rotamer_sample_data ); // returns last_chi_angles_
371  } else if ( move_type_prob > (prob_uniform_ + prob_withinrot_) ) {
372  //ek added in new option to perturb current chi and evaluate according to dunbrack
373  preturb_rot_and_dunbrack_eval( input_residue ); // ?
374  } else if (move_type_prob > prob_uniform_) {
376  residue_dunbrack_library->get_all_rotamer_samples(phi, psi)
377  );
378  perturb_rot_within_well( rotamer_sample_data, previous_chi_angles );
379  }
380  } else {
381  if ( TR.visible( basic::t_debug )) {
382  TR.Debug << "making a uniform jump " << std::endl;
383  }
384  for ( Size ii = 1; ii <= last_nchi_; ++ii ) {
385  last_chi_angles_[ ii ] = RG.uniform() * 360.0 - 180.0;
386  }
387  last_uniform_ = true;
388  }
389  //at the end, have the new angles assigned to last_chi_angles_
390 
391  core::Real proposal_density_reverse(1);
392  core::Real proposal_density_forward(1);
393 
395  proposal_density_reverse = proposal_density(*input_residue, resnum, *residue_type, last_chi_angles_);
396  }
397 
398 
399  if ( TR.visible( basic::t_debug )) {
400  TR.Debug << "residue angles were previously: ";
401 
402  for (Size i = 1; i <= input_residue->nchi(); ++i) {
403  TR.Debug << " " << input_residue->chi( i );;
404  }
405  TR.Debug << std::endl;
406  }
407 
408  /// set the chi
409  for (Size i = 1; i <= input_residue->nchi(); ++i) {
410  input_residue->set_chi( i, last_chi_angles_[ i ] );
411  }
412 
413  if ( TR.visible( basic::t_debug )) {
414  TR.Debug << "Set residue chi angles to:";
415  for (Size i = 1; i <= input_residue->nchi(); ++i) {
416  TR.Debug << " " << last_chi_angles_[ i ];
417  TR.Debug << " " << input_residue->chi( i );
418  }
419  TR.Debug << std::endl;
420  }
421 
422  // swap in a new residue if necessary
423  core::conformation::ResidueOP previous_residue = input_residue;
424  core::conformation::ResidueOP new_residue;
425  if (residue_type() != & previous_residue->type() ) { // apl, note: pointer comparison is faster
426  if ( TR.visible( basic::t_debug )) {
427  TR.Debug << "previous residue " << previous_residue->type().name() << " doesn't match new res-name " << residue_type->name() << std::endl;
428  }
429  new_residue =
431  *input_residue,
432  pose_->conformation(),
433  residue_task.preserve_c_beta());
434  if ( TR.visible( basic::t_debug )) {
435  TR.Debug << "type of new residue created " << new_residue->type().name() << std::endl;
436  }
437  for( Size ii = 1; ii <= residue_type->nchi(); ii++ ){
438  if ( TR.visible( basic::t_debug )) {
439  TR.Debug << " setting chi of new residue " << last_chi_angles_[ ii ] << std::endl;
440  }
441  new_residue->set_chi( ii, numeric::principal_angle_degrees(last_chi_angles_[ ii ] ));
442  if ( TR.visible( basic::t_debug )) {
443  TR.Debug << " input residue chi is now: " << input_residue->chi( ii ) << std::endl;
444  }
445  }
446  }
447  else{
448  new_residue = input_residue;
449  }
450  //core::conformation::ResidueOP new_residue(input_residue);
451  //pose_.replace_residue(resnum, *new_residue, false); //moved to outside apply
452 
453  /// last_chi_angles_ holds radians after this code executes;
454  for ( Size ii = 1; ii <= residue_type->nchi(); ++ii ) {
455  last_chi_angles_[ ii ] = numeric::principal_angle_degrees(last_chi_angles_[ ii ]);
456  //pose.set_chi( ii, resnum, last_chi_angles_[ ii ] );
457  last_chi_angles_[ ii ] = radians( last_chi_angles_[ ii ] );
458  }
459 
460 
462  proposal_density_forward = proposal_density(*input_residue, resnum, previous_residue_type, previous_chi_angles);
463  }
464  last_proposal_density_ratio_ = proposal_density_reverse / proposal_density_forward;
465  if ( TR.visible( basic::t_debug )) {
466  TR.Debug << "last proposal density ratio set to: " << last_proposal_density_ratio_ << std::endl;
467  }
468 
469 
470  update_type();
471  /// comments in this section were distracting me .. they have been moved to the end of the file.
472  return new_residue;
473 
474 }
475 
476 void
479 )
480 {
481  Size rotnum = 0;
482  if ( TR.visible( basic::t_debug )) {
483  TR.Debug << "making a rot-well jump " << std::endl;
484  }
485  // choose a random rotamer according to its probability
486  core::Real random_prob = RG.uniform();
487 
488  //yuan, 01/06/10
489  //modify the rotprob, if want to sample at different temperature
490  utility::vector1< core::Real > rot_prob_list(rotamer_sample_data.size());
491  core::Real sum_prob=0.0;
492  for (rotnum=rotamer_sample_data.size(); rotnum>0; rotnum--)
493  {
494  rot_prob_list[rotnum] = rotamer_sample_data[rotnum].probability();
495  //modified by temperature
496  rot_prob_list[rotnum]=std::pow(rot_prob_list[rotnum],temperature0_/sampling_temperature_);
497  sum_prob+=rot_prob_list[rotnum];
498  }
499 
500  runtime_assert(sum_prob>0.0);
501  for (rotnum=rotamer_sample_data.size(); rotnum>0; rotnum--){rot_prob_list[rotnum]/=sum_prob;}
502 
503  rotnum = 0;
504  /// go through rotamers in decreasing order by probability and stop when the
505  while ( random_prob > 0 ) {
506  if( sample_rotwells_unif_ ){
507  random_prob -= (1.0/rotamer_sample_data.size()); //pick any rotamer with uniform probability
508  rotnum++;
509  }else{
510  //random_prob -= rotamer_sample_data[++rotnum].probability();
511  random_prob -= rot_prob_list[++rotnum];
512  }
513  // loop condition might end up satisfied even if we've walked through all possible rotamers
514  // if the chosen random number was nearly 1
515  // (and interpolation introduced a tiny bit of numerical noise).
516  if ( rotnum == rotamer_sample_data.size() ) break;
517  }
518  //rotamer_sample_data[rotnum].assign_random_chi(last_chi_angles_,RG);
519  rotamer_sample_data[rotnum].assign_random_chi(last_chi_angles_, RG, std::sqrt(sampling_temperature_/temperature0_));
520  for(unsigned int ii = 1; ii <= last_chi_angles_.size(); ii++){
521  last_chi_angles_[ii] = basic::periodic_range( last_chi_angles_[ii], 360.0 );
522  }
523 
524 }
525 
526 void
528 {
529  if ( TR.visible( basic::t_debug )) {
530  TR.Debug << "making a perterb-rot (ek) " << std::endl;
531  }
532  core::Real const max_deviation = 10.0; //arbitrary_value!
533  utility::vector1< core::Real > new_chi_angles;
534  utility::vector1< core::Real > previous_chi_angles = input_residue->chi();
536  //compute probability of acceptance based on dunbrack rotamer distribution
537  /// apl -- unused -- core::Real rand = 0;
538  /// apl -- unused -- core::Real proposed_move_dunbrack_probability = -1;
539  /// apl -- unused -- core::Real before_pert_prob = 0;
540  do {
541  perturb_chi( RG, max_deviation, previous_chi_angles, new_chi_angles );
542  // new_chi_angles.resize( previous_chi_angles.size() );
543  // for(unsigned int chi_i = 1; chi_i <= previous_chi_angles.size(); chi_i++)
544  //{
545  // new_chi_angles[ chi_i ] = basic::periodic_range( ( (2.0*RG.uniform()-1.0)*max_deviation + previous_chi_angles[ chi_i ]) , 360.0 );
546  // }
547 
548  }
549  while( !dunbrack_accept( RG, *input_residue, previous_chi_angles, new_chi_angles ) );
551  TR << "ERROR: you cannot specify accept_according_to_dunbrack_ and preserve_detailed_balance_ both as true!" << std::endl;
552  TR << "Recommend rerunning with 'random perturb current' frequency set to zero." << std::endl;
553  utility_exit();
554  }
555  }
556  last_pertrot_ = true;
557  last_chi_angles_ = new_chi_angles;
558 
559 }
560 
561 void
564  utility::vector1<core::Real> const & previous_chi_angles
565 )
566 {
567  Size rotnum = 0;
568  //ek added in new option to perturb current chi and evaluate according to dunbrack 3/30/10
569  if ( TR.visible( basic::t_debug )) {
570  TR.Debug << "making a within-rot-well jump " << std::endl;
571  }
572  // find the rotamer that has the highest probability of proposing the previous chi angles
573  core::Real max_rot_prob = 0;
574  for (core::Size ii = 1; ii <= rotamer_sample_data.size(); ++ii) {
575  core::Real candidate_rot_prob( rotamer_sample_data[ii].chi_probability(previous_chi_angles) );
576  if (candidate_rot_prob > max_rot_prob) {
577  rotnum = ii;
578  max_rot_prob = candidate_rot_prob;
579  }
580  }
581  last_withinrot_ = true;
582  rotamer_sample_data[rotnum].assign_random_chi(last_chi_angles_,RG);
583  for(unsigned int ii = 1; ii <= last_chi_angles_.size(); ii++){
584  last_chi_angles_[ii] = basic::periodic_range(last_chi_angles_[ii],360.0);
585  }
586  //residue_rotamer_library->assign_random_rotamer_with_bias(
587  // pose.residue( resnum ), *scratch_, RG,
588  // last_chi_angles_, true );
589 
590 }
591 
592 
594  return task_initialized_;
595  }
596 
597 /// @detailed
598 void
600  Pose & pose
601 )
602 {
603  using numeric::conversions::degrees;
604  using numeric::conversions::radians;
605 
606  PROF_START( basic::APPLY_SC_MOVE );
607 
608  init_task(pose);
609 
610  // select a residue to change
611  runtime_assert(packed_residues_.size() > 0);
612 
613  Size resnum;
614  if (next_resnum_) {
615  resnum = next_resnum_;
616  next_resnum_ = 0;
617  } else {
618  resnum = packed_residues_[RG.random_range(1, packed_residues_.size())];
619  }
620  conformation::ResidueOP newresidue = new conformation::Residue( pose.residue( resnum ) );
621  if ( TR.visible( basic::t_debug )) {
622  TR.Debug << "old residue chi is : ";
623  for (Size i = 1; i <= newresidue->nchi(); ++i) TR.Debug << " " << newresidue->chi(i);
624  TR.Debug << std::endl;
625  }
626 
627  conformation::ResidueOP final = make_move( newresidue );
628  if ( TR.visible( basic::t_debug )) {
629  TR.Debug << "new residue chi is : ";
630  for (Size i = 1; i <= pose.residue(resnum).type().nchi(); ++i) TR.Debug << " " << newresidue->chi(i);
631  TR.Debug << std::endl;
632  }
633 
634  //perform replace_residue by default, or if there was a mutation
636  pose.replace_residue(resnum, *final, true);
637  } else { //optionally, perform in-place chi rotations instead of a residue replace. This causes proper kinematic dependency if the atomtree has atoms that are children of the moving residue.
638  core::Size const nchi(final->nchi());
639  for( core::Size i(1); i<=nchi; ++i ){
640  pose.set_chi(i, resnum, final->chi(i));
641  }
642  }
643 
644  if ( TR.visible( basic::t_debug )) {
645  TR.Debug << "pose replaced " << resnum << " " << pose.residue(resnum).type().name() << " has phi-psi " << pose.phi(resnum) << " " << pose.psi(resnum) << " and chi: ";
646 
647  for (Size i = 1; i <= pose.residue(resnum).type().nchi(); ++i) TR.Debug << " " << (pose.residue(resnum).chi(i));
648  TR.Debug << std::endl;
649  }
650  PROF_STOP( basic::APPLY_SC_MOVE );
651 }
652 
655  return "SidechainMover";
656 }
657 
658 
661  core::conformation::Residue const & proposed_residue,
662  core::Size const proposed_resnum,
663  core::chemical::ResidueType const & initial_residue_type,
664  utility::vector1<core::Real> const & initial_chi_angles
665 ) const
666 {
667  utility::vector1<core::Real> const & proposed_chi_angles( proposed_residue.chi() );
668 
669  core::Real density(0);
670 
672  rotamer_library_.get_rsd_library(proposed_residue.type())
673  );
675  dynamic_cast< core::pack::dunbrack::SingleResidueDunbrackLibrary const * >(residue_rotamer_library.get())
676  );
677 
678  if (residue_dunbrack_library) {
679 
680  core::Real const phi( residue_dunbrack_library->get_phi_from_rsd( proposed_residue ) );
681  core::Real const psi( residue_dunbrack_library->get_psi_from_rsd( proposed_residue ) );
682 
684  residue_dunbrack_library->get_all_rotamer_samples(phi, psi)
685  );
686 
688  core::Real probability_threshold = 0.01;
689  if( sample_rotwells_unif_ ){
690  core::Size itr_i = 1;
691  while( itr_i <= rotamer_sample_data.size() &&
692  rotamer_sample_data[ itr_i ].probability() > probability_threshold){
693  most_probable_rotamers.push_back( rotamer_sample_data[ itr_i ] );
694  itr_i++;
695  }
696  rotamer_sample_data = most_probable_rotamers; //replace all rots with most probable ones
697  }
698 
699  core::Real rot_density(0);
700 
701  core::Real max_proposed_rot_prob(0);
702  core::Real max_initial_rot_prob(0);
703 
704  bool calc_withinrot( prob_withinrot_ && proposed_residue.type().aa() == initial_residue_type.aa() );
705 
706  for (core::Size ii = 1; ii <= rotamer_sample_data.size(); ++ii) {
707 
708  core::Real const proposed_rot_prob( rotamer_sample_data[ii].chi_probability(proposed_chi_angles) );
709 
710  if( sample_rotwells_unif_ ){
711  rot_density += ( 1.0 / rotamer_sample_data.size() ) * proposed_rot_prob;
712  }else{
713  //rot_density += rotamer_sample_data[ii].probability() * proposed_rot_prob;
714  rot_density += exp(log(rotamer_sample_data[ii].probability()) + log(proposed_rot_prob));
715  }
716 
717  if (calc_withinrot) {
718 
719  core::Real const initial_rot_prob( rotamer_sample_data[ii].chi_probability(initial_chi_angles) );
720 
721  if (initial_rot_prob > max_initial_rot_prob) {
722  max_initial_rot_prob = initial_rot_prob;
723  max_proposed_rot_prob = proposed_rot_prob;
724  }
725  }
726  }
727 
728  rot_density *= 1 - prob_uniform_ - prob_withinrot_;
729 
730  density += rot_density;
731 
732  if (calc_withinrot) {
733 
734  core::Real const withinrot_density( prob_withinrot_ * max_proposed_rot_prob );
735 
736  density += withinrot_density;
737  }
738  }
739 
740  if (prob_uniform_ || !residue_dunbrack_library) {
741 
742  core::Real uniform_density(1);
743 
744  for (core::Size ii = 1; ii <= proposed_residue.nchi(); ++ii) {
745  uniform_density *= 1.0/360.0;
746  }
747 
748  if (residue_dunbrack_library) uniform_density *= prob_uniform_;
749 
750  density += uniform_density;
751  }
752 
753  // Probability of selecting the given ResidueType
754  // This isn't needed now, but should be changed if the way the ResidueTypes
755  // are sampled changes.
756  core::pack::task::ResidueLevelTask const & residue_task(task_->residue_task(proposed_resnum));
757  density *= 1.0/residue_task.allowed_residue_types().size();
758  return density;
759 }
760 
761 /// @detailed
762 void
764  Pose &
765 )
766 {
767 
768 }
769 
770 /// @detailed
771 /// all sidechains that might be changed are replaced with ideal coordinates that have
772 /// the original chi angles
773 void
775  core::pose::Pose & pose
776 )
777 {
779 
780  init_task(pose);
781 
782  for (Size i = 1; i <= packed_residues_.size(); ++i) {
783 
784  Size const resnum(packed_residues_[i]);
785 
786  // get the residue type and residue level task
787  chemical::ResidueType const & residue_type(pose.residue_type(resnum));
788  pack::task::ResidueLevelTask const & residue_task(task_->residue_task(resnum));
789 
790  // disable proline idealization for now
791  if (residue_type.aa() == chemical::aa_pro) continue;
792 
793  // save original chi angles
794  if (residue_type.nchi() > chi.size()) chi.resize(residue_type.nchi());
795  for (Size chinum = 1; chinum <= residue_type.nchi(); ++chinum) {
796  chi[chinum] = pose.chi(chinum, resnum);
797  }
798 
799  // create a new residue and replace the old one with it
800  conformation::ResidueOP new_residue(
801  conformation::ResidueFactory::create_residue(residue_type, pose.residue(resnum), pose.conformation(),
802  residue_task.preserve_c_beta())
803  );
804  pose.replace_residue(resnum, *new_residue, false);
805 
806  // put original chi angles back
807  for (Size chinum = 1; chinum <= residue_type.nchi(); ++chinum) {
808  pose.set_chi(chinum, resnum, chi[chinum]);
809  }
810  }
811 }
812 
815 {
816  return rotamer_library_;
817 }
818 
821 {
822  return task_factory_;
823 }
824 
825 void
828 )
829 {
831 }
832 
835 {
836  return task_;
837 }
838 
839 void
842 )
843 {
845 
846  task_ = task;
847 
848  // update the list of residues being packed
849  packed_residues_.clear();
850  residue_packed_.resize(task_->total_residue());
851  for (Size i = 1; i <= task_->total_residue(); ++i) {
852 
853  // loop over all possible residue types and check if any have chi angles
854  residue_packed_[i] = false;
855  core::pack::task::ResidueLevelTask const & residue_task(task->residue_task(i));
856  for (ResidueLevelTask::ResidueTypeCOPListConstIter iter(residue_task.allowed_residue_types_begin());
857  iter != residue_task.allowed_residue_types_end(); ++iter) {
858 
859  // temporarily exclude proline residues from side chain sampling
860  if ((*iter)->nchi() > 0 && (*iter)->aa() != core::chemical::aa_pro) {
861  packed_residues_.push_back(i);
862  residue_packed_[i] = true;
863  break;
864  }
865  }
866  }
867 }
868 
871 {
872  return prob_uniform_;
873 }
874 
875 void
877  core::Real prob_uniform
878 )
879 {
881 }
882 
885 {
886  return prob_withinrot_;
887 }
888 
889 void
891  core::Real prob_withinrot
892 )
893 {
895 }
896 
900 }
901 
902 void
904  core::Real prob_pert
905 )
906 {
907  prob_random_pert_to_current_ = prob_pert;
908 }
909 
910 bool
912 {
914 }
915 
916 void
918  bool preserve_detailed_balance
919 )
920 {
922 }
923 
924 bool
926 {
928 }
929 
930 void
932  bool const change_chi_without_replacing_residue
933 )
934 {
936 }
937 
940  core::pose::Pose & //pose
941 )
942 {
944 }
945 
948  core::pose::Pose & pose
949 )
950 {
951  Real static const pi(numeric::NumericTraits<Real>::pi());
952 
953  init_task(pose);
954 
956 
957  for (core::Size i = 1; i <= packed_residues_.size(); ++i) {
958 
959  core::Size const resnum(packed_residues_[i]);
960 
961  bool all_names_match = true;
962 
963  // we only monitor DOFs of residues that won't change primary type
964  // check to see if pose residue type has the same name as all allowed residue types
965  core::pack::task::ResidueLevelTask const & residueleveltask(task_->residue_task(resnum));
966  for (core::pack::task::ResidueLevelTask::ResidueTypeCOPListConstIter iter(residueleveltask.allowed_residue_types_begin());
967  iter != residueleveltask.allowed_residue_types_end(); ++iter) {
968 
969  if ((*iter)->name3() != pose.residue_type(resnum).name3()) {
970  all_names_match = false;
971  break;
972  }
973  }
974 
975  if (!all_names_match) break;
976 
977  for (core::Size j = 1; j <= pose.residue_type(resnum).nchi(); ++j) {
978 
979  core::id::TorsionID chi_torsion(resnum, core::id::CHI, j);
980  core::id::DOF_ID chi_dof(pose.conformation().dof_id_from_torsion_id(chi_torsion));
981  if (chi_dof.valid()) range_vector.push_back(core::id::DOF_ID_Range(chi_dof, -pi, pi));
982  }
983  }
984 
985  return range_vector;
986 }
987 
990 {
991  return packed_residues_;
992 }
993 
996 {
997  return residue_packed_;
998 }
999 
1000 core::Size
1002 {
1003  return next_resnum_;
1004 }
1005 
1006 void
1008  core::Size resnum
1009 )
1010 {
1011  runtime_assert(resnum == 0 || residue_packed_[resnum]);
1012  next_resnum_ = resnum;
1013 }
1014 
1015 core::Size
1017 {
1018  return last_nchi_;
1019 }
1020 
1021 bool
1023 {
1024  return last_mutation_;
1025 }
1026 
1027 bool
1029 {
1030  return last_uniform_;
1031 }
1032 
1033 bool
1035 {
1036  return last_withinrot_;
1037 }
1038 
1039 core::Real
1041 {
1043 }
1044 
1045 /// @detailed
1046 /// All move types are prefixed with "sc". Sections are divided by underscores.
1047 /// The next section indicates whether a mutation was made ("mut") or not ("chi").
1048 /// The last section indicates wehter chi sampling was uniform ("unif"), used
1049 /// Dunbrack rotamer statistics ("rot"), or whether no chi angles existed in the
1050 /// placed residue ("none").
1051 void
1053 {
1054  std::stringstream mt;
1055 
1056  mt << "sc_" << (last_mutation_ ? "mut" : "chi") << "_" << (last_nchi_ ? (last_uniform_ ? "unif" : (last_withinrot_ ? "withinrot" : (last_pertrot_ ? "pertrot" : "rot"))) : "none");
1057 
1058  std::string const new_type(mt.str());
1059  type(new_type);
1060 }
1061 
1062 
1063 /// APL NOTE:
1064 /// The following block of comments was originally in make_move
1065 /// but have been moved here
1066 
1067  //Size chinum(1);
1068  // use Dunbrack statistics to bias chi angle sampling
1069  //if (RG.uniform() > prob_uniform_ && residue_dunbrack_library) {
1070  //
1071  // // get indices of the phi and psi bins, plus extra information we don't need
1072  // Size phibin, psibin, phibin_next, psibin_next;
1073  // Real phi_err, psi_err;
1074  // residue_dunbrack_library->get_phi_interpolate_bin(pose.phi(resnum), pose.psi(resnum), phibin, psibin,
1075  // phibin_next, psibin_next, phi_err, psi_err);
1076 
1077  // // choose a random rotamer according to its probability
1078  // Real accprob = RG.uniform();
1079  // for (Size rotnum = 1; rotnum <= residue_dunbrack_library->nrots_per_bin(); rotnum++) {
1080  //
1081  // core::pack::dunbrack::DunbrackRotamer< core::pack::dunbrack::FOUR > rotamer(
1082  // residue_dunbrack_library->retrieve_rotamer(phibin, psibin, rotnum)
1083  // );
1084 
1085  // // keep looking if we haven't decremented the accumulated probability below zero
1086  // accprob -= rotamer.rotamer_probability();
1087  // if (accprob > 0) continue;
1088 
1089  // // for chi angles which have statistics, sample according to rotamer SD and mean
1090  // TR.Debug << "Using rotamer " << rotnum << ": ";
1091  // for ( ; chinum <= residue_dunbrack_library->nchi_aa(); ++chinum) {
1092  // TR.Debug << " " << rotamer.chi_mean(chinum) << "(" << rotamer.chi_sd(chinum) << ")";
1093  // last_chi_angles_[chinum] = radians(RG.gaussian()*rotamer.chi_sd(chinum) + rotamer.chi_mean(chinum));
1094  // pose.set_chi(chinum, resnum, degrees(last_chi_angles_[chinum]));
1095  // }
1096  // TR.Debug << std::endl;
1097 
1098  // last_uniform_ = false;
1099  // break;
1100  // }
1101  //}
1102 
1103  // any/all remaning chi angles are chosen uniformly
1104  //for ( ; chinum <= residue_type->nchi(); ++chinum) {
1105  // last_chi_angles_[chinum] = RG.uniform()*numeric::constants::d::pi_2 - numeric::constants::d::pi;
1106  // pose.set_chi(chinum, resnum, degrees(last_chi_angles_[chinum]));
1107  //}
1108 
1109 
1110  // TR << "new chi angles:";
1111  // utility::vector1< Real > const & nchis(pose.residue(resnum).chi());
1112  // for (core::Size i = 1; i <= nchis.size(); ++i)
1113  // TR << " " << nchis[i];
1114  // TR << std::endl;
1115 
1116 
1117  // TR.Debug << "Set residue chi angles to:";
1118  // for (Size i = 1; i <= residue_type->nchi(); ++i) TR.Debug << " " << degrees(last_chi_angles_[i]);
1119  // TR.Debug << std::endl;
1120 
1121 
1122 
1123 } // sidechain_moves
1124 } // simple_moves
1125 } // protocols