Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ParsedProtocol.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/rosetta_scripts/ParsedProtocol.cc
11 /// @author Sarel Fleishman (sarelf@u.washington.edu)
12 
13 // Unit Headers
19 
20 // Project Headers
21 #include <protocols/moves/Mover.hh>
22 #include <core/pose/Pose.hh>
24 
25 #include <core/kinematics/Jump.hh>
26 #include <basic/Tracer.hh>
27 
29 
32 
35 #include <utility/tag/Tag.hh>
36 #include <protocols/moves/ResId.hh>
37 
38 // JD2 headers
41 #include <protocols/jd2/Job.hh>
42 // Utility Headers
43 
44 // AUTO-REMOVED #include <core/pose/symmetry/util.hh>
45 // AUTO-REMOVED #include <core/conformation/symmetry/util.hh>
46 
47 //Numeric Headers
48 #include <numeric/random/random.hh>
49 #include <numeric/random/random_permutation.hh>
50 
51 // C++ headers
52 #include <map>
53 #include <string>
54 // AUTO-REMOVED #include <set>
55 #include <algorithm>
56 
57 #include <protocols/jd2/Job.hh>
58 #include <utility/vector0.hh>
59 #include <utility/vector1.hh>
60 #include <utility/excn/Exceptions.hh>
61 #include <boost/foreach.hpp>
62 
63 //Auto Headers
64 #define foreach BOOST_FOREACH
65 namespace protocols {
66 namespace rosetta_scripts {
67 
68 static basic::Tracer TR( "protocols.rosetta_scripts.ParsedProtocol" );
69 static basic::Tracer TR_call_order( "protocols.rosetta_scripts.ParsedProtocol_call_order" );
70 static basic::Tracer TR_report( "protocols.rosetta_scripts.ParsedProtocol.REPORT" );
71 static numeric::random::RandomGenerator RG(48569);
72 
73 typedef core::Real Real;
75 
76 using namespace core;
77 using namespace std;
78 
81 {
83 }
84 
87  return new ParsedProtocol;
88 }
89 
92 {
93  return "ParsedProtocol";
94 }
95 
97  protocols::moves::Mover( "ParsedProtocol" ),
98  final_scorefxn_( 0 ), // By default, don't rescore with any scorefunction.
99  mode_("sequence"),
100  last_attempted_mover_idx_( 0 ),
101  report_call_order_( false )
102 {}
103 
104 /// @detailed Takes care of the docking, design and filtering moves. pre_cycle and pose_cycle can
105 /// be setup in derived classes to setup variables before and after these cycles.
106 void
108 {
111 
112  //fpd search the mover-filter pairs backwards for movers that have remaining poses
115  if(mode_ == "sequence")
116  {
117  for ( rmover_it=movers_.rbegin() ; rmover_it != movers_crend; ++rmover_it ) {
118  core::pose::PoseOP checkpoint = (*rmover_it).first.first->get_additional_output();
119 
120  // otherwise continue where we left off
121  if (checkpoint) {
122  std::string const mover_name( rmover_it->first.first->get_name() );
123 
124  // if mode_ is not 'sequence' then checkpointing is unsupported
125  if (checkpoint && mode_ != "sequence")
126  utility_exit_with_message("Mover "+mover_name+" returned multiple poses in a ParsedProtocol with mode!=sequence");
127 
128  TR<<"=======================RESUMING FROM "<<mover_name<<"======================="<<std::endl;
129  pose = *checkpoint;
130 
131  if( ! apply_filter( pose, *rmover_it) ) {
132 // final_score(pose);
133  return;
134  } else {
135  break;
136  }
137  }
138  }
139  }
140 
141  if(mode_ == "sequence"){
142  sequence_protocol(pose, rmover_it.base());
143  }else if(mode_ =="random_order"){
144  random_order_protocol(pose);
145  }else if(mode_ =="single_random"){
147  }else
148  {
149  TR <<"WARNING: mode is " << mode_ << " .This is not a valid ParsedProtocol Mode, your pose is being ignored" <<std::endl;
150  }
151  if( get_last_move_status() == protocols::moves::MS_SUCCESS ) // no point scoring a failed trajectory (and sometimes you get etable vs. pose atomset mismatches
152  final_score(pose);
153 }
154 
158 }
159 
160 /// Tricky! movers are cloned into the protocol b/c their apply functions (which are nonconst) could accumulate
161 /// state information. Filters are safe and are therefore merely registered.
162 /// Under this state of affairs, a mover or filter may be called many times in the protocol, and it will be
163 /// guaranteed to have no state accumulation.
165  protocols::moves::MoverOP mover_p = mover->clone();
166  protocols::filters::FilterOP filter_p = filter;
167  mover_filter_pair p( std::pair< protocols::moves::MoverOP, std::string > ( mover_p, mover_name ), filter_p );
168  movers_.push_back( p );
169 }
170 
172 {
173  final_scorefxn_ = scorefxn;
174 }
175 
177 {
178  return final_scorefxn_;
179 }
180 
181 void
184 
185  if( ! scorefxn ) { return; }
186 
188  scorefxn = new core::scoring::symmetry::SymmetricScoreFunction(scorefxn);
189  }
190  (*scorefxn)(pose);
191 }
192 
193 void
194 ParsedProtocol::report_all( Pose const & pose ) const {
195  TR_report<<"=============Starting final report================"<<std::endl;
196  foreach(mover_filter_pair mover_pair, movers_){
197  TR_report<<"============Begin report for "<<mover_pair.second->get_user_defined_name()<<"=================="<<std::endl;
198  mover_pair.second->report( TR_report, pose );
199  TR_report<<"============End report for "<<mover_pair.second->get_user_defined_name()<<"=================="<<std::endl;
200  }
201  TR_report.flush();
202 }
203 
204 void
207  protocols::jd2::JobOP job_me( JobDistributor::get_instance()->current_job() );
209  mover_it!=movers_.end(); ++mover_it ) {
210  core::Real const filter_value( (*mover_it).second->report_sm( pose ) );
211  if( filter_value > -9999 )
212  job_me->add_string_real_pair((*mover_it).second->get_user_defined_name(), filter_value);
213  }
214 }
215 
216 void
217 ParsedProtocol::report_all_sm( std::map< std::string, core::Real > & score_map, Pose const & pose ) const {
219  mover_it!=movers_.end(); ++mover_it ) {
220  core::Real const filter_value( (*mover_it).second->report_sm( pose ) );
221  if( filter_value >= -9999 )
222  score_map[ (*mover_it).second->get_user_defined_name() ] = filter_value;
223  }
224 }
225 
228  return movers_.begin();
229 }
230 
233  return movers_.begin();
234 }
235 
238  return movers_.end();
239 }
241 
244  return movers_.end();
245 }
246 
247 /// @details sets resid for the constituent filters and movers
248 void
250  for( iterator it( movers_.begin() ); it!=movers_.end(); ++it ){
251  using namespace protocols::moves;
252  modify_ResId_based_object( it->first.first, resid );
253  modify_ResId_based_object( it->second, resid );
254  }
255 }
256 
258 {
260 }
261 
262 void
264  TagPtr const tag,
266  protocols::filters::Filters_map const &filters,
267  protocols::moves::Movers_map const &movers,
268  core::pose::Pose const & )
269 {
270  using namespace protocols::moves;
271  using namespace utility::tag;
272 
273  TR<<"ParsedProtocol mover with the following movers and filters\n";
274 
275  mode_=tag->getOption<string>("mode", "sequence");
276  if(mode_ != "sequence" && mode_ != "random_order" && mode_ != "single_random"){
277  throw utility::excn::EXCN_RosettaScriptsOption("Error: mode must be sequence, random_order, or single_random");
278  }
279 
280  utility::vector0< TagPtr > const dd_tags( tag->getTags() );
281  utility::vector1< core::Real > a_probability( dd_tags.size(), 1.0/dd_tags.size() );
282  core::Size count( 1 );
283  for( utility::vector0< TagPtr >::const_iterator dd_it=dd_tags.begin(); dd_it!=dd_tags.end(); ++dd_it ) {
284  TagPtr const tag_ptr = *dd_it;
285 
286  MoverOP mover_to_add;
287  protocols::filters::FilterOP filter_to_add;
288 
289  bool mover_defined( false ), filter_defined( false );
290 
291  std::string mover_name="null"; // user must specify a mover name. there is no valid default.
292  runtime_assert( !( tag_ptr->hasOption("mover_name") && tag_ptr->hasOption("mover") ) );
293  if( tag_ptr->hasOption( "mover_name" ) ){
294  mover_name = tag_ptr->getOption<string>( "mover_name", "null" );
295  mover_defined = true;
296  }
297  else if( tag_ptr->hasOption( "mover" ) ){
298  mover_name = tag_ptr->getOption<string>( "mover", "null" );
299  mover_defined = true;
300  }
301  //runtime_assert( mover_name ); // redundant with mover find below
302 
303  if( data.has( "stopping_condition", mover_name ) && tag->hasOption( "name" ) ){
304  TR<<"ParsedProtocol's mover "<<mover_name<<" requests its own stopping condition. This ParsedProtocol's stopping_condition will point at the mover's"<<std::endl;
305  data.add( "stopping_condition", tag->getOption< std::string >( "name" ), data.get< protocols::moves::DataMapObj< bool > * >( "stopping_condition", mover_name ) );
306  }
307 
308  std::string filter_name="true_filter"; // used in case user does not specify a filter name.
309  runtime_assert( !( tag_ptr->hasOption("filter_name") && tag_ptr->hasOption( "filter" ) ) );
310  if( tag_ptr->hasOption( "filter_name" ) ){
311  filter_name = tag_ptr->getOption<string>( "filter_name", "true_filter" );
312  filter_defined = true;
313  } else if( tag_ptr->hasOption( "filter" ) ){
314  filter_name = tag_ptr->getOption<string>( "filter", "true_filter" );
315  filter_defined = true;
316  }
317 
318  if( mover_defined ){
319  Movers_map::const_iterator find_mover( movers.find( mover_name ) );
320  if( find_mover == movers.end() ) {
321  TR.Error<<"mover not found in map. skipping:\n"<<tag_ptr<<std::endl;
322  runtime_assert( find_mover != movers.end() );
323  continue;
324  }
325  mover_to_add = find_mover->second;
326  } else {
327  mover_to_add = new NullMover;
328  }
329  if( filter_defined ){
330  protocols::filters::Filters_map::const_iterator find_filter( filters.find( filter_name ));
331  if( find_filter == filters.end() ) {
332  TR.Error<<"filter not found in map. skipping:\n"<<tag_ptr<<std::endl;
333  runtime_assert( find_filter != filters.end() );
334  continue;
335  }
336  filter_to_add = find_filter->second;
337  } else {
338  filter_to_add = new protocols::filters::TrueFilter;
339  }
340  add_mover( mover_to_add, mover_name, filter_to_add );
341  TR << "added mover \"" << mover_name << "\" with filter \"" << filter_name << "\"\n";
342  if( mode_ == "single_random" ){
343  a_probability[ count ] = tag_ptr->getOption< core::Real >( "apply_probability", 1.0/dd_tags.size() );
344  TR<<"and execution probability of "<<a_probability[ count ]<<'\n';
345  }
346  count++;
347  }
348  if( mode_ == "single_random" )
349  apply_probability( a_probability );
350  report_call_order( tag->getOption< bool >( "report_call_order", false ) );
351  TR.flush();
352 }
353 
354 /// @detailed Looks for any submovers that have additional output poses to process.
355 /// If any are found, run remainder of parsed protocol.
358 {
359  //fpd search the mover-filter pairs backwards; look for movers that have remaining poses
360  core::pose::PoseOP pose=NULL;
363  for ( rmover_it=movers_.rbegin() ; rmover_it != movers_crend; ++rmover_it ) {
364  core::pose::PoseOP checkpoint = (*rmover_it).first.first->get_additional_output();
365  if (checkpoint) {
366  std::string const mover_name( rmover_it->first.first->get_name() );
367  TR<<"=======================RESUMING FROM "<<mover_name<<"======================="<<std::endl;
368  pose = checkpoint;
369 
370  if( ! apply_filter( *pose, *rmover_it) ) {
371  return pose;
372  } else {
373  break;
374  }
375  }
376  }
377 
378  // no saved poses? return now
379  if (!pose) return NULL;
380 
381  // if mode_ is not 'sequence' then checkpointing is unsupported
382  if (mode_ != "sequence")
383  utility_exit_with_message("ParsedProtocol returned multiple poses in a ParsedProtocol with mode!=sequence");
384 
385  // otherwise pick up from the checkpoint
386  for( utility::vector1< mover_filter_pair >::const_iterator mover_it = rmover_it.base();
387  mover_it!=movers_.end(); ++mover_it ) {
388  if ( ! apply_mover_filter_pair( *pose, *mover_it ) ) {
389  return pose;
390  }
391  }
393  TR<<"setting status to success"<<std::endl;
394 
395  // report filter values to the job object as string_real_pair
396  report_filters_to_job( *pose );
397  // report filter values to tracer output
398  report_all( *pose );
399  // rescore the pose with either score12 or a user-specified scorefunction. this ensures that all output files end up with scores.
400 // core::scoring::ScoreFunctionOP scorefxn = core::scoring::getScoreFunction();
401 // (*scorefxn)(*pose);
402 
403  return pose;
404 }
405 
407 {
408  std::string const mover_name( mover_pair.first.first->get_name() );
409 
410  mover_pair.first.first->set_native_pose( get_native_pose() );
411  TR<<"=======================BEGIN MOVER "<<mover_name<<"=======================\n{"<<std::endl;
412  mover_pair.first.first->apply( pose );
413  TR<<"\n}\n=======================END MOVER "<<mover_name<<"======================="<<std::endl;
414 
415  // Split out filter application in seperate function to allow for reuse in resuming from additional output pose cases.
416  return apply_filter( pose, mover_pair);
417 }
418 
419 bool ParsedProtocol::apply_filter(Pose & pose, mover_filter_pair const & mover_pair)
420 {
421  std::string const filter_name( mover_pair.second->get_user_defined_name() );
422 
423  TR<<"=======================BEGIN FILTER "<<filter_name<<"=======================\n{"<<std::endl;
424  info().insert( info().end(), mover_pair.first.first->info().begin(), mover_pair.first.first->info().end() );
426  moves::MoverStatus status( mover_pair.first.first->get_last_move_status() );
427  bool const pass( status==protocols::moves::MS_SUCCESS && mover_pair.second->apply( pose ) );
428  TR<<"\n}\n=======================END FILTER "<<filter_name<<"======================="<<std::endl;
429  if( !pass ) {
430  if( status != protocols::moves::MS_SUCCESS ) {
431  TR << "Mover " << mover_pair.first.first->get_name() << " reports failure!" << std::endl;
433  } else {
434  TR << "Filter " << filter_name << " reports failure!" << std::endl;
436  }
437  return false;
438  }
439  return true;
440 }
441 
444  TR<<"setting status to success"<<std::endl;
445 
446  // report filter values to the job object as string_real_pair
447  report_filters_to_job( pose );
448  // report filter values to tracer output
449  report_all( pose );
450 
451  using namespace protocols::jd2;
453  std::string job_name (JobDistributor::get_instance()->job_outputter()->output_name( job2 ) );
454  if( report_call_order() ){
455  TR_call_order << job_name<<" ";
456  foreach( mover_filter_pair const p, movers_ )
457  TR_call_order<<p.first.second<<" ";
458  TR_call_order<<std::endl;
459  }
460  // rescore the pose with either score12 or a user-specified scorefunction. this ensures that all output files end up with scores.
461 // core::scoring::ScoreFunctionOP scorefxn = core::scoring::getScoreFunction();
462 // (*scorefxn)(pose);
463 
464 }
465 
466 
468 {
469  //bool last_mover=false;
470  for( utility::vector1< mover_filter_pair >::const_iterator mover_it = mover_it_in;
471  mover_it!=movers_.end(); ++mover_it ) {
472 
473  if(!apply_mover_filter_pair(pose, *mover_it)) {
474  return;
475  }
476  }
477 
478  // we're done! mark as success
479  finish_protocol( pose );
480 }
481 
482 
484  numeric::random::random_permutation(movers_.begin(),movers_.end(),RG);
485  for(utility::vector1<mover_filter_pair>::const_iterator it = movers_.begin(); it != movers_.end();++it)
486  {
487  if(!apply_mover_filter_pair(pose, *it))
488  {
489  return;
490  }
491  }
492  // we're done! mark as success
493  finish_protocol( pose );
494 }
495 
498  core::Real sum( 0 );
499  foreach( core::Real const prob, apply_probability_ )
500  sum += prob;
501  runtime_assert( sum >= 0.999 && sum <= 1.001 );
502  return apply_probability_;
503 }
504 
505 void
507  apply_probability_ = a;
508  runtime_assert( apply_probability_.size() == movers_.size() );
509  core::Real sum( 0 );
510  foreach( core::Real const prob, apply_probability_ )
511  sum += prob;
512  runtime_assert( sum >= 0.999 && sum <= 1.001 );
513 }
514 
516  core::Real const random_num( RG.uniform() );
517  core::Real sum( 0.0 );
518  core::Size mover_index( 0 );
519  foreach( core::Real const probability, apply_probability() ){
520  sum += probability; mover_index++;
521  if( sum >= random_num )
522  break;
523  }
524  last_attempted_mover_idx( mover_index );
525  if(!apply_mover_filter_pair(pose, movers_[mover_index])) {
526  return;
527  }
528 
529  // we're done! mark as success
530  finish_protocol( pose );
531 }
532 
533 } //rosetta_scripts
534 } //protocols
535