openModeller  Version 1.5.0
om_console.cpp
Go to the documentation of this file.
1 
27 #include <openmodeller/om.hh>
30 
31 #include "request_file.hh"
32 #include "om_cmd_utils.hh"
33 
34 #include <istream>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdio.h>
38 #include <string>
39 #include <stdexcept>
40 
41 #ifdef MPI_FOUND
42 #include "mpi.h"
43 #endif
44 
45 int showAlgorithms ( AlgMetadata const **availables );
46 AlgMetadata const *readAlgorithm( AlgMetadata const **availables );
47 int readParameters( AlgParameter *result, AlgMetadata const *metadata );
48 char *extractParameter( char *name, int nvet, char **vet );
49 
50 void mapCallback( float progress, void *extra_param );
51 void modelCallback( float progress, void * extra_param );
52 
53 /**************************************************************/
54 /*************** openModeller Console Interface ***************/
55 
56 /************/
57 /*** main ***/
58 int
59 main( int argc, char **argv )
60 {
61  if ( argc < 2 ) {
62 
63  printf ("Usage: %s request_file [log_level [config_file]]\n", argv[0]);
64  exit(1);
65  }
66 
67  // Reconfigure the global logger
68  string log_level("info");
69 
70  if ( argc > 2 ) {
71 
72  log_level.assign( argv[2] );
73  }
74 
75  Log::Level level_code = getLogLevel( log_level );
76  Log::instance()->setLevel( level_code );
77  Log::instance()->setPrefix( "" );
78 
79  if ( argc > 3 ) {
80 
81  Settings::loadConfig( argv[3] );
82  }
83 
84  // Set up any related external resources
86 
87  try {
88 
89  char *request_file = argv[1];
90 
92  OpenModeller om;
93  Log::instance()->info( "openModeller version %s\n", om.getVersion().c_str() );
94 
95  // Configure the OpenModeller object from data read from the
96  // request file.
97  RequestFile request;
98  int resp = request.configure( &om, request_file );
99 
100  if ( resp < 0 ) {
101 
102  Log::instance()->error( "Could not read request file %s", request_file );
103  exit(1);
104  }
105 
106  // If something was not set...
107  if ( resp ) {
108 
109  if ( ! request.occurrencesSet() ) {
110 
111  exit(1);
112  }
113 
114  if ( ! request.algorithmSet() ) {
115 
116  // Find out which model algorithm is to be used.
117  AlgMetadata const **availables = om.availableAlgorithms();
118  AlgMetadata const *metadata;
119 
120  if ( ! (metadata = readAlgorithm( availables )) ) {
121 
122  return 1;
123  }
124 
125  Log::instance()->info( "\n> Algorithm used: %s\n\n", metadata->name.c_str() );
126  Log::instance()->info( " %s\n\n", metadata->overview.c_str() );
127 
128  // For resulting parameters storage.
129  int nparam = metadata->nparam;
130  AlgParameter *param = new AlgParameter[nparam];
131 
132  // Read from console the parameters not set by request
133  // file. Fills 'param' with all 'metadata->nparam'
134  // parameters set.
135  readParameters( param, metadata );
136 
137  // Set the model algorithm to be used by the controller
138  om.setAlgorithm( metadata->id, nparam, param );
139 
140  delete[] param;
141  delete[] availables;
142  }
143  }
144 
145 #ifdef MPI_FOUND
146 
147  Log::instance()->info( "Running the parallel version of the algorithm\n" );
148 
149  MPI_Init( &argc, &argv ); // MPI initialization
150 
151  int rank;
152 
153  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
154 
155 #endif
156 
157  // Run model
159 
160  request.makeModel( &om );
161 
162  if ( request.requestedProjection() ) {
163 
164  // Run projection
166 
167  try {
168 
169  request.makeProjection( &om );
170  }
171  catch ( ... ) {}
172  }
173  else {
174 
175  Log::instance()->warn( "Skipping projection\n" );
176  }
177 
178  if ( request.calcConfusionMatrix() ) {
179 
180  // Instantiate objects for model statistics
181  const ConfusionMatrix * const matrix = om.getConfusionMatrix();
182 
183  // Confusion Matrix
184  Log::instance()->info( "\n" );
185  Log::instance()->info( "Model statistics for training data\n" );
186  Log::instance()->info( "Threshold: %7.2f%%\n", matrix->getThreshold() * 100 );
187  Log::instance()->info( "Accuracy: %7.2f%%\n", matrix->getAccuracy() * 100 );
188 
189  int omissions = matrix->getValue(0.0, 1.0);
190  int total = omissions + matrix->getValue(1.0, 1.0);
191 
192  Log::instance()->info( "Omission error: %7.2f%% (%d/%d)\n", matrix->getOmissionError() * 100, omissions, total );
193 
194  double commissionError = matrix->getCommissionError();
195 
196  if ( commissionError >= 0.0 ) {
197 
198  int commissions = matrix->getValue(1.0, 0.0);
199  total = commissions + matrix->getValue(0.0, 0.0);
200 
201  Log::instance()->info( "Commission error: %7.2f%% (%d/%d)\n", commissionError * 100, commissions, total );
202  }
203 
204  ConfusionMatrix auxMatrix;
205  auxMatrix.setLowestTrainingThreshold( om.getModel(), om.getSampler() );
206  Log::instance()->info( "Lowest prediction: %7.2f\n", auxMatrix.getThreshold() );
207  }
208 
209  if ( request.calcAuc() ) {
210 
211  RocCurve * const roc_curve = om.getRocCurve();
212 
213  // ROC curve
214  Log::instance()->info( "AUC: %7.2f\n", roc_curve->getTotalArea() );
215  }
216 
217  // Projection statistics
218  if ( request.requestedProjection() ) {
219 
220  Log::instance()->info( "\n" );
221  Log::instance()->info( "Projection statistics\n" );
222 
223  AreaStats * stats = om.getActualAreaStats();
224 
225  Log::instance()->info( "Threshold: 50%%\n" );
226  Log::instance()->info( "Cells predicted present: %7.2f%%\n",
227  stats->getAreaPredictedPresent() / (double) stats->getTotalArea() * 100 );
228  Log::instance()->info( "Total number of cells: %d\n", stats->getTotalArea() );
229  Log::instance()->info( "Done.\n" );
230 
231  delete stats;
232  }
233  }
234  catch ( std::exception& e ) {
235  Log::instance()->info( "Exception occurred: %s", e.what() );
236  }
237  catch ( ... ) {
238  Log::instance()->info( "Unknown error occurred\n" );
239  }
240 
241  #ifdef MPI_FOUND
242  MPI_Finalize();
243  #endif
244 
245  return 0;
246 }
247 
248 
249 /***********************/
250 /*** show algorithms ***/
251 //
252 // Print available algorithms.
253 // Returns the option number associated with 'Quit' that is
254 // equal to the number of algorithms.
255 //
256 int
257 showAlgorithms( AlgMetadata const **availables )
258 {
259  if ( ! *availables )
260  {
261  printf( "Could not find any algorithms.\n" );
262  return 0;
263  }
264 
265  printf( "\nChoose an algorithm between:\n" );
266 
267  int count = 1;
268  AlgMetadata const *metadata;
269  while ( ( metadata = *availables++ ) )
270  {
271  printf( " [%d] %s\n", count++, metadata->name.c_str() );
272  }
273  printf( " [q] Quit\n" );
274  printf( "\n" );
275 
276  return count;
277 }
278 
279 
280 /**********************/
281 /*** read algorithm ***/
282 //
283 // Let the user choose an algorithm and enter its parameters.
284 // Returns the choosed algorithm's metadata.
285 //
286 AlgMetadata const *
287 readAlgorithm( AlgMetadata const **availables )
288 {
289  char buf[128];
290 
291  while ( 1 ) {
292 
293  int quit_option = showAlgorithms( availables );
294  if ( ! quit_option ) {
295  return 0;
296  }
297 
298  int option = -1;
299 
300  printf( "\nOption: " );
301  fgets( buf, 128, stdin );
302 
303  int first_char_ascii = (int)buf[0];
304 
305  // Quit if input is "q" or "Q"
306  if ( first_char_ascii == 113 || first_char_ascii == 81 ) {
307  return 0;
308  }
309 
310  option = atoi( buf );
311 
312  if ( option <= 0 || option >= quit_option ) {
313  return 0;
314  }
315 
316  // An algorithm was choosed.
317  else {
318  return availables[option-1];
319  }
320  }
321 }
322 
323 
324 /***********************/
325 /*** read Parameters ***/
326 int
328 {
329  AlgParamMetadata *param = metadata->param;
330  AlgParamMetadata *end = param + metadata->nparam;
331 
332  // Read from stdin each algorithm parameter.
333  for ( ; param < end; param++, result++ )
334  {
335  // The resulting ID is equal the ID set in algorithm's
336  // metadata.
337  result->setId( param->id );
338 
339  // Informs the parameter's metadata to the user.
340  printf( "\n* Parameter: %s\n\n", param->name.c_str() );
341  printf( " %s\n", param->overview.c_str() );
342 
343  if ( param->type != String ) {
344 
345  if ( param->has_min ) {
346 
347  if ( param->type == Integer ) {
348 
349  printf( "%s >= %d\n", param->name.c_str(), int( param->min_val ) );
350  }
351  else {
352 
353  printf( " %s >= %f\n", param->name.c_str(), param->min_val );
354  }
355  }
356  if ( param->has_max ) {
357 
358  if ( param->type == Integer ) {
359 
360  printf( "%s <= %d\n\n", param->name.c_str(), int( param->max_val ) );
361  }
362  else {
363 
364  printf( " %s <= %f\n\n", param->name.c_str(), param->max_val );
365  }
366  }
367  }
368 
369  printf( "Enter with value [%s]: ", param->typical.c_str() );
370 
371  // Read parameter's value or use the "typical" value
372  // if the user does not enter a new value.
373  char value[64];
374  *value = 0;
375  if ( fgets( value, 64, stdin ) && ( *value >= ' ' ) ) {
376 
377  // Remove line feed to avoid problems with string parameters
378  if ( param->type == String ) {
379 
380  char * pos = strchr( value, '\n' );
381 
382  if ( pos ) {
383 
384  *pos = '\0';
385  }
386  }
387 
388  result->setValue( value );
389  }
390  else {
391 
392  result->setValue( param->typical );
393  }
394  }
395 
396  return metadata->nparam;
397 }
398 
399 
400 /*************************/
401 /*** extract Parameter ***/
408 char *
409 extractParameter( char *id, int nvet, char **vet )
410 {
411  int length = strlen( id );
412  char **end = vet + nvet;
413 
414  while ( vet < end )
415  if ( ! strncmp( id, *vet++, length ) )
416  return *(vet-1) + length;
417 
418  return 0;
419 }
420 
421 
422 /********************/
423 /*** map Callback ***/
427 void
428 modelCallback( float progress, void *extra_param )
429 {
430  Log::instance()->info( "Model creation: %07.4f%%\r", 100 * progress );
431 }
432 
433 
434 /********************/
435 /*** map Callback ***/
439 void
440 mapCallback( float progress, void *extra_param )
441 {
442  Log::instance()->info( "Map creation: %07.4f%%\r", 100 * progress );
443 }
static void loadConfig(const std::string configFile)
Definition: Settings.cpp:100
int configure(OpenModeller *om, char *request_file)
void warn(const char *format,...)
'Warn' level.
Definition: Log.cpp:273
void setPrefix(const char *pref)
Definition: Log.cpp:222
bool calcConfusionMatrix()
Definition: request_file.hh:71
AlgMetadata const * readAlgorithm(AlgMetadata const **availables)
Definition: om_console.cpp:287
int showAlgorithms(AlgMetadata const **availables)
Definition: om_console.cpp:257
AreaStats * getActualAreaStats()
void setModelCallback(ModelCreationCallback func, void *param=0)
double getAccuracy() const
const ConfusionMatrix *const getConfusionMatrix()
void setValue(std::string const val)
Definition: AlgParameter.hh:68
Model getModel() const
static Log * instance()
Returns the instance pointer, creating the object on the first call.
Definition: Log.cpp:45
void setMapCallback(ModelProjectionCallback func, void *param=0)
int getValue(Scalar predictionValue, Scalar actualValue) const
bool calcAuc()
Definition: request_file.hh:72
Log::Level getLogLevel(std::string level)
std::string id
Identifier to be used by programmers.
Definition: AlgMetadata.hh:75
void mapCallback(float progress, void *extra_param)
Definition: om_console.cpp:440
Level
Definition: Log.hh:54
int occurrencesSet()
Definition: request_file.hh:63
void setLevel(Level level)
Definition: Log.hh:107
Scalar max_val
Maximum parameter value.
Definition: AlgMetadata.hh:61
double getCommissionError() const
AlgParamMetadata * param
Definition: AlgMetadata.hh:91
AlgParamDatatype type
Real, Integer, String.
Definition: AlgMetadata.hh:54
void makeModel(OpenModeller *om)
int has_max
Zero if the parameter has no upper limit.
Definition: AlgMetadata.hh:60
Scalar min_val
Minimum parameter value.
Definition: AlgMetadata.hh:59
void error(const char *format,...)
'Error' level.
Definition: Log.cpp:290
std::string name
Name to be shown to end users.
Definition: AlgMetadata.hh:53
char * extractParameter(char *name, int nvet, char **vet)
Definition: om_console.cpp:409
int algorithmSet()
Definition: request_file.hh:66
void setupExternalResources()
Definition: os_specific.cpp:95
std::string typical
Typical parameter value.
Definition: AlgMetadata.hh:62
AlgMetadata const ** availableAlgorithms()
int getTotalArea() const
Definition: AreaStats.hh:82
std::string id
Identifier to be used by programmers.
Definition: AlgMetadata.hh:52
static int searchDefaultDirs()
int nparam
Number of parameters.
Definition: AlgMetadata.hh:89
std::string name
Name to be shown to end users.
Definition: AlgMetadata.hh:76
void setLowestTrainingThreshold(const Model &model, const SamplerPtr &sampler)
int setAlgorithm(std::string const id, int nparam, AlgParameter const *param)
std::string getVersion()
double getOmissionError() const
double getThreshold() const
int has_min
Zero if the parameter has no lower limit.
Definition: AlgMetadata.hh:58
void setId(std::string const id)
Definition: AlgParameter.hh:59
void info(const char *format,...)
'Info' level.
Definition: Log.cpp:256
const SamplerPtr & getSampler() const
bool requestedProjection()
void makeProjection(OpenModeller *om)
RocCurve *const getRocCurve()
void modelCallback(float progress, void *extra_param)
Definition: om_console.cpp:428
int getAreaPredictedPresent() const
Definition: AreaStats.hh:87
double getTotalArea()
Definition: RocCurve.cpp:602
int main(int argc, char **argv)
Definition: om_console.cpp:59
int readParameters(AlgParameter *result, AlgMetadata const *metadata)
Definition: om_console.cpp:327
AlgMetadata metadata
Definition: garp.cpp:134
std::string overview
Short description.
Definition: AlgMetadata.hh:55
std::string overview
Short description.
Definition: AlgMetadata.hh:78