R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
testNeulandDigitizingTamex.cxx
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
3 * Copyright (C) 2019 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
15#include "R3BDigitizingTamex.h"
16#include "R3BShared.h"
17#include "gtest/gtest.h"
18#include <memory>
19#include <vector>
20
21// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers)
22namespace
23{
24 namespace Digitizing = R3B::Digitizing;
25 using TmxChannel = Digitizing::Neuland::Tamex::Channel;
26 using FQTPeak = Digitizing::Neuland::Tamex::FQTPeak;
27 using PMTPeak = Digitizing::Neuland::Tamex::PMTPeak;
28 using Channel = Digitizing::AbstractChannel;
29 using TmxPar = Digitizing::Neuland::Tamex::Params;
30
31 class testNeulandTamexChannel : public ::testing::Test
32 {
33 protected:
34 testNeulandTamexChannel()
35 : channel_{ std::make_unique<TmxChannel>(R3B::Side::left) }
36 {
37 auto par = channel_->GetPar();
38 SetChannelPar(par);
39 channel_->SetPar(par);
40 }
41
42 void SetUp() override {}
43
44 void SetPar(const TmxPar& par) { channel_->SetPar(par); }
45
46 void Construct() { channel_->Construct(); }
47
48 [[nodiscard]] auto GetChannel() const -> TmxChannel* { return channel_.get(); }
49
50 [[nodiscard]] auto GetPar() const -> const TmxPar& { return channel_->GetPar(); }
51
52 static void SetChannelPar(TmxPar& par)
53 {
54 par.pmt_thresh = 1.;
55 par.saturation_coefficient = 0.012;
56 par.experimental_data_is_corrected_for_saturation = true;
57 par.energy_gain = 15.0;
58 par.pedestal = 14.0;
59 par.max_time = 1000.;
60 par.min_time = 1.;
61 par.min_energy = 0.67;
62 }
63
64 void AddSignal(double time, double light) { channel_->add_signal({ time, light }); }
65
66 [[nodiscard]] auto GetSignals() const -> const Channel::Hits& { return channel_->GetHits(); }
67 [[nodiscard]] auto GetPMTPeaks() const -> const std::vector<PMTPeak>& { return channel_->GetPMTPeaks(); }
68 [[nodiscard]] auto GetPeaks() const -> const std::vector<FQTPeak>& { return channel_->GetFQTPeaks(); }
69
70 private:
71 std::unique_ptr<TmxChannel> channel_ = nullptr;
72 };
73
74 TEST_F(testNeulandTamexChannel, basic_hit_processing) // NOLINT
75 {
76 AddSignal(20., 20.);
77 Construct();
78
79 auto signals = GetSignals();
80 auto peaks = GetPeaks();
81
82 // check whether signal got lost
83 ASSERT_EQ(peaks.size(), 1) << "no peak is generated!";
84 ASSERT_EQ(signals.size(), 1) << "No channel signal is outputted!";
85
86 // check PMT saturation
87 ASSERT_LT(peaks[0].GetEnergy(), 20.) << "PMT saturation is not implemented!";
88 ASSERT_NE(signals[0].tdc, 20.) << "tdc value is not smeared!";
89 }
90
91 TEST_F(testNeulandTamexChannel, pmt_threshold_check) // NOLINT
92 {
93 AddSignal(20., 0.5);
94 Construct();
95 auto signals = GetSignals();
96 auto peaks = GetPeaks();
97 ASSERT_EQ(signals.size(), 0) << "PMT threshold doesn't filter out low energy signals!";
98 }
99
100 TEST_F(testNeulandTamexChannel, pmt_threshold_overlap) // NOLINT
101 {
102 AddSignal(20., 0.5);
103 AddSignal(20., 0.5);
104 AddSignal(20., 0.5);
105 AddSignal(20., 0.5);
106 Construct();
107 auto signals = GetSignals();
108 auto peaks = GetPeaks();
109 ASSERT_EQ(signals.size(), 1) << "overlapped signals cannot pass PMT threshold!";
110 }
111
112 TEST_F(testNeulandTamexChannel, ifno_timeRes_check) // NOLINT
113 {
114 auto par = GetPar();
115 par.time_res = 0.0;
116 SetPar(par);
117
118 AddSignal(20., 20.);
119 Construct();
120 const auto& signals = GetSignals();
121 ASSERT_DOUBLE_EQ(signals[0].tdc, 20.) << "tdc value is not correctly passed on!";
122 }
123
124 TEST_F(testNeulandTamexChannel, signal_pileup_check) // NOLINT
125 {
126 AddSignal(20., 20.);
127 AddSignal(20., 1.5);
128 Construct();
129 ASSERT_EQ(GetSignals().size(), 1) << "overlapping failed!";
130
131 auto width = GetPeaks().back().GetToT();
132 AddSignal(width + 21., 1.5);
133 Construct();
134 ASSERT_EQ(GetSignals().size(), 2) << "should not be overlapped!";
135 }
136
137 // TODO: this test is highly depenedent on how signals are piled up. Therefore, it's better to have different tests
138 // for different pileup strategy.
139 TEST_F(testNeulandTamexChannel, signal_multiPileup_check) // NOLINT
140 {
141 AddSignal(20., 5.);
142 Construct();
143 ASSERT_EQ(GetSignals().size(), 1);
144 AddSignal(GetPeaks().back().GetTETime() + 5., 5.);
145 Construct();
146 ASSERT_EQ(GetSignals().size(), 2);
147 AddSignal(GetPeaks().back().GetTETime() + 5., 5.);
148 Construct();
149 ASSERT_EQ(GetSignals().size(), 3);
150 AddSignal(GetPeaks().back().GetTETime() + 5., 5.);
151 Construct();
152 ASSERT_EQ(GetSignals().size(), 4);
153 AddSignal(GetPeaks().back().GetTETime() + 5., 5.);
154 Construct();
155 ASSERT_EQ(GetSignals().size(), 5);
156 auto minTime = GetPeaks().front().GetLETime();
157 auto maxTime = GetPeaks().back().GetTETime();
158 auto qdc_test = FQTPeak::ToT2Energy(maxTime - minTime + 10., GetPar());
159 AddSignal(minTime - 5., qdc_test);
160 Construct();
161 ASSERT_EQ(GetSignals().size(), 1);
162 }
163
164 constexpr auto AssessReduction(double inE, double outE) { return (inE - outE) / inE; }
165
166 TEST_F(testNeulandTamexChannel, PMT_saturation_check) // NOLINT
167 {
168 const auto lowE = 10.;
169 const auto highE = 40.;
170
171 AddSignal(20., lowE);
172 AddSignal(200., highE);
173 Construct();
174 const auto& pmtSignals = GetPMTPeaks();
175 ASSERT_EQ(pmtSignals.size(), 2);
176 const auto lowE_out = pmtSignals[0].GetHeight();
177 const auto highE_out = pmtSignals[1].GetHeight();
178 ASSERT_LT(AssessReduction(lowE, lowE_out), AssessReduction(highE, highE_out)) << "PMT saturation not applied!";
179 }
180} // namespace
181// NOLINTEND(cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers)
Side
Definition R3BShared.h:113