Elaboradar  0.1
 Tutto Classi Namespace File Funzioni Variabili Tipi enumerati (enum) Gruppi
test-utils.h
1 #ifndef ARCHIVIATORE_TEST_UTILS_CLASS_H
2 #define ARCHIVIATORE_TEST_UTILS_CLASS_H
3 
4 #include <radarelab/utils/tests.h>
5 #include <radarelab/volume.h>
6 
7 namespace elaboradar {
8 struct Cart;
9 struct CartLowris;
10 struct CartProducts;
11 struct CUM_BAC;
12 }
13 
14 namespace testradar {
15 
16 template<typename T>
17 struct ArrayStats
18 {
19  bool all_missing = true;
20  T min = 0;
21  T max = 0;
22  double sum = 0;
23  unsigned count_missing = 0;
24  unsigned count_values = 0;
25 
26  ArrayStats() {}
27 
28  double avg() const { return count_values ? sum / count_values : min; }
29 
30  void count_sample(const T& sample)
31  {
32  if (all_missing)
33  {
34  min = sample;
35  max = sample;
36  all_missing = false;
37  }
38  else
39  {
40  if (sample < min)
41  min = sample;
42  if (sample > max)
43  max = sample;
44  }
45  sum += (double)sample;
46  ++count_values;
47  }
48 
49  void count_sample(const T& missing, const T& sample)
50  {
51  if (sample == missing)
52  ++count_missing;
53  else
54  count_sample(sample);
55  }
56 
57 
58  void fill(const T* arr, unsigned size)
59  {
60  for (unsigned i = 0; i < size; ++i)
61  this->count_sample(arr[i]);
62  }
63 
64  void fill(const radarelab::Matrix2D<T>& arr)
65  {
66  this->fill(arr.data(), arr.size());
67  }
68 
69  void fill(const radarelab::Volume<T>& vol)
70  {
71  for (unsigned i = 0; i < vol.size(); ++i)
72  this->fill(vol.scan(i));
73  }
74 
75 
76  void fill(const T& missing, const T* arr, unsigned size)
77  {
78  for (unsigned i = 0; i < size; ++i)
79  this->count_sample(missing, arr[i]);
80  }
81 
82  void fill(const T& missing, const radarelab::Matrix2D<T>& arr)
83  {
84  this->fill(missing, arr.data(), arr.size());
85  }
86 
87  void fill(const T& missing, const radarelab::Volume<T>& vol)
88  {
89  for (unsigned i = 0; i < vol.size(); ++i)
90  this->fill(missing, vol.scan(i));
91  }
92 
93 
94  void print()
95  {
96 // fprintf(stderr, "min %f max %f avg %f, zeros: %u, ones: %u\n",
97 // (double)this->min, (double)this->max, this->avg(),
98 // this->count_zeros, this->count_ones);
99  fprintf(stderr, "min %f max %f \n",(double)this->min, (double)this->max);
100  }
101 };
102 
103 template<typename T> inline T to_num(const T& val) { return val; }
104 inline std::string to_num(const double& val)
105 {
106  char buf[30];
107  snprintf(buf, 30, "%.2f", val);
108  return buf;
109 }
110 inline float to_num(const float& val) { return round(val * 100.0) / 100.0; }
111 inline unsigned to_num(const unsigned char& val) { return val; }
112 inline int to_num(const char& val) { return val; }
113 
114 template<typename T> inline bool approx_equals(const T& v1, const T& v2) { return v1 == v2; }
115 inline bool approx_equals(const double& v1, const double& v2) { return round(v1 * 100) == round(v2 * 100); }
116 inline bool approx_equals(const float& v1, const float& v2) { return roundf(v1 * 100) == roundf(v2 * 100); }
117 
118 template<typename DATA>
119 struct TestStatsEqual
120 {
121  typedef typename DATA::Scalar Scalar;
122  const DATA& matrix;
123  bool has_missing = false;
124  Scalar missing;
125  unsigned count_missing = 0;
126  Scalar min;
127  double avg;
128  Scalar max;
129 
130  TestStatsEqual(const DATA& actual, Scalar min, double avg, Scalar max)
131  : matrix(actual), min(min), avg(avg), max(max)
132  {
133  }
134 
135  TestStatsEqual(const DATA& actual, Scalar missing, unsigned count_missing, Scalar min, double avg, Scalar max)
136  : matrix(actual), has_missing(true), missing(missing), count_missing(count_missing), min(min), avg(avg), max(max)
137  {
138  }
139 
140  void check() const
141  {
142  using namespace radarelab::utils::tests;
143  using namespace std;
144  ArrayStats<Scalar> stats;
145  bool failed = false;
146  if (has_missing)
147  {
148  stats.fill(missing, matrix);
149  if (stats.count_missing != count_missing)
150  failed = true;
151  } else
152  stats.fill(matrix);
153  if (!approx_equals(stats.min, min)) failed = true;
154  if (!approx_equals(stats.max, max)) failed = true;
155  if (!approx_equals(stats.avg(), avg)) failed = true;
156 
157  if (failed)
158  {
159  std::stringstream ss;
160  ss << "stats (";
161  if (has_missing)
162  ss << "missing: " << stats.count_missing << " ";
163  ss << "min: " << to_num(stats.min)
164  << " avg: " << to_num(stats.avg())
165  << " max: " << to_num(stats.max)
166  << ") differ from expected (";
167  if (has_missing)
168  ss << "missing: " << count_missing << " ";
169  ss << "min: " << to_num(min)
170  << " avg: " << to_num(avg)
171  << " max: " << to_num(max)
172  << ")";
173  throw TestFailed(ss.str());
174  }
175  }
176 };
177 
178 template<typename T>
179 struct ActualMatrix2D : public radarelab::utils::tests::Actual<const radarelab::Matrix2D<T>&>
180 {
181  using radarelab::utils::tests::Actual<const radarelab::Matrix2D<T>&>::Actual;
182 
183  template<typename... args>
184  TestStatsEqual<radarelab::Matrix2D<T>> statsEqual(args&&... params) const
185  {
186  return TestStatsEqual<radarelab::Matrix2D<T>>(this->_actual, params...);
187  }
188 };
189 
190 template<typename T>
191 struct ActualVolume : public radarelab::utils::tests::Actual<const radarelab::Volume<T>&>
192 {
193  using radarelab::utils::tests::Actual<const radarelab::Volume<T>&>::Actual;
194 
195  template<typename... args>
196  TestStatsEqual<radarelab::Volume<T>> statsEqual(args&&... params) const
197  {
198  return TestStatsEqual<radarelab::Volume<T>>(this->_actual, params...);
199  }
200 };
201 
202 template<typename T>
203 inline ActualMatrix2D<T> actual(const radarelab::Matrix2D<T>& actual) { return ActualMatrix2D<T>(actual); }
204 
205 template<typename T>
206 inline ActualMatrix2D<T> actual(const radarelab::PolarScan<T>& actual) { return ActualMatrix2D<T>(actual); }
207 
208 template<typename T>
209 inline ActualMatrix2D<T> actual(const radarelab::Image<T>& actual) { return ActualMatrix2D<T>(actual); }
210 
211 template<typename T>
212 inline ActualVolume<T> actual(const radarelab::Volume<T>& actual) { return ActualVolume<T>(actual); }
213 
214 template<typename DATA>
215 void print_stats(const std::string& name, const DATA& data, const typename DATA::Scalar& missing, std::ostream& out)
216 {
217  using namespace std;
218  ArrayStats<typename DATA::Scalar> stats;
219  stats.fill(missing, data);
220  out << "wassert(actual(" << name << ").statsEqual"
221  << "(" << to_num(missing)
222  << ", " << stats.count_missing
223  << ", " << to_num(stats.min)
224  << ", " << to_num(stats.avg())
225  << ", " << to_num(stats.max)
226  << "));" << endl;
227 }
228 
229 template<typename DATA>
230 void print_stats(const std::string& name, const DATA& data, std::ostream& out)
231 {
232  using namespace std;
233  ArrayStats<typename DATA::Scalar> stats;
234  stats.fill(data);
235  out << "wassert(actual(" << name << ").statsEqual"
236  << "(" << to_num(stats.min)
237  << ", " << to_num(stats.avg())
238  << ", " << to_num(stats.max)
239  << "));" << endl;
240 }
241 
242 void print_stats(const std::string& name, const elaboradar::CUM_BAC& cb, std::ostream& out);
243 #if 0
244 void print_stats(const std::string& name, const elaboradar::Cart& cart, std::ostream& out);
245 void print_stats(const std::string& name, const elaboradar::CartLowris& cart, std::ostream& out);
246 void print_stats(const std::string& name, const elaboradar::CartProducts& cart, std::ostream& out);
247 #endif
248 
249 }
250 
251 #endif
PolarScan< T > & scan(unsigned idx)
Access a polar scan.
Definition: volume.h:298
Definisce le principali strutture che contengono i dati.
PolarScan - structure to describe a polarScan containing a matrix of data and conversion factors...
Definition: volume.h:112
Base for all matrices we use, since we rely on row-major data.
Definition: matrix.h:36
Classe principale del programma.
Definition: cum_bac.h:61
Homogeneous volume with a common beam count for all PolarScans.
Definition: volume.h:415
Exception thrown when a test assertion fails, normally by Location::fail_test.
Definition: tests.h:105