Belle II Software development
minMaxCollector.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <gtest/gtest.h>
10
11#include <tracking/trackFindingVXD/sectorMapTools/MinMaxCollector.h>
12
13#include <TRandom.h>
14// #include <tracking/spacePointCreation/SpacePoint.h>
15// #include <tracking/trackFindingVXD/filterMap/fourHitVariables/DeltaPt.h>
16// #include <tracking/trackFindingVXD/filterMap/fourHitVariables/DeltaDistCircleCenter.h>
17// #include <tracking/trackFindingVXD/filterTools/SelectionVariableHelper.h>
18//
19// #include <tracking/trackFindingVXD/filterMap/filterFramework/Shortcuts.h>
20//
21// #include <vxd/geometry/SensorInfoBase.h>
22//
23// #include <math.h>
24
25
26using namespace std;
27using namespace Belle2;
28
29namespace VXDTFMinMaxCollectorTest {
30
32 class MinMaxCollectorTest : public ::testing::Test {
33 protected:
34 };
35
36
38 TEST_F(MinMaxCollectorTest, CheckUserHandling)
39 {
40 // only requests for quantiles 0-0.5 are allowed, for quantile cut q, MinMaxCollector collects quantile-ranges 0 - q & (1-q) - 1.
41 EXPECT_ANY_THROW(MinMaxCollector<double>(0.55));
42 EXPECT_ANY_THROW(MinMaxCollector<double>(-0.1));
43 EXPECT_ANY_THROW(MinMaxCollector<double>(42.));
44
45 double quantileCut = 0.025;
46 auto newCollector = MinMaxCollector<double>(0.025);
47
48 // request for quantiles in empty container:
49 EXPECT_ANY_THROW(newCollector.getMinMax(0., 1.));
50
51 for (unsigned i = 1 ; i < 501 ; i++) { // fill up to 500
52 newCollector.append(gRandom->Uniform(1.));
53 }
54
55 EXPECT_ANY_THROW(newCollector.getMinMax(quantileCut + 0.1, 1.)); // first breaks, second is okay
56 EXPECT_ANY_THROW(newCollector.getMinMax(0.1, 1. + quantileCut)); // first is okay, second is not
57
58 }
59
60
61
63 TEST_F(MinMaxCollectorTest, SomeBasicFillingAndTesting)
64 {
65 auto newCollector = MinMaxCollector<double>();
66
67
68 EXPECT_EQ(0, newCollector.size());
69 EXPECT_EQ(0, newCollector.totalSize());
70 EXPECT_EQ(0, newCollector.sampleSize());
71 EXPECT_TRUE(newCollector.empty());
72
73 B2INFO("add first entry");
74 newCollector.append(42.);
75 newCollector.print();
76
77 EXPECT_EQ(1, newCollector.size());
78 EXPECT_EQ(2, newCollector.totalSize());
79 EXPECT_EQ(1, newCollector.sampleSize());
80 EXPECT_FALSE(newCollector.empty());
81
82 EXPECT_EQ(42., newCollector.getMinMax(0.01, 0.99).first);
83 EXPECT_EQ(42., newCollector.getMinMax(0.01, 0.99).second);
84
85 B2INFO("add 2nd entry");
86 newCollector.append(23.);
87 newCollector.print();
88
89 EXPECT_EQ(2, newCollector.size());
90 EXPECT_EQ(4, newCollector.totalSize()); // did not grow, old value replaced...
91 EXPECT_EQ(2, newCollector.sampleSize());
92 EXPECT_EQ(23., newCollector.getMinMax(0.01, 0.99).first);
93 EXPECT_EQ(42., newCollector.getMinMax(0.01, 0.99).second);
94
95 B2INFO("add 3rd entry");
96 newCollector.append(5.);
97 newCollector.print();
98
99 EXPECT_EQ(3, newCollector.size());
100 EXPECT_EQ(6, newCollector.totalSize()); // did not grow, old value replaced...
101 EXPECT_EQ(3, newCollector.sampleSize());
102 EXPECT_EQ(5., newCollector.getMinMax(0.01, 0.99).first);
103 EXPECT_EQ(42., newCollector.getMinMax(0.01, 0.99).second);
104
105 B2INFO("add 47 more entries (sorted add, now 50)");
106 for (int i = 1; i < 48; i++) {
107 newCollector.append(5. + 0.25 * double(i));
108 }
109 newCollector.print();
110
111 EXPECT_EQ(9, newCollector.size());
112 EXPECT_EQ(18, newCollector.totalSize()); // did not grow, old value replaced...
113 EXPECT_EQ(50, newCollector.sampleSize());
114 EXPECT_EQ(5., newCollector.getMinMax(0.009, 0.991).first);
115 EXPECT_EQ(42., newCollector.getMinMax(0.009, 0.991).second);
116 EXPECT_EQ(5.25, newCollector.getMinMax(0.02, 0.98).first);
117 EXPECT_EQ(23., newCollector.getMinMax(0.02, 0.98).second);
118 EXPECT_NE(16.75, newCollector.getMinMax(0.02, 0.98).second);
119
120 B2INFO("add 50 more entries (sorted add, now 100)");
121 for (int i = 1; i < 51; i++) {
122 newCollector.append(23. + 0.25 * double(i));
123 }
124 B2INFO("add 150 more entries (sorted add, now 250)");
125 for (int i = 1; i < 151; i++) {
126 newCollector.append(3. + 0.3 * double(i));
127 }
128 newCollector.print(true);
129 newCollector.print();
130
131 EXPECT_EQ(10, newCollector.size());
132 EXPECT_EQ(unsigned(newCollector.size() * 2), newCollector.totalSize());
133 EXPECT_EQ(250, newCollector.sampleSize());
134 EXPECT_EQ(3.3, newCollector.getMinMax(0., 1.).first);
135 // worst case: through sorted adding, some of the lower quantiles are lost
136 EXPECT_EQ(3.9, newCollector.getMinMax(0.009, 0.99).first);
137 EXPECT_NE(3.9, newCollector.getMinMax(0.01, 0.99).first);
138 EXPECT_NE(4.5, newCollector.getMinMax(0.02, 0.98).first);
139 EXPECT_EQ(48., newCollector.getMinMax(0., 1.).second);
140 EXPECT_EQ(47.4, newCollector.getMinMax(0.01, 0.991).second);
141 EXPECT_EQ(46.5, newCollector.getMinMax(0.02, 0.98).second);
142 }
143
144
145
147 TEST_F(MinMaxCollectorTest, ComparisonWithClassicApproach)
148 {
149 auto newCollector = MinMaxCollector<double>(0.03);
150
151 auto vectorCollector = std::vector<double>();
152 unsigned vecSize = vectorCollector.size();
153
155 auto getIndex = [&](double quantile) -> unsigned int { return (double(vecSize - 1) * quantile + 0.5); };
156
157
158 EXPECT_EQ(0, newCollector.size());
159 EXPECT_EQ(0, newCollector.totalSize());
160 EXPECT_EQ(0, newCollector.sampleSize());
161 EXPECT_TRUE(newCollector.empty());
162
163
164 for (unsigned i = 1 ; i < 51 ; i++) { // fill up to 50
165 double val = gRandom->Uniform(1.);
166 newCollector.append(val);
167 vectorCollector.push_back(val);
168 }
169
170 newCollector.print();
171
172 std::sort(vectorCollector.begin(), vectorCollector.end());
173 vecSize = vectorCollector.size();
174
175 EXPECT_EQ(vectorCollector.size(), newCollector.sampleSize());
176 EXPECT_EQ(vectorCollector.front(), newCollector.getMinMax(0., 1.).first);
177 EXPECT_EQ(vectorCollector.back(), newCollector.getMinMax(0., 1.).second);
178 EXPECT_EQ(vectorCollector.at(1), newCollector.getMinMax(0.011, 0.989).first);
179 EXPECT_EQ(vectorCollector.at(vecSize - 2), newCollector.getMinMax(0.011, 0.989).second);
180
181
182
183 for (unsigned i = 1 ; i < 151 ; i++) { // fill up to 200
184 double val = gRandom->Uniform(1.);
185 newCollector.append(val);
186 vectorCollector.push_back(val);
187 }
188
189 newCollector.print();
190
191 std::sort(vectorCollector.begin(), vectorCollector.end());
192 vecSize = vectorCollector.size();
193
194 EXPECT_EQ(vectorCollector.size(), newCollector.sampleSize());
195 EXPECT_EQ(vectorCollector.front(), newCollector.getMinMax(0., 1.).first);
196 EXPECT_EQ(vectorCollector.back(), newCollector.getMinMax(0., 1.).second);
197 EXPECT_EQ(vectorCollector.at(2), newCollector.getMinMax(0.011, 0.989).first);
198 EXPECT_EQ(vectorCollector.at(vecSize - 3), newCollector.getMinMax(0.011, 0.989).second);
199 EXPECT_EQ(vectorCollector.at(4), newCollector.getMinMax(0.022, 0.978).first);
200 EXPECT_EQ(vectorCollector.at(vecSize - 5), newCollector.getMinMax(0.022, 0.978).second);
201
202
203
204 for (unsigned i = 1 ; i < 801 ; i++) { // fill up to 1000
205 double val = gRandom->Uniform(1.);
206 newCollector.append(val);
207 vectorCollector.push_back(val);
208 }
209
210 newCollector.print(true);
211 newCollector.print();
212
213 std::sort(vectorCollector.begin(), vectorCollector.end());
214 vecSize = vectorCollector.size();
215
216 EXPECT_EQ(vectorCollector.size(), newCollector.sampleSize());
217 EXPECT_EQ(vectorCollector.front(), newCollector.getMinMax(0., 1.).first);
218 EXPECT_EQ(vectorCollector.back(), newCollector.getMinMax(0., 1.).second);
219 EXPECT_EQ(vectorCollector.at(getIndex(0.01)), newCollector.getMinMax(0.01, 0.99).first);
220 EXPECT_EQ(vectorCollector.at(getIndex(0.99)), newCollector.getMinMax(0.01, 0.99).second);
221 EXPECT_NEAR(vectorCollector.at(getIndex(0.022)), newCollector.getMinMax(0.022, 0.978).first,
222 0.001); // requested quantile is near the threshold, therefore no exact results quaranteed
223 EXPECT_EQ(vectorCollector.at(getIndex(0.978)), newCollector.getMinMax(0.022, 0.978).second);
224
225
226
227 for (unsigned i = 1 ; i < 9001 ; i++) { // fill up to 10000
228 double val = gRandom->Uniform(1.);
229 newCollector.append(val);
230 vectorCollector.push_back(val);
231 }
232
233 newCollector.print();
234
235 std::sort(vectorCollector.begin(), vectorCollector.end());
236 vecSize = vectorCollector.size();
237
238 EXPECT_EQ(vectorCollector.size(), newCollector.sampleSize());
239 EXPECT_EQ(vectorCollector.front(), newCollector.getMinMax(0., 1.).first);
240 EXPECT_EQ(vectorCollector.back(), newCollector.getMinMax(0., 1.).second);
241 EXPECT_EQ(vectorCollector.at(getIndex(0.01)), newCollector.getMinMax(0.01, 0.99).first);
242 EXPECT_EQ(vectorCollector.at(getIndex(0.99)), newCollector.getMinMax(0.01, 0.99).second);
243 EXPECT_NEAR(vectorCollector.at(getIndex(0.022)), newCollector.getMinMax(0.022, 0.978).first, 0.001);
244 EXPECT_EQ(vectorCollector.at(getIndex(0.978)), newCollector.getMinMax(0.022, 0.978).second);
245
246
247
248 // starting now a second collector to be merged afterwards:
249 auto secondCollector = MinMaxCollector<double>();
250 for (unsigned i = 1 ; i < 10001 ; i++) { // fill up to 10000
251 double val = gRandom->Uniform(1.);
252 secondCollector.append(val);
253 vectorCollector.push_back(val);
254 }
255 newCollector.merge(secondCollector);
256
257 std::sort(vectorCollector.begin(), vectorCollector.end());
258 vecSize = vectorCollector.size();
259
260 EXPECT_EQ(vectorCollector.size(), newCollector.sampleSize());
261 EXPECT_EQ(vectorCollector.front(), newCollector.getMinMax(0., 1.).first);
262 EXPECT_EQ(vectorCollector.back(), newCollector.getMinMax(0., 1.).second);
263 EXPECT_EQ(vectorCollector.at(getIndex(0.01)), newCollector.getMinMax(0.01, 0.99).first);
264 EXPECT_EQ(vectorCollector.at(getIndex(0.99)), newCollector.getMinMax(0.01, 0.99).second);
265 EXPECT_EQ(vectorCollector.at(getIndex(0.022)), newCollector.getMinMax(0.022, 0.978).first);
266 EXPECT_NEAR(vectorCollector.at(getIndex(0.978)), newCollector.getMinMax(0.022, 0.978).second, 0.0005);
267
268
269
270 for (unsigned i = 1 ; i < 30001 ; i++) { // fill up to 50,000
271 double val = gRandom->Uniform(1.);
272 newCollector.append(val);
273 vectorCollector.push_back(val);
274 }
275
276 newCollector.print();
277
278 std::sort(vectorCollector.begin(), vectorCollector.end());
279 vecSize = vectorCollector.size();
280
281 EXPECT_EQ(vectorCollector.size(), newCollector.sampleSize());
282 EXPECT_EQ(vectorCollector.front(), newCollector.getMinMax(0., 1.).first);
283 EXPECT_EQ(vectorCollector.back(), newCollector.getMinMax(0., 1.).second);
284 EXPECT_EQ(vectorCollector.at(getIndex(0.01)), newCollector.getMinMax(0.01, 0.99).first);
285 EXPECT_EQ(vectorCollector.at(getIndex(0.99)), newCollector.getMinMax(0.01, 0.99).second);
286 EXPECT_EQ(vectorCollector.at(getIndex(0.022)), newCollector.getMinMax(0.022, 0.978).first);
287 EXPECT_NEAR(vectorCollector.at(getIndex(0.978)), newCollector.getMinMax(0.022, 0.978).second, 0.0001);
288 }
289}
290
A container for collecting data, where min- and max-quantiles near q(0) and q(1) are to be found.
Test class for these new and shiny two-hit-filters.
Abstract base class for different kinds of events.
STL namespace.