|
19 | 19 |
|
20 | 20 | #include <vector> |
21 | 21 | #include <fmt/format.h> |
| 22 | +#include <filesystem> |
22 | 23 | #include "Framework/Task.h" |
23 | 24 | #include "Framework/ControlService.h" |
24 | 25 | #include "Framework/Logger.h" |
25 | 26 | #include "Framework/DataProcessorSpec.h" |
26 | 27 | #include "Framework/DeviceSpec.h" |
| 28 | +#include "Framework/DataTakingContext.h" |
| 29 | +#include "DetectorsCommonDataFormats/FileMetaData.h" |
27 | 30 | #include "Headers/DataHeader.h" |
28 | 31 | #include "TPCCalibration/IDCFactorization.h" |
29 | 32 | #include "TPCCalibration/IDCAverageGroup.h" |
@@ -59,9 +62,19 @@ class TPCFactorizeIDCSpec : public o2::framework::Task |
59 | 62 | mDumpIDC0 = ic.options().get<bool>("dump-IDC0"); |
60 | 63 | mDumpIDC1 = ic.options().get<bool>("dump-IDC1"); |
61 | 64 | mDumpIDCDelta = ic.options().get<bool>("dump-IDCDelta"); |
| 65 | + mDumpIDCDeltaCalibData = ic.options().get<bool>("dump-IDCDelta-calib-data"); |
62 | 66 | mDumpIDCs = ic.options().get<bool>("dump-IDCs"); |
63 | 67 | mOffsetCCDB = ic.options().get<bool>("add-offset-for-CCDB-timestamp"); |
64 | 68 | mDisableIDCDelta = ic.options().get<bool>("disable-IDCDelta"); |
| 69 | + mCalibFileDir = ic.options().get<std::string>("output-dir"); |
| 70 | + if (mCalibFileDir != "/dev/null") { |
| 71 | + mCalibFileDir = o2::utils::Str::rectifyDirectory(mCalibFileDir); |
| 72 | + } |
| 73 | + mMetaFileDir = ic.options().get<std::string>("meta-output-dir"); |
| 74 | + if (mMetaFileDir != "/dev/null") { |
| 75 | + mMetaFileDir = o2::utils::Str::rectifyDirectory(mMetaFileDir); |
| 76 | + } |
| 77 | + |
65 | 78 | const std::string refGainMapFile = ic.options().get<std::string>("gainMapFile"); |
66 | 79 | if (!refGainMapFile.empty()) { |
67 | 80 | LOGP(info, "Loading GainMap from file {}", refGainMapFile); |
@@ -89,6 +102,12 @@ class TPCFactorizeIDCSpec : public o2::framework::Task |
89 | 102 | LOGP(warning, "firstTF not Found!!! Found valid inputs {}. Setting {} as first TF", pc.inputs().countValidInputs(), mTFFirst); |
90 | 103 | } |
91 | 104 |
|
| 105 | + // set data taking context only once |
| 106 | + if (mSetDataTakingCont) { |
| 107 | + mDataTakingContext = pc.services().get<DataTakingContext>(); |
| 108 | + mSetDataTakingCont = false; |
| 109 | + } |
| 110 | + |
92 | 111 | const long relTF = (mTFFirst == -1) ? 0 : (currTF - mTFFirst) / mNTFsBuffer; |
93 | 112 |
|
94 | 113 | // loop over input data |
@@ -164,29 +183,34 @@ class TPCFactorizeIDCSpec : public o2::framework::Task |
164 | 183 | static constexpr header::DataDescription getDataDescriptionCCDBIDCPadFlag() { return header::DataDescription{"TPC_CalibFlags"}; } |
165 | 184 |
|
166 | 185 | private: |
167 | | - const std::vector<uint32_t> mCRUs{}; ///< CRUs to process in this instance |
168 | | - unsigned int mProcessedCRUs{}; ///< number of processed CRUs to keep track of when the writing to CCDB etc. will be done |
169 | | - IDCFactorization mIDCFactorization; ///< object aggregating the IDCs and performing the factorization of the IDCs |
170 | | - IDCAverageGroup<IDCAverageGroupTPC> mIDCGrouping; ///< object for averaging and grouping of the IDCs |
171 | | - const IDCDeltaCompression mCompressionDeltaIDC{}; ///< compression type for IDC Delta |
172 | | - const bool mUsePrecisetimeStamp{true}; ///< use precise time stamp when writing to CCDB |
173 | | - const bool mSendOutFFT{false}; ///< flag if the output will be send for the FFT |
174 | | - const bool mSendOutCCDB{false}; ///< sending the outputs for ccdb populator |
175 | | - long mTFFirst{-1}; ///< first TF of current aggregation interval |
176 | | - bool mUpdateGroupingPar{true}; ///< flag to set if grouping parameters should be updated or not |
177 | | - const int mLaneId{0}; ///< the id of the current process within the parallel pipeline |
178 | | - std::vector<Side> mSides{}; ///< processed TPC sides |
179 | | - const int mNTFsBuffer{1}; ///< number of TFs for which the IDCs will be buffered |
180 | | - std::unique_ptr<CalDet<PadFlags>> 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 |
181 | | - int mNOrbitsIDC{12}; ///< Number of orbits over which the IDCs are integrated. |
182 | | - bool mDumpIDC0{false}; ///< Dump IDC0 to file |
183 | | - bool mDumpIDC1{false}; ///< Dump IDC1 to file |
184 | | - bool mDumpIDCDelta{false}; ///< Dump IDCDelta to file |
185 | | - bool mDumpIDCs{false}; ///< dump IDCs to file |
186 | | - bool mOffsetCCDB{false}; ///< flag for setting and offset for CCDB timestamp |
187 | | - bool mDisableIDCDelta{false}; ///< disable the processing and storage of IDCDelta |
188 | | - dataformats::Pair<long, int> mTFInfo{}; ///< orbit reset time for CCDB time stamp writing |
189 | | - bool mEnableWritingPadStatusMap{false}; ///< do not store the pad status map in the CCDB |
| 186 | + const std::vector<uint32_t> mCRUs{}; ///< CRUs to process in this instance |
| 187 | + unsigned int mProcessedCRUs{}; ///< number of processed CRUs to keep track of when the writing to CCDB etc. will be done |
| 188 | + std::string mMetaFileDir{}; |
| 189 | + std::string mCalibFileDir{}; |
| 190 | + IDCFactorization mIDCFactorization; ///< object aggregating the IDCs and performing the factorization of the IDCs |
| 191 | + IDCAverageGroup<IDCAverageGroupTPC> mIDCGrouping; ///< object for averaging and grouping of the IDCs |
| 192 | + const IDCDeltaCompression mCompressionDeltaIDC{}; ///< compression type for IDC Delta |
| 193 | + const bool mUsePrecisetimeStamp{true}; ///< use precise time stamp when writing to CCDB |
| 194 | + const bool mSendOutFFT{false}; ///< flag if the output will be send for the FFT |
| 195 | + const bool mSendOutCCDB{false}; ///< sending the outputs for ccdb populator |
| 196 | + long mTFFirst{-1}; ///< first TF of current aggregation interval |
| 197 | + bool mUpdateGroupingPar{true}; ///< flag to set if grouping parameters should be updated or not |
| 198 | + const int mLaneId{0}; ///< the id of the current process within the parallel pipeline |
| 199 | + std::vector<Side> mSides{}; ///< processed TPC sides |
| 200 | + const int mNTFsBuffer{1}; ///< number of TFs for which the IDCs will be buffered |
| 201 | + std::unique_ptr<CalDet<PadFlags>> 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 |
| 202 | + int mNOrbitsIDC{12}; ///< Number of orbits over which the IDCs are integrated. |
| 203 | + bool mDumpIDC0{false}; ///< Dump IDC0 to file |
| 204 | + bool mDumpIDC1{false}; ///< Dump IDC1 to file |
| 205 | + bool mDumpIDCDelta{false}; ///< Dump IDCDelta to file |
| 206 | + bool mDumpIDCDeltaCalibData{false}; ///< dump the IDC Delta as a calibration file |
| 207 | + bool mDumpIDCs{false}; ///< dump IDCs to file |
| 208 | + bool mOffsetCCDB{false}; ///< flag for setting and offset for CCDB timestamp |
| 209 | + bool mDisableIDCDelta{false}; ///< disable the processing and storage of IDCDelta |
| 210 | + dataformats::Pair<long, int> mTFInfo{}; ///< orbit reset time for CCDB time stamp writing |
| 211 | + bool mEnableWritingPadStatusMap{false}; ///< do not store the pad status map in the CCDB |
| 212 | + o2::framework::DataTakingContext mDataTakingContext{}; |
| 213 | + bool mSetDataTakingCont{true}; |
190 | 214 | const std::vector<InputSpec> mFilter = {{"idcagg", ConcreteDataTypeMatcher{gDataOriginTPC, TPCDistributeIDCSpec::getDataDescriptionIDC(mLaneId)}, Lifetime::Sporadic}}; ///< filter for looping over input data |
191 | 215 |
|
192 | 216 | void sendOutput(DataAllocator& output, const long timeStampStart) |
@@ -286,7 +310,7 @@ class TPCFactorizeIDCSpec : public o2::framework::Task |
286 | 310 | totalTime += time.count(); |
287 | 311 | } |
288 | 312 |
|
289 | | - if (!mDisableIDCDelta) { |
| 313 | + if (!mDisableIDCDelta || mDumpIDCDeltaCalibData) { |
290 | 314 | start = timer::now(); |
291 | 315 | for (unsigned int iChunk = 0; iChunk < mIDCFactorization.getNChunks(side); ++iChunk) { |
292 | 316 | auto startGrouping = timer::now(); |
@@ -325,9 +349,43 @@ class TPCFactorizeIDCSpec : public o2::framework::Task |
325 | 349 | imageIDCDelta = o2::ccdb::CcdbApi::createObjectImage(&idcDelta, &ccdbInfoIDCDelta); |
326 | 350 | break; |
327 | 351 | } |
328 | | - LOGP(info, "Sending object {} / {} of size {} bytes, valid for {} : {} ", ccdbInfoIDCDelta.getPath(), ccdbInfoIDCDelta.getFileName(), imageIDCDelta->size(), ccdbInfoIDCDelta.getStartValidityTimestamp(), ccdbInfoIDCDelta.getEndValidityTimestamp()); |
329 | | - output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, getDataDescriptionCCDBIDCDelta(), iChunk}, *imageIDCDelta.get()); |
330 | | - output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, getDataDescriptionCCDBIDCDelta(), iChunk}, ccdbInfoIDCDelta); |
| 352 | + |
| 353 | + if (!mDisableIDCDelta) { |
| 354 | + LOGP(info, "Sending object {} / {} of size {} bytes, valid for {} : {} ", ccdbInfoIDCDelta.getPath(), ccdbInfoIDCDelta.getFileName(), imageIDCDelta->size(), ccdbInfoIDCDelta.getStartValidityTimestamp(), ccdbInfoIDCDelta.getEndValidityTimestamp()); |
| 355 | + output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, getDataDescriptionCCDBIDCDelta(), iChunk}, *imageIDCDelta.get()); |
| 356 | + output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, getDataDescriptionCCDBIDCDelta(), iChunk}, ccdbInfoIDCDelta); |
| 357 | + } |
| 358 | + |
| 359 | + if (mDumpIDCDeltaCalibData && mCalibFileDir != "/dev/null") { |
| 360 | + const std::string sideStr = sideA ? "A" : "C"; |
| 361 | + std::string calibFName = fmt::format("IDCDelta_side{}_cal_data_{}.root", sideStr, ccdbInfoIDCDelta.getStartValidityTimestamp()); |
| 362 | + try { |
| 363 | + std::ofstream calFile(fmt::format("{}{}", mCalibFileDir, calibFName), std::ios::out | std::ios::binary); |
| 364 | + calFile.write(imageIDCDelta->data(), imageIDCDelta->size()); |
| 365 | + calFile.close(); |
| 366 | + } catch (std::exception const& e) { |
| 367 | + LOG(error) << "Failed to store IDC calibration data file " << calibFName << ", reason: " << e.what(); |
| 368 | + } |
| 369 | + |
| 370 | + if (mMetaFileDir != "/dev/null") { |
| 371 | + o2::dataformats::FileMetaData calMetaData; |
| 372 | + calMetaData.fillFileData(calibFName); |
| 373 | + calMetaData.setDataTakingContext(mDataTakingContext); |
| 374 | + calMetaData.type = "calib"; |
| 375 | + calMetaData.priority = "low"; |
| 376 | + auto metaFileNameTmp = fmt::format("{}{}.tmp", mMetaFileDir, calibFName); |
| 377 | + auto metaFileName = fmt::format("{}{}.done", mMetaFileDir, calibFName); |
| 378 | + try { |
| 379 | + std::ofstream metaFileOut(metaFileNameTmp); |
| 380 | + metaFileOut << calMetaData; |
| 381 | + metaFileOut.close(); |
| 382 | + std::filesystem::rename(metaFileNameTmp, metaFileName); |
| 383 | + } catch (std::exception const& e) { |
| 384 | + LOG(error) << "Failed to store CTF meta data file " << metaFileName << ", reason: " << e.what(); |
| 385 | + } |
| 386 | + } |
| 387 | + } |
| 388 | + |
331 | 389 | auto stopCCDBIDCDelta = timer::now(); |
332 | 390 | time = stopCCDBIDCDelta - startCCDBIDCDelta; |
333 | 391 | LOGP(info, "Compression and CCDB object creation time: {}", time.count()); |
@@ -408,7 +466,10 @@ DataProcessorSpec getTPCFactorizeIDCSpec(const int lane, const std::vector<uint3 |
408 | 466 | {"dump-IDC1", VariantType::Bool, false, {"Dump IDC1 to file"}}, |
409 | 467 | {"disable-IDCDelta", VariantType::Bool, false, {"Disable processing of IDCDelta and storage in the CCDB"}}, |
410 | 468 | {"dump-IDCDelta", VariantType::Bool, false, {"Dump IDCDelta to file"}}, |
| 469 | + {"dump-IDCDelta-calib-data", VariantType::Bool, false, {"Dump IDCDelta as calibration data to file"}}, |
411 | 470 | {"add-offset-for-CCDB-timestamp", VariantType::Bool, false, {"Add an offset of 1 hour for the validity range of the CCDB objects"}}, |
| 471 | + {"output-dir", VariantType::String, "none", {"calibration files output directory, must exist"}}, |
| 472 | + {"meta-output-dir", VariantType::String, "/dev/null", {"calibration metadata output directory, must exist (if not /dev/null)"}}, |
412 | 473 | {"update-not-grouping-parameter", VariantType::Bool, false, {"Do NOT Update/Writing grouping parameters to CCDB."}}}}; // end DataProcessorSpec |
413 | 474 | spec.rank = lane; |
414 | 475 | return spec; |
|
0 commit comments