IODA Bundle
Comparator.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 1996-2012 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 #ifndef Comparator_H
12 #define Comparator_H
13 
14 #include <cmath>
15 #include <vector>
16 #include <set>
17 
18 #include "eckit/exception/Exceptions.h"
19 #include "eckit/log/Log.h"
20 
21 namespace eckit {
22  class PathName;
23  class DataHandle;
24 }
25 
26 namespace odc {
27 
28 namespace core {
29  class MetaData;
30  class Column;
31 }
32 
33 const double maxAbsoluteError = 1e-9;
34 const double maxRelativeError = 1e-9;
35 
36 
37 class Comparator {
38 public:
39  Comparator(bool checkMissingFlag = true);
40 
41  void operator()() { run(); }
42  void run();
43 
44  template <typename T1, typename T2>
45  bool compare(T1& it1, const T1& end1,
46  T2& it2, const T2& end2,
47  const std::string& desc1, const std::string& desc2);
48 
49  template <typename T1, typename T2>
50  bool compare(T1& it1, const T1& end1,
51  T2& it2, const T2& end2,
52  const std::string& desc1, const std::string& desc2,
53  const std::vector<std::string>& excludedColumnsTypes,
54  const std::vector<std::string>& excludedColumns);
55 
56  void compare(eckit::DataHandle&, eckit::DataHandle&);
57  void compare(const eckit::PathName&, const eckit::PathName&);
58 
59  void compare(const eckit::PathName& pathName1,
60  const eckit::PathName& pathName2,
61  const std::vector<std::string>& excludedColumnsTypes,
62  const std::vector<std::string>& excludedcolumns);
63 
64  void compare(const core::MetaData& metaData1, const core::MetaData& metaData2,
65  const std::set<std::string>& excludedColumnsTypes,
66  const std::set<std::string>& excludedColumns,
67  std::vector<int>& skipCols);
68 
69  void compare(int nCols,
70  const double *data1,
71  const double *data2,
72  const core::MetaData& metaData1,
73  const core::MetaData& metaData2);
74 
75  void compare(int nCols,
76  const double *data1,
77  const double *data2,
78  const core::MetaData& metaData1,
79  const core::MetaData& metaData2,
80  const std::vector<int>& skipCols);
81 
82  void checkMissingFlag(bool v) { checkMissingFlag_ = v; }
83 
84  inline static double err(double A, double B)
85  {
86  double relativeError;
87 
88  if(fabs(A) <= maxAbsoluteError || fabs(B) <= maxAbsoluteError)
89  relativeError = fabs(A-B);
90  else if (fabs(B) > fabs(A))
91  relativeError = fabs((A - B) / B);
92  else
93  relativeError = fabs((A - B) / A);
94  return relativeError;
95  }
96 
97  inline static int same(double A,double B) { return err(A,B) < maxRelativeError; }
98 
99  void raiseNotEqual(const core::Column&, double, double);
100 
101 private:
102  long nRow_;
104  bool NaN_isOK_;
105 };
106 
107 template<typename T1, typename T2>
108 bool Comparator::compare(T1& it1, const T1& end1, T2& it2, const T2& end2, const std::string& desc1, const std::string& desc2)
109 {
110  std::vector<std::string> noExcludedColumnsTypes;
111  std::vector<std::string> noExcludedColumns;
112  return compare(it1, end1, it2, end2, desc1, desc2, noExcludedColumnsTypes, noExcludedColumns);
113 }
114 
115 template<typename T1, typename T2>
116 bool Comparator::compare(T1& it1, const T1& end1,
117  T2& it2, const T2& end2,
118  const std::string& desc1, const std::string& desc2,
119  const std::vector<std::string>& excludedColumnsTypes,
120  const std::vector<std::string>& excludedColumns)
121 {
122  eckit::Log::info() << "Comparator::compare: (1) " << desc1 << " to (2) " << desc2 << std::endl;
123 
124  nRow_ = 0;
125 
126  // The columns to skip are filled in by the column comparator function
127  std::vector<int> skipCols;
128 
129  // Convert the excluded columns/types into sets, for more efficient lookups
130  std::set<std::string> excludedColumnsTypesSet(excludedColumnsTypes.begin(), excludedColumnsTypes.end());
131  std::set<std::string> excludedColumnsSet(excludedColumns.begin(), excludedColumns.end());
132 
133  compare(it1->columns(), it2->columns(), excludedColumnsTypesSet, excludedColumnsSet, skipCols);
134 
135  for (; it1 != end1 && it2 != end2; ++it1, ++it2)
136  {
137  ++nRow_;
138 
139  if (it1->isNewDataset())
140  compare(it1->columns(), it2->columns(), excludedColumnsTypesSet, excludedColumnsSet, skipCols);
141  if (it2->isNewDataset())
142  compare(it1->columns(), it2->columns(), excludedColumnsTypesSet, excludedColumnsSet, skipCols);
143 
144  compare(it1->columns().size(), it1->data(), it2->data(), it1->columns(), it2->columns(), skipCols);
145  }
146 
147  ASSERT("First file has more rows!" && ! (it1 != end1));
148  ASSERT("Second file has more rows!" && ! (it2 != end2));
149  return true; // ?
150 }
151 
152 } // namespace odc
153 
154 #endif
void compare(const eckit::PathName &pathName1, const eckit::PathName &pathName2, const std::vector< std::string > &excludedColumnsTypes, const std::vector< std::string > &excludedcolumns)
static double err(double A, double B)
Definition: Comparator.h:84
bool compare(T1 &it1, const T1 &end1, T2 &it2, const T2 &end2, const std::string &desc1, const std::string &desc2)
Definition: Comparator.h:108
void raiseNotEqual(const core::Column &, double, double)
Definition: Comparator.cc:87
static int same(double A, double B)
Definition: Comparator.h:97
Comparator(bool checkMissingFlag=true)
Definition: Comparator.cc:41
void operator()()
Definition: Comparator.h:41
void checkMissingFlag(bool v)
Definition: Comparator.h:82
void compare(const eckit::PathName &, const eckit::PathName &)
bool checkMissingFlag_
Definition: Comparator.h:103
Definition: ColumnInfo.h:23
const double maxRelativeError
Definition: Comparator.h:34
const double maxAbsoluteError
Definition: Comparator.h:33