GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
TDescantHit.cxx
Go to the documentation of this file.
1#include "TDescantHit.h"
2
3#include <iostream>
4#include <algorithm>
5#include <climits>
6
7#include "TDescant.h"
8#include "TGRSIOptions.h"
9
14
16{
17 Clear();
18 rhs.Copy(*this);
19}
20
22{
23 frag.Copy(*this);
24
25 SetZc(frag.GetZc());
26 SetCcShort(frag.GetCcShort());
27 SetCcLong(frag.GetCcLong());
28
29 // if(TDescant::SetWave()) {
30 if(TGRSIOptions::Get()->ExtractWaves()) {
31 if(frag.GetWaveform()->empty()) {
32 }
33 frag.CopyWave(*this);
34 if(!GetWaveform()->empty()) {
36 }
37 }
38}
39
40void TDescantHit::Copy(TObject& rhs) const
41{
43 if(TGRSIOptions::Get()->ExtractWaves()) {
45 }
46 static_cast<TDescantHit&>(rhs).fFilter = fFilter;
47 static_cast<TDescantHit&>(rhs).fZc = fZc;
48 static_cast<TDescantHit&>(rhs).fCcShort = fCcShort;
49 static_cast<TDescantHit&>(rhs).fCcLong = fCcLong;
50 static_cast<TDescantHit&>(rhs).fPsd = fPsd;
51 static_cast<TDescantHit&>(rhs).fCfdMonitor = fCfdMonitor;
52 static_cast<TDescantHit&>(rhs).fPartialSum = fPartialSum;
53}
54
55void TDescantHit::Copy(TObject& obj, bool waveform) const
56{
57 Copy(obj);
58 if(waveform) {
59 CopyWave(obj);
60 }
61}
62
63TVector3 TDescantHit::GetPosition(Double_t dist) const
64{
65 /// TDetectorHit::GetPosition
66 return TDescant::GetPosition(GetDetector(), dist);
67}
68
73
75{
76 /// check if the desired filter is in wanted filter;
77 /// return the answer;
78 return true;
79}
80
81Float_t TDescantHit::GetCfd() const
82{
83 /// special function for TDescantHit to return CFD after mapping out the high bits
84 /// which are the remainder between the 125 MHz data and the 100 MHz timestamp clock
85 return static_cast<Float_t>(static_cast<Int_t>(TDetectorHit::GetCfd()) & 0x3fffff) + static_cast<Float_t>(gRandom->Uniform());
86}
87
89{
90 /// returns the remainder between 100 MHz/10ns timestamp and 125 MHz/8 ns data in ns
91 return static_cast<Int_t>(TDetectorHit::GetCfd()) >> 22;
92}
93
94void TDescantHit::Clear(Option_t*)
95{
96 fFilter = 0;
97 fPsd = -1;
98 fZc = 0;
99 fCcShort = 0;
100 fCcLong = 0;
101 fCfdMonitor.clear();
102 fPartialSum.clear();
104}
105
106void TDescantHit::Print(Option_t*) const
107{
108 Print(std::cout);
109}
110
111void TDescantHit::Print(std::ostream& out) const
112{
113 std::ostringstream str;
114 str << "Descant Detector: " << GetDetector() << std::endl;
115 str << "Descant hit energy: " << GetEnergy() << std::endl;
116 str << "Descant hit time: " << GetTime() << std::endl;
117 out << str.str();
118}
119
121{
122 bool error = false;
123
124 if(!HasWave()) {
125 return false; // Error!
126 }
127 std::vector<Int_t> baselineCorrections(8, 0);
128 std::vector<Short_t> newWaveform;
129
130 // all timing algorithms use interpolation with this many steps between two samples (all times are stored as
131 // integers)
132 unsigned int interpolationSteps = 256;
133 int delay = 8;
134 double attenuation = 24. / 64.;
135 int halfSmoothingWindow = 0; // 2*halfsmoothingwindow + 1 = number of samples in moving window.
136
137 // baseline algorithm: correct each adc with average of first two samples in that adc
138 for(size_t i = 0; i < 8 && i < WaveSize(); ++i) {
139 baselineCorrections[i] = GetWaveform()->at(i);
140 }
141 for(size_t i = 8; i < 16 && i < WaveSize(); ++i) {
142 baselineCorrections[i - 8] =
143 ((baselineCorrections[i - 8] + GetWaveform()->at(i)) + ((baselineCorrections[i - 8] + GetWaveform()->at(i)) > 0 ? 1 : -1)) >>
144 1; // Average
145 }
146 for(size_t i = 0; i < WaveSize(); ++i) {
147 newWaveform[i] -= baselineCorrections[i % 8];
148 }
149 SetWaveform(newWaveform);
150
151 SetCfd(CalculateCfd(attenuation, delay, halfSmoothingWindow, interpolationSteps));
152
153 // PSD
154 // time to zero-crossing algorithm: time when sum reaches n% of the total sum minus the cfd time
155 double fraction = 0.90;
156
157 SetPsd(CalculatePsd(fraction, interpolationSteps));
158
160
161 if(fPsd < 0) {
162 error = true;
163 }
164
165 return !(error);
166}
167
168Int_t TDescantHit::CalculateCfd(double attenuation, unsigned int delay, int halfsmoothingwindow,
169 unsigned int interpolation_steps)
170{
171
172 std::vector<Short_t> monitor;
173
174 return CalculateCfdAndMonitor(attenuation, delay, halfsmoothingwindow, interpolation_steps, monitor);
175}
176
177Int_t TDescantHit::CalculateCfdAndMonitor(double attenuation, unsigned int delay, int halfSmoothingWindow,
178 unsigned int interpolationSteps, std::vector<Short_t>& monitor)
179{
180
181 Short_t monitormax = 0;
182 bool armed = false;
183
184 Int_t cfd = 0;
185 if(!HasWave()) {
186 return INT_MAX; // Error!
187 }
188 std::vector<Short_t> smoothedWaveform;
189
190 if(WaveSize() > delay + 1) {
191 if(halfSmoothingWindow > 0) {
192 smoothedWaveform = TDescantHit::CalculateSmoothedWaveform(halfSmoothingWindow);
193 } else {
194 smoothedWaveform = *GetWaveform();
195 }
196
197 monitor.clear();
198 monitor.resize(smoothedWaveform.size() - delay);
199 monitor[0] = static_cast<Short_t>(attenuation * smoothedWaveform[delay] - smoothedWaveform[0]);
200 if(monitor[0] > monitormax) {
201 armed = true;
202 monitormax = monitor[0];
203 }
204
205 for(size_t i = delay + 1; i < smoothedWaveform.size(); ++i) {
206 monitor[i - delay] = static_cast<Short_t>(attenuation * smoothedWaveform[i] - smoothedWaveform[i - delay]);
207 if(monitor[i - delay] > monitormax) {
208 armed = true;
209 monitormax = monitor[i - delay];
210 } else {
211 if(armed && monitor[i - delay] < 0) {
212 armed = false;
213 if(monitor[i - delay - 1] - monitor[i - delay] != 0) {
214 // Linear interpolation.
215 cfd = (i - delay - 1) * interpolationSteps +
216 (monitor[i - delay - 1] * interpolationSteps) / (monitor[i - delay - 1] - monitor[i - delay]);
217 } else {
218 // Should be impossible, since monitor[i-delay-1] => 0 and monitor[i-delay] > 0
219 cfd = 0;
220 }
221 }
222 }
223 }
224 } else {
225 monitor.resize(0);
226 }
227
228 if(TGRSIOptions::Get()->Debug()) {
229 fCfdMonitor = monitor;
230 }
231
232 // correct for remainder between the 100MHz timestamp and the 125MHz start of the waveform
233 // we save this in the upper bits, otherwise we can't correct the waveform themselves
234 cfd = (cfd & 0x3fffff) | (static_cast<Int_t>(TDetectorHit::GetCfd()) & 0x7c00000);
235
236 return cfd;
237}
238
239std::vector<Short_t> TDescantHit::CalculateSmoothedWaveform(unsigned int halfSmoothingWindow)
240{
241
242 if(!HasWave()) {
243 return {}; // Error!
244 }
245
246 std::vector<Short_t> smoothedWaveform(std::max((static_cast<size_t>(0)), WaveSize() - 2 * halfSmoothingWindow),
247 0);
248
249 for(size_t i = halfSmoothingWindow; i < WaveSize() - halfSmoothingWindow; ++i) {
250 for(int j = -static_cast<int>(halfSmoothingWindow); j <= static_cast<int>(halfSmoothingWindow); ++j) {
251 smoothedWaveform[i - halfSmoothingWindow] += GetWaveform()->at(i + j);
252 }
253 }
254
255 return smoothedWaveform;
256}
257
258std::vector<Short_t> TDescantHit::CalculateCfdMonitor(double attenuation, unsigned int delay,
259 unsigned int halfSmoothingWindow)
260{
261 if(!HasWave()) {
262 return {}; // Error!
263 }
264 std::vector<Short_t> smoothedWaveform;
265
266 if(halfSmoothingWindow > 0) {
267 smoothedWaveform = TDescantHit::CalculateSmoothedWaveform(halfSmoothingWindow);
268 } else {
269 smoothedWaveform = *GetWaveform();
270 }
271
272 std::vector<Short_t> monitor(std::max((static_cast<size_t>(0)), smoothedWaveform.size() - delay), 0);
273
274 for(size_t i = delay; i < WaveSize(); ++i) {
275 monitor[i - delay] = static_cast<Short_t>(attenuation * smoothedWaveform[i] - smoothedWaveform[i - delay]);
276 }
277
278 return monitor;
279}
280
282{
283 if(!HasWave()) {
284 return {}; // Error!
285 }
286
287 std::vector<Int_t> partialSums(WaveSize(), 0);
288
289 partialSums[0] = GetWaveform()->at(0);
290 for(size_t i = 1; i < WaveSize(); ++i) {
291 partialSums[i] = partialSums[i - 1] + GetWaveform()->at(i);
292 }
293
294 if(TGRSIOptions::Get()->Debug()) {
295 fPartialSum = partialSums;
296 }
297
298 return partialSums;
299}
300
301Int_t TDescantHit::CalculatePsd(double fraction, unsigned int interpolationSteps)
302{
303 std::vector<Int_t> partialSums;
304
305 return CalculatePsdAndPartialSums(fraction, interpolationSteps, partialSums);
306}
307
308Int_t TDescantHit::CalculatePsdAndPartialSums(double fraction, unsigned int interpolationSteps,
309 std::vector<Int_t>& partialSums)
310{
311 Int_t psd = 0;
312
313 partialSums = CalculatePartialSum();
314 if(partialSums.empty()) {
315 return -1;
316 }
317 int totalSum = partialSums.back();
318
319 fPsd = -1;
320 if(partialSums[0] < fraction * totalSum) {
321 for(size_t i = 1; i < partialSums.size(); ++i) {
322 if(partialSums[i] >= fraction * totalSum) {
323 psd = static_cast<Int_t>(static_cast<double>(i * interpolationSteps) - ((partialSums[i] - fraction * totalSum) * interpolationSteps) / GetWaveform()->at(i));
324 break;
325 }
326 }
327 }
328
329 return psd;
330}
std::vector< int > fPartialSum
Definition TDescantHit.h:36
std::vector< Short_t > CalculateCfdMonitor(double attenuation, unsigned int delay, unsigned int halfSmoothingWindow)
!
void SetCcLong(const int &x)
!
Definition TDescantHit.h:44
void SetCcShort(const int &x)
!
Definition TDescantHit.h:43
Int_t fCcLong
Definition TDescantHit.h:34
bool InFilter(Int_t)
!
Int_t CalculatePsd(double fraction, unsigned int interpolationSteps)
!
Int_t fCcShort
Definition TDescantHit.h:33
Int_t CalculatePsdAndPartialSums(double fraction, unsigned int interpolationSteps, std::vector< Int_t > &partialSums)
!
Int_t fFilter
Definition TDescantHit.h:30
std::vector< Int_t > CalculatePartialSum()
!
void Print(Option_t *opt="") const override
!
void Clear(Option_t *opt="") override
!
std::vector< int16_t > fCfdMonitor
Definition TDescantHit.h:35
Int_t CalculateCfdAndMonitor(double attenuation, unsigned int delay, int halfSmoothingWindow, unsigned int interpolationSteps, std::vector< Short_t > &monitor)
!
Int_t GetRemainder() const
void SetPsd(const int &x)
!
Definition TDescantHit.h:41
void Copy(TObject &) const override
!
TVector3 GetPosition() const override
!
Double_t GetDefaultDistance() const
Definition TDescantHit.h:87
std::vector< Short_t > CalculateSmoothedWaveform(unsigned int halfSmoothingWindow)
!
Int_t CalculateCfd(double attenuation, unsigned int delay, int halfsmoothingwindow, unsigned int interpolation_steps)
!
bool AnalyzeWaveform()
!
Float_t GetCfd() const override
!
void SetZc(const int &x)
!
Definition TDescantHit.h:42
static TVector3 GetPosition(int DetNbr, double dist=222)
!
Definition TDescant.cxx:150
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
!
Int_t GetCcLong() const
Definition TFragment.h:65
Int_t GetZc() const
Definition TFragment.h:87
Int_t GetCcShort() const
Definition TFragment.h:66
static TGRSIOptions * Get(int argc=0, char **argv=nullptr)
Do not use!