ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
AtPSASpectrum.cxx
Go to the documentation of this file.
1 #include "AtPSASpectrum.h"
2 
3 #include "AtHit.h"
4 #include "AtPad.h"
5 
6 #include <FairLogger.h>
7 
8 #include <Math/Point3D.h> // for PositionVector3D
9 #include <Math/Point3Dfwd.h> // for XYZPoint
10 #include <TSpectrum.h>
11 
12 #include <array> // for array
13 #include <cmath>
14 #include <memory> // for unique_ptr, make_unique
15 #include <numeric>
16 #include <utility> // for pair
17 
18 //#ifdef _OPENMP
19 //#include <omp.h>
20 //#endif
24 {
25  LOG(debug) << "Running PSA on pad " << pad->GetPadNum();
26  Int_t PadNum = pad->GetPadNum();
27  double padThreshold = getThreshold(pad->GetSizeID());
28 
29  XYZPoint pos{pad->GetPadCoord().X(), pad->GetPadCoord().Y(), 0};
30  XYZPoint posCorr{0, 0, 0};
31 
32  if (pos.X() < -9000 || pos.Y() < -9000) {
33  LOG(debug) << "Skipping pad, position is invalid";
34  return {};
35  }
36 
37  if (!(pad->IsPedestalSubtracted())) {
38  LOG(ERROR) << "Pedestal should be subtracted to use this class!";
39  }
40 
41  auto adc = pad->GetADC();
42  std::array<double, 512> floatADC = adc;
43  std::array<double, 512> dummy{};
44  floatADC.fill(0);
45  dummy.fill(0);
46 
47  double traceIntegral = std::accumulate(adc.begin(), adc.end(), 0.0);
48 
49  auto PeakFinder = std::make_unique<TSpectrum>();
50  auto numPeaks =
51  PeakFinder->SearchHighRes(floatADC.data(), dummy.data(), fNumTbs, 4.7, 5, fBackGroundSuppression, 3, kTRUE, 3);
52 
53  if (fBackGroundInterp) {
54  subtractBackground(floatADC);
55  }
56  HitVector hits;
57  // Create a hit for each peak
58  for (Int_t iPeak = 0; iPeak < numPeaks; iPeak++) {
59 
60  auto maxAdcIdx = (Int_t)(ceil((PeakFinder->GetPositionX())[iPeak]));
61  if (maxAdcIdx < 3 || maxAdcIdx > 509)
62  continue; // excluding the first and last 3 tb
63 
64  auto charge = floatADC[maxAdcIdx];
65  if (padThreshold > 0 && charge < padThreshold) {
66  LOG(debug) << "Invalid threshold with charge: " << charge << " and threshold: " << padThreshold;
67  continue;
68  }
69 
70  // Calculation of the mean value of the peak time by interpolating the pulse
71  Double_t timemax = 0.5 * (floatADC[maxAdcIdx - 1] - floatADC[maxAdcIdx + 1]) /
72  (floatADC[maxAdcIdx - 1] + floatADC[maxAdcIdx + 1] - 2 * floatADC[maxAdcIdx]);
73 
74  Double_t TBCorr = calcTbCorrection(floatADC, maxAdcIdx);
75 
76  if (fIsTimeCorr)
77  pos.SetZ(CalculateZGeo(TBCorr));
78  else
79  pos.SetZ(CalculateZGeo(maxAdcIdx));
80 
81  auto hit = std::make_unique<AtHit>(PadNum, pos, charge);
82 
83  hit->SetTimeStamp(maxAdcIdx);
84  hit->SetTimeStampCorr(TBCorr);
85  hit->SetTimeStampCorrInter(timemax);
86  hit->SetTraceIntegral(traceIntegral);
87  // TODO: The charge of each hit is the total charge of the spectrum, so for double
88  // structures this is unrealistic.
89 
90  hits.push_back(std::move(hit));
91  } // End loop over peaks
92  return hits;
93 }
94 
98 void AtPSASpectrum::subtractBackground(std::array<Double_t, 512> &adc)
99 {
100  auto bg = adc;
101  auto BGInter = std::make_unique<TSpectrum>();
102  BGInter->Background(bg.data(), fNumTbs, 6, TSpectrum::kBackDecreasingWindow, TSpectrum::kBackOrder2, kTRUE,
103  TSpectrum::kBackSmoothing7, kTRUE);
104 
105  for (Int_t iTb = 1; iTb < fNumTbs; iTb++) {
106  adc[iTb] = adc[iTb] - bg[iTb];
107  if (adc[iTb] < 0)
108  adc[iTb] = 0;
109  }
110 }
111 double AtPSASpectrum::calcTbCorrection(const std::array<Double_t, 512> &floatADC, int maxAdcIdx)
112 {
113  double TBCorr = 0;
114  double qTot = 0;
115  if (maxAdcIdx > 11) {
116  for (Int_t i = 0; i < 11; i++) {
117 
118  if (floatADC[maxAdcIdx - i + 10] > 0 && floatADC[maxAdcIdx - i + 10] < 4000) {
119  TBCorr += (floatADC[maxAdcIdx - i + 5]) * (maxAdcIdx - i + 5);
120  qTot += floatADC[maxAdcIdx - i + 5];
121  }
122  }
123  }
124  return TBCorr / qTot;
125 }
AtPSASpectrum.h
AtPad.h
ClassImp
ClassImp(AtPSASpectrum)
AtPSA::CalculateZGeo
Double_t CalculateZGeo(Double_t peakIdx)
Definition: AtPSA.cxx:90
AtPad::GetSizeID
Int_t GetSizeID() const
Definition: AtPad.h:98
AtPSA::HitVector
std::vector< std::unique_ptr< AtHit > > HitVector
Definition: AtPSA.h:50
AtPSASpectrum
PSA method using TSpectrum.
Definition: AtPSASpectrum.h:22
AtPSA::fNumTbs
Int_t fNumTbs
Definition: AtPSA.h:44
XYZPoint
ROOT::Math::XYZPoint XYZPoint
Definition: AtPatternCircle2D.h:18
AtPSASpectrum::AnalyzePad
HitVector AnalyzePad(AtPad *pad) override
Definition: AtPSASpectrum.cxx:23
AtPad::GetPadCoord
XYPoint GetPadCoord() const
Definition: AtPad.h:107
AtPSASpectrum::calcTbCorrection
double calcTbCorrection(const std::array< Double_t, 512 > &adc, int idxPeak)
Definition: AtPSASpectrum.cxx:111
XYZPoint
ROOT::Math::XYZPoint XYZPoint
Definition: AtPSASpectrum.cxx:21
AtPSA::getThreshold
Double_t getThreshold(int padSize=-1)
Definition: AtPSA.cxx:179
AtHit.h
AtPad::GetPadNum
Int_t GetPadNum() const
Definition: AtPad.h:96
AtPad::GetADC
const trace & GetADC() const
Definition: AtPad.cxx:97
AtPSASpectrum::subtractBackground
void subtractBackground(std::array< Double_t, 512 > &adc)
Definition: AtPSASpectrum.cxx:98
AtPad::IsPedestalSubtracted
Bool_t IsPedestalSubtracted() const
Definition: AtPad.h:94
AtPad
Container class for AtPadBase objects.
Definition: AtPad.h:38