From 346100773393e2ec822a6848402b92e9a96ca990 Mon Sep 17 00:00:00 2001 From: Matthias Kleiner Date: Sat, 12 Nov 2022 11:25:45 +0100 Subject: [PATCH 1/3] IDCs: Add option to write IDCDelta to calibration file --- .../include/TPCWorkflow/TPCFactorizeIDCSpec.h | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Detectors/TPC/workflow/include/TPCWorkflow/TPCFactorizeIDCSpec.h b/Detectors/TPC/workflow/include/TPCWorkflow/TPCFactorizeIDCSpec.h index aad36f716006a..dc8071aec78a5 100644 --- a/Detectors/TPC/workflow/include/TPCWorkflow/TPCFactorizeIDCSpec.h +++ b/Detectors/TPC/workflow/include/TPCWorkflow/TPCFactorizeIDCSpec.h @@ -59,6 +59,7 @@ class TPCFactorizeIDCSpec : public o2::framework::Task mDumpIDC0 = ic.options().get("dump-IDC0"); mDumpIDC1 = ic.options().get("dump-IDC1"); mDumpIDCDelta = ic.options().get("dump-IDCDelta"); + mDumpIDCDeltaCalibData = ic.options().get("dump-IDCDelta-calib-data"); mDumpIDCs = ic.options().get("dump-IDCs"); mOffsetCCDB = ic.options().get("add-offset-for-CCDB-timestamp"); mDisableIDCDelta = ic.options().get("disable-IDCDelta"); @@ -182,6 +183,7 @@ class TPCFactorizeIDCSpec : public o2::framework::Task bool mDumpIDC0{false}; ///< Dump IDC0 to file bool mDumpIDC1{false}; ///< Dump IDC1 to file bool mDumpIDCDelta{false}; ///< Dump IDCDelta to file + bool mDumpIDCDeltaCalibData{false}; ///< dump the IDC Delta as a calibration file bool mDumpIDCs{false}; ///< dump IDCs to file bool mOffsetCCDB{false}; ///< flag for setting and offset for CCDB timestamp bool mDisableIDCDelta{false}; ///< disable the processing and storage of IDCDelta @@ -286,7 +288,7 @@ class TPCFactorizeIDCSpec : public o2::framework::Task totalTime += time.count(); } - if (!mDisableIDCDelta) { + if (!mDisableIDCDelta || mDumpIDCDeltaCalibData) { start = timer::now(); for (unsigned int iChunk = 0; iChunk < mIDCFactorization.getNChunks(side); ++iChunk) { auto startGrouping = timer::now(); @@ -325,9 +327,24 @@ class TPCFactorizeIDCSpec : public o2::framework::Task imageIDCDelta = o2::ccdb::CcdbApi::createObjectImage(&idcDelta, &ccdbInfoIDCDelta); break; } - LOGP(info, "Sending object {} / {} of size {} bytes, valid for {} : {} ", ccdbInfoIDCDelta.getPath(), ccdbInfoIDCDelta.getFileName(), imageIDCDelta->size(), ccdbInfoIDCDelta.getStartValidityTimestamp(), ccdbInfoIDCDelta.getEndValidityTimestamp()); - output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, getDataDescriptionCCDBIDCDelta(), iChunk}, *imageIDCDelta.get()); - output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, getDataDescriptionCCDBIDCDelta(), iChunk}, ccdbInfoIDCDelta); + + if (!mDisableIDCDelta) { + LOGP(info, "Sending object {} / {} of size {} bytes, valid for {} : {} ", ccdbInfoIDCDelta.getPath(), ccdbInfoIDCDelta.getFileName(), imageIDCDelta->size(), ccdbInfoIDCDelta.getStartValidityTimestamp(), ccdbInfoIDCDelta.getEndValidityTimestamp()); + output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, getDataDescriptionCCDBIDCDelta(), iChunk}, *imageIDCDelta.get()); + output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, getDataDescriptionCCDBIDCDelta(), iChunk}, ccdbInfoIDCDelta); + } + + if (mDumpIDCDeltaCalibData) { + const std::string sideStr = sideA ? "A" : "C"; + TFile fCalibData(fmt::format("IDCDelta_side{}_cal_data_{}.root", sideStr, ccdbInfoIDCDelta.getStartValidityTimestamp()).data(), "RECREATE"); + fCalibData.WriteObject(imageIDCDelta.get(), "ccdb_object"); + fCalibData.Close(); + + TFile fCalibMetaData(fmt::format("IDCDelta_side{}_cal_metadata_{}.root", sideStr, ccdbInfoIDCDelta.getStartValidityTimestamp()).data(), "RECREATE"); + fCalibMetaData.WriteObject(&ccdbInfoIDCDelta, "ccdb_object"); + fCalibMetaData.Close(); + } + auto stopCCDBIDCDelta = timer::now(); time = stopCCDBIDCDelta - startCCDBIDCDelta; LOGP(info, "Compression and CCDB object creation time: {}", time.count()); @@ -408,6 +425,7 @@ DataProcessorSpec getTPCFactorizeIDCSpec(const int lane, const std::vector Date: Sat, 12 Nov 2022 17:47:34 +0100 Subject: [PATCH 2/3] IDCs: fix creation of calib file --- .../include/TPCWorkflow/TPCFactorizeIDCSpec.h | 105 ++++++++++++------ 1 file changed, 74 insertions(+), 31 deletions(-) diff --git a/Detectors/TPC/workflow/include/TPCWorkflow/TPCFactorizeIDCSpec.h b/Detectors/TPC/workflow/include/TPCWorkflow/TPCFactorizeIDCSpec.h index dc8071aec78a5..c64478bf7ac49 100644 --- a/Detectors/TPC/workflow/include/TPCWorkflow/TPCFactorizeIDCSpec.h +++ b/Detectors/TPC/workflow/include/TPCWorkflow/TPCFactorizeIDCSpec.h @@ -19,11 +19,14 @@ #include #include +#include #include "Framework/Task.h" #include "Framework/ControlService.h" #include "Framework/Logger.h" #include "Framework/DataProcessorSpec.h" #include "Framework/DeviceSpec.h" +#include "Framework/DataTakingContext.h" +#include "DetectorsCommonDataFormats/FileMetaData.h" #include "Headers/DataHeader.h" #include "TPCCalibration/IDCFactorization.h" #include "TPCCalibration/IDCAverageGroup.h" @@ -63,6 +66,15 @@ class TPCFactorizeIDCSpec : public o2::framework::Task mDumpIDCs = ic.options().get("dump-IDCs"); mOffsetCCDB = ic.options().get("add-offset-for-CCDB-timestamp"); mDisableIDCDelta = ic.options().get("disable-IDCDelta"); + mCalibFileDir = ic.options().get("output-dir"); + if (mCalibFileDir != "/dev/null") { + mCalibFileDir = o2::utils::Str::rectifyDirectory(mCalibFileDir); + } + mMetaFileDir = ic.options().get("meta-output-dir"); + if (mMetaFileDir != "/dev/null") { + mMetaFileDir = o2::utils::Str::rectifyDirectory(mMetaFileDir); + } + const std::string refGainMapFile = ic.options().get("gainMapFile"); if (!refGainMapFile.empty()) { LOGP(info, "Loading GainMap from file {}", refGainMapFile); @@ -90,6 +102,12 @@ class TPCFactorizeIDCSpec : public o2::framework::Task LOGP(warning, "firstTF not Found!!! Found valid inputs {}. Setting {} as first TF", pc.inputs().countValidInputs(), mTFFirst); } + // set data taking context only once + if (mSetDataTakingCont) { + mDataTakingContext = pc.services().get(); + mSetDataTakingCont = false; + } + const long relTF = (mTFFirst == -1) ? 0 : (currTF - mTFFirst) / mNTFsBuffer; // loop over input data @@ -165,30 +183,34 @@ class TPCFactorizeIDCSpec : public o2::framework::Task static constexpr header::DataDescription getDataDescriptionCCDBIDCPadFlag() { return header::DataDescription{"TPC_CalibFlags"}; } private: - const std::vector mCRUs{}; ///< CRUs to process in this instance - unsigned int mProcessedCRUs{}; ///< number of processed CRUs to keep track of when the writing to CCDB etc. will be done - IDCFactorization mIDCFactorization; ///< object aggregating the IDCs and performing the factorization of the IDCs - IDCAverageGroup mIDCGrouping; ///< object for averaging and grouping of the IDCs - const IDCDeltaCompression mCompressionDeltaIDC{}; ///< compression type for IDC Delta - const bool mUsePrecisetimeStamp{true}; ///< use precise time stamp when writing to CCDB - const bool mSendOutFFT{false}; ///< flag if the output will be send for the FFT - const bool mSendOutCCDB{false}; ///< sending the outputs for ccdb populator - long mTFFirst{-1}; ///< first TF of current aggregation interval - bool mUpdateGroupingPar{true}; ///< flag to set if grouping parameters should be updated or not - const int mLaneId{0}; ///< the id of the current process within the parallel pipeline - std::vector mSides{}; ///< processed TPC sides - const int mNTFsBuffer{1}; ///< number of TFs for which the IDCs will be buffered - std::unique_ptr> mPadFlagsMap; ///< status flag for each pad (i.e. if the pad is dead). This map is buffered to check if something changed, when a new map is created - int mNOrbitsIDC{12}; ///< Number of orbits over which the IDCs are integrated. - bool mDumpIDC0{false}; ///< Dump IDC0 to file - bool mDumpIDC1{false}; ///< Dump IDC1 to file - bool mDumpIDCDelta{false}; ///< Dump IDCDelta to file - bool mDumpIDCDeltaCalibData{false}; ///< dump the IDC Delta as a calibration file - bool mDumpIDCs{false}; ///< dump IDCs to file - bool mOffsetCCDB{false}; ///< flag for setting and offset for CCDB timestamp - bool mDisableIDCDelta{false}; ///< disable the processing and storage of IDCDelta - dataformats::Pair mTFInfo{}; ///< orbit reset time for CCDB time stamp writing - bool mEnableWritingPadStatusMap{false}; ///< do not store the pad status map in the CCDB + const std::vector mCRUs{}; ///< CRUs to process in this instance + unsigned int mProcessedCRUs{}; ///< number of processed CRUs to keep track of when the writing to CCDB etc. will be done + std::string mMetaFileDir{}; + std::string mCalibFileDir{}; + IDCFactorization mIDCFactorization; ///< object aggregating the IDCs and performing the factorization of the IDCs + IDCAverageGroup mIDCGrouping; ///< object for averaging and grouping of the IDCs + const IDCDeltaCompression mCompressionDeltaIDC{}; ///< compression type for IDC Delta + const bool mUsePrecisetimeStamp{true}; ///< use precise time stamp when writing to CCDB + const bool mSendOutFFT{false}; ///< flag if the output will be send for the FFT + const bool mSendOutCCDB{false}; ///< sending the outputs for ccdb populator + long mTFFirst{-1}; ///< first TF of current aggregation interval + bool mUpdateGroupingPar{true}; ///< flag to set if grouping parameters should be updated or not + const int mLaneId{0}; ///< the id of the current process within the parallel pipeline + std::vector mSides{}; ///< processed TPC sides + const int mNTFsBuffer{1}; ///< number of TFs for which the IDCs will be buffered + std::unique_ptr> mPadFlagsMap; ///< status flag for each pad (i.e. if the pad is dead). This map is buffered to check if something changed, when a new map is created + int mNOrbitsIDC{12}; ///< Number of orbits over which the IDCs are integrated. + bool mDumpIDC0{false}; ///< Dump IDC0 to file + bool mDumpIDC1{false}; ///< Dump IDC1 to file + bool mDumpIDCDelta{false}; ///< Dump IDCDelta to file + bool mDumpIDCDeltaCalibData{false}; ///< dump the IDC Delta as a calibration file + bool mDumpIDCs{false}; ///< dump IDCs to file + bool mOffsetCCDB{false}; ///< flag for setting and offset for CCDB timestamp + bool mDisableIDCDelta{false}; ///< disable the processing and storage of IDCDelta + dataformats::Pair mTFInfo{}; ///< orbit reset time for CCDB time stamp writing + bool mEnableWritingPadStatusMap{false}; ///< do not store the pad status map in the CCDB + o2::framework::DataTakingContext mDataTakingContext{}; + bool mSetDataTakingCont{true}; const std::vector mFilter = {{"idcagg", ConcreteDataTypeMatcher{gDataOriginTPC, TPCDistributeIDCSpec::getDataDescriptionIDC(mLaneId)}, Lifetime::Sporadic}}; ///< filter for looping over input data void sendOutput(DataAllocator& output, const long timeStampStart) @@ -334,15 +356,34 @@ class TPCFactorizeIDCSpec : public o2::framework::Task output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, getDataDescriptionCCDBIDCDelta(), iChunk}, ccdbInfoIDCDelta); } - if (mDumpIDCDeltaCalibData) { + if (mDumpIDCDeltaCalibData && mCalibFileDir != "/dev/null") { const std::string sideStr = sideA ? "A" : "C"; - TFile fCalibData(fmt::format("IDCDelta_side{}_cal_data_{}.root", sideStr, ccdbInfoIDCDelta.getStartValidityTimestamp()).data(), "RECREATE"); - fCalibData.WriteObject(imageIDCDelta.get(), "ccdb_object"); - fCalibData.Close(); + std::string calibFName = fmt::format("IDCDelta_side{}_cal_data_{}.root", sideStr, ccdbInfoIDCDelta.getStartValidityTimestamp()); + try { + std::ofstream calFile(fmt::format("{}{}", mCalibFileDir, calibFName), std::ios::out | std::ios::binary); + calFile.write(imageIDCDelta->data(), imageIDCDelta->size()); + calFile.close(); + } catch (std::exception const& e) { + LOG(error) << "Failed to store IDC calibration data file " << calibFName << ", reason: " << e.what(); + } - TFile fCalibMetaData(fmt::format("IDCDelta_side{}_cal_metadata_{}.root", sideStr, ccdbInfoIDCDelta.getStartValidityTimestamp()).data(), "RECREATE"); - fCalibMetaData.WriteObject(&ccdbInfoIDCDelta, "ccdb_object"); - fCalibMetaData.Close(); + if (mMetaFileDir != "/dev/null") { + o2::dataformats::FileMetaData calMetaData; + calMetaData.fillFileData(calibFName); + calMetaData.setDataTakingContext(mDataTakingContext); + calMetaData.type = "calib"; + calMetaData.priority = "low"; + auto metaFileNameTmp = fmt::format("{}{}.tmp", mMetaFileDir, calibFName); + auto metaFileName = fmt::format("{}{}.done", mMetaFileDir, calibFName); + try { + std::ofstream metaFileOut(metaFileNameTmp); + metaFileOut << calMetaData; + metaFileOut.close(); + std::filesystem::rename(metaFileNameTmp, metaFileName); + } catch (std::exception const& e) { + LOG(error) << "Failed to store CTF meta data file " << metaFileName << ", reason: " << e.what(); + } + } } auto stopCCDBIDCDelta = timer::now(); @@ -427,6 +468,8 @@ DataProcessorSpec getTPCFactorizeIDCSpec(const int lane, const std::vector Date: Sat, 12 Nov 2022 18:12:25 +0100 Subject: [PATCH 3/3] IDCs: Fix start range of for loop for C-Side --- Detectors/TPC/calibration/src/IDCAverageGroup.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/TPC/calibration/src/IDCAverageGroup.cxx b/Detectors/TPC/calibration/src/IDCAverageGroup.cxx index 15f27df5b0f24..71e3e5f53ad55 100644 --- a/Detectors/TPC/calibration/src/IDCAverageGroup.cxx +++ b/Detectors/TPC/calibration/src/IDCAverageGroup.cxx @@ -130,7 +130,7 @@ void o2::tpc::IDCAverageGroup::processIDCs(const Ca const int cruEnd = (mSide == Side::A) ? CRU::MaxCRU / 2 : CRU::MaxCRU; #pragma omp parallel for num_threads(sNThreads) - for (unsigned int i = 0; i < cruEnd; ++i) { + for (unsigned int i = cruStart; i < cruEnd; ++i) { const unsigned int threadNum = omp_get_thread_num(); const CRU cru(i); idcStruct[threadNum].setCRU(cru);