Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SidechainMCMover.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/SidechainMCMover.cc
11 /// @brief implementation of SidechainMCMover class and functions
12 /// @author Colin A. Smith (colin.smith@ucsf.edu)
13 
17 
18 #include <basic/prof.hh>
19 
20 // Core Headers
23 // AUTO-REMOVED #include <core/conformation/ResidueFactory.hh>
26 #include <core/pose/Pose.hh>
27 // AUTO-REMOVED #include <core/pack/dunbrack/DunbrackRotamer.hh>
28 // AUTO-REMOVED #include <core/pack/dunbrack/SingleResidueDunbrackLibrary.hh>
29 // AUTO-REMOVED #include <core/pack/dunbrack/RotamerLibraryScratchSpace.hh>
30 // AUTO-REMOVED #include <core/pack/task/operation/TaskOperations.hh>
31 // AUTO-REMOVED #include <core/scoring/ScoringManager.hh>
32 #include <core/types.hh>
33 #include <basic/Tracer.hh>
34 // AUTO-REMOVED #include <basic/basic.hh>
39 
41 #include <utility/tag/Tag.hh>
42 
43 // Numeric Headers
44 // AUTO-REMOVED #include <numeric/angle.functions.hh>
45 // AUTO-REMOVED #include <numeric/constants.hh>
46 // AUTO-REMOVED #include <numeric/conversions.hh>
47 #include <numeric/random/random.hh>
48 
49 // AUTO-REMOVED #include <core/scoring/TenANeighborGraph.hh>
50 // AUTO-REMOVED #include <core/scoring/Energies.hh>
51 
52 
53 // C++ Headers
54 #include <ostream>
55 #include <sstream>
56 // AUTO-REMOVED #include <fstream>
57 // AUTO-REMOVED #include <utility/fixedsizearray1.hh>
58 
59 #include <utility/string_util.hh>
60 #include <utility/vector0.hh>
61 #include <utility/vector1.hh>
62 
63 //Auto Headers
64 #include <utility/excn/Exceptions.hh>
66 
67 #ifdef WIN_PYROSETTA
69 #endif
70 
71 
72 using namespace core;
73 using namespace core::pose;
74 using namespace basic;
75 using namespace protocols::moves;
76 
77 
78 static numeric::random::RandomGenerator Rg(38627227);
79 static basic::Tracer TR("protocols.simple_moves.sidechain_moves.SidechainMCMover");
80 
81 namespace protocols {
82 namespace simple_moves {
83 namespace sidechain_moves {
84 
86 SidechainMCMoverCreator::keyname() const {
87  return SidechainMCMoverCreator::mover_name();
88 }
89 
91 SidechainMCMoverCreator::create_mover() const {
92  return new SidechainMCMover;
93 }
94 
96 SidechainMCMoverCreator::mover_name() {
97  return "SidechainMC";
98 }
99 
100 SidechainMCMover::SidechainMCMover():
101  protocols::simple_moves::sidechain_moves::SidechainMover(),
102  current_(),
103  previous_(),
104  best_(),
105  temperature_(0),
106  ntrials_(0),
107  best_energy_(0),
108  sfxn_(),
109  inherit_scorefxn_temperature_(false),
110  ig_(0),
111  accepts_(0),
112  current_ntrial_(0),
113  score_pre_apply_(0),
114  score_post_apply_(0),
115  metropolis_hastings_mover_(0)
116 {}
117 
119  core::pack::dunbrack::RotamerLibrary const & rotamer_library
120 ):
121  protocols::simple_moves::sidechain_moves::SidechainMover(rotamer_library),
122  current_(),
123  previous_(),
124  best_(),
125  temperature_(0),
126  ntrials_(0),
127  best_energy_(0),
128  sfxn_(),
129  inherit_scorefxn_temperature_(false),
130  ig_(0),
131  accepts_(0),
132  current_ntrial_(0),
133  score_pre_apply_(0),
134  score_post_apply_(0),
135  metropolis_hastings_mover_(0)
136 {}
137 
139 
140 
141 void
143  ig_ = new core::pack::interaction_graph::SimpleInteractionGraph(); //commented out debug
144  //(*sfxn)(pose); //gets called in apply
145  set_scorefunction( *sfxn );
146  ig_->set_scorefunction( *sfxn );
147  //ig_->initialize( pose ); //gets called in apply. we can't count on the graph being up-to-date between setup and apply
148 }
149 
150 void
151 SidechainMCMover::show_counters( std::ostream & out){
152  out << "SCMCMover: trials " << current_ntrial_ << " accepts= " << (accepts_/current_ntrial_) << std::endl;
153 }
154 
158 }
159 
163 }
164 
165 /// @detailed
166 void
168  Pose & pose
169 )
170 {
171 
172  bool const DEBUG = false;
173 
174  using namespace core::scoring;
175  using namespace protocols;
176  using namespace protocols::moves;
177  //using namespace protocols::fast_sc_mover;
178 
180  core::Real current_energy = sfxn_(pose);
181  score_pre_apply_ = current_energy;
182  init_task(pose);
183 
184  current_.resize(pose.total_residue());
185  previous_.resize(pose.total_residue());
186  best_.resize(pose.total_residue());
187  runtime_assert(temperature_ != 0);
188  runtime_assert(ntrials_ != 0);
189  runtime_assert(packed_residues().size() > 0);
190 
192  runtime_assert(metropolis_hastings_mover_);
193  // update temperature every time in case temperature changes are implemented in the future
194  set_temperature(metropolis_hastings_mover_->monte_carlo()->temperature());
195  }
196 
197  // for debugging
198  pose::Pose temp(pose);
199  pose::Pose dummy(pose);
200  //
201 
202  for(core::Size itr = 1; itr <= pose.total_residue(); itr++){
203  current_[ itr ] = new core::conformation::Residue(pose.residue( itr ));
204  }
205 
206  // PROF_START( SIMPLEINTGRAPH );
207  //SimpleInteractionGraphOP ig(new SimpleInteractionGraph()); //commented out debug
208  //ig->set_scorefunction( sfxn_ ); //commented out debug
209  ig_->initialize( pose ); //commented out debug
211  // PROF_STOP( SIMPLEINTGRAPH );
212  //runtime_assert(ig_ != 0);
213 
214  for( core::Size iter_i = 1; iter_i <= ntrials_; iter_i++){
215  //pick randomly
216  core::Size rand_res;
217  do {
218  //pick residue, respecting underlying packer task
219  rand_res = packed_residues()[Rg.random_range(1, packed_residues().size())];
220  }while ( pose.residue( rand_res ).name1() == 'P'); //SidechainMover cannot sample proline rotamers? (is this true?)
221 
222  core::conformation::ResidueOP new_state( new core::conformation::Residue( pose.residue( rand_res ) ) );
223 
224  /// APL Note: you have to remove output if you're trying to optimize.
225  if ( TR.visible( basic::t_debug )) {
226  TR.Debug << "old-chi-angles: ";
227  for(unsigned int i = 1; i <= new_state->nchi(); i++){
228  TR.Debug << new_state->chi( i ) << " ";
229  }
230  TR.Debug << std::endl;
231  }
232  // if( !task_initialized() ){
233  // init_task( pose );
234  // }
235  new_state = make_move( new_state );
236  //new_state->update_actcoord();
237  if ( TR.visible( basic::t_debug )) {
238  TR.Debug << "new-chi-angles: ";
239  for(unsigned int i = 1; i <= new_state->nchi(); i++){
240  TR.Debug << new_state->chi( i ) << " ";
241  }
242  TR.Debug << std::endl;
243  }
244 
245 
246  PROF_START( SIMPLEINTGRAPH );
247  core::Real delta_energy = ig_->consider_substitution( rand_res, new_state );
248  PROF_STOP( SIMPLEINTGRAPH );
249 
250  if( DEBUG )
251  {//debug
252  core::Real s1= sfxn_(temp);
253  dummy = temp;
254  //for(unsigned int i = 1; i <= new_state->nchi(); i++ ){
255  //dummy.set_chi( i, rand_res, new_state->chi( i ) );
256  //}
257  dummy.replace_residue( rand_res, *new_state, true );
258  core::Real s2 = sfxn_(dummy);
259 
260  if( (s1 - s2) - delta_energy > 0.05 ) {
261  TR.Debug << "WARNING: ENERGIES DON'T MATCH UP! " << s1 << " " << s2 << " " << (s1 - s2) << " " << delta_energy << std::endl;
262  dummy.dump_pdb("dummy.pdb");
263  temp.dump_pdb("temp.pdb");
264  //exit(1);
265 
266  }else{
267  TR.Debug << "energies match up " << std::endl;
268  }
269  }//debug
270 
271 
272  if( pass_metropolis( delta_energy, SidechainMover::last_proposal_density_ratio() ) ){ //ek
273  if( DEBUG )
274  { //debug//
275  core::Real s1= sfxn_(temp);
276  temp.replace_residue( rand_res, *new_state, true );
277  core::Real s2 = sfxn_(dummy);
278  TR.Debug << "current energy after accept: " << sfxn_(temp) << " delta " << (s2-s1) << std::endl;
279  //for( core::Size itr_i = 1; itr_i <= new_state->nchi(); itr_i++ ){
280  //temp.set_chi( itr_i, rand_res, new_state->chi(itr_i) );
281  //}
282  }
283 
284  if ( TR.visible( basic::t_debug )) {
285  TR.Debug << "passed metropolis! assigning new move to current " << std::endl;
286  }
287  previous_[ rand_res ] = current_[ rand_res ] ;
288 
289  PROF_START( SIMPLEINTGRAPH );
290  ig_->commit_change( rand_res );
291  PROF_STOP( SIMPLEINTGRAPH );
292  current_energy -= delta_energy;
293  current_[ rand_res ] = new_state;
294  if( ( current_energy ) < best_energy_ ){
295  best_[ rand_res ] = new_state;
296  best_energy_ = current_energy;
297  }
298  } else{ //rejected metropolis criterion
299  PROF_START( SIMPLEINTGRAPH );
300  ig_->reject_change( rand_res );
301  PROF_STOP( SIMPLEINTGRAPH );
302  }
303  } // n_iterations
304 
305 
306  for(core::Size res_i = 1; res_i <= current_.size(); res_i++ ){
307  //for(core::Size chi_i = 1; chi_i <= current_[ res_i ]->nchi(); chi_i++){
308  //pose.set_chi( chi_i, res_i, current_[ res_i ]->chi( chi_i ) );
309  //}
310  pose.replace_residue( res_i, (*current_[ res_i ]), true );
311  }
312 
313  score_post_apply_ = current_energy;
315  score_post_apply_ = sfxn_(pose);
316  //TR << "Score Actual: " << score_post_apply_ << " Accumulated: " << current_energy << " Delta: " << current_energy - score_post_apply_ << std::endl;
317  }
318 
319  type("sc_mc");
320 }
321 
324  return "SidechainMCMover";
325 }
326 
327 bool
329 
330  core::Real boltz_factor = delta_energy / temperature_;
331  core::Real probability = std::exp( std::min( 40.0, std::max( -40.0, boltz_factor ))) * last_proposal_density_ratio ;
332 
333  if( probability < 1 && Rg.uniform() >= probability ) {
334  current_ntrial_++;
335  if ( TR.visible( basic::t_debug )) {
336  TR.Debug << "delta energy is " << delta_energy << " probability: " << probability << " accepted: FALSE " << std::endl;
337  }
338  return false;
339  }
340  else {
341  accepts_++;
342  current_ntrial_++;
343  if ( TR.visible( basic::t_debug )) {
344  TR.Debug << "delta energy is " << delta_energy << " probability: " << probability << " accepted: TRUE" << std::endl;
345  }
346  return true;
347  }
348 }
349 
350 void
352 
353  // code duplication: should really call SidechainMover::parse_my_tag() instead of having most of the code below
354  if ( tag->hasOption("task_operations") ) {
355 
357 
358  std::string const t_o_val( tag->getOption<std::string>("task_operations") );
359  typedef utility::vector1< std::string > StringVec;
360  StringVec const t_o_keys( utility::string_split( t_o_val, ',' ) );
361  for ( StringVec::const_iterator t_o_key( t_o_keys.begin() ), end( t_o_keys.end() );
362  t_o_key != end; ++t_o_key ) {
363  if ( data.has( "task_operations", *t_o_key ) ) {
364  new_task_factory->push_back( data.get< core::pack::task::operation::TaskOperation* >( "task_operations", *t_o_key ) );
365  } else {
366  throw utility::excn::EXCN_RosettaScriptsOption("TaskOperation " + *t_o_key + " not found in protocols::moves::DataMap.");
367  }
368  }
369 
370  set_task_factory(new_task_factory);
371 
372  } else {
373 
375  set_task( pt );
376  pt->restrict_to_repacking();
377  // probably should call init_task(), but it's cleaner if we wait untill it's called in apply()
378  }
379 
380  ntrials_ = tag->getOption<core::Size>( "ntrials", 10000 );
381  set_preserve_detailed_balance( tag->getOption<bool>( "preserve_detailed_balance", 1 ) );
382  temperature_ = tag->getOption<core::Real>( "temperature", 1.0 );
383  set_inherit_scorefxn_temperature( tag->getOption<bool>( "inherit_scorefxn_temperature", inherit_scorefxn_temperature() ) );
384 
385  set_prob_uniform( tag->getOption<core::Real>( "prob_uniform", 0.0 ) );
386  set_prob_withinrot( tag->getOption<core::Real>( "prob_withinrot", 0.0 ) );
387  set_prob_random_pert_current( tag->getOption<core::Real>( "prob_random_pert_current", 0.0 ) );
388  core::Real between_rot = 1.0 - prob_uniform() - prob_withinrot () - prob_random_pert_current();
389 
390  std::string const scorefxn( tag->getOption<std::string>( "scorefxn", "score12" ) );
391  using namespace core::scoring;
392  ScoreFunctionOP sfxn = new ScoreFunction(*data.get< ScoreFunction * >( "scorefxns", scorefxn ) );
393  setup( sfxn );
394 
395  TR<<"Initialized SidechainMCMover from .xml file: ntrials="<<ntrials_<< " temperature= "<< temperature_<<" detailed balance="<<(preserve_detailed_balance()?"true":"false")<<" scorefunction="<<scorefxn<<" Probablities uniform/withinrot/random_pert/betweenrot: "<<prob_uniform()<<'/'<<prob_withinrot ()<<'/'<<prob_random_pert_current()<<'/'<<between_rot<<std::endl;
396 }
397 
398 void
400  core::pose::Pose & pose,
402  core::Size cycle //default=0; non-zero if trajectory is restarted
403 )
404 {
405  SidechainMover::initialize_simulation(pose, metropolis_hastings_mover,cycle);
406 
408  runtime_assert(metropolis_hastings_mover_);
409  set_scorefunction(metropolis_hastings_mover_->monte_carlo()->score_function());
410  set_temperature(metropolis_hastings_mover_->monte_carlo()->temperature());
411  }
412 }
413 
414 
415 } // sidechain_moves
416 } // simple_moves
417 } // protocols