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 "gtest/gtest.h"
17
18namespace
19{
20 namespace Digitizing = R3B::Digitizing;
21 using TmxChannel = Digitizing::Neuland::Tamex::Channel;
24 using Channel = Digitizing::Channel;
26
27 class testNeulandTamexChannel : public ::testing::Test
28 {
29 protected:
30 testNeulandTamexChannel()
31 : fChannel{ std::make_unique<TmxChannel>(Digitizing::ChannelSide::left) }
32 {
33 SetChannelPar(fChannel->GetPar());
34 }
35
36 void SetUp() override {}
37
38 [[nodiscard]] auto GetChannel() const -> TmxChannel* { return fChannel.get(); }
39
40 [[nodiscard]] auto GetPar() const -> TmxPar& { return fChannel->GetPar(); }
41
42 static void SetChannelPar(TmxPar& par)
43 {
44 par.fPMTThresh = 1.;
45 par.fSaturationCoefficient = 0.012;
46 par.fExperimentalDataIsCorrectedForSaturation = true;
47 par.fEnergyGain = 15.0;
48 par.fPedestal = 14.0;
49 par.fTimeMax = 1000.;
50 par.fTimeMin = 1.;
51 par.fQdcMin = 0.67;
52 }
53
54 void AddHit(double time, double light) { fChannel->AddHit({ time, light }); }
55
56 [[nodiscard]] auto GetSignals() const -> const Channel::Signals& { return fChannel->GetSignals(); }
57 [[nodiscard]] auto GetPMTPeaks() const -> const std::vector<PMTPeak>& { return fChannel->GetPMTPeaks(); }
58 [[nodiscard]] auto GetPeaks() const -> const std::vector<FQTPeak>& { return fChannel->GetFQTPeaks(); }
59
60 private:
61 std::unique_ptr<TmxChannel> fChannel = nullptr;
62 };
63
64 TEST_F(testNeulandTamexChannel, basic_hit_processing) // NOLINT
65 {
66 AddHit(20., 20.);
67 auto signals = GetSignals();
68 auto peaks = GetPeaks();
69
70 // check whether signal got lost
71 ASSERT_EQ(peaks.size(), 1) << "no peak is generated!";
72 ASSERT_EQ(signals.size(), 1) << "No channel signal is outputted!";
73
74 // check PMT saturation
75 ASSERT_LT(peaks[0].GetQDC(), 20.) << "PMT saturation is not implemented!";
76 ASSERT_NE(signals[0].tdc, 20.) << "tdc value is not smeared!";
77 }
78
79 TEST_F(testNeulandTamexChannel, pmt_threshold_check) // NOLINT
80 {
81 AddHit(20., 0.5);
82 auto signals = GetSignals();
83 auto peaks = GetPeaks();
84 ASSERT_EQ(signals.size(), 0) << "PMT threshold doesn't filter out low energy signals!";
85 }
86
87 TEST_F(testNeulandTamexChannel, pmt_threshold_overlap) // NOLINT
88 {
89 AddHit(20., 0.5);
90 AddHit(20., 0.5);
91 AddHit(20., 0.5);
92 AddHit(20., 0.5);
93 auto signals = GetSignals();
94 auto peaks = GetPeaks();
95 ASSERT_EQ(signals.size(), 1) << "overlapped signals cannot pass PMT threshold!";
96 }
97
98 TEST_F(testNeulandTamexChannel, ifno_timeRes_check) // NOLINT
99 {
100 decltype(auto) par = GetPar();
101 par.fTimeRes = 0.0;
102
103 AddHit(20., 20.);
104 const auto& signals = GetSignals();
105 ASSERT_DOUBLE_EQ(signals[0].tdc, 20.) << "tdc value is not correctly passed on!";
106 }
107
108 TEST_F(testNeulandTamexChannel, signal_pileup_check) // NOLINT
109 {
110 AddHit(20., 20.);
111 AddHit(20., 1.5);
112 ASSERT_EQ(GetSignals().size(), 1) << "overlapping failed!";
113
114 auto width = GetPeaks().back().GetWidth();
115 AddHit(width + 21., 1.5);
116 ASSERT_EQ(GetSignals().size(), 2) << "should not be overlapped!";
117 }
118
119 // TODO: this test is highly depenedent on how signals are piled up. Therefore, it's better to have different tests
120 // for different pileup strategy.
121 TEST_F(testNeulandTamexChannel, signal_multiPileup_check) // NOLINT
122 {
123 AddHit(20., 5.);
124 ASSERT_EQ(GetSignals().size(), 1);
125 AddHit(GetPeaks().back().GetTETime() + 5., 5.);
126 ASSERT_EQ(GetSignals().size(), 2);
127 AddHit(GetPeaks().back().GetTETime() + 5., 5.);
128 ASSERT_EQ(GetSignals().size(), 3);
129 AddHit(GetPeaks().back().GetTETime() + 5., 5.);
130 ASSERT_EQ(GetSignals().size(), 4);
131 AddHit(GetPeaks().back().GetTETime() + 5., 5.);
132 ASSERT_EQ(GetSignals().size(), 5);
133 auto minTime = GetPeaks().front().GetLETime();
134 auto maxTime = GetPeaks().back().GetTETime();
135 auto qdc_test = FQTPeak::WidthToQdc(maxTime - minTime + 10., GetPar());
136 AddHit(minTime - 5., qdc_test);
137 ASSERT_EQ(GetSignals().size(), 1);
138 }
139
140 constexpr auto AssessReduction(double inE, double outE) { return (inE - outE) / inE; }
141
142 TEST_F(testNeulandTamexChannel, PMT_saturation_check) // NOLINT
143 {
144 const auto lowE = 10.;
145 const auto highE = 40.;
146
147 AddHit(20., lowE);
148 AddHit(200., highE);
149 const auto& pmtSignals = GetPMTPeaks();
150 ASSERT_EQ(pmtSignals.size(), 2);
151 const auto lowE_out = pmtSignals[0].GetQDC();
152 const auto highE_out = pmtSignals[1].GetQDC();
153 ASSERT_LT(AssessReduction(lowE, lowE_out), AssessReduction(highE, highE_out)) << "PMT saturation not applied!";
154 }
155} // namespace