From a9d73367ec22c758560763db244b9f7ff985aea0 Mon Sep 17 00:00:00 2001 From: Nicolo Valle Date: Wed, 13 Dec 2023 13:28:16 +0100 Subject: [PATCH 1/7] ITS and MFT dead damp builder workflow --- .../ITSMFT/common/workflow/CMakeLists.txt | 8 + .../ITSMFTWorkflow/DeadMapBuilderSpec.h | 134 ++++++++ .../workflow/src/DeadMapBuilderSpec.cxx | 308 ++++++++++++++++++ .../workflow/src/deadmap-builder-workflow.cxx | 45 +++ 4 files changed, 495 insertions(+) create mode 100644 Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h create mode 100644 Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx create mode 100644 Detectors/ITSMFT/common/workflow/src/deadmap-builder-workflow.cxx diff --git a/Detectors/ITSMFT/common/workflow/CMakeLists.txt b/Detectors/ITSMFT/common/workflow/CMakeLists.txt index 305fadaba2346..f14525e9d4092 100644 --- a/Detectors/ITSMFT/common/workflow/CMakeLists.txt +++ b/Detectors/ITSMFT/common/workflow/CMakeLists.txt @@ -16,12 +16,14 @@ o2_add_library(ITSMFTWorkflow src/STFDecoderSpec.cxx src/EntropyEncoderSpec.cxx src/EntropyDecoderSpec.cxx + src/DeadMapBuilderSpec.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DataFormatsITSMFT O2::SimulationDataFormat O2::ITSMFTReconstruction O2::ITSBase O2::MFTBase + O2::DetectorsCalibration O2::DetectorsCommonDataFormats O2::DataFormatsParameters) @@ -50,3 +52,9 @@ o2_add_executable(trigges-writer-workflow SOURCES src/trigger-writer-workflow.cxx COMPONENT_NAME itsmft PUBLIC_LINK_LIBRARIES O2::ITSMFTWorkflow) + +o2_add_executable(deadmap-builder-workflow + SOURCES src/deadmap-builder-workflow.cxx + COMPONENT_NAME itsmft + PUBLIC_LINK_LIBRARIES O2::ITSMFTWorkflow) + diff --git a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h new file mode 100644 index 0000000000000..91b9c2b63bc82 --- /dev/null +++ b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h @@ -0,0 +1,134 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file DeadMapBuilderSpec.h + +#ifndef O2_ITSMFT_DEADMAP_BUILDER_ +#define O2_ITSMFT_DEADMAP_BUILDER_ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// Boost library for easy access of host name +#include + +#include "Framework/CCDBParamSpec.h" +#include "Framework/DataProcessorSpec.h" +#include "Framework/Task.h" +#include "Framework/ControlService.h" +#include "Framework/ConfigParamRegistry.h" +#include "Framework/RawDeviceService.h" +#include "Framework/WorkflowSpec.h" +#include "Framework/Task.h" +#include "Framework/DataTakingContext.h" +#include "Framework/TimingInfo.h" +#include + +#include //o2::itsmft::RawPixelDecoder +#include "DetectorsCalibration/Utils.h" +#include "DetectorsCommonDataFormats/FileMetaData.h" +#include "DetectorsBase/GRPGeomHelper.h" //nicolo +#include "CCDB/CcdbApi.h" +#include "CommonUtils/MemFileHelper.h" + +// ROOT includes +#include "TTree.h" +#include "TH1F.h" +#include "TH2F.h" +#include "TF1.h" +#include "TFile.h" + +using namespace o2::framework; +using namespace o2::itsmft; + +namespace o2 +{ +namespace itsmft +{ + +struct ITSDMInpConf { + int chipModSel = 0; + int chipModBase = 1; +}; + +class ITSMFTDeadMapBuilder : public Task +{ + public: + ITSMFTDeadMapBuilder(std::string datasource, bool doMFT); + ~ITSMFTDeadMapBuilder() override; + + void init(InitContext& ic) final; + void run(ProcessingContext& pc) final; + void endOfStream(EndOfStreamContext& ec) final; + + void stop() final; + + ////////////////////////////////////////////////////////////////// + private: + std::string mSelfName; + + bool mRunMFT = false; + bool mDoLocalOutput = false; + uint16_t N_CHIPS; + uint16_t N_CHIPS_ITSIB = o2::itsmft::ChipMappingITS::getNChips(0); + int mTFLength = 32; // TODO find utility for proper value -- o2::base::GRPGeomHelper::getNHBFPerTF() returns 128 see https://github.com/AliceO2Group/AliceO2/blob/051b56f9f136e7977e83f5d26d922db9bd6ecef5/Detectors/Base/src/GRPGeomHelper.cxx#L233 and correct also default option is getSpec + std::set mDeadElements; + uint mStepCounter = 0; + uint mTFCounter = 0; + + std::string mObjectName; + std::string mLocalOutputDir; + + std::string MAP_VERSION = "1"; // to change in case the encoding or the format change + + std::vector* mDeadMapTF = nullptr; + + Long64_t mFirstOrbitTF = 0x0; + + std::string mDataSource = "chipsstatus"; + + int mTFSampling = 1000; + + TTree* mTreeObject = nullptr; + + void finalizeOutput(); + void PrepareOutputCcdb(DataAllocator& output); + + // Utils + + uint16_t getElementIDFromChip(uint16_t); + + o2::framework::DataTakingContext mDataTakingContext{}; + o2::framework::TimingInfo mTimingInfo{}; + + // Flag to avoid that endOfStream and stop are both done + bool isEnded = false; + + // Run stop requested flag for EoS operations + bool mRunStopRequested = false; +}; + +// Create a processor spec +o2::framework::DataProcessorSpec getITSMFTDeadMapBuilderSpec(std::string datasource, bool doMFT); + +} // namespace itsmft +} // namespace o2 + +#endif diff --git a/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx new file mode 100644 index 0000000000000..bbfa8fe2324f9 --- /dev/null +++ b/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx @@ -0,0 +1,308 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file DeadMapBuilderSpec.cxx + +#include "ITSMFTWorkflow/DeadMapBuilderSpec.h" +#include "CommonUtils/FileSystemUtils.h" +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsITSMFT/Digit.h" +#include "DataFormatsITSMFT/CompCluster.h" + +namespace o2 +{ +namespace itsmft +{ + +////////////////////////////////////////////////////////////////////////////// +// Default constructor +ITSMFTDeadMapBuilder::ITSMFTDeadMapBuilder(std::string datasource, bool doMFT) + : mDataSource(datasource), mRunMFT(doMFT) +{ + std::string detector = doMFT ? "MFT" : "ITS"; + mSelfName = o2::utils::Str::concat_string("ITSMFTDeadMapBuilder_", detector); +} + +////////////////////////////////////////////////////////////////////////////// +// Default deconstructor +ITSMFTDeadMapBuilder::~ITSMFTDeadMapBuilder() +{ + // Clear dynamic memory + delete mDeadMapTF; + delete mTreeObject; +} + +////////////////////////////////////////////////////////////////////////////// +void ITSMFTDeadMapBuilder::init(InitContext& ic) +{ + + LOG(info) << "ITSMFTDeadMapBuilder init... " << mSelfName; + + if (mRunMFT) { + N_CHIPS = o2::itsmft::ChipMappingMFT::getNChips(); + } else { + N_CHIPS = o2::itsmft::ChipMappingITS::getNChips(); + } + + mDeadMapTF = new std::vector{}; + + mTreeObject = new TTree("ccdb_object", "ccdb_object"); + mTreeObject->Branch("orbit", &mFirstOrbitTF); + mTreeObject->Branch("deadmap", &mDeadMapTF); + + mTFSampling = ic.options().get("tf-sampling"); + mTFLength = ic.options().get("tf-length"); + mDoLocalOutput = ic.options().get("local-output"); + mObjectName = ic.options().get("output-filename"); + mLocalOutputDir = ic.options().get("output-dir"); + + LOG(info) << "Sampling one TF every " << mTFSampling; + + return; +} + +////////////////////////////////////////////////////////////////////////////// +uint16_t ITSMFTDeadMapBuilder::getElementIDFromChip(uint16_t chip) +{ + // MFT - no grouping + if (mRunMFT) { + return (uint16_t)chip; + } + // ITS - group chips into lanes + // TODO: does o2::itsmft::ChipMappingITS already contain this? + else { + if (chip < N_CHIPS_ITSIB) { + return (uint16_t)chip; + } else { + return N_CHIPS_ITSIB + (uint16_t)((chip - N_CHIPS_ITSIB) / 7); + } + } +} + +////////////////////////////////////////////////////////////////////////////// + +void ITSMFTDeadMapBuilder::finalizeOutput() +{ + + if (mDoLocalOutput) { + std::string localoutfilename = mLocalOutputDir + "/" + mObjectName; + TFile outfile(localoutfilename.c_str(), "RECREATE"); + outfile.cd(); + mTreeObject->Write(); + outfile.Close(); + } + return; + +} // finalizeOutput + +////////////////////////////////////////////////////////////////////////////// +// Main running function +void ITSMFTDeadMapBuilder::run(ProcessingContext& pc) +{ + if (mRunStopRequested) { // give up when run stop request arrived + return; + } + + std::chrono::time_point start; + std::chrono::time_point end; + + start = std::chrono::high_resolution_clock::now(); + + mTFCounter++; + + mFirstOrbitTF = pc.services().get().firstTForbit; + + if ((Long64_t)(mFirstOrbitTF / mTFLength) % mTFSampling != 0) { + return; + } + + mStepCounter++; + LOG(info) << "Processing step #" << mStepCounter << " out of " << mTFCounter << " TF received. First orbit " << mFirstOrbitTF; + + mDeadElements.clear(); + mDeadMapTF->clear(); + + if (mDataSource == "digits") { + std::generate_n(std::inserter(mDeadElements, mDeadElements.begin()), getElementIDFromChip(N_CHIPS), [n = 0]() mutable { return n++; }); + const auto elements = pc.inputs().get>("elements"); + const auto ROFs = pc.inputs().get>("ROFs"); + for (const auto& rof : ROFs) { + auto elementsInTF = rof.getROFData(elements); + for (const auto& el : elementsInTF) { + uint16_t chipID = (uint16_t)el.getChipIndex(); + mDeadElements.erase(getElementIDFromChip(chipID)); + } + } + } else if (mDataSource == "clusters") { + std::generate_n(std::inserter(mDeadElements, mDeadElements.begin()), getElementIDFromChip(N_CHIPS), [n = 0]() mutable { return n++; }); + const auto elements = pc.inputs().get>("elements"); + const auto ROFs = pc.inputs().get>("ROFs"); + for (const auto& rof : ROFs) { + auto elementsInTF = rof.getROFData(elements); + for (const auto& el : elementsInTF) { + uint16_t chipID = (uint16_t)el.getSensorID(); + mDeadElements.erase(getElementIDFromChip(chipID)); + } + } + } else if (mDataSource == "chipsstatus") { + const auto elements = pc.inputs().get>("elements"); + for (uint16_t chipID = 0; chipID < elements.size(); chipID++) { + if (!elements.at(chipID)) { + mDeadElements.insert(getElementIDFromChip(chipID)); + } + } + } + + std::set::iterator itr; + + for (itr = mDeadElements.begin(); itr != mDeadElements.end(); itr++) { + uint16_t el = *itr; + bool previous_exists = (itr != mDeadElements.begin()) && (*std::prev(itr) == (el - 1)); + bool next_exists = (itr != mDeadElements.end()) && (*std::next(itr) == (el + 1)); + + if (!previous_exists && next_exists) { + mDeadMapTF->push_back(el | (uint16_t)(0x8000)); + } else if (previous_exists && next_exists) { + continue; + } else { + mDeadMapTF->push_back(el); + } + } + + LOG(info) << "TF contains " << mDeadElements.size() << " dead elements, saved into " << mDeadMapTF->size() << " words."; + + // filling the tree + mTreeObject->Fill(); + + end = std::chrono::high_resolution_clock::now(); + int difference = std::chrono::duration_cast(end - start).count(); + + LOG(info) << "Elapsed time in TF processing: " << difference / 1000. << " ms"; + + return; +} + +////////////////////////////////////////////////////////////////////////////// +void ITSMFTDeadMapBuilder::PrepareOutputCcdb(DataAllocator& output) +{ + + long tstart = o2::ccdb::getCurrentTimestamp(); + long secinyear = 365L * 24 * 3600; + long tend = o2::ccdb::getFutureTimestamp(secinyear); + + std::map md = { + {"map_version", MAP_VERSION}}; + + std::string path = mRunMFT ? "MFT/Calib" : "ITS/Calib/"; + std::string name_str = "time_dead_map"; + + o2::ccdb::CcdbObjectInfo info((path + name_str), "time_dead_map", mObjectName, md, tstart, tend); + + auto image = o2::ccdb::CcdbApi::createObjectImage(mTreeObject, &info); + + info.setAdjustableEOV(); + + LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName() + << " of size " << image->size() << "bytes, valid for " + << info.getStartValidityTimestamp() << " : " << info.getEndValidityTimestamp(); + + if (mRunMFT) { + output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "MFT_TimeDeadMap", 0}, *image.get()); + output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "MFT_TimeDeadMap", 0}, info); + } else { + output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "ITS_TimeDeadMap", 0}, *image.get()); + output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "ITS_TimeDeadMap", 0}, info); + } + + return; +} + +////////////////////////////////////////////////////////////////////////////// +// O2 functionality allowing to do post-processing when the upstream device +// tells that there will be no more input data +void ITSMFTDeadMapBuilder::endOfStream(EndOfStreamContext& ec) +{ + if (!isEnded && !mRunStopRequested) { + LOG(info) << "endOfStream report:" << mSelfName; + finalizeOutput(); + PrepareOutputCcdb(ec.outputs()); + isEnded = true; + } + return; +} + +////////////////////////////////////////////////////////////////////////////// +// DDS stop method: simply close the latest tree +void ITSMFTDeadMapBuilder::stop() +{ + if (!isEnded) { + LOG(info) << "stop() report:" << mSelfName; + finalizeOutput(); + if (mDoLocalOutput) { + LOG(info) << "stop() not sending object as output. ccdb will not be populated."; + } else { + LOG(error) << "stop() not sending object as output. ccdb will not be populated."; + } + isEnded = true; + } + return; +} + +////////////////////////////////////////////////////////////////////////////// +DataProcessorSpec getITSMFTDeadMapBuilderSpec(std::string datasource, bool doMFT) +{ + o2::header::DataOrigin detOrig; + if (doMFT) { + detOrig = o2::header::gDataOriginMFT; + } else { + detOrig = o2::header::gDataOriginITS; + } + + std::vector inputs; + + if (datasource == "digits") { + inputs.emplace_back("elements", detOrig, "DIGITS", 0, Lifetime::Timeframe); + inputs.emplace_back("ROFs", detOrig, "DIGITSROF", 0, Lifetime::Timeframe); + } else if (datasource == "clusters") { + inputs.emplace_back("elements", detOrig, "COMPCLUSTERS", 0, Lifetime::Timeframe); + inputs.emplace_back("ROFs", detOrig, "CLUSTERSROF", 0, Lifetime::Timeframe); + } else if (datasource == "chipsstatus") { + inputs.emplace_back("elements", detOrig, "CHIPSSTATUS", 0, Lifetime::Timeframe); + } else { + return DataProcessorSpec{0x0}; // TODO: ADD PROTECTION + } + + std::vector outputs; + if (doMFT) { + outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "MFT_TimeDeadMap"}); + outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "MFT_TimeDeadMap"}); + } else { + outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "ITS_TimeDeadMap"}); + outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "ITS_TimeDeadMap"}); + } + + std::string detector = doMFT ? "mft" : "its"; + std::string objectname_default = detector + "_time_deadmap.root"; + + return DataProcessorSpec{ + "itsmft-deadmap-builder_" + detector, + inputs, + outputs, + AlgorithmSpec{adaptFromTask(datasource, doMFT)}, + Options{{"tf-sampling", VariantType::Int, 1000, {"Process every Nth TF. Selection according to first TF orbit."}}, + {"tf-length", VariantType::Int, 32, {"Orbits per TF."}}, + {"output-filename", VariantType::String, objectname_default, {"ROOT object file name."}}, + {"local-output", VariantType::Bool, false, {"Save ROOT tree file locally."}}, + {"output-dir", VariantType::String, "./", {"ROOT tree local output directory."}}}}; +} + +} // namespace itsmft +} // namespace o2 diff --git a/Detectors/ITSMFT/common/workflow/src/deadmap-builder-workflow.cxx b/Detectors/ITSMFT/common/workflow/src/deadmap-builder-workflow.cxx new file mode 100644 index 0000000000000..d76bc6167b173 --- /dev/null +++ b/Detectors/ITSMFT/common/workflow/src/deadmap-builder-workflow.cxx @@ -0,0 +1,45 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "ITSMFTWorkflow/DeadMapBuilderSpec.h" +#include "CommonUtils/ConfigurableParam.h" +#include "Framework/ConfigParamSpec.h" + +using namespace o2::framework; + +void customize(std::vector& workflowOptions) +{ + // option allowing to set parameters + std::vector options{ + ConfigParamSpec{"runmft", VariantType::Bool, false, {"Expect MFT data"}}, + ConfigParamSpec{"source", VariantType::String, "chipsstatus", {"Loop over: digits, clusters or chipsstatus"}}}; + + std::swap(workflowOptions, options); +} + +#include "Framework/runDataProcessing.h" +#include "Framework/Logger.h" + +WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) +{ + LOG(info) << "Initializing O2 ITSMFT Dead Map Builder"; + + WorkflowSpec wf; + + bool doMFT = configcontext.options().get("runmft"); + std::string datasource = configcontext.options().get("source"); + std::string detector = doMFT ? "MFT" : "ITS"; + + LOG(info) << "Building " << detector << " deadmaps from collection of: " << datasource; + wf.emplace_back(o2::itsmft::getITSMFTDeadMapBuilderSpec(datasource, doMFT)); + + return wf; +} From 970bb812ff4eeefd92d3fd1bd14ffb9310d0cc2a Mon Sep 17 00:00:00 2001 From: Nicolo Valle Date: Wed, 13 Dec 2023 13:34:28 +0100 Subject: [PATCH 2/7] removing trailing spaces --- Detectors/ITSMFT/common/workflow/CMakeLists.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Detectors/ITSMFT/common/workflow/CMakeLists.txt b/Detectors/ITSMFT/common/workflow/CMakeLists.txt index f14525e9d4092..63cd8d6c0bcee 100644 --- a/Detectors/ITSMFT/common/workflow/CMakeLists.txt +++ b/Detectors/ITSMFT/common/workflow/CMakeLists.txt @@ -52,9 +52,8 @@ o2_add_executable(trigges-writer-workflow SOURCES src/trigger-writer-workflow.cxx COMPONENT_NAME itsmft PUBLIC_LINK_LIBRARIES O2::ITSMFTWorkflow) - + o2_add_executable(deadmap-builder-workflow SOURCES src/deadmap-builder-workflow.cxx COMPONENT_NAME itsmft - PUBLIC_LINK_LIBRARIES O2::ITSMFTWorkflow) - + PUBLIC_LINK_LIBRARIES O2::ITSMFTWorkflow) From 62fd9bfd6c257ffa0f9ad9b2ec0a2e1f3d4f0e70 Mon Sep 17 00:00:00 2001 From: Nicolo Valle Date: Wed, 13 Dec 2023 13:42:01 +0100 Subject: [PATCH 3/7] removing unused struct --- .../workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h index 91b9c2b63bc82..008773b93d3b2 100644 --- a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h +++ b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h @@ -63,10 +63,6 @@ namespace o2 namespace itsmft { -struct ITSDMInpConf { - int chipModSel = 0; - int chipModBase = 1; -}; class ITSMFTDeadMapBuilder : public Task { From 868dcb9997d4bdcb6d1119ea25d445b483e2fbe6 Mon Sep 17 00:00:00 2001 From: Nicolo Valle Date: Wed, 13 Dec 2023 13:47:00 +0100 Subject: [PATCH 4/7] fixing format --- .../common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h index 008773b93d3b2..b0915f7f4e6bf 100644 --- a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h +++ b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h @@ -63,7 +63,6 @@ namespace o2 namespace itsmft { - class ITSMFTDeadMapBuilder : public Task { public: From 66e5afd6079fc80cf2177c04733a0b22f6348b55 Mon Sep 17 00:00:00 2001 From: Nicolo Valle Date: Wed, 13 Dec 2023 23:38:58 +0100 Subject: [PATCH 5/7] optimization --- .../ITSMFTWorkflow/DeadMapBuilderSpec.h | 2 +- .../workflow/src/DeadMapBuilderSpec.cxx | 35 ++++++++++--------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h index b0915f7f4e6bf..ea0fa75ccafa4 100644 --- a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h +++ b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h @@ -84,7 +84,7 @@ class ITSMFTDeadMapBuilder : public Task uint16_t N_CHIPS; uint16_t N_CHIPS_ITSIB = o2::itsmft::ChipMappingITS::getNChips(0); int mTFLength = 32; // TODO find utility for proper value -- o2::base::GRPGeomHelper::getNHBFPerTF() returns 128 see https://github.com/AliceO2Group/AliceO2/blob/051b56f9f136e7977e83f5d26d922db9bd6ecef5/Detectors/Base/src/GRPGeomHelper.cxx#L233 and correct also default option is getSpec - std::set mDeadElements; + uint mStepCounter = 0; uint mTFCounter = 0; diff --git a/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx index bbfa8fe2324f9..886722cb7f2e6 100644 --- a/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx +++ b/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx @@ -127,57 +127,58 @@ void ITSMFTDeadMapBuilder::run(ProcessingContext& pc) mStepCounter++; LOG(info) << "Processing step #" << mStepCounter << " out of " << mTFCounter << " TF received. First orbit " << mFirstOrbitTF; - mDeadElements.clear(); mDeadMapTF->clear(); + std::vector ElementsStatus(getElementIDFromChip(N_CHIPS), false); + if (mDataSource == "digits") { - std::generate_n(std::inserter(mDeadElements, mDeadElements.begin()), getElementIDFromChip(N_CHIPS), [n = 0]() mutable { return n++; }); const auto elements = pc.inputs().get>("elements"); const auto ROFs = pc.inputs().get>("ROFs"); for (const auto& rof : ROFs) { auto elementsInTF = rof.getROFData(elements); for (const auto& el : elementsInTF) { uint16_t chipID = (uint16_t)el.getChipIndex(); - mDeadElements.erase(getElementIDFromChip(chipID)); + ElementsStatus.at(getElementIDFromChip(chipID)) = true; } } } else if (mDataSource == "clusters") { - std::generate_n(std::inserter(mDeadElements, mDeadElements.begin()), getElementIDFromChip(N_CHIPS), [n = 0]() mutable { return n++; }); const auto elements = pc.inputs().get>("elements"); const auto ROFs = pc.inputs().get>("ROFs"); for (const auto& rof : ROFs) { auto elementsInTF = rof.getROFData(elements); for (const auto& el : elementsInTF) { uint16_t chipID = (uint16_t)el.getSensorID(); - mDeadElements.erase(getElementIDFromChip(chipID)); + ElementsStatus.at(getElementIDFromChip(chipID)) = true; } } } else if (mDataSource == "chipsstatus") { - const auto elements = pc.inputs().get>("elements"); + const auto elements = pc.inputs().get>("elements"); for (uint16_t chipID = 0; chipID < elements.size(); chipID++) { - if (!elements.at(chipID)) { - mDeadElements.insert(getElementIDFromChip(chipID)); + if (elements[chipID]) { + ElementsStatus.at(getElementIDFromChip(chipID)) = true; } } } - std::set::iterator itr; - - for (itr = mDeadElements.begin(); itr != mDeadElements.end(); itr++) { - uint16_t el = *itr; - bool previous_exists = (itr != mDeadElements.begin()) && (*std::prev(itr) == (el - 1)); - bool next_exists = (itr != mDeadElements.end()) && (*std::next(itr) == (el + 1)); + int CountDead = 0; - if (!previous_exists && next_exists) { + for (uint16_t el = 0; el < ElementsStatus.size(); el++) { + if (ElementsStatus.at(el)) { + continue; + } + CountDead++; + bool previous_dead = (el > 0 && !ElementsStatus.at(el - 1)); + bool next_dead = (el < ElementsStatus.size() - 1 && !ElementsStatus.at(el + 1)); + if (!previous_dead && next_dead) { mDeadMapTF->push_back(el | (uint16_t)(0x8000)); - } else if (previous_exists && next_exists) { + } else if (previous_dead && next_dead) { continue; } else { mDeadMapTF->push_back(el); } } - LOG(info) << "TF contains " << mDeadElements.size() << " dead elements, saved into " << mDeadMapTF->size() << " words."; + LOG(info) << "TF contains " << CountDead << " dead elements, saved into " << mDeadMapTF->size() << " words."; // filling the tree mTreeObject->Fill(); From 20eee4db32090df8aff365cb7286d1f4bd2f8feb Mon Sep 17 00:00:00 2001 From: Nicolo Valle Date: Fri, 15 Dec 2023 11:46:00 +0100 Subject: [PATCH 6/7] ITSMFT dead maps using map objects --- .../common/src/ITSMFTDataFormatsLinkDef.h | 2 ++ .../src/ITSMFTReconstructionLinkDef.h | 2 ++ .../ITSMFTWorkflow/DeadMapBuilderSpec.h | 10 +++--- .../workflow/src/DeadMapBuilderSpec.cxx | 34 ++++++++----------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/DataFormats/Detectors/ITSMFT/common/src/ITSMFTDataFormatsLinkDef.h b/DataFormats/Detectors/ITSMFT/common/src/ITSMFTDataFormatsLinkDef.h index 5edd964ce2cd0..80fc3a1b3f70a 100644 --- a/DataFormats/Detectors/ITSMFT/common/src/ITSMFTDataFormatsLinkDef.h +++ b/DataFormats/Detectors/ITSMFT/common/src/ITSMFTDataFormatsLinkDef.h @@ -49,6 +49,8 @@ #pragma link C++ class o2::itsmft::CTF + ; #pragma link C++ class o2::ctf::EncodedBlocks < o2::itsmft::CTFHeader, 10, uint32_t> + ; +#pragma link C++ class std::map < unsigned long, std::vector < uint16_t>> + ; + #pragma link C++ function o2::itsmft::getROFData(const gsl::span tfdata) const; #pragma link C++ function o2::itsmft::getROFData(const gsl::span tfdata) const; #pragma link C++ function o2::itsmft::getROFData(const gsl::span tfdata) const; diff --git a/Detectors/ITSMFT/common/reconstruction/src/ITSMFTReconstructionLinkDef.h b/Detectors/ITSMFT/common/reconstruction/src/ITSMFTReconstructionLinkDef.h index a3b9b2bd3b025..e6785e4402f37 100644 --- a/Detectors/ITSMFT/common/reconstruction/src/ITSMFTReconstructionLinkDef.h +++ b/Detectors/ITSMFT/common/reconstruction/src/ITSMFTReconstructionLinkDef.h @@ -48,6 +48,8 @@ #pragma link C++ class o2::itsmft::ChipStat + ; #pragma link C++ class std::map < unsigned long, std::pair < o2::itsmft::ClusterTopology, unsigned long>> + ; +#pragma link C++ class std::map < unsigned long, std::vector < uint16_t>> + ; + #pragma link C++ class o2::itsmft::ClustererParam < o2::detectors::DetID::ITS> + ; #pragma link C++ class o2::itsmft::ClustererParam < o2::detectors::DetID::MFT> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::itsmft::ClustererParam < o2::detectors::DetID::ITS>> + ; diff --git a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h index ea0fa75ccafa4..35e3a5bc422c9 100644 --- a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h +++ b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h @@ -44,7 +44,7 @@ #include //o2::itsmft::RawPixelDecoder #include "DetectorsCalibration/Utils.h" #include "DetectorsCommonDataFormats/FileMetaData.h" -#include "DetectorsBase/GRPGeomHelper.h" //nicolo +#include "DetectorsBase/GRPGeomHelper.h" #include "CCDB/CcdbApi.h" #include "CommonUtils/MemFileHelper.h" @@ -91,17 +91,17 @@ class ITSMFTDeadMapBuilder : public Task std::string mObjectName; std::string mLocalOutputDir; - std::string MAP_VERSION = "1"; // to change in case the encoding or the format change + std::string MAP_VERSION = "2"; // to change in case the encoding or the format change - std::vector* mDeadMapTF = nullptr; + std::vector mDeadMapTF{}; - Long64_t mFirstOrbitTF = 0x0; + unsigned long mFirstOrbitTF = 0x0; std::string mDataSource = "chipsstatus"; int mTFSampling = 1000; - TTree* mTreeObject = nullptr; + std::map> mMapObject{}; void finalizeOutput(); void PrepareOutputCcdb(DataAllocator& output); diff --git a/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx index 886722cb7f2e6..2702179a1140e 100644 --- a/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx +++ b/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx @@ -36,8 +36,7 @@ ITSMFTDeadMapBuilder::ITSMFTDeadMapBuilder(std::string datasource, bool doMFT) ITSMFTDeadMapBuilder::~ITSMFTDeadMapBuilder() { // Clear dynamic memory - delete mDeadMapTF; - delete mTreeObject; + return; } ////////////////////////////////////////////////////////////////////////////// @@ -52,11 +51,9 @@ void ITSMFTDeadMapBuilder::init(InitContext& ic) N_CHIPS = o2::itsmft::ChipMappingITS::getNChips(); } - mDeadMapTF = new std::vector{}; + mDeadMapTF.clear(); - mTreeObject = new TTree("ccdb_object", "ccdb_object"); - mTreeObject->Branch("orbit", &mFirstOrbitTF); - mTreeObject->Branch("deadmap", &mDeadMapTF); + mMapObject.clear(); mTFSampling = ic.options().get("tf-sampling"); mTFLength = ic.options().get("tf-length"); @@ -95,13 +92,11 @@ void ITSMFTDeadMapBuilder::finalizeOutput() if (mDoLocalOutput) { std::string localoutfilename = mLocalOutputDir + "/" + mObjectName; TFile outfile(localoutfilename.c_str(), "RECREATE"); - outfile.cd(); - mTreeObject->Write(); + outfile.WriteObjectAny(&mMapObject, "std::map>", "ccdb_object"); outfile.Close(); } return; - -} // finalizeOutput +} ////////////////////////////////////////////////////////////////////////////// // Main running function @@ -120,14 +115,14 @@ void ITSMFTDeadMapBuilder::run(ProcessingContext& pc) mFirstOrbitTF = pc.services().get().firstTForbit; - if ((Long64_t)(mFirstOrbitTF / mTFLength) % mTFSampling != 0) { + if ((unsigned long)(mFirstOrbitTF / mTFLength) % mTFSampling != 0) { return; } mStepCounter++; LOG(info) << "Processing step #" << mStepCounter << " out of " << mTFCounter << " TF received. First orbit " << mFirstOrbitTF; - mDeadMapTF->clear(); + mDeadMapTF.clear(); std::vector ElementsStatus(getElementIDFromChip(N_CHIPS), false); @@ -170,18 +165,18 @@ void ITSMFTDeadMapBuilder::run(ProcessingContext& pc) bool previous_dead = (el > 0 && !ElementsStatus.at(el - 1)); bool next_dead = (el < ElementsStatus.size() - 1 && !ElementsStatus.at(el + 1)); if (!previous_dead && next_dead) { - mDeadMapTF->push_back(el | (uint16_t)(0x8000)); + mDeadMapTF.push_back(el | (uint16_t)(0x8000)); } else if (previous_dead && next_dead) { continue; } else { - mDeadMapTF->push_back(el); + mDeadMapTF.push_back(el); } } - LOG(info) << "TF contains " << CountDead << " dead elements, saved into " << mDeadMapTF->size() << " words."; + LOG(info) << "TF contains " << CountDead << " dead elements, saved into " << mDeadMapTF.size() << " words."; - // filling the tree - mTreeObject->Fill(); + // filling the map + mMapObject[mFirstOrbitTF] = mDeadMapTF; end = std::chrono::high_resolution_clock::now(); int difference = std::chrono::duration_cast(end - start).count(); @@ -207,7 +202,8 @@ void ITSMFTDeadMapBuilder::PrepareOutputCcdb(DataAllocator& output) o2::ccdb::CcdbObjectInfo info((path + name_str), "time_dead_map", mObjectName, md, tstart, tend); - auto image = o2::ccdb::CcdbApi::createObjectImage(mTreeObject, &info); + auto image = o2::ccdb::CcdbApi::createObjectImage(&mMapObject, &info); + info.setFileName(mObjectName); info.setAdjustableEOV(); @@ -241,7 +237,7 @@ void ITSMFTDeadMapBuilder::endOfStream(EndOfStreamContext& ec) } ////////////////////////////////////////////////////////////////////////////// -// DDS stop method: simply close the latest tree +// DDS stop method: create local output if endOfStream not processed void ITSMFTDeadMapBuilder::stop() { if (!isEnded) { From 62e5432a2079c5702ab0dd2a9061ba6585f3bd72 Mon Sep 17 00:00:00 2001 From: nicolovalle <35177278+nicolovalle@users.noreply.github.com> Date: Fri, 15 Dec 2023 12:04:48 +0100 Subject: [PATCH 7/7] Update DeadMapBuilderSpec.h --- .../common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h index d858a60e7fd75..35e3a5bc422c9 100644 --- a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h +++ b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h @@ -91,7 +91,6 @@ class ITSMFTDeadMapBuilder : public Task std::string mObjectName; std::string mLocalOutputDir; - std::string MAP_VERSION = "2"; // to change in case the encoding or the format change std::vector mDeadMapTF{};