Belle II Software development
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
12using namespace Belle2;
13namespace {
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
Abstract base class for different kinds of events.