All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BinningSpecs_test.cc
Go to the documentation of this file.
1 /**
2  * @file BinningSpecs_test.cc
3  * @brief Unit test for `icarus::ns::util::BinningSpecs` class and utilities.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date September 21, 2021
6  * @see icarusalg/Utilities/BinningSpecs.h
7  */
8 
9 
10 // Boost libraries
11 #define BOOST_TEST_MODULE BinningSpecs
12 #include <cetlib/quiet_unit_test.hpp> // BOOST_AUTO_TEST_CASE()
13 #include <boost/test/test_tools.hpp> // BOOST_TEST()
14 
15 // ICARUS libraries
17 
18 
19 // -----------------------------------------------------------------------------
21 
23 
24  BOOST_TEST(BinningSpecs::NBinsFor(-5.0, 8.0, 2.0) == 7UL);
25  BOOST_TEST(BinningSpecs::NBinsFor(-5.0, 8.0, 0.1) == 130UL);
26  BOOST_TEST(BinningSpecs::NBinsFor(-5.0, -5.0, 0.1) == 0UL);
27 
28 } // BinningSpecs_test()
29 
30 
32 
35 
36  BinningSpecs const binning { -5.0, 8.0, 2.0 }; // range 13 split into 7 bins
37 
38  BOOST_TEST(binning.lower() == -5.0, 0.001% tolerance());
39  BOOST_TEST(binning.upper() == 9.0, 0.001% tolerance());
40  BOOST_TEST(binning.range() == 14.0, 0.001% tolerance());
41  BOOST_TEST(binning.nBins() == 7UL);
42  BOOST_TEST(binning.binWidth() == 2.0, 0.001% tolerance());
43 
44  BOOST_TEST(binning.binWith( -7.0) == -1);
45  BOOST_TEST(binning.binWith( -6.0) == -1);
46  BOOST_TEST(binning.binWith( -5.0) == 0);
47  BOOST_TEST(binning.binWith( -4.0) == 0);
48  BOOST_TEST(binning.binWith( -3.0) == 1);
49  BOOST_TEST(binning.binWith( -2.0) == 1);
50  BOOST_TEST(binning.binWith( -1.0) == 2);
51  BOOST_TEST(binning.binWith( 0.0) == 2);
52  BOOST_TEST(binning.binWith( +1.0) == 3);
53  BOOST_TEST(binning.binWith( +2.0) == 3);
54  BOOST_TEST(binning.binWith( +3.0) == 4);
55  BOOST_TEST(binning.binWith( +4.0) == 4);
56  BOOST_TEST(binning.binWith( +5.0) == 5);
57  BOOST_TEST(binning.binWith( +6.0) == 5);
58  BOOST_TEST(binning.binWith( +7.0) == 6);
59  BOOST_TEST(binning.binWith( +8.0) == 6);
60  BOOST_TEST(binning.binWith( +9.0) == 7);
61  BOOST_TEST(binning.binWith(+10.0) == 7);
62  BOOST_TEST(binning.binWith(+11.0) == 8);
63  BOOST_TEST(binning.binWith(+12.0) == 8);
64  BOOST_TEST(binning.binWith(+13.0) == 9);
65 
66  BOOST_TEST(binning.binBorders(-1).first == -7.0, 0.001% tolerance());
67  BOOST_TEST(binning.binBorders(-1).second == -5.0, 0.001% tolerance());
68  BOOST_TEST(binning.binBorders( 0).first == -5.0, 0.001% tolerance());
69  BOOST_TEST(binning.binBorders( 0).second == -3.0, 0.001% tolerance());
70  BOOST_TEST(binning.binBorders( 1).first == -3.0, 0.001% tolerance());
71  BOOST_TEST(binning.binBorders( 1).second == -1.0, 0.001% tolerance());
72  BOOST_TEST(binning.binBorders( 2).first == -1.0, 0.001% tolerance());
73  BOOST_TEST(binning.binBorders( 2).second == +1.0, 0.001% tolerance());
74  BOOST_TEST(binning.binBorders( 3).first == +1.0, 0.001% tolerance());
75  BOOST_TEST(binning.binBorders( 3).second == +3.0, 0.001% tolerance());
76  BOOST_TEST(binning.binBorders( 4).first == +3.0, 0.001% tolerance());
77  BOOST_TEST(binning.binBorders( 4).second == +5.0, 0.001% tolerance());
78  BOOST_TEST(binning.binBorders( 5).first == +5.0, 0.001% tolerance());
79  BOOST_TEST(binning.binBorders( 5).second == +7.0, 0.001% tolerance());
80  BOOST_TEST(binning.binBorders( 6).first == +7.0, 0.001% tolerance());
81  BOOST_TEST(binning.binBorders( 6).second == +9.0, 0.001% tolerance());
82  BOOST_TEST(binning.binBorders( 7).first == +9.0, 0.001% tolerance());
83  BOOST_TEST(binning.binBorders( 7).second == +11.0, 0.001% tolerance());
84  BOOST_TEST(binning.binBorders( 8).first == +11.0, 0.001% tolerance());
85  BOOST_TEST(binning.binBorders( 8).second == +13.0, 0.001% tolerance());
86  BOOST_TEST(binning.binBorders( 9).first == +13.0, 0.001% tolerance());
87 
88 } // BinningSpecs_test()
89 
90 
91 // -----------------------------------------------------------------------------
93 
95 
96  auto const binning
98 
99  BOOST_TEST(binning.lower() == -6.0, 0.001% tolerance());
100  BOOST_TEST(binning.upper() == 8.0, 0.001% tolerance());
101  BOOST_TEST(binning.range() == 14.0, 0.001% tolerance());
102  BOOST_TEST(binning.nBins() == 7UL);
103  BOOST_TEST(binning.binWidth() == 2.0, 0.001% tolerance());
104 
105 } // makeBinningFromBinWidth_alignment_test()
106 
107 
109 
111 
112  auto const binning
114 
115  BOOST_TEST(binning.lower() == -6.0, 0.001% tolerance());
116  BOOST_TEST(binning.upper() == 8.0, 0.001% tolerance());
117  BOOST_TEST(binning.range() == 14.0, 0.001% tolerance());
118  BOOST_TEST(binning.nBins() == 7UL);
119  BOOST_TEST(binning.binWidth() == 2.0, 0.001% tolerance());
120 
121 } // makeBinningFromBinWidth_extension_test()
122 
123 
125 
127 
128  // this has bin width order of magnitude 0.1
129  auto const binning
130  = icarus::ns::util::makeBinningFromBinWidth(-1.0, 3.0, 0.25 );
131 
132  BOOST_TEST(binning.lower() == -1.0, 0.001% tolerance());
133  BOOST_TEST(binning.upper() == 3.0, 0.001% tolerance());
134  BOOST_TEST(binning.range() == 4.0, 0.001% tolerance());
135  BOOST_TEST(binning.nBins() == 20UL);
136  BOOST_TEST(binning.binWidth() == 0.2, 0.001% tolerance());
137 
138 } // makeBinningFromBinWidth_defhints_test()
139 
140 
142 
144 
145  // this has bin width order of magnitude 0.1, so hints are 0.3 and 0.4:
146  auto const binning
147  = icarus::ns::util::makeBinningFromBinWidth(-1.0, 3.0, 0.25, { 3, 4 } );
148 
149  BOOST_TEST(binning.lower() == -1.2, 0.001% tolerance());
150  BOOST_TEST(binning.upper() == 3.0, 0.001% tolerance());
151  BOOST_TEST(binning.range() == 4.2, 0.001% tolerance());
152  BOOST_TEST(binning.nBins() == 14UL);
153  BOOST_TEST(binning.binWidth() == 0.3, 0.001% tolerance());
154 
155 } // makeBinningFromBinWidth_hints_test()
156 
157 
159 
161 
162  /*
163  * this has bin width order of magnitude 0.1 (0.1 <= 0.25 < 1.0),
164  * so the hint { 0.1, 0.3 } translates into bin width hints 0.01 and 0.03;
165  * the starting number of bins is 16 (range of 4.0 divided by 0.25).
166  * So the candidate ranges are 0.16 and 0.48, with stretch factors from
167  * the original 4.0 of about 25 and ~0.87, both larger than the allowed
168  * default (0.5). So the original proposal is kept.
169  */
170  auto const binning
171  = icarus::ns::util::makeBinningFromBinWidth(-1.0, 3.0, 0.25, { 0.1, 0.3 } );
172 
173  BOOST_TEST(binning.lower() == -1.0, 0.001% tolerance());
174  BOOST_TEST(binning.upper() == 3.0, 0.001% tolerance());
175  BOOST_TEST(binning.range() == 4.0, 0.001% tolerance());
176  BOOST_TEST(binning.nBins() == 16UL);
177  BOOST_TEST(binning.binWidth() == 0.25, 0.001% tolerance());
178 
179 } // makeBinningFromBinWidth_hints_test()
180 
181 
183 
185 
186  // the original proposal is kept
187  auto const binning
188  = icarus::ns::util::makeBinningFromBinWidth(-1.0, 3.0, 0.25, {});
189 
190  BOOST_TEST(binning.lower() == -1.0, 0.001% tolerance());
191  BOOST_TEST(binning.upper() == 3.0, 0.001% tolerance());
192  BOOST_TEST(binning.range() == 4.0, 0.001% tolerance());
193  BOOST_TEST(binning.nBins() == 16UL);
194  BOOST_TEST(binning.binWidth() == 0.25, 0.001% tolerance());
195 
196 } // makeBinningFromBinWidth_nohint_test()
197 
198 
199 //------------------------------------------------------------------------------
201 
203 
204  // bin width = 13/7, order 1
205  auto const binning
206  = icarus::ns::util::makeBinningFromNBins(-5.0, 8.0, 7UL);
207 
208  BOOST_TEST(binning.lower() == -6.0, 0.001% tolerance());
209  BOOST_TEST(binning.upper() == 8.0, 0.001% tolerance());
210  BOOST_TEST(binning.range() == 14.0, 0.001% tolerance());
211  BOOST_TEST(binning.nBins() == 7UL);
212  BOOST_TEST(binning.binWidth() == 2.0, 0.001% tolerance());
213 
214 } // makeBinningFromNBins_alignment_test()
215 
216 
218 
220 
221  auto const binning
222  = icarus::ns::util::makeBinningFromNBins(-5.0, 7.5, 7UL);
223 
224  BOOST_TEST(binning.lower() == -6.0, 0.001% tolerance());
225  BOOST_TEST(binning.upper() == 8.0, 0.001% tolerance());
226  BOOST_TEST(binning.range() == 14.0, 0.001% tolerance());
227  BOOST_TEST(binning.nBins() == 7UL);
228  BOOST_TEST(binning.binWidth() == 2.0, 0.001% tolerance());
229 
230 } // makeBinningFromNBins_extension_test()
231 
232 
234 
236 
237  // this has bin width (4/9) of order of magnitude 0.1
238  auto const binning
239  = icarus::ns::util::makeBinningFromNBins(-1.0, 3.0, 9UL );
240 
241  BOOST_TEST(binning.lower() == -1.2, 0.001% tolerance());
242  BOOST_TEST(binning.upper() == 3.2, 0.001% tolerance());
243  BOOST_TEST(binning.range() == 4.4, 0.001% tolerance());
244  BOOST_TEST(binning.nBins() == 11UL);
245  BOOST_TEST(binning.binWidth() == 0.4, 0.001% tolerance());
246 
247 } // makeBinningFromNBins_defhints_test()
248 
249 
251 
253 
254  // this has bin width order of magnitude 1, so hints are 3 and 4:
255  auto const binning
256  = icarus::ns::util::makeBinningFromNBins(-1.0, 3.0, 3UL, { 1.0, 1.5 } );
257 
258  BOOST_TEST(binning.lower() == -1.5, 0.001% tolerance());
259  BOOST_TEST(binning.upper() == 3.0, 0.001% tolerance());
260  BOOST_TEST(binning.range() == 4.5, 0.001% tolerance());
261  BOOST_TEST(binning.nBins() == 3UL);
262  BOOST_TEST(binning.binWidth() == 1.5, 0.001% tolerance());
263 
264 } // makeBinningFromNBins()
265 
266 
268 
270 
271  /*
272  * this has bin width order of magnitude 0.1 (0.1 <= 4/9 < 1.0),
273  * so the hint { 0.1, 0.3 } translates into bin width hints 0.01 and 0.03;
274  * the starting number of bins is 9.
275  * So the candidate ranges are 0.09 and 0.27, with stretch factors from
276  * the original 4.0 of about ~44 and ~15, both larger than the allowed
277  * default (0.5). So the original proposal is kept.
278  */
279  auto const binning
280  = icarus::ns::util::makeBinningFromNBins(-1.0, 3.0, 9UL, { 0.1, 0.3 } );
281 
282  BOOST_TEST(binning.lower() == -12.0/9.0, 0.001% tolerance());
283  BOOST_TEST(binning.upper() == 28.0/9.0, 0.001% tolerance());
284  BOOST_TEST(binning.range() == 40.0/9.0, 0.001% tolerance());
285  BOOST_TEST(binning.nBins() == 10UL);
286  BOOST_TEST(binning.binWidth() == 4.0/9.0, 0.001% tolerance());
287 
288 } // makeBinningFromNBins_stretch_test()
289 
290 
292 
294 
295  // the original proposal is kept
296  auto const binning = icarus::ns::util::makeBinningFromNBins(-1.0, 3.0, 2, {});
297 
298  BOOST_TEST(binning.lower() == -2.0, 0.001% tolerance());
299  BOOST_TEST(binning.upper() == 4.0, 0.001% tolerance());
300  BOOST_TEST(binning.range() == 6.0, 0.001% tolerance());
301  BOOST_TEST(binning.nBins() == 3UL);
302  BOOST_TEST(binning.binWidth() == 2.0, 0.001% tolerance());
303 
304 } // makeBinningFromNBins_nohint_test()
305 
306 
307 //------------------------------------------------------------------------------
308 //--- The tests
309 //---
310 BOOST_AUTO_TEST_CASE( BinningSpecs_testCase ) {
311 
314 
315 } // BOOST_AUTO_TEST_CASE( BinningSpecs_testCase )
316 
317 
318 BOOST_AUTO_TEST_CASE( makeBinningFromBinWidth_testCase ) {
319 
326 
327 } // BOOST_AUTO_TEST_CASE( makeBinningFromBinWidth_testCase )
328 
329 
330 BOOST_AUTO_TEST_CASE( makeBinningFromNBins_testCase ) {
331 
338 
339 } // BOOST_AUTO_TEST_CASE( makeBinningFromNBins_testCase )
340 
341 
342 //------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(AllTests)
void makeBinningFromBinWidth_alignment_test()
void BinningSpecs_test()
Simple utility for human-friendly binning.
void makeBinningFromNBins_alignment_test()
auto const tolerance
void BinningSpecs_NBinsFor_test()
void makeBinningFromNBins_extension_test()
Data structure holding binning information.
Definition: BinningSpecs.h:170
void makeBinningFromNBins_hints_test()
void makeBinningFromBinWidth_stretch_test()
void makeBinningFromBinWidth_nohint_test()
void makeBinningFromBinWidth_extension_test()
void makeBinningFromNBins_stretch_test()
void makeBinningFromNBins_defhints_test()
BinningSpecs makeBinningFromNBins(double lower, double upper, unsigned long nBins, std::initializer_list< double > hints=DefaultBinningHints, double allowedStretch=DefaultAllowedBinningStretch)
Returns the &quot;optimal&quot; binning for the requested parameters.
void makeBinningFromBinWidth_defhints_test()
void makeBinningFromNBins_nohint_test()
void makeBinningFromBinWidth_hints_test()
BinningSpecs makeBinningFromBinWidth(double lower, double upper, double width, std::initializer_list< double > hints=DefaultBinningHints, double allowedStretch=DefaultAllowedBinningStretch)
Returns the &quot;optimal&quot; binning for the requested parameters.