From ec560d1fca64ec7fce8ddaba2c8eeeb67ea63cb9 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 15 Oct 2025 14:04:21 +0200 Subject: [PATCH] DPL Analysis: fix multiple HistogramRegistry instances per task In particular when one of them needs to have its own folder. --- Framework/AnalysisSupport/src/AODWriterHelpers.cxx | 12 ++++++++++++ Framework/Core/include/Framework/OutputObjHeader.h | 5 ++++- Framework/Core/src/HistogramRegistry.cxx | 3 ++- Framework/TestWorkflows/src/o2TestHistograms.cxx | 12 ++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Framework/AnalysisSupport/src/AODWriterHelpers.cxx b/Framework/AnalysisSupport/src/AODWriterHelpers.cxx index 27dad43480913..bcf27d0be5ba3 100644 --- a/Framework/AnalysisSupport/src/AODWriterHelpers.cxx +++ b/Framework/AnalysisSupport/src/AODWriterHelpers.cxx @@ -339,7 +339,9 @@ AlgorithmSpec AODWriterHelpers::getOutputObjHistWriter(ConfigContext const& ctx) O2_SIGNPOST_END(histogram_registry, did, "deserialization", "Done deserialization."); // If we have a folder, we assume the first element of the path // to be the name of the registry. + bool folderForContainer = false; if (sourceType == HistogramRegistrySource) { + folderForContainer = objh->createContainer != 0; obj.container = objh->containerName; } else { obj.container = obj.name; @@ -423,6 +425,16 @@ AlgorithmSpec AODWriterHelpers::getOutputObjHistWriter(ConfigContext const& ctx) // FIXME: handle folders f[route.policy]->cd("/"); auto* currentDir = f[route.policy]->GetDirectory(currentDirectory.c_str()); + + // In case we need a folder for the registry, let's create it. + if (folderForContainer) { + auto* histogramRegistryFolder = currentDir->GetDirectory(obj.container.data()); + if (!histogramRegistryFolder) { + histogramRegistryFolder = currentDir->mkdir(obj.container.c_str(), "", kTRUE); + } + currentDir = histogramRegistryFolder; + } + // The name contains a path... int objSize = 0; if (sourceType == HistogramRegistrySource) { diff --git a/Framework/Core/include/Framework/OutputObjHeader.h b/Framework/Core/include/Framework/OutputObjHeader.h index f1c284d564f15..801642ec6af4f 100644 --- a/Framework/Core/include/Framework/OutputObjHeader.h +++ b/Framework/Core/include/Framework/OutputObjHeader.h @@ -37,6 +37,7 @@ enum OutputObjSourceType : unsigned int { /// @brief O2 header for OutputObj metadata struct OutputObjHeader : public BaseHeader { constexpr static const uint32_t sVersion = 1; + constexpr static const uint32_t MAX_REGISTRY_NAME_SIZE = 128; constexpr static const o2::header::HeaderType sHeaderType = "OutObjMD"; constexpr static const o2::header::SerializationMethod sSerializationMethod = o2::header::gSerializationMethodNone; OutputObjHandlingPolicy mPolicy; @@ -45,7 +46,9 @@ struct OutputObjHeader : public BaseHeader { uint16_t mPipelineIndex = 0; uint16_t mPipelineSize = 1; // Name of the actual container for the object, e.g. the HistogramRegistry name - char containerName[64] = {0}; + char containerName[MAX_REGISTRY_NAME_SIZE] = {0}; + // Wether or not the container should have a name + char createContainer = false; constexpr OutputObjHeader() : BaseHeader(sizeof(OutputObjHeader), sHeaderType, sSerializationMethod, sVersion), diff --git a/Framework/Core/src/HistogramRegistry.cxx b/Framework/Core/src/HistogramRegistry.cxx index 5e39fbe7181e7..9caa7cbd1f48e 100644 --- a/Framework/Core/src/HistogramRegistry.cxx +++ b/Framework/Core/src/HistogramRegistry.cxx @@ -55,7 +55,8 @@ OutputRef HistogramRegistry::ref(uint16_t pipelineIndex, uint16_t pipelineSize) { OutputObjHeader header{mPolicy, OutputObjSourceType::HistogramRegistrySource, mTaskHash, pipelineIndex, pipelineSize}; // Copy the name of the registry to the haeder. - strncpy(header.containerName, mName.data(), 64); + strncpy(header.containerName, mName.data(), OutputObjHeader::MAX_REGISTRY_NAME_SIZE); + header.createContainer = mCreateRegistryDir ? 1 : 0; return OutputRef{std::string{mName}, 0, o2::header::Stack{header}}; } diff --git a/Framework/TestWorkflows/src/o2TestHistograms.cxx b/Framework/TestWorkflows/src/o2TestHistograms.cxx index ae3610ca01e67..640a165fb91ff 100644 --- a/Framework/TestWorkflows/src/o2TestHistograms.cxx +++ b/Framework/TestWorkflows/src/o2TestHistograms.cxx @@ -53,6 +53,18 @@ struct EtaAndClsHistogramsSimple { } // }; + HistogramRegistry registry2{ + "registry2", + { + {"a/foo/b/eta", "#Eta", {HistType::kTH1F, {{100, -2.0, 2.0}}}}, // + {"fii/c/hpt", "p_{T}", {HistType::kTH1D, {{1002, -0.01, 50.1}}}}, // + {"a/foobar/phi", "#Phi", {HistType::kTH1D, {{102, 0, 2 * M_PI}}}}, // + {"fifi/ptToPt", "#ptToPt", {HistType::kTH2F, {{100, -0.01, 10.01}, {100, -0.01, 10.01}}}} // + }, + OutputObjHandlingPolicy::AnalysisObject, + false, + true}; + void init(InitContext&) { if (!trackFilterString->empty()) {