R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
testNeulandDigitizingPaddle.cxx
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
3 * Copyright (C) 2019-2025 Members of R3B Collaboration *
4 * *
5 * This software is distributed under the terms of the *
6 * GNU General Public Licence (GPL) version 3, *
7 * copied verbatim in the file "LICENSE". *
8 * *
9 * In applying this license GSI does not waive the privileges and immunities *
10 * granted to it by virtue of its status as an Intergovernmental Organization *
11 * or submit itself to any jurisdiction. *
12 ******************************************************************************/
13
14#include "MockModels.h"
16#include "gtest/gtest.h"
17#include <vector>
18
24namespace
25{
26 namespace Digitizing = R3B::Digitizing;
32 using ::testing::Return;
33 template <typename Type>
34 using Pair = Digitizing::LRPair<Type>;
35
36 class testNeulandPaddle : public ::testing::Test
37 {
38 protected:
39 testNeulandPaddle() = default;
40
41 void SetUp() override
42 {
43 auto leftChannel = std::make_unique<GMockChannel>(ChannelSide::left);
44 auto rightChannel = std::make_unique<GMockChannel>(ChannelSide::right);
45 channels_.left = leftChannel.get();
46 channels_.right = rightChannel.get();
47 EXPECT_CALL(*channels_.left, AttachToPaddle).Times(1);
48 EXPECT_CALL(*channels_.right, AttachToPaddle).Times(1);
49 paddle_->SetChannel(std::move(leftChannel));
50 paddle_->SetChannel(std::move(rightChannel));
51 }
52
53 // void SetExpectCall()
54 // {
55 // EXPECT_CALL(*channels_.left,
56 // ConstructSignals()).Times(1).WillOnce(Return(std::move(channelSignals_.left)));
57 // EXPECT_CALL(*channels_.right, ConstructSignals())
58 // .Times(1)
59 // .WillOnce(Return(std::move(channelSignals_.right)));
60 // }
61
62 template <ChannelSide side>
63 void AddChannelSignal(const double& time, const double& energy)
64 {
65 auto signal = Channel::Signal{};
66 signal.tdc = time;
67 signal.qdc = energy;
68 signal.qdcUnSat = energy;
69 signal.side = side;
70 if constexpr (side == ChannelSide::right)
71 {
72 channelSignals_.right.push_back(signal);
73 }
74 else
75 {
76 channelSignals_.left.push_back(signal);
77 }
78 }
79
80 template <ChannelSide side>
81 auto ExtractChannelSignals()
82 {
83 if constexpr (side == ChannelSide::right)
84 {
85 return std::move(channelSignals_.right);
86 }
87 else
88 {
89 return std::move(channelSignals_.left);
90 }
91 }
92 [[nodiscard]] const auto& GetChannels() const { return channels_; }
93 [[nodiscard]] auto* GetPaddle() const { return paddle_.get(); }
94
95 private:
96 std::unique_ptr<NeulandPaddle> paddle_ = std::make_unique<NeulandPaddle>(0);
97 Pair<std::vector<Channel::Signal>> channelSignals_;
98 Pair<GMockChannel*> channels_ = { nullptr, nullptr };
99 };
100
101 TEST_F(testNeulandPaddle, check_inputN_to_channel) // NOLINT
102 {
103 auto* paddle = GetPaddle();
104 paddle->DepositLight(PaddleHit{ 10., 20., 0. });
105 paddle->DepositLight(PaddleHit{ 10., 20., 0. });
106 paddle->DepositLight(PaddleHit{ 20., 0., 0. });
107 const auto& leftHits = GetChannels().left->hits_;
108 const auto& rightHits = GetChannels().right->hits_;
109 ASSERT_EQ(leftHits.size(), rightHits.size()) << "Numbers of hits of both PMT channels don't match!";
110 ASSERT_EQ(leftHits.size(), 3) << "Number of hits for a PMT channel doesn't match with paddle inputs";
111 }
112
113 TEST_F(testNeulandPaddle, check_light_attenuation) // NOLINT
114 {
115 auto* paddle = GetPaddle();
116 auto const inputE = 20.;
117 auto paddleHit = PaddleHit{ 10., inputE, 0 };
118 paddle->DepositLight(paddleHit);
119 const auto& leftHits = GetChannels().left->hits_;
120 const auto& rightHits = GetChannels().right->hits_;
121 ASSERT_LT(leftHits[0].light, inputE) << "No light attenuation for the left channel!";
122 ASSERT_LT(rightHits[0].light, inputE) << "No light attenuation for the right channel!";
123 }
124
125 TEST_F(testNeulandPaddle, check_positive_direction) // NOLINT
126 {
127 auto* paddle = GetPaddle();
128 auto const inputE = 20.;
129 auto const initPos = 0.8 * NeulandPaddle::gHalfLength;
130 auto paddleHit = PaddleHit{ 10., inputE, initPos };
131 paddle->DepositLight(paddleHit);
132 const auto& leftHits = GetChannels().left->hits_;
133 const auto& rightHits = GetChannels().right->hits_;
134 ASSERT_LT(leftHits[0].light, rightHits[0].light) << "left channel has larger light input with longer distance!";
135 ASSERT_GT(leftHits[0].time, rightHits[0].time) << "light hit left channel ealier with longer distance!";
136 }
137
138 TEST_F(testNeulandPaddle, check_coupling_counts) // NOLINT
139 {
140 auto* paddle = GetPaddle();
141 paddle->DepositLight(PaddleHit{ 10., 20., 0.5 * NeulandPaddle::gHalfLength });
142 paddle->DepositLight(PaddleHit{ 60., 10., -0.3 * NeulandPaddle::gHalfLength });
143 const auto& leftHits = GetChannels().left->hits_;
144 const auto& rightHits = GetChannels().right->hits_;
145 AddChannelSignal<ChannelSide::left>(leftHits[0].time, leftHits[0].light);
146 AddChannelSignal<ChannelSide::left>(leftHits[1].time, leftHits[1].light);
147 AddChannelSignal<ChannelSide::right>(rightHits[1].time, rightHits[1].light);
148 AddChannelSignal<ChannelSide::right>(rightHits[0].time, rightHits[0].light);
149 EXPECT_CALL(*GetChannels().left, ConstructSignals())
150 .Times(1)
151 .WillOnce(Return(ExtractChannelSignals<ChannelSide::left>()));
152 EXPECT_CALL(*GetChannels().right, ConstructSignals())
153 .Times(1)
154 .WillOnce(Return(ExtractChannelSignals<ChannelSide::right>()));
155 const auto& signals = paddle->GetSignals();
156 ASSERT_EQ(signals.size(), 2) << "Fail to reconstruct the same number of signals!";
157 }
158
159 TEST_F(testNeulandPaddle, check_output_singal) // NOLINT
160 {
161 auto* paddle = GetPaddle();
162 paddle->DepositLight(PaddleHit{ 10., 20., 0.5 * NeulandPaddle::gHalfLength });
163 const auto& leftHits = GetChannels().left->hits_;
164 const auto& rightHits = GetChannels().right->hits_;
165 AddChannelSignal<ChannelSide::left>(leftHits[0].time, leftHits[0].light);
166 AddChannelSignal<ChannelSide::right>(rightHits[0].time, rightHits[0].light);
167 EXPECT_CALL(*GetChannels().left, ConstructSignals())
168 .Times(1)
169 .WillOnce(Return(ExtractChannelSignals<ChannelSide::left>()));
170 EXPECT_CALL(*GetChannels().right, ConstructSignals())
171 .Times(1)
172 .WillOnce(Return(ExtractChannelSignals<ChannelSide::right>()));
173 auto const& signals = paddle->GetSignals();
174 ASSERT_EQ(signals.size(), 1) << "Fail to reconstruct the same number of signals!";
175 const double err = 0.1 * 0.5 * NeulandPaddle::gHalfLength;
176 ASSERT_NEAR(0.5 * NeulandPaddle::gHalfLength, signals.front().position, err)
177 << "reconstructed position is way different to predefined position!";
178 }
179
180 // TEST_F(testNeulandPaddle, check_coupling_NoEQ_counts) // NOLINT
181 // {
182 // auto* paddle = GetPaddle();
183 // paddle->DepositLight(PaddleHit{ 10., 20., 0.5 * NeulandPaddle::gHalfLength });
184 // paddle->DepositLight(PaddleHit{ 60., 10., -0.3 * NeulandPaddle::gHalfLength });
185 // const auto& leftHits = GetChannels().left->hits_;
186 // const auto& rightHits = GetChannels().right->hits_;
187 // AddChannelSignal<ChannelSide::left>(leftHits[0].time, leftHits[0].light);
188 // AddChannelSignal<ChannelSide::left>(leftHits[1].time, leftHits[1].light);
189 // AddChannelSignal<ChannelSide::right>(rightHits[1].time, rightHits[1].light);
190 // SetExpectCall();
191 // const auto& signals = paddle->GetSignals();
192 // ASSERT_EQ(signals.size(), 1) << "inequal number of channel signals are not paired correctly!";
193 // }
194
195 // TEST_F(testNeulandPaddle, check_coupling_badParing) // NOLINT
196 // {
197 // FairLogger::GetLogger()->SetLogScreenLevel("error");
198 // auto* paddle = GetPaddle();
199 // paddle->DepositLight(PaddleHit{ 10., 20., 0.5 * NeulandPaddle::gHalfLength });
200 // paddle->DepositLight(PaddleHit{ 60., 10., -0.3 * NeulandPaddle::gHalfLength });
201 // const auto& leftHits = GetChannels().left->hits_;
202 // const auto& rightHits = GetChannels().right->hits_;
203 // AddChannelSignal<ChannelSide::left>(leftHits[0].time, leftHits[0].light);
204 // AddChannelSignal<ChannelSide::left>(leftHits[0].time, leftHits[0].light);
205 // AddChannelSignal<ChannelSide::right>(rightHits[0].time, rightHits[0].light);
206 // AddChannelSignal<ChannelSide::right>(rightHits[1].time, rightHits[1].light);
207 // SetExpectCall();
208 // const auto& signals = paddle->GetSignals();
209 // ASSERT_EQ(signals.size(), 1) << "recursive paring is not prohibited!";
210 // }
211} // namespace