Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BasicFilters.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/filters/BasicFilters.cc
11 /// @brief
12 /// @detailed
13 /// Contains currently:
14 ///
15 ///
16 /// @author Florian Richter, Sarel Fleishman (sarelf@uw.edu), Rocco Moretti (rmoretti@u.washington.edu)
17 
18 // Unit Headers
21 
22 // AUTO-REMOVED #include <protocols/moves/Mover.hh>
23 // AUTO-REMOVED #include <protocols/moves/DataMap.hh>
24 #include <utility/tag/Tag.hh>
25 #include <basic/Tracer.hh>
26 
27 // Package Headers
28 
29 // Project Headers
31 #include <protocols/moves/Mover.hh>
32 #include <core/pose/Pose.hh>
33 #include <core/types.hh>
34 
35 // ObjexxFCL Headers
36 
37 // Utility headers
38 #include <numeric/random/random.hh>
39 
40 // Boost Headers
41 #include <boost/foreach.hpp>
42 
43 #include <utility/vector0.hh>
44 #include <utility/excn/Exceptions.hh>
45 #include <utility/vector1.hh>
46 
47 #define foreach BOOST_FOREACH
48 
49 //// C++ headers
50 static basic::Tracer TR("protocols.filters.Filter");
51 static numeric::random::RandomGenerator RG( 140789 ); // <- Magic number, do not change it!!!
52 
53 namespace protocols {
54 namespace filters {
55 
56 using namespace core;
57 typedef std::pair< std::string const, FilterCOP > StringFilter_pair;
60 
61 ////////////////////////////////////////////////////////////////////////////////////////////////////
62 
65 
67  : Filter( "Stochastic" ), confidence_( confidence )
68 {}
69 
70 bool
71 StochasticFilter::apply( Pose const & ) const
72 {
73  if( confidence_ >= 0.999 ) return true;
74 
75  core::Real const random_number( RG.uniform() );
76  if( random_number <= confidence_ ) {
77  TR<<"stochastic filter returning false"<<std::endl;
78  return false;
79  }
80  TR<<"stochastic filter returning true"<<std::endl;
81  return true;
82 }
83 
84 
87 {
88  return new StochasticFilter( *this );
89 }
90 
93 {
94  return new StochasticFilter();
95 }
96 
97 void
99  TagPtr const tag,
100  moves::DataMap &,
101  Filters_map const &,
102  moves::Movers_map const &,
103  Pose const & )
104 {
105  confidence_ = tag->getOption< core::Real >( "confidence", 1.0 );
106  TR<<"stochastic filter with confidence "<<confidence_<<std::endl;
107 }
108 
109 ////////////////////////////////////////////////////////////////////////////////////////////////////
110 // @brief Used to define a compound logical statement involving other filters with
111 // AND, OR and XOR
113  Filter( "CompoundStatement" ),
114  invert_(false)
115  {}
117 
118 CompoundFilter::CompoundFilter( CompoundStatement const & compound_statement ) :
119  Filter( "CompoundStatement" ),
120  compound_statement_( compound_statement ),
121  invert_(false)
122 {}
123 
124 bool
125 CompoundFilter::apply( Pose const & pose ) const
126 {
127  bool const value( compute( pose ) );
128 
129  TR<<"Compound logical statement is "<<value<<"."<<std::endl;
130  return( value );
131 }
132 
133 FilterOP
135 {
136  return new CompoundFilter( *this );
137 }
138 
139 FilterOP
141 {
142  return new CompoundFilter();
143 }
144 
145 void
146 CompoundFilter::report( std::ostream & out, Pose const & pose ) const
147 {
148  if( compound_statement_.size() == 2 ){
149  //special case for filters that are defined with a confidence value. In that case, we want to report the value of the filter regardless of the stochastic filter
150  bool confidence( false );
151  CompoundStatement::const_iterator non_stochastic_filter;
152  for( CompoundStatement::const_iterator it=compound_statement_.begin(); it!=compound_statement_.end(); ++it ){
153  if( it->first->get_type() == "Stochastic" ) confidence = true;
154  else non_stochastic_filter = it;
155  }
156  if( confidence ) non_stochastic_filter->first->report( out, pose );
157  }
158  bool const value( compute( pose ) );
159 
160  out<<"Compound filter returns: "<<value<<'\n';
161 }
162 
164 CompoundFilter::report_sm( Pose const & pose ) const
165 {
166  if( compound_statement_.size() == 2 ){
167  //special case for filters that are defined with a confidence value. In that case, we want to report the value of the filter regardless of the stochastic filter
168  bool confidence( false );
169  CompoundStatement::const_iterator non_stochastic_filter;
170  for( CompoundStatement::const_iterator it=compound_statement_.begin(); it!=compound_statement_.end(); ++it ){
171  if( it->first->get_type() == "Stochastic" ) confidence = true;
172  else non_stochastic_filter = it;
173  }
174  if( confidence ) return( non_stochastic_filter->first->report_sm( pose ) );
175  }
176  bool const value( compute( pose ) );
177  return( value );
178 }
179 
180 bool
181 CompoundFilter::compute( Pose const & pose ) const
182 {
183  bool value( true );
184 
185  for( CompoundStatement::const_iterator it=compound_statement_.begin(); it!=compound_statement_.end(); ++it ) {
186  if( it - compound_statement_.begin() == 0 ){
187  // first logical op may only be NOT
188  // ANDNOT and ORNOT are also treated as NOT (with a warning)
189  value = it->first->apply( pose );
190  if (it->second == NOT) value = !value;
191  if (it->second == ORNOT) {
192  TR << "WARNING: CompoundFilter treating operator ORNOT as NOT" << std::endl;
193  value = !value;
194  }
195  if (it->second == ANDNOT) {
196  TR << "WARNING: CompoundFilter treating operator ANDNOT as NOT" << std::endl;
197  value = !value;
198  }
199  } else {
200  switch( it->second ) {
201  case ( AND ) : value = value && it->first->apply( pose ); break;
202  case ( OR ) : value = value || it->first->apply( pose ); break;
203  case ( XOR ) : value = value ^ it->first->apply( pose ); break;
204  case ( ORNOT ) : value = value || !it->first->apply( pose ); break;
205  case ( ANDNOT ) : value = value && !it->first->apply( pose ); break;
206  case ( NOR ) : value = !( value || it->first->apply( pose ) ); break;
207  case (NAND ) : value = !( value && it->first->apply( pose ) ); break;
208  case (NOT ) :
209  TR << "WARNING: CompoundFilter treating operator NOT as ANDNOT" << std::endl;
210  value = value && !it->first->apply( pose );
211  break;
212  }
213  }
214  }
215  if( invert_ ) value = !value;
216  return( value );
217 }
218 
219 void
221 {
222  compound_statement_.clear();
223 }
224 
227 {
228  return( compound_statement_.begin() );
229 }
232 {
233  return( compound_statement_.begin() );
234 }
235 
238 {
239  return( compound_statement_.end() );
240 }
241 
244 {
245  return( compound_statement_.end() );
246 }
247 
248 void
249 CompoundFilter::invert( bool const inv )
250 {
251  invert_ = inv;
252 }
253 
254 /// @details call the compound statement's constituent filters' set_resid
255 void
257 {
258  for( iterator it( compound_statement_.begin() ); it!=compound_statement_.end(); ++it )
260 }
261 
262 void
264  TagPtr const tag,
265  moves::DataMap &,
266  Filters_map const & filters,
267  moves::Movers_map const &,
268  Pose const & )
269 {
270  TR<<"CompoundStatement"<<std::endl;
271  invert_ = tag->getOption<bool>( "invert", false );
272 
273  foreach(TagPtr cmp_tag_ptr, tag->getTags() ){
274  std::string const operation( cmp_tag_ptr->getName() );
275  std::pair< FilterOP, boolean_operations > filter_pair;
276  if( operation == "AND" ) filter_pair.second = AND;
277  else if( operation == "OR" ) filter_pair.second = OR;
278  else if( operation == "XOR" ) filter_pair.second = XOR;
279  else if( operation == "NOR" ) filter_pair.second = NOR;
280  else if( operation == "NAND" ) filter_pair.second = NAND;
281  else if( operation == "ORNOT" ) filter_pair.second = ORNOT;
282  else if( operation == "ANDNOT" ) filter_pair.second = ANDNOT;
283  else if( operation == "NOT" ) filter_pair.second = NOT;
284  else {
285  throw utility::excn::EXCN_RosettaScriptsOption( "Error: Boolean operation in tag is undefined." );
286  }
287  std::string const filter_name( cmp_tag_ptr->getOption<std::string>( "filter_name" ) );
288 
289  Filters_map::const_iterator find_filter( filters.find( filter_name ));
290  bool const filter_found( find_filter!=filters.end() );
291  if( filter_found )
292  filter_pair.first = find_filter->second->clone();
293  else {
294  TR<<"***WARNING WARNING! Filter defined for CompoundStatement not found in filter_list!!!! Defaulting to truefilter***"<<std::endl;
295  filter_pair.first = new filters::TrueFilter;
296  }
297  runtime_assert( filter_found );
298  compound_statement_.push_back( filter_pair );
299  }
300 }
301 
302 ////////////////////////////////////////////////////////////////////////////////////////////////////
303 // @brief Used to combine multiple seperate filters into a single filter value
304  CombinedFilter::CombinedFilter() : Filter( "CombinedValue" ), threshold_(0.0) {}
306 
307 bool
309 {
310  core::Real const value( compute( pose ) );
311 
312  TR<<"CombinedFilter value is "<<value<<", threshold is "<< threshold_ << "."<<std::endl;
313  return( value <= threshold_ );
314 }
315 
316 FilterOP
318 {
319  return new CombinedFilter( *this );
320 }
321 
322 FilterOP
324 {
325  return new CombinedFilter();
326 }
327 
328 void
329 CombinedFilter::report( std::ostream & out, core::pose::Pose const & pose ) const
330 {
331  Real value( compute( pose ) );
332 
333  out<<"Combined filter returns: "<<value<<'\n';
334 }
335 
338 {
339  return compute(pose);
340 }
341 
344 {
345  core::Real value( 0.0 );
346 
347  foreach(FilterWeightPair fw_pair, filterlist_){
348  value += fw_pair.second * fw_pair.first->report_sm( pose );
349  }
350  return( value );
351 }
352 
353 void
355  TagPtr const tag,
356  moves::DataMap &,
357  Filters_map const & filters,
358  moves::Movers_map const &,
359  Pose const & )
360 {
361  threshold_ = tag->getOption<core::Real>( "threshold", 0.0 );
362  utility::vector1< TagPtr > const sub_tags( tag->getTags() );
363  foreach(TagPtr tag_ptr, sub_tags){
364  core::Real weight(1.0);
365  if (tag_ptr->hasOption("factor") ) {
366  weight = tag_ptr->getOption<core::Real>( "factor" );
367  } else if (tag_ptr->hasOption("temp") ) {
368  weight = 1.0 / tag_ptr->getOption<core::Real>( "temp" );
369  }
370 
371  FilterOP filter;
372  std::string const filter_name( tag_ptr->getOption<std::string>( "filter_name" ) );
373  Filters_map::const_iterator find_filter( filters.find( filter_name ));
374  bool const filter_found( find_filter!=filters.end() );
375  if( filter_found ) {
376  filter = find_filter->second->clone();
377  }
378  else {
379  TR.Warning<<"***WARNING WARNING! Filter " << filter_name << " defined for CombinedValue not found in filter_list!!!! ***"<<std::endl;
380  throw utility::excn::EXCN_RosettaScriptsOption("Filter "+filter_name+" not found in filter list.");
381  }
382  filterlist_.push_back( FilterWeightPair(filter, weight) );
383  }
384 }
385 
386 ////////////////////////////////////////////////////////////////////////////////////////////////////
387 /// @brief Apply a sub-mover prior to calculating a filter value
388 MoveBeforeFilter::MoveBeforeFilter() : Filter( "MoveBeforeFilter" ) {}
389 MoveBeforeFilter::MoveBeforeFilter(moves::MoverOP mover, FilterCOP filter) : Filter( "MoveBeforeFilter" ), subfilter_(filter), submover_(mover) {}
391 
392 bool
394 {
395  core::pose::Pose p_mod(pose);
396  submover_->apply(p_mod);
397  return subfilter_->apply(p_mod);
398 }
399 
400 FilterOP
402 {
403  return new MoveBeforeFilter( *this );
404 }
405 
406 FilterOP
408 {
409  return new MoveBeforeFilter();
410 }
411 
412 void
413 MoveBeforeFilter::report( std::ostream & out, core::pose::Pose const & pose ) const
414 {
415  core::pose::Pose p_mod(pose);
416  submover_->apply(p_mod);
417  subfilter_->report(out, p_mod);
418 }
419 
422 {
423  core::pose::Pose p_mod(pose);
424  submover_->apply(p_mod);
425  return subfilter_->report_sm(p_mod);
426 }
427 
428 void
430  TagPtr const tag,
431  moves::DataMap &,
432  Filters_map const & filters,
433  moves::Movers_map const & movers,
434  Pose const & )
435 {
436  std::string mover_name("");
437  std::string filter_name("");
438  if ( tag->hasOption("mover") ) mover_name = tag->getOption< std::string >( "mover" );
439  if ( tag->hasOption("mover_name") ) mover_name = tag->getOption< std::string >( "mover_name" );
440  if ( tag->hasOption("filter") ) filter_name = tag->getOption< std::string >( "filter" );
441  if ( tag->hasOption("filter_name") ) filter_name = tag->getOption< std::string >( "filter_name" );
442 
443  moves::Movers_map::const_iterator find_mover ( movers.find( mover_name ));
444  Filters_map::const_iterator find_filter( filters.find( filter_name ));
445 
446  if( find_mover == movers.end() ) {
447  TR.Error << "ERROR !! mover '"<<mover_name<<"' not found in map: \n" << tag << std::endl;
448  runtime_assert( find_mover != movers.end() );
449  }
450  if( find_filter == filters.end() ) {
451  TR.Error << "ERROR !! filter '"<<filter_name<<"' not found in map: \n" << tag << std::endl;
452  runtime_assert( find_filter != filters.end() );
453  }
454  submover_ = find_mover->second;
455  subfilter_ = find_filter->second;
456 
457  TR << "Setting MoveBeforeFilter for mover '"<<mover_name<<"' and filter '"<<filter_name<<"'"<<std::endl;
458 
459 }
460 
461 ////////////////////////////////////////////////////////////////////////////////////////////////////
462 /// @brief Evaluate to a value contingent on the evaluation of another filter.
463 
465  Filter( "IfThenFilter" ),
466  elsevalue_(0),
467  threshold_(0),
468  floor_(false)
469  {}
471 
472 void
473 IfThenFilter::add_condition( FilterCOP testfilter, FilterCOP valuefilter, core::Real value, bool invert, core::Real weight) {
474  runtime_assert( iffilters_.size() == thenfilters_.size() );
475  runtime_assert( iffilters_.size() == values_.size() );
476  runtime_assert( iffilters_.size() == weights_.size() );
477  runtime_assert( iffilters_.size() == invert_.size() );
478 
479  iffilters_.push_back( testfilter );
480  thenfilters_.push_back( valuefilter );
481  values_.push_back( value );
482  weights_.push_back( weight );
483  invert_.push_back( invert );
484 }
485 
486 void
487 IfThenFilter::set_else( FilterCOP elsefilter, core::Real value, core::Real elseweight ) {
488  elsefilter_ = elsefilter;
489  elsevalue_ = value;
490  elseweight_ = elseweight;
491 }
492 
493 bool
495 {
496  core::Real const value( compute( pose ) );
497 
498  TR<<"IfThenFilter value is "<<value<<", threshold is "<< threshold_;
499  if( floor_ ) {
500  TR << " (lower limit)" << std::endl;
501  return value >= threshold_;
502  } else {
503  TR << " (upper limit)" << std::endl;
504  return value <= threshold_;
505  }
506 }
507 
508 FilterOP
510 {
511  return new IfThenFilter( *this );
512 }
513 
514 FilterOP
516 {
517  return new IfThenFilter();
518 }
519 
520 void
521 IfThenFilter::report( std::ostream & out, core::pose::Pose const & pose ) const
522 {
523  Real value( compute( pose ) );
524 
525  out<<"IfThen filter returns: "<<value<<'\n';
526 }
527 
530 {
531  return compute(pose);
532 }
533 
536 {
537  assert( iffilters_.size() == thenfilters_.size() );
538  assert( iffilters_.size() == values_.size() );
539  assert( iffilters_.size() == weights_.size() );
540  assert( iffilters_.size() == invert_.size() );
541 
542  for( core::Size ii(1); ii<= iffilters_.size(); ++ii ) {
543  assert( iffilters_[ii] );
544  if( invert_[ii] ^ iffilters_[ii]->apply( pose ) ) { // XOR: if invert_ is true, true becomes false and false becomes true
545  if( thenfilters_[ii] ) {
546  return weights_[ii] * thenfilters_[ii]->report_sm( pose );
547  } else {
548  return weights_[ii] * values_[ii];
549  }
550  }
551  }
552  if( iffilters_.size() == 0 ) {
553  TR.Warning << "WARNING: No conditional filters specified for IfThenFilter. Using else values only." << std::endl;
554  }
555  if( elsefilter_ ) {
556  return elseweight_ * elsefilter_->report_sm( pose );
557  }
558 
559  return elseweight_ * elsevalue_;
560 }
561 
562 
563 void
565  TagPtr const tag,
566  moves::DataMap &,
567  Filters_map const & filters,
568  moves::Movers_map const &,
569  Pose const & )
570 {
571  threshold( tag->getOption<core::Real>( "threshold", 0.0 ) );
572  set_lower_threshold( tag->getOption<bool>( "lower_threshold", false ) );
573  if( tag->hasOption( "lower_threshold" ) && ! tag->hasOption( "threshold" ) ){
574  TR.Warning << "WARNING: In IfThenFilter, lower_threshold set without setting threshold." << std::endl;
575  TR.Warning << "WARNING: Note that lower_threshold is a true/false flag, not a real-valued setting." << std::endl;
576  }
577  utility::vector1< TagPtr > const sub_tags( tag->getTags() );
578  foreach(TagPtr tag_ptr, sub_tags){
579  std::string const tagname = tag_ptr->getName();
580  FilterOP valuefilter = 0; //default NULL
581  if( tag_ptr->hasOption("valuefilter") ) {
582  valuefilter = protocols::rosetta_scripts::parse_filter( tag_ptr->getOption<std::string>( "valuefilter" ), filters);
583  }
584  core::Real value( tag_ptr->getOption<core::Real>( "value", 0 ) );
585  core::Real weight( tag_ptr->getOption<core::Real>( "weight", 1 ) );
586 
587  if( tagname == "IF" || tagname == "ELIF" ){
588  if( ! tag_ptr->hasOption("testfilter") ) {
589  TR.Error << "In IfThenFilter, If and ELIF require a tesfilter option." << std::endl;
590  throw utility::excn::EXCN_RosettaScriptsOption("In IfThenFilter, If and ELIF require a tesfilter option.");
591  }
592  FilterOP testfilter = protocols::rosetta_scripts::parse_filter( tag_ptr->getOption<std::string>( "testfilter" ), filters);
593  bool inverttest = tag_ptr->getOption< bool >( "inverttest", false );
594  add_condition( testfilter, valuefilter, value, inverttest, weight );
595  } else if ( tagname == "ELSE" ) {
596  set_else( valuefilter, value, weight );
597  } else {
598  TR.Error << "Unknown subtag name in IfThenFilter: " << tagname << std::endl;
599  TR.Error << " Acceptable values are: IF ELIF ELSE" << std::endl;
600  throw utility::excn::EXCN_RosettaScriptsOption("Unknown subtag name in IfThenFilter: " + tagname );
601  }
602  }
603  TR << "IfThenFilter defined with " << iffilters_.size() << " conditions and "
604  << ( elsefilter_ ? "an ": "no " ) << " else filter and a "
605  << ( floor_ ? "lower " : "upper " ) << "threshold of " << threshold_ << std::endl;
606 }
607 
608 
609 ////////////////////////////////////////////////////////////////////////////////////////////////////
610 // @brief FilterCreator methods
611 
612 FilterOP
614 
616 TrueFilterCreator::keyname() const { return "TrueFilter"; }
617 
618 FilterOP
620 
622 FalseFilterCreator::keyname() const { return "FalseFilter"; }
623 
624 FilterOP
626 
628 StochasticFilterCreator::keyname() const { return "Stochastic"; }
629 
630 FilterOP
632 
634 CompoundFilterCreator::keyname() const { return "CompoundStatement"; }
635 
636 FilterOP
638 
640 CombinedFilterCreator::keyname() const { return "CombinedValue"; }
641 
642 FilterOP
644 
646 MoveBeforeFilterCreator::keyname() const { return "MoveBeforeFilter"; }
647 
648 FilterOP
650 
652 IfThenFilterCreator::keyname() const { return "IfThenFilter"; }
653 
654 
655 } // filters
656 } // protocols