Project
Loading...
Searching...
No Matches
DigitDump.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
14
15#include <cstddef>
16#include "TTree.h"
17#include "TString.h"
18
19#include "Framework/Logger.h"
20
21#include "TPCBase/Mapper.h"
22#include "TPCBase/ROC.h"
25
26using namespace o2::tpc;
27
28//______________________________________________________________________________
30{
31 if (mFile) {
32 mFile->Write();
33 }
34}
35
36//______________________________________________________________________________
38{
39 const auto& param = DigitDumpParam::Instance();
40
41 if (param.FirstTimeBin >= 0) {
42 mFirstTimeBin = param.FirstTimeBin;
43 LOGP(info, "Setting FirstTimeBin = {} from TPCDigitDump.FirstTimeBin", mFirstTimeBin);
44 }
45 if (param.LastTimeBin >= 0) {
46 mLastTimeBin = param.LastTimeBin;
47 LOGP(info, "Setting LastTimeBin = {} from TPCDigitDump.LastTimeBin", mLastTimeBin);
48 }
49 mADCMin = param.ADCMin;
50 mADCMax = param.ADCMax;
51 mNoiseThreshold = param.NoiseThreshold;
52 mPedestalAndNoiseFile = param.PedestalAndNoiseFile;
53}
54
55//______________________________________________________________________________
56Int_t DigitDump::updateCRU(const CRU& cru, const Int_t row, const Int_t pad,
57 const Int_t timeBin, const Float_t signal)
58{
59 if ((timeBin < mFirstTimeBin) || (timeBin > mLastTimeBin)) {
60 return 0;
61 }
62
63 if (!mInitialized) {
65 }
66
67 Mapper& mapper = Mapper::instance();
68 const PadRegionInfo& regionInfo = mMapper.getPadRegionInfo(cru.region());
69 const int globalRow = row + regionInfo.getGlobalRowOffset();
70 const int sectorRow = globalRow - (cru.rocType() == RocType::OROC) * mapper.getNumberOfRowsROC(0);
71
72 // noise and pedestal values
73 float pedestal = 0;
74 float noise = 0;
75 if (mPedestal) {
76 pedestal = mPedestal->getValue(cru.roc(), sectorRow, pad);
77 }
78 if (mNoise) {
79 noise = mNoise->getValue(cru.roc(), sectorRow, pad);
80 }
81
82 // check adc thresholds (zero suppression)
83 const Float_t signalCorr = signal - pedestal;
84
85 if ((signalCorr < mADCMin) || (signalCorr > mADCMax)) {
86 return 0;
87 }
88
89 if ((mNoiseThreshold > 0) && (signalCorr < noise * mNoiseThreshold)) {
90 return 0;
91 }
92
93 // check for masked pads
94 if (mPadMask.size() && std::find(mPadMask.begin(), mPadMask.end(), std::array<int, 3>({int(cru.roc()), sectorRow, pad})) != mPadMask.end()) {
95 return 1;
96 }
97 // printf("updateCRU: %d, %d (%d, %d), %d, %d, %f, %f\n", int(cru), row, globalRow, sectorRow, pad, timeBin, signal, pedestal);
98
99 // fill digits
100 addDigit(cru, signalCorr, globalRow, pad, timeBin);
101
102 // fill time bin occupancy
103 ++mTimeBinOccupancy[timeBin - mFirstTimeBin];
104
105 return 0;
106}
107
108//______________________________________________________________________________
110{
111 // sort digits
112 for (auto& digits : mDigits) {
113 std::sort(digits.begin(), digits.end(), [](const auto& a, const auto& b) {
114 if (a.getTimeStamp() < b.getTimeStamp()) {
115 return true;
116 }
117 if (a.getTimeStamp() == b.getTimeStamp()) {
118 if (a.getRow() < b.getRow()) {
119 return true;
120 } else if (a.getRow() == b.getRow()) {
121 return a.getPad() < b.getPad();
122 }
123 }
124 return false;
125 });
126 }
127}
128
129//______________________________________________________________________________
131{
132 // sort digits
133 sortDigits();
134
135 mTree->Fill();
136
137 clearDigits();
138}
139
140//______________________________________________________________________________
141void DigitDump::loadNoiseAndPedestal()
142{
143 if (!mPedestalAndNoiseFile.size()) {
144 LOG(warning) << "No pedestal and noise file name set";
145 return;
146 }
147
148 std::unique_ptr<TFile> f(TFile::Open(mPedestalAndNoiseFile.data()));
149 if (!f || !f->IsOpen() || f->IsZombie()) {
150 LOG(fatal) << "Could not open pedestal file: " << mPedestalAndNoiseFile;
151 }
152
153 CalPad* pedestal{nullptr};
154 CalPad* noise{nullptr};
155
156 f->GetObject("Pedestals", pedestal);
157 f->GetObject("Noise", noise);
158
159 mPedestal = std::move(std::unique_ptr<const CalPad>(pedestal));
160 mNoise = std::move(std::unique_ptr<const CalPad>(noise));
161}
162
163//______________________________________________________________________________
164void DigitDump::setupOutputTree()
165{
166 mFile = std::make_unique<TFile>(mDigitFile.data(), "recreate");
167 mTree = new TTree("o2sim", "o2sim");
168
169 for (int iSec = 0; iSec < Sector::MAXSECTOR; ++iSec) {
170 mTree->Branch(Form("TPCDigit_%d", iSec), &mDigits[iSec]);
171 }
172}
173
174//______________________________________________________________________________
176{
177 loadNoiseAndPedestal();
178 if (!mInMemoryOnly) {
179 setupOutputTree();
180 }
181 mTimeBinOccupancy.resize(mLastTimeBin - mFirstTimeBin + 1);
182 mInitialized = true;
183}
184
185//______________________________________________________________________________
187{
188 sortDigits();
189
190 auto isEqual = [](const Digit& a, const Digit& b) {
191 if ((a.getTimeStamp() == b.getTimeStamp()) && (a.getRow() == b.getRow()) && (a.getPad() == b.getPad())) {
192 LOGP(debug, "digit found twice at sector {:2}, cru {:3}, row {:3}, pad {:3}, time {:6}, ADC {:.2} (other: {:.2})", b.getCRU() / 10, b.getCRU(), b.getRow(), b.getPad(), b.getTimeStamp(), b.getChargeFloat(), a.getChargeFloat());
193 return true;
194 }
195 return false;
196 };
197
198 for (size_t iSec = 0; iSec < Sector::MAXSECTOR; ++iSec) {
199 auto& digits = mDigits[iSec];
200 if (!digits.size()) {
201 continue;
202 }
203
204 size_t nDuplicates = 0;
205 if (removeDuplicates) {
206 const auto last = std::unique(digits.begin(), digits.end(), isEqual);
207 nDuplicates = std::distance(last, digits.end());
208 digits.erase(last, digits.end());
209 } else {
210 auto first = digits.begin();
211 const auto last = digits.end();
212 while (++first != last) {
213 nDuplicates += isEqual(*(first - 1), *first);
214 }
215 }
216 if (nDuplicates) {
217 static std::array<size_t, Sector::MAXSECTOR> nWarning{};
218 static std::array<size_t, Sector::MAXSECTOR> suppression{};
219 if (nWarning[iSec] < 5 || nWarning[iSec] == suppression[iSec]) {
220 LOGP(alarm, "{} {} duplicate digits in sector {}, warned {} times in this sector", removeDuplicates ? "removed" : "found", nDuplicates, iSec, nWarning[iSec]);
221 if (nWarning[iSec] == 4) {
222 suppression[iSec] = 10;
223 }
224 suppression[iSec] *= 10;
225 }
226 ++nWarning[iSec];
227 }
228 }
229}
230
231//______________________________________________________________________________
232void DigitDump::removeCEdigits(uint32_t removeNtimeBinsBefore, uint32_t removeNtimeBinsAfter, std::array<std::vector<Digit>, Sector::MAXSECTOR>* removedDigits)
233{
234 if (!mInitialized || !mTimeBinOccupancy.size()) {
235 LOGP(info, "Cannot calculate CE position, mInitialized = {}, mTimeBinOccupancy.size() = {}", mInitialized, mTimeBinOccupancy.size());
236 return;
237 }
238 // ===| check if proper CE signal was found |===
239 const auto sectorsWithDigits = std::count_if(mDigits.begin(), mDigits.end(), [](const auto& v) { return v.size(); });
240 const auto maxElem = std::max_element(mTimeBinOccupancy.begin(), mTimeBinOccupancy.end());
241 const auto maxVal = *maxElem;
242
243 if (!sectorsWithDigits || maxVal < 10) {
244 LOGP(info, "No sectors with digits: {} or too few pads with max number of digits: {} < 10, CE detection stopped", sectorsWithDigits, maxVal);
245 return;
246 }
247
248 // at least 20% of all pad should have fired in sectors wich have digits
249 const size_t threshold = Mapper::getPadsInSector() * sectorsWithDigits / 5;
250 if (maxVal < threshold) {
251 LOGP(warning, "No CE signal found. Number of fired pads is too small {} < {} (with {} sectors having digits)", maxVal, threshold, sectorsWithDigits);
252 return;
253 }
254
255 // identify the first time bin to remove
256 const auto posMaxElem = std::distance(mTimeBinOccupancy.begin(), maxElem);
257 const auto cePos = posMaxElem + mFirstTimeBin;
258
259 if (cePos < posMaxElem) {
260 LOGP(warning, "Number of time bins to be removed {} is bigger than the CE peak position {}", removeNtimeBinsBefore, posMaxElem);
261 return;
262 }
263
264 const auto firstTimeBin = cePos - removeNtimeBinsBefore;
265 const auto lastTimeBin = cePos + removeNtimeBinsAfter;
266 LOGP(info, "CE position found at time bin {}, removing the range {} - {}", cePos, firstTimeBin, lastTimeBin);
267
268 for (size_t iSec = 0; iSec < Sector::MAXSECTOR; ++iSec) {
269 auto& digits = mDigits[iSec];
270 if (!digits.size()) {
271 continue;
272 }
273
274 // LOGP(info, "processing sector iSec");
275 const auto itFirstTB = std::lower_bound(digits.begin(), digits.end(),
276 firstTimeBin,
277 [](const auto& digit, const auto val) {
278 return digit.getTimeStamp() < val;
279 });
280
281 // LOGP(info, "first time bin to remove is {} at position {} / {}", *itFirstTB, std::distance(digits.begin(), itFirstTB), digits.size());
282 if (itFirstTB == digits.end()) {
283 continue;
284 }
285
286 const auto itLastTB = std::upper_bound(digits.begin(), digits.end(),
287 lastTimeBin,
288 [](const auto val, const auto& digit) {
289 return val < digit.getTimeStamp();
290 });
291
292 // LOGP(info, "last time bin to remove is {} at position {} / {}", *(itLastTB - 1), std::distance(digits.begin(), itLastTB), digits.size());
293 if (removedDigits) {
294 // LOGP(info, "copy removed digits");
295 auto& cpDigits = (*removedDigits)[iSec];
296 cpDigits.clear();
297 std::copy(itFirstTB, itLastTB, std::back_inserter(cpDigits));
298 }
299
300 // LOGP(info, "erasing {} digits", std::distance(itFirstTB, itLastTB));
301 digits.erase(itFirstTB, itLastTB);
302 }
303}
Implementation of the parameter class for the hardware clusterer.
std::ostringstream debug
unsigned char region() const
Definition CRU.h:64
RocType rocType() const
Definition CRU.h:66
const ROC roc() const
Definition CRU.h:61
const Mapper & mMapper
TPC mapper.
void clearDigits()
clear the digits
Definition DigitDump.h:120
void checkDuplicates(bool removeDuplicates=false)
check duplicates and remove the if removeDuplicates is true
void sortDigits()
sort the digits
void removeCEdigits(uint32_t removeNtimeBinsBefore=10, uint32_t removeNtimeBinsAfter=100, std::array< std::vector< Digit >, Sector::MAXSECTOR > *removedDigits=nullptr)
remove digits close to the CE
void addDigit(const CRU &cru, const float signal, const int rowInSector, const int padInRow, const int timeBin)
directly add a digit
Definition DigitDump.h:143
void endEvent() final
End event function.
void initInputOutput()
initialize
void init()
initialize DigitDump from DigitDumpParam
Definition DigitDump.cxx:37
Int_t updateCRU(const CRU &cru, const Int_t row, const Int_t pad, const Int_t timeBin, const Float_t signal) final
not used
Definition DigitDump.cxx:56
~DigitDump() override
default destructor
Definition DigitDump.cxx:29
int getNumberOfRowsROC(ROC roc) const
Definition Mapper.h:305
static Mapper & instance(const std::string mappingDir="")
Definition Mapper.h:44
const PadRegionInfo & getPadRegionInfo(const unsigned char region) const
Definition Mapper.h:385
static constexpr unsigned short getPadsInSector()
Definition Mapper.h:414
unsigned char getGlobalRowOffset() const
static constexpr int MAXSECTOR
Definition Sector.h:44
void removeDuplicates(std::vector< int > &vec)
const GLdouble * v
Definition glcorearb.h:832
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLuint GLfloat * val
Definition glcorearb.h:1582
GLenum GLfloat param
Definition glcorearb.h:271
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
Global TPC definitions and constants.
Definition SimTraits.h:167
@ OROC
Definition Defs.h:49
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits
std::vector< int > row