52 TPCFactorizeIDCSpec(
const std::vector<uint32_t>& crus,
const unsigned int timeframes,
const unsigned int timeframesDeltaIDC, std::array<unsigned char, Mapper::NREGIONS> groupPads,
53 std::array<unsigned char, Mapper::NREGIONS> groupRows, std::array<unsigned char, Mapper::NREGIONS> groupLastRowsThreshold,
54 std::array<unsigned char, Mapper::NREGIONS> groupLastPadsThreshold,
const unsigned int groupPadsSectorEdges,
const IDCDeltaCompression compression,
const bool usePrecisetimeStamp,
const bool sendOutputFFT,
const bool sendCCDB,
const int lane,
const std::vector<o2::tpc::Side>& sides,
const int nTFsBuffer)
55 : mCRUs{crus}, mIDCFactorization{timeframes, timeframesDeltaIDC, crus}, mIDCGrouping{groupPads, groupRows, groupLastRowsThreshold, groupLastPadsThreshold, groupPadsSectorEdges}, mCompressionDeltaIDC{compression}, mUsePrecisetimeStamp{usePrecisetimeStamp}, mSendOutFFT{sendOutputFFT}, mSendOutCCDB{sendCCDB}, mLaneId{lane}, mSides{sides}, mNTFsBuffer{nTFsBuffer} {};
59 mUpdateGroupingPar = mLaneId == 0 ? !(ic.options().get<
bool>(
"update-not-grouping-parameter")) :
false;
61 mEnableWritingPadStatusMap = ic.options().get<
bool>(
"enableWritingPadStatusMap");
62 mNOrbitsIDC = ic.options().get<
int>(
"orbits-IDCs");
63 mDumpIDC0 = ic.options().get<
bool>(
"dump-IDC0");
64 mDumpIDC1 = ic.options().get<
bool>(
"dump-IDC1");
65 mDumpIDCDelta = ic.options().get<
bool>(
"dump-IDCDelta");
66 mDumpIDCDeltaCalibData = ic.options().get<
bool>(
"dump-IDCDelta-calib-data");
67 mDumpIDCs = ic.options().get<
bool>(
"dump-IDCs");
68 mOffsetCCDB = ic.options().get<
bool>(
"add-offset-for-CCDB-timestamp");
69 mDisableIDCDelta = ic.options().get<
bool>(
"disable-IDCDelta");
70 mCalibFileDir = ic.options().get<std::string>(
"output-dir");
71 if (mCalibFileDir !=
"/dev/null") {
74 mMetaFileDir = ic.options().get<std::string>(
"meta-output-dir");
75 if (mMetaFileDir !=
"/dev/null") {
79 mStatusMapOffsSec = ic.options().get<
float>(
"pad-status-map-offset");
80 mStatusMapOffsNSlot = ic.options().get<
int>(
"pad-status-map-offset-nslots");
81 const std::string refGainMapFile = ic.options().get<std::string>(
"gainMapFile");
82 if (!refGainMapFile.empty()) {
83 LOGP(info,
"Loading GainMap from file {}", refGainMapFile);
84 mIDCFactorization.
setGainMap(refGainMapFile.data(),
"GainMap");
91 if (mUsePrecisetimeStamp && pc.inputs().isValid(
"orbitreset")) {
93 if (pc.inputs().countValidInputs() == 1) {
99 if ((mTFFirst == -1) && pc.inputs().isValid(
"firstTF")) {
100 mTFFirst = pc.inputs().get<
long>(
"firstTF");
103 if (mTFFirst == -1) {
105 LOGP(warning,
"firstTF not Found!!! Found valid inputs {}. Setting {} as first TF", pc.inputs().countValidInputs(), mTFFirst);
109 if (mSetDataTakingCont) {
111 mSetDataTakingCont =
false;
119 const long relTF = (mTFFirst == -1) ? 0 : (currTF - mTFFirst) / mNTFsBuffer;
122 if (mTimestampStart == 0) {
123 setTimeStampCCDB(relTF, pc);
129 if ((relTF >= mIDCFactorization.
getNTimeframes()) || (relTF < 0)) {
133 auto data = pc.inputs().get<std::vector<float>>(
ref);
138 auto const* tpcCRUHeader = o2::framework::DataRefUtils::getHeader<o2::header::DataHeader*>(
ref);
139 const unsigned int cru = tpcCRUHeader->subSpecification;
140 mIDCFactorization.
setIDCs(std::move(
data), cru, relTF);
143 if (mProcessedCRUs == mCRUs.size() * mIDCFactorization.
getNTimeframes()) {
144 LOGP(info,
"ProcessedTFs: {} currTF: {} relTF: {} OrbitResetTime: {} orbits per TF: {}", mProcessedCRUs / mCRUs.size(), currTF, relTF, mTFInfo.
first, mTFInfo.
second);
146 sendOutput(pc.outputs());
153 sendOutput(ec.outputs());
173 const std::vector<uint32_t> mCRUs{};
174 unsigned int mProcessedCRUs{};
175 std::string mMetaFileDir{};
176 std::string mCalibFileDir{};
180 const bool mUsePrecisetimeStamp{
true};
181 const bool mSendOutFFT{
false};
182 bool mSendOutCCDB{
false};
184 bool mUpdateGroupingPar{
true};
185 const int mLaneId{0};
186 std::vector<Side> mSides{};
187 const int mNTFsBuffer{1};
188 std::unique_ptr<CalDet<PadFlags>> mPadFlagsMap;
190 bool mDumpIDC0{
false};
191 bool mDumpIDC1{
false};
192 bool mDumpIDCDelta{
false};
193 bool mDumpIDCDeltaCalibData{
false};
194 bool mDumpIDCs{
false};
195 bool mOffsetCCDB{
false};
196 bool mDisableIDCDelta{
false};
198 bool mEnableWritingPadStatusMap{
false};
200 bool mSetDataTakingCont{
true};
201 long mTimestampStart{0};
203 float mStatusMapOffsSec = 0;
204 int mStatusMapOffsNSlot = 0;
209 using timer = std::chrono::high_resolution_clock;
212 LOGP(info,
"Setting time stamp range from {} to {} for writing to CCDB with an offset of {}", mTimestampStart, timeStampEnd, offsetCCDB);
216 for (
const auto side : mSides) {
217 const unsigned int iSide =
static_cast<unsigned int>(
side);
218 LOGP(info,
"Sending IDC1 for side {} of size {}", iSide, mIDCFactorization.
getIDCOneVec(
side).size());
223 LOGP(info,
"Sending mean of: {}", mean);
231 if (mSendOutCCDB && (timeStampEnd > mTimestampStart)) {
232 for (
int iSide = 0; iSide < mSides.size(); ++iSide) {
234 LOGP(info,
"Writing IDCs to CCDB for Side {}",
static_cast<int>(
side));
238 if (mUpdateGroupingPar) {
242 LOGP(info,
"Sending object {} / {} of size {} bytes, valid for {} : {} ", ccdbInfo.getPath(), ccdbInfo.getFileName(),
image->size(), ccdbInfo.getStartValidityTimestamp(), ccdbInfo.getEndValidityTimestamp());
245 mUpdateGroupingPar =
false;
248 auto start = timer::now();
251 LOGP(info,
"Sending object {} / {} of size {} bytes, valid for {} : {} ", ccdbInfoIDC0.getPath(), ccdbInfoIDC0.getFileName(), imageIDC0->size(), ccdbInfoIDC0.getStartValidityTimestamp(), ccdbInfoIDC0.getEndValidityTimestamp());
254 auto stop = timer::now();
256 float totalTime =
time.count();
257 LOGP(info,
"IDCZero CCDB time: {}",
time.count());
259 start = timer::now();
262 LOGP(info,
"Sending object {} / {} of size {} bytes, valid for {} : {} ", ccdbInfoIDC1.getPath(), ccdbInfoIDC1.getFileName(), imageIDC1->size(), ccdbInfoIDC1.getStartValidityTimestamp(), ccdbInfoIDC1.getEndValidityTimestamp());
267 LOGP(info,
"IDC1 CCDB time: {}",
time.count());
268 totalTime +=
time.count();
271 if (padStatusMap && iSide == 0) {
272 start = timer::now();
275 if (mEnableWritingPadStatusMap) {
276 long timeStampEndOffsPad = 0;
277 if (mStatusMapOffsSec > 0) {
278 timeStampEndOffsPad = mStatusMapOffsSec * 1000;
279 }
else if (mStatusMapOffsNSlot > 0) {
280 const long length = timeStampEnd - mTimestampStart;
281 timeStampEndOffsPad = mStatusMapOffsNSlot *
length;
284 mPadFlagsMap = std::move(padStatusMap);
285 LOGP(info,
"Writing pad status map to CCDB with an offset of {}.", timeStampEndOffsPad);
288 LOGP(info,
"Sending object {} / {} of size {} bytes, valid for {} : {} ", ccdbInfoPadFlags.getPath(), ccdbInfoPadFlags.getFileName(), imageFlagMap->size(), ccdbInfoPadFlags.getStartValidityTimestamp(), ccdbInfoPadFlags.getEndValidityTimestamp());
291 LOGP(info,
"Pad status map written to CCDB");
294 LOGP(info,
"Pad status map CCDB time: {}",
time.count());
295 totalTime +=
time.count();
299 LOGP(info,
"Pad status map CCDB time: {}",
time.count());
300 totalTime +=
time.count();
303 if (!mDisableIDCDelta || mDumpIDCDeltaCalibData) {
304 start = timer::now();
305 for (
unsigned int iChunk = 0; iChunk < mIDCFactorization.
getNChunks(
side); ++iChunk) {
306 auto startGrouping = timer::now();
307 mIDCGrouping.setIDCs(std::move(mIDCFactorization).getIDCDeltaUncompressed(iChunk,
side),
side);
309 auto stopGrouping = timer::now();
310 time = stopGrouping - startGrouping;
311 LOGP(info,
"Averaging and grouping time: {}",
time.count());
318 mIDCGrouping.
dumpToFile(fmt::format(
"{}DeltaAveraged_chunk{:02}_{:02}_side{}.root", getCurrentType(), iChunk, timeStampStartDelta, (
int)
side).data());
321 auto startCCDBIDCDelta = timer::now();
322 std::unique_ptr<std::vector<char>> imageIDCDelta;
323 switch (mCompressionDeltaIDC) {
326 using compType =
unsigned short;
332 using compType =
unsigned char;
343 if (!mDisableIDCDelta) {
344 LOGP(info,
"Sending object {} / {} of size {} bytes, valid for {} : {} ", ccdbInfoIDCDelta.getPath(), ccdbInfoIDCDelta.getFileName(), imageIDCDelta->size(), ccdbInfoIDCDelta.getStartValidityTimestamp(), ccdbInfoIDCDelta.getEndValidityTimestamp());
349 if (mDumpIDCDeltaCalibData && mCalibFileDir !=
"/dev/null") {
350 const std::string sideStr = sideA ?
"A" :
"C";
351 std::string calibFName = fmt::format(
"IDCDelta_side{}_cal_data_{}.root", sideStr, ccdbInfoIDCDelta.getStartValidityTimestamp());
353 std::ofstream calFile(fmt::format(
"{}{}", mCalibFileDir, calibFName), std::ios::out | std::ios::binary);
354 calFile.write(imageIDCDelta->data(), imageIDCDelta->size());
356 }
catch (std::exception
const& e) {
357 LOG(error) <<
"Failed to store IDC calibration data file " << calibFName <<
", reason: " << e.what();
360 if (mMetaFileDir !=
"/dev/null") {
364 calMetaData.
type =
"calib";
366 auto metaFileNameTmp = fmt::format(
"{}{}.tmp", mMetaFileDir, calibFName);
367 auto metaFileName = fmt::format(
"{}{}.done", mMetaFileDir, calibFName);
369 std::ofstream metaFileOut(metaFileNameTmp);
370 metaFileOut << calMetaData;
372 std::filesystem::rename(metaFileNameTmp, metaFileName);
373 }
catch (std::exception
const& e) {
374 LOG(error) <<
"Failed to store CTF meta data file " << metaFileName <<
", reason: " << e.what();
379 auto stopCCDBIDCDelta = timer::now();
380 time = stopCCDBIDCDelta - startCCDBIDCDelta;
381 LOGP(info,
"Compression and CCDB object creation time: {}",
time.count());
386 LOGP(info,
"IDCDelta CCDB time: {}",
time.count());
388 totalTime +=
time.count();
389 LOGP(info,
"CCDB object creation done. Total time: {}", totalTime);
394 LOGP(info,
"Everything done! Clearing memory...");
395 mIDCFactorization.
reset();
399 LOGP(info,
"Everything cleared. Waiting for new data to arrive.");
405 if (mUsePrecisetimeStamp && !mTFInfo.
second) {
409 const auto nOrbitsOffset = (relTF * mNTFsBuffer + (mNTFsBuffer - 1)) * mTFInfo.
second;
411 LOGP(info,
"setting time stamp reset reference to: {}, at tfCounter: {}, firstTForbit: {}, NHBFPerTF: {}, relTF: {}, nOrbitsOffset: {}", mTFInfo.
first, tinfo.tfCounter, tinfo.firstTForbit, mTFInfo.
second, relTF, nOrbitsOffset);
417 LOGP(info,
"dumping aggregated and factorized IDCs to file for mTFFirst {}", mTFFirst);
419 mIDCFactorization.
setRun(mRun);
420 mIDCFactorization.
dumpLargeObjectToFile(fmt::format(
"{}Factorized_TF_{:02}_TS_{}.root", getCurrentType(), mTFFirst, mTimestampStart).
data());
423 const bool calcDeltas = mDumpIDCDeltaCalibData || !mDisableIDCDelta;
427 LOGP(info,
"dumping IDC Zero to file");
428 for (
auto side : mIDCFactorization.getSides()) {
429 const std::string outFileName = (
side ==
Side::A) ? fmt::format(
"{}Zero_A_{:02}.root", getCurrentType(), mTFFirst) :
fmt::
format(
"{}Zero_C_{:02}.root", getCurrentType(), mTFFirst);
435 LOGP(info,
"dumping IDC1 to file");
436 for (
auto side : mIDCFactorization.getSides()) {
437 const std::string outFileName = (
side ==
Side::A) ? fmt::format(
"{}One_A_{:02}.root", getCurrentType(), mTFFirst) :
fmt::
format(
"{}One_C_{:02}.root", getCurrentType(), mTFFirst);
443 std::string getCurrentType()
const {
return "IDC"; }
446DataProcessorSpec getTPCFactorizeIDCSpec(
const int lane,
const std::vector<uint32_t>& crus,
const unsigned int timeframes,
const unsigned int timeframesDeltaIDC,
const IDCDeltaCompression compression,
const bool usePrecisetimeStamp,
const bool sendOutputFFT,
const bool sendCCDB,
const int nTFsBuffer = 1)
450 std::vector<OutputSpec> outputSpecs;
465 for (
auto side : sides) {
474 std::vector<InputSpec> inputSpecs;
477 if (usePrecisetimeStamp) {
482 std::array<unsigned char, Mapper::NREGIONS> groupPads{};
483 std::array<unsigned char, Mapper::NREGIONS> groupRows{};
484 std::array<unsigned char, Mapper::NREGIONS> groupLastRowsThreshold{};
485 std::array<unsigned char, Mapper::NREGIONS> groupLastPadsThreshold{};
486 std::copy(std::begin(paramIDCGroup.groupPads), std::end(paramIDCGroup.groupPads), std::begin(groupPads));
487 std::copy(std::begin(paramIDCGroup.groupRows), std::end(paramIDCGroup.groupRows), std::begin(groupRows));
488 std::copy(std::begin(paramIDCGroup.groupLastRowsThreshold), std::end(paramIDCGroup.groupLastRowsThreshold), std::begin(groupLastRowsThreshold));
489 std::copy(std::begin(paramIDCGroup.groupLastPadsThreshold), std::end(paramIDCGroup.groupLastPadsThreshold), std::begin(groupLastPadsThreshold));
490 const unsigned int groupPadsSectorEdges = paramIDCGroup.groupPadsSectorEdges;
492 const std::string
type =
"idc";
494 fmt::format(
"tpc-factorize-{}-{:02}",
type, lane).data(),
497 AlgorithmSpec{adaptFromTask<TPCFactorizeIDCSpec>(crus, timeframes, timeframesDeltaIDC, groupPads, groupRows, groupLastRowsThreshold, groupLastPadsThreshold, groupPadsSectorEdges, compression, usePrecisetimeStamp, sendOutputFFT, sendCCDB, lane, sides, nTFsBuffer)},
498 Options{{
"gainMapFile", VariantType::String,
"", {
"file to reference gain map, which will be used for correcting the cluster charge"}},
499 {
"enablePadStatusMap", VariantType::Bool,
false, {
"Enabling the usage of the pad-by-pad status map during factorization."}},
500 {
"enableWritingPadStatusMap", VariantType::Bool,
false, {
"Write the pad status map to CCDB."}},
501 {
"orbits-IDCs", VariantType::Int, 12, {
"Number of orbits over which the IDCs are integrated."}},
502 {
"dump-IDCs", VariantType::Bool,
false, {
"Dump IDCs to file"}},
503 {
"dump-IDC0", VariantType::Bool,
false, {
"Dump IDC0 to file"}},
504 {
"dump-IDC1", VariantType::Bool,
false, {
"Dump IDC1 to file"}},
505 {
"disable-IDCDelta", VariantType::Bool,
false, {
"Disable processing of IDCDelta and storage in the CCDB"}},
506 {
"dump-IDCDelta", VariantType::Bool,
false, {
"Dump IDCDelta to file"}},
507 {
"dump-IDCDelta-calib-data", VariantType::Bool,
false, {
"Dump IDCDelta as calibration data to file"}},
508 {
"add-offset-for-CCDB-timestamp", VariantType::Bool,
false, {
"Add an offset of 1 hour for the validity range of the CCDB objects"}},
509 {
"pad-status-map-offset", VariantType::Float, 0.f, {
"Offset in seconds for timestamp of pad status map CCDB object (overwrites pad-status-map-offset-nslots)"}},
510 {
"pad-status-map-offset-nslots", VariantType::Int, 0, {
"Offset in slot length units for timestamp of pad status map CCDB object"}},
511 {
"output-dir", VariantType::String,
"none", {
"calibration files output directory, must exist"}},
512 {
"meta-output-dir", VariantType::String,
"/dev/null", {
"calibration metadata output directory, must exist (if not /dev/null)"}},
513 {
"update-not-grouping-parameter", VariantType::Bool,
false, {
"Do NOT Update/Writing grouping parameters to CCDB."}}}};