Elaboradar 0.1
Caricamento in corso...
Ricerca in corso...
Nessun risultato
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
7namespace elaboradar {
8struct Cart;
9struct CartLowris;
10struct CartProducts;
11struct CUM_BAC;
12}
13
14namespace testradar {
15
16template<typename T>
17struct 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
103template<typename T> inline T to_num(const T& val) { return val; }
104inline std::string to_num(const double& val)
105{
106 char buf[30];
107 snprintf(buf, 30, "%.2f", val);
108 return buf;
109}
110inline float to_num(const float& val) { return round(val * 100.0) / 100.0; }
111inline unsigned to_num(const unsigned char& val) { return val; }
112inline int to_num(const char& val) { return val; }
113
114template<typename T> inline bool approx_equals(const T& v1, const T& v2) { return v1 == v2; }
115inline bool approx_equals(const double& v1, const double& v2) { return round(v1 * 100) == round(v2 * 100); }
116inline bool approx_equals(const float& v1, const float& v2) { return roundf(v1 * 100) == roundf(v2 * 100); }
117
118template<typename DATA>
119struct 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
178template<typename T>
179struct 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
190template<typename T>
191struct 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
202template<typename T>
203inline ActualMatrix2D<T> actual(const radarelab::Matrix2D<T>& actual) { return ActualMatrix2D<T>(actual); }
204
205template<typename T>
206inline ActualMatrix2D<T> actual(const radarelab::PolarScan<T>& actual) { return ActualMatrix2D<T>(actual); }
207
208template<typename T>
209inline ActualMatrix2D<T> actual(const radarelab::Image<T>& actual) { return ActualMatrix2D<T>(actual); }
210
211template<typename T>
212inline ActualVolume<T> actual(const radarelab::Volume<T>& actual) { return ActualVolume<T>(actual); }
213
214template<typename DATA>
215void 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
229template<typename DATA>
230void 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
242void print_stats(const std::string& name, const elaboradar::CUM_BAC& cb, std::ostream& out);
243#if 0
244void print_stats(const std::string& name, const elaboradar::Cart& cart, std::ostream& out);
245void print_stats(const std::string& name, const elaboradar::CartLowris& cart, std::ostream& out);
246void print_stats(const std::string& name, const elaboradar::CartProducts& cart, std::ostream& out);
247#endif
248
249}
250
251#endif
Classe principale del programma.
Definition: cum_bac.h:62
PolarScan - structure to describe a polarScan containing a matrix of data and conversion factors.
Definition: volume.h:113
Homogeneous volume with a common beam count for all PolarScans.
Definition: volume.h:431
PolarScan< T > & scan(unsigned idx)
Access a polar scan.
Definition: volume.h:313
name space generale del programma
Definition: assets.h:28
Base for all matrices we use, since we rely on row-major data.
Definition: matrix.h:37
Exception thrown when a test assertion fails, normally by Location::fail_test.
Definition: tests.h:107
Definisce le principali strutture che contengono i dati.