From 6126f4863637b706bb7ff767ca0225b0d8b7875a Mon Sep 17 00:00:00 2001 From: Zeynep Eda Cabukoglu Date: Fri, 24 Jul 2026 16:00:34 +0200 Subject: [PATCH] Expose event weight names through DataSource --- include/podio/DataSource.h | 14 +++++++++- src/DataSource.cc | 56 +++++++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/include/podio/DataSource.h b/include/podio/DataSource.h index 33f6ab921..8a206d930 100644 --- a/include/podio/DataSource.h +++ b/include/podio/DataSource.h @@ -129,12 +129,24 @@ class DataSource : public ROOT::RDF::RDataSource { /// Ranges of events available ever created std::vector> m_rangesAll = {}; - /// Column names + /// Column names visible to RDataFrame std::vector m_columnNames{}; + /// Event collection names read from each event frame. + /// This separate list prevents metadata such as _EventWeightNames from being + /// searched for inside every event frame. m_eventColumnNames is used when + /// reading events, while m_columnNames exposes both event and metadata columns + /// to RDataFrame. + std::vector m_eventColumnNames = {}; + /// Column types std::vector m_columnTypes = {}; + /// Event weight names copied from the metadata frame + std::vector m_eventWeightNames = {}; + /// Pointers used to connect the stored metadata labels to RDataFrame + std::vector*> m_eventWeightNameReaders = {}; + /// Collections, m_Collections[columnIndex][slotIndex] std::vector> m_Collections = {}; diff --git a/src/DataSource.cc b/src/DataSource.cc index 5e4f0779f..66d73225b 100644 --- a/src/DataSource.cc +++ b/src/DataSource.cc @@ -39,6 +39,24 @@ void DataSource::SetupInput(int nEvents, const std::vector& collsTo nEventsInFiles = podioReader.getEntries(podio::Category::Event); frame = podioReader.readFrame(podio::Category::Event, 0, collsToRead); + // Read the file-level metadata once from the first metadata frame. + // If EventWeightNames exists, copy it into DataSource-owned memory so + // the same labels remain available throughout the full RDataFrame run. + auto nMetadataFrames = podioReader.getEntries(podio::Category::Metadata); + + if (nMetadataFrames > 0) { + auto metadataFrame = + podioReader.readFrame(podio::Category::Metadata, 0); + + auto weightNames = + metadataFrame.getParameter>( + "EventWeightNames"); + + if (weightNames) { + m_eventWeightNames = *weightNames; + } + } + // Determine over how many events to run if (nEventsInFiles == 0) { throw std::runtime_error("podio::DataSource: No events found!"); @@ -60,14 +78,32 @@ void DataSource::SetupInput(int nEvents, const std::vector& collsTo for (auto&& collName : collNames) { const podio::CollectionBase* coll = frame.get(collName); if (coll) { + // Store each valid event collection in both lists: + // m_eventColumnNames will later be used to read only real event-frame collections, + // while m_columnNames will also contain metadata columns exposed to RDataFrame. + m_eventColumnNames.emplace_back(collName); m_columnNames.emplace_back(std::move(collName)); m_columnTypes.emplace_back(coll->getTypeName()); } } + // Expose the stored event-weight labels to RDataFrame as a metadata column. + // It is added only to m_columnNames because it does not exist in event frames. + //Only continue when m_eventWeightNames actually contains weight labels. (! = not) + if (!m_eventWeightNames.empty()) { + m_columnNames.emplace_back("_EventWeightNames"); + //adds a new column name called _EventWeightNames to the list of columns RDataFrame can see. + m_columnTypes.emplace_back("std::vector"); + //tells RDataFrame that this column contains a vector of strings + } + + } void DataSource::SetNSlots(unsigned int nSlots) { m_nSlots = nSlots; + // Create one metadata reader pointer for each RDataFrame processing slot. + // Every pointer refers to the same file-level event-weight labels. + m_eventWeightNameReaders.assign(m_nSlots, &m_eventWeightNames); if (m_nSlots > m_nEvents) { throw std::runtime_error("podio::DataSource: Number of events too small!"); @@ -119,7 +155,7 @@ void DataSource::InitSlot(unsigned int, ULong64_t) { bool DataSource::SetEntry(unsigned int slot, ULong64_t entry) { m_frames[slot] = - std::make_unique(m_podioReaders[slot]->readFrame(podio::Category::Event, entry, m_columnNames)); + std::make_unique(m_podioReaders[slot]->readFrame(podio::Category::Event, entry, m_eventColumnNames)); for (auto& collectionIndex : m_activeCollections) { m_Collections[collectionIndex][slot] = m_frames[slot]->get(m_columnNames.at(collectionIndex)); @@ -142,6 +178,24 @@ std::vector DataSource::GetColumnReadersImpl(std::string_view columnName, errMsg += "\"!"; throw std::runtime_error(errMsg); } + + // We already stored the metadata labels in m_eventWeightNames and registered + // _EventWeightNames as an RDataFrame column. This block connects that column + // to the stored vector, so RDataFrame reads the real metadata values instead + // of looking for _EventWeightNames inside each event frame. + + //check whether RDataFrame is asking for the metadata column. + if (columnName == "_EventWeightNames") { + std::vector columnReaders(m_nSlots); + + for (size_t slotIndex = 0; slotIndex < m_nSlots; ++slotIndex) { + columnReaders[slotIndex] = + static_cast(&m_eventWeightNameReaders[slotIndex]); + } + + return columnReaders; +} + auto columnIndex = std::distance(m_columnNames.begin(), itr); m_activeCollections.emplace_back(columnIndex);