Project
Loading...
Searching...
No Matches
CommonModeCorrection.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 <random>
16#include <algorithm>
17#include <thread>
18#include <mutex>
19#include "CCDB/CcdbApi.h"
21#include "TPCBase/Mapper.h"
22#include "TPCBase/Utils.h"
24#include "TChain.h"
25#include "TROOT.h"
26#include "TFile.h"
29
30using namespace o2::tpc;
31using namespace o2::tpc::cru_calib_helpers;
32CommonModeCorrection::CMInfo CommonModeCorrection::getCommonMode(gsl::span<const float> values, gsl::span<const float> cmKValues, gsl::span<const float> pedestals, CMDebug* cmDebug) const
33{
34 if (values.size() == 0) {
35 return CMInfo{};
36 }
37 // sanity check
38 if (values.size() != cmKValues.size() || values.size() != pedestals.size()) {
39 LOGP(error, "vector sizes of input values, cmKValues and pedestals don't match: {}, {}, {}", values.size(), cmKValues.size(), pedestals.size());
40 return CMInfo{};
41 }
43 std::vector<float> adcCM; //< ADC values used for common mode calculation
44
45 CMInfo cmInfo;
46 if (cmDebug) {
47 cmDebug->nPadsOk.resize(mNPadsCompRamdom + 1);
48 cmDebug->adcDist.resize(10);
49 }
50
51 for (size_t iPad = 0; iPad < values.size(); ++iPad) {
52 const float kCM = mLimitKFactor ? fixedSizeToFloat<6>(floatToFixedSize<8, 6>(cmKValues[iPad])) : cmKValues[iPad];
53 const float pedestal = mLimitPedestal ? fixedSizeToFloat(floatToFixedSize(pedestals[iPad])) : pedestals[iPad];
54 const float adcPadRaw = values[iPad];
55 const float adcPad = adcPadRaw - pedestal;
56 const float adcPadNorm = (kCM > 0) ? adcPad / kCM : 0;
57
58 if (adcPadRaw > 1023.7) {
59 ++cmInfo.nSaturation;
60 }
61
62 if (adcPad > mQEmpty) {
63 continue;
64 }
65
66 float qCompAdd = 0;
67 if ((mQCompScaleThreshold < 0) && (adcPadNorm < mQCompScaleThreshold)) {
68 qCompAdd = (mQCompScaleThreshold - adcPadNorm) * mQCompScale;
69 LOGP(info, "Setting qCompAdd to {} for {}", qCompAdd, adcPadNorm);
70 }
71
72 int nPadsOK = 0;
73
74 for (int iRnd = 0; iRnd < mNPadsCompRamdom; ++iRnd) {
75 int padRnd = 0;
76 do {
77 padRnd = int(random.getNextValue() * (values.size() - 1));
78 } while (padRnd == iPad);
79 const float kCMRnd = mLimitKFactor ? fixedSizeToFloat<6>(floatToFixedSize<8, 6>(cmKValues[padRnd])) : cmKValues[padRnd];
80 const float pedestalRnd = mLimitPedestal ? fixedSizeToFloat(floatToFixedSize(pedestals[padRnd])) : pedestals[padRnd];
81 const float adcPadRnd = values[padRnd] - pedestalRnd;
82 const float adcPadRndNorm = (kCMRnd > 0) ? adcPadRnd / kCMRnd : 0;
83 const float adcDist = std::abs(adcPadNorm - adcPadRndNorm);
84 if (cmDebug) {
85 const size_t distPos = std::min(cmDebug->adcDist.size() - 1, size_t(adcDist / 0.5));
86 ++cmDebug->adcDist[distPos];
87 }
88 if (adcDist < mQComp) {
89 ++nPadsOK;
90 }
91 }
92
93 if (cmDebug) {
94 ++cmDebug->nPadsOk[nPadsOK];
95 }
96
97 if (nPadsOK >= mNPadsCompMin) {
98 adcCM.emplace_back(adcPadNorm);
99 }
100 }
101
102 const int entriesCM = int(adcCM.size());
103 float commonMode = 0; // std::accumulate(adcCM.begin(), adcCM.end(), 0.f);
104 float commonModeStd = 0;
105
106 if (entriesCM > 0) {
107 std::for_each(adcCM.begin(), adcCM.end(), [&commonMode, &commonModeStd](const auto val) {
108 commonMode += val;
109 commonModeStd += val * val;
110 });
111 commonMode /= float(entriesCM);
112 commonModeStd = std::sqrt(std::abs(commonModeStd / entriesCM - commonMode * commonMode));
113 }
114 cmInfo.cmValue = commonMode;
115 cmInfo.cmValueStd = commonModeStd;
116 cmInfo.nPadsUsed = entriesCM;
117
118 for (size_t iPad = 0; iPad < values.size(); ++iPad) {
119 const float kCM = mLimitKFactor ? fixedSizeToFloat<6>(floatToFixedSize<8, 6>(cmKValues[iPad])) : cmKValues[iPad];
120 const float pedestal = mLimitPedestal ? fixedSizeToFloat(floatToFixedSize(pedestals[iPad])) : pedestals[iPad];
121 const float adcPadRaw = values[iPad];
122 const float adcPad = adcPadRaw - pedestal;
123 const float adcPadNorm = (kCM > 0) ? adcPad / kCM : 0;
124 const float adcPadCorr = adcPad - kCM * commonMode;
125
126 if (adcPadCorr > mSumPosThreshold) {
127 cmInfo.sumPos += adcPadCorr;
128 } else {
129 cmInfo.sumNeg += adcPadNorm;
130 ++cmInfo.nNeg;
131 }
132
133 if (mOccupancyThreshold > 0) {
134 if (adcPadCorr > mOccupancyThreshold) {
135 ++cmInfo.nOccupancy;
136 }
137 }
138 }
139
140 return cmInfo;
141}
142
144{
145 o2::ccdb::CcdbApi cdbApi;
146 cdbApi.init("http://alice-ccdb.cern.ch");
147 const auto feeConfig = cdbApi.retrieveFromTFileAny<FEEConfig>("TPC/Config/FEE", {}, long(tag));
148 if (!feeConfig) {
149 LOGP(error, "Could not retrieve pad maps");
150 return;
151 }
152 mPadMaps = feeConfig->padMaps;
153 delete feeConfig;
154}
155
156CommonModeCorrection::CMdata CommonModeCorrection::collectCMdata(const std::vector<Digit>& digits, int cru, int timeBin)
157{
158
159 CMdata data;
160 if (!padMapExists("CMkValues") || padMapExists("Pedestals")) {
161 return data;
162 }
163
164 for (const auto& digit : digits) {
165 if (digit.getTimeStamp() < timeBin) {
166 continue;
167 }
168
169 if (digit.getTimeStamp() > timeBin) {
170 break;
171 }
172
173 if (digit.getCRU() < cru) {
174 continue;
175 }
176
177 if (digit.getCRU() > cru) {
178 break;
179 }
180
181 const auto sector = CRU(digit.getCRU()).sector();
182 data.adcValues.emplace_back(digit.getChargeFloat());
183 data.cmKValues.emplace_back(mPadMaps["CMkValues"].getValue(sector, digit.getRow(), digit.getPad()));
184 data.pedestals.emplace_back(mPadMaps["Pedestals"].getValue(sector, digit.getRow(), digit.getPad()));
185 }
186 return data;
187}
188
189int CommonModeCorrection::getCommonMode(std::vector<Digit>& digits, std::vector<std::vector<CMInfo>>& cmValues, bool negativeOnly, bool hasInjectedCMValue, std::vector<std::vector<CMDebug>>* cmDebug, int minTimeBin, int maxTimeBin) const
190{
191 // calculation common mode values
192 int maxTimeBinProcessed = -1;
193 int lastCRU = -1;
194 int lastTimeBin = -1;
195 CMdata data;
196 const auto& cmkValues = mPadMaps.at("CMkValues");
197 const auto& pedestals = mPadMaps.at("Pedestals");
198
199 bool doArtificialCM = std::abs(mArtificialCM) > 0;
200
201 // for decoding of the injected common mode signals
202 float cmInjectedLower{};
203 float cmInjectedUpper{};
204
205 for (size_t iDigit = 0; iDigit < digits.size(); ++iDigit) {
206 auto& digit = digits[iDigit];
207 const auto timeBin = digit.getTimeStamp();
208 if ((minTimeBin > -1) && (timeBin < minTimeBin)) {
209 continue;
210 }
211 if ((maxTimeBin > -1) && (timeBin > maxTimeBin)) {
212 continue;
213 }
214 if ((lastCRU > -1) && ((digit.getCRU() != lastCRU) || (digit.getTimeStamp() != lastTimeBin))) {
215 auto& cmValuesCRU = cmValues[lastCRU];
216 if (cmValuesCRU.size() <= lastTimeBin) {
217 cmValuesCRU.resize(lastTimeBin + 500);
218 if (cmDebug) {
219 (*cmDebug)[lastCRU].resize(lastTimeBin + 500);
220 }
221 }
222 if (mSubthreshold > 0) {
223 const size_t nPadsCRU = Mapper::PADSPERREGION[lastCRU % 10];
224 const auto dataSize = data.adcValues.size();
225 if (dataSize < nPadsCRU) {
226 data.resize(nPadsCRU);
227 if (mSubthreshold == 2) {
228 for (size_t i = dataSize; i < nPadsCRU; ++i) {
229 data.adcValues[i] = gRandom->Gaus();
230 }
231 }
232 }
233 }
234 cmValuesCRU[lastTimeBin] = getCommonMode(data.adcValues, data.cmKValues, data.pedestals, cmDebug ? &((*cmDebug)[lastCRU][lastTimeBin]) : nullptr);
235 if (hasInjectedCMValue) {
236 cmValuesCRU[lastTimeBin].cmValueCRU = decodeInjectedCMValue(cmInjectedLower, cmInjectedUpper);
237 }
238 // LOGP(info, "processing CRU {}, timeBin {}, CM = {}", lastCRU, lastTimeBin, cmValuesCRU[lastTimeBin].cmValue);
239
240 data.clear();
241 }
242 const auto sector = CRU(digit.getCRU()).sector();
243 const auto cmkValue = cmkValues.getValue(sector, digit.getRow(), digit.getPad());
244 const auto pedestal = pedestals.getValue(sector, digit.getRow(), digit.getPad());
245 float charge = digit.getChargeFloat();
246 if (doArtificialCM) {
247 charge = std::clamp(charge + mArtificialCM * cmkValue, 0.f, 1023.f);
248 }
249 lastCRU = digit.getCRU();
250 lastTimeBin = timeBin;
251 maxTimeBinProcessed = std::max(lastTimeBin, maxTimeBinProcessed);
252
253 bool isInjectedCMPad = false;
254 if (hasInjectedCMValue) {
255 const auto posLow = mCMInjectIDLower[lastCRU % 10];
256 const auto posUpper = mCMInjectIDUpper[lastCRU % 10];
257 const auto row = digit.getRow();
258 const auto pad = digit.getPad();
259 if (row == posLow.row) {
260 if (pad == posLow.pad) {
261 cmInjectedLower = digit.getChargeFloat();
262 isInjectedCMPad = true;
263 // LOGP(info, "setting lower CM value cru {}, row {}, pad {}: {:012b}", digit.getCRU(), row, pad, floatToFixedSize(digit.getChargeFloat()));
264 }
265 }
266 if (row == posUpper.row) {
267 if (pad == posUpper.pad) {
268 cmInjectedUpper = digit.getChargeFloat();
269 isInjectedCMPad = true;
270 // LOGP(info, "setting upper CM value cru {}, row {}, pad {}: {:012b}", digit.getCRU(), row, pad, floatToFixedSize(digit.getChargeFloat()));
271 if (cmInjectedUpper == 0) {
272 LOGP(info, "cm upper = 0 cru {}, row {}, pad {}", digit.getCRU(), row, pad);
273 }
274 }
275 }
276 }
277
278 if (!isInjectedCMPad) {
279 data.adcValues.emplace_back(charge);
280 data.cmKValues.emplace_back(cmkValue);
281 data.pedestals.emplace_back(pedestal);
282 }
283 }
284 {
285 auto& cmValuesCRU = cmValues[lastCRU];
286 if (cmValuesCRU.size() <= lastTimeBin) {
287 cmValuesCRU.resize(lastTimeBin + 500);
288 if (cmDebug) {
289 (*cmDebug)[lastCRU].resize(lastTimeBin + 500);
290 }
291 }
292 cmValuesCRU[lastTimeBin] = getCommonMode(data.adcValues, data.cmKValues, data.pedestals, cmDebug ? &((*cmDebug)[lastCRU][lastTimeBin]) : nullptr);
293 // LOGP(info, "processing CRU {}, timeBin {}, CM = {}", lastCRU, lastTimeBin, cmValuesCRU[lastTimeBin].cmValue);
294
295 if (hasInjectedCMValue) {
296 cmValuesCRU[lastTimeBin].cmValueCRU = decodeInjectedCMValue(cmInjectedLower, cmInjectedUpper);
297 }
298
299 data.clear();
300 }
301 return maxTimeBinProcessed;
302}
303
304int CommonModeCorrection::correctDigits(std::vector<Digit>& digits, std::vector<std::vector<CMInfo>>& cmValues, bool negativeOnly, bool hasInjectedCMValue, std::vector<std::vector<CMDebug>>* cmDebug, int minTimeBin, int maxTimeBin) const
305{
306 const auto maxTimeBinProcessed = getCommonMode(digits, cmValues, negativeOnly, hasInjectedCMValue, cmDebug, minTimeBin, maxTimeBin);
307 const auto& cmkValues = mPadMaps.at("CMkValues");
308 const auto& pedestals = mPadMaps.at("Pedestals");
309 // ===| apply correction |====
310 for (auto& digit : digits) {
311 const auto timeBin = digit.getTimeStamp();
312 if ((minTimeBin > -1) && (timeBin < minTimeBin)) {
313 continue;
314 }
315 if ((maxTimeBin > -1) && (timeBin > maxTimeBin)) {
316 continue;
317 }
318 const auto sector = CRU(digit.getCRU()).sector();
319 const auto cmKValue = cmkValues.getValue(sector, digit.getRow(), digit.getPad());
320 // LOGP(info, "correcting value for CRU {}, time bin {}", digit.getCRU(), digit.getTimeStamp());
321 const auto cmValue = cmValues[digit.getCRU()][digit.getTimeStamp()].cmValue;
322 const auto cmNPads = cmValues[digit.getCRU()][digit.getTimeStamp()].nPadsUsed;
323 if ((!negativeOnly || cmValue < 0) && (cmNPads > mNPadsMinCM)) {
324 digit.setCharge(digit.getCharge() - cmValue * cmKValue);
325 if (mCorrectOutputForPedestal) {
326 const auto sector = CRU(digit.getCRU()).sector();
327 const auto pedestal = pedestals.getValue(sector, digit.getRow(), digit.getPad());
328 digit.setCharge(digit.getChargeFloat() - pedestal);
329 }
330 }
331 }
332
333 return maxTimeBinProcessed;
334}
335
336void CommonModeCorrection::correctDigits(std::string_view digiFileIn, Long64_t maxEntries, std::string_view digitFileOut, std::string_view cmFileOut, bool negativeOnly, int nThreads, bool writeOnlyCM, bool writeDebug, bool hasInjectedCMValue, int minTimeBin, int maxTimeBin)
337{
338 ROOT::EnableThreadSafety();
339
340 TChain* tree = o2::tpc::utils::buildChain(fmt::format("ls {}", digiFileIn), "o2sim", "o2sim");
341 Long64_t nEntries = tree->GetEntries();
342 if (maxEntries > 0) {
343 nEntries = std::min(nEntries, maxEntries);
344 }
345
346 if (mPadMaps.find("Pedestals") == mPadMaps.end()) {
347 LOGP(info, "Using empty pedestals");
348 mPadMaps["Pedestals"] = CalPad("Pedestals");
349 }
350
351 std::unique_ptr<TFile> fOut;
352 std::unique_ptr<TTree> tOut;
353 if (!writeOnlyCM) {
354 fOut.reset(TFile::Open(digitFileOut.data(), "RECREATE"));
355 fOut->SetCompressionLevel(5); // zstd default level
356 fOut->SetCompressionAlgorithm(5); // zstd
357 tOut = std::make_unique<TTree>("o2sim", "o2sim");
358 }
359
360 std::array<std::vector<o2::tpc::Digit>*, 36> digitizedSignal;
361 std::array<TBranch*, 36> outBranches{};
362 for (size_t iSec = 0; iSec < digitizedSignal.size(); ++iSec) {
363 digitizedSignal[iSec] = nullptr;
364 tree->SetBranchAddress(Form("TPCDigit_%zu", iSec), &digitizedSignal[iSec]);
365 if (tOut) {
366 outBranches[iSec] = tOut->Branch(Form("TPCDigit_%zu", iSec), &digitizedSignal[iSec]);
367 }
368 }
369
370 o2::utils::TreeStreamRedirector pcstream(cmFileOut.data(), "recreate");
371 pcstream.GetFile()->SetCompressionAlgorithm(5);
372 pcstream.GetFile()->SetCompressionLevel(5);
373
374 for (Long64_t iTF = 0; iTF < nEntries; ++iTF) {
375 tree->GetEntry(iTF);
376 LOGP(info, "Processing entry {}/{}", iTF + 1, nEntries);
377
378 std::vector<std::vector<CMInfo>> cmValues; // CRU * timeBin
379 std::vector<std::vector<CMDebug>> cmDebug; // CRU * timeBin
380
381 cmValues.resize(CRU::MaxCRU);
382 if (writeDebug) {
383 cmDebug.resize(CRU::MaxCRU);
384 }
385 int maxTimeBinSeen = -1;
386
387 auto worker = [&](int iTread) {
388 // for (size_t iSector = 0; iSector < 36; ++iSector) {
389 for (size_t iSector = iTread; iSector < 36; iSector += nThreads) {
390 LOGP(info, "Processing entry {}/{}, starting sector {}", iTF + 1, nEntries, iSector);
391 auto digits = digitizedSignal[iSector];
392 int maxTimeBinSector = 0;
393 if (digits && (digits->size() > 0)) {
394 maxTimeBinSector = correctDigits(*digits, cmValues, negativeOnly, hasInjectedCMValue, writeDebug ? &cmDebug : nullptr, minTimeBin, maxTimeBin);
395 }
396 {
397 static std::mutex maxMutex;
398 std::lock_guard lock{maxMutex};
399 maxTimeBinSeen = std::max(maxTimeBinSeen, maxTimeBinSector);
400 if (outBranches[iSector]) {
401 outBranches[iSector]->Fill();
402 LOGP(info, "Filling branch for sector {}", iSector);
403 }
404 }
405 }
406 };
407
408 std::vector<std::thread> threads(nThreads);
409
410 for (int i = 0; i < threads.size(); i++) {
411 threads[i] = std::thread(worker, i);
412 }
413
414 // wait for the threads to finish
415 for (auto& th : threads) {
416 th.join();
417 }
418
419 size_t maxTimeCRU = 0;
420 for (int iCRU = 0; iCRU < cmValues.size(); ++iCRU) {
421 maxTimeCRU = std::max(maxTimeCRU, cmValues[iCRU].size());
422 }
423 const int maxTBCRU = std::min(maxTimeBinSeen, int(maxTimeCRU));
424
425 for (int iTimeBin = 0; iTimeBin < maxTBCRU; ++iTimeBin) {
426
427 std::vector<CMInfo> cm(CRU::MaxCRU);
428 std::vector<CMDebug> cmD(CRU::MaxCRU);
429 std::vector<float> sumPosStack(36 * 4);
430 std::vector<float> nPosStack(36 * 4);
431 std::vector<float> nSaturationStack(36 * 4);
432 std::vector<float> sumPosStackCRU(CRU::MaxCRU);
433 std::vector<float> sumPosStackCRUCorr(CRU::MaxCRU);
434 std::vector<float> nSaturationStackCRU(CRU::MaxCRU);
435
436 for (int iCRU = 0; iCRU < cmValues.size(); ++iCRU) {
437 if (cmValues[iCRU].size() == 0) {
438 continue;
439 }
440 cm[iCRU] = cmValues[iCRU][iTimeBin];
441 if (writeDebug) {
442 cmD[iCRU] = cmDebug[iCRU][iTimeBin];
443 }
444 const CRU cru(iCRU);
445 const StackID stackID{cru.sector(), cru.gemStack()};
446 const auto index = stackID.getIndex();
447 sumPosStack[index] += cm[iCRU].sumPos;
448 nPosStack[index] += (Mapper::PADSPERREGION[cru.region()] - cm[iCRU].nNeg);
449 nSaturationStack[index] += cm[iCRU].nSaturation;
450 }
451
452 for (int iCRU = 0; iCRU < cmValues.size(); ++iCRU) {
453 if (cmValues[iCRU].size() == 0) {
454 continue;
455 }
456 const CRU cru(iCRU);
457 const StackID stackID{cru.sector(), cru.gemStack()};
458 const auto index = stackID.getIndex();
459 sumPosStackCRU[iCRU] = sumPosStack[index];
460 sumPosStackCRUCorr[iCRU] = sumPosStack[index] - nPosStack[index] * cm[iCRU].cmValue;
461 nSaturationStackCRU[iCRU] = nSaturationStack[index];
462 }
463
464 pcstream << "cm"
465 << "iTF=" << iTF
466 << "iTimeBin=" << iTimeBin
467 << "cmInfo=" << cm
468 << "sumPosStack=" << sumPosStackCRU
469 << "sumPosStackCorr=" << sumPosStackCRUCorr
470 << "nSaturationStack=" << nSaturationStackCRU;
471
472 if (writeDebug) {
473 pcstream << "cm"
474 << "cmDebug=" << cmD;
475 }
476
477 pcstream << "cm"
478 << "\n";
479 }
480
481 // if (tOut) {
482 // tOut->Fill();
483 // }
484 }
485
486 pcstream.Close();
487 if (fOut && tOut) {
488 tOut->SetEntries(nEntries);
489 fOut->cd();
490 tOut->Write();
491 tOut.reset();
492 fOut->Close();
493 }
494}
495
496float CommonModeCorrection::decodeInjectedCMValue(float lower, float upper)
497{
498 // CRU row0 pad0 row1 pad1
499 // 0 0 2 0 3
500 // 1 20 1 20 3
501 // 2 32 2 32 3
502 // 3 51 1 51 3
503 // 4 62 1 62 2
504 // 5 84 1 84 4
505 // 6 97 1 97 2
506 // 7 116 2 115 5
507 // 8 127 2 127 3
508 // 9 142 0 142 4
509 //
510 // CM Value encoding:
511 // Kanal 0 : Bit 11 ... 8 = 0x8. Bit 7..0 CM-Werte Bits 7...0
512 // Kanal 1 : Bit 11.. 9 = "100". Bit 8 = CM Positive, Bits 6..0 = CM-Wert Bits 14..8
513 const int ilower = floatToFixedSize(lower);
514 const int iupper = floatToFixedSize(upper);
515 if (!(ilower & 0x800) || !(iupper & 0x800)) {
516 LOGP(error, "Not a CM word: lower: {:012b} upper: {:012b}", ilower, iupper);
517 return 0;
518 }
519 const int fixedSizeCM = ((iupper & 0x7F) << 8) + (ilower & 0xFF);
520 const float floatCM = fixedSizeToFloat<8>(fixedSizeCM);
521
522 // bit 8 of upper word is the sign 1 = positive
523 return (iupper & 0x100) ? floatCM : -floatCM;
524}
525
526float CommonModeCorrection::getCalPadValue(const std::string calibName, int icru, int pad) const
527{
528 if (mPadMaps.find(calibName) == mPadMaps.end()) {
529 LOGP(error, "{} not set, cannot be used", calibName);
530 return 0;
531 }
532 const auto& calPad = mPadMaps.at(calibName);
533 const CRU cru(icru);
534 const int roc = cru.roc();
535 const int padOffset = (cru.isIROC()) ? Mapper::GLOBALPADOFFSET[cru.region()] : Mapper::GLOBALPADOFFSET[cru.region()] - Mapper::GLOBALPADOFFSET[4];
536
537 const auto& calArray = calPad.getCalArray(roc);
538
539 return calArray.getValue(padOffset + pad);
540}
541
542bool CommonModeCorrection::padMapExists(const std::string& calibName)
543{
544 if (mPadMaps.find(calibName) == mPadMaps.end()) {
545 LOGP(error, "{} not in mPadMaps", calibName);
546 return false;
547 }
548 return true;
549}
550
551void CommonModeCorrection::loadCalPad(std::string_view fileName, std::string_view nameInFile, std::string_view namePadMap)
552{
553 if (fileName.size() == 0) {
554 return;
555 }
556
557 auto pads = o2::tpc::utils::readCalPads(fileName, nameInFile);
558 if ((pads.size() == 0) || (pads.at(0) == nullptr)) {
559 LOGP(error, "Could not load object {} from file {}", nameInFile, fileName);
560 return;
561 }
562
563 if (namePadMap.size() == 0) {
564 namePadMap = nameInFile;
565 }
566
567 mPadMaps[namePadMap.data()] = *pads[0];
568}
Calculate the common mode correction factor.
int16_t charge
Definition RawEventData.h:5
int32_t i
uint32_t roc
Definition RawData.h:3
void init(std::string const &hosts)
Definition CcdbApi.cxx:165
std::enable_if<!std::is_base_of< o2::conf::ConfigurableParam, T >::value, T * >::type retrieveFromTFileAny(std::string const &path, std::map< std::string, std::string > const &metadata, long timestamp=-1, std::map< std::string, std::string > *headers=nullptr, std::string const &etag="", const std::string &createdNotAfter="", const std::string &createdNotBefore="") const
Definition CcdbApi.h:660
unsigned char region() const
Definition CRU.h:64
GEMstack gemStack() const
Definition CRU.h:82
@ MaxCRU
Definition CRU.h:31
const Sector sector() const
Definition CRU.h:65
CMdata collectCMdata(const std::vector< Digit > &digits, int cru, int timeBin)
CMInfo getCommonMode(gsl::span< const float > values, gsl::span< const float > cmKValues, gsl::span< const float > pedestals, CMDebug *cmDebug=nullptr) const
int correctDigits(std::vector< Digit > &digits, std::vector< std::vector< CMInfo > > &cmValues, bool negativeOnly=false, bool hasInjectedCMValue=false, std::vector< std::vector< CMDebug > > *cmDebug=nullptr, int minTimeBin=-1, int maxTimeBin=-1) const
void loadCalPad(std::string_view fileName, std::string_view nameInFile, std::string_view namePadMap="")
static float decodeInjectedCMValue(float lower, float upper)
void loadDefaultPadMaps(FEEConfig::Tags feeTag=FEEConfig::Tags::Physics30sigma)
load the Pad maps from CCDB
static constexpr unsigned int GLOBALPADOFFSET[NREGIONS]
offset of number of pads for region
Definition Mapper.h:531
static constexpr unsigned int PADSPERREGION[NREGIONS]
number of pads per CRU
Definition Mapper.h:530
GLsizeiptr size
Definition glcorearb.h:659
GLenum GLsizei dataSize
Definition glcorearb.h:3994
GLuint index
Definition glcorearb.h:781
GLenum GLsizei GLsizei GLint * values
Definition glcorearb.h:1576
GLboolean * data
Definition glcorearb.h:298
GLuint GLfloat * val
Definition glcorearb.h:1582
constexpr uint32_t floatToFixedSize(float value)
convert float to integer with fixed precision and max number of digits
constexpr float fixedSizeToFloat(uint32_t value)
std::vector< CalPad * > readCalPads(const std::string_view fileName, const std::vector< std::string > &calPadNames)
Definition Utils.cxx:190
TChain * buildChain(std::string_view command, std::string_view treeName, std::string_view treeTitle="", bool checkSubDir=false)
Definition Utils.cxx:278
Global TPC definitions and constants.
Definition SimTraits.h:167
CalDet< float > CalPad
Definition CalDet.h:492
float cmValueCRU
common mode value from firmware, if available
uint16_t nSaturation
number of pads in saturation
float cmValueStd
std dev of common mode values from pseudo code
uint16_t nPadsUsed
number of pads used for CM calculation
float sumNeg
sum of negative signals <= mSumPosThreshold, corrected for k-factor
uint16_t nOccupancy
number of CM corrected pads larger than mOccupancyThreshold
float sumPos
sum of positive signals > mSumPosThreshold
float cmValue
common mode value from pseudo code
uint16_t nNeg
number of pads used for sumNeg
Tags
Tag definitions for TPC/Config/FEE.
Definition FEEConfig.h:50
GEM stack identification.
Definition Defs.h:77
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))
std::vector< Digit > digits
std::vector< int > row