openModeller
Version 1.4.0
|
00001 /************************************************************************************* 00002 * This code simply loads a previously created model, loads a reprojection 00003 * environment, and projects the model into that environment, 00004 * then writes the model out. 00005 * ------------------- 00006 * begin : November 2005 00007 * copyright : (C) 2005 by T.Sutton, Kevin Ruland, Renato De Giovanni 00008 * email : tim@linfiniti.com 00009 *************************************************************************************/ 00010 00011 /*************************************************************************** 00012 * 00013 * This program is free software; you can redistribute it and/or modify * 00014 * it under the terms of the GNU General Public License as published by * 00015 * the Free Software Foundation; either version 2 of the License, or * 00016 * (at your option) any later version. * 00017 * * 00018 ***************************************************************************/ 00019 00020 #include <openmodeller/om.hh> 00021 #include <openmodeller/Log.hh> 00022 #include <openmodeller/os_specific.hh> 00023 00024 #include "getopts/getopts.h" 00025 00026 #include "om_cmd_utils.hh" 00027 00028 #include <fstream> // file I/O for XML 00029 #include <sstream> // ostringstream datatype 00030 #include <stdio.h> // file I/O for log 00031 #include <time.h> // used to limit the number of times that the progress is written to a file 00032 #include <string> // string library 00033 #include <stdexcept> // try/catch 00034 00035 #ifdef MPI_FOUND 00036 #include "mpi.h" 00037 #endif 00038 00039 using namespace std; 00040 00041 int main( int argc, char **argv ) { 00042 00043 Options opts; 00044 int option; 00045 00046 // command-line parameters (short name, long name, description, take args) 00047 opts.addOption( "v", "version" , "Display version info" , false ); 00048 opts.addOption( "r", "xml-req" , "Projection request file in XML" , true ); 00049 opts.addOption( "o", "model" , "File with serialized model (native projection)", true ); 00050 opts.addOption( "t", "template" , "Raster template for the distribution map (native projection)", true ); 00051 opts.addOption( "f", "format" , "File format for the distribution map (native projection)", true ); 00052 opts.addOption( "m", "dist-map" , "File to store the generated model" , true ); 00053 opts.addOption( "" , "log-level" , "Set the log level (debug, warn, info, error)", true ); 00054 opts.addOption( "" , "log-file" , "Log file" , true ); 00055 opts.addOption( "" , "prog-file" , "File to store projection progress" , true ); 00056 opts.addOption( "" , "stat-file" , "File to store projection statistics" , true ); 00057 opts.addOption( "c", "config-file", "Configuration file for openModeller" , true ); 00058 00059 std::string log_level("info"); 00060 std::string request_file; 00061 std::string model_file; 00062 std::string tmpl_file; 00063 std::string format; 00064 std::string map_file; 00065 std::string log_file; 00066 std::string progress_file; 00067 std::string statistics_file; 00068 std::string config_file; 00069 00070 if ( ! opts.parse( argc, argv ) ) { 00071 00072 opts.showHelp( argv[0] ); 00073 exit(0); 00074 } 00075 00076 // Set up any related external resources 00077 setupExternalResources(); 00078 00079 OpenModeller om; 00080 00081 while ( ( option = opts.cycle() ) >= 0 ) { 00082 00083 switch ( option ) { 00084 00085 case 0: 00086 printf( "om_project %s\n", om.getVersion().c_str() ); 00087 printf("This is free software; see the source for copying conditions. There is NO\n"); 00088 printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); 00089 exit(0); 00090 break; 00091 case 1: 00092 request_file = opts.getArgs( option ); 00093 break; 00094 case 2: 00095 model_file = opts.getArgs( option ); 00096 break; 00097 case 3: 00098 tmpl_file = opts.getArgs( option ); 00099 break; 00100 case 4: 00101 format = opts.getArgs( option ); 00102 break; 00103 case 5: 00104 map_file = opts.getArgs( option ); 00105 break; 00106 case 6: 00107 log_level = opts.getArgs( option ); 00108 break; 00109 case 7: 00110 log_file = opts.getArgs( option ); 00111 break; 00112 case 8: 00113 progress_file = opts.getArgs( option ); 00114 break; 00115 case 9: 00116 statistics_file = opts.getArgs( option ); 00117 break; 00118 case 10: 00119 config_file = opts.getArgs( option ); 00120 break; 00121 default: 00122 break; 00123 } 00124 } 00125 00126 // om configuration 00127 if ( ! config_file.empty() ) { 00128 00129 Settings::loadConfig( config_file ); 00130 } 00131 00132 // Log stuff 00133 00134 Log::Level level_code = getLogLevel( log_level ); 00135 00136 if ( ! log_file.empty() ) { 00137 00138 Log::instance()->set( level_code, log_file, "" ); 00139 } 00140 else { 00141 00142 // Just set the level - things will go to stderr 00143 Log::instance()->setLevel( level_code ); 00144 } 00145 00146 // Check parameters 00147 00148 if ( request_file.empty() && model_file.empty() ) { 00149 00150 printf( "Please specify either a projection request file in XML or a serialized model\n"); 00151 exit(-1); 00152 } 00153 00154 if ( (! request_file.empty()) && ( (! model_file.empty()) || (! tmpl_file.empty()) || (! format.empty() ) ) ) { 00155 00156 Log::instance()->warn( "When a request file is specified, --model, --template and --format are ignored" ); 00157 } 00158 00159 if ( map_file.empty() ) { 00160 00161 printf( "Please specify a file to store the distribution map\n"); 00162 exit(-1); 00163 } 00164 00165 // Initialize progress data if user wants to track progress 00166 progress_data prog_data; 00167 00168 if ( ! progress_file.empty() ) { 00169 00170 prog_data.file_name = progress_file; 00171 00172 time( &prog_data.timestamp ); 00173 00174 prog_data.progress = -1.0; // queued 00175 00176 // Always create initial file with progress 0 00177 progressFileCallback( 0.0, &prog_data ); 00178 } 00179 00180 // Real work 00181 00182 try { 00183 00184 #ifdef MPI_FOUND 00185 Log::instance()->info( "Running parallel projection version\n" ); 00186 MPI_Init( &argc, &argv ); 00187 int rank; 00188 MPI_Comm_rank( MPI_COMM_WORLD, &rank ); 00189 Log::instance()->debug( "Rank of calling process: %d\n", rank ); 00190 MPI_Barrier( MPI_COMM_WORLD ); 00191 #else 00192 Log::instance()->info( "Running serial projection version\n" ); 00193 #endif 00194 00195 // Load algorithms and instantiate controller class 00196 AlgorithmFactory::searchDefaultDirs(); 00197 00198 // If user wants to track progress 00199 if ( ! progress_file.empty() ) { 00200 00201 // Set callback to write to a file 00202 om.setMapCallback( progressFileCallback, &prog_data ); 00203 } 00204 else if ( ! statistics_file.empty() ) { 00205 00206 // Default callback will display progress on screen when a statistics file was specified 00207 // (which means statistics won't be sent to stdout) 00208 om.setMapCallback( progressDisplayCallback ); 00209 } 00210 00211 std::ostringstream model_output; 00212 00213 if ( ! request_file.empty() ) { 00214 00215 ConfigurationPtr input = Configuration::readXml( request_file.c_str() ); 00216 om.setProjectionConfiguration( input ); 00217 om.createMap( map_file.c_str() ); 00218 } 00219 else { 00220 00221 // Native projection - get original environment from serialized model 00222 ConfigurationPtr input = Configuration::readXml( model_file.c_str() ); 00223 00224 om.setModelConfiguration( input ); 00225 00226 EnvironmentPtr env = om.getEnvironment(); 00227 00228 MapFormat tmpl; 00229 00230 if ( tmpl_file.empty() ) { 00231 00232 // Use first layer as reference 00233 std::string first_layer = env->getLayerPath(0); 00234 00235 tmpl = MapFormat( first_layer.c_str() ); 00236 } 00237 else { 00238 00239 tmpl = MapFormat( tmpl_file.c_str() ); 00240 } 00241 00242 if ( ! format.empty() ) { 00243 00244 tmpl.setFormat( format ); 00245 } 00246 00247 om.createMap( env, map_file.c_str(), tmpl ); 00248 } 00249 00250 AreaStats * stats = om.getActualAreaStats(); 00251 00252 ConfigurationPtr stats_cfg = stats->getConfiguration(); 00253 00254 std::ostringstream statistics_output; 00255 00256 Configuration::writeXml( stats_cfg, statistics_output ); 00257 00258 std::cerr << flush; 00259 00260 // Write statistics output to file, if requested 00261 if ( ! statistics_file.empty() ) { 00262 00263 ofstream file( statistics_file.c_str() ); 00264 file << statistics_output.str(); 00265 file.close(); 00266 } 00267 else { 00268 00269 // Otherwise send it to stdout 00270 std::cout << statistics_output.str().c_str() << endl << flush; 00271 } 00272 00273 delete stats; 00274 00275 // If user wants to track progress 00276 if ( ! progress_file.empty() ) { 00277 00278 // Check if job was completed 00279 if ( prog_data.progress != 1 ) { 00280 00281 // -2 means aborted 00282 progressFileCallback( -2.0, &prog_data ); 00283 } 00284 } 00285 } 00286 catch ( runtime_error e ) { 00287 00288 // If user is tracking progress 00289 if ( ! progress_file.empty() ) { 00290 00291 // -2 means aborted 00292 progressFileCallback( -2.0, &prog_data ); 00293 } 00294 00295 printf( "om_project aborted: %s\n", e.what() ); 00296 } 00297 00298 #ifdef MPI_FOUND 00299 MPI_Barrier( MPI_COMM_WORLD ); 00300 MPI_Finalize(); 00301 #endif 00302 00303 }