openModeller  Version 1.4.0
om_model.cpp
Go to the documentation of this file.
00001 /*************************************************************************************
00002  *  A simple command line app to create an openModeller model
00003  *    -------------------
00004  *       begin                : November 2005
00005  *       copyright            : (C) 2005 by T.Sutton, Kevin Ruland, Renato De Giovanni
00006  *       email                : tim@linfiniti.com
00007  *************************************************************************************/
00008 
00009 /***************************************************************************
00010  *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 #include <openmodeller/om.hh>
00018 #include <openmodeller/Log.hh>
00019 #include <openmodeller/os_specific.hh>
00020 
00021 #include "getopts/getopts.h"
00022 
00023 #include "om_cmd_utils.hh"
00024 
00025 #include <fstream>   // file I/O for XML
00026 #include <sstream>   // ostringstream datatype
00027 #include <stdio.h>   // file I/O for log
00028 #include <time.h>    // used to limit the number of times that the progress is written to a file
00029 #include <string>    // string library
00030 #include <stdexcept> // try/catch
00031 
00032 using namespace std;
00033 
00035 int main( int argc, char **argv ) {
00036 
00037   Options opts;
00038   int option;
00039 
00040   // command-line parameters (short name, long name, description, take args)
00041   opts.addOption( "v", "version"     , "Display version info"                        , false );
00042   opts.addOption( "r", "xml-req"     , "Model creation request file in XML"          , true );
00043   opts.addOption( "m", "model-file"  , "File to store the generated model"           , true );
00044   opts.addOption( "" , "log-level"   , "Set the log level (debug, warn, info, error)", true );
00045   opts.addOption( "" , "log-file"    , "Log file"                                    , true );
00046   opts.addOption( "" , "prog-file"   , "File to store model creation progress"       , true );
00047   opts.addOption( "c", "config-file" , "Configuration file for openModeller"         , true );
00048 
00049   std::string log_level("info");
00050   std::string request_file;
00051   std::string model_file;
00052   std::string log_file;
00053   std::string progress_file;
00054   std::string config_file;
00055 
00056   if ( ! opts.parse( argc, argv ) ) {
00057 
00058     opts.showHelp( argv[0] ); 
00059     exit(0);
00060   }
00061 
00062   // Set up any related external resources
00063   setupExternalResources();
00064 
00065   OpenModeller om;
00066 
00067   while ( ( option = opts.cycle() ) >= 0 ) {
00068 
00069     switch ( option ) {
00070 
00071       case 0:
00072         printf( "om_model %s\n", om.getVersion().c_str() );
00073         printf("This is free software; see the source for copying conditions. There is NO\n");
00074         printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
00075         exit(0);
00076         break;
00077       case 1:
00078         request_file = opts.getArgs( option );
00079         break;
00080       case 2:
00081         model_file = opts.getArgs( option );
00082         break;
00083       case 3:
00084         log_level = opts.getArgs( option );
00085         break;
00086       case 4:
00087         log_file = opts.getArgs( option );
00088         break;
00089       case 5:
00090         progress_file = opts.getArgs( option );
00091         break;
00092       case 6:
00093         config_file = opts.getArgs( option );
00094         break;
00095       default:
00096         break;
00097     }
00098   }
00099 
00100   // om configuration
00101   if ( ! config_file.empty() ) { 
00102 
00103     Settings::loadConfig( config_file );
00104   }
00105 
00106   // Log stuff
00107 
00108   Log::Level level_code = getLogLevel( log_level );
00109 
00110   if ( ! log_file.empty() ) {
00111 
00112     Log::instance()->set( level_code, log_file, "" );
00113   }
00114   else {
00115  
00116     // Just set the level - things will go to stderr
00117     Log::instance()->setLevel( level_code );
00118   }
00119 
00120   // Check parameters
00121 
00122   if ( request_file.empty() ) {
00123 
00124     printf( "Please specify a model creation request file in XML\n");
00125     exit(-1);
00126   }
00127 
00128   // Initialize progress data if user wants to track progress
00129   progress_data prog_data;
00130 
00131   if ( ! progress_file.empty() ) { 
00132 
00133     prog_data.file_name = progress_file;
00134 
00135     time( &prog_data.timestamp );
00136 
00137     prog_data.progress = -1.0; // queued
00138 
00139     // Always create initial file with progress 0
00140     progressFileCallback( 0.0, &prog_data );
00141   }
00142 
00143   // Real work
00144 
00145   try {
00146 
00147     // Load algorithms and instantiate controller class
00148     AlgorithmFactory::searchDefaultDirs();
00149 
00150     // If user wants to track progress
00151     if ( ! progress_file.empty() ) { 
00152 
00153       // Set callback to write to a file
00154       om.setModelCallback( progressFileCallback, &prog_data );
00155     }
00156     else if ( ! model_file.empty() ) {
00157 
00158       // Default callback will display progress on screen when a model file was specified
00159       // (which means the model won't be sent to stdout)
00160       om.setModelCallback( progressDisplayCallback );
00161     }
00162 
00163     ConfigurationPtr input = Configuration::readXml( request_file.c_str() );
00164     om.setModelConfiguration( input );
00165 
00166     om.createModel();
00167 
00168     om.calculateModelStatistics( input );
00169 
00170     ConfigurationPtr output = om.getModelConfiguration();
00171 
00172     std::ostringstream model_output;
00173 
00174     Configuration::writeXml( output, model_output );
00175 
00176     std::cerr << flush;
00177 
00178     // Write model output to file, if requested
00179     if ( ! model_file.empty() ) {
00180 
00181       ofstream file( model_file.c_str() );
00182       file << model_output.str();
00183       file.close();
00184     }
00185     else {
00186 
00187       // Otherwise send it to stdout
00188       std::cout << model_output.str().c_str() << endl << flush;
00189     }
00190 
00191     // If user wants to track progress
00192     if ( ! progress_file.empty() ) { 
00193 
00194       // Check if job was completed
00195       if ( prog_data.progress != 1 ) {
00196 
00197         // -2 means aborted
00198         progressFileCallback( -2.0, &prog_data );
00199       }
00200     }
00201   }
00202   catch ( runtime_error e ) {
00203 
00204     // If user is tracking progress
00205     if ( ! progress_file.empty() ) { 
00206 
00207       // -2 means aborted
00208       progressFileCallback( -2.0, &prog_data );
00209     }
00210 
00211     printf( "om_model aborted: %s\n", e.what() );
00212   }
00213 }