9 #include <FairLogger.h>
11 #include <Math/Point2D.h>
12 #include <Math/Point3D.h>
13 #include <Math/Point3Dfwd.h>
14 #include <Math/Rotation3D.h>
15 #include <TSpectrum.h>
36 Double_t QEventTot = 0.0;
37 Double_t RhoVariance = 0.0;
38 Double_t RhoMean = 0.0;
40 std::map<Int_t, Int_t> PadMultiplicity;
41 std::array<Float_t, 512> mesh{};
45 LOG(debug) <<
"MC Simulated points Map size " << mcPointsMap.size();
48 for (
const auto &pad : rawEvent->
GetPads()) {
50 LOG(debug) <<
"Running PSA on pad " << pad->GetPadNum();
51 Int_t PadNum = pad->GetPadNum();
54 Double_t QHitTot = 0.0;
56 ROOT::Math::Rotation3D HitPosRot;
58 Bool_t fValidBuff = kTRUE;
59 Bool_t fValidThreshold = kTRUE;
60 Bool_t fValidDerivative = kTRUE;
62 auto pos = pad->GetPadCoord();
68 if (pos.X() < -9000 || pos.Y() < -9000) {
69 LOG(debug) <<
"Skipping pad, position is invalid";
73 if (!(pad->IsPedestalSubtracted())) {
74 LOG(ERROR) <<
"Pedestal should be subtracted to use this class!";
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{};
92 for (Int_t iTb = 0; iTb <
fNumTbs; iTb++) {
93 floatADC[iTb] = adc[iTb];
98 auto PeakFinder = std::make_unique<TSpectrum>();
100 numPeaks = PeakFinder->SearchHighRes(floatADC.data(), dummy.data(),
fNumTbs, 4.7, 5, fBackGroundSuppression, 3,
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)
122 for (Int_t iPeak = 0; iPeak < numPeaks; iPeak++) {
129 maxAdcIdx = (Int_t)(ceil((PeakFinder->GetPositionX())[iPeak]));
130 if (maxAdcIdx < 3 || maxAdcIdx > 509)
136 for (Int_t ij = 20; ij < 500; ij++)
138 if (floatADC[ij] > max) {
148 Double_t basecorr = 0.0;
149 Double_t slope = 0.0;
153 for (Int_t i = 0; i < 10; i++) {
155 basecorr += floatADC[maxAdcIdx - 8 - i];
158 slope = (floatADC[maxAdcIdx - i] - floatADC[maxAdcIdx - i - 1]);
161 if (slope < 0 && fIsBaseCorr && fIsMaxFinder)
167 Double_t timemax = 0.5 * (floatADC[maxAdcIdx - 1] - floatADC[maxAdcIdx + 1]) /
168 (floatADC[maxAdcIdx - 1] + floatADC[maxAdcIdx + 1] - 2 * floatADC[maxAdcIdx]);
171 Double_t TBCorr = 0.0;
172 Double_t TB_TotQ = 0.0;
174 if (maxAdcIdx > 11) {
175 for (Int_t i = 0; i < 11; i++) {
177 if (floatADC[maxAdcIdx - i + 10] > 0 && floatADC[maxAdcIdx - i + 10] < 4000) {
178 TBCorr += (floatADC[maxAdcIdx - i + 5] - basecorr / 10.0) *
180 TB_TotQ += floatADC[maxAdcIdx - i + 5] - basecorr / 10.0;
184 TBCorr = TBCorr / TB_TotQ;
187 charge = floatADC[maxAdcIdx] - basecorr / 10.0;
189 charge = floatADC[maxAdcIdx];
196 if (gthreshold > 0 && charge < gthreshold) {
197 fValidThreshold =
false;
198 LOG(debug) <<
"Invalid threshold with charge: " << charge <<
" and threshold: " << gthreshold;
200 if (fIsMaxFinder && (maxTime < 20 || maxTime > 500)) {
201 fValidThreshold = kFALSE;
202 LOG(debug) <<
"Peak is outside valid time window (20,500) TBs.";
205 if (fValidThreshold && fValidDerivative) {
210 QEventTot += QHitTot;
212 auto &hit =
event->AddHit(PadNum,
XYZPoint(pos.X(), pos.Y(), zPos), charge);
213 LOG(debug) <<
"Added hit with ID" << hit.GetHitID();
215 hit.SetTimeStamp(maxAdcIdx);
216 hit.SetTimeStampCorr(TBCorr);
217 hit.SetTimeStampCorrInter(timemax);
219 hit.SetTraceIntegral(QHitTot);
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()
234 for (Int_t iTb = 0; iTb <
fNumTbs; iTb++)
235 mesh[iTb] += floatADC[iTb];
245 PadMultiplicity.insert(std::pair<Int_t, Int_t>(pad->GetPadNum(), 1));
251 RhoVariance = Rho2 - (
event->GetNumHits() * pow((RhoMean / event->
GetNumHits()), 2));
253 for (Int_t iTb = 0; iTb <
fNumTbs; iTb++)
255 event->SortHitArrayTime();
256 event->SetMultiplicityMap(PadMultiplicity);
257 event->SetRhoVariance(RhoVariance);
258 event->SetEventCharge(QEventTot);
273 fBackGroundSuppression = kTRUE;
278 fBackGroundInterp = kTRUE;
283 fIsPeakFinder = kTRUE;
284 fIsMaxFinder = kFALSE;
289 fIsMaxFinder = kTRUE;
290 fIsPeakFinder = kFALSE;