DGtalTools  0.9.4
statisticsEstimators.cpp
1 
30 #include <iostream>
32 #include <fstream>
33 #include <sstream>
34 #include <string>
35 #include <cmath>
36 #include <math.h>
37 #include <limits>
38 #include <boost/foreach.hpp>
39 #include <boost/tokenizer.hpp>
40 #include <boost/program_options/options_description.hpp>
41 #include <boost/program_options/parsers.hpp>
42 #include <boost/program_options/variables_map.hpp>
43 
44 #include "DGtal/base/Common.h"
45 
46 using namespace DGtal;
47 
48 
101 bool LoadingStringFromFile( std::ifstream & file, std::string & value )
102 {
103  if( file.good() )
104  {
105  std::getline( file, value );
106  return true;
107  }
108  return false;
109 }
110 
118 void split( const std::string & s, char delim, std::vector< std::string > & elems )
119 {
120  std::stringstream ss( s );
121  std::string item;
122  while( std::getline( ss, item, delim ))
123  {
124  elems.push_back( item );
125  }
126 }
127 
138 int ComputeStatistics ( const std::string & inputdata1,
139  const std::string & inputdata2,
140  const unsigned int & idColumnData1,
141  const unsigned int & idColumnData2,
142  const bool & isMongeMean,
143  std::ofstream & output )
144 {
145  std::ifstream file1( inputdata1.c_str() );
146  std::ifstream file2( inputdata2.c_str() );
147 
148  double absd1d2;
149  double L1 = 0.0;
150  double L2 = 0.0;
151  double Linf = 0.0;
152 
153  std::string s1, s2;
154  double v1, v2;
155  double h = - std::numeric_limits<double>::max();
156 
157  unsigned int nb_elements = 0;
158  bool finish = false;
159  while(( LoadingStringFromFile( file1, s1 ) && LoadingStringFromFile( file2, s2 )) && !finish )
160  {
161  while ( s1[ 0 ] == '#' )
162  {
163  std::size_t p = s1.find( "# h = " );
164  if ( p != std::string::npos )
165  {
166  h = atof((s1.erase( p, 5 )).c_str());
167  }
168  if( ! LoadingStringFromFile( file1, s1 ) )
169  {
170  s1 = "NA";
171  finish = true;
172  }
173  }
174 
175  while ( s2[ 0 ] == '#' )
176  {
177  if( ! LoadingStringFromFile( file2, s2 ) )
178  {
179  s2 = "NA";
180  finish = true;
181  }
182  }
183 
184  if ( s1 == "NA" || s1 == "-nan" || s1 == "-inf" || s1 == "inf" || s1 == "" || s1 == " " )
185  continue;
186  if ( s2 == "NA" || s2 == "-nan" || s2 == "-inf" || s2 == "inf" || s2 == "" || s2 == " " )
187  continue;
188 
189  std::vector< std::string > elems1;
190  split( s1, ' ', elems1 );
191  std::vector< std::string > elems2;
192  split( s2, ' ', elems2 );
193 
194  if( elems1.size() <= idColumnData1 )
195  {
196  std::cerr << "Can't found " << idColumnData1 << " column on file1 (" << inputdata1 << "). Is the file/column exist ?" << std::endl;
197  continue;
198  }
199  if( elems2.size() <= idColumnData2 )
200  {
201  std::cerr << "Can't found " << idColumnData2 << " column on file2 (" << inputdata2 << "). Is the file/column exist ?" << std::endl;
202  continue;
203  }
204 
205  v1 = atof( elems1[ idColumnData1 ].c_str() );
206  v2 = atof( elems2[ idColumnData2 ].c_str() );
207 
208  if( isMongeMean && (( v1 >= 0.0 ) ^ ( v2 >= 0.0 ))) // hack for Monge. Can be reversed.
209  {
210  v2 = -v2;
211  }
212 
213  absd1d2 = std::abs ( v1 - v2 );
214  if ( Linf < absd1d2 )
215  {
216  Linf = absd1d2;
217  }
218  L1 += absd1d2;
219  L2 += absd1d2 * absd1d2;
220 
221  ++nb_elements;
222  }
223 
224  if( h == - std::numeric_limits<double>::max())
225  {
226  std::cerr << "Can't found h value on file1 (" << inputdata1 << "). Is the file exist ?" << std::endl;
227  return 0;
228  }
229 
230  double meanL1 = L1 / (double)nb_elements;
231  double meanL2 = ( sqrt ( L2 )) / (double)nb_elements;
232 
233  output << h << " "
234  << meanL1 << " "
235  << meanL2 << " "
236  << Linf
237  << std::endl;
238 
239  return 1;
240 }
241 
247 void missingParam( std::string param )
248 {
249  trace.error() << " Parameter: " << param << " is required.";
250  trace.info() << std::endl;
251  exit( 1 );
252 }
253 
254 namespace po = boost::program_options;
255 
256 int main( int argc, char** argv )
257 {
258  po::options_description general_opt("Allowed options are");
259  general_opt.add_options()
260  ("help,h", "display this message")
261  ("file1,f", po::value< std::string >(), "File 1")
262  ("file2,F", po::value< std::string >(), "File 2")
263  ("column1,c", po::value< unsigned int >(), "Column of file 1" )
264  ("column2,C", po::value< unsigned int >(), "Column of file 2" )
265  ("output,o", po::value< std::string >(), "Output file")
266  ("monge,m", po::value< bool >()->default_value( false ), "Is from Monge mean computation (optional)" );
267 
268 
269  bool parseOK = true;
270  po::variables_map vm;
271  try
272  {
273  po::store( po::parse_command_line( argc, argv, general_opt ), vm );
274  }
275  catch( const std::exception & ex )
276  {
277  parseOK = false;
278  trace.info() << "Error checking program options: " << ex.what() << std::endl;
279  }
280  po::notify( vm );
281  if( !parseOK || vm.count("help") || argc <= 1 )
282  {
283  trace.info()<< "Compute satistics (L1, L2, Loo) from results of two estimators" <<std::endl
284  << "Basic usage: "<<std::endl
285  << "\tstatisticsEstimators --file1 <file1> --column1 <column1> --file2 <file2> --column2 <column2> --output <output>"<<std::endl
286  << std::endl
287  << general_opt << std::endl;
288 
289  return 0;
290  }
291 
292 
293  if (!(vm.count("file1"))) missingParam("--file1");
294  if (!(vm.count("file2"))) missingParam("--file2");
295  if (!(vm.count("column1"))) missingParam("--column1");
296  if (!(vm.count("column2"))) missingParam("--column2");
297  if (!(vm.count("output"))) missingParam("--output");
298 
299  std::string filename1 = vm["file1"].as< std::string >();
300  std::string filename2 = vm["file2"].as< std::string >();
301  unsigned int column1 = vm["column1"].as< unsigned int >();
302  unsigned int column2 = vm["column2"].as< unsigned int >();
303  std::string output_filename = vm["output"].as< std::string >();
304  bool isMongeMean = vm["monge"].as< bool >();
305 
306  std::ifstream inFileEmptyTest; inFileEmptyTest.open(output_filename.c_str());
307  bool isNew = inFileEmptyTest.peek() == std::ifstream::traits_type::eof(); inFileEmptyTest.close();
308  std::ofstream file( output_filename.c_str(), std::ofstream::out | std::ofstream::app );
309 
310  if( isNew )
311  {
312  file << "# h | "
313  << "L1 Mean Error | "
314  << "L2 Mean Error | "
315  << "Loo Mean Error"
316  << std::endl;
317  }
318 
319  if ( ComputeStatistics( filename1, filename2, column1, column2, isMongeMean, file ) == 0 )
320  {
321  file.close();
322  return -1;
323  }
324 
325  file.close();
326  return 1;
327 }
Trace trace(traceWriterTerm)
std::ostream & info()
std::ostream & error()