Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JD2ResourceManager.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/JD2ResourceManager.cc
11 /// @brief The ResourceManager that is compatible with the JD2 JobDistributor
12 /// @author Andrew Leaver-Fay
13 /// @author Brian Weitzner
14 /// @author Matthew O'Meara
15 
16 //unit headers
19 #include <basic/resource_manager/types.hh>
20 #include <basic/resource_manager/FallbackConfiguration.hh>
21 #include <basic/resource_manager/FallbackConfigurationFactory.hh>
22 #include <basic/resource_manager/JobOptions.hh>
24 #include <protocols/jd2/Job.hh>
25 
26 // Project Headers
27 #include <basic/options/option.hh>
28 
29 // Numeric headers
30 #include <numeric/random/random.hh>
31 
32 // basic Headers
33 #include <basic/Tracer.hh>
34 #include <basic/resource_manager/types.hh>
35 #include <basic/resource_manager/ResourceLoader.hh>
36 #include <basic/resource_manager/ResourceLoaderFactory.hh>
37 #include <basic/resource_manager/ResourceLocator.hh>
38 #include <basic/resource_manager/ResourceLocatorFactory.hh>
39 #include <basic/resource_manager/ResourceOptions.hh>
40 #include <basic/resource_manager/ResourceOptionsFactory.hh>
41 #include <basic/database/sql_utils.hh>
42 
43 // Utility headers
44 #include <utility/vector1.hh>
45 #include <utility/exit.hh>
46 #include <utility/tag/Tag.hh>
47 #include <utility/excn/Exceptions.hh>
48 #include <utility/string_util.hh>
49 #include <utility/sql_database/DatabaseSessionManager.hh>
50 
51 // Boost Headers
52 #include <boost/foreach.hpp>
53 #define foreach BOOST_FOREACH
54 
55 // External Headers
56 #include <cppdb/frontend.h>
57 
58 //C++ headers
59 #include <string>
60 #include <sstream>
61 
62 namespace protocols {
63 namespace jd2 {
64 
65 using std::endl;
66 using std::stringstream;
67 using std::string;
68 using platform::Size;
69 using basic::Tracer;
70 using basic::resource_manager::ResourceManager;
71 using basic::resource_manager::ResourceDescription;
72 using basic::resource_manager::ResourceOP;
73 using basic::resource_manager::JobOptionsOP;
74 using utility::excn::EXCN_Msg_Exception;
75 using basic::resource_manager::LoaderType;
76 using basic::resource_manager::LocatorTag;
77 using basic::resource_manager::LocatorID;
78 using basic::resource_manager::ResourceConfiguration;
79 using basic::resource_manager::ResourceOptionsTag;
80 using basic::resource_manager::ResourceLoaderFactory;
81 using basic::resource_manager::ResourceTag;
82 using utility::tag::Tag;
84 
85 static Tracer TR("protocols.resource_manager.planner.JD2ResourceManager");
86 
88 
89 ResourceManager *
91 {
92  return new JD2ResourceManager;
93 }
94 
95 
96 string
98 {
99  return "JD2ResourceManager";
100 }
101 
102 void
104 {
105  basic::resource_manager::LazyResourceManager::clear();
106 }
107 
108 
110 }
111 
113 
114 /// @details instantiate all the resource locators given in the input tags, and
115 /// put them into the base class. Make sure no two resource locators share a common
116 /// name.
118 {
119  using basic::resource_manager::ResourceLocatorFactory;
120  using basic::resource_manager::ResourceLocatorOP;
121  using basic::resource_manager::LocatorTag;
122  using utility::tag::Tag;
123  typedef utility::excn::EXCN_Msg_Exception MsgException;
124 
125  for ( Tag::tags_t::const_iterator
126  tag_iter = tags->getTags().begin(),
127  tag_iter_end = tags->getTags().end();
128  tag_iter != tag_iter_end; ++tag_iter ) {
129  std::string const & locator_type = (*tag_iter)->getName();
130 
131  /// 1. Make sure the resource locator has been given a tag.
132  if ( ! (*tag_iter)->hasOption( "tag" ) ) {
133  std::ostringstream err;
134  err << "Unable to find a 'tag' for a ResourceLocator of type '" << locator_type << "'\n";
135  throw MsgException( err.str() );
136  }
137  LocatorTag locator_tag = (*tag_iter)->getOption< LocatorTag >( "tag" );
138 
139  // 2. Make sure no other resource locator object has been declared with this name
140  if ( LazyResourceManager::has_resource_locator( locator_tag ) ) {
141  std::ostringstream err;
142  err << "Duplicated tag, '" << locator_tag <<"' assigned to a ResourceLocator object with type '";
143  err << locator_type << "'.\n";
144  err << "Prevous ResourceLocator object with this tag was of type '";
145  err << LazyResourceManager::find_resource_locator( locator_tag )->type() << "'\n";
146  throw MsgException( err.str() );
147  }
148 
149  /// 3. Try to create this ResourceLocator object; the factory may throw. Catch any thrown MsgException and
150  /// append to its message the locator_type and locator_tag for the ResourceLocator being read.
151  ResourceLocatorOP resource_locator;
152  try {
153  resource_locator = ResourceLocatorFactory::get_instance()->create_resource_locator( locator_type, locator_tag, *tag_iter );
154  } catch ( MsgException const & e ) {
155  std::ostringstream err;
156  err << e.msg() << "\n";
157  err << "Exception thrown while trying to initialize a ResourceLocator of type '";
158  err << locator_type << "' with a tag of '" << locator_tag << "'\n";
159  err << "from JD2ResourceManager::read_resource_locators_tags\n";
160  throw MsgException( err.str() );
161  }
162  LazyResourceManager::add_resource_locator( locator_tag, resource_locator );
163  }
164 
165 }
166 
167 /// @details instantiate all the resource options and put them in the base class.
168 /// Make sure no two resource options are given the same name.
170 {
171  using utility::tag::Tag;
172  typedef utility::excn::EXCN_Msg_Exception MsgException;
173 
174  for ( Tag::tags_t::const_iterator
175  tag_iter = tags->getTags().begin(),
176  tag_iter_end = tags->getTags().end();
177  tag_iter != tag_iter_end; ++tag_iter ) {
178  std::string const & tagname = (*tag_iter)->getName();
179 
180  if(tagname == "OptionsTable") {
182  continue;
183  } else {
184  read_resource_option_item(*tag_iter);
185  }
186  }
187 }
188 
189 void
191  TagPtr tag
192 ) {
193  using namespace basic::database;
194 
195  utility::sql_database::sessionOP db_session = parse_database_connection(tag);
196 
197  string sql_command;
198  if(tag->hasOption("sql_command")){
199  sql_command = tag->getOption<string>("sql_command");
200  check_statement_sanity(sql_command);
201  } else {
202  stringstream err_msg;
203  err_msg
204  << "The OptionsTable Table tag requires a 'sql_command' tag that "
205  << "is an SQL SELECT statement that returns the following column formats" << endl
206  << "ordered by <job_name>:" << endl
207  << "\t(<resource_options_tag>, <resource_options_type>, <resource_option_key>, resource_option_value>)" << endl;
208  throw utility::excn::EXCN_Msg_Exception(err_msg.str());
209  }
210 
211  cppdb::statement select_stmt(safely_prepare_statement(sql_command, db_session));
212  cppdb::result res(safely_read_from_database(select_stmt));
213 
214  std::string table_schema =
215  "Each row of the resource options table should have the following format\n"
216  "\n"
217  " resource_options_tag, resource_options_type, resource_option_key, resource_option_value\n"
218  "\n"
219  " * The table should 'ORDER BY job_name', to have data for a\n"
220  " specific job adjacent in the table\n"
221  "\n"
222  " * resource_option_{key, value}: Each resource options takes set of key value pairs (string -> string)\n"
223  " for example, for PoseFromPDBOptions, has the key 'exit_if_missing_heavy_atoms' and takes '1' for true or '0' for false.\n";
224 
225  if(res.cols() != 4){
226  stringstream err_msg;
227  err_msg
228  << "The OptionsTable tag requires a 'sql_command' tag" << endl
229  << table_schema << endl
230  << "Instead, the query returned " << res.cols() << ":" << endl
231  << "SQL query:" << endl
232  << sql_command << endl;
233  throw utility::excn::EXCN_Msg_Exception(err_msg.str());
234  }
235 
236  Size row_number(0);
237  std::map< string, TagPtr > tags;
238  while(res.next()){
239  row_number++;
240 
241  string tag, type, key, value;
242  res >> tag >> type >> key >> value;
243 
244  std::map< string, TagPtr >::iterator t(tags.find(tag));
245  if(t == tags.end()){
246  TagPtr newtag = new Tag();
247  newtag->setOption("tag", tag);
248  newtag->setName(type);
249  if(!key.empty()){
250  newtag->setOption(key, value);
251  }
252  tags[tag] = newtag;
253  } else {
254  t->second->setOption(key, value);
255  }
256  }
257 
258  if(row_number == 0){
259  TR.Warning << "JobsTable returned no rows." << endl;
260  }
261 
262  for(
263  std::map<string, TagPtr>::const_iterator t=tags.begin(), te=tags.end();
264  t != te; ++t){
265  read_resource_option_item(t->second);
266  }
267 }
268 
269 
270 void
272  TagPtr tag
273 ) {
274  using basic::resource_manager::ResourceOptionsFactory;
275  using basic::resource_manager::ResourceOptionsOP;
276  using basic::resource_manager::ResourceOptionsTag;
277  typedef utility::excn::EXCN_Msg_Exception MsgException;
278 
279  std::string const & tagname = tag->getName();
280 
281  /// 1. Make sure this resource_options object has been declared.
282  if ( ! tag->hasOption( "tag" ) ) {
283  std::ostringstream err;
284  err << "Unable to find a 'tag' for a ResourceOption of type '" << tagname << "'\n";
285  throw MsgException( err.str() );
286  }
287  ResourceOptionsTag options_tag = tag->getOption< ResourceOptionsTag >( "tag" );
288 
289  // 2. Make sure no other resource_options object has been declared with this name
290  if ( LazyResourceManager::has_resource_options( options_tag ) ) {
291  std::ostringstream err;
292  err << "Duplicated tag, '" << options_tag <<"' assigned to a ResourceOptions object with type '";
293  err << tagname << "'.\n";
294  err << "Prevous ResourceOptions object with this tag was of type '";
295  err << LazyResourceManager::find_resource_options( options_tag )->type() << "'\n";
296  throw MsgException( err.str() );
297  }
298 
299  /// 3. Try to create this ResourceOptions object; the factory may throw. Catch any thrown MsgException and
300  /// append to its message the tagname and options_tag for the ResourceOptions being read.
301  ResourceOptionsOP resource_options;
302  try {
303  resource_options = ResourceOptionsFactory::get_instance()->create_resource_options( tagname, tag );
304  } catch ( MsgException const & e ) {
305  std::ostringstream err;
306  err << e.msg() << "\n";
307  err << "Exception thrown while trying to initialize a ResourceOption of type '";
308  err << tagname << "' with a tag of '" << options_tag << "'\n";
309  err << "from JD2ResourceManager::read_resource_options_tags\n";
310  throw MsgException( err.str() );
311  }
312  LazyResourceManager::add_resource_options( options_tag, resource_options );
313 }
314 
315 
316 
317 ///@detail Check if the loader type is defined with the ResourceLoaderFactory
318 void
320  LoaderType const & loader_type
321 ) {
322  typedef utility::excn::EXCN_Msg_Exception MsgException;
323 
324  /// 1. Make sure this is an allowed resource type / loader type
325  if ( ! ResourceLoaderFactory::get_instance()->has_resource_loader( loader_type ) ) {
326  std::ostringstream err;
327  err << "ResourceLoader type '" << loader_type << "' requested in JD2ResourceManager::read_resources_tags has not been registered with the ResourceLoaderFactory. Available types include:.\n";
328  std::list< std::string > loader_types = ResourceLoaderFactory::get_instance()->available_resource_loaders();
329  for ( std::list< std::string >::const_iterator
330  iter = loader_types.begin(), iter_end = loader_types.end(); iter != iter_end; ++iter ) {
331  err << " '" << *iter << std::endl;
332  }
333  throw MsgException( err.str() );
334  }
335 }
336 
337 ///@details make sure the resource object has been given a tag and
338 ///that no other resource object has been delecared with the same name.
339 ResourceTag
341  TagPtr tag,
342  LoaderType const & loader_type,
343  LocatorID const & locator_id
344 ) {
345  typedef utility::excn::EXCN_Msg_Exception MsgException;
346 
347  /// 2. Set the resource tag to be the locator id unless it has been
348  /// explcitely provided.
349  ResourceTag resource_tag;
350  if ( ! tag->hasOption( "tag" ) ) {
351  resource_tag = locator_id;
352  } else {
353  resource_tag = tag->getOption< ResourceTag >( "tag" );
354  }
355 
356  // 3. Make sure no other resource object has been declared with this name
357  if ( LazyResourceManager::has_resource_configuration( resource_tag ) ) {
358  std::ostringstream err;
359  err << "Duplicated tag, '" << resource_tag << "' assigned to a Resource object with ResourceLoader type '";
360  err << loader_type << "'.\n";
361  throw MsgException( err.str() );
362  }
363  return resource_tag;
364 }
365 
366 ///@brief find the LocatorTag item from the resource tag. Based on the
367 ///LocatorTag fill the LocatorID.
368 /// locator item (&string):
369 /// FileSystemResourceLocator (default)
370 /// - file item is interchangable with the locatorID item
371 /// locatorID item (&string):
372 LocatorTag
374  TagPtr tag,
375  LoaderType const & loader_type,
376  LocatorID & locator_id
377 ) {
378  typedef utility::excn::EXCN_Msg_Exception MsgException;
379 
380  /// 4. Verify that, if it's been given a locator, that the ResourceLocator has previously been declared
381  LocatorTag locator_tag;
382  if ( tag->hasOption( "locator" ) ) {
383  locator_tag = tag->getOption< LocatorTag >( "locator" );
384  if ( ! LazyResourceManager::has_resource_locator( locator_tag ) ) {
385  std::ostringstream err;
386  err
387  << "Resource subtag"
388  << " with LoaderType '" << loader_type << "'"
389  << " was given the ResourceLocator tag '" << locator_tag << "',"
390  << " which has not previously been declared.";
391  throw MsgException( err.str() );
392  }
393  if( tag->hasOption( "file" ) && locator_tag != "FileSystemResourceLocator" ){
394  std::ostringstream err;
395  err
396  << "Resource subtag "
397  << "with LoaderType '" << loader_type << "'"
398  << " has locator='" << locator_tag << "' and "
399  << " file='" << tag->getOption< LocatorID > ("file") << "'."
400  << " But specifying a file is only compatible with the"
401  << " FileSystemResourceLocator." << std::endl;
402  throw MsgException(err.str());
403  }
404  if( locator_tag == "NULL" ){
405  locator_id = "";
406  return locator_tag;
407  }
408  } else {
409  locator_tag = "";
410  }
411 
412  if(tag->hasOption( "file" )){
413  if(tag->hasOption("locatorID")) {
414  std::ostringstream err;
415  err
416  << "Resource subtag"
417  << " with LoaderType '" << loader_type << "'"
418  << " has both"
419  << " file='" << tag->getOption< LocatorID >("file") << "' and"
420  << " locatorID='" << tag->getOption< LocatorID >("locatorID") << "'"
421  << " but it is only allowed to have one." << std::endl;
422  throw MsgException(err.str());
423  }
424  locator_id = tag->getOption< LocatorID >("file");
425  } else if( tag->hasOption("locatorID")){
426  locator_id = tag->getOption< LocatorID >( "locatorID" );
427  } else {
428  std::ostringstream err;
429  err
430  << "Resource subtag"
431  << " with LoaderType '" << loader_type << "' was not supplied"
432  << " with a locatorID tag, which is required." << std::endl;
433  throw MsgException( err.str() );
434  }
435 
436  return locator_tag;
437 }
438 
439 
440 ResourceOptionsTag
442  TagPtr tag,
443  LoaderType const & loader_type,
444  ResourceTag const & resource_tag
445 ) {
446  typedef utility::excn::EXCN_Msg_Exception MsgException;
447 
448  /// 5. Verify that, if it's been given a resource options, that the
449  /// ResourceOptions has been previously declared
450  ResourceOptionsTag resource_options_tag;
451  if ( tag->hasOption( "options" ) ) {
452  resource_options_tag = tag->getOption< ResourceOptionsTag >( "options" );
453  if ( ! LazyResourceManager::has_resource_options( resource_options_tag ) ) {
454  std::ostringstream err;
455  err << "Resource '" << resource_tag << "' with LoaderType '" << loader_type << "' was given the tag ";
456  err << "for a ResourceLoaderOptions, '" << resource_options_tag << "', which has not previously been declared.";
457  throw MsgException( err.str() );
458  }
459  }
460  return resource_options_tag;
461 }
462 
463 /// @details read through all the resources, and put them into the base class
464 /// for later instantiation. Make sure each resource is named, that it is the
465 /// only resource that has been declared with this name, and that
467 {
468 
469  for ( Tag::tags_t::const_iterator
470  tag_iter = tags->getTags().begin(),
471  tag_iter_end = tags->getTags().end();
472  tag_iter != tag_iter_end; ++tag_iter ) {
473 
474  LoaderType loader_type((*tag_iter)->getName());
475  if( loader_type == "ResourceTable" ){
476  read_resource_table_tag(*tag_iter);
477  continue;
478  }
479 
480  check_resource_loader_type(loader_type);
481 
482  LocatorID locator_id;
483  LocatorTag locator_tag(
485  *tag_iter, loader_type, locator_id));
486 
487  ResourceTag resource_tag(
488  read_resource_tag_item(*tag_iter, loader_type, locator_id));
489 
490 
491  ResourceOptionsTag resource_options_tag(
492  read_resource_options_tag_item(*tag_iter, loader_type, resource_tag));
493 
494  ResourceConfiguration resource_configuration;
495  resource_configuration.loader_type = loader_type;
496  resource_configuration.resource_tag = resource_tag;
497  resource_configuration.locator_tag = locator_tag;
498  resource_configuration.locator_id = locator_id;
499  resource_configuration.resource_options_tag = resource_options_tag;
500 
501  LazyResourceManager::add_resource_configuration(
502  resource_tag, resource_configuration );
503  }
504 
505 }
506 
507 void
509  TagPtr tag
510 ) {
511  using namespace basic::database;
512 
513  utility::sql_database::sessionOP db_session = parse_database_connection(tag);
514 
515  std::string sql_command;
516  if(tag->hasOption("sql_command")){
517  sql_command = tag->getOption<string>("sql_command");
518  check_statement_sanity(sql_command);
519  } else {
520  stringstream err_msg;
521  err_msg
522  << "The ResourceTable tag requires a 'sql_command' tag that "
523  << "is an SQL SELECT statement that returns the following columns:" << endl
524  << "\tresource_tag" << endl
525  << "\tlocator_tag" << endl
526  << "\tlocator_id" << endl
527  << "\tloader_type" << endl
528  << "\toptions_tag" << endl;
529  throw utility::excn::EXCN_Msg_Exception(err_msg.str());
530  }
531 
532  cppdb::statement select_stmt(safely_prepare_statement(sql_command, db_session));
533  cppdb::result res(safely_read_from_database(select_stmt));
534 
535  if(res.cols() != 5){
536  stringstream err_msg;
537  err_msg
538  << "The ResourceTable tag requires a 'sql_command' tag that "
539  << "is an SQL SELECT statement that returns the following columns:" << endl
540  << "\tresource_tag" << endl
541  << "\tlocator_tag" << endl
542  << "\tlocator_id" << endl
543  << "\tloader_type" << endl
544  << "\tresource_options_tag" << endl
545  << "Instead, the query returned " << res.cols() << ":" << endl
546  << sql_command << endl;
547  throw utility::excn::EXCN_Msg_Exception(err_msg.str());
548  }
549 
550  Size row_number(0);
551  while(res.next()){
552  row_number++;
553 
554  ResourceTag resource_tag;
555  LocatorTag locator_tag;
556  LocatorID locator_id;
557  LoaderType loader_type;
558  ResourceOptionsTag resource_options_tag;
559  res >> resource_tag;
560  res >> locator_tag;
561  res >> locator_id;
562  res >> loader_type;
563  res >> resource_options_tag;
564 
565  if(!LazyResourceManager::has_resource_locator(locator_tag)){
566  std::stringstream err;
567  err
568  << "Row " << row_number << " in the ResourceTable "
569  << "has an unrecognized locator_tag: '" << locator_tag << "' " << endl
570  << "locator_tag, locator_id, loader_type, resource_options_tag" << endl
571  << "'" << locator_tag << ", '" << locator_id << "', '" << loader_type << "', '" << resource_options_tag << "'" << endl
572  << "SQL comand: " << endl
573  << sql_command;
574  throw utility::excn::EXCN_Msg_Exception( err.str() );
575  }
576 
577  check_resource_loader_type(loader_type);
578 
579  if(!resource_options_tag.empty() && !LazyResourceManager::has_resource_options(resource_options_tag)){
580  std::stringstream err;
581  err
582  << "Row " << row_number << "in the ResourceTable "
583  << "has an unrecognized resource_options_tag: '" << resource_options_tag << "' " << endl
584  << "locator_tag\tlocator_id\tloader_type\tresource_options_tag" << endl
585  << locator_tag << "\t" << locator_id << "\t" << loader_type << "\t" << resource_options_tag << endl
586  << "SQL comand: " << endl
587  << sql_command;
588  throw utility::excn::EXCN_Msg_Exception( err.str() );
589  }
590 
591  ResourceConfiguration resource_configuration;
592  resource_configuration.loader_type = loader_type;
593  resource_configuration.resource_tag = resource_tag;
594  resource_configuration.locator_tag = locator_tag;
595  resource_configuration.locator_id = locator_id;
596  resource_configuration.resource_options_tag = resource_options_tag;
597 
598  LazyResourceManager::add_resource_configuration(
599  resource_tag, resource_configuration );
600  }
601 
602  if(row_number == 0){
603  TR.Warning << "ResourceTable returned no rows." << endl;
604  }
605 
606 }
607 
610 ){
611  JD2ResourceManager * jd2_resource_manager(
612  dynamic_cast< JD2ResourceManager * > ( ResourceManager::get_instance() ));
613  if ( ! jd2_resource_manager ) {
614  std::ostringstream err;
615  err
616  << "Error trying to access the JD2ResourceManager "
617  << "from the JD2ResourceManagerJobInputer";
618  EXCN_Msg_Exception( err.str() );
619  }
620  return jd2_resource_manager;
621 }
622 
623 bool
625  ResourceDescription const & resource_description
626 ) {
627  using basic::resource_manager::FallbackConfigurationFactory;
628  using basic::resource_manager::FallbackConfigurationOP;
629  using basic::resource_manager::ResourceTag;
630 
631  if ( has_resource_tag_by_job_tag(
632  resource_description,
633  JobDistributor::get_instance()->current_job()->input_tag()) ) {
634  return true;
635  }
636 
637  /// check, have we already created a fallback resource description?
638  if ( fallback_resource_descriptions_created_.find( resource_description )
640  return true;
641  }
642 
643  if ( FallbackConfigurationFactory::get_instance()->has_fallback_for_resource( resource_description )) {
644  FallbackConfigurationOP fallback = FallbackConfigurationFactory::get_instance()->create_fallback_configuration( resource_description );
645  return fallback->fallback_specified( resource_description );
646  }
647  return false;
648 }
649 
650 ResourceOP
652  ResourceDescription const & resource_description
653 ) {
654  std::string const & jobtag = JobDistributor::get_instance()->current_job()->input_tag();
655 
656  if ( has_resource_tag_by_job_tag( resource_description, jobtag ) ) {
657  return get_resource_by_job_tag( resource_description, jobtag);
658  }
659 
660  std::map< std::string, std::string >::const_iterator fallbackname_iterator
661  = fallback_resource_descriptions_created_.find( resource_description );
662 
663  if ( fallbackname_iterator != fallback_resource_descriptions_created_.end() ) {
664  return find_resource( fallbackname_iterator->second );
665  } else {
666  using basic::resource_manager::FallbackConfigurationFactory;
667  using basic::resource_manager::FallbackConfigurationOP;
668 
669  if ( FallbackConfigurationFactory::get_instance()->has_fallback_for_resource( resource_description )) {
670  FallbackConfigurationOP fallback = FallbackConfigurationFactory::get_instance()->create_fallback_configuration( resource_description );
671  if ( fallback->fallback_specified( resource_description ) ) {
672  ResourceOP fallbackresource = create_resource_from_fallback( fallback, resource_description );
673  // now make sure that the resource is saved for later; create a pheax uuid for this
674  std::string fallbackname = "fallback_" + resource_description;
675  for ( core::Size ii = 1; ii <= 10000; ++ii ) {
676  if ( ! has_resource_configuration( fallbackname )) break;
677  fallbackname = "fallback_" + resource_description + "_" + utility::to_string( numeric::random::random_range(1,4000000) );
678  }
679  if ( has_resource_configuration( fallbackname ) ) {
680  throw utility::excn::EXCN_Msg_Exception( "Could not name the fallback resource after 10000 attempts. Try not to name your resources"
681  " beginning with the prefix 'fallback_'." );
682  }
683  basic::resource_manager::ResourceConfiguration fake_configuration;
684  fake_configuration.resource_tag = fallbackname;
685  add_resource_configuration( fallbackname, fake_configuration );
686  fallback_resource_descriptions_created_[ resource_description ] = fallbackname;
687  add_resource( fallbackname, fallbackresource );
688  return fallbackresource;
689  }
690  }
691 
692  std::ostringstream errmsg;
693  errmsg << "JD2ResourceManager does not have a resource "
694  "corresponding to the resource description '" + resource_description + "'. for job '" +
695  jobtag + "'.\n";
696  errmsg << "Resources may be specified on the command line or through the JD2ResourceManagerJobInputter resource-declaration file.\n";
697 
698  if ( FallbackConfigurationFactory::get_instance()->has_fallback_for_resource( resource_description ) ) {
699  // i.e. this is a valid resource description, but the command line options required for this resource description
700  // were not provided.
701  errmsg << "The FallbackConfiguration for this resource description gives this error:\n";
702  FallbackConfigurationOP fallback = FallbackConfigurationFactory::get_instance()->create_fallback_configuration( resource_description );
703  errmsg << fallback->could_not_create_resource_error_message( resource_description ) << "\n";
704  } else {
705  errmsg << "This resource description does not have a FallbackConfiguration defined.\n";
706  }
707 
708  errmsg << "Thrown from JD2ResourceManager::get_resource\n";
709  throw utility::excn::EXCN_Msg_Exception( errmsg.str() );
710  }
711  return 0; // appease compiler
712 }
713 
714 bool
716  utility::options::BooleanOptionKey key
717 ) const {
718  Job const & currjob( * JobDistributor::get_instance()->current_job() );
719  if ( has_job_options( currjob.input_tag() ) ) {
720  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
721  if(job_option->has_option(key)){
722  return job_option->get_option(key);
723  }
724  }
725  return basic::options::option[ key ]();
726 }
727 
730  utility::options::BooleanVectorOptionKey key
731 ) const {
732  Job const & currjob( * JobDistributor::get_instance()->current_job() );
733  if ( has_job_options( currjob.input_tag() ) ) {
734  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
735  if(job_option->has_option(key)){
736  return job_option->get_option(key);
737  }
738  }
739  return basic::options::option[ key ]();
740 }
741 
744  utility::options::FileOptionKey key
745 ) const {
746  Job const & currjob( * JobDistributor::get_instance()->current_job() );
747  if ( has_job_options( currjob.input_tag() ) ) {
748  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
749  if(job_option->has_option(key)){
750  return job_option->get_option(key);
751  }
752  }
753  return basic::options::option[ key ]();
754 }
755 
758  utility::options::FileVectorOptionKey key
759 ) const {
760  Job const & currjob( * JobDistributor::get_instance()->current_job() );
761  if ( has_job_options( currjob.input_tag() ) ) {
762  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
763  if(job_option->has_option(key)){
764  return job_option->get_option(key);
765  }
766  }
767  return basic::options::option[ key ]();
768 }
769 
770 int
772  utility::options::IntegerOptionKey key
773 ) const {
774  Job const & currjob( * JobDistributor::get_instance()->current_job() );
775  if ( has_job_options( currjob.input_tag() ) ) {
776  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
777  if(job_option->has_option(key)){
778  return job_option->get_option(key);
779  }
780  }
781  return basic::options::option[ key ]();
782 }
783 
786  utility::options::IntegerVectorOptionKey key
787 ) const {
788  Job const & currjob( * JobDistributor::get_instance()->current_job() );
789  if ( has_job_options( currjob.input_tag() ) ) {
790  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
791  if(job_option->has_option(key)){
792  return job_option->get_option(key);
793  }
794  }
795  return basic::options::option[ key ]();
796 }
797 
798 utility::file::PathName const &
800  utility::options::PathOptionKey key
801 ) const {
802  Job const & currjob( * JobDistributor::get_instance()->current_job() );
803  if ( has_job_options( currjob.input_tag() ) ) {
804  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
805  if(job_option->has_option(key)){
806  return job_option->get_option(key);
807  }
808  }
809  return basic::options::option[ key ]();
810 }
811 
814  utility::options::PathVectorOptionKey key
815 ) const {
816  Job const & currjob( * JobDistributor::get_instance()->current_job() );
817  if ( has_job_options( currjob.input_tag() ) ) {
818  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
819  if(job_option->has_option(key)){
820  return job_option->get_option(key);
821  }
822  }
823  return basic::options::option[ key ]();
824 }
825 
828  utility::options::RealOptionKey key
829 ) const {
830  Job const & currjob( * JobDistributor::get_instance()->current_job() );
831  if ( has_job_options( currjob.input_tag() ) ) {
832  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
833  if(job_option->has_option(key)){
834  return job_option->get_option(key);
835  }
836  }
837  return basic::options::option[ key ]();
838 }
839 
842  utility::options::RealVectorOptionKey key
843 ) const {
844  Job const & currjob( * JobDistributor::get_instance()->current_job() );
845  if ( has_job_options( currjob.input_tag() ) ) {
846  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
847  if(job_option->has_option(key)){
848  return job_option->get_option(key);
849  }
850  }
851  return basic::options::option[ key ]();
852 }
853 
854 std::string const &
856  utility::options::StringOptionKey key
857 ) const {
858  Job const & currjob( * JobDistributor::get_instance()->current_job() );
859  if ( has_job_options( currjob.input_tag() ) ) {
860  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
861  if(job_option->has_option(key)){
862  return job_option->get_option(key);
863  }
864  }
865  return basic::options::option[ key ]();
866 }
867 
870  utility::options::StringVectorOptionKey key
871 ) const {
872  Job const & currjob( * JobDistributor::get_instance()->current_job() );
873  if ( has_job_options( currjob.input_tag() ) ) {
874  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
875  if(job_option->has_option(key)){
876  return job_option->get_option(key);
877  }
878  }
879  return basic::options::option[ key ]();
880 }
881 
882 bool
884  utility::options::BooleanOptionKey key
885 ) const {
886 
887  if ( ! has_job_options( JobDistributor::get_instance()->current_job()->input_tag() )) return false;
888  JobOptionsOP job_option(
889  get_job_options(
890  JobDistributor::get_instance()->current_job()->input_tag()));
891  return job_option->has_option(key);
892 }
893 
894 bool
896  utility::options::BooleanVectorOptionKey key
897 ) const {
898  Job const & currjob( * JobDistributor::get_instance()->current_job() );
899  if ( ! has_job_options( currjob.input_tag() ) ) { return false; }
900  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
901  return job_option->has_option(key);
902 }
903 
904 bool
906  utility::options::FileOptionKey key
907 ) const {
908  Job const & currjob( * JobDistributor::get_instance()->current_job() );
909  if ( ! has_job_options( currjob.input_tag() ) ) { return false; }
910  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
911  return job_option->has_option(key);
912 }
913 
914 bool
916  utility::options::FileVectorOptionKey key
917 ) const {
918  Job const & currjob( * JobDistributor::get_instance()->current_job() );
919  if ( ! has_job_options( currjob.input_tag() ) ) { return false; }
920  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
921  return job_option->has_option(key);
922 }
923 
924 bool
926  utility::options::IntegerOptionKey key
927 ) const {
928  Job const & currjob( * JobDistributor::get_instance()->current_job() );
929  if ( ! has_job_options( currjob.input_tag() ) ) { return false; }
930  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
931  return job_option->has_option(key);
932 }
933 
934 bool
936  utility::options::IntegerVectorOptionKey key
937 ) const {
938  Job const & currjob( * JobDistributor::get_instance()->current_job() );
939  if ( ! has_job_options( currjob.input_tag() ) ) { return false; }
940  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
941  return job_option->has_option(key);
942 }
943 
944 bool
946  utility::options::PathOptionKey key
947 ) const {
948  Job const & currjob( * JobDistributor::get_instance()->current_job() );
949  if ( ! has_job_options( currjob.input_tag() ) ) { return false; }
950  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
951  return job_option->has_option(key);
952 }
953 
954 bool
956  utility::options::PathVectorOptionKey key
957 ) const {
958  Job const & currjob( * JobDistributor::get_instance()->current_job() );
959  if ( ! has_job_options( currjob.input_tag() ) ) { return false; }
960  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
961  return job_option->has_option(key);
962 }
963 
964 bool
966  utility::options::RealOptionKey key
967 ) const {
968  Job const & currjob( * JobDistributor::get_instance()->current_job() );
969  if ( ! has_job_options( currjob.input_tag() ) ) { return false; }
970  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
971  return job_option->has_option(key);
972 }
973 
974 bool
976  utility::options::RealVectorOptionKey key
977 ) const {
978  Job const & currjob( * JobDistributor::get_instance()->current_job() );
979  if ( ! has_job_options( currjob.input_tag() ) ) { return false; }
980  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
981  return job_option->has_option(key);
982 }
983 
984 bool
986  utility::options::StringOptionKey key
987 ) const {
988  Job const & currjob( * JobDistributor::get_instance()->current_job() );
989  if ( ! has_job_options( currjob.input_tag() ) ) { return false; }
990  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
991  return job_option->has_option(key);
992 }
993 
994 bool
996  utility::options::StringVectorOptionKey key
997 ) const {
998  Job const & currjob( * JobDistributor::get_instance()->current_job() );
999  if ( ! has_job_options( currjob.input_tag() ) ) { return false; }
1000  JobOptionsOP job_option( get_job_options( currjob.input_tag() ));
1001  return job_option->has_option(key);
1002 }
1003 
1004 basic::resource_manager::ResourceOP
1006  basic::resource_manager::FallbackConfigurationCOP fallback,
1007  ResourceDescription const & resource_description
1008 )
1009 {
1010  using namespace basic::resource_manager;
1011 
1012  /// APL: Fix this. For now, always use the FileSystemResourceLocator
1013  ResourceLocatorOP locator(find_resource_locator(""));
1014 
1015  ResourceStreamOP stream( locator->locate_resource_stream(
1016  fallback->get_locator_id(resource_description) ));
1017 
1018  ResourceLoaderOP loader(
1019  ResourceLoaderFactory::get_instance()->create_resource_loader(
1020  fallback->get_resource_loader( resource_description )));
1021 
1022  ResourceOptionsOP resource_options = fallback->get_resource_options( resource_description );
1023  if ( resource_options == 0 ) {
1024  resource_options = loader->default_options();
1025  }
1026 
1027  return loader->create_resource( *resource_options, fallback->get_locator_id( resource_description ), stream->stream());
1028 }
1029 
1030 } // namespace
1031 } // namespace