Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
init.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 core/init.cc
12 /// @brief options system initialization routines
13 /// @author Sergey Lyskov
14 ///
15 
16 #ifdef USEMPI
17 #include <mpi.h> // Must go first
18 #include <basic/TracerToFile.hh>
19 #endif
20 
21 // Unit headers
22 #include <time.h>
23 #include <core/init.hh>
24 
25 // Project Headers
26 #include <core/svn_version.hh>
27 #include <core/types.hh>
28 #include <basic/options/option.hh>
29 #include <utility/basic_sys_util.hh>
30 #include <utility/excn/Exceptions.hh>
31 #include <utility/io/izstream.hh>
32 #include <basic/Tracer.hh>
33 #include <basic/prof.hh>
34 // Classes in core that must register with factorys
40 
68 
70 
71 // define this for compiling a slimmed down version of mini libraries lacking about 3/4s of the code
72 // this is required for compiling a less memory hungry version of mini for Bluegene etc..
73 //#define MINI_SLIM
74 #ifndef MINI_SLIM
84 //XRW_B_T1
85 //#include <core/scoring/etable/CoarseEtableEnergyCreator.hh>
86 //XRW_E_T1
163 
164 
165 // Constraint registration
168 
171 
172 // SilentStruct registration
176 
177 // Sequence registration
180 
181 // for registering TaskOperations, ResLvlTaskOperations, and ResFilters
193 // (end for registering TaskOperations, ResLvlTaskOperations, and ResFilters)
194 
195 #endif
196 
197 #ifndef WIN_PYROSETTA
198  #include <platform/types.hh>
199 #endif
200 
201 #ifdef MAC
202 #include <mach-o/dyld.h> // for _NSGetExecutablePath
203 #endif
204 
205 
206 #include <basic/options/keys/in.OptionKeys.gen.hh>
207 #include <cstring>
208 
209 using basic::T;
210 using basic::Error;
211 using basic::Warning;
212 
213 // Windows headers
214 #if (defined WIN32) && (!defined WIN_PYROSETTA)
215 #include <windows.h>
216 #include <wincrypt.h>
217 #endif
218 
219 // STL headers
220 #include <fstream>
221 #include <sstream>
222 #include <string>
223 
224 // option key includes
225 
226 #include <basic/options/keys/out.OptionKeys.gen.hh>
227 #include <basic/options/keys/run.OptionKeys.gen.hh>
228 #include <basic/options/keys/corrections.OptionKeys.gen.hh>
229 #include <basic/options/keys/score.OptionKeys.gen.hh>
230 #include <basic/options/keys/OptionKeys.hh>
231 
232 // ResourceManager includes
233 #include <basic/resource_manager/ResourceLoaderRegistrator.hh>
240 #include <basic/resource_manager/ResourceOptionsRegistrator.hh>
245 
246 
247 
248 
249 //option key includes for deprecated pdbs
250 #include <basic/options/keys/LoopModel.OptionKeys.gen.hh>
251 
256 #include <utility/vector0.hh>
257 #include <utility/vector1.hh>
258 
259 
260 #ifdef UNICODE
261 typedef std::wostringstream ostringstream_t;
262 #else
263 typedef std::ostringstream ostringstream_t;
264 #endif
265 
266 namespace core {
267 
268 /// The following global varialbles force the linker to always include
269 /// the EnergyMethodCreator files to be included in staticly linked
270 /// executables. These variables will be initialized before main()
271 /// begins during the "dynamic initialization" phase of loading.
272 /// During this time, the Registrotor classes will register their templated
273 /// EnergyMethods with the ScoringManager before main() begins.
274 
275 using namespace scoring::methods;
276 
308 
310 
311 // define this for compiling a slimmed down version of mini libraries lacking about 3/4s of the code
312 // this is required for compiling a less memory hungry version of mini for Bluegene etc..
313 #ifndef MINI_SLIM
326 //XRW_B_T1
327 //static EnergyMethodRegistrator< scoring::etable::CoarseEtableEnergyCreator > CoarseEtableEnergyCreator_registrator;
328 //XRW_E_T1
398 
403 
404 /// Constraint Registrators
405 using namespace scoring::constraints;
419 
424 
425 // SilentStruct registrators
426 using namespace core::io::silent;
434 
435 // Sequence registrators
436 using namespace core::sequence;
441 
442 // perhaps these long registration lists live in their own separate file?
443 using namespace pack::task::operation;
444 // register TaskOperationCreators
470 // register ResLvlTaskOperationCreators
476 // register ResFilterCreators
491 
492 using basic::resource_manager::ResourceLoaderRegistrator;
493 static ResourceLoaderRegistrator< core::conformation::symmetry::SymmDataLoaderCreator > SymmDataLoaderCreator_registrator;
494 static ResourceLoaderRegistrator< core::io::silent::SilentFileLoaderCreator > SilentFileLoaderCreator_registrator;
495 static ResourceLoaderRegistrator< core::import_pose::PoseFromPDBLoaderCreator > PoseFromPDBLoaderCreator_registrator;
496 static ResourceLoaderRegistrator< core::scoring::electron_density::ElectronDensityLoaderCreator > ElectronDensityLoaderCreator_registrator;
497 static ResourceLoaderRegistrator< core::chemical::ResidueLoaderCreator > ResidueLoaderCreator_registrator;
498 
499 using basic::resource_manager::ResourceOptionsRegistrator;
500 static ResourceOptionsRegistrator< core::conformation::symmetry::SymmDataOptionsCreator > SymmDataOptionsCreator_registrator;
501 static ResourceOptionsRegistrator< core::import_pose::ImportPoseOptionsCreator > ImportPoseOptionsCreator_registrator;
502 static ResourceOptionsRegistrator< core::io::silent::SilentFileOptionsCreator > SilentFileOptionsCreator_registrator;
503 static ResourceOptionsRegistrator< core::scoring::electron_density::ElectronDensityOptionsCreator > ElectronDensityOptionsCreator_registrator;
504 static ResourceOptionsRegistrator< core::chemical::ResidueLoaderOptionsCreator > ResiudeLoaderOptionsCreator_registrator;
505 
506 #endif
507 
508 static basic::Tracer TR("core.init");
509 
510 using namespace numeric::random;
511 using namespace basic::options;
512 using namespace basic::options::OptionKeys;
513 
514 #ifdef USEMPI
515 void
516 init_mpi(int argc, char * argv []) {
517  int already_initialized( 0 );
518  MPI_Initialized( & already_initialized );
519  if ( already_initialized == 0 ) MPI_Init(&argc, &argv);
520 }
521 #else
522 void
523 init_mpi(int, char **) {}
524 #endif
525 
526 
527 void
528 init_options(int argc, char * argv []) {
529 #ifdef BOINC
530  std::cerr << "Initializing options.... ok " << std::endl;std::cerr.flush();
531 #endif
532 
533  // initialize options
534  initialize().load( argc, argv, false /* no "free" cmd line args (just discarded anyway) */ );
535 #ifdef BOINC
536  std::cerr << "Loaded options.... ok " << std::endl;std::cerr.flush();
537 #endif
538  process();
539 #ifdef BOINC
540  std::cerr << "Processed options.... ok " << std::endl; std::cerr.flush();
541 #endif
542 
543  // Set option system global
544  OptionCollection::set_show_accessed_options_flag( option[ out::show_accessed_options ].value() );
545 }
546 
547 void
549  // set Tracer options
550  basic::TracerOptions & TO( basic::Tracer::tracer_options() );
551 
552  if( option[ out::mute ].active() ) TO.muted = option[ out::mute ]();
553 
554  if( option[ out::unmute ].active() ) TO.unmuted = option[ out::unmute ]();
555  if( option[ out::level ].active() ) TO.level = option[ out::level ]();
556  if( option[ out::levels ].active() ) TO.levels = option[ out::levels ]();
557  if( option[ out::chname ].active() ) TO.print_channel_name = option[ out::chname ]();
558  if( option[ out::chtimestamp ].active() ) TO.timestamp = option[ out::chtimestamp ]();
559 
560  // Adding Tracer::flush_all_tracers to list of exit-callbacks so all tracer output got flush out when utility_exit is used.
561  utility::add_exit_callback(basic::Tracer::flush_all_tracers);
562 }
563 
564 void
566 
567  // set default corrections
568  if( option[corrections::correct]) {
569  // Pair energy
570  if ( ! option[ corrections::score::no_his_his_pairE ].user() ) {
571  option[corrections::score::no_his_his_pairE].value( true );
572  }
573 
574  // p_aa_pp
575  if ( ! option[ corrections::score::p_aa_pp ].user() ) {
576  option[corrections::score::p_aa_pp].value( "scoring/score_functions/P_AA_pp/P_AA_pp_08.2009" );
577  }
578  if ( ! option[ corrections::score::p_aa_pp_nogridshift ].user() ) {
579  option[corrections::score::p_aa_pp_nogridshift].value( true );
580  }
581 
582  //Ramachandran
583  if ( ! option[ corrections::score::rama_not_squared ].user() ) {
584  option[corrections::score::rama_not_squared].value( true );
585  }
586  if ( ! option[ corrections::score::rama_map ].user() ) {
587  option[ corrections::score::rama_map ].value("scoring/score_functions/rama/Rama09_noEH_kernel25_it08.dat");
588  }
589  //rotamer library
590  if ( ! option[ corrections::score::dun02_file ].user() ) {
591  option[corrections::score::dun02_file].value( "rotamer/bbdep02.May.sortlib-correct.12.2010" );
592  }
593 
594  //icoor
595  if ( ! option[ corrections::chemical::icoor_05_2009 ].user() ) {
596  option[corrections::chemical::icoor_05_2009].value( true );
597  }
598  if ( ! option[ score::hbond_params ].user() ) {
599  option[score::hbond_params].value( "correct_params" );
600  }
601 
602  if ( ! option[ corrections::score::ch_o_bond_potential ].user() ) {
603  option[ corrections::score::ch_o_bond_potential ].value("scoring/score_functions/carbon_hbond/ch_o_bond_potential_near_min_yf.dat");
604  }
605  }
606 }
607 
608 void
610  if( option[ run::version ]() ) {
611  TR << "Mini-Rosetta version " << core::minirosetta_svn_version() << " from " << core::minirosetta_svn_url() << std::endl;
612  }
613 }
614 
615 void
617  if( option[ in::path::path ].user() ){
618  utility::io::izstream::set_alternative_search_paths(
619  option[ in::path::path ]());
620  }
621 }
622 
623 /// @detail If you deprecate a long standing flag, add a line to this function to describe what the deprecated flag has been replaced with.
624 /// If the user specifies one of these flags, Rosetta will utility exit with a helpful message directing the user towards the new functionality
626 
627  utility::vector1<std::string> error_messages;
628 
629  //Add deprecated flags and corresponding helpful error messages here. This is the only thing you need to do to deprecate a flag
630  if(option[LoopModel::input_pdb].user())
631  error_messages.push_back("-LoopModel:input_pdb is no longer used. Please use -s to input pdb files.");
632 
633 
634  if(error_messages.size() > 0)
635  {
637  for(error_it = error_messages.begin();error_it != error_messages.end();++error_it)
638  {
639  TR.Fatal << "ERROR: You have specified one or more deprecated flags:" <<std::endl;
640  TR.Fatal << *error_it <<std::endl;
641  }
642  std::exit(1);
643 
644  }
645 
646 }
647 
648 void
649 report_application_command(int argc, char * argv []){
650  TR << "command:";
651  for ( int i=0; i< argc; ++i ) {
652  TR << ' ' << argv[i];
653  }
654  TR << std::endl;
655 }
656 
657 void
659  using namespace numeric::random;
660 
661  int seed = 1111111;
662  int seed_offset = 0;
663  bool const_seed = false;
664  bool use_time_as_seed = false;
665  if( option[ run::constant_seed ].active() ) const_seed = option[ run::constant_seed ]();
666  if( option[ run::jran ].active() ) seed = option[ run::jran ]();
667  if( option[ run::seed_offset ].active() ) seed_offset = option[ run::seed_offset ]();
668  if( option[ run::use_time_as_seed ].active() ) use_time_as_seed = option[ run::use_time_as_seed ]();
669 
670 #ifdef USEMPI
671  if( option[ out::mpi_tracer_to_file ].user() ){
672  int mpi_rank( 0 );
673  MPI_Comm_rank( MPI_COMM_WORLD, &mpi_rank );
674 
675  std::stringstream outfilename;
676  outfilename << option[ out::mpi_tracer_to_file ]() << "_" << mpi_rank;
677  basic::otstreamOP redirect_tracer = new basic::TracerToFile( outfilename.str() );
678  basic::Tracer::set_ios_hook( redirect_tracer, basic::Tracer::AllChannels, false );
679  basic::Tracer::super_mute( true );
680  }
681 
682 #endif
683 
684 
685  std::string random_device_name( option[ run::rng_seed_device ]() ); // typically /dev/urandom or /dev/random
686 
687  int real_seed;
688 
689  if( const_seed ) {
690  real_seed = seed + seed_offset;
691 #ifdef USEMPI
692  { // scope
693  /// Give a different RNG seed to each processor
694  int mpi_rank( 0 );
695  MPI_Comm_rank( MPI_COMM_WORLD, &mpi_rank );
696  real_seed += mpi_rank;
697  }
698 #endif
699  T("core.init") << "Constant seed mode, seed=" << seed << " seed_offset=" << seed_offset
700  << " real_seed=" << real_seed << std::endl;
701  }
702  else {
703 #if (defined WIN32) && (!defined WIN_PYROSETTA)
704  bool const on_windows_platform = true;
705 #else
706  bool const on_windows_platform = false;
707 #endif
708  // attempt to open rng device, if failure then fallback to time
709  std::ifstream random_device( random_device_name.c_str(), std::ios::in | std::ios::binary );
710  if ( ( random_device.fail() && !on_windows_platform ) || use_time_as_seed ) {
711  if ( !use_time_as_seed ) {
712  // notify user that opening rng device has failed
713  T("core.init") << "NOTICE: rng device failure, using time as seed" << std::endl;
714  }
715  random_device.close();
716 
717  //iwd When using time-based seed on a cluster, seed_offset is usually from 0 to num_processes.
718  //iwd If jobs start a few seconds apart, a simple sum of seed and seed_offset can lead to collisions.
719  //iwd Thus we multiply the time by some number larger than the largest expected value of seed_offset.
720  //iwd If anyone's using this on more than 1000 machines at a time, we need to increase this value.
721  //iwd (Rosetta++ used a multiplier of 20, which helps some, but is nonetheless too small.)
722  seed = time(0);
723  //seed = seed%10000; // PB-- USE THIS ON OUR CLUSTER TO GET UNIQUE RUNS
724  //real_seed = seed + seed_offset;
725  real_seed = 1000*seed + seed_offset;
726 
727 #ifdef USEMPI
728  // When we use MPI and time-based seeds on a cluster, adjust the RNG seed so that it is the seed of the head node
729  // (the node with an mpi rank of zero) plus the rank of the processer. This or is garentees that each node will
730  // have a unique seed.
731 
732  /// get the processor rank
733  int mpi_rank( 0 );
734  MPI_Comm_rank( MPI_COMM_WORLD, &mpi_rank );
735  // set the real_seed of each processor to the real seed of the head node
736  MPI_Bcast( &real_seed, 1, MPI_INT, 0, MPI_COMM_WORLD );
737  // adjust the real seed based on the rank
738  real_seed += mpi_rank;
739 #endif
740 
741  T("core.init") << "'Time' seed mode, seed=" << seed << " seed_offset=" << seed_offset
742  << " real_seed=" << real_seed << std::endl;
743  } else {
744  // grab seeds from device
745  uint32_t unsigned_32bit_seed;
746 
747 #if (defined WIN32) && (!defined WIN_PYROSETTA)
748  // windows random device name
749  random_device_name = "CryptGenRandom";
750 
751  // unique name for key container
752  ostringstream_t key_container_name;
753  key_container_name << "arzetta-" << GetCurrentProcessId() << "-" << GetCurrentThreadId();
754 
755  // init cryptographic provider, creates key container
756  HCRYPTPROV hCryptProv = 0;
757 
758  if ( !CryptAcquireContext( &hCryptProv, key_container_name.str().c_str(), NULL, PROV_RSA_AES, CRYPT_NEWKEYSET ) ) {
759  TR.Fatal << "FATAL: CryptAcquireContext unable to acquire cryptographic provider!" << std::endl;
760  TR.Fatal << std::hex << GetLastError() << std::endl;
761  std::exit( 1 );
762  }
763 
764  // grab the random number seed from CryptGenRandom
765  BYTE pbData[ 4 ];
766  if ( !CryptGenRandom( hCryptProv, 4, pbData ) ) {
767  TR.Fatal << "FATAL: Unable to obtain random number seed using CryptGenRandom!" << std::endl;
768  TR.Fatal << std::hex << GetLastError() << std::endl;
769  std::exit( 1 );
770  }
771 
772  // store seed in 'unsigned_32bit_seed'
773  unsigned_32bit_seed = pbData[ 0 ] + ( pbData[ 1 ] << 8 ) + ( pbData[ 2 ] << 16 ) + ( pbData[ 3 ] << 24 );
774 
775  // release cryptographic provider handle
776  if ( !CryptReleaseContext( hCryptProv, 0 ) ) {
777  TR.Fatal << "FATAL: CryptReleaseContext failed to release cryptographic provider!" << std::endl;
778  TR.Fatal << std::hex << GetLastError() << std::endl;
779  std::exit( 1 );
780  }
781 
782  // delete key container
783  if ( !CryptAcquireContext( &hCryptProv, key_container_name.str().c_str(), NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET ) ) {
784  TR.Fatal << "FATAL: CryptAcquireContext failed to delete key container!" << std::endl;
785  TR.Fatal << std::hex << GetLastError() << std::endl;
786  std::exit( 1 );
787  }
788 
789 #else
790  random_device.read( reinterpret_cast< char * >( &unsigned_32bit_seed ), sizeof( uint32_t ));
791 #endif
792  random_device.close();
793 
794  // calculate actual seeds
795  seed = static_cast< int >( unsigned_32bit_seed );
796  real_seed = seed + seed_offset;
797 
798 #ifdef USEMPI
799  // Although not as critical with device-based seeding as with time-based clusters, when we use MPI and
800  // device-based seeds on a cluster, adjust the RNG seed so that it is the seed of the head node (the node with an
801  // mpi rank of zero) plus the rank of the processer. This or is garentees that each node will have a unique
802  // seed. Different OSs impliment their RNG differently and as we use increassingly large numbers of processors
803  // this may become an issue (but probaly not).
804 
805  /// get the processor rank
806  int mpi_rank( 0 );
807  MPI_Comm_rank( MPI_COMM_WORLD, &mpi_rank );
808  // set the real_seed of each processor to the real seed of the head node
809  MPI_Bcast( &real_seed, 1, MPI_INT, 0, MPI_COMM_WORLD );
810  // adjust the real seed based on the rank
811  real_seed += mpi_rank;
812 #endif
813 
814  // log seeds
815  T("core.init") << "'RNG device' seed mode, using '" << random_device_name << "', seed=" << seed << " seed_offset=" << seed_offset
816  << " real_seed=" << real_seed << std::endl;
817  }
818 
819  }
820 
821  /*numeric::random::RandomGenerator::initializeRandomGenerators(
822  real_seed, numeric::random::_RND_ConstantSeed_,
823  option[ run::rng ] );
824  */
825 #ifdef BOINC
826  std::cerr << "Initializing random generators... ok " << std::endl;std::cerr.flush();
827 #endif
828  init_random_generators(real_seed, _RND_NormalRun_, option[ run::rng ]);
829 
830  srand( time(NULL) ); // seed default random generator, this will expose all code that use non approved random methods
831 }
832 
833 /// @brief Initialize random generator systems (and send debug io to tracer with seed/mode info).
834 void init_random_generators(int const start_seed, RND_RunType run_type, std::string const & RGtype)
835 {
836  if( run_type == _RND_TestRun_ ) {
837  T("core.init.random") << "RandomGenerator:init: _RND_TestRun_ mode, seed=" << start_seed <<
838  " RG_type=" << RGtype << std::endl;
839  }
840  else {
841  T("core.init.random") << "RandomGenerator:init: Normal mode, seed=" << start_seed <<
842  " RG_type=" << RGtype << std::endl;
843  }
844 
845  RandomGenerator::initializeRandomGenerators(start_seed, run_type, RGtype);
846 }
847 
848 
849 void
851  // no silly waiting in DEBUG or BOINC builds
852 #ifdef NDEBUG
853 #ifndef BOINC
854  if( !option[ run::nodelay ]() ){
855  if( option[ run::delay ]() > 0 ) {
856  int waittime = option[ run::delay ]();
857  TR << "Delaying start of mini for " << waittime << " seconds due to -delay option" << std::endl;
858  utility::sys_sleep( waittime );
859  } else
860  if( option[ run::random_delay ]() > 0 ) {
861  int waittime = (int) ( (Real)option[ run::random_delay ]() * numeric::random::uniform() );
862  TR << "Delaying of mini for " << waittime << " seconds (maximum = "
863  << option[ run::random_delay ]()
864  << " )" << std::endl
865  << "This prevents extreme IO levels when multiple jobs start simultaneously on" << std::endl
866  << "large computer clusters and is default now. To prevent this add the option -nodelay" << std::endl
867  << "To change the random wait time use -run::random_delay <int> " << std::endl;
868  utility::sys_sleep( waittime );
869  }
870  }
871 #endif
872 #endif
873 }
874 
875 void
877  if ( !option[ in::path::database ].user() ) {
878  std::string database_path;
879  char * descr = getenv("ROSETTA3_DB");
880  if ( descr ) {
881  TR << "found database environment variable ROSETTA3_DB: "<< descr << std::endl;
882  database_path = std::string( descr );
883  } else {
884 
885  char path[1024];
886  uint32_t path_size = sizeof( path );
887 
888 #ifdef MAC
889  _NSGetExecutablePath(path, &path_size );
890 #endif
891 #ifdef LINUX
892  readlink( "/proc/self/exe", path, path_size ); // This works on plain Linux, but not FreeBSD or Solaris.
893 #endif
894 #ifdef WIN32
895  TR << "There is some way to automatically figure out the path to rosetta_database with GetModuleFileName in Windows. This is already set up for linux and mac, its probably just one line to change in core/init.cc" << std::endl;
896  // I think its this -- can someone comment out and compile on Windows?
897  // GetModuleFileName( NULL, path, path_size );
898 #endif
899 
900  std::string path_string( path );
901  Size found = path_string.find("rosetta_source/"); //This better be in the path -- now part of the standard rosetta3 directory structure!
902  if ( found != std::string::npos && path_size > 0){
903  std::string rosetta_exe_dir = path_string.substr(0,found);
904  database_path = rosetta_exe_dir + "rosetta_database/";
905  TR << "Looking for database based on location of executable: " << database_path << std::endl;
906  } else {
907  TR << "Could not determine location of executable." << std::endl;
908  }
909 
910  }
911 
912  if ( database_path.size() > 0 ){
913  option[ in::path::database ].value( database_path );
914  } else {
915  TR << "Could not find database. Either specify -database or set environment variable ROSETTA3_DB." << std::endl;
916  }
917 
918  }
919 }
920 
921 void
923  basic::prof_reset(); //reads option run::profile -- starts clock TOTAL
924 }
925 
926 /// @brief Init basic core systems: options system, random system.
927 void init(int argc, char * argv [])
928 {
929  try{
930  //Initialize MPI
931  init_mpi(argc, argv);
932 
933  //The options system manages command line options
934  init_options(argc, argv);
935 
936  //Tracers control output to std::cout and std::cerr
937  init_tracers();
938 
939  //Initialize the latest and greatest score function parameters
941 
942  //Choose to output source version control information?
944 
945  //Setup basic search paths
946  init_paths();
947 
948  //Check for deprecated flags specified by the user and output error messages if necessary
950 
951  //Describe the application execution command
952  report_application_command(argc, argv);
953 
954  //Initalize random number generators
956 
957  //Choose to randomly delay execution to desyncronize parallel execution
958  random_delay();
959 
960  //Locate rosetta_database
962 
963 #ifdef BOINC
964  std::cerr << "Initialization complete. " << std::endl;
965 #endif
966 
967  //Profiling measures execution performance
968  init_profiling();
969 
970  // help out user...
971  if ( argc == 1 ) TR << std::endl << "USEFUL TIP: Type -help to get the options for this Rosetta executable." << std::endl << std::endl;
972 
973  }
974  // Catch any Rosetta exceptions
975  catch( utility::excn::EXCN_Msg_Exception &e){
976  // print the error message to standard error
977  e.show( std::cerr );
978  // and rethrow to make sure we quit (or give caller opportunity to clean up or catch)
979  throw;
980  }
981 }
982 
983 
984 /// @brief wrapper for core system Init
986 {
987  // create arguments in argc/argv format
988  int argc = args.size();
989  char **argv = new char*[ argc ];
990  for( int ii = 0; ii < argc; ++ii ) {
991  argv[ ii ] = new char[ args[ii+1].size()+1 ];
992  strncpy( argv[ii], args[ii+1].c_str(), args[ii+1].size() );
993  argv[ ii ][ args[ii+1].size() ] = 0; // ensure null termination
994  }
995 
996  // call init
997  init( argc, argv );
998 
999  // delete freestore
1000  for ( int ii = 0; ii < argc; ++ii ) {
1001  delete[] argv[ ii ];
1002  }
1003  delete[] argv;
1004 }
1005 
1006 } // namespace core
1007