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