Project
Loading...
Searching...
No Matches
FT0TimeOffsetSlotContainer.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
16#include <Framework/Logger.h>
17
18#include "TH1.h"
19#include "TFile.h"
20#include "TFitResult.h"
21
22using namespace o2::ft0;
23
25
27{
28 if (mTotalNevents == 0) {
29 // Dummy slot, should be ignored for protection
30 LOG(warning) << "RESULT: Empty slot, ignoring";
31 return false;
32 } else if (mIsReady) {
33 // ready : bad+good == NChannels (i.e. no pending channel)
34 LOG(info) << "RESULT: ready";
35 print();
36 return true;
37 } else if (mCurrentSlot >= CalibParam::Instance().mNExtraSlots) {
38 LOG(info) << "RESULT: Extra slots(" << CalibParam::Instance().mNExtraSlots << ") are used";
39 print();
40 return true;
41 } else if (mCurrentSlot < CalibParam::Instance().mNExtraSlots) {
42 for (int iCh = 0; iCh < sNCHANNELS; iCh++) {
43 const auto nEntries = mArrEntries[iCh];
44 if (nEntries >= CalibParam::Instance().mMinEntriesThreshold && nEntries < CalibParam::Instance().mMaxEntriesThreshold) {
45 // Check if there are any pending channel in first slot
46 LOG(info) << "RESULT: pending channels";
47 print();
48 return false;
49 }
50 }
51 // If sum of bad+good == NChannels (i.e. no pending channel in first slot)
52 LOG(info) << "RESULT: NO pending channels";
53 print();
54 return true;
55 } else {
56 // Probably will be never happen, all other conditions are already checked
57 LOG(info) << "RESULT: should be never happen";
58 print();
59 return true;
60 }
61}
62
63void FT0TimeOffsetSlotContainer::fill(const gsl::span<const float>& data)
64{
65 // Per TF procedure
66 const FlatHisto2D_t histView(data);
67 if (mIsFirstTF) {
68 // To make histogram parameters dynamic, depending on TimeSpectraProcessor output
69 mHistogram.init(histView.getNBinsX(), histView.getXMin(), histView.getXMax(), histView.getNBinsY(), histView.getYMin(), histView.getYMax());
70 mIsFirstTF = false;
71 }
72 mHistogram.add(histView);
73 // This part should at the stage `hasEnoughData()` but it is const method
74 for (int iCh = 0; iCh < sNCHANNELS; iCh++) {
75 if (mBitsetGoodChIDs.test(iCh) || mBitsetBadChIDs.test(iCh)) {
76 // No need in checking entries at channels with enough data or at channels which marked as bad in first slot
77 continue;
78 }
79 auto sliceChID = mHistogram.getSliceY(iCh);
80 FlatHistoValue_t nEntries{};
81 for (auto& en : sliceChID) {
82 nEntries += en;
83 }
84 mArrEntries[iCh] = nEntries;
85 mTotalNevents += nEntries;
87 mBitsetGoodChIDs.set(iCh);
88 }
89 }
90 const auto totalNCheckedChIDs = mBitsetGoodChIDs.count() + mBitsetBadChIDs.count();
91 if (totalNCheckedChIDs == sNCHANNELS) {
92 mIsReady = true;
93 }
94}
95
97{
98 LOG(info) << "MERGING";
99 if (mIsFirstTF && prev->isFirstTF()) {
100 // nothing to be done
101 return;
102 } else if (mIsFirstTF && !prev->isFirstTF()) {
103 // need to make mHistogram operational first
104 mHistogram.init(prev->getHistogram().getNBinsX(), prev->getHistogram().getXMin(), prev->getHistogram().getXMax(), prev->getHistogram().getNBinsY(), prev->getHistogram().getYMin(), prev->getHistogram().getYMax());
105 mIsFirstTF = false;
106 }
107 *this = *prev;
108 if (mCurrentSlot == 0) {
109 // This part should at the stage `hasEnoughData()` but it is const method
110 for (int iCh = 0; iCh < sNCHANNELS; iCh++) {
111 if (mArrEntries[iCh] < CalibParam::Instance().mMinEntriesThreshold) {
112 // If in first slot channel entries below range => set status bad
113 mBitsetBadChIDs.set(iCh);
114 }
115 }
116 }
117 this->print();
118 mCurrentSlot++;
119}
120
122{
123 uint32_t statusBits{};
124 double minFitRange{0};
125 double maxFitRange{0};
126 auto hist = mHistogram.createSliceYTH1F(channelID);
127 if (channelID < sNCHANNELS) {
128 if (CalibParam::Instance().mRebinFactorPerChID[channelID] > 0) {
129 hist->Rebin(CalibParam::Instance().mRebinFactorPerChID[channelID]);
130 }
131 }
132 const float meanHist = hist->GetMean();
133 const float rmsHist = hist->GetRMS();
134 const float stat = hist->Integral();
135 if (CalibParam::Instance().mUseDynamicRange) {
136 minFitRange = meanHist - CalibParam::Instance().mRangeInRMS * rmsHist;
137 maxFitRange = meanHist + CalibParam::Instance().mRangeInRMS * rmsHist;
138 } else {
139 minFitRange = CalibParam::Instance().mMinFitRange;
140 maxFitRange = CalibParam::Instance().mMaxFitRange;
141 }
142 float constantGaus{};
143 float meanGaus{};
144 float sigmaGaus{};
145 float fitChi2{};
146 if (stat > 0) {
147 TFitResultPtr resultFit = hist->Fit("gaus", "0SQ", "", minFitRange, maxFitRange);
148 if (((int)resultFit) == 0) {
149 constantGaus = resultFit->Parameters()[0];
150 meanGaus = resultFit->Parameters()[1];
151 sigmaGaus = resultFit->Parameters()[2];
152 fitChi2 = resultFit->Chi2();
153 statusBits |= (1 << 0);
154 }
155 if (((int)resultFit) != 0 || std::abs(meanGaus - meanHist) > CalibParam::Instance().mMaxDiffMean || rmsHist < CalibParam::Instance().mMinRMS || sigmaGaus > CalibParam::Instance().mMaxSigma) {
156 statusBits |= (2 << 0);
157 LOG(debug) << "Bad gaus fit: meanGaus " << meanGaus << " sigmaGaus " << sigmaGaus << " meanHist " << meanHist << " rmsHist " << rmsHist << "resultFit " << ((int)resultFit);
158 }
159 }
160 if (listHists != nullptr) {
161 auto histPtr = hist.release();
162 const std::string histName = "histCh" + std::to_string(channelID);
163 histPtr->SetName(histName.c_str());
164 listHists->Add(histPtr);
165 }
166 return SpectraInfoObject{meanGaus, sigmaGaus, constantGaus, fitChi2, meanHist, rmsHist, stat, statusBits};
167}
168
169TimeSpectraInfoObject FT0TimeOffsetSlotContainer::generateCalibrationObject(long tsStartMS, long tsEndMS, const std::string& extraInfo) const
170{
171 TList* listHists = nullptr;
172 bool storeHists{false};
173 if (extraInfo.size() > 0) {
174 storeHists = true;
175 listHists = new TList();
176 listHists->SetOwner(true);
177 listHists->SetName("output");
178 }
179 TimeSpectraInfoObject calibrationObject;
180 for (unsigned int iCh = 0; iCh < sNCHANNELS; ++iCh) {
181 calibrationObject.mTime[iCh] = getSpectraInfoObject(iCh, listHists);
182 }
183 calibrationObject.mTimeA = getSpectraInfoObject(sNCHANNELS, listHists);
184 calibrationObject.mTimeC = getSpectraInfoObject(sNCHANNELS + 1, listHists);
185 calibrationObject.mSumTimeAC = getSpectraInfoObject(sNCHANNELS + 2, listHists);
186 calibrationObject.mDiffTimeCA = getSpectraInfoObject(sNCHANNELS + 3, listHists);
187 if (storeHists) {
188 const std::string filename = extraInfo + "/histsTimeSpectra" + std::to_string(tsStartMS) + "_" + std::to_string(tsEndMS) + ".root";
189 TFile fileHists(filename.c_str(), "RECREATE");
190 fileHists.WriteObject(listHists, listHists->GetName(), "SingleKey");
191 fileHists.Close();
192 delete listHists;
193 }
194 return calibrationObject;
195}
196
198{
199 LOG(info) << "Total entries: " << mHistogram.getSum();
200 LOG(info) << "Hist " << mHistogram.getNBinsX() << " " << mHistogram.getXMin() << " " << mHistogram.getXMax() << " " << mHistogram.getNBinsY() << " " << mHistogram.getYMin() << " " << mHistogram.getYMax();
201 LOG(info) << "Number of good channels: " << mBitsetGoodChIDs.count();
202 LOG(info) << "Number of bad channels: " << mBitsetBadChIDs.count();
203 LOG(info) << "Number of pending channels: " << sNCHANNELS - (mBitsetGoodChIDs.count() + mBitsetBadChIDs.count());
204 LOG(info) << "mIsFirstTF " << mIsFirstTF;
205 LOG(info) << "mIsReady " << mIsReady;
206 // QC will do that part
207}
uint8_t channelID
Definition RawEventData.h:8
1D messeageable histo class
std::ostringstream debug
uint32_t getNBinsY() const
Definition FlatHisto2D.h:78
gsl::span< const T > getSliceY(uint32_t binX) const
std::unique_ptr< TH1F > createSliceYTH1F(uint32_t binX, const std::string &name="histo2dsliceY") const
void add(const FlatHisto2D &other)
uint32_t getNBinsX() const
Definition FlatHisto2D.h:77
void merge(FT0TimeOffsetSlotContainer *prev)
SpectraInfoObject getSpectraInfoObject(std::size_t channelID, TList *listHists) const
void fill(const gsl::span< const float > &data)
TimeSpectraInfoObject generateCalibrationObject(long tsStartMS, long tsEndMS, const std::string &pathToHists) const
GLboolean * data
Definition glcorearb.h:298
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
std::string filename()
std::size_t mMaxEntriesThreshold
Definition CalibParam.h:29
std::array< SpectraInfoObject, o2::ft0::Geometry::Nchannels > mTime
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"