Skip to content

Commit 0ed5808

Browse files
author
jryu
committed
chore: test git push permission for StuckPixels
1 parent 2e80e74 commit 0ed5808

1 file changed

Lines changed: 117 additions & 49 deletions

File tree

Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx

Lines changed: 117 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#include "DataFormatsITSMFT/Digit.h"
1818
#include "DataFormatsITSMFT/CompCluster.h"
1919
#include "DataFormatsITSMFT/TimeDeadMap.h"
20+
#include "ITSMFTReconstruction/DecodingStat.h"
21+
#include <TFile.h>
22+
#include <TTree.h>
2023

2124
namespace o2
2225
{
@@ -87,6 +90,20 @@ void ITSMFTDeadMapBuilder::init(InitContext& ic)
8790

8891
LOG(info) << "Sampling one TF every " << mTFSampling << " with " << mTFSamplingTolerance << " TF tolerance";
8992

93+
mStuckPixelFileName = ic.options().get<std::string>("save-stuck-pixels");
94+
95+
if (!mRunMFT && !mStuckPixelFileName.empty()) {
96+
LOG(info) << "Stuck pixel saving ENABLED. Output file: " << mStuckPixelFileName;
97+
mErrorTree = new TTree ("ErrorTree", "Stuck Pixel Errors");
98+
mErrorTree->SetDirectory(nullptr);
99+
mErrorTree->Branch("orbit", &mErrOrbit, "orbit/L");
100+
mErrorTree->Branch("chipid", &mErrChipID, "chipid/S");
101+
mErrorTree->Branch("row", &mErrRow, "row/S");
102+
mErrorTree->Branch("col", &mErrCol, "col/S");
103+
} else {
104+
LOG(info) << "Stuck pixel saving DISABLED.";
105+
}
106+
90107
return;
91108
}
92109

@@ -172,6 +189,21 @@ void ITSMFTDeadMapBuilder::finalizeOutput()
172189
outfile.WriteObjectAny(&mMapObject, "o2::itsmft::TimeDeadMap", "ccdb_object");
173190
outfile.Close();
174191
}
192+
193+
if (mErrorTree && !mStuckPixelFileName.empty()) {
194+
std::string stuckOutFileName = mLocalOutputDir + "/" + mStuckPixelFileName;
195+
TFile stuckOutFile(stuckOutFileName.c_str(), "RECREATE");
196+
197+
if (!stuckOutFile.IsZombie()) {
198+
stuckOutFile.cd();
199+
mErrorTree->Write();
200+
stuckOutFile.Close();
201+
LOG(info) << "Stuck Pixel Tree saved to separate file: " << stuckOutFileName;
202+
} else {
203+
LOG(error) << "Failed to open " << stuckOutFileName << " for stuck pixel tree.";
204+
}
205+
}
206+
175207
return;
176208
}
177209

@@ -213,6 +245,21 @@ void ITSMFTDeadMapBuilder::run(ProcessingContext& pc)
213245
}
214246

215247
mStepCounter++;
248+
249+
if (mErrorTree) {
250+
const auto repErrors = pc.inputs().get<gsl::span<o2::itsmft::ErrorMessage>>("repErr");
251+
for (const auto& err : repErrors) {
252+
if (err.errType == o2::itsmft::ChipStat::RepeatingPixel) {
253+
mErrOrbit = (long)mFirstOrbitTF;
254+
mErrChipID = (short)err.id;
255+
mErrRow = (short)err.errInfo0;
256+
mErrCol = (short)err.errInfo1;
257+
258+
mErrorTree->Fill();
259+
}
260+
}
261+
}
262+
216263
LOG(info) << "Processing step #" << mStepCounter << " out of " << mTFCounter << " good TF received. First orbit " << mFirstOrbitTF;
217264

218265
mDeadMapTF.clear();
@@ -304,84 +351,96 @@ void ITSMFTDeadMapBuilder::run(ProcessingContext& pc)
304351
}
305352

306353
//////////////////////////////////////////////////////////////////////////////
307-
void ITSMFTDeadMapBuilder::PrepareOutputCcdb(EndOfStreamContext* ec, std::string ccdburl = "")
354+
void ITSMFTDeadMapBuilder::PrepareOutputCcdb(EndOfStreamContext* ec, std::string ccdburl)
308355
{
309-
310-
// if ccdburl is specified, the object is sent to ccdb from this workflow
311-
312356
long tend = o2::ccdb::getCurrentTimestamp();
313-
314357
std::map<std::string, std::string> md = {{"map_version", MAP_VERSION}, {"runNumber", std::to_string(mRunNumber)}};
315-
316358
std::string path = mRunMFT ? "MFT/Calib/" : "ITS/Calib/";
317-
std::string name_str = "TimeDeadMap";
318359

319-
o2::ccdb::CcdbObjectInfo info((path + name_str), name_str, mObjectName, md, mTimeStart - 120 * 1000, tend + 60 * 1000);
320360

321-
auto image = o2::ccdb::CcdbApi::createObjectImage(&mMapObject, &info);
322-
info.setFileName(mObjectName);
361+
if (mMapObject.getEvolvingMapSize() > 0) {
362+
std::string name_str = "TimeDeadMap";
363+
o2::ccdb::CcdbObjectInfo info((path + name_str), name_str, mObjectName, md, mTimeStart - 120 * 1000, tend + 60 * 1000);
364+
auto image = o2::ccdb::CcdbApi::createObjectImage(&mMapObject, &info);
365+
info.setFileName(mObjectName);
366+
info.setAdjustableEOV();
323367

324-
info.setAdjustableEOV();
325-
326-
if (ec != nullptr) {
327-
328-
LOG(important) << "Sending object " << info.getPath() << "/" << info.getFileName()
329-
<< " to ccdb-populator, of size " << image->size() << " bytes, valid for "
330-
<< info.getStartValidityTimestamp() << " : " << info.getEndValidityTimestamp();
331-
332-
if (mRunMFT) {
333-
ec->outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "TimeDeadMap", 1}, *image.get());
334-
ec->outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "TimeDeadMap", 1}, info);
335-
} else {
336-
ec->outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "TimeDeadMap", 0}, *image.get());
337-
ec->outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "TimeDeadMap", 0}, info);
368+
if (ec != nullptr) {
369+
LOG(important) << "Sending object " << info.getPath() << "/" << info.getFileName()
370+
<< " to ccdb-populator, of size " << image->size() << " bytes";
371+
if (mRunMFT) {
372+
ec->outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "TimeDeadMap", 1}, *image.get());
373+
ec->outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "TimeDeadMap", 1}, info);
374+
} else {
375+
ec->outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "TimeDeadMap", 0}, *image.get());
376+
ec->outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "TimeDeadMap", 0}, info);
377+
}
378+
} else if (!ccdburl.empty()) {
379+
LOG(important) << mSelfName << " sending object " << ccdburl << "/browse/" << info.getPath() << "/" << info.getFileName();
380+
o2::ccdb::CcdbApi mApi;
381+
mApi.init(ccdburl);
382+
mApi.storeAsBinaryFile(
383+
&image->at(0), image->size(), info.getFileName(), info.getObjectType(),
384+
info.getPath(), info.getMetaData(),
385+
info.getStartValidityTimestamp(), info.getEndValidityTimestamp());
386+
o2::ccdb::adjustOverriddenEOV(mApi, info);
338387
}
388+
} else {
389+
LOG(warning) << "Time-dependent dead map is empty and will not be forwarded as output";
339390
}
340391

341-
else if (!ccdburl.empty()) { // send from this workflow
342392

343-
LOG(important) << mSelfName << " sending object " << ccdburl << "/browse/" << info.getPath() << "/" << info.getFileName()
344-
<< " of size " << image->size() << " bytes, valid for "
345-
<< info.getStartValidityTimestamp() << " : " << info.getEndValidityTimestamp();
393+
if (mErrorTree && !mStuckPixelFileName.empty()) {
394+
std::string name_sp = "StuckPixels";
395+
o2::ccdb::CcdbObjectInfo info_sp((path + name_sp), name_sp, mStuckPixelFileName, md, mTimeStart - 120 * 1000, tend + 60 * 1000);
396+
346397

347-
o2::ccdb::CcdbApi mApi;
348-
mApi.init(ccdburl);
349-
mApi.storeAsBinaryFile(
350-
&image->at(0), image->size(), info.getFileName(), info.getObjectType(),
351-
info.getPath(), info.getMetaData(),
352-
info.getStartValidityTimestamp(), info.getEndValidityTimestamp());
353-
o2::ccdb::adjustOverriddenEOV(mApi, info);
354-
}
398+
auto image_sp = o2::ccdb::CcdbApi::createObjectImage(mErrorTree, &info_sp);
399+
info_sp.setFileName(mStuckPixelFileName);
400+
info_sp.setAdjustableEOV();
355401

356-
else {
402+
if (ec != nullptr) {
403+
LOG(important) << "Sending StuckPixels object to ccdb-populator, Path: " << info_sp.getPath();
404+
if (mRunMFT) {
405+
ec->outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "StuckPixels", 1}, *image_sp.get());
406+
ec->outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "StuckPixels", 1}, info_sp);
407+
} else {
408+
ec->outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "StuckPixels", 0}, *image_sp.get());
409+
ec->outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "StuckPixels", 0}, info_sp);
410+
}
411+
} else if (!ccdburl.empty()) {
412+
LOG(important) << mSelfName << " sending StuckPixels to external CCDB: " << ccdburl << "/browse/" << info_sp.getPath();
413+
o2::ccdb::CcdbApi mApi_sp;
414+
mApi_sp.init(ccdburl);
415+
mApi_sp.storeAsBinaryFile(
416+
&image_sp->at(0), image_sp->size(), info_sp.getFileName(), info_sp.getObjectType(),
417+
info_sp.getPath(), info_sp.getMetaData(),
418+
info_sp.getStartValidityTimestamp(), info_sp.getEndValidityTimestamp());
419+
o2::ccdb::adjustOverriddenEOV(mApi_sp, info_sp);
420+
}
357421

358-
LOG(warning) << "PrepareOutputCcdb called with empty arguments. Doing nothing.";
422+
delete mErrorTree;
423+
mErrorTree = nullptr;
359424
}
360425

361426
return;
362427
}
363428

364429
//////////////////////////////////////////////////////////////////////////////
365-
// O2 functionality allowing to do post-processing when the upstream device
366-
// tells that there will be no more input data
367430
void ITSMFTDeadMapBuilder::endOfStream(EndOfStreamContext& ec)
368431
{
369432
if (!isEnded) {
370433
LOG(info) << "endOfStream report: " << mSelfName;
371434
finalizeOutput();
372-
if (mMapObject.getEvolvingMapSize() > 0) {
373-
PrepareOutputCcdb(&ec);
374-
} else {
375-
LOG(warning) << "Time-dependent dead map is empty and will not be forwarded as output";
376-
}
435+
// 데이터 유무 및 업로드 조건 처리를 내부에서 독립적으로 검증하도록 PrepareOutputCcdb를 무조건 호출구조로 변경
436+
PrepareOutputCcdb(&ec);
377437
LOG(info) << "Stop process of new data because of endOfStream";
378438
isEnded = true;
379439
}
380440
return;
381441
}
382442

383443
//////////////////////////////////////////////////////////////////////////////
384-
// DDS stop method: create local output if endOfStream not processed
385444
void ITSMFTDeadMapBuilder::stop()
386445
{
387446
if (!isEnded) {
@@ -421,12 +480,18 @@ DataProcessorSpec getITSMFTDeadMapBuilderSpec(std::string datasource, bool doMFT
421480
} else if (datasource == "chipsstatus") {
422481
inputs.emplace_back("elements", detOrig, "CHIPSSTATUS", 0, Lifetime::Timeframe);
423482
} else {
424-
return DataProcessorSpec{0x0}; // TODO: ADD PROTECTION
483+
return DataProcessorSpec{0x0};
425484
}
426485

486+
inputs.emplace_back("repErr", detOrig, "ErrorInfo", 0, Lifetime::Timeframe);
487+
427488
std::vector<OutputSpec> outputs;
489+
428490
outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "TimeDeadMap"}, Lifetime::Sporadic);
429491
outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "TimeDeadMap"}, Lifetime::Sporadic);
492+
// New CCDB for StuckPixels
493+
outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "StuckPixels"}, Lifetime::Sporadic);
494+
outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "StuckPixels"}, Lifetime::Sporadic);
430495

431496
std::string detector = doMFT ? "mft" : "its";
432497
std::string objectname_default = detector + "_time_deadmap.root";
@@ -445,8 +510,11 @@ DataProcessorSpec getITSMFTDeadMapBuilderSpec(std::string datasource, bool doMFT
445510
{"ccdb-url", VariantType::String, "", {"CCDB url. Ignored if endOfStream is processed."}},
446511
{"outfile", VariantType::String, objectname_default, {"ROOT object file name."}},
447512
{"local-output", VariantType::Bool, false, {"Save ROOT tree file locally."}},
448-
{"output-dir", VariantType::String, "./", {"ROOT tree local output directory."}}}};
513+
{"output-dir", VariantType::String, "./", {"ROOT tree local output directory."}},
514+
515+
{"save-stuck-pixels", VariantType::String, "", {"Save stuck pixels to a separate ROOT file. If empty, stuck pixel computation is disabled."}}
516+
}};
449517
}
450518

451519
} // namespace itsmft
452-
} // namespace o2
520+
} // namespace o2

0 commit comments

Comments
 (0)