openModeller  Version 1.5.0
om_sampler.cpp
Go to the documentation of this file.
1 #include <openmodeller/om.hh>
5 
6 #include "request_file.hh"
7 
8 #include "getopts/getopts.h"
9 
10 #include "om_cmd_utils.hh"
11 
12 #include <istream>
13 #include <stdlib.h>
14 #include <string>
15 #include <stdio.h>
16 #include <iostream> // I/O
17 #include <fstream> // file I/O
18 
19 #include <stdexcept>
20 
21 using namespace std;
22 
23 void printOccurrences( ostream & stream, ConstOccurrencesPtr occ );
24 
25 int main( int argc, char **argv ) {
26 
27  Options opts;
28  int option;
29 
30  // command-line parameters (short name, long name, description, take args)
31  opts.addOption( "v", "version" , "Display version info" , false );
32  opts.addOption( "s", "source" , "Source with references to points and layers" , true );
33  opts.addOption( "e", "dump-env" , "Dump environment data for a specified cell range", false );
34  opts.addOption( "" , "cell-start" , "Cell position to start environment dumping (default 0)" , true );
35  opts.addOption( "" , "cell-end" , "Cell position to end environment dumping (default 1000)" , true );
36  opts.addOption( "" , "log-level" , "Set the log level (debug, warn, info, error)", true );
37  opts.addOption( "c", "config-file", "Configuration file for openModeller" , true );
38 
39  std::string log_level("info");
40  std::string source("");
41  bool dump_env = false;
42  std::string start_string("0");
43  std::string end_string("1000");
44  std::string config_file;
45 
46  if ( ! opts.parse( argc, argv ) ) {
47 
48  opts.showHelp( argv[0] );
49  exit(0);
50  }
51 
52  // Set up any related external resources
54 
55  OpenModeller om;
56 
57  while ( ( option = opts.cycle() ) >= 0 ) {
58 
59  switch ( option ) {
60 
61  case 0:
62  printf( "om_sampler %s\n", om.getVersion().c_str() );
63  printf("This is free software; see the source for copying conditions. There is NO\n");
64  printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
65  exit(0);
66  break;
67  case 1:
68  source = opts.getArgs( option );
69  break;
70  case 2:
71  dump_env = true;
72  break;
73  case 3:
74  start_string = opts.getArgs( option );
75  break;
76  case 4:
77  end_string = opts.getArgs( option );
78  break;
79  case 5:
80  log_level = opts.getArgs( option );
81  break;
82  case 6:
83  config_file = opts.getArgs( option );
84  break;
85  default:
86  break;
87  }
88  }
89 
90  // Check requirements
91  if ( source.empty() ) {
92 
93  printf( "Please specify a source (request file in txt or xml) with references to points and layers.\n");
94  exit(-1);
95  }
96 
97  int cell_start = 0;
98  int cell_end = 0;
99 
100  if ( dump_env ) {
101 
102  cell_start = atoi( start_string.c_str() );
103 
104  cell_end = atoi( end_string.c_str() );
105  }
106 
107  // Log stuff
108 
109  Log::Level level_code = getLogLevel( log_level );
110 
111  Log::instance()->setLevel( level_code );
112 
113  // om configuration
114  if ( ! config_file.empty() ) {
115 
116  Settings::loadConfig( config_file );
117  }
118 
119  // Real work
120 
121  try {
122 
123  // Read source
124 
125  bool is_xml = false;
126 
127  // Try to open file and check if first char is "<". In this case we will
128  // assume that it's an XML file.
129  std::ifstream fs( source.c_str(), std::ios_base::in );
130 
131  if ( fs.fail() ) {
132 
133  printf( "Could not open source file.\n");
134  exit(-1);
135  }
136 
137  std::string line("");
138 
139  while ( getline( fs, line ) ) {
140 
141  for ( unsigned int i = 0; i < line.size(); ++i ) {
142 
143  // Skip carriage returns, line feeds and spaces
144  if ( line[i] == '\r' || line[i] == '\n' || line[i] == ' ' ) {
145 
146  continue;
147  }
148 
149  // Looks like an XML file
150  if ( line[i] == '<' ) {
151 
152  is_xml = true;
153  }
154 
155  break;
156  }
157  }
158 
159  fs.close();
160 
161  SamplerPtr sampler;
162 
163  if ( is_xml ) {
164 
165  ConfigurationPtr config = Configuration::readXml( source.c_str() );
166 
167  sampler = createSampler( config->getSubsection( "Sampler" ) );
168  }
169  else {
170 
171  // Must be a txt request file, so parse it
172 
173  FileParser fp( source.c_str() );
174 
175  // Load points
176 
177  // Obtain the Well Known Text string for the localities
178  // coordinate system.
179  std::string oc_cs = fp.get( "WKT coord system" );
180 
181  // Get the name of the file containing localities
182  std::string oc_file = fp.get( "Occurrences source" );
183 
184  // Get the label
185  std::string oc_name = fp.get( "Occurrences group" );
186 
187  // When a model needs to be created, 'WKT coord system' and
188  // 'Species file' are mandatory parameters
189  if ( oc_cs.empty() ) {
190 
191  printf( "'WKT coord system' keyword not specified in the request file!\n" );
192  exit(-1);
193  }
194 
195  if ( oc_file.empty() ) {
196 
197  printf( "'Occurrences source' keyword not specified in the request file!\n" );
198  exit(-1);
199  }
200 
201  // Populate the occurences list from the localities file
202  OccurrencesReader* oc_reader = OccurrencesFactory::instance().create( oc_file.c_str(), oc_cs.c_str() );
203 
204  OccurrencesPtr presences = oc_reader->getPresences( oc_name.c_str() );
205 
206  OccurrencesPtr absences = oc_reader->getAbsences( oc_name.c_str() );
207 
208  delete oc_reader;
209 
210  // Load layers
211 
212  // Mask to select the desired species occurrence points
213  std::string input_mask = fp.get( "Mask" );
214 
215  // Initiate the environment with all maps.
216  std::vector<std::string> categ_map = fp.getAll( "Categorical map" );
217  std::vector<std::string> cont_map = fp.getAll( "Map" );
218 
219  // When a model needs to be created, there should be at least one input map
220  if ( ! (categ_map.size() + cont_map.size()) ) {
221 
222  printf( "At least one 'Map' or 'Categorical map' needs to be specified in the request file!\n" );
223  exit(-1);
224  }
225 
226  // If Mask was not specified, use the first layer
227  if ( input_mask.empty() ) {
228 
229  if ( cont_map.size() ) {
230 
231  input_mask = cont_map[0];
232  }
233  else {
234 
235  input_mask = categ_map[0];
236  }
237  }
238 
239  EnvironmentPtr env = createEnvironment( categ_map, cont_map, input_mask );
240 
241  sampler = createSampler( env, presences, absences );
242 
243  std::string spatially_unique = fp.get( "Spatially unique" );
244  if ( spatially_unique == "true" ) {
245 
246  sampler->spatiallyUnique();
247  }
248 
249  std::string environmentally_unique = fp.get( "Environmentally unique" );
250  if ( environmentally_unique == "true" ) {
251 
252  sampler->environmentallyUnique();
253  }
254  }
255 
256  // Print output
257 
258  int dim = sampler->numIndependent();
259 
260  // Header
261  cout << "#id\tlabel\tlongitude\tlatitude\tabundance";
262 
263  for ( int i = 0; i < dim; ++i ) {
264 
265  cout << "\tattr" << i+1;
266  }
267 
268  if ( dump_env ) {
269 
270  // Dump environment data
271 
272  EnvironmentPtr e = sampler->getEnvironment();
273 
274  // Initialize the iterator
275  MapIterator it = e->getMask()->begin();
276 
277  // Initialize the terminal
278  MapIterator fin;
279 
280  int cnt = 0;
281 
282  while( it != fin ) {
283 
284  if ( cnt < cell_start) {
285 
286  ++it;
287  ++cnt;
288  continue;
289  }
290 
291  // Get the lon/lat coordinates from the iterator
292  pair<Coord,Coord> lonlat = *it;
293 
294  // Extract the environment sample at that point
295  Sample s = e->get( lonlat.first, lonlat.second );
296 
297  cout << "\n" << cnt << "\t" << "env data" << "\t" << lonlat.first << "\t" << lonlat.second << "\t" << "-";
298 
299  // Note: s will have size() == 0 if the environment
300  // does not have data for that location. This can happen
301  // for a couple of reasons.
302  // 1. The location is not in the mask.
303  // 2. One of the layers has value == NoVal at that location.
304  if ( s.size() > 0 ) {
305 
306  for ( int i = 0; i < dim; ++i ) {
307 
308  cout << "\t" << s[i];
309  }
310  }
311  else {
312 
313  cout << "\t" << "nodata";
314  }
315 
316  ++cnt;
317  ++it;
318 
319  if ( cnt > cell_end ) {
320 
321  break;
322  }
323  }
324 
325  return 0;
326  }
327 
328  // Default action: dump locality samples
329 
330  ConstOccurrencesPtr p = sampler->getPresences();
331 
332  if ( p ) {
333 
334  printOccurrences( cout, p );
335  }
336 
337  ConstOccurrencesPtr a = sampler->getAbsences();
338 
339  if ( a ) {
340 
341  printOccurrences( cout, a );
342  }
343 
344  return 0;
345  }
346  catch ( runtime_error e ) {
347 
348  printf( "om_sampler: %s\n", e.what() );
349  exit(-1);
350  }
351 }
352 
353 // Print occurrences
354 void printOccurrences( ostream & stream, ConstOccurrencesPtr occ ) {
355 
356  int dim = occ->dimension();
357 
358  OccurrencesImpl::const_iterator it = occ->begin();
359  OccurrencesImpl::const_iterator fin = occ->end();
360 
361  while ( it != fin ) {
362 
363  stream << "\n" << ((*it)->id()).c_str() << "\t" << occ->label() << "\t" << (*it)->x() << "\t" << (*it)->y() << "\t" << (*it)->abundance();
364 
365  Sample s = (*it)->environment();
366 
367  for ( int i = 0; i < dim; ++i ) {
368 
369  stream << "\t" << s[i];
370  }
371 
372  it++;
373  }
374 }
static void loadConfig(const std::string configFile)
Definition: Settings.cpp:100
static ConfigurationPtr readXml(char const *filename)
static Log * instance()
Returns the instance pointer, creating the object on the first call.
Definition: Log.cpp:45
static OccurrencesFactory & instance()
Log::Level getLogLevel(std::string level)
virtual OccurrencesPtr getAbsences(const char *groupId)
Level
Definition: Log.hh:54
void setLevel(Level level)
Definition: Log.hh:107
EnvironmentPtr createEnvironment(const std::vector< std::string > &categs, const std::vector< std::string > &maps, const std::string &mask_file)
Definition: Environment.cpp:55
SamplerPtr createSampler(const EnvironmentPtr &env, const OccurrencesPtr &presence, const OccurrencesPtr &absence)
Definition: Sampler.cpp:52
int main(int argc, char **argv)
Definition: om_sampler.cpp:25
void setupExternalResources()
Definition: os_specific.cpp:95
virtual OccurrencesPtr getPresences(const char *groupId)
std::size_t size() const
Definition: Sample.hh:70
std::string getVersion()
std::vector< OccurrencePtr >::const_iterator const_iterator
Definition: Occurrences.hh:85
std::string get(const std::string &key) const
Definition: FileParser.cpp:145
void printOccurrences(ostream &stream, ConstOccurrencesPtr occ)
Definition: om_sampler.cpp:354
Definition: Sample.hh:25
OccurrencesReader * create(const char *source, const char *coordSystem)