openModeller  Version 1.5.0
om_project.cpp
Go to the documentation of this file.
1 /*************************************************************************************
2  * This code simply loads a previously created model, loads a reprojection
3  * environment, and projects the model into that environment,
4  * then writes the model out.
5  * -------------------
6  * begin : November 2005
7  * copyright : (C) 2005 by T.Sutton, Kevin Ruland, Renato De Giovanni
8  * email : tim@linfiniti.com
9  *************************************************************************************/
10 
11 /***************************************************************************
12  *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * *
18  ***************************************************************************/
19 
20 #include <openmodeller/om.hh>
21 #include <openmodeller/Log.hh>
23 
24 #include "getopts/getopts.h"
25 
26 #include "om_cmd_utils.hh"
27 
28 #include <fstream> // file I/O for XML
29 #include <sstream> // ostringstream datatype
30 #include <stdio.h> // file I/O for log
31 #include <time.h> // used to limit the number of times that the progress is written to a file
32 #include <string> // string library
33 #include <stdexcept> // try/catch
34 
35 #ifdef MPI_FOUND
36 #include "mpi.h"
37 #endif
38 
39 using namespace std;
40 
41 int main( int argc, char **argv ) {
42 
43  Options opts;
44  int option;
45 
46  // command-line parameters (short name, long name, description, take args)
47  opts.addOption( "v", "version" , "Display version info" , false );
48  opts.addOption( "r", "xml-req" , "Projection request file in XML" , true );
49  opts.addOption( "o", "model" , "File with serialized model (native projection)", true );
50  opts.addOption( "t", "template" , "Raster template for the distribution map (native projection)", true );
51  opts.addOption( "f", "format" , "File format for the distribution map (native projection)", true );
52  opts.addOption( "m", "dist-map" , "File to store the generated model" , true );
53  opts.addOption( "" , "log-level" , "Set the log level (debug, warn, info, error)", true );
54  opts.addOption( "" , "log-file" , "Log file" , true );
55  opts.addOption( "" , "prog-file" , "File to store projection progress" , true );
56  opts.addOption( "" , "stat-file" , "File to store projection statistics" , true );
57  opts.addOption( "c", "config-file", "Configuration file for openModeller" , true );
58 
59  std::string log_level("info");
60  std::string request_file;
61  std::string model_file;
62  std::string tmpl_file;
63  std::string format;
64  std::string map_file;
65  std::string log_file;
66  std::string progress_file;
67  std::string statistics_file;
68  std::string config_file;
69 
70  if ( ! opts.parse( argc, argv ) ) {
71 
72  opts.showHelp( argv[0] );
73  exit(0);
74  }
75 
76  // Set up any related external resources
78 
79  OpenModeller om;
80 
81  while ( ( option = opts.cycle() ) >= 0 ) {
82 
83  switch ( option ) {
84 
85  case 0:
86  printf( "om_project %s\n", om.getVersion().c_str() );
87  printf("This is free software; see the source for copying conditions. There is NO\n");
88  printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
89  exit(0);
90  break;
91  case 1:
92  request_file = opts.getArgs( option );
93  break;
94  case 2:
95  model_file = opts.getArgs( option );
96  break;
97  case 3:
98  tmpl_file = opts.getArgs( option );
99  break;
100  case 4:
101  format = opts.getArgs( option );
102  break;
103  case 5:
104  map_file = opts.getArgs( option );
105  break;
106  case 6:
107  log_level = opts.getArgs( option );
108  break;
109  case 7:
110  log_file = opts.getArgs( option );
111  break;
112  case 8:
113  progress_file = opts.getArgs( option );
114  break;
115  case 9:
116  statistics_file = opts.getArgs( option );
117  break;
118  case 10:
119  config_file = opts.getArgs( option );
120  break;
121  default:
122  break;
123  }
124  }
125 
126  // Log stuff
127 
128  Log::Level level_code = getLogLevel( log_level );
129 
130  if ( ! log_file.empty() ) {
131 
132  Log::instance()->set( level_code, log_file, "" );
133  }
134  else {
135 
136  // Just set the level - things will go to stderr
137  Log::instance()->setLevel( level_code );
138  }
139 
140  // om configuration
141  if ( ! config_file.empty() ) {
142 
143  Settings::loadConfig( config_file );
144  }
145 
146  // Check parameters
147 
148  if ( request_file.empty() && model_file.empty() ) {
149 
150  printf( "Please specify either a projection request file in XML or a serialized model\n");
151  exit(-1);
152  }
153 
154  if ( (! request_file.empty()) && ( (! model_file.empty()) || (! tmpl_file.empty()) || (! format.empty() ) ) ) {
155 
156  Log::instance()->warn( "When a request file is specified, --model, --template and --format are ignored" );
157  }
158 
159  if ( map_file.empty() ) {
160 
161  printf( "Please specify a file to store the distribution map\n");
162  exit(-1);
163  }
164 
165  // Initialize progress data if user wants to track progress
166  progress_data prog_data;
167 
168  if ( ! progress_file.empty() ) {
169 
170  prog_data.file_name = progress_file;
171 
172  time( &prog_data.timestamp );
173 
174  prog_data.progress = -1.0; // queued
175 
176  // Always create initial file with progress 0
177  progressFileCallback( 0.0, &prog_data );
178  }
179 
180  // Real work
181 
182  try {
183 
184  #ifdef MPI_FOUND
185  Log::instance()->info( "Running parallel projection version\n" );
186  MPI_Init( &argc, &argv );
187  int rank;
188  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
189  Log::instance()->debug( "Rank of calling process: %d\n", rank );
190  MPI_Barrier( MPI_COMM_WORLD );
191  #else
192  Log::instance()->info( "Running serial projection version\n" );
193  #endif
194 
195  // Load algorithms and instantiate controller class
197 
198  // If user wants to track progress
199  if ( ! progress_file.empty() ) {
200 
201  // Set callback to write to a file
202  om.setMapCallback( progressFileCallback, &prog_data );
203  }
204  else if ( ! statistics_file.empty() ) {
205 
206  // Default callback will display progress on screen when a statistics file was specified
207  // (which means statistics won't be sent to stdout)
209  }
210 
211  std::ostringstream model_output;
212 
213  if ( ! request_file.empty() ) {
214 
215  ConfigurationPtr input = Configuration::readXml( request_file.c_str() );
216  om.setProjectionConfiguration( input );
217  om.createMap( map_file.c_str() );
218  }
219  else {
220 
221  // Native projection - get original environment from serialized model
222  ConfigurationPtr input = Configuration::readXml( model_file.c_str() );
223 
224  om.setModelConfiguration( input );
225 
226  EnvironmentPtr env = om.getEnvironment();
227 
228  MapFormat tmpl;
229 
230  if ( tmpl_file.empty() ) {
231 
232  // Use first layer as reference
233  std::string first_layer = env->getLayerPath(0);
234 
235  tmpl = MapFormat( first_layer.c_str() );
236  }
237  else {
238 
239  tmpl = MapFormat( tmpl_file.c_str() );
240  }
241 
242  if ( ! format.empty() ) {
243 
244  tmpl.setFormat( format );
245  }
246 
247  om.createMap( env, map_file.c_str(), tmpl );
248  }
249 
250  AreaStats * stats = om.getActualAreaStats();
251 
252  ConfigurationPtr stats_cfg = stats->getConfiguration();
253 
254  std::ostringstream statistics_output;
255 
256  Configuration::writeXml( stats_cfg, statistics_output );
257 
258  std::cerr << flush;
259 
260  // Write statistics output to file, if requested
261  if ( ! statistics_file.empty() ) {
262 
263  ofstream file( statistics_file.c_str() );
264  file << statistics_output.str();
265  file.close();
266  }
267  else {
268 
269  // Otherwise send it to stdout
270  std::cout << statistics_output.str().c_str() << endl << flush;
271  }
272 
273  delete stats;
274 
275  // If user wants to track progress
276  if ( ! progress_file.empty() ) {
277 
278  // Check if job was completed
279  if ( prog_data.progress != 1 ) {
280 
281  // -2 means aborted
282  progressFileCallback( -2.0, &prog_data );
283  }
284  }
285  }
286  catch ( runtime_error e ) {
287 
288  // If user is tracking progress
289  if ( ! progress_file.empty() ) {
290 
291  // -2 means aborted
292  progressFileCallback( -2.0, &prog_data );
293  }
294 
295  printf( "om_project aborted: %s\n", e.what() );
296  }
297 
298  #ifdef MPI_FOUND
299  MPI_Barrier( MPI_COMM_WORLD );
300  MPI_Finalize();
301  #endif
302 
303 }
static void loadConfig(const std::string configFile)
Definition: Settings.cpp:100
void setProjectionConfiguration(const ConstConfigurationPtr &)
void warn(const char *format,...)
'Warn' level.
Definition: Log.cpp:273
static ConfigurationPtr readXml(char const *filename)
int main(int argc, char **argv)
Definition: om_project.cpp:41
AreaStats * getActualAreaStats()
static Log * instance()
Returns the instance pointer, creating the object on the first call.
Definition: Log.cpp:45
std::string file_name
Definition: om_cmd_utils.hh:42
void setMapCallback(ModelProjectionCallback func, void *param=0)
Log::Level getLogLevel(std::string level)
Level
Definition: Log.hh:54
void setLevel(Level level)
Definition: Log.hh:107
EnvironmentPtr getEnvironment()
ConfigurationPtr getConfiguration() const
Definition: AreaStats.cpp:75
int createMap(const EnvironmentPtr &env, char const *output_file, MapFormat &format)
void setupExternalResources()
Definition: os_specific.cpp:95
void set(Level level, std::string fileName, char const *pref="")
Definition: Log.cpp:196
void progressDisplayCallback(float progress, void *extraParam)
static void writeXml(const ConstConfigurationPtr &config, char const *fileaname)
static int searchDefaultDirs()
std::string getVersion()
void info(const char *format,...)
'Info' level.
Definition: Log.cpp:256
void setFormat(int format)
Definition: MapFormat.cpp:151
void debug(const char *format,...)
'Debug' level.
Definition: Log.cpp:237
time_t timestamp
Definition: om_cmd_utils.hh:43
void setModelConfiguration(const ConstConfigurationPtr &)
void progressFileCallback(float progress, void *progressData)