Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RampingMover.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/RampingMover.cc
11 /// @brief Mover class for ramping the repulsive term of a score function
12 /// over the course of several apply() evaluations.
13 /// @author Monica Berrondo
14 
15 // Unit Headers
18 
19 // Project headers
23 
26 
27 // Utility headers
28 #include <utility/tag/Tag.hh>
29 #include <utility/exit.hh>
30 #include <utility/vector0.hh>
31 #include <utility/vector1.hh>
32 
33 // tracer
34 #include <basic/Tracer.hh>
35 #include <utility/excn/Exceptions.hh>
36 #include <complex>
37 
38 using basic::T;
39 using basic::Error;
40 using basic::Warning;
41 
42 // C++ Headers
43 
44 // ObjexxFCL Headers
45 //#include <ObjexxFCL/string.functions.hh>
46 
47 namespace protocols {
48 namespace moves {
49 
50 static basic::Tracer TR( "protocols.moves.RampingMover" );
51 
53 
55 
57  Real xval_start_ramp,
58  Real xval_end_ramp
59 ) :
60  xval_start_ramp_( xval_start_ramp ),
61  xval_end_ramp_( xval_end_ramp )
62 {
63  runtime_assert( 0 <= xval_start_ramp && xval_start_ramp <= 1 );
64  runtime_assert( 0 <= xval_end_ramp && xval_end_ramp <= 1 );
65  runtime_assert( xval_start_ramp <= xval_end_ramp );
66 }
67 
69 
72 {
73  /// If xval_start_ramp_ == xval_end_ramp_; step function.
74  /// Make sure 1/(xval_end - xval_start ) is never evaluated!
75  if ( x <= xval_start_ramp_ ) return 0.0;
76  else if ( x >= xval_end_ramp_ ) return 1.0;
77  else {
78  return ( x - xval_start_ramp_ ) / (xval_end_ramp_ - xval_start_ramp_ );
79  }
80 }
81 
82 /// @brief Ramps rapidly from the starting value to the final value.
83 /// Not 1 at x=1. Doesn't really finish at (1,1).
85  inv_xval_at_0p5_( 1 / xval_at_0p5 )
86 {
87  runtime_assert( xval_at_0p5 != 0.0 );
88 }
89 
90 /// @default ctor -- val of 0.5 produces 0.5
92  inv_xval_at_0p5_( 3 )
93 {
94 
95 }
96 
98 
99 /// func(x) = 1 - exp( -1 * x * inv_xval_at_0p5 * 0.6931 );
102 {
103  static Real const ln_0p5 = std::log( 0.5 ); // ~0.6931
104  return 1 - std::exp( -1 * x * inv_xval_at_0p5_ * ln_0p5 );
105 
106 }
107 
108 /// @brief Ramps slowly from the starting value to the final value
109 /// Non-zero for x = 0. Doesn't really start at (0,0).
110 /// func(x) = exp( -1 * ( 1 - x ) / ( 1 - xval_at_0p5 ) * 0.6931 );
112 :
113  inv_one_minus_xval_at_0p5_( 1 / ( 1 - xval_at_0p5 ))
114 {}
115 
117  inv_one_minus_xval_at_0p5_( 1 / ( 1 - 0.66 ))
118 {}
119 
121 
122  /// func(x) = exp( -1 * ( 1 - x ) / ( 1 - xval_at_0p5 ) * 0.6931 );
125 {
126  static Real const ln_0p5 = std::log( 0.5 );
127  return std::exp( -1 * ( 1 - x ) * inv_one_minus_xval_at_0p5_ * ln_0p5 );
128 }
129 
132 std::string RampingMoverCreator::mover_name() { return "RampingMover"; }
133 
134 
135 /// RampingMover
136 
138  Mover( RampingMoverCreator::mover_name() ),
139  mover_( 0 ),
140  scorefxn_( 0 ),
141  ramp_one_weight_( true ),
142  score_type_( core::scoring::fa_rep ),
143  ramping_funcs_for_weights_( core::scoring::n_score_types, 0 ),
144  outer_cycles_( 0 ),
145  inner_cycles_( 0 ),
146  mc_( 0 )
147 {
149 }
150 
152  MoverOP mover_in,
153  core::scoring::ScoreFunctionOP scorefxn_in,
154  core::scoring::ScoreType score_type_in,
155  int outer_cycles_in,
156  int inner_cycles_in,
157  MonteCarloOP mc_in,
158  bool geometric_in
159 ) :
160  Mover( RampingMoverCreator::mover_name() ),
161  mover_( mover_in ),
162  scorefxn_( scorefxn_in ), // replace this with clone() when symmetry comes online.
163  ramp_one_weight_( true ),
164  score_type_( score_type_in ),
165  start_weights_( scorefxn_in->weights() ),
166  ramping_funcs_for_weights_( core::scoring::n_score_types, 0 ),
167  outer_cycles_( outer_cycles_in ),
168  inner_cycles_( inner_cycles_in ),
169  mc_( mc_in )
170 {
171  start_weights_[ score_type_ ] = 0.2;
172  end_weights_[ score_type_ ] = 1.0;
174 }
175 
177  MoverOP mover_in,
178  core::scoring::ScoreFunctionOP scorefxn_in,
179  core::scoring::EnergyMap start_weights,
180  core::scoring::EnergyMap end_weights,
181  int outer_cycles_in,
182  int inner_cycles_in,
183  MonteCarloOP mc_in
184 ) :
185  Mover( RampingMoverCreator::mover_name() ),
186  mover_( mover_in ),
187  scorefxn_( scorefxn_in ), // replace this with clone() when symmetry comes online.
188  ramp_one_weight_( false ),
189  score_type_( core::scoring::fa_rep ), // unused
190  start_weights_( start_weights ),
191  end_weights_( end_weights ),
192  ramping_funcs_for_weights_( core::scoring::n_score_types, 0 ),
193  outer_cycles_( outer_cycles_in ),
194  inner_cycles_( inner_cycles_in ),
195  mc_( mc_in )
196 {
197  for ( Size ii = 1; ii <= core::scoring::n_score_types; ++ii ) {
199  if ( start_weights_[ iist ] != end_weights_[ iist ] ) {
201  }
202  }
203 }
204 
206 
208 {
209  return new RampingMover(*this);
210 }
211 
212 void
214  TagPtr const tag,
215  DataMap & datamap,
216  Filters_map const & /*filters*/,
217  Movers_map const & movers,
218  Pose const & /*pose*/
219 )
220 {
221 
222  if(!tag->hasOption("outer_cycles")) {
223  throw utility::excn::EXCN_RosettaScriptsOption("You must specify the option outer_cycles in RampingMover");
224  }
225  if(!tag->hasOption("inner_cycles")) {
226  throw utility::excn::EXCN_RosettaScriptsOption("You must specify the option inner_cycles in RampingMover");
227  }
228  if(!tag->hasOption("mover")) {
229  throw utility::excn::EXCN_RosettaScriptsOption("You must specify the option mover in RampingMover");
230  }
231 
232  //Get options values out of the tag
233  outer_cycles_ = tag->getOption<int>("outer_cycles");
234  inner_cycles_ = tag->getOption<int>("inner_cycles");
235  std::string montecarlo_name(tag->getOption<std::string>("montecarlo","none"));
236  std::string mover_name(tag->getOption<std::string>("mover"));
237 
239  if ( sfxn == 0 ) {
240  throw utility::excn::EXCN_RosettaScriptsOption("scorefxn required to create a RampingMover");
241  }
242  scorefxn_ = sfxn;
243 
244 
245  //get the mover to ramp out of the movemap
246  Movers_map::const_iterator find_mover(movers.find(mover_name));
247  if(find_mover == movers.end()) {
248  throw utility::excn::EXCN_RosettaScriptsOption("cannot find "+mover_name+" in mover map.");
249  }
250  mover_ = find_mover->second;
251 
252  //get the montecarlo object out of the datamap
253  if ( montecarlo_name != "none" ) {
254  mc_ = *datamap.get<protocols::moves::MonteCarlo *>("montecarlos", montecarlo_name);
255  }
256 
257  // Two modes for the Ramping mover:
258  // either we ramp one weight, in which case start-weight, end-weight,
259  // ramp_func, and scoretype must be provided,
260  // OR we ramp several weights, in which case those four should not be provided.
261  // CASE 1: Ramp one weight
262 
263  if ( tag->hasOption("start_weight") ||
264  tag->hasOption("end_weight") ||
265  tag->hasOption("scoretype") ||
266  tag->hasOption("ramp_func") ) {
267 
268  // 1st: Make sure all the required options have been provided.
269  if(!tag->hasOption("start_weight")) {
270  throw utility::excn::EXCN_RosettaScriptsOption("One-weight ramping mode: you must specify the option start_weight in RampingMover");
271  }
272  if(!tag->hasOption("end_weight")) {
273  throw utility::excn::EXCN_RosettaScriptsOption("One-weight ramping mode: you must specify the option end_weight in RampingMover");
274  }
275  if(!tag->hasOption("score_type")) {
276  throw utility::excn::EXCN_RosettaScriptsOption("One-weight ramping mode: you must specify the option score_type in RampingMover");
277  }
278  if(!tag->hasOption("ramp_func")) {
279  throw utility::excn::EXCN_RosettaScriptsOption("One-weight ramping mode: you must specify the option ramp_func in RampingMover");
280  }
281  ramp_one_weight_ = true;
282 
283  core::Real start_weight(tag->getOption<core::Real>("start_weight"));
284  core::Real end_weight(tag->getOption<core::Real>("end_weight"));
285  std::string score_type(tag->getOption<std::string>("score_type"));
286  std::string ramping_func(tag->getOption<std::string>("ramp_func"));
287 
288  //set up the start and end weights
289  this->start_weight(start_weight);
290  this->end_weight(end_weight);
291 
292 
293  //set up the score type
294  if ( ! core::scoring::ScoreTypeManager::is_score_type( score_type ) ) {
295  throw utility::excn::EXCN_RosettaScriptsOption( "The value for option score_type \"" + score_type + "\" is not a valid name for a score_type" );
296  }
299 
300  } else {
301  ramp_one_weight_ = false;
302  if( tag->hasOption("unramped_weights_from_sfxn")) {
303  std::string const scorefxn_key( tag->getOption<std::string>("unramped_weights_from_sfxn") );
304  if ( ! datamap.has( "scorefxns", scorefxn_key ) ) {
305  throw utility::excn::EXCN_RosettaScriptsOption("ScoreFunction " + scorefxn_key + " not found in DataMap.");
306  }
307  core::scoring::ScoreFunctionCOP sfxn = datamap.get< core::scoring::ScoreFunction * >( "scorefxns", scorefxn_key );
308  start_weights_ = end_weights_ = sfxn->weights();
309 
310  }
311 
312 
313 
314  utility::vector0< TagPtr > const rampterm_tags( tag->getTags() );
316  rampterm_it=rampterm_tags.begin(), rampterm_it_end = rampterm_tags.end();
317  rampterm_it!=rampterm_it_end; ++rampterm_it ) {
318  TagPtr const tag_ptr = *rampterm_it;
319  if ( ! tag_ptr->hasOption("score_type") ) {
320  throw utility::excn::EXCN_RosettaScriptsOption("Ramping mover Add statement requires the score_type option");
321  }
322  if ( ! tag_ptr->hasOption("start_weight") ) {
323  throw utility::excn::EXCN_RosettaScriptsOption("Ramping mover Add statement requires the start_weight option");
324  }
325  if ( ! tag_ptr->hasOption("end_weight") ) {
326  throw utility::excn::EXCN_RosettaScriptsOption("Ramping mover Add statement requires the end_weight option");
327  }
328  if ( ! tag_ptr->hasOption("ramp_func") ) {
329  throw utility::excn::EXCN_RosettaScriptsOption("Ramping mover Add statement requires the ramp_func option");
330  }
331  core::Real start_weight(tag_ptr->getOption<core::Real>("start_weight"));
332  core::Real end_weight(tag_ptr->getOption<core::Real>("end_weight"));
333  std::string score_type(tag_ptr->getOption<std::string>("score_type"));
334  std::string ramping_func(tag_ptr->getOption<std::string>("ramp_func"));
335 
336  //read the score type
337  if ( ! core::scoring::ScoreTypeManager::is_score_type( score_type ) ) {
338  throw utility::excn::EXCN_RosettaScriptsOption( "The value for option score_type \"" + score_type + "\" is not a valid name for a score_type" );
339  }
342  end_weights_[ st ] = end_weight;
343 
344  ramping_funcs_for_weights_[ st ] = instantiate_rampfunc( ramping_func, tag_ptr );
345  TR << "Ramping weight " << score_type << std::endl;
346  }
347  }
348 }
349 
350 void
352 {
354  for ( int i = 0; i <= outer_cycles_; ++i ) {
355  //T("protocols.moves.RampingMover") << "Move: " << i << "/" << outer_cycles_ << std::endl;
356  update_weights( i );
357  (*scorefxn_)(pose);
358 
359  // reset the score function for the monte carlo object, if any.
360  if ( mc_ ) {
361  mc_->reset_scorefxn( pose, *scorefxn_ );
362  }
363  //T("protocols.moves.RampingMover") << "Move: " << i << "/" << outer_cycles_ << " " << scorefxn_->weights()[ core::scoring::fa_rep ] << std::endl;
364 
365  // pose.dump_pdb("ramp" + ObjexxFCL::right_string_of(i,2,'0') + "_before.pdb" );
366  for ( int j = 0; j < inner_cycles_; ++j ) {
367  mover_->apply( pose );
368  }
369  // pose.dump_pdb("ramp" + ObjexxFCL::right_string_of(i,2,'0') + "_after.pdb" );
370  (*scorefxn_)(pose);
371  // scorefxn_->show(std::cout, pose);
372 
373  }
374 }
375 
378  return "RampingMover";
379 }
380 
381 
382 // @details The Ramping mover performs a shallow copy of the input
383 // score function pointer, so that multiple objects can share the
384 // same score function and be influenced by this mover's change to
385 // that score function.
387 {
388  scorefxn_ = scorefxn;
389  start_weights_ = scorefxn->weights();
390 }
391 
392 
393 void
395 {
396  runtime_assert( ramp_one_weight_ );
397  start_weights_[ score_type_ ] = start_weight_in;
398 }
399 
400 void
402 {
403  runtime_assert( ramp_one_weight_ );
404  end_weights_[ score_type_ ] = end_weight_in;
405 }
406 
407 void
409  core::scoring::ScoreType scoretype,
410  RampingFuncOP func
411 )
412 {
413  ramping_funcs_for_weights_[ scoretype ] = func;
414 }
415 
416 
417 void
419 {
420  core::Real progress = ((core::Real) round) / outer_cycles_;
422  for ( Size ii = 1; ii <= core::scoring::n_score_types; ++ii ) {
424  if ( ! ramping_funcs_for_weights_[ ii ] ) continue;
425  core::Real const alpha = ramping_funcs_for_weights_[ ii ]->func( progress );
426  core::Real const beta = 1 - alpha;
427  /// if alpha is outside [0..1], then extrapolate.
428  intermediate_weights_[ iist ] = start_weights_[ iist ] * beta + end_weights_[ iist ] * alpha;
429  }
431 }
432 
433 void
435 {
436  for ( Size ii = 1; ii <= core::scoring::n_score_types; ++ii ) {
438  scorefxn_->set_weight( iist, emap[ iist ] );
439  if ( emap[ iist ] == 0.0 ) continue;
440  //T.Debug("protocols.moves.RampingMover") << iist << " " << emap[ iist ] << " ";
441  }
442  //T.Debug("protocols.moves.RampingMover") << std::endl;
443 }
444 
447  std::string const & func_name,
448  utility::tag::TagPtr const tag_ptr
449 ) const
450 {
451 
452  if ( func_name == "geometric" ) {
453  core::Real xval_at_0p5 = tag_ptr->getOption< core::Real >( "xval_at_0p5", 0.75 );
454  return new GeometricFunc( xval_at_0p5 );
455  } else if ( func_name == "linear" ) {
456  return new LinearFunc;
457  } else if ( func_name == "fast_linear" ) {
458  core::Real xval_start_ramp = tag_ptr->getOption<core::Real>("xval_start_ramp",0.0);
459  core::Real xval_end_ramp = tag_ptr->getOption<core::Real>("xval_end_ramp",1.0);
460  return new FastLinearFunc( xval_start_ramp, xval_end_ramp );
461  } else if ( func_name == "inverse_geometric") {
462  core::Real xval_at_0p5 = tag_ptr->getOption<core::Real>("xval_at_0p5",0.75);
463  return new InvGeometricFunc( xval_at_0p5 );
464  } else {
465  utility_exit_with_message("option ramping_func in RampingMover must be: geometric, linear, fast_linear, or inverse_geometric");
466  }
467 
468  return new LinearFunc; // appease compiler.
469 }
470 
471 
472 } // moves
473 } // protocols
474