GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
TZeroDegreeHit.cxx
Go to the documentation of this file.
1#include "TZeroDegreeHit.h"
2
3#include <iostream>
4#include <algorithm>
5#include <climits>
6
7#include "TGRSIOptions.h"
8
10{
11 // Default Constructor
12 Clear();
13}
14
16{
17 frag.Copy(*this);
18 if(TGRSIOptions::Get()->ExtractWaves()) {
19 if(frag.GetWaveform()->empty()) {
20 std::cout << "Warning, TZeroDegree::SetWave() set, but data waveform size is zero!" << std::endl;
21 } else {
22 frag.CopyWave(*this);
23 }
24 if(!GetWaveform()->empty()) {
26 }
27 }
28}
29
31{
32 // Copy Constructor
33 Clear();
34 rhs.Copy(*this);
35}
36
37void TZeroDegreeHit::Copy(TObject& rhs) const
38{
39 /// Copies a TZeroDegreeHit
41 if(TGRSIOptions::Get()->ExtractWaves()) {
43 }
44 static_cast<TZeroDegreeHit&>(rhs).fFilter = fFilter;
45 static_cast<TZeroDegreeHit&>(rhs).fCfdMonitor = fCfdMonitor;
46 static_cast<TZeroDegreeHit&>(rhs).fPartialSum = fPartialSum;
47}
48
49void TZeroDegreeHit::Copy(TObject& obj, bool waveform) const
50{
51 Copy(obj);
52 if(waveform) {
53 CopyWave(obj);
54 }
55}
56
58{
59 /// check if the desired filter is in wanted filter;
60 /// return the answer;
61 return true;
62}
63
65{
66 /// special function for TZeroDegreeHit to return CFD after mapping out the high bits
67 /// which are the remainder between the 125 MHz data and the 100 MHz timestamp clock
68 return static_cast<Float_t>(static_cast<Int_t>(TDetectorHit::GetCfd()) & 0x3fffff) + static_cast<Float_t>(gRandom->Uniform());
69}
70
72{
73 /// returns the remainder between 100 MHz/10ns timestamp and 125 MHz/8 ns data in ns
74 return static_cast<Int_t>(TDetectorHit::GetCfd()) >> 22;
75}
76
77void TZeroDegreeHit::Clear(Option_t*)
78{
79 /// Clears the ZeroDegreeHit
80 fFilter = 0;
82 fCfdMonitor.clear();
83 fPartialSum.clear();
84}
85
86void TZeroDegreeHit::Print(Option_t*) const
87{
88 ///Prints the ZeroDegreeHit. Returns:
89 ///Detector
90 ///Energy
91 ///Time
92 Print(std::cout);
93}
94
95void TZeroDegreeHit::Print(std::ostream& out) const
96{
97 std::ostringstream str;
98 str << "ZeroDegree Detector: " << GetDetector() << std::endl;
99 str << "ZeroDegree hit energy: " << GetEnergy() << std::endl;
100 str << "ZeroDegree hit time: " << GetTime() << std::endl;
101 out << str.str();
102}
103
105{
106 /// Calculates the cfd time from the waveform
107 bool error = false;
108 if(!HasWave()) {
109 return false; // Error!
110 }
111
112 std::vector<Int_t> baselineCorrections(8, 0);
113 std::vector<Short_t> newWaveform(*GetWaveform());
114
115 // all timing algorithms use interpolation with this many steps between two samples (all times are stored as
116 // integers)
117 unsigned int interpolationSteps = 256;
118 int delay = 2;
119 double attenuation = 24. / 64.;
120 int halfsmoothingwindow = 0; // 2*halfsmoothingwindow + 1 = number of samples in moving window.
121
122 // baseline algorithm: correct each adc with average of first two samples in that adc
123 for(size_t i = 0; i < 8 && i < WaveSize(); ++i) {
124 baselineCorrections[i] = GetWaveform()->at(i);
125 }
126 for(size_t i = 8; i < 16 && i < WaveSize(); ++i) {
127 baselineCorrections[i - 8] = ((baselineCorrections[i - 8] + GetWaveform()->at(i)) + ((baselineCorrections[i - 8] + GetWaveform()->at(i)) > 0 ? 1 : -1)) >> 1;
128 }
129 for(size_t i = 0; i < WaveSize(); ++i) {
130 newWaveform[i] -= baselineCorrections[i % 8];
131 }
132 SetWaveform(newWaveform);
133
134 SetCfd(CalculateCfd(attenuation, delay, halfsmoothingwindow, interpolationSteps));
135
137
138 return !error;
139}
140
141Int_t TZeroDegreeHit::CalculateCfd(double attenuation, unsigned int delay, int halfsmoothingwindow,
142 unsigned int interpolationSteps)
143{
144 /// Used when calculating the CFD from the waveform
145 std::vector<Short_t> monitor;
146
147 return CalculateCfdAndMonitor(attenuation, delay, halfsmoothingwindow, interpolationSteps, monitor);
148}
149
150Int_t TZeroDegreeHit::CalculateCfdAndMonitor(double attenuation, unsigned int delay, int halfsmoothingwindow,
151 unsigned int interpolationSteps, std::vector<Short_t>& monitor)
152{
153 /// Used when calculating the CFD from the waveform
154
155 Short_t monitormax = 0;
156
157 bool armed = false;
158
159 Int_t cfd = 0;
160
161 std::vector<Short_t> smoothedWaveform;
162
163 if(!HasWave()) {
164 return INT_MAX; // Error!
165 }
166
167 if(static_cast<unsigned int>(WaveSize()) > delay + 1) {
168
169 if(halfsmoothingwindow > 0) {
170 smoothedWaveform = TZeroDegreeHit::CalculateSmoothedWaveform(halfsmoothingwindow);
171 } else {
172 smoothedWaveform = *GetWaveform();
173 }
174
175 monitor.resize(smoothedWaveform.size() - delay);
176 monitor[0] = static_cast<Short_t>(attenuation * smoothedWaveform[delay] - smoothedWaveform[0]);
177 if(monitor[0] > monitormax) {
178 armed = true;
179 monitormax = monitor[0];
180 }
181
182 for(unsigned int i = delay + 1; i < smoothedWaveform.size(); ++i) {
183 monitor[i - delay] = static_cast<Short_t>(attenuation * smoothedWaveform[i] - smoothedWaveform[i - delay]);
184 if(monitor[i - delay] > monitormax) {
185 armed = true;
186 monitormax = monitor[i - delay];
187 } else {
188 if(armed && monitor[i - delay] < 0) {
189 armed = false;
190 if(monitor[i - delay - 1] - monitor[i - delay] != 0) {
191 // Linear interpolation.
192 cfd = (i - delay - 1) * interpolationSteps +
193 (monitor[i - delay - 1] * interpolationSteps) / (monitor[i - delay - 1] - monitor[i - delay]);
194 } else {
195 // Should be impossible, since monitor[i-delay-1] => 0 and monitor[i-delay] > 0
196 cfd = 0;
197 }
198 }
199 }
200 }
201 } else {
202 monitor.resize(0);
203 }
204
205 if(TGRSIOptions::Get()->Debug()) {
206 fCfdMonitor = monitor;
207 }
208
209 // correct for remainder between the 100MHz timestamp and the 125MHz start of the waveform
210 // we save this in the upper bits, otherwise we can't correct the waveform themselves
211 cfd = (cfd & 0x3fffff) | (static_cast<Int_t>(TDetectorHit::GetCfd()) & 0x7c00000);
212
213 return cfd;
214}
215
216std::vector<Short_t> TZeroDegreeHit::CalculateSmoothedWaveform(unsigned int halfsmoothingwindow)
217{
218 /// Used when calculating the CFD from the waveform
219
220 if(!HasWave()) {
221 return {}; // Error!
222 }
223
224 std::vector<Short_t> smoothedWaveform(std::max(static_cast<size_t>(0), WaveSize() - 2 * halfsmoothingwindow),
225 0);
226
227 for(size_t i = halfsmoothingwindow; i < WaveSize() - halfsmoothingwindow; ++i) {
228 for(int j = -static_cast<int>(halfsmoothingwindow); j <= static_cast<int>(halfsmoothingwindow); ++j) {
229 smoothedWaveform[i - halfsmoothingwindow] += GetWaveform()->at(i + j);
230 }
231 }
232
233 return smoothedWaveform;
234}
235
236std::vector<Short_t> TZeroDegreeHit::CalculateCfdMonitor(double attenuation, int delay, int halfsmoothingwindow)
237{
238 /// Used when calculating the CFD from the waveform
239
240 if(!HasWave()) {
241 return {}; // Error!
242 }
243
244 std::vector<Short_t> smoothedWaveform;
245
246 if(halfsmoothingwindow > 0) {
247 smoothedWaveform = TZeroDegreeHit::CalculateSmoothedWaveform(halfsmoothingwindow);
248 } else {
249 smoothedWaveform = *GetWaveform();
250 }
251
252 std::vector<Short_t> monitor(std::max(static_cast<size_t>(0), smoothedWaveform.size() - delay), 0);
253
254 for(size_t i = delay; i < smoothedWaveform.size(); ++i) {
255 monitor[i - delay] = static_cast<Short_t>(attenuation * smoothedWaveform[i] - smoothedWaveform[i - delay]);
256 }
257
258 return monitor;
259}
260
262{
263
264 if(!HasWave()) {
265 return {}; // Error!
266 }
267
268 std::vector<Int_t> partialSums(WaveSize(), 0);
269
270 partialSums[0] = GetWaveform()->at(0);
271 for(size_t i = 1; i < WaveSize(); ++i) {
272 partialSums[i] = partialSums[i - 1] + GetWaveform()->at(i);
273 }
274
275 if(TGRSIOptions::Get()->Debug()) {
276 fPartialSum = partialSums;
277 }
278
279 return partialSums;
280}
virtual void SetCfd(const Float_t &val)
!
virtual double GetEnergy(Option_t *opt="") const
void SetWaveform(const std::vector< Short_t > &val)
!
const std::vector< Short_t > * GetWaveform() const
!
void SetCharge(const Float_t &temp_charge)
!
void Clear(Option_t *opt="") override
!
virtual Int_t GetDetector() const
!
virtual Float_t GetCfd() const
!
void Copy(TObject &) const override
!
virtual Double_t GetTime(const ETimeFlag &correct_flag=ETimeFlag::kAll, Option_t *opt="") const
Returns a time value to the nearest nanosecond!
virtual bool HasWave() const
!
virtual size_t WaveSize() const
!
virtual void CopyWave(TObject &) const
!
static TGRSIOptions * Get(int argc=0, char **argv=nullptr)
Do not use!
std::vector< Short_t > CalculateCfdMonitor(double attenuation, int delay, int halfsmoothingwindow)
!
Int_t CalculateCfd(double attenuation, unsigned int delay, int halfsmoothingwindow, unsigned int interpolationSteps)
!
void Clear(Option_t *opt="") override
!
void Print(Option_t *opt="") const override
!
std::vector< int > fPartialSum
Int_t GetRemainder() const
Float_t GetCfd() const override
!
std::vector< int16_t > fCfdMonitor
void Copy(TObject &) const override
!
std::vector< Int_t > CalculatePartialSum()
!
std::vector< Short_t > CalculateSmoothedWaveform(unsigned int halfsmoothingwindow)
!
bool InFilter(Int_t)
!
Int_t CalculateCfdAndMonitor(double attenuation, unsigned int delay, int halfsmoothingwindow, unsigned int interpolationSteps, std::vector< Short_t > &monitor)
!