ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
AtPSASimple2.cxx
Go to the documentation of this file.
1 #include "AtPSASimple2.h"
2 
3 #include "AtCalibration.h"
4 #include "AtEvent.h"
5 #include "AtHit.h"
6 #include "AtPad.h"
7 #include "AtRawEvent.h"
8 
9 #include <FairLogger.h>
10 
11 #include <Math/Point2D.h>
12 #include <Math/Point3D.h> // for PositionVector3D
13 #include <Math/Point3Dfwd.h> // for XYZPoint
14 #include <Math/Rotation3D.h>
15 #include <TSpectrum.h>
16 
17 #include <algorithm>
18 #include <array> // for array
19 #include <cmath>
20 #include <iostream> // for basic_ostream::operator<<
21 #include <map>
22 #include <memory> // for unique_ptr, make_unique
23 #include <utility> // for pair
24 #include <vector> // for vector
25 
26 //#ifdef _OPENMP
27 //#include <omp.h>
28 //#endif
31 
32 void AtPSASimple2::Analyze(AtRawEvent *rawEvent, AtEvent *event)
33 {
34 
35  Int_t hitNum = 0;
36  Double_t QEventTot = 0.0;
37  Double_t RhoVariance = 0.0;
38  Double_t RhoMean = 0.0;
39  Double_t Rho2 = 0.0;
40  std::map<Int_t, Int_t> PadMultiplicity;
41  std::array<Float_t, 512> mesh{};
42  mesh.fill(0);
43 
44  auto mcPointsMap = rawEvent->GetSimMCPointMap();
45  LOG(debug) << "MC Simulated points Map size " << mcPointsMap.size();
46 
47  //#pragma omp parallel for ordered schedule(dynamic,1) private(iPad)
48  for (const auto &pad : rawEvent->GetPads()) {
49 
50  LOG(debug) << "Running PSA on pad " << pad->GetPadNum();
51  Int_t PadNum = pad->GetPadNum();
52  Double_t gthreshold = getThreshold(pad->GetSizeID());
53 
54  Double_t QHitTot = 0.0;
55  XYZPoint HitPos;
56  ROOT::Math::Rotation3D HitPosRot;
57 
58  Bool_t fValidBuff = kTRUE;
59  Bool_t fValidThreshold = kTRUE;
60  Bool_t fValidDerivative = kTRUE;
61 
62  auto pos = pad->GetPadCoord();
63  Double_t zPos = 0;
64  Double_t charge = 0;
65  Int_t maxAdcIdx = 0;
66  Int_t numPeaks = 0;
67 
68  if (pos.X() < -9000 || pos.Y() < -9000) {
69  LOG(debug) << "Skipping pad, position is invalid";
70  continue;
71  }
72 
73  if (!(pad->IsPedestalSubtracted())) {
74  LOG(ERROR) << "Pedestal should be subtracted to use this class!";
75  }
76 
77  auto adc = pad->GetADC();
78  std::array<Double_t, 512> floatADC{};
79  std::array<Double_t, 512> dummy{};
80  std::array<Double_t, 512> bg{};
81  floatADC.fill(0);
82  dummy.fill(0);
83  bg.fill(0);
84 
85  if (fCalibration.IsGainFile()) {
86  adc = fCalibration.CalibrateGain(adc, PadNum);
87  }
88  if (fCalibration.IsJitterFile()) {
89  adc = fCalibration.CalibrateJitter(adc, PadNum);
90  }
91 
92  for (Int_t iTb = 0; iTb < fNumTbs; iTb++) {
93  floatADC[iTb] = adc[iTb];
94  QHitTot += adc[iTb];
95  bg[iTb] = adc[iTb];
96  }
97 
98  auto PeakFinder = std::make_unique<TSpectrum>();
99  if (fIsPeakFinder)
100  numPeaks = PeakFinder->SearchHighRes(floatADC.data(), dummy.data(), fNumTbs, 4.7, 5, fBackGroundSuppression, 3,
101  kTRUE, 3);
102  if (fIsMaxFinder)
103  numPeaks = 1;
104 
105  auto BGInter = std::make_unique<TSpectrum>();
106  if (fBackGroundInterp) {
107  BGInter->Background(bg.data(), fNumTbs, 6, TSpectrum::kBackDecreasingWindow, TSpectrum::kBackOrder2, kTRUE,
108  TSpectrum::kBackSmoothing7, kTRUE);
109  for (Int_t iTb = 1; iTb < fNumTbs; iTb++) {
110  floatADC[iTb] = floatADC[iTb] - bg[iTb];
111  if (floatADC[iTb] < 0)
112  floatADC[iTb] = 0;
113  }
114  }
115 
116  if (numPeaks == 0)
117  fValidBuff = kFALSE;
118  // continue;
119 
120  if (fValidBuff) {
121 
122  for (Int_t iPeak = 0; iPeak < numPeaks; iPeak++) {
123 
124  Float_t max = 0.0;
125  Float_t min = 0.0;
126  Int_t maxTime = 0;
127 
128  if (fIsPeakFinder) {
129  maxAdcIdx = (Int_t)(ceil((PeakFinder->GetPositionX())[iPeak]));
130  if (maxAdcIdx < 3 || maxAdcIdx > 509)
131  continue; // excluding the first and last 3 tb
132  }
133  // Int_t maxAdcIdx = *std::max_element(floatADC,floatADC+fNumTbs);
134 
135  if (fIsMaxFinder) {
136  for (Int_t ij = 20; ij < 500; ij++) // Excluding first and last 12 Time Buckets
137  {
138  if (floatADC[ij] > max) {
139  max = floatADC[ij];
140  maxTime = ij;
141  }
142  }
143 
144  maxAdcIdx = maxTime;
145  }
146  // Charge Correction due to mesh induction (base line)
147 
148  Double_t basecorr = 0.0;
149  Double_t slope = 0.0;
150  Int_t slope_cnt = 0;
151 
152  if (maxAdcIdx > 20)
153  for (Int_t i = 0; i < 10; i++) {
154 
155  basecorr += floatADC[maxAdcIdx - 8 - i];
156 
157  if (i < 5) {
158  slope = (floatADC[maxAdcIdx - i] - floatADC[maxAdcIdx - i - 1]); // Derivate for 5 Timebuckets
159  // if(slope<0 && floatADC[maxAdcIdx]<3500 && fIsBaseCorr && fIsMaxFinder)
160  // fValidDerivative = kFALSE; //3500 condition to avoid killing saturated pads
161  if (slope < 0 && fIsBaseCorr && fIsMaxFinder)
162  slope_cnt++;
163  }
164  }
165  // Calculation of the mean value of the peak time by interpolating the pulse
166 
167  Double_t timemax = 0.5 * (floatADC[maxAdcIdx - 1] - floatADC[maxAdcIdx + 1]) /
168  (floatADC[maxAdcIdx - 1] + floatADC[maxAdcIdx + 1] - 2 * floatADC[maxAdcIdx]);
169 
170  // Time Correction by Center of Gravity
171  Double_t TBCorr = 0.0;
172  Double_t TB_TotQ = 0.0;
173 
174  if (maxAdcIdx > 11) {
175  for (Int_t i = 0; i < 11; i++) {
176 
177  if (floatADC[maxAdcIdx - i + 10] > 0 && floatADC[maxAdcIdx - i + 10] < 4000) {
178  TBCorr += (floatADC[maxAdcIdx - i + 5] - basecorr / 10.0) *
179  (maxAdcIdx - i + 5); // Substract the baseline correction
180  TB_TotQ += floatADC[maxAdcIdx - i + 5] - basecorr / 10.0;
181  }
182  }
183  }
184  TBCorr = TBCorr / TB_TotQ;
185 
186  if (fIsBaseCorr)
187  charge = floatADC[maxAdcIdx] - basecorr / 10.0;
188  else
189  charge = floatADC[maxAdcIdx];
190 
191  if (fIsTimeCorr)
192  zPos = CalculateZGeo(TBCorr);
193  else
194  zPos = CalculateZGeo(maxAdcIdx);
195 
196  if (gthreshold > 0 && charge < gthreshold) {
197  fValidThreshold = false;
198  LOG(debug) << "Invalid threshold with charge: " << charge << " and threshold: " << gthreshold;
199  }
200  if (fIsMaxFinder && (maxTime < 20 || maxTime > 500)) {
201  fValidThreshold = kFALSE;
202  LOG(debug) << "Peak is outside valid time window (20,500) TBs.";
203  }
204 
205  if (fValidThreshold && fValidDerivative) {
206 
207  // Sum only if Hit is valid - We only sum once (iPeak==0) to account for the
208  // whole spectrum.
209  if (iPeak == 0)
210  QEventTot += QHitTot;
211 
212  auto &hit = event->AddHit(PadNum, XYZPoint(pos.X(), pos.Y(), zPos), charge);
213  LOG(debug) << "Added hit with ID" << hit.GetHitID();
214 
215  hit.SetTimeStamp(maxAdcIdx);
216  hit.SetTimeStampCorr(TBCorr);
217  hit.SetTimeStampCorrInter(timemax);
218 
219  hit.SetTraceIntegral(QHitTot);
220  // TODO: The charge of each hit is the total charge of the spectrum, so for double
221  // structures this is unrealistic.
222 
223  HitPos = hit.GetPosition();
224  Rho2 += HitPos.Mag2();
225  RhoMean += HitPos.Rho();
226  if ((pos.X() < -9000 || pos.Y() < -9000) && pad->GetPadNum() != -1)
227  std::cout << " AtPSASimple2::Analysis Warning! Wrong Coordinates for Pad : " << pad->GetPadNum()
228  << std::endl;
229 
230  // Tracking MC points
231  // if (mcPointsMap.size() > 0)
232  // TrackMCPoints(mcPointsMap, hit);
233 
234  for (Int_t iTb = 0; iTb < fNumTbs; iTb++)
235  mesh[iTb] += floatADC[iTb];
236 
237  } // Valid Threshold
238  } // Peak Loop
239 
240  // #pragma omp ordered
241  // if(fValidThreshold && fValidBuff)
242  // PadMultiplicity.insert(std::pair<Int_t,Int_t>(PadNum,PadHitNum));
243 
244  //#pragma omp ordered
245  PadMultiplicity.insert(std::pair<Int_t, Int_t>(pad->GetPadNum(), 1));
246 
247  } // if Valid Num Peaks
248  } // Pad Loop
249 
250  // RhoVariance = Rho2 - (pow(RhoMean, 2) / (event->GetNumHits()));
251  RhoVariance = Rho2 - (event->GetNumHits() * pow((RhoMean / event->GetNumHits()), 2));
252 
253  for (Int_t iTb = 0; iTb < fNumTbs; iTb++)
254  event->SetMeshSignal(iTb, mesh[iTb]);
255  event->SortHitArrayTime();
256  event->SetMultiplicityMap(PadMultiplicity);
257  event->SetRhoVariance(RhoVariance);
258  event->SetEventCharge(QEventTot);
259 }
260 
262 {
263  fIsBaseCorr = value;
264 }
265 
267 {
268  fIsTimeCorr = value;
269 }
270 
272 {
273  fBackGroundSuppression = kTRUE;
274 }
275 
277 {
278  fBackGroundInterp = kTRUE;
279 }
280 
282 {
283  fIsPeakFinder = kTRUE;
284  fIsMaxFinder = kFALSE;
285 }
286 
288 {
289  fIsMaxFinder = kTRUE;
290  fIsPeakFinder = kFALSE;
291 }
AtPad.h
AtEvent::GetNumHits
Int_t GetNumHits() const
Definition: AtEvent.h:108
AtRawEvent.h
AtEvent.h
AtCalibration::CalibrateGain
const trace & CalibrateGain(const trace &adc, Int_t padNum)
Definition: AtCalibration.cxx:73
AtPSA::CalculateZGeo
Double_t CalculateZGeo(Double_t peakIdx)
Definition: AtPSA.cxx:90
AtPSASimple2::SetBackGroundSuppression
void SetBackGroundSuppression()
Definition: AtPSASimple2.cxx:271
AtPSASimple2::SetBackGroundInterpolation
void SetBackGroundInterpolation()
Definition: AtPSASimple2.cxx:276
AtPSASimple2::SetMaxFinder
void SetMaxFinder()
Definition: AtPSASimple2.cxx:287
AtPSA::fNumTbs
Int_t fNumTbs
Definition: AtPSA.h:44
AtPSASimple2::SetTimeCorrection
void SetTimeCorrection(Bool_t value)
Definition: AtPSASimple2.cxx:266
AtEvent
Definition: AtEvent.h:22
AtRawEvent
Definition: AtRawEvent.h:34
XYZPoint
ROOT::Math::XYZPoint XYZPoint
Definition: AtPSASimple2.cxx:29
XYZPoint
ROOT::Math::XYZPoint XYZPoint
Definition: AtPatternCircle2D.h:18
AtRawEvent::GetPads
const PadVector & GetPads() const
Definition: AtRawEvent.h:131
AtPSASimple2
Definition: AtPSASimple2.h:20
AtPSA::getThreshold
Double_t getThreshold(int padSize=-1)
Definition: AtPSA.cxx:179
AtHit.h
AtPSASimple2.h
AtPSASimple2::SetPeakFinder
void SetPeakFinder()
Definition: AtPSASimple2.cxx:281
ClassImp
ClassImp(AtPSASimple2)
AtCalibration::IsJitterFile
Bool_t IsJitterFile()
Definition: AtCalibration.cxx:19
AtPSASimple2::Analyze
void Analyze(AtRawEvent *rawEvent, AtEvent *event) override
Definition: AtPSASimple2.cxx:32
AtCalibration.h
AtCalibration::CalibrateJitter
const trace & CalibrateJitter(const trace &adc, Int_t padNum)
Definition: AtCalibration.cxx:88
AtRawEvent::GetSimMCPointMap
std::multimap< Int_t, std::size_t > & GetSimMCPointMap()
Definition: AtRawEvent.h:137
AtEvent::SetMeshSignal
void SetMeshSignal(TraceArray mesharray)
Definition: AtEvent.h:105
AtCalibration::IsGainFile
Bool_t IsGainFile()
Definition: AtCalibration.cxx:14
AtPSASimple2::SetBaseCorrection
void SetBaseCorrection(Bool_t value)
Definition: AtPSASimple2.cxx:261