Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GenericMonteCarloMover.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 src/protocols/moves/GenericMonteCarloMover.cc
11 /// @brief perform a given mover and sample structures by MonteCarlo
12 /// @detailed The score evaluation of pose during MC after applying mover is done by
13 /// either FilterOP that can do report_sm() or ScoreFunctionOP.
14 /// By setting sample_type_ to high, you can also sample the pose that have higher score.
15 /// @author Nobuyasu Koga ( nobuyasu@uw.edu )
16 
17 
18 // Unit Headers
23 
24 // C/C++ headers
25 #include <iostream>
26 #include <iterator>
27 #include <string>
28 
29 // External headers
30 #include <boost/bind.hpp>
31 #include <boost/foreach.hpp>
32 #include <boost/function.hpp>
33 #define foreach BOOST_FOREACH
34 #include <algorithm>
35 
36 // Utility headers
37 #include <basic/Tracer.hh>
38 #include <ObjexxFCL/format.hh>
39 #include <numeric/random/random.hh>
40 #include <utility/tag/Tag.hh>
42 
43 // Project Headers
44 #include <core/pose/Pose.hh>
50 
51 // Package Headers
53 #include <protocols/moves/Mover.hh>
56 #include <fstream>
57 #include <utility/io/izstream.hh>
58 #include <sstream>
59 #include <core/pose/util.hh>
62 
63 static basic::Tracer TR("protocols.simple_moves.GenericMonteCarloMover");
64 static basic::Tracer TR_energies("protocols.simple_moves.GenericMonteCarloMover.individual_energies");
65 static numeric::random::RandomGenerator mc_RG(61452); // <- Magic number, do not change it!!!
66 
67 using namespace core;
68 
69 namespace protocols {
70 namespace simple_moves {
71 
72 using namespace ObjexxFCL::fmt;
73 
75 GenericMonteCarloMoverCreator::keyname() const
76 {
77  return GenericMonteCarloMoverCreator::mover_name();
78 }
79 
81 GenericMonteCarloMoverCreator::create_mover() const {
82  return new GenericMonteCarloMover;
83 }
84 
86 GenericMonteCarloMoverCreator::mover_name()
87 {
88  return "GenericMonteCarlo";
89 }
90 
91 /// @brief default constructor
92 GenericMonteCarloMover::GenericMonteCarloMover():
93  Mover("GenericMonteCarlo"),
94  maxtrials_( 10 ),
95  task_scaling_( 5 ),
96  mover_( NULL ),
97  scorefxn_( NULL ),
98  temperature_( 0.0 ),
99  sample_type_( "low" ),
100  drift_( true ),
101  preapply_( true ),
102  recover_low_( true ),
103  rank_by_filter_( 1 ),
104  boltz_rank_( false ),
105  last_accepted_pose_( NULL ),
106  lowest_score_pose_( NULL ),
107  stopping_condition_( NULL ),
108  mover_stopping_condition_( NULL ),
109  adaptive_movers_( false ),
110  adaptation_period_( 0 ),
111  saved_accept_file_name_( "" ),
112  saved_trial_number_file_( "" ),
113  mover_tag_( NULL ),
114  reset_baselines_( true )
115 {
116  initialize();
117 }
118 
119 
120 /// @brief value constructor without a score function
121 
123  Size const maxtrials,
124  Size const task_scaling,
125  MoverOP const & mover,
126  Real const temperature,
127  String const sample_type,
128  bool const drift ) :
129  Super("GenericMonteCarlo"),
130  maxtrials_( maxtrials ),
131  task_scaling_( task_scaling ),
132  mover_( mover ),
133  temperature_( temperature ),
134  sample_type_( sample_type ),
135  drift_( drift ),
136  preapply_( true ),
137  recover_low_( true ),
138  rank_by_filter_(1),
139  boltz_rank_( false ),
140  last_accepted_pose_( NULL ),
141  lowest_score_pose_( NULL ),
142  saved_accept_file_name_( "" ),
143  mover_tag_( NULL ),
144  reset_baselines_( true )
145 {
146  initialize();
147 }
148 
149 
150 /// @brief value constructor with a TaskFactory
152  Size const maxtrials,
153  Size const task_scaling,
154  MoverOP const & mover,
155  TaskFactoryOP factory_in,
156  Real const temperature,
157  String const sample_type,
158  bool const drift ) :
159  Super("GenericMonteCarlo"),
160  maxtrials_( maxtrials ),
161  task_scaling_( task_scaling ),
162  mover_( mover ),
163  task_( NULL ),
164  factory_ (factory_in),
165  temperature_( temperature ),
166  sample_type_( sample_type ),
167  drift_( drift ),
168  preapply_( true ),
169  recover_low_( true ),
170  rank_by_filter_(1),
171  boltz_rank_( false ),
172  saved_accept_file_name_( "" ),
173  mover_tag_( NULL ),
174  reset_baselines_( true )
175 {
176  initialize();
177 }
178 
179 
180 /// @brief destructor
182 
183 /// @brief clone this object
186 {
187  return new GenericMonteCarloMover( *this );
188 }
189 
191 
192 /// @brief create this type of object
195 {
196  return new GenericMonteCarloMover();
197 }
198 
199 /// @brief initialize
200 void
202 {
203  last_accepted_scores_.clear();
204  if( sample_type_ == "high" ){
205  flip_sign_ = -1;
206  }else if( sample_type_ == "low" ){
207  flip_sign_ = 1;
208  }else{
209  TR << "WARNING: the sample type, " << sample_type_ << ", is not defined." << std::endl;
210  runtime_assert( false );
211  }
212  trial_counter_ = 0;
213  accept_counter_ = 0;
214  energy_gap_counter_ = 0.0;
215 
216  // trigger initialization
217  next_trigger_id_ = 1;
218 }
219 
220 /// @brief return the last accepted pose
223 {
224  return last_accepted_pose_;
225 }
226 
227 /// @brief return the last accepted score
230 {
231  return last_accepted_score_;
232 }
233 
234 /// @brief return the lowest score pose
237 {
238  return lowest_score_pose_;
239 }
240 
241 /// @brief return the lowest score
244 {
245  return lowest_score_;
246 }
247 
248 /// @brief return the lowest score
251 {
252  return current_score_;
253 }
254 
255 /// @brief return mc_accepted
256 MCA
258 {
259  return mc_accepted_;
260 }
261 
262 /// @brief set max trials of monte carlo iterations
263 void
265 {
266  maxtrials_ = ntrial;
267 }
268 
269 /// @brief set task multiplier to calculate trials from task
270 void
272 {
273  task_scaling_ = scaling;
274 }
275 
276 /// @brief set mover
277 void
279 {
280  mover_ = mover;
281 }
282 
283 /// @brief set filter
284 /// Pose is evaluated by FilterOP which can do report_sm() or ScoreFunctionOP during MC trials
285 /// You can choose either way FilterOP or ScoreFunction.
286 void
287 GenericMonteCarloMover::add_filter( FilterOP filter, bool const adaptive, Real const temp, String const sample_type, bool rank_by)
288 {
289  filters_.push_back( filter );
290  if(rank_by) {
291  rank_by_filter_ = filters_.size();
292  }
293  adaptive_.push_back( adaptive );
294  temperatures_.push_back( temp );
295  sample_types_.push_back( sample_type );
296  last_accepted_scores_.assign( filters_.size(), 100000 );
297  num_rejections_.push_back(0);
298  scorefxn_ = NULL;
299 }
300 
301 /// @brief set scorefxn
302 /// Pose is evaluated by FilterOP which can do report_sm() or ScoreFunctionOP during MC trials
303 /// You can choose either way FilterOP or ScoreFunction.
304 void
306 {
307  scorefxn_ = sfxn;
308  filters_.clear();
309 }
310 
311 /// @brief set temperatrue
312 void
314 {
315  temperature_ = temp;
316 }
317 
318 /// @brief set sample type, high or low
319 /// when sample_type == high, sample pose which have higher value of scorey
320 /// when sample_type == low, sample pose which have lower value of score
321 void
323 {
324  if( sample_type_ != "high" && sample_type_ != "low" ){
325  TR << "WARNING !! the sample type, " << type << ", is not defined." << std::endl;
326  runtime_assert( false );
327  }
328  sample_type_ = type;
329 }
330 
331 /// @brief if drift=false, the pose is set back to the initial pose
332 /// Of course, this is not MC sampling.
333 void
335  drift_ = drift;
336 }
337 
338 /// @brief if preapply=true, auto-accept the first application of the submover,
339 /// ignoring boltzman criteria.
340 void
341 GenericMonteCarloMover::set_preapply( bool const preapply ) {
342  preapply_ = preapply;
343 }
344 
345 /// @brief if recover_low=true, after apply() the returned
346 /// is the lowest energy structure, rather than the last accepted structure.
347 void
348 GenericMonteCarloMover::set_recover_low( bool const recover_low ){
350 }
351 
352 /// @brief if boltz_rank=true, rank structures by the temperature-weighted
353 /// sum of scores, rather than a single filter
354 void
355 GenericMonteCarloMover::set_boltz_rank( bool const boltz_rank ){
356  boltz_rank_ = boltz_rank;
357 }
358 
359 /// @brief show scores of last_accepted_score and lowest_score
360 void
361 GenericMonteCarloMover::show_scores( std::ostream & out ) const
362 {
363  if( sample_type_ == "high" ){
364  out << "Higher score sampled: trial=" << I( 5, trial_counter_ ) << ", score(current/last_accepted/best)=";
365  }else{
366  out << "Lower score sampled: trial=" << I( 5, trial_counter_ ) << ", score(current/last_accepted/best)=";
367  }
368  out << F( 9, 3, flip_sign_*current_score() ) << '/'
369  << F( 9, 3, flip_sign_*last_accepted_score() )<< '/'
370  << F( 9, 3, flip_sign_*lowest_score() ) << std::endl;
371 }
372 
373 /// @brief show counters
374 void
375 GenericMonteCarloMover::show_counters( std::ostream & out ) const
376 {
377  String const & mover( mover_->get_name() );
378  String evaluation;
379  if( scorefxn_ ){
380  evaluation = "ScoreXXX"; // should we have name for ScoreFunction ?
381  }
382  int const ntrials( trial_counter_ );
383  int const accepts( accept_counter_ );
384  Real const energy_gap( energy_gap_counter_ );
385  if( accepts > 0 ){
386  out << "mover=" << LJ( 16, mover ) << " Score_eval=" << LJ( 16, evaluation ) <<
387  " trials= " << I( 5, ntrials ) << "; " <<
388  " accepts= " << F( 6, 3, Real( accepts )/ntrials ) << "; " <<
389  " energy_gap/trial= " << F( 8, 3, Real( flip_sign_ * energy_gap ) / ntrials ) << std::endl;
390  }else{
391  out << "mover=" << A( 16, mover ) << " Score_eval=" << A( 16, evaluation )
392  << " trials= " << I( 6, ntrials ) << " NO ACCEPTS." << std::endl;
393  }
394  if(num_rejections_.size()) {
395  out << "Number of rejections per filter: ";
396  for( core::Size ii(1); ii <= num_rejections_.size(); ++ii) {
397  out << num_rejections_[ii] << " ";
398  }
399  out << std::endl;
400  }
401 }
402 
403 /// @brief return the simulation state to the lowest energy structure we've seen
404 void
406 {
407  if( lowest_score_pose_ ) {
408  pose = *lowest_score_pose_;
410  }else{
411  // Case of that lowest_score_pose_ was never updated in MonteCarlo
412  TR << " No lowest_score_pose_ exists, probably because all movers or filters failed. " << std::endl;
413  }
414 }
415 
416 
417 /// @brief reset this GenericMonteCarloMover
418 void
420 {
421  if( filters_.size() == 0 ) {
422  lowest_score_ = scoring( pose );
423  } else {
424  last_accepted_scores_.clear();
425  for( Size index = 1; index <= filters_.size(); ++index ){
426  protocols::filters::FilterCOP filter( filters_[ index ] );
427  Real const flip( sample_types_[ index ] == "high" ? -1 : 1 );
428  last_accepted_scores_.push_back( flip * filter->report_sm( pose ) );
429  }
430  }// fi filters_.size()
431 
432  lowest_score_pose_ = new Pose( pose );
433  last_accepted_pose_ = new Pose( pose );
435 
436  trial_counter_ = 0;
437  accept_counter_ = 0;
439  if ( num_rejections_.size() ) {
440  num_rejections_.assign( num_rejections_.size(), 0 );
441  }
442  TR << "Initialization done " << std::endl;
443 }
444 
445 /// @brief score pose based on filter or scorefxn
448 {
449  Real score( 0.0 );
450  if( scorefxn_ ){
451  score = flip_sign_ * (*scorefxn_)( pose );
452  }
453  return score;
454 }
457 {
458  Size number_designable = 0;
459  TR << "Designable Residues: ";
460  for(Size i = 1, i_end = pose.total_residue(); i <= i_end; ++i){
461  if(task->design_residue(i)) {
462  ++number_designable;
463  TR << i << ", ";
464  }
465  }
466  TR << std::endl << "Calculated number designable residues" << ": ";
467  TR << number_designable << std::endl;
468  return number_designable;
469 }
470 
471 // @brief
472 bool
474 {
475  ++trial_counter_;
476  TR.Debug <<"filters.size() "<<filters_.size()<<std::endl;
477  if( filters_.size() ){
478  runtime_assert( filters_.size() == adaptive_.size() && filters_.size() == temperatures_.size() && filters_.size() == sample_types_.size() && filters_.size() == num_rejections_.size());
479  bool accept( false );
480  utility::vector1< Real > provisional_scores;
481  provisional_scores.clear();
482  Real ranking_score( 0.0 );
483  for( core::Size index( 1 ); index <= filters_.size(); ++index ){
484  TR.Debug <<"Filter #"<<index<<std::endl;
485  protocols::filters::FilterCOP filter( filters_[ index ] );
486  bool const adaptive( adaptive_[ index ] );
487  Real const temp( temperatures_[ index ] );
488  Real const flip( sample_types_[ index ] == "high" ? -1 : 1 );
489  core::Real const filter_val( filter->report_sm( pose ));
490  TR<<"Filter "<<index<<" reports "<<filter_val<<std::endl;
491 
492  provisional_scores.push_back( flip * filter_val );
493  if( index == rank_by_filter_ ) {
494  ranking_score = provisional_scores[ rank_by_filter_ ];
495  }
496  Real const boltz_factor = ( last_accepted_scores_[ index ] - provisional_scores[ index ] ) / temp;
497  TR_energies.Debug <<"energy index, last_accepted_score, current_score "<<index<<" "<< last_accepted_scores_[ index ]<<" "<<provisional_scores[ index ]<<std::endl;
498  TR.Debug <<"Current, best, boltz "<<provisional_scores[ index ]<<" "<<last_accepted_scores_[ index ]<<" "<<boltz_factor<<std::endl;
499  if( !adaptive ) { // return the starting score
500  provisional_scores[ index ] = last_accepted_scores_[ index ];
501  }
502  Real const probability = std::exp( std::min (40.0, std::max(-40.0,boltz_factor)) );
503  Real const random_num( mc_RG.uniform() );
504  bool const reject_filter( provisional_scores[ index ] > last_accepted_scores_[ index ] && random_num >= probability );
505  if( reject_filter ){
506  accept = false;
507  ++num_rejections_[index];
508  break;
509  }
510  if( !reject_filter ) {
511  accept = true;
512  }
513  }//for index
514  if( accept ){
515  TR<<"Accept"<<std::endl;
517  copy( provisional_scores.begin(), provisional_scores.end(), last_accepted_scores_.begin() );
518  ++accept_counter_;
519  if(boltz_rank_) {
520  ranking_score = 0.0;
521  for(core::Size ii(1); ii <= filters_.size(); ++ii ){
522  ranking_score += provisional_scores[ii] / temperatures_[ii];
523  }
524  }
525  energy_gap_counter_ += ranking_score - last_accepted_score();
526  last_accepted_score_ = ranking_score;
527  *last_accepted_pose_ = pose;
528  if( ranking_score <= lowest_score() ){
529  *lowest_score_pose_ = pose;
530  lowest_score_ = ranking_score;
532  if( saved_accept_file_name_ != "" ){
533  if( mover_tag_() != NULL ){
534  TR<<"Adding accepted mover tag to pose comments"<<std::endl;
535 // std::ofstream f;
536 // std::string const fname( saved_accept_file_name_ + ".mover_tag" );
537 // f.open( fname.c_str(), std::ios::out );
538 // if( !f.good() )
539 // utility_exit_with_message( "Unable to open MC mover_tag file " + fname );
540 // f<<mover_tag_->obj;
541 // f.close();
542  core::pose::add_comment( pose, user_defined_mover_name_, mover_tag_->obj ); /// adding comment to the pose to save the mover's tag since it's accepted
543  }
544  TR<<"Dumping accepted file to disk as: "<<saved_accept_file_name_<<std::endl;
546  }
547  }
548  return( true );
549  }// fi accept
550  else{
551  TR.Debug <<"Reject"<<std::endl;
553  return( false );
554  }
555  }//fi filters_.size()
556  else{
557  Real score = scoring( pose );
558  current_score_ = score; // for debugging
559  show_scores( TR.Debug );
560  if ( score > last_accepted_score() ) {
561  if( temperature_ < 1e-8 ){
562  mc_accepted_ = MCA_rejected; // rejected
563  }else{
564  Real const boltz_factor = ( last_accepted_score() - score ) / temperature_;
565  Real const probability = std::exp( std::min (40.0, std::max(-40.0,boltz_factor)) );
566  if ( mc_RG.uniform() >= probability ) {
567  mc_accepted_ = MCA_rejected; // rejected
568  }else{
569  mc_accepted_ = MCA_accepted_thermally; // accepted thermally
570  }
571  }
572  }else{
573  mc_accepted_ = MCA_accepted_score_beat_last; // accepted: energy is lower than last_accepted
574  }
575 
576  if( mc_accepted_ >= 1 ){ // accepted
577  ++accept_counter_;
579  *last_accepted_pose_ = pose;
580  last_accepted_score_ = score;
581  if ( score < lowest_score() ){ // energy is lower than last_accepted
582  lowest_score_ = score;
583  *lowest_score_pose_ = pose;
585  }
586  return true;
587  }else{ //rejected
588  return false;
589  }
590  }
591 } // boltzmann
592 
595  using namespace std;
596  core::Size trial( 1 );
597  if( saved_trial_number_file_ != "" ){
598  ifstream f( saved_trial_number_file_.c_str(), ios::in );
599  if( f.good() ){
600  core::Size const begin = f.tellg();
601  f.seekg( 0, ios::end );
602  core::Size const end = f.tellg();
603  if( end - begin != 0 ){//file size != 0
604  f.seekg( 0, ios::beg );// return to the beginning
605 
606  TR<<"Loading trial number from checkpoint"<<std::endl;
607  std::string line;
608  getline( f, line );
609  std::istringstream line_stream( line );
610  line_stream >> trial;
611  TR<<"Loaded trial number: "<<trial<<std::endl;
612  }//fi end-begin
613  f.close();
614  }//fi f.good()
615  }// fi saved_trial_number_file_ != ""
616  if( mover_tag_() != NULL ){
617  std::string const fname( saved_trial_number_file_ + ".mover_tag" );
618  ifstream f_mover_tag( fname.c_str(), ios::in );
619  if( f_mover_tag.good() ){
620  f_mover_tag >> mover_tag_->obj;
621  TR<<"Loaded mover_tag from checkpointing file: "<<mover_tag_->obj<<std::endl;
622  }
623  else
624  TR<<"File containing mover_tag "<<fname<<" not found. Not loading movertag from checkpoint"<<std::endl;
625  }
626  if( reset_baselines() ){
627  /// see if any subfilters need to be reset
628  bool call_reset( false );
629  using namespace protocols::filters;
630  using namespace protocols::simple_filters;
631  foreach( FilterOP filter, filters_ ){
632  if( filter->get_type() == "Operator" ){
633  TR<<"Resetting Operator filter's baseline"<<std::endl;
634  OperatorOP operator_filter( dynamic_cast< Operator * >( filter() ) );
635  operator_filter->reset_baseline( pose, trial != 1/*if trial>1, attempt to read the baselines from checkpointing files. Otherwise, don't use the checkpointing files*/ );
636  call_reset = true;
637  }// fi Operator
638  else if( filter->get_type() == "CompoundStatement" ){ /// User defined filters with confidence!=1 in RosettaScripts are all CompoundFilter, so poke inside...
639  CompoundFilterOP comp_filt_op( dynamic_cast< CompoundFilter * >( filter() ) );
640  runtime_assert( comp_filt_op );
641  for( CompoundFilter::CompoundStatement::iterator cs_it = comp_filt_op->begin(); cs_it != comp_filt_op->end(); ++cs_it ){
642  FilterOP filt( cs_it->first );
643  if( filt->get_type() == "Operator" ){
644  TR<<"Resetting Operator filter's baseline"<<std::endl;
645  OperatorOP operator_filter( dynamic_cast< Operator * >( filt() ) );
646  operator_filter->reset_baseline( pose, trial != 1/*if trial>1, attempt to read the baselines from checkpointing files. Otherwise, don't use the checkpointing files*/ );
647  call_reset = true;
648  }// fi Operator
649  }// for cs_it
650  }//elseif CompoundStatement
651  } //foreach
652  if( call_reset ){
653  TR<<"Resetting Boltzmann's accepted values, in case filters have changed during loading"<<std::endl;
654  reset( pose );// this is called to reset the boltzmann scores with the new baselines
655  }
656  }/// fi reset_baselines
657  return trial;
658 }
659 
660 void
662  if( saved_trial_number_file_ == "" )
663  return;
664  std::ofstream f;
665  f.open( saved_trial_number_file_.c_str(), std::ios::out );
666  if( !f.good() )
667  utility_exit_with_message( "Unable to open MC checkpointing file " + saved_trial_number_file_ );
668 
669  f<<i;
670  f.close();
671 }
672 
673 /// @Brief
674 ///comment
675 void
677 {
681 
682  if( !mover_ ){
683  TR.Warning << "Mover is empty ! " << std::endl;
684  return;
685  }
686  if( !filters_.size() && !scorefxn_ ){
687  TR.Warning << "Both ScorefunctionOP and FilterOP are empty ! " << std::endl;
688  return;
689  }
690 
692 
693  if ( factory_ ) {
694  task = factory_->create_task_and_apply_taskoperations( pose );
695  } else {
696  TR << "No task inputted" << std::endl; //LGN
697  }
698 
699  if (factory_ ){
700  number_designable_ = num_designable (pose, task);
701  TR << "Input number of trials is " << maxtrials_ << std::endl;
702  TR << "The task_scaling is: " << task_scaling_ << std::endl;
704  TR << "Resetting number of trials based on your input task to: " << maxtrials_ << std::endl;
705  }
706  TR << "The number of trials for this run is: " << maxtrials_ << std::endl;
707 
708  bool const stop_at_start( ( mover_stopping_condition_() != NULL && mover_stopping_condition_->obj ) || stopping_condition()->apply( pose ) );
709  if( stop_at_start ){
710  TR<<"MC stopping condition met at the start, so failing without retrying "<<std::endl;
712  return;
713  }
714 
715  //fpd
716  if (mover_->get_additional_output())
717  utility_exit_with_message("Movers returning multiple poses are unsupported by GenericMontoCarloMover.");
718  if( saved_accept_file_name_ != "" ){
719  TR<<"Saving initial pose entering the MC trajectory, for use in checkpoint recovery. Checkpointing filename: "<<saved_accept_file_name_<<std::endl;
721  }
722 
723  PoseOP initial_pose = new Pose( pose );
724  reset( pose ); //(re)initialize MC statistics
726  core::Size accept( 0 ), reject( 0 );
727  using namespace protocols::rosetta_scripts;
728  ParsedProtocolOP mover_pp( dynamic_cast< ParsedProtocol * >( mover_() ) );
729  if( adaptive_movers() ){
730  bool is_single_random( mover_pp->mode() == "single_random" );
731  if( mover_pp && !is_single_random ){ // dig in one level (at most) to find the correct ParsedProtocol; if this becomes more generally useful then it would make sense to generatlize this to look for all parsedprotocols of type single_random that are being called by the MC mover. A simple recursion could do it, but I'm not sure how useful this would be
732  foreach( ParsedProtocol::mover_filter_pair const mfp, *mover_pp ){
733  ParsedProtocolOP tmp( dynamic_cast< ParsedProtocol * >( mfp.first.first() ) );
734  if( tmp && tmp->mode() == "single_random" ){/// the parsedprotocol mover must be run in mode single_random for the apply_probabilities to be modified
735  mover_pp = tmp;
736  is_single_random = true;
737  }
738  }//foreach mfp
739  }//fi mover_pp && is_single_random
740  runtime_assert( is_single_random ); /// yes, we found a single-random parsedprotocol mover somewhere; notice that this part boils down to finding the first parsed protocol of single-random mode up to a depth level of 2
741  }//fi adaptive_movers()
742  utility::vector1< core::Size > mover_accepts;// count how many accepts each mover in the parsedprotocol made
743  mover_accepts.clear();
744  if( adaptive_movers() ){
745  runtime_assert( mover_pp );
746  runtime_assert( mover_pp->mode() == "single_random" );
747  mover_accepts = utility::vector1< core::Size >( mover_pp->size(), 1 ); /// each mover gets a pseudocount of 1. This ensures that the running probability of each mover never goes to 0
748  }
749  for( Size i=load_trial_number_from_checkpoint( pose ); i<=maxtrials_; i++ ){
750  TR<<"Trial number: "<<i<<std::endl;
751  if( i > 1 && adaptive_movers() && i % adaptation_period() == 0 ){
752 /// The probability for each mover within a single-random parsedprotocol is determined by the number of accepts it had during the previous adaptation period:
753 /// each mover is assigned a pseducount of 1, and then any additional accept favors it over others. At the adaptation stage, the total number of accepts (including pseudocounts) is used to normalize the individual movers' number of accepts and the probability is the mover's accepts / by the total accepts
754  core::Size sum_prev_accepts( 0 );
755  foreach( core::Size const a, mover_accepts )
756  sum_prev_accepts += a;
757  utility::vector1< core::Real > new_probabilities;
758  new_probabilities = utility::vector1< core::Real >( mover_accepts.size(), 0.0 );
759  TR<<"Adapting running probabilities: old/new probabilities per mover\n";
760  for( core::Size ma = 1; ma<= mover_accepts.size(); ma++ ){
761  new_probabilities[ ma ] = ( core::Real )mover_accepts[ ma ] / ( core::Real )sum_prev_accepts;
762  TR<<mover_pp->apply_probability()[ ma ]<<"/"<<new_probabilities[ ma ]<<'\n';
763  }
764  TR.flush();
765  mover_pp->apply_probability( new_probabilities );
766  mover_accepts = utility::vector1< core::Size >( mover_accepts.size(), 1 );
767  }
768  bool const stop( ( mover_stopping_condition_() != NULL && mover_stopping_condition_->obj ) || stopping_condition()->apply( pose ) );
769  if( stop ){
770  TR<<"MC stopping condition met at trial "<<i<<std::endl;
771  break;
772  }
773  Pose store_pose( pose );
774  // Mover apply
775  mover_->apply( pose );
776  ms = mover_->get_last_move_status();
777  if( ms == FAIL_RETRY ){
778  TR.Warning << "Mover failed. The mover, " << mover_->get_name() << ", is performed again. " << std::endl;
779  pose = store_pose;
780  continue;
781  }else if( ms == FAIL_DO_NOT_RETRY || ms == FAIL_BAD_INPUT ){
782  TR.Error << "Mover failed. Exit from GenericMonteCarloMover." << std::endl;
783  break;
784  }
785  // MonteCarlo
786  if( preapply_ && i==1 ){ // Auto-accept first application in order to deal with movers that e.g. change the length of the pose.
787  reset( pose );
788  }else{
789  if( ! boltzmann( pose ) ){ // evaluate pose by scorefxn_ or filter_.report_sm()
790  pose = *last_accepted_pose();
791  reject++;
792  }
793  else{
794  accept++;
795  if( adaptive_movers() )
796  mover_accepts[ mover_pp->last_attempted_mover_idx() ]++;
797  }
798  }
799  if( !drift_ ){
800  pose = (*initial_pose); // set back pose to initial one, of course this is not way of Monte Carlo
801  }
802 
803  // Iterate over the list of triggers, executing each of them in turn
806  } // i<=maxtrials_
807 
808  // Output final diagnositics, for potential tuning
809  show_scores(TR);
810  show_counters(TR);
811  TR<<"Finished MC. Out of "<<maxtrials_<<" "<<accept<<" accepted "<<" and "<<reject<<" rejected."<<std::endl;
812  // Recover pose that have the lowest score, or the last accepted pose, as appropriate
813  if(recover_low_) {
814  recover_low( pose );
815  } else {
816  if (last_accepted_pose()) {
817  pose = *last_accepted_pose();
818  }
819  }
820 
821 }// apply
822 
826 }
827 
828 /// @brief parse xml file
829 void
830 GenericMonteCarloMover::parse_my_tag( TagPtr const tag, protocols::moves::DataMap & data, Filters_map const &filters, Movers_map const &movers, Pose const & )
831 {
832  //using core::pack::task::operation::TaskOperation;
833  //using core::pack::task::TaskFactoryOP;
834  //using core::pack::task::TaskFactory;
835 
836  maxtrials_ = tag->getOption< core::Size >( "trials", 10 );
837  temperature_ = tag->getOption< Real >( "temperature", 0.0 );
838  task_scaling_ = tag->getOption< core::Size >( "task_scaling", 5 );
839  adaptive_movers( tag->getOption< bool >( "adaptive_movers", false ) );
840  if( adaptive_movers() )
841  adaptation_period( tag->getOption< core::Size >( "adaptation_period", std::max( (int) maxtrials_ / 10, 10 ) ) );
842 
843  String const user_defined_mover_name_( tag->getOption< String >( "mover_name" ,""));
844  if( data.has( "stopping_condition", user_defined_mover_name_ ) ){
845  TR<<user_defined_mover_name_<<" defines its own stopping condition, and GenericMC will respect this stopping condition"<<std::endl;
847  }
848 
849  String const filter_name( tag->getOption< String >( "filter_name", "true_filter" ) );
850  Movers_map::const_iterator find_mover ( movers.find( user_defined_mover_name_ ));
851  Filters_map::const_iterator find_filter( filters.find( filter_name ));
852  if( find_mover == movers.end() && user_defined_mover_name_ != "" ) {
853  TR.Error << "ERROR !! mover not found in map: \n" << tag << std::endl;
854  runtime_assert( find_mover != movers.end() );
855  }
856  if( find_filter == filters.end() ) {
857  TR.Error << "ERROR !! filter not found in map: \n" << tag << std::endl;
858  runtime_assert( find_filter != filters.end() );
859  }
860  if( user_defined_mover_name_ != "" )
861  mover_ = find_mover->second;
862 
863  if( adaptive_movers() ) /// adaptive movers only works if the mover being called is of type parsedprotocol
864  runtime_assert( dynamic_cast< protocols::rosetta_scripts::ParsedProtocol * >( mover_() ));
865 
866  bool const adaptive( tag->getOption< bool >( "adaptive", true ) );
867  add_filter( find_filter->second->clone(), adaptive, temperature_, sample_type_ );
868  String const sfxn ( tag->getOption< String >( "scorefxn_name", "" ) );
869  if( sfxn != "" ){
870  //scorefxn_ = new ScoreFunction( *data.get< ScoreFunction * >( "scorefxns", sfxn ));
871  scorefxn_ = data.get< ScoreFunction * >( "scorefxns", sfxn )->clone(); //fpd use clone
872  TR << "Score evaluation during MC is done by" << sfxn << ", ";
873  TR << filter_name << " is ignored." << std::endl;
874  filters_.clear();
875  }else{
876  scorefxn_ = NULL;
877  }
878 
879  parse_task_operations( tag, data, filters, movers );
880 
881  if( filter_name == "true_filter" && !scorefxn_ ){
882  TR.Error << "You need to set filter_name or scorefxn_name for MC criteria." << std::endl;
883  runtime_assert( false );
884  }
885 
886  if( filters_.size() == 0 ){
887  TR << "Apply mover of " << user_defined_mover_name_ << ", and evaluate score by " << sfxn
888  << " at Temperature=" << temperature_ << ", ntrails= " << maxtrials_ << std::endl;
889  }
890 
891  stopping_condition( protocols::rosetta_scripts::parse_filter( tag->getOption< std::string >( "stopping_condition", "false_filter" ), filters ) );
892  if( tag->hasOption( "stopping_condition" ) )
893  TR<<"Generic MC using stopping condition "<< stopping_condition()->get_user_defined_name()<<std::endl;
894  drift_ = tag->getOption< bool >( "drift", 1 );
895  preapply_ = tag->getOption< bool >( "preapply", 1 ); // Default true for historical reasons
896  recover_low_ = tag->getOption< bool >( "recover_low", 1 );
897  boltz_rank_ = tag->getOption< bool >( "bolz_rank", 0 );
898  sample_type_ = tag->getOption< String >( "sample_type", "low" );
899 
900  utility::vector1< TagPtr > const branch_tags( tag->getTags() );
901  foreach( TagPtr const btag, branch_tags ){
902  if( btag->getName() == "Filters" ){
903  utility::vector1< TagPtr > const filters_tags( btag->getTags() );
904  foreach( TagPtr const ftag, filters_tags ){
905  String const filter_name( ftag->getOption< String >( "filter_name" ) );
906  Filters_map::const_iterator find_filt( filters.find( filter_name ));
907  if( find_filt == filters.end() ) {
908  TR.Error << "Error !! filter not found in map: \n" << tag << std::endl;
909  runtime_assert( find_filt != filters.end() );
910  }
911  Real const temp( ftag->getOption< Real >( "temperature", 1 ) );
912  bool const adap( ftag->getOption< bool >( "adaptive", true ));
913  String const samp_type( ftag->getOption< String >( "sample_type", "low" ));
914  bool const rank( ftag->getOption< bool >( "rank", false ) );
915  if( rank ) {
916  if( rank_by_filter_ != 1 ) {
917  TR.Warning << "WARNING Multiple filters set to rank! Using most recent (currently "<< filter_name << ")." << std::endl;
918  }
919  if( boltz_rank_ ) {
920  TR.Warning << "WARNING Setting of rank on sub-filter "<< filter_name << " will be ignored as parent is set to Boltzmann rank all." << std::endl;
921  }
922  }
923  add_filter( find_filt->second, adap, temp, samp_type, rank );
924  } //foreach ftag
925  }// fi Filters
926  else
927  utility_exit_with_message( "tag name " + btag->getName() + " unrecognized." );
928  }//foreach btag
929 
930  if( !drift_ ){
931  TR << "Pose is set back to initial pose every after applying mover and score evaluation." << std::endl;
932  }
933 
934  if( sample_type_ == "high" ){
935  TR << "Pose that have higher score is sampled." << sfxn << std::endl;
936  }
937 
938  saved_accept_file_name_ = tag->getOption< std::string >( "saved_accept_file_name", "" );
939  saved_trial_number_file_ = tag->getOption< std::string >( "saved_trial_number_file", "" );
940  if( tag->hasOption( "mover_tag" ) )
942  reset_baselines( tag->getOption< bool >( "reset_baselines", true ) );
943  initialize();
944 }
945 
946 ///@brief parse "task_operations" XML option
948  TagPtr const tag,
949  protocols::moves::DataMap const & datamap,
950  Filters_map const &,
951  Movers_map const &
952 )
953 {
954  if ( ( tag->hasOption("task_operations") )){
955  TR << "Found a task operation" << std::endl;
956  TaskFactoryOP new_task_factory( protocols::rosetta_scripts::parse_task_operations( tag, datamap ) );
957  if ( new_task_factory == 0) return;
958  task_factory( new_task_factory );
959  }
960 }
961 
962 
964  Size cycle,
965  Size num_cycles,
966  const Pose& pose,
968 {
969  boost::unordered_map<Size, GenericMonteCarloMoverTrigger>::iterator i;
970  for (i = triggers_.begin(); i != triggers_.end(); ++i) {
971  GenericMonteCarloMoverTrigger& t = i->second;
972  bool rescore = t(cycle, num_cycles, pose, scoring);
973 
974  if (rescore) {
975  last_accepted_score_ = scoring->score(*last_accepted_pose_);
976  lowest_score_ = scoring->score(*lowest_score_pose_);
977  }
978  }
979 }
980 
982  Size tid = next_trigger_id_++;
983  triggers_[tid] = trigger;
984  return tid;
985 }
986 
988  boost::unordered_map<Size, GenericMonteCarloMoverTrigger>::iterator i = triggers_.find(trigger_id);
989  if (i == triggers_.end()) {
990  TR.Warning << "Attempt to remove invalid trigger_id => " << trigger_id << std::endl;
991  return;
992  }
993  triggers_.erase(i);
994 }
995 
997  return triggers_.size();
998 }
999 
1000 void
1002  stopping_condition_ = f;
1003 }
1004 
1007  return stopping_condition_;
1008 }
1009 
1012  return saved_accept_file_name_;
1013 }
1014 
1015 void
1018 }
1019 
1022  return saved_trial_number_file_;
1023 }
1024 
1025 void
1028 }
1029 } // ns simple_moves
1030 } // ns protocols