Belle II Software  release-08-01-10
generalCut.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 #include <framework/utilities/GeneralCut.h>
9 #include <framework/utilities/TestHelpers.h>
10 #include <gtest/gtest.h>
11 
12 using namespace Belle2;
13 namespace {
15  struct MockObjectType {
17  double value = 4.2;
18  };
19 
25  class MockVariableType {
26  public:
28  double function(const MockObjectType* object) const
29  {
30  return object->value;
31  }
32 
34  const std::string name = "mocking_variable";
35  };
36 
41  class MockVariableManager {
42  public:
44  using Object = MockObjectType;
46  using Var = MockVariableType;
48  typedef std::variant<double, int, bool> VarVariant;
49 
51  static MockVariableManager& Instance()
52  {
53  static MockVariableManager instance;
54  return instance;
55  }
56 
58  Var* getVariable(const std::string& name)
59  {
60  if (name == "mocking_variable") {
61  return &m_mocking_variable;
62  } else {
63  return nullptr;
64  }
65  }
66 
67  Var* getVariable(const std::string& functionName, __attribute__((unused)) const std::vector<std::string>& functionArguments)
68  {
69  if (functionName == "mocking_variable") {
70  return &m_mocking_variable;
71  } else {
72  return nullptr;
73  }
74 
75  }
76 
78  Var m_mocking_variable;
79  };
80 
82  using MockGeneralCut = GeneralCut<MockVariableManager>;
83 
85  TEST(GeneralCutTest, cutCheck)
86  {
87  MockObjectType testObject;
88 
89  std::unique_ptr<MockGeneralCut> a = MockGeneralCut::compile("1.2 < 1.5 ");
90  EXPECT_TRUE(a->check(&testObject));
91  a = MockGeneralCut::compile(" 1.5<1.2");
92  EXPECT_FALSE(a->check(&testObject));
93 
94  // Check for regression
95  // This was broken in the past due to the abs function in almostEqual
96  a = MockGeneralCut::compile("-1 == 1");
97  EXPECT_FALSE(a->check(&testObject));
98  a = MockGeneralCut::compile("-1 != 1");
99  EXPECT_TRUE(a->check(&testObject));
100 
101  a = MockGeneralCut::compile(" 12.3 >1.5 ");
102  EXPECT_TRUE(a->check(&testObject));
103  a = MockGeneralCut::compile("12 > 15");
104  EXPECT_FALSE(a->check(&testObject));
105 
106  a = MockGeneralCut::compile("1.2 == 1.2");
107  EXPECT_TRUE(a->check(&testObject));
108  a = MockGeneralCut::compile(" 1.5!=1.2");
109  EXPECT_TRUE(a->check(&testObject));
110 
111  a = MockGeneralCut::compile("1.2 == 1.2 == 1.2");
112  EXPECT_TRUE(a->check(&testObject));
113  a = MockGeneralCut::compile(" 1.5 == 1.5!=1.2");
114  EXPECT_TRUE(a->check(&testObject));
115  a = MockGeneralCut::compile(" 1.5 == 1.5!=1.5");
116  EXPECT_FALSE(a->check(&testObject));
117 
118  a = MockGeneralCut::compile("1.0 < 1.2 == 1.2");
119  EXPECT_TRUE(a->check(&testObject));
120  a = MockGeneralCut::compile(" 1.5 < 1.6 != 1.6");
121  EXPECT_FALSE(a->check(&testObject));
122  a = MockGeneralCut::compile(" 1.5 < 1.6 != 1.7");
123  EXPECT_TRUE(a->check(&testObject));
124 
125  a = MockGeneralCut::compile(" [12 >= 12 ]");
126  EXPECT_TRUE(a->check(&testObject));
127  a = MockGeneralCut::compile("[ 15>= 16 ]");
128  EXPECT_FALSE(a->check(&testObject));
129 
130  a = MockGeneralCut::compile(" [12 <= 12 ]");
131  EXPECT_TRUE(a->check(&testObject));
132  a = MockGeneralCut::compile(" [ 17<= 16.7 ]");
133  EXPECT_FALSE(a->check(&testObject));
134 
135  a = MockGeneralCut::compile(" [12 <= 12 < 13]");
136  EXPECT_TRUE(a->check(&testObject));
137  a = MockGeneralCut::compile(" [ 17<= 16.7 < 18 ]");
138  EXPECT_FALSE(a->check(&testObject));
139 
140  a = MockGeneralCut::compile(" [12 >= 12 < 13]");
141  EXPECT_TRUE(a->check(&testObject));
142  a = MockGeneralCut::compile(" [ 15> 16.7 <= 18 ]");
143  EXPECT_FALSE(a->check(&testObject));
144 
145  a = MockGeneralCut::compile("mocking_variable > 1.0");
146  EXPECT_TRUE(a->check(&testObject));
147  a = MockGeneralCut::compile("1.0 < mocking_variable <= mocking_variable");
148  EXPECT_TRUE(a->check(&testObject));
149 
150  a = MockGeneralCut::compile("mocking_variable < 100.0");
151  EXPECT_TRUE(a->check(&testObject));
152  a = MockGeneralCut::compile("mocking_variable <= mocking_variable <= mocking_variable");
153  EXPECT_TRUE(a->check(&testObject));
154 
155  a = MockGeneralCut::compile("1 < 2 and 3 < 4");
156  EXPECT_TRUE(a->check(&testObject));
157  a = MockGeneralCut::compile("1 < 2 and 4 < 3");
158  EXPECT_FALSE(a->check(&testObject));
159  a = MockGeneralCut::compile("2 < 1 and 4 < 3");
160  EXPECT_FALSE(a->check(&testObject));
161  a = MockGeneralCut::compile("2 < 1 and 3 < 4");
162  EXPECT_FALSE(a->check(&testObject));
163 
164  a = MockGeneralCut::compile("1 < 2 or 3 < 4");
165  EXPECT_TRUE(a->check(&testObject));
166  a = MockGeneralCut::compile("1 < 2 or 4 < 3");
167  EXPECT_TRUE(a->check(&testObject));
168  a = MockGeneralCut::compile("2 < 1 or 4 < 3");
169  EXPECT_FALSE(a->check(&testObject));
170  a = MockGeneralCut::compile("2 < 1 or 3 < 4");
171  EXPECT_TRUE(a->check(&testObject));
172 
173  a = MockGeneralCut::compile("1 < 2 and 3 < 4 and [ 5 < 6 or 7 > 6 ]");
174  EXPECT_TRUE(a->check(&testObject));
175  a = MockGeneralCut::compile("[1 < 2 < 3 or 3 > 4 ] and [ 5 < 6 or 7 > 6 ]");
176  EXPECT_TRUE(a->check(&testObject));
177  a = MockGeneralCut::compile("[1 < 2 < 3 or 3 > 4 ] or [ 5 < 6 and 7 > 6 ]");
178  EXPECT_TRUE(a->check(&testObject));
179 
180  a = MockGeneralCut::compile("1 < 2 and 3 < 4 or 5 > 6");
181  EXPECT_TRUE(a->check(&testObject));
182  a = MockGeneralCut::compile("1 < 2 or 3 < 4 and 5 > 6");
183  EXPECT_TRUE(a->check(&testObject));
184  a = MockGeneralCut::compile("1 < 2 and 4 < 3 or 6 > 5");
185  EXPECT_TRUE(a->check(&testObject));
186  a = MockGeneralCut::compile("1 < 2 or 4 < 3 and 6 > 5");
187  EXPECT_TRUE(a->check(&testObject));
188 
189  a = MockGeneralCut::compile("1 != 2 and 3 < 4 or 5 > 6");
190  EXPECT_TRUE(a->check(&testObject));
191  a = MockGeneralCut::compile("1 < 2 or 3 != 4 and 5 > 6");
192  EXPECT_TRUE(a->check(&testObject));
193 
194  a = MockGeneralCut::compile("1 != 2 and 3 == 4 or 5 > 6");
195  EXPECT_FALSE(a->check(&testObject));
196  a = MockGeneralCut::compile("1 < 2 or 3 == 4 and 5 > 6");
197  EXPECT_TRUE(a->check(&testObject));
198 
199  a = MockGeneralCut::compile("15 != 0x15");
200  EXPECT_TRUE(a->check(&testObject));
201 
202  a = MockGeneralCut::compile("15 == 0xF");
203  EXPECT_TRUE(a->check(&testObject));
204 
205  // Should trigger B2FATAL
206  EXPECT_B2FATAL(a = MockGeneralCut::compile("15 == 15.0 bla"));
207  // Should throw runtime error
208  EXPECT_THROW(a = MockGeneralCut::compile("15 == other_var"), std::runtime_error);
209 
210  a = MockGeneralCut::compile("infinity == 15e1000");
211  EXPECT_TRUE(a->check(&testObject));
212 
213  a = MockGeneralCut::compile("1e-3 < 1e3");
214  EXPECT_TRUE(a->check(&testObject));
215 
216  a = MockGeneralCut::compile("1e-3 == 0.001");
217  EXPECT_TRUE(a->check(&testObject));
218 
219  a = MockGeneralCut::compile("1000 < infinity");
220  EXPECT_TRUE(a->check(&testObject));
221 
222  a = MockGeneralCut::compile("1000 > infinity");
223  EXPECT_FALSE(a->check(&testObject));
224 
225  a = MockGeneralCut::compile("1000 < nan");
226  EXPECT_FALSE(a->check(&testObject));
227 
228  a = MockGeneralCut::compile("1000 > nan");
229  EXPECT_FALSE(a->check(&testObject));
230 
231  // Check if we have double precision
232  a = MockGeneralCut::compile("3.141592653589793 == 3.141592653589792");
233  EXPECT_FALSE(a->check(&testObject));
234 
235  a = MockGeneralCut::compile("3.1415926535897931234567890 == 3.1415926535897931234567891");
236  EXPECT_TRUE(a->check(&testObject));
237 
238  a = MockGeneralCut::compile("3141592653589 != 3141592653588");
239  EXPECT_TRUE(a->check(&testObject));
240 
241  a = MockGeneralCut::compile("");
242  EXPECT_TRUE(a->check(&testObject));
243 
244  a = MockGeneralCut::compile(" ");
245  EXPECT_TRUE(a->check(&testObject));
246 
247  EXPECT_B2FATAL(a = MockGeneralCut::compile("[ ]"));
248 
249  EXPECT_B2FATAL(a = MockGeneralCut::compile("[ ] and []"));
250  }
251 
253  TEST(GeneralCutTest, compileAndDecompile)
254  {
255 
256  std::unique_ptr<MockGeneralCut> a = MockGeneralCut::compile("1 < 2");
257  EXPECT_EQ(a->decompile(), "1 < 2");
258 
259  a = MockGeneralCut::compile("[1 < 2]");
260  EXPECT_EQ(a->decompile(), "[1 < 2]");
261 
262  a = MockGeneralCut::compile("1 < 2 < 3");
263  EXPECT_EQ(a->decompile(), "1 < 2 < 3");
264 
265  a = MockGeneralCut::compile("( 1 + 3 ) * 2");
266  EXPECT_EQ(a->decompile(), "( 1 + 3 ) * 2");
267 
268  a = MockGeneralCut::compile("[1 < 2 < 3] or [[ 2 < 4] and [ mocking_variable < 4.4231 and [1 < 3 and 4 < mocking_variable]]]");
269  EXPECT_EQ(a->decompile(),
270  "[1 < 2 < 3] or [[2 < 4] and [mocking_variable < 4.4231 and [1 < 3 and 4 < mocking_variable]]]");
271  }
272 
273 
274 } // namespace
This class implements a common way to implement cut/selection functionality for arbitrary objects.
Definition: GeneralCut.h:71
TEST(TestgetDetectorRegion, TestgetDetectorRegion)
Test Constructors.
Abstract base class for different kinds of events.