From 3258a14b74ca409f0fb9feca543575fc37844e27 Mon Sep 17 00:00:00 2001 From: Matthias Kleiner Date: Sat, 28 Oct 2023 12:52:06 +0200 Subject: [PATCH] TPC IDCs: Adding consistency check for received IDCs - setting Lifetime to Sporadic due to buffering of IDCs for several TFs --- .../include/TPCCalibration/IDCFactorization.h | 4 ++ .../TPC/calibration/src/IDCFactorization.cxx | 59 +++++++++++++++++++ .../include/TPCWorkflow/TPCFLPIDCSpec.h | 2 +- 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/Detectors/TPC/calibration/include/TPCCalibration/IDCFactorization.h b/Detectors/TPC/calibration/include/TPCCalibration/IDCFactorization.h index 4e9d3ab542ff3..13c9d0b98412f 100644 --- a/Detectors/TPC/calibration/include/TPCCalibration/IDCFactorization.h +++ b/Detectors/TPC/calibration/include/TPCCalibration/IDCFactorization.h @@ -451,6 +451,10 @@ class IDCFactorization : public IDCGroupHelperSector /// normalize IDC0 void normIDCZero(const int type); + /// check if received have all the same size -received IDCs which have different size than expected are cleared- + /// \return returns true if all IDCs have same size + bool checkReceivedIDCs(); + ClassDefNV(IDCFactorization, 2) }; diff --git a/Detectors/TPC/calibration/src/IDCFactorization.cxx b/Detectors/TPC/calibration/src/IDCFactorization.cxx index a1df9ba46a1bb..1e61ded449d07 100644 --- a/Detectors/TPC/calibration/src/IDCFactorization.cxx +++ b/Detectors/TPC/calibration/src/IDCFactorization.cxx @@ -191,6 +191,10 @@ void o2::tpc::IDCFactorization::dumpIDCOneToFile(const Side side, const char* ou void o2::tpc::IDCFactorization::dumpToTree(const Side side, const char* outFileName) { + if (mIDCZero[mSideIndex[side]].mIDCZero.empty() || mIDCOne[mSideIndex[side]].mIDCOne.empty()) { + LOGP(info, "IDC0, IDC1 is empty! Returning"); + return; + } o2::tpc::IDCCCDBHelper helper; if (!mPadFlagsMap) { createStatusMap(); @@ -415,6 +419,10 @@ void o2::tpc::IDCFactorization::calcIDCOne(const DataVec& idcsData, const int id } } + if (idcOneTmp.size() <= integrationInterval) { + LOGP(error, "integrationInterval {} is larger than maximum: {}", integrationInterval, idcOneTmp.size()); + break; + } idcOneTmp[integrationInterval] += (idcZeroVal == 0) ? idcsData[idcs] : idcsData[idcs] / idcZeroVal; ++weights[integrationInterval]; } @@ -843,6 +851,9 @@ void o2::tpc::IDCFactorization::factorizeIDCs(const bool norm, const bool calcDe using timer = std::chrono::high_resolution_clock; LOGP(info, "Using {} threads for factorization of IDCs", sNThreads); + LOGP(info, "Checking received IDCs for consistency"); + checkReceivedIDCs(); + LOGP(info, "Calculating IDC0"); auto start = timer::now(); @@ -1184,4 +1195,52 @@ std::array o2::tpc::IDCFactorization::getStackMedian( return median; } +bool o2::tpc::IDCFactorization::checkReceivedIDCs() +{ + bool idcsGood = true; + for (unsigned int timeframe = 0; timeframe < mTimeFrames; ++timeframe) { + // check number of received slices for each CRU - this should be the same value or if no data has been received empty - + std::unordered_map> receivedIDCsSize; // number of received slices, CRUs + for (unsigned int cruInd = 0; cruInd < mCRUs.size(); ++cruInd) { + const unsigned int cru = mCRUs[cruInd]; + const o2::tpc::CRU cruTmp(cru); + const unsigned int region = cruTmp.region(); + const int nSlices = mIDCs[cru][timeframe].size() / mNIDCsPerCRU[region]; + if (nSlices > 0) { + if (receivedIDCsSize[nSlices].empty()) { + receivedIDCsSize[nSlices].reserve(mCRUs.size()); + } + receivedIDCsSize[nSlices].emplace_back(cru); + } + } + // if more than one slice has been found use the IDCs from CRUs which have the most equal slices + if (receivedIDCsSize.size() > 1) { + LOGP(warning, "Received inconsistent IDCs!"); + idcsGood = false; + // check which slice has the most CRUs - reset all other - + std::pair nSlicesMostCRUs = {-1, -1}; // nSlices, nCRUs + for (auto nSlices : receivedIDCsSize) { + const int nCRUs = nSlices.second.size(); + // store number of slices with most CRUs + if (nCRUs > nSlicesMostCRUs.second) { + nSlicesMostCRUs = {nSlices.first, nCRUs}; + } + for (auto cru : nSlices.second) { + LOGP(info, "Received {} slices for CRU {}", nSlices.first, cru); + } + } + LOGP(info, "Setting {} slices for {} valid CRUs", nSlicesMostCRUs.first, nSlicesMostCRUs.second); + for (auto nSlices : receivedIDCsSize) { + if (nSlices.first != nSlicesMostCRUs.first) { + for (auto cru : nSlices.second) { + LOGP(info, "Clearing IDCs for CRU {}", cru); + mIDCs[cru][timeframe].clear(); + } + } + } + } + } + return idcsGood; +} + template void o2::tpc::IDCFactorization::calcIDCOne(const o2::pmr::vector&, const int, const int, const unsigned int, const CRU, std::vector&, std::vector&, const IDCZero*, const CalDet*, const bool); diff --git a/Detectors/TPC/workflow/include/TPCWorkflow/TPCFLPIDCSpec.h b/Detectors/TPC/workflow/include/TPCWorkflow/TPCFLPIDCSpec.h index 3674ff4eb1b79..6316824966856 100644 --- a/Detectors/TPC/workflow/include/TPCWorkflow/TPCFLPIDCSpec.h +++ b/Detectors/TPC/workflow/include/TPCWorkflow/TPCFLPIDCSpec.h @@ -233,7 +233,7 @@ DataProcessorSpec getTPCFLPIDCSpec(const int ilane, const std::vector& inputSpecs.emplace_back(InputSpec{"idcs", gDataOriginTPC, TPCIntegrateIDCDevice::getDataDescription(TPCIntegrateIDCDevice::IDCFormat::Sim), subSpec, Lifetime::Timeframe}); const Side side = CRU(cru).side(); - outputSpecs.emplace_back(ConcreteDataMatcher{gDataOriginTPC, TPCFLPIDCDevice::getDataDescriptionIDCGroup(side), subSpec}); + outputSpecs.emplace_back(ConcreteDataMatcher{gDataOriginTPC, TPCFLPIDCDevice::getDataDescriptionIDCGroup(side), subSpec}, Lifetime::Sporadic); if (enableSynchProc) { outputSpecs.emplace_back(ConcreteDataMatcher{gDataOriginTPC, TPCFLPIDCDevice::getDataDescription1DIDCEPN(), subSpec}); outputSpecs.emplace_back(ConcreteDataMatcher{gDataOriginTPC, TPCFLPIDCDevice::getDataDescription1DIDCEPNWeights(), subSpec});