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