Belle II Software development
softwareTriggerCut.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 <hlt/softwaretrigger/core/SoftwareTriggerCut.h>
10#include <gtest/gtest.h>
11#include <stdint.h>
12
13using namespace std;
14
15namespace Belle2 {
20 namespace SoftwareTrigger {
21
23 class SoftwareTriggerCutTest : public ::testing::Test {};
24
26 TEST_F(SoftwareTriggerCutTest, basic)
27 {
28 SoftwareTriggerObject object;
29
30 auto cut = SoftwareTriggerCut::compile("1 == 1", 1, false);
31 EXPECT_EQ(SoftwareTriggerCutResult::c_accept, cut->checkPreScaled(object));
32
33 cut = SoftwareTriggerCut::compile("1 == 1", 1, true);
34 EXPECT_EQ(SoftwareTriggerCutResult::c_reject, cut->checkPreScaled(object));
35
36 cut = SoftwareTriggerCut::compile("-1 == 1", 1, false);
37 EXPECT_EQ(SoftwareTriggerCutResult::c_noResult, cut->checkPreScaled(object));
38
39 cut = SoftwareTriggerCut::compile("-1 == 1", 1, true);
40 EXPECT_EQ(SoftwareTriggerCutResult::c_noResult, cut->checkPreScaled(object));
41 }
42
44 TEST_F(SoftwareTriggerCutTest, prescalingRandom)
45 {
46
47 SoftwareTriggerObject object;
48
49 // As a random seed is implemented in the software trigger cut, we test it multiple times.
50 auto cut = SoftwareTriggerCut::compile("1 == 1", 0, false);
51 for (unsigned int i = 0; i < 1e3; i++) {
52 EXPECT_EQ(SoftwareTriggerCutResult::c_noResult, cut->checkPreScaled(object));
53 }
54
55 // For reject cuts, the prescale is not allowed to have any influence
56 cut = SoftwareTriggerCut::compile("1 == 1", 0, true);
57 for (unsigned int i = 0; i < 1e3; i++) {
58 EXPECT_EQ(SoftwareTriggerCutResult::c_reject, cut->checkPreScaled(object));
59 }
60
61 cut = SoftwareTriggerCut::compile("1 == 1", 1, true);
62 for (unsigned int i = 0; i < 1e3; i++) {
63 EXPECT_EQ(SoftwareTriggerCutResult::c_reject, cut->checkPreScaled(object));
64 }
65
66 cut = SoftwareTriggerCut::compile("1 == 1", 1);
67 for (unsigned int i = 0; i < 1e3; i++) {
68 EXPECT_EQ(SoftwareTriggerCutResult::c_accept, cut->checkPreScaled(object));
69 }
70 // As we set a stable seed, we know already the result quite well
71 cut = SoftwareTriggerCut::compile("1 == 1", 10);
72
73 unsigned int numberOfYes = 0;
74 unsigned int numberOfNo = 0;
75 for (unsigned int i = 0; i < 1e4; i++) {
76 const auto cutResult = cut->checkPreScaled(object);
77 EXPECT_NE(SoftwareTriggerCutResult::c_reject, cutResult);
78
79 if (cutResult == SoftwareTriggerCutResult::c_accept) {
80 numberOfYes++;
81 } else if (cutResult == SoftwareTriggerCutResult::c_noResult) {
82 numberOfNo++;
83 }
84 }
85
86 // More or less 1 out of 10...
87 EXPECT_EQ(numberOfYes, 1022);
88 EXPECT_EQ(numberOfNo, 1e4 - 1022);
89 }
90
92 TEST_F(SoftwareTriggerCutTest, prescalingCounter)
93 {
94
95 SoftwareTriggerObject object;
96
97 // We test it multiple times, just to be sure.
98 auto cut = SoftwareTriggerCut::compile("1 == 1", 0, false);
99 for (uint32_t i = 0; i < 1e3; i++) {
100 EXPECT_EQ(SoftwareTriggerCutResult::c_noResult, cut->check(object).first);
101 }
102
103 // For reject cuts, the prescale is not allowed to have any influence
104 cut = SoftwareTriggerCut::compile("1 == 1", 0, true);
105 for (uint32_t i = 0; i < 1e3; i++) {
106 EXPECT_EQ(SoftwareTriggerCutResult::c_reject, cut->check(object).first);
107 }
108
109 cut = SoftwareTriggerCut::compile("1 == 1", 1, true);
110 for (uint32_t i = 0; i < 1e3; i++) {
111 EXPECT_EQ(SoftwareTriggerCutResult::c_reject, cut->check(object).first);
112 }
113
114 cut = SoftwareTriggerCut::compile("1 == 1", 1);
115 for (uint32_t i = 0; i < 1e3; i++) {
116 EXPECT_EQ(SoftwareTriggerCutResult::c_accept, cut->check(object).first);
117 }
118
119 // Now let's test the counters.
120 cut = SoftwareTriggerCut::compile("1 == 1", 10);
121 uint32_t counter = 0;
122 uint32_t numberOfYes = 0;
123 uint32_t numberOfNo = 0;
124 // Since the counter starts with 0, we expect (729/10)+1 yes.
125 for (uint32_t i = 0; i < 729; i++) {
126 const auto cutResult = cut->check(object, &counter).first;
127 EXPECT_NE(SoftwareTriggerCutResult::c_reject, cutResult);
128 if (cutResult == SoftwareTriggerCutResult::c_accept) {
129 numberOfYes++;
130 } else if (cutResult == SoftwareTriggerCutResult::c_noResult) {
131 numberOfNo++;
132 }
133 }
134 uint32_t expectedYes = (729 / 10) + 1;
135 EXPECT_EQ(numberOfYes, expectedYes);
136 EXPECT_EQ(numberOfNo, 729 - expectedYes);
137
138 cut = SoftwareTriggerCut::compile("1 == 1", 7);
139 counter = 1;
140 numberOfYes = 0;
141 numberOfNo = 0;
142 // Now the counter starts with 1, so we expect (544/7) yes.
143 for (uint32_t i = 1; i <= 544; i++) {
144 const auto cutResult = cut->check(object, &counter).first;
145 EXPECT_NE(SoftwareTriggerCutResult::c_reject, cutResult);
146 if (cutResult == SoftwareTriggerCutResult::c_accept) {
147 numberOfYes++;
148 } else if (cutResult == SoftwareTriggerCutResult::c_noResult) {
149 numberOfNo++;
150 }
151 }
152 expectedYes = (544 / 7);
153 EXPECT_EQ(numberOfYes, expectedYes);
154 EXPECT_EQ(numberOfNo, 544 - expectedYes);
155 }
156 }
158}
static std::unique_ptr< SoftwareTriggerCut > compile(const std::string &cut_string, const unsigned int prescaleFactor, const bool rejectCut=false)
Compile a new SoftwareTriggerCut from a cut string (by using the GeneralCut::compile function) and an...
@ c_accept
Accept this event.
@ c_reject
Reject this event.
@ c_noResult
There were not enough information to decide on what to do with the event.
Abstract base class for different kinds of events.
STL namespace.