Belle II Software  release-06-01-15
filters.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 
12 #include <tracking/trackFindingVXD/filterMap/filterFramework/Shortcuts.h>
13 #include <tuple>
14 #include <iostream>
15 #include <math.h>
16 
17 using namespace std;
18 
19 using namespace Belle2;
20 
21 namespace VXDTFfilterTest {
22 
24  class spacePoint: public tuple<float, float, float> {
25  public:
27  spacePoint(float x, float y, float z): tuple<float, float, float>(x, y, z)
28  {};
29  private:
32  spacePoint(const spacePoint&) = delete;
33  };
34 
35 
37  class SquaredDistance3D : public SelectionVariable< spacePoint , 2, float > {
38  public:
40  static const std::string name(void) {return "SquaredDistance3D"; };
41 
43  static float value(const spacePoint& p1, const spacePoint& p2)
44  {
45  return
46  pow(get<0>(p1) - get<0>(p2) , 2) +
47  pow(get<1>(p1) - get<1>(p2) , 2) +
48  pow(get<2>(p1) - get<2>(p2) , 2) ;
49  }
50  };
51 
52 
54  class SquaredDistance2Dxy : public SelectionVariable< spacePoint , 2, float > {
55  public:
57  static const std::string name(void) {return "SquaredDistance2Dxy"; };
58 
60  static float value(const spacePoint& p1, const spacePoint& p2)
61  {
62  return
63  pow(get<0>(p1) - get<0>(p2) , 2) +
64  pow(get<1>(p1) - get<1>(p2) , 2) ;
65  }
66  };
67 
68 
70  class SquaredDistance1Dx : public SelectionVariable< spacePoint , 2, float > {
71  public:
73  static const std::string name(void) {return "SquaredDistance1Dx"; };
74 
76  static float value(const spacePoint& p1, const spacePoint& p2)
77  {
78  return
79  pow(get<0>(p1) - get<0>(p2) , 2);
80  }
81  };
82 
83 
85  class BooleanVariable : public SelectionVariable< spacePoint , 2, bool > {
86  public:
88  static const std::string name(void) {return "BooleanVariable"; };
89 
91  static float value(const spacePoint& p1, const spacePoint& p2)
92  {
93  return
94  get<0>(p1) - get<0>(p2) == 0.;
95  }
96  };
97 
98 
100  template < class T> class counter {
101  public:
102  static int N;
103  counter() {};
104  ~counter() {};
105  };
106 
107 
109  template<>
111 
112 
114  template<>
116 
117 
119  template<>
121 
122 
124  class Observer : public VoidObserver {
125  public:
127  template<class Var, typename ... otherTypes>
128  static void notify(const Var&,
129  const otherTypes& ...)
130  {
131  counter<Var>::N ++ ;
132  }
133  };
134 
135 
136 
138  class FilterTest : public ::testing::Test {
139  protected:
140  };
141 
142 
145  {
146 
147  Range<double, double> range(0. , 1.);
148  EXPECT_TRUE(range.contains(0.5));
149  EXPECT_FALSE(range.contains(-1.));
150  EXPECT_FALSE(range.contains(0.));
151  EXPECT_FALSE(range.contains(1.));
152  EXPECT_FALSE(range.contains(2.));
153  EXPECT_EQ(0. , range.getInf());
154  EXPECT_EQ(1. , range.getSup());
155  }
156 
158  TEST_F(FilterTest, ClosedRange)
159  {
160 
161  ClosedRange<double, double> range(0. , 1.);
162  EXPECT_TRUE(range.contains(0.5));
163  EXPECT_FALSE(range.contains(-1.));
164  EXPECT_TRUE(range.contains(0.));
165  EXPECT_TRUE(range.contains(1.));
166  EXPECT_FALSE(range.contains(2.));
167  EXPECT_EQ(0. , range.getInf());
168  EXPECT_EQ(1. , range.getSup());
169  }
170 
171 
173  TEST_F(FilterTest, UpperBoundedSet)
174  {
175 
176  UpperBoundedSet<double> upperBoundedSet(0.);
177  EXPECT_TRUE(upperBoundedSet.contains(-1.));
178  EXPECT_FALSE(upperBoundedSet.contains(0.));
179  EXPECT_FALSE(upperBoundedSet.contains(1.));
180  EXPECT_EQ(0. , upperBoundedSet.getSup());
181  }
182 
184  TEST_F(FilterTest, ClosedUpperBoundedSet)
185  {
186 
187  ClosedUpperBoundedSet<double> upperBoundedSet(0.);
188  EXPECT_TRUE(upperBoundedSet.contains(-1.));
189  EXPECT_TRUE(upperBoundedSet.contains(0.));
190  EXPECT_FALSE(upperBoundedSet.contains(1.));
191  EXPECT_EQ(0. , upperBoundedSet.getSup());
192  }
193 
194 
196  TEST_F(FilterTest, LowerBoundedSet)
197  {
198 
199  LowerBoundedSet<double> lowerBoundedSet(0.);
200  EXPECT_TRUE(lowerBoundedSet.contains(1.));
201  EXPECT_FALSE(lowerBoundedSet.contains(0.));
202  EXPECT_FALSE(lowerBoundedSet.contains(-1.));
203  EXPECT_EQ(0. , lowerBoundedSet.getInf());
204  }
205 
207  TEST_F(FilterTest, ClosedLowerBoundedSet)
208  {
209 
210  ClosedLowerBoundedSet<double> lowerBoundedSet(0.);
211  EXPECT_TRUE(lowerBoundedSet.contains(1.));
212  EXPECT_TRUE(lowerBoundedSet.contains(0.));
213  EXPECT_FALSE(lowerBoundedSet.contains(-1.));
214  EXPECT_EQ(0. , lowerBoundedSet.getInf());
215  }
216 
217 
219  TEST_F(FilterTest, SelectionVariableName)
220  {
221 
222  EXPECT_EQ("SquaredDistance3D" , SquaredDistance3D().name());
223  }
224 
225 
227  TEST_F(FilterTest, BasicFilter)
228  {
229  // Very verbose declaration, see below for convenient shortcuts
231 
232  spacePoint x1(0.0f , 0.0f, 0.0f);
233  spacePoint x2(0.5f , 0.0f, 0.0f);
234  spacePoint x3(2.0f , 0.0f, 0.0f);
235 
236  EXPECT_TRUE(filter.accept(x1, x2));
237  EXPECT_FALSE(filter.accept(x1, x3));
238 
239  }
240 
241 
243  TEST_F(FilterTest, ObservedFilter)
244  {
245  // Very verbose declaration, see below for convenient shortcuts
247 
249  spacePoint x1(0.0f , 0.0f, 0.0f);
250  spacePoint x2(0.5f , 0.0f, 0.0f);
251  spacePoint x3(2.0f , 0.0f, 0.0f);
252  counter< SquaredDistance3D >::N = 0;
253 
254  EXPECT_TRUE(filter.accept(x1, x2));
255  EXPECT_FALSE(filter.accept(x1, x3));
256  EXPECT_EQ(2 , counter< SquaredDistance3D >::N);
257  }
258 
260  TEST_F(FilterTest, SwitchingObservers)
261  {
262  //build an dummy filter which is unobserved (VoidObserver)
263  auto dummyFilter = ((-10. <= SquaredDistance3D() <= 10.) &&
264  ((-100. <= SquaredDistance2Dxy() <= -10.) || // put 2nd pair of parentheses to silence warning
265  (-10. <= SquaredDistance1Dx() <= 10.)) &&
266  !(-10. <= SquaredDistance1Dx() <= -10.));
267 
268  // values are chosen in that way that all sub-filters of dummyFilter have to be called (see comment below)
269  // and so that dummyFilter is always true
270  spacePoint x1(0.0f , 0.0f, 0.0f);
271  spacePoint x2(0.5f , 0.0f, 0.0f);
272  spacePoint x3(2.0f , 0.0f, 0.0f);
273 
274  counter< SquaredDistance3D >::N = 0;
275  counter< SquaredDistance1Dx >::N = 0;
276  counter< SquaredDistance2Dxy >::N = 0;
277 
278  dummyFilter.accept(x1, x2);
279  dummyFilter.accept(x1, x3);
280 
281  // useless test as it tests if realy unobserved
282  EXPECT_EQ(0 , counter< SquaredDistance3D >::N);
283  EXPECT_EQ(0 , counter< SquaredDistance2Dxy >::N);
284  EXPECT_EQ(0 , counter< SquaredDistance1Dx >::N);
285 
286  // Now switch observer, this is done recursively for each of the underlying filters
287  // One cannot switch the observer of an existing filter (as it would mean to switch type) so one has to create a new one!
288  // Note that if one filter is evaluated as false the other filter are not evaluated anymore and thus not observed!
289  auto observedDummyFilter = dummyFilter.observe(Observer());
290  observedDummyFilter.accept(x1, x2);
291  observedDummyFilter.accept(x1, x3);
292 
293  EXPECT_EQ(2 , counter< SquaredDistance3D >::N);
294  EXPECT_EQ(2 , counter< SquaredDistance2Dxy >::N);
295  //Note SquaredDistance1D is used twice in the filter so it is evaluated twice!
296  EXPECT_EQ(4 , counter< SquaredDistance1Dx >::N);
297  }
298 
299 
301  TEST_F(FilterTest, BypassableFilter)
302  {
303  bool bypassControl(false);
304  // Very verbose declaration, see below for convenient shortcuts
306  auto filter = nonBypassableFilter.bypass(bypassControl);
307  spacePoint x1(0.0f , 0.0f, 0.0f);
308  spacePoint x2(2.0f , 0.0f, 0.0f);
309  counter< SquaredDistance3D >::N = 0;
310 
311  EXPECT_FALSE(filter.accept(x1, x2));
312  EXPECT_EQ(1 , counter< SquaredDistance3D >::N);
313 
314  bypassControl = true;
315  EXPECT_TRUE(filter.accept(x1, x2));
316  EXPECT_EQ(2 , counter< SquaredDistance3D >::N);
317 
318  }
319 
320 
322  TEST_F(FilterTest, Shortcuts)
323  {
324 
325  spacePoint x1(0.0f , 0.0f, 0.0f);
326  spacePoint x2(0.5f , 0.0f, 0.0f);
327  spacePoint x3(2.0f , 0.0f, 0.0f);
328  spacePoint x4(1.0f , 0.0f, 0.0f);
329 
330  auto filterSup = (SquaredDistance3D() < 1.) ;
331  EXPECT_TRUE(filterSup.accept(x1, x2));
332  EXPECT_FALSE(filterSup.accept(x1, x4));
333  EXPECT_FALSE(filterSup.accept(x1, x3));
334 
335  auto filterMax = (SquaredDistance3D() <= 1.) ;
336  EXPECT_TRUE(filterMax.accept(x1, x2));
337  EXPECT_TRUE(filterMax.accept(x1, x4));
338  EXPECT_FALSE(filterMax.accept(x1, x3));
339 
340 
341  auto filterSup2 = (1 > SquaredDistance3D()) ;
342  EXPECT_TRUE(filterSup2.accept(x1, x2));
343  EXPECT_FALSE(filterSup2.accept(x1, x3));
344  EXPECT_FALSE(filterSup2.accept(x1, x4));
345 
346  auto filterMax2 = (1 >= SquaredDistance3D()) ;
347  EXPECT_TRUE(filterMax2.accept(x1, x2));
348  EXPECT_FALSE(filterMax2.accept(x1, x3));
349  EXPECT_TRUE(filterMax2.accept(x1, x4));
350 
351  auto filterInf = (SquaredDistance3D() > 1.) ;
352  EXPECT_TRUE(filterInf.accept(x1, x3));
353  EXPECT_FALSE(filterInf.accept(x1, x2));
354  EXPECT_FALSE(filterInf.accept(x1, x4));
355 
356  auto filterMin = (SquaredDistance3D() >= 1.) ;
357  EXPECT_TRUE(filterMin.accept(x1, x3));
358  EXPECT_FALSE(filterMin.accept(x1, x2));
359  EXPECT_TRUE(filterMin.accept(x1, x4));
360 
361  auto filterInf2 = (1 < SquaredDistance3D()) ;
362  EXPECT_TRUE(filterInf2.accept(x1, x3));
363  EXPECT_FALSE(filterInf2.accept(x1, x2));
364  EXPECT_FALSE(filterInf2.accept(x1, x4));
365 
366  auto filterMin2 = (1 <= SquaredDistance3D()) ;
367  EXPECT_TRUE(filterMin2.accept(x1, x3));
368  EXPECT_FALSE(filterMin2.accept(x1, x2));
369  EXPECT_TRUE(filterMin2.accept(x1, x4));
370 
371  auto filterRange = (0. < SquaredDistance3D() < 1);
372  EXPECT_FALSE(filterRange.accept(x1, x1));
373  EXPECT_TRUE(filterRange.accept(x1, x2));
374  EXPECT_FALSE(filterRange.accept(x1, x3));
375  EXPECT_FALSE(filterRange.accept(x1, x4));
376 
377  // cppcheck-suppress compareBoolExpressionWithInt
378  auto filterClosedRange = (0. <= SquaredDistance3D() <= 1);
379  EXPECT_TRUE(filterClosedRange.accept(x1, x1));
380  EXPECT_TRUE(filterClosedRange.accept(x1, x2));
381  EXPECT_FALSE(filterClosedRange.accept(x1, x3));
382  EXPECT_TRUE(filterClosedRange.accept(x1, x4));
383 
384  }
385 
386 
388  TEST_F(FilterTest, BooleanOperations)
389  {
390 
391 
392  spacePoint x1(0.0f , 0.0f, 0.0f);
393  spacePoint x2(1.0f , 0.0f, 0.0f);
394  spacePoint x3(2.0f , 0.0f, 0.0f);
395 
396  auto filter = !(SquaredDistance3D() > 1.);
397  EXPECT_TRUE(filter.accept(x1, x2));
398  EXPECT_TRUE(filter.accept(x1, x1));
399  EXPECT_FALSE(filter.accept(x1, x3));
400 
401  auto filter2 =
402  !(SquaredDistance3D() > 1.) &&
403  !(SquaredDistance3D() < 1);
404  // i.e. SquaredDistance3D == 1
405  EXPECT_TRUE(filter2.accept(x1, x2));
406  EXPECT_FALSE(filter2.accept(x1, x1));
407  EXPECT_FALSE(filter2.accept(x1, x3));
408 
409 
410  auto filter3 =
411  (SquaredDistance3D() > 1.) ||
412  (SquaredDistance3D() < 1);
413  // i.e. SquaredDistance3D != 1
414  EXPECT_FALSE(filter3.accept(x1, x2));
415  EXPECT_TRUE(filter3.accept(x1, x1));
416  EXPECT_TRUE(filter3.accept(x1, x3));
417 
418 
419  }
420 
421 
423  TEST_F(FilterTest, ShortCircuitsEvaluation)
424  {
425  auto filter(
426  (SquaredDistance2Dxy() < 1).observeLeaf(Observer()) &&
427  (SquaredDistance3D() < 1).observeLeaf(Observer())
428  );
429 
430  spacePoint x1(0.0f , 0.0f, 0.0f);
431  spacePoint x3(2.0f , 0.0f, 0.0f);
432 
433  counter< SquaredDistance3D >::N = 0;
434  counter< SquaredDistance2Dxy >::N = 0;
435 
436  EXPECT_FALSE(filter.accept(x1, x3));
437  // since the pair x1, x3 does not satisfy the SquaredDistance2Dxy
438  // requirement, we do expect SquaredDistance2Dxy evaluated once:
439  EXPECT_EQ(1 , counter< SquaredDistance2Dxy >::N);
440  // and SquaredDistance3D not evaluated at all
441  EXPECT_EQ(0 , counter< SquaredDistance3D >::N);
442 
443  EXPECT_TRUE(filter.accept(x1, x1));
444  // in this case Distance2Dxy is satisfied
445  EXPECT_EQ(2 , counter< SquaredDistance2Dxy >::N);
446  // and Distance3D is evaluated
447  EXPECT_EQ(1 , counter< SquaredDistance3D >::N);
448 
449  }
450 
451 
453  TEST_F(FilterTest, BooleanVariableShortcuts)
454  {
455  auto filter1(BooleanVariable() == true);
456  auto filter2(false == BooleanVariable());
457  spacePoint x1(0.0f , 0.0f, 0.0f);
458  spacePoint x2(1.0f , 0.0f, 0.0f);
459 
460  EXPECT_TRUE(filter1.accept(x1, x1));
461  EXPECT_FALSE(filter1.accept(x1, x2));
462 
463 
464  EXPECT_FALSE(filter2.accept(x1, x1));
465  EXPECT_TRUE(filter2.accept(x1, x2));
466 
467 
468 
469  }
470 
471 }
Represents a closed lower bounded set of arithmetic types.
Represents a closed set of arithmetic types.
Definition: ClosedRange.h:32
Represents an upper bounded set of arithmetic types.
This class is used to select pairs, triplets...
Definition: Filter.h:34
Represents a lower bounded set of arithmetic types.
Observer base class which can be used to evaluate the VXDTF2's Filters.
Definition: Observer.h:19
Represents a range of arithmetic types.
Definition: Range.h:29
Base class of the selection variable objects used for pair filtering.
Represents an upper bounded set of arithmetic types.
The most CPU efficient Observer for the VXDTF filter tools (even if useless).
Definition: VoidObserver.h:30
a small filter illustrating the behavior of a filter which is compatible with boolean comparisons
Definition: filters.cc:85
static float value(const spacePoint &p1, const spacePoint &p2)
value function does the actual calculation of this class.
Definition: filters.cc:91
static const std::string name(void)
return name of the class
Definition: filters.cc:88
Test class for Filter object.
Definition: filters.cc:138
this observer does simply count the number of times, the attached Filter was used
Definition: filters.cc:124
static void notify(const Var &, const otherTypes &...)
notify function is called by the filter, this one increases the counter.
Definition: filters.cc:128
a small filter illustrating the behavior of a distance1D-filter in X
Definition: filters.cc:70
static float value(const spacePoint &p1, const spacePoint &p2)
value function does the actual calculation of this class.
Definition: filters.cc:76
static const std::string name(void)
return name of the class
Definition: filters.cc:73
a small filter illustrating the behavior of a distance2D-filter in XY
Definition: filters.cc:54
static float value(const spacePoint &p1, const spacePoint &p2)
value function does the actual calculation of this class.
Definition: filters.cc:60
static const std::string name(void)
return name of the class
Definition: filters.cc:57
a small filter illustrating the behavior of a distance3D-filter
Definition: filters.cc:37
static float value(const spacePoint &p1, const spacePoint &p2)
value function does the actual calculation of this class.
Definition: filters.cc:43
static const std::string name(void)
return name of the class
Definition: filters.cc:40
small class counting usage.
Definition: filters.cc:100
static int N
counter.
Definition: filters.cc:102
~counter()
constructor.
Definition: filters.cc:104
just a small proto-container storing coordinates
Definition: filters.cc:24
spacePoint(const spacePoint &)=delete
private copy constructor to test that all the arguments are passed by reference.
spacePoint(float x, float y, float z)
Constructor accepting coordinates.
Definition: filters.cc:27
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:72
std::map< ExpRun, std::pair< double, double > > filter(const std::map< ExpRun, std::pair< double, double >> &runs, double cut, std::map< ExpRun, std::pair< double, double >> &runsRemoved)
filter events to remove runs shorter than cut, it stores removed runs in runsRemoved
Definition: Splitter.cc:40
Abstract base class for different kinds of events.