Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DockDesignParser.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 // :noTabs=false:tabSize=4:indentSize=4:
4 //
5 // (c) Copyright Rosetta Commons Member Institutions.
6 // (c) This file is part of the Rosetta software suite and is made available under license.
7 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
8 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
9 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
10 
11 /// @file protocols/jd2/DockDesignParser.cc
12 /// @brief August 2008 job distributor as planned at RosettaCon08 - Interface base class Parser
13 /// @author Sarel Fleishman sarelf@u.washington.edu
14 
15 #include <protocols/jd2/Job.hh>
17 
18 // Package headers
21 
22 // Project headers
23 #include <core/types.hh>
26 #include <core/pose/Pose.hh>
27 
28 #include <ObjexxFCL/string.functions.hh>
29 //#include <core/pack/task/operation/TaskOperation.hh>
30 //#include <core/pack/task/operation/TaskOperationFactory.hh>
31 #include <basic/options/option.hh>
33 
37 #include <utility/tag/Tag.hh>
40 
41 // movers
42 #include <protocols/moves/Mover.hh>
46 #include <boost/foreach.hpp>
47 #define foreach BOOST_FOREACH
48 
49 
50 //scoring grids
51 //#include <protocols/qsar/scoring_grid/GridManager.hh>
52 //#include <protocols/qsar/qsarTypeManager.hh>
53 
54 //Pose Metric Calculators for filters
59 
60 //#include <protocols/fldsgn/filters/SheetTopologyFilter.hh>
61 //#include <protocols/fldsgn/filters/NcontactsFilter.hh>
62 
63 //#include <protocols/enzdes/EnzFilters.hh>
64 
65 // constraint types
66 // AUTO-REMOVED #include <core/scoring/constraints/ConstraintIO.hh>
67 
68 // Utility headers
69 #include <utility/vector1.hh>
70 #include <utility/io/izstream.hh>
71 
72 // C++ headers
73 #include <iostream>
74 #include <sstream>
75 #include <fstream>
76 #include <map>
77 #include <set>
78 
79 // option key includes
80 
81 #include <basic/options/keys/parser.OptionKeys.gen.hh>
83 
84 #include <utility/vector0.hh>
85 #include <basic/Tracer.hh>
86 
87 
88 namespace protocols {
89 namespace jd2 { // why is this in namespace jd2?
90 
91 using namespace core;
92  using namespace basic::options;
93  using namespace scoring;
94 using namespace moves;
95 
96 static basic::Tracer TR( "protocols.jd2.DockDesignParser" );
97 
99  Parser()
100  //,ddfilter_factory_( new DockDesignFilterFactory )
101 {
103 }
104 
106 
109 
110 /// @details Uses the Tag interface to the xml reader library in boost to parse an xml file that contains design
111 /// protocol information. A sample protocol file can be found in src/pilot/apps/sarel/dock_design.protocol.
112 /// SCOREFXNS provides a way to define scorefunctions as they are defined in the rosetta database, using the
113 /// weights/patch convenctions. Several default scorefunctions are preset and can be used without defining them
114 /// explicitly.
115 /// FILTERS defines a set of filters that can be used together with the dockdesign movers to prune out poses that
116 /// don't meet certain criteria
117 /// MOVERS defines the movers that will be used
118 /// PROTOCOLS is the only order-sensitive section where subsequent movers and filters are expected to be defined.
119 /// These movers and filters were defined in the previous two sections. The order in which the protocols are
120 /// specified by the user will be maintained by the DockDesign mover.
121 /// APPLY_TO_POSE This section allows for certain movers to be applied to the pose prior to starting the DockDesign
122 /// protocol. For instance, these movers could set constraints, such as favor_native_residue. In this case, for
123 /// example, the weights of res_type_constraint in all of the scorefunctions that are defined in SCOREFXNS or by
124 /// default are set to 1.0, but can be changed by the user globally (in the definition of the weight on the constraint),
125 /// or in particular for each of the scorefunctions by changing the relevant term (which is set by default to the
126 /// global value).
127 /// OUTPUT is a section which allows the XML control of how things are output
128 /// Notice that the order of the sections by which the protocol is written doesn't matter, BUT the order of the
129 /// mover-filter pairs in PROTOCOLS section does matter.
130 bool
131 DockDesignParser::generate_mover_from_pose( JobCOP, Pose & pose, MoverOP & in_mover, bool new_input, std::string const xml_fname ){
132 
133  bool modified_pose( false );
134 
135  if( !new_input ) return modified_pose;
136 
138 
139  std::string const dock_design_filename( xml_fname == "" ? option[ OptionKeys::parser::protocol ] : xml_fname );
140  TR << "dock_design_filename=" << dock_design_filename << std::endl;
141  utility::io::izstream fin;
142  fin.open(dock_design_filename.c_str() );
143  if( !fin.good() ){
144  utility_exit_with_message("Unable to open Rosetta Scripts XML file: '" + dock_design_filename + "'.");
145  }
146  TagPtr tag;
147  if( option[ OptionKeys::parser::script_vars ].user() ) {
148  std::stringstream fin_sub;
149  substitute_variables_in_stream(fin, option[ OptionKeys::parser::script_vars ], fin_sub);
150  tag = utility::tag::Tag::create( fin_sub );
151  }
152  else {
153  tag = utility::tag::Tag::create(fin);
154  }
155  fin.close();
156  TR << "Parsed script:" << "\n";
157  TR << tag;
158  TR.flush();
159  runtime_assert( tag->getName() == "dock_design" || tag->getName() == "ROSETTASCRIPTS" );
160 
161  Movers_map movers;
163  DataMap data; // abstract objects, such as scorefunctions, to be used by filter and movers
164 
165  MoverOP mover;
166 
167  typedef std::pair< std::string const, MoverOP > StringMover_pair;
168  typedef std::pair< std::string const, protocols::filters::FilterOP > StringFilter_pair;
169  typedef std::pair< std::string const, ScoreFunctionOP > StringScorefxn_pair;
170  typedef std::pair< std::string const, StringScorefxn_pair > ScorefxnObjects_pair;
171 //setting up some defaults
174  filters.insert( StringFilter_pair( "true_filter", true_filter ) );
175  filters.insert( StringFilter_pair( "false_filter", false_filter ) );
176 
177  MoverOP null_mover = new protocols::moves::NullMover();
178  movers.insert( StringMover_pair( "null", null_mover) );
179 
180 // default scorefxns
185  ScoreFunctionOP docking_score_low = ScoreFunctionFactory::create_score_function( "interchain_cen" );
186  ScoreFunctionOP score4L = ScoreFunctionFactory::create_score_function( "cen_std", "score4L" );
187 
188  data.add( "scorefxns", "commandline", commandline_sfxn );
189  data.add( "scorefxns", "score12", score12 );
190  data.add( "scorefxns", "score_docking", docking_score );
191  data.add( "scorefxns", "soft_rep", soft_rep );
192  data.add( "scorefxns", "score_docking_low", docking_score_low );
193  data.add( "scorefxns", "score4L", score4L );
194  //default scorefxns end
195 
196  /// Data Loaders
197  std::set< std::string > non_data_loader_tags;
198  non_data_loader_tags.insert( "MOVERS" );
199  non_data_loader_tags.insert( "APPLY_TO_POSE" );
200  non_data_loader_tags.insert( "FILTERS" );
201  non_data_loader_tags.insert( "PROTOCOLS" );
202  non_data_loader_tags.insert( "OUTPUT" );
203 
204  /// Load in data into the DataMap object. All tags beside those listed
205  /// in the non_data_loader_tags set are considered DataLoader tags.
206  TagPtrs const all_tags = tag->getTags();
207  for ( Size ii = 0; ii < all_tags.size(); ++ii ) {
208  using namespace parser;
209  TagPtr iitag = all_tags[ ii ];
210  if ( non_data_loader_tags.find( iitag->getName() ) != non_data_loader_tags.end() ) continue;
211  DataLoaderOP loader = DataLoaderFactory::get_instance()->newDataLoader( iitag->getName() );
212  loader->load_data( pose, iitag, data );
213  }
214  if ( !tag->hasTag("MOVERS") )
215  utility_exit_with_message("parser::protocol file must specify MOVERS section");
216  if ( !tag->hasTag("PROTOCOLS") )
217  utility_exit_with_message("parser::protocol file must specify PROTOCOLS section");
218 
219  foreach( TagPtr const curr_tag, all_tags ){
220  ///// APPLY TO POSE
221  if ( curr_tag->getName() == "APPLY_TO_POSE" ) { // section is not mandatory
222  /// apply to pose may affect all of the scorefxn definitions below, so it is called first.
223  TagPtrs const apply_tags( curr_tag->getTags() );
224  //bool has_profile( false ); // This mutual-exclusion check has been disabled., has_fnr( false ); // to see that the user hasn't turned both on by mistake
225 
226  foreach(TagPtr apply_tag_ptr, apply_tags){
227  std::string const mover_type( apply_tag_ptr->getName() );
228  MoverOP new_mover( MoverFactory::get_instance()->newMover( apply_tag_ptr, data, filters, movers, pose ) );
229  runtime_assert( new_mover );
230  new_mover->apply( pose );
231  TR << "Defined and applied mover of type " << mover_type << std::endl;
232  bool const name_exists( movers.find( mover_type ) != movers.end() );
233  if ( name_exists ) {
234  utility_exit_with_message( "Can't apply_to_pose the same mover twice" + mover_type );
235  }
236 
237  modified_pose = true;
238  } /// done applyt_tag_it
239 
240  }// fi apply_to_pose
241 
242 
243  TR.flush();
244 
245  ////// Filters
246  if ( curr_tag->getName() == "FILTERS" ) {
247 
248  foreach(TagPtr tag_ptr, curr_tag->getTags()){
249  std::string const type( tag_ptr->getName() );
250  if ( ! tag_ptr->hasOption("name") )
251  utility_exit_with_message("Can't define unnamed Filter of type " + type );
252  std::string const user_defined_name( tag_ptr->getOption<std::string>("name") );
253  bool const name_exists( filters.find( user_defined_name ) != filters.end() );
254  if ( name_exists ) {
255  TR.Error << "ERROR filter of name \"" << user_defined_name << "\" (with type " << type
256  << ") already exists. \n" << tag << std::endl;
257  utility_exit_with_message("Duplicate definition of Filter with name " + user_defined_name);
258  }
259  protocols::filters::FilterOP new_ddf( protocols::filters::FilterFactory::get_instance()->newFilter( tag_ptr, data, filters, movers, pose ) );
260  runtime_assert( new_ddf );
261  filters.insert( std::make_pair( user_defined_name, new_ddf ) );
262  TR << "Defined filter named \"" << user_defined_name << "\" of type " << type << std::endl;
263  }
264  }
265 
266  TR.flush();
267 
268  ////// MOVERS
269  if( curr_tag->getName() == "MOVERS" ){
270  foreach(TagPtr tag_ptr, curr_tag->getTags()){
271  std::string const type( tag_ptr->getName() );
272  if ( ! tag_ptr->hasOption("name") )
273  utility_exit_with_message("Can't define unnamed Mover of type " + type );
274  std::string const user_defined_name( tag_ptr->getOption<std::string>("name") );
275  bool const name_exists( movers.find( user_defined_name ) != movers.end() );
276  if ( name_exists ) {
277  TR.Error << "ERROR mover of name \"" << user_defined_name << "\" (with type " << type
278  << ") already exists.\n" << tag << std::endl;
279  utility_exit_with_message("Duplicate definition of Mover with name " + user_defined_name);
280  }
281  /// APL -- singleton factory replacement.
282  MoverOP new_mover( MoverFactory::get_instance()->newMover( tag_ptr, data, filters, movers, pose ) );
283  runtime_assert( new_mover );
284  movers.insert( std::make_pair( user_defined_name, new_mover ) );
285  TR << "Defined mover named \"" << user_defined_name << "\" of type " << type << std::endl;
286  }
287  }//fi MOVERS
288  TR.flush();
289  }// foreach curr_tag
290 
291  ////// ADD MOVER FILTER PAIRS
292  TagPtr const protocols_tag( tag->getTag("PROTOCOLS") );
293  protocol->parse_my_tag( protocols_tag, data, filters, movers, pose );
294  TR.flush();
295 
296  ////// Set Output options
297  if ( tag->hasTag("OUTPUT") ) {
298  TagPtr const output_tag( tag->getTag("OUTPUT") );
299  protocol->final_scorefxn( rosetta_scripts::parse_score_function( output_tag, data, "commandline" ) );
300  } else {
301  protocol->final_scorefxn( commandline_sfxn );
302  }
303 
304  tag->die_for_unaccessed_options_recursively();
305  in_mover = protocol;
306  return modified_pose;
307 }
308 
309 ///@brief Create a variable substituted version of the input stream, given a StringVectorOption formated list of variables
310 ///to substitiute. Each item in script_vars should be in the form of "variable=value", where "value" is the string to substitiute
311 ///into the input stream whereever the string "%%variable%%" is found in the input.
312 ///
313 ///Having the return value be passed through a parameter is to get around some copy-constructor limitations of C++ streams.
314 void
315 DockDesignParser::substitute_variables_in_stream( std::istream & in, utility::options::StringVectorOption const& script_vars, std::stringstream & out){
316  using namespace std;
317  //Parse variable substitutions
318  map<string,string> var_map;
319  for( Size ii = 1; ii <= script_vars.size(); ii++ ) {
320  Size eq_pos(script_vars[ii].find('='));
321  if(eq_pos != string::npos) { //ignore ones without a '='
322  var_map[ script_vars[ii].substr(0,eq_pos) ] = script_vars[ii].substr(eq_pos+1);
323  }
324  }
325  //Print parsing for confirmation
326  TR << "Variable substitution will occur with the following values: ";
327  for( map<string,string>::const_iterator map_it( var_map.begin() ), map_end( var_map.end() );
328  map_it != map_end; ++map_it ){
329  TR << "'%%" << map_it->first << "%%'='" << map_it->second << "'; ";
330  }
331  TR << std::endl;
332  var_map[""] = "%%"; //for %%%%->%% substitutions
333  //Perform actual variable substitution
334  TR << "Substituted script:" << "\n";
335  string line;
336  while( getline( in, line ) ) {
337  Size pos, end, last(0);
338  string outline; // empty string
339  while( ( pos = line.find("%%", last) ) != string::npos) {
340  end = line.find("%%", pos+2);
341  if(end == string::npos) break; //Unmatched %% on line - keep as is.
342  outline += line.substr( last, pos-last );
343  last = end+2;
344  string var( line.substr( pos+2, end-(pos+2) ) );
345  if( var_map.find( var ) != var_map.end() ) {
346  outline += var_map[var];
347  }
348  else {
349  outline += "%%" + var + "%%"; // Silently ignore missing values - will probably cause error later.
350  }
351  }
352  outline += line.substr( last ); // Add the rest of the line, starting at last
353  TR << outline << "\n";
354  out << outline << "\n";
355  }
356  TR.flush();
357 }
358 
359 ///@brief Factories avoid requiring compiler dependencies for all possible constructible derived classes,
360 ///by allowing runtime registration of derived class prototypes. However, this requires
361 ///pre-registration of a derived type with the factory prior to asking the factory to return an
362 ///instance of that type. This method registers those additional derived classes that are available for
363 ///construction in the DockDesignParser context.
364 /// TO-DO: replace this manual factory registration system with a load-time-initialized singleton scheme (see r32404 for example)
365 void
367 {
368  // note: TaskOperations are now registered with a singleton factory at load time using apl's creator/registrator scheme
369 
370  // also register some constraint types with the ConstraintFactory (global singleton class)
371  // this allows derived non-core constraints to be constructed from string definitions in constraints files
372  //using namespace core::scoring::constraints;
373  //ConstraintFactory & cstf( ConstraintIO::get_cst_factory() );
374  //cstf.add_type( new core::scoring::constraints::SequenceProfileConstraint(
375  // Size(), utility::vector1< id::AtomID >(), NULL ) );
376 
377  // register calculators
378  core::Size const chain1( 1 ), chain2( 2 );
379  using namespace core::pose::metrics;
380 
381  if( !CalculatorFactory::Instance().check_calculator_exists( "sasa_interface" ) ){
383  CalculatorFactory::Instance().register_calculator( "sasa_interface", int_sasa_calculator );
384  }
385 
386  if( !CalculatorFactory::Instance().check_calculator_exists( "sasa" ) ){
388  CalculatorFactory::Instance().register_calculator( "sasa", sasa_calculator );
389  }
390  if( !CalculatorFactory::Instance().check_calculator_exists( "ligneigh" ) ){
392  CalculatorFactory::Instance().register_calculator( "ligneigh", lig_neighbor_calc );
393  }
394  if( !CalculatorFactory::Instance().check_calculator_exists( "liginterfE" ) ){
396  CalculatorFactory::Instance().register_calculator( "liginterfE", lig_interf_E_calc );
397  }
398 }
399 
400 }//jd2
401 }//protocols