Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JD2ResourceManagerJobInputter.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/resource_manager/planner/JD2ResourceManagerJobInputter.cc
11 /// @brief
12 /// @author
13 
14 // Unit headers
17 
18 // Package headers
20 #include <protocols/jd2/Job.hh>
21 #include <basic/resource_manager/JobOptions.hh>
23 
24 // Project headers
25 #include <core/pose/Pose.hh>
26 
30 
31 // Utility Headers
32 #include <utility/io/izstream.hh>
33 #include <utility/excn/Exceptions.hh>
34 #include <utility/pointer/ReferenceCount.hh>
35 #include <utility/tag/Tag.hh>
36 #include <utility/file/FileName.hh>
37 #include <utility/options/keys/BooleanOptionKey.hh>
38 #include <utility/options/keys/IntegerOptionKey.hh>
39 #include <utility/options/keys/FileOptionKey.hh>
40 #include <utility/options/keys/PathOptionKey.hh>
41 #include <utility/options/keys/RealOptionKey.hh>
42 #include <utility/options/keys/StringOptionKey.hh>
43 #include <utility/string_util.hh>
44 #include <utility/sql_database/DatabaseSessionManager.hh>
45 
46 // Basic headers
47 #include <basic/Tracer.hh>
48 #include <basic/options/option.hh>
49 #include <basic/options/keys/OptionKeys.hh>
50 #include <basic/options/keys/jd2.OptionKeys.gen.hh>
51 #include <basic/options/keys/out.OptionKeys.gen.hh>
52 #include <basic/database/sql_utils.hh>
53 
54 // Boost headers
55 #include <boost/lexical_cast.hpp>
56 
57 // External headers
58 #include <cppdb/frontend.h>
59 
60 //C++ headers
61 #include <istream>
62 #include <string>
63 #include <sstream>
64 
65 namespace protocols {
66 namespace jd2 {
67 
68 using utility::excn::EXCN_Msg_Exception;
69 using basic::resource_manager::ResourceOP;
70 using basic::resource_manager::ResourceManager;
71 using basic::resource_manager::ResourceTag;
72 using basic::resource_manager::JobOptions;
73 using basic::resource_manager::JobOptionsOP;
74 using core::pose::PoseOP;
75 using core::pose::Pose;
76 
77 using std::endl;
78 using std::string;
79 using std::stringstream;
80 
81 static basic::Tracer tr("protocols.jd2.JD2ResourceManagerJobInputter");
82 
83 
84 
85 //CREATOR SECTION
88 {
89  return "JD2ResourceManagerJobInputter";
90 }
91 
95 }
96 
97 
99  last_input_tag_("")
100 {}
101 
103 
104 void
106  Pose & pose,
107  JobOP job )
108 {
109  tr.Debug << "JD2ResourceManagerJobInputter::pose_from_job" << endl;
110 
111  std::string const & input_tag(job->inner_job()->input_tag());
112 
113  if(last_input_tag_ == ""){
114  last_input_tag_ = input_tag;
115  } else {
116  if(last_input_tag_ != input_tag){
118  last_input_tag_ = input_tag;
119  }
120  }
121 
122  if ( !job->inner_job()->get_pose() ) {
123  tr.Debug
124  << "Retrieving pose from ResourceManager (tag = " << input_tag << ")" << endl;
125  pose.clear();
126  JD2ResourceManager * jd2_resource_manager(
128  ResourceOP resource;
129 
130  //Check to see if we have a Residue resource, if so load it into the chemical manager if it hasn't already been loaded
131  if(jd2_resource_manager->has_resource_tag_by_job_tag("residue", input_tag))
132  {
133  ResourceOP residue_resource(jd2_resource_manager->get_resource_by_job_tag("residue",input_tag));
134 
135  core::chemical::ResidueTypeOP new_residue(dynamic_cast<core::chemical::ResidueType *>(residue_resource()));
136  std::string type_set_name(new_residue->residue_type_set().name());
137  if(!core::chemical::ChemicalManager::get_instance()->residue_type_set(type_set_name)->has_name(new_residue->name()))
138  {
139  tr << "loading residue " << new_residue->name() << " into " << type_set_name <<" residue_type_set" <<std::endl;
141  }
142  }
143 
144  try {
145  tr << "Loading startstruct " << jd2_resource_manager->find_resource_tag_by_job_tag( "startstruct", input_tag ) << " for job " <<
146  input_tag <<std::endl;
147  resource = jd2_resource_manager->get_resource_by_job_tag("startstruct", input_tag);
148  } catch ( utility::excn::EXCN_Msg_Exception const & e ) {
149  std::ostringstream err;
150  err << e.msg() << std::endl;
151  err << "Failed to access 'startstruct' resource from the JD2ResourceManager for job '";
152  err << input_tag << "' with nstruct index " << job->nstruct_index();
153  err << "\n" << "Exception caught and re-thrown from JD2ResourceManagerJobInputter::pose_from_job\n";
154  throw utility::excn::EXCN_Msg_Exception( err.str() );
155  }
156 
157  PoseOP resource_pose( dynamic_cast< Pose * > ( resource() ) );
158 
159  /// make sure the resource that we requested from the resource manager is in fact a pose.
160  if ( ! resource_pose ) {
161  std::ostringstream err;
162  err
163  << "Error trying to access starting structure (startstruct) "
164  << "for job with tag '";
165  err << input_tag << "'.";
166  if ( jd2_resource_manager->has_resource_tag_by_job_tag("startstruct", input_tag) ) {
167  ResourceTag rt(jd2_resource_manager->find_resource_tag_by_job_tag("startstruct", input_tag));
168  err
169  << " The resource tag '" << rt << "' "
170  << "for this job is not for a Pose object" << endl;
171  } else {
172  err << " This starting structure for this job is critically absent\n";
173  }
174  throw EXCN_Msg_Exception( err.str() );
175  }
176 
177  /// Save a copy of the resource_pose into the inner job.
178  load_pose_into_job(resource_pose, job);
179  pose = *resource_pose;
180  } else {
181  pose.clear();
182  pose = *(job->inner_job()->get_pose());
183  tr.Debug
184  << "filling pose from saved copy (tag = "
185  << job->input_tag() << ")" << endl;
186  }
187 
188 }
189 
190 void
192 {
193  tr << "Initializing jobs from resource definition files" << std::endl;
194  utility::vector1< utility::file::FileName > resource_definition_files
195  = basic::options::option[ basic::options::OptionKeys::jd2::resource_definition_files ];
196  for ( core::Size ii = 1; ii <= resource_definition_files.size(); ++ii ) {
197 
198  tr.Debug << "Reading from resource definition file " << resource_definition_files[ii] << std::endl;
199  utility::io::izstream instream( resource_definition_files[ii]().c_str() );
200  fill_jobs_from_stream( instream, jobs );
201  }
202 }
203 
204 void
206  std::string const & job_tag)
207 {
208  JD2ResourceManager * jd2_resource_manager(
210 
211  jd2_resource_manager->mark_job_tag_as_complete(job_tag);
212  std::list<ResourceTag> resources_for_job(jd2_resource_manager->get_resource_tags_for_job_tag(job_tag));
213 
214  std::list<ResourceTag>::iterator resource_list_it = resources_for_job.begin();
215  for(; resource_list_it != resources_for_job.end(); ++resource_list_it)
216  {
217  core::Size job_count(jd2_resource_manager->get_count_of_jobs_associated_with_resource_tag(*resource_list_it));
218  if(job_count == 0)
219  {
220  if(!jd2_resource_manager->ResourceManager::has_resource(*resource_list_it)){
221  tr << "Skipping deleting '" << *resource_list_it << "' because it doesn't exist in the ResourceManager." << std::endl;
222  continue;
223  }
224 
225  //This might be a ResidueType. if it is, we should delete the residue from the resource from the ChemicalManager
226  ResourceOP current_residue = jd2_resource_manager->find_resource(*resource_list_it);
227  core::chemical::ResidueTypeOP new_residue(dynamic_cast<core::chemical::ResidueType *>(current_residue()));
228 
229  if(new_residue)
230  {
231  std::string residue_type_set = new_residue->residue_type_set().name();
233  ChemicalManager::nonconst_residue_type_set(residue_type_set).remove_residue_type(new_residue->name());
234  }
235 
236  tr << "Deleting resource " << *resource_list_it <<std::endl;
237 
238  jd2_resource_manager->free_resource_by_tag(*resource_list_it);
239  }
240  }
241 }
242 
243 void
245 {
246  JD2ResourceManager * jd2_resource_manager(
248 
249  utility::tag::TagPtr resource_tags = utility::tag::Tag::create( instream );
250 
251  for ( utility::tag::Tag::tags_t::const_iterator
252  tag_iter = resource_tags->getTags().begin(),
253  tag_iter_end = resource_tags->getTags().end();
254  tag_iter != tag_iter_end; ++tag_iter ) {
255  std::string const & tagname = (*tag_iter)->getName();
256  if ( tagname == "ResourceLocators" ) {
257  jd2_resource_manager->read_resource_locators_tags( *tag_iter );
258  } else if ( tagname == "ResourceOptions" ) {
259  jd2_resource_manager->read_resource_options_tags( *tag_iter );
260  } else if ( tagname == "Resources" ) {
261  jd2_resource_manager->read_resources_tags( *tag_iter );
262  } else if ( tagname == "Jobs" ) {
263  parse_jobs_tags( *tag_iter, jobs );
264  }
265  }
266 }
267 
268 void
270  utility::tag::TagPtr jobs_tags,
271  Jobs & jobs
272 )
273 {
274  //identify options and resources that apply to each job
275  std::map< std::string, std::string > generic_resources_for_job;
276  JobOptionsOP generic_job_options(new JobOptions());
277 
278  for ( utility::tag::Tag::tags_t::const_iterator
279  tag_iter = jobs_tags->getTags().begin(),
280  tag_iter_end = jobs_tags->getTags().end();
281  tag_iter != tag_iter_end; ++tag_iter ) {
282  std::string const & tagname = (*tag_iter)->getName();
283  if ( tagname == "Option" ) {
284  read_Option_subtag_for_job( *tag_iter, generic_job_options );
285  } else if ( tagname == "Data" ) {
286  std::string dummy_input_tag;
288  *tag_iter, "generic", dummy_input_tag,
289  generic_resources_for_job );
290  }
291  }
292 
293 
294  for ( utility::tag::Tag::tags_t::const_iterator
295  tag_iter = jobs_tags->getTags().begin(),
296  tag_iter_end = jobs_tags->getTags().end();
297  tag_iter != tag_iter_end; ++tag_iter ) {
298  std::string const & tagname = (*tag_iter)->getName();
299  if ( tagname == "Job" ) {
300  parse_job_tag( *tag_iter, generic_resources_for_job, *generic_job_options, jobs );
301  } else if( tagname == "JobsTable"){
302  parse_jobs_table_tag( *tag_iter, generic_resources_for_job, *generic_job_options, jobs );
303  } else {
304  std::ostringstream err;
305  err << "Error parsing jobs tags in JD2ResourceManagerJobInputter: unrecognized tag '" << tagname << "'";
306  EXCN_Msg_Exception( err.str() );
307  }
308  }
309 
311 }
312 
313 void
315  utility::tag::TagPtr jobs_tag,
316  std::map< std::string, std::string > const & generic_resources_for_job,
317  JobOptions const & generic_job_options,
318  Jobs & jobs
319 )
320 {
322 
323  //InnerJobOP inner_job = new InnerJob;
324  std::string jobname;
325  std::string input_tag; // <--- pdb name
326  std::map< std::string, std::string > resources_for_job(generic_resources_for_job);
327 
328 
329  /// if the name is not given
330  if ( jobs_tag->hasOption( "name" )) {
331  jobname = jobs_tag->getOption< std::string >( "name" );
332  }
333 
334  JobOptionsOP job_options = new JobOptions(generic_job_options);
335  for ( utility::tag::Tag::tags_t::const_iterator
336  tag_iter = jobs_tag->getTags().begin(),
337  tag_iter_end = jobs_tag->getTags().end();
338  tag_iter != tag_iter_end; ++tag_iter ) {
339  std::string const & tagname = (*tag_iter)->getName();
340  if ( tagname == "Option" ) {
341  read_Option_subtag_for_job( *tag_iter, job_options );
342  } else if ( tagname == "Data" ) {
343  read_Data_for_subtag( *tag_iter, jobname, input_tag, resources_for_job );
344  } else if (tagname == "ResidueType") {
345  read_ResidueType_for_subtag(*tag_iter, resources_for_job);
346  }// are there other kinds of tags?
347  }
348 
349  if(jobs_tag->hasOption("nstruct")){
350  // if it's not specified here, it can be specified in an <Option/>
351  // tag or default to 1.
353  "nstruct", jobs_tag->getOption<string>("nstruct"), job_options);
354  }
355 
356  if ( jobname.size() == 0 ) {
357  if ( jd2rm->has_resource_configuration( input_tag ) ) {
358  std::ostringstream err;
359  err << "Repeat input startstruct for a job which has not been given a name. Ordinarily, if a job is\n";
360  err << "given without a name, it is assigned a name based on its startstruct. If, however, the same\n";
361  err << "startstruct is given multiple times, then we cannot ensure that job names are unique. Please\n";
362  err << "give each job with a shared startstrct a different name.\n";
363  err << "Offeding startstruct: '" << input_tag << "\n";
364  throw EXCN_Msg_Exception( err.str() );
365  }
366 
367  jobname = input_tag;
368  }
369 
370  record_job(jobname, resources_for_job, job_options, jobs);
371 }
372 
373 void
376  std::map< std::string, std::string > const & generic_resources_for_job,
377  JobOptions const & generic_job_options,
378  Jobs & jobs
379 ) {
380  using namespace basic::database;
381 
382  utility::sql_database::sessionOP db_session = parse_database_connection(tag);
383 
384  string sql_command;
385  if(tag->hasOption("sql_command")){
386  sql_command = tag->getOption<string>("sql_command");
387  check_statement_sanity(sql_command);
388  } else {
389  stringstream err_msg;
390  err_msg
391  << "The JobsTable tag requires a 'sql_command' tag that "
392  << "is an SQL SELECT statement that returns the following column formats" << endl
393  << "ordered by <job_name>:" << endl
394  << "\t(<job_name>, 'Resource', <desc>, <resource_tag>)" << endl
395  << "\t(<job_name>, 'Option', <option_key>, <option_value>)" << endl;
396  throw utility::excn::EXCN_Msg_Exception(err_msg.str());
397  }
398 
399  cppdb::statement select_stmt(safely_prepare_statement(sql_command, db_session));
400  cppdb::result res(safely_read_from_database(select_stmt));
401 
402  std::string job_table_schema =
403  "Each row of the jobs table should have one of the following formats\n"
404  "\n"
405  " job_name, 'Resource', desc, resource_tag\n"
406  " job_name, 'Option', option_key, option_value\n"
407  "\n"
408  " * desc: A job-agnostic description for a resource like 'native' or 'symm_data'\n"
409  " that can be referenced in the protocol.\n"
410  "\n"
411  " * resource_tag: The tag of a resource described in the <Resources/> block.\n"
412  "\n"
413  " * option_key: An optionally namespaced option key (string) for the options\n"
414  " system like 'in:file:native'\n"
415  "\n"
416  " * option_value: A value or list of values that processed into the option system\n";
417 
418  if(res.cols() != 4){
419  stringstream err_msg;
420  err_msg
421  << "The JobsTable tag requires a 'sql_command' tag" << endl
422  << job_table_schema << endl
423  << "Instead, the query returned " << res.cols() << ":" << endl
424  << "SQL query:" << endl
425  << sql_command << endl;
426  throw utility::excn::EXCN_Msg_Exception(err_msg.str());
427  }
428 
429  Size row_number(0);
430  string previous_job_name("");
431  string input_tag;
432  std::map< string, string > resources_for_job(generic_resources_for_job);
433  JobOptionsOP job_options = new JobOptions(generic_job_options);
434  while(res.next()){
435  row_number++;
436 
437  string job_name, resource_type, key, value;
438  res >> job_name >> resource_type >> key >> value;
439 
440  if(row_number != 1 && previous_job_name != job_name){
441  // we've just finished collecting information for the job,
442  // record job and reset the invariants
443  record_job(previous_job_name, resources_for_job, job_options, jobs);
444  resources_for_job = generic_resources_for_job;
445  job_options = new JobOptions(generic_job_options);
446  previous_job_name = job_name;
447 
448  }
449 
450 
451  if(resource_type == "Resource"){
452  resources_for_job[ key ] = value;
453  } else if (resource_type == "Option"){
454  parse_options_name_and_value(key, value, job_options);
455  } else {
456  stringstream err_msg;
457  err_msg
458  << "Unrecognized data type '" << resource_type << "' for job '" << job_name << "'" << endl
459  << "The JobsTable tag requires a 'sql_command' tag" << endl
460  << job_table_schema << endl
461  << endl
462  << "SQL query:" << endl
463  << sql_command << endl
464  << endl
465  << "Resources:" << endl;
466  for(std::map<string,string>::const_iterator i=resources_for_job.begin(), ie=resources_for_job.end(); i != ie; ++i){
467  err_msg << "\t '" << i->first << "' <- '" << i->second << "'" << endl;
468  }
469  err_msg
470  << "Options:" << endl
471  << job_options << endl;
472 
473  throw EXCN_Msg_Exception(err_msg.str());
474  }
475 
476  if(previous_job_name.empty()){
477  previous_job_name = job_name;
478  }
479  }
480 
481  if(row_number == 0){
482  tr.Warning << "JobsTable returned no rows." << endl;
483  }
484 
485  record_job(previous_job_name, resources_for_job, job_options, jobs);
486 }
487 
488 void
490  string const & job_name,
491  std::map< string, string > const & resources_for_job,
492  JobOptionsOP job_options,
493  Jobs & jobs
494 ) {
495 
496  JD2ResourceManager * jd2rm(
498 
499  using namespace basic::options;
500 
501  for ( std::map< string, string >::const_iterator
502  iter = resources_for_job.begin(), iter_end = resources_for_job.end();
503  iter != iter_end; ++iter ) {
504  jd2rm->add_resource_tag_by_job_tag( iter->first, job_name, iter->second );
505  }
506 
508  job_name, job_options);
509 
510  //Have the jobs with this job_name already been created?
511  core::Size n_jobs(0);
512  for(Jobs::const_iterator ii = jobs.begin(), iie = jobs.end(); ii != iie; ++ii){
513  if( (*ii)->input_tag() == job_name ) {
514  n_jobs++;
515  }
516  }
517 
518  //If not, then add them
519  if(n_jobs==0){
520  Size nstruct(1);
521  if(job_options->has_option(OptionKeys::out::nstruct)){
522  nstruct = job_options->get_option(OptionKeys::out::nstruct);
523  }
524 
525  InnerJobOP inner_job = new InnerJob( job_name, nstruct );
526  for ( Size ii = 1; ii <= nstruct; ++ii ) {
527  jobs.push_back( new Job( inner_job, ii ));
528  }
529  } else {
530  if(job_options->has_option(OptionKeys::out::nstruct)){
531  Size requested_nstruct = job_options->get_option(OptionKeys::out::nstruct);
532  if(requested_nstruct != n_jobs){
533  std::stringstream err_msg;
534  err_msg
535  << "Conflicting specification for nstruct for job with name '" << job_name << "'" << std::endl
536  << "Previous nstruct=" << n_jobs << ", new nstruct=" << requested_nstruct << std::endl;
537  throw EXCN_Msg_Exception( err_msg.str() );
538  }
539  }
540  }
541 }
542 
543 void
545  utility::tag::TagPtr options_tag,
546  JobOptionsOP job_options
547 )
548 {
549  for ( utility::tag::Tag::options_t::const_iterator
550  opt_iter = options_tag->getOptions().begin(),
551  opt_iter_end = options_tag->getOptions().end();
552  opt_iter != opt_iter_end; ++opt_iter ) {
553  std::string const & optname = opt_iter->first;
554  std::string const & val = opt_iter->second;
555  parse_options_name_and_value(optname, val, job_options);
556  }
557 }
558 
559 
560 void
562  std::string const & optname,
563  std::string const & val,
564  JobOptionsOP job_options
565 )
566 {
567  using namespace basic::options;
568 
569  std::string full_key;
570  try{
571  full_key = option.find_key_cl(optname, "", true);
572  } catch (...) {
573  std::stringstream err_msg;
574  err_msg
575  << "Error: Option key '" << optname << "' not found. Please remember to use only one colon when giving options." << endl;
576  throw EXCN_Msg_Exception( err_msg.str() );
577  }
578 
579  if ( basic::options::OptionKeys::has( full_key ) ) {
580  OptionKey const & opt( basic::options::OptionKeys::key( full_key ));
581  if ( opt.scalar() ) {
582  // scalar options
583  if ( dynamic_cast< BooleanOptionKey const * > (&opt) ) {
584  BooleanOptionKey const & boolopt( static_cast< BooleanOptionKey const & > (opt) );
585  read_BooleanOption_subtag_for_job( boolopt, full_key, val, job_options );
586  } else if ( dynamic_cast< FileOptionKey const * > (&opt) ) {
587  FileOptionKey const & fileopt( static_cast< FileOptionKey const & > (opt) );
588  read_FileOption_subtag_for_job( fileopt, full_key, val, job_options );
589  } else if ( dynamic_cast< IntegerOptionKey const * > (&opt) ) {
590  IntegerOptionKey const & iopt( static_cast< IntegerOptionKey const & > (opt) );
591  read_IntegerOption_subtag_for_job( iopt, full_key, val, job_options );
592  } else if ( dynamic_cast< PathOptionKey const * > (&opt) ) {
593  PathOptionKey const & pathopt( static_cast< PathOptionKey const & > (opt) );
594  read_PathOption_subtag_for_job( pathopt, full_key, val, job_options );
595  } else if ( dynamic_cast< RealOptionKey const * > (&opt) ) {
596  RealOptionKey const & ropt( static_cast< RealOptionKey const & > (opt) );
597  read_RealOption_subtag_for_job( ropt, full_key, val, job_options );
598  } else if ( dynamic_cast< StringOptionKey const * > (&opt) ) {
599  StringOptionKey const & stopt( static_cast< StringOptionKey const & > (opt) );
600  read_StringOption_subtag_for_job( stopt, full_key, val, job_options );
601  }
602 
603  } else {
604  /// vector option
605  utility::vector1< std::string > vals = utility::string_split( val, ',' );
606  if ( dynamic_cast< BooleanVectorOptionKey const * > (&opt) ) {
607  BooleanVectorOptionKey const & boolvectopt( static_cast< BooleanVectorOptionKey const & > (opt) );
608  read_BooleanVectorOption_subtag_for_job( boolvectopt, full_key, val, vals, job_options );
609  } else if ( dynamic_cast< FileVectorOptionKey const * > (&opt) ) {
610  FileVectorOptionKey const & filevectopt( static_cast< FileVectorOptionKey const & > (opt) );
611  read_FileVectorOption_subtag_for_job( filevectopt, full_key, val, vals, job_options );
612  } else if ( dynamic_cast< IntegerVectorOptionKey const * > (&opt) ) {
613  IntegerVectorOptionKey const & ivectopt( static_cast< IntegerVectorOptionKey const & > (opt) );
614  read_IntegerVectorOption_subtag_for_job( ivectopt, full_key, val, vals, job_options );
615  } else if ( dynamic_cast< PathVectorOptionKey const * > (&opt) ) {
616  PathVectorOptionKey const & pathvectopt( static_cast< PathVectorOptionKey const & > (opt) );
617  read_PathVectorOption_subtag_for_job( pathvectopt, full_key, val, vals, job_options );
618  } else if ( dynamic_cast< RealVectorOptionKey const * > (&opt) ) {
619  RealVectorOptionKey const & rvectopt( static_cast< RealVectorOptionKey const & > (opt) );
620  read_RealVectorOption_subtag_for_job( rvectopt, full_key, val, vals, job_options );
621  } else if ( dynamic_cast< StringVectorOptionKey const * > (&opt) ) {
622  StringVectorOptionKey const & stvectopt( static_cast< StringVectorOptionKey const & > (opt) );
623  read_StringVectorOption_subtag_for_job( stvectopt, full_key, val, vals, job_options );
624  }
625  }
626  } else {
627  std::ostringstream err;
628  err << "Error: option '" << optname << "' corresponding to the full key '" << full_key << "' does not match any existing option in Rosetta.\n";
629  err << "Thrown from JD2ResourceManagerJobInputter::parse_job_tag\n";
630  throw EXCN_Msg_Exception( err.str() );
631  }
632 }
633 
634 void
636  basic::options::BooleanOptionKey const & boolopt,
637  std::string const & optname,
638  std::string const & val,
639  basic::resource_manager::JobOptionsOP job_options
640 )
641 {
642  bool boolval;
643  try {
644  boolval = boost::lexical_cast< bool >( val );
645  } catch ( boost::bad_lexical_cast const& ) {
646  std::ostringstream err;
647  err << "Error converting value '" << val << "' given for option '" << optname << "' to a boolean from within JD2ResourceManagerJobInputter::parse_job_tag\n Boolean options must be given either a '1' or a '0'";
648  throw EXCN_Msg_Exception( err.str() );
649  }
650  job_options->add_option( boolopt, boolval );
651 
652 }
653 
654 void
656  basic::options::FileOptionKey const & fileopt,
657  std::string const &,
658  std::string const & val,
659  basic::resource_manager::JobOptionsOP job_options
660 )
661 {
662  job_options->add_option( fileopt, val );
663 }
664 
665 
666 void
668  basic::options::IntegerOptionKey const & intopt,
669  std::string const & optname,
670  std::string const & val,
671  basic::resource_manager::JobOptionsOP job_options
672 )
673 {
674  int intval;
675  try {
676  intval = boost::lexical_cast< int >( val );
677  } catch ( boost::bad_lexical_cast const& ) {
678  std::ostringstream err;
679  err << "Error converting value '" << val << "' given for option '"
680  << optname << "' to an integer from within JD2ResourceManagerJobInputter::parse_job_tag\n";
681  throw EXCN_Msg_Exception( err.str() );
682  }
683  job_options->add_option( intopt, intval );
684 
685 }
686 
687 void
689  basic::options::PathOptionKey const & pathopt,
690  std::string const &,
691  std::string const & val,
692  basic::resource_manager::JobOptionsOP job_options
693 )
694 {
695  job_options->add_option( pathopt, val );
696 }
697 
698 
699 void
701  basic::options::RealOptionKey const & realopt,
702  std::string const & optname,
703  std::string const & val,
704  basic::resource_manager::JobOptionsOP job_options
705 )
706 {
707  core::Real realval;
708  try {
709  realval = boost::lexical_cast< core::Real >( val );
710  } catch ( boost::bad_lexical_cast const& ) {
711  std::ostringstream err;
712  err << "Error converting value '" << val << "' given for option '" << optname << "' to a floating point number from within JD2ResourceManagerJobInputter::parse_job_tag\n";
713  throw EXCN_Msg_Exception( err.str() );
714  }
715  job_options->add_option( realopt, realval );
716 }
717 
718 void
720  basic::options::StringOptionKey const & stringopt,
721  std::string const & ,
722  std::string const & val,
723  basic::resource_manager::JobOptionsOP job_options
724 )
725 {
726  job_options->add_option( stringopt, val );
727 }
728 
729 
730 void
732  basic::options::BooleanVectorOptionKey const & boolvectopt,
733  std::string const & optname,
734  std::string const & val,
735  utility::vector1< std::string > const & vals,
736  basic::resource_manager::JobOptionsOP job_options
737 )
738 {
739  utility::vector1< bool > boolvect( vals.size() );
740  for ( Size ii = 1; ii <= vals.size(); ++ii ) {
741  bool boolval;
742  try {
743  boolval = boost::lexical_cast< bool >( vals[ii] );
744  } catch ( boost::bad_lexical_cast const& ) {
745  std::ostringstream err;
746  err << "Error converting value '" << vals[ii] << "', option # " << ii
747  << ", given for the comma-separated vector option '"
748  << optname << "' to a boolean\nfrom within JD2ResourceManagerJobInputter::parse_job_tag\n"
749  << "Original value string: '" << val << "'\n"
750  << "Boolean options must be given either a '1' or a '0'\n";
751  throw EXCN_Msg_Exception( err.str() );
752  }
753  boolvect[ ii ] = boolval;
754  }
755  job_options->add_option( boolvectopt, boolvect );
756 }
757 
758 void
760  basic::options::FileVectorOptionKey const & filevectopt,
761  std::string const & ,
762  std::string const & ,
763  utility::vector1< std::string > const & vals,
764  basic::resource_manager::JobOptionsOP job_options
765 )
766 {
767  job_options->add_option( filevectopt, vals );
768 }
769 
770 void
772  basic::options::IntegerVectorOptionKey const & intvectopt,
773  std::string const & optname,
774  std::string const & val,
775  utility::vector1< std::string > const & vals,
776  basic::resource_manager::JobOptionsOP job_options
777 )
778 {
779  utility::vector1< int > intvect( vals.size() );
780  for ( Size ii = 1; ii <= vals.size(); ++ii ) {
781  bool intval;
782  try {
783  intval = boost::lexical_cast< int >( vals[ii] );
784  } catch ( boost::bad_lexical_cast const& ) {
785  std::ostringstream err;
786  err << "Error converting value '" << vals[ii] << "', option # " << ii
787  << ", given for the comma-separated vector option '"
788  << optname << "' to an integer\nfrom within JD2ResourceManagerJobInputter::parse_job_tag\n"
789  << "Original value string: '" << val << "'\n";
790  throw EXCN_Msg_Exception( err.str() );
791  }
792  intvect[ ii ] = intval;
793  }
794  job_options->add_option( intvectopt, intvect );
795 }
796 
797 void
799  basic::options::PathVectorOptionKey const & pathvectopt,
800  std::string const & ,
801  std::string const & ,
802  utility::vector1< std::string > const & vals,
803  basic::resource_manager::JobOptionsOP job_options
804 )
805 {
806  job_options->add_option( pathvectopt, vals );
807 }
808 
809 void
811  basic::options::RealVectorOptionKey const & realvectopt,
812  std::string const & optname,
813  std::string const & val,
814  utility::vector1< std::string > const & vals,
815  basic::resource_manager::JobOptionsOP job_options
816 )
817 {
818  utility::vector1< core::Real > realvect( vals.size() );
819  for ( Size ii = 1; ii <= vals.size(); ++ii ) {
820  core::Real realval;
821  try {
822  realval = boost::lexical_cast< core::Real >( vals[ii] );
823  } catch ( boost::bad_lexical_cast const& ) {
824  std::ostringstream err;
825  err << "Error converting value '" << vals[ii] << "', option # " << ii << ", given for the comma-separated vector option '"
826  << optname << "' to a boolean\nfrom within JD2ResourceManagerJobInputter::parse_job_tag\n"
827  << "Original value string: '" << val << "'\n";
828  throw EXCN_Msg_Exception( err.str() );
829  }
830  realvect[ ii ] = realval;
831  }
832  job_options->add_option( realvectopt, realvect );
833 }
834 
835 void
837  basic::options::StringVectorOptionKey const & strinvectopt,
838  std::string const & ,
839  std::string const & ,
840  utility::vector1< std::string > const & vals,
841  basic::resource_manager::JobOptionsOP job_options
842 )
843 {
844  job_options->add_option( strinvectopt, vals );
845 }
846 
847 
848 void
850  utility::tag::TagPtr options_tag,
851  std::map< std::string, std::string > & resources_for_job
852 ){
853  std::string rname;
854 
855  std::ostringstream err;
856  if(!options_tag->hasOption("resource_tag"))
857  {
858  err << "you must specify the resource_tag option when using a ResidueType tag";
859  err <<std::endl;
860  throw EXCN_Msg_Exception( err.str() );
861  }
862  for ( utility::tag::Tag::options_t::const_iterator
863  opt_iter = options_tag->getOptions().begin(),
864  opt_iter_end = options_tag->getOptions().end();
865  opt_iter != opt_iter_end; ++opt_iter ) {
866  if(opt_iter->first == "resource_tag")
867  {
868  rname = opt_iter->second;
869  resources_for_job["residue"] = rname;
870  }
871  }
872 
873 
874 }
875 
876 ///@details Read the <Data/> subtag of the <Job/>
877 ///
878 /// Form 1: <Data desc="resource_description" resource="resource_tag"/>
879 /// Precondition requirements:
880 /// has_resource_configuration(resource_tag)
881 /// Postcondition guarentees:
882 /// resources_for_job["resource_description"] == "resource_tag"
883 ///
884 void
886  utility::tag::TagPtr data_tag,
887  std::string const & jobname,
888  std::string & input_tag,
889  std::map< std::string, std::string > & resources_for_job
890 )
891 {
893 
894  bool desc_found( false );
895  bool resource_found( false );
896  bool pdb_found( false );
897  bool local_startstruct_found( false );
898  std::string desc;
899  std::string rname;
900  std::string locator = "";
901  for ( utility::tag::Tag::options_t::const_iterator
902  opt_iter = data_tag->getOptions().begin(),
903  opt_iter_end = data_tag->getOptions().end();
904  opt_iter != opt_iter_end; ++opt_iter ) {
905  if ( opt_iter->first == "desc" ) {
906  if ( opt_iter->second == "startstruct" ) {
907  local_startstruct_found = true;
908  }
909  desc_found = true;
910  desc = opt_iter->second;
911  } else if ( opt_iter->first == "resource_tag" ) {
912  resource_found = true;
913  rname = opt_iter->second;
914  } else if ( opt_iter->first == "pdb" ) {
915  pdb_found = true;
916  rname = opt_iter->second;
917  } else if (opt_iter->first == "locator")
918  {
919  locator = opt_iter->second;
920  }
921  }
922 
923  /// now let's make sure the provided data is consistent and complete
924  bool in_error = false;
925  std::ostringstream err;
926  if ( ! desc_found ) {
927  in_error = true;
928  err << "Failed to find a data description (desc) amongst the options pairs listed reading a 'Data' tag in a Job tag.\n A desc option must always be given.\n";
929  }
930  if ( rname.size() == 0 ) {
931  in_error = true;
932  err << "Failed to find a resource name or a pdb name reading a 'Data' tag in a Job tag. Either a 'resource_tag' or a 'pdb' option must be provided.\n";
933  }
934  if ( resource_found && pdb_found ) {
935  in_error = true;
936  err << "Error: Both a 'resource_tag' and a 'pdb' tag were found for a 'Data' tag in the Job tag." << std::endl;
937  } else if ( resource_found && ! jd2rm->has_resource_configuration( rname )) {
938  in_error = true;
939  err << "Error: In Data subtag with descr='" << desc << "', the ResourceManager has no resource configuration for ResourceTag '" << rname << "'.\n";
940  }
941  if ( ! local_startstruct_found && pdb_found ) {
942  in_error = true;
943  err << "Error: 'pdb' tag given for a non-'startstruct' option in the 'Data' tag of a Job tag." << std::endl;
944  }
945  if ( resources_for_job.find( desc ) != resources_for_job.end() ) {
946  in_error = true;
947  err << "Error: description '" << desc << "' appears twice";
948  err << ".\nFirst specified as '" << resources_for_job[ desc ] << "', and now as '" << rname << "'.";
949  err << "A 'desc' may only be given once\n";
950  }
951 
952  if ( in_error ) {
953  err << "Problem encountered ";
954  if ( jobname.size() != 0 ) {
955  err << "for job named '" << jobname << "'";
956  } else if ( desc != "startstruct" && resources_for_job.find("startstruct") != resources_for_job.end()) {
957  err << "for job whose starstruct is given as '" << resources_for_job[ "startstruct" ] << "'";
958  }
959  err << ".\nOptions given:\n";
960  for ( utility::tag::Tag::options_t::const_iterator
961  opt_iter = data_tag->getOptions().begin(),
962  opt_iter_end = data_tag->getOptions().end();
963  opt_iter != opt_iter_end; ++opt_iter ) {
964  err << "\t(" << opt_iter->first << ", " << opt_iter->second << ")\n";
965  }
966  err << "Thrown from protocols::jd2::JD2ResourceManagerJobInputter::parse_job_tag\n";
967  throw EXCN_Msg_Exception( err.str() );
968  }
969 
970  if ( local_startstruct_found && pdb_found ) {
971  /// add a pose to the ResourceManager with a canonical name, and then add that pose
972  /// as a resource for this job.
973  /// Then, when the
974  input_tag = rname;
975  std::string pdb_resource_name = "pdb_resource_" + rname;
976  if ( jd2rm->has_resource_configuration( pdb_resource_name ) ) {
977  // TODO: make sure the other resource has the right type
978  } else {
979  tr << "Adding implicit resource '" << pdb_resource_name << "' for job whose startstruct is given as pdb='" << rname << "'.";
980  basic::resource_manager::ResourceConfiguration rconfig;
981  rconfig.resource_tag = pdb_resource_name;
982  rconfig.locator_tag = locator; // <--- default
983  rconfig.locator_id = rname;
984  rconfig.loader_type = "PoseFromPDB";
985  rconfig.resource_options_tag = ""; // <-- default PoseFromPDB options
986  jd2rm->add_resource_configuration( pdb_resource_name, rconfig );
987  }
988  resources_for_job[ desc ] = pdb_resource_name;
989  } else {
990  /// put this resource name in a list for later telling the resource manager
991  /// that this job (whose name may not yet be resolved) requires a particular resource
992  resources_for_job[ desc ] = rname;
993  }
994 
995 }
996 
997 void
999  Jobs const & jobs
1000 ) const {
1001  JD2ResourceManager * jd2rm(
1003 
1004  for(
1005  Jobs::const_iterator job=jobs.begin(), jobs_end=jobs.end();
1006  job != jobs_end; ++job){
1007  if(!(jd2rm->has_resource_tag_by_job_tag("startstruct", (*job)->input_tag()))) {
1008  std::stringstream errmsg;
1009  errmsg
1010  << "Error: Job '" << (*job)->input_tag() << "' given without a 'startstruct'";
1011  throw EXCN_Msg_Exception( errmsg.str() );
1012  }
1013  }
1014 }
1015 
1018 {
1020 }
1021 
1022 
1023 } // namespace jd2
1024 } // namespace protocols
1025