Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion include/podio/DataSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,24 @@ class DataSource : public ROOT::RDF::RDataSource {
/// Ranges of events available ever created
std::vector<std::pair<ULong64_t, ULong64_t>> m_rangesAll = {};

/// Column names
/// Column names visible to RDataFrame
std::vector<std::string> 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<std::string> m_eventColumnNames = {};

/// Column types
std::vector<std::string> m_columnTypes = {};

/// Event weight names copied from the metadata frame
std::vector<std::string> m_eventWeightNames = {};
/// Pointers used to connect the stored metadata labels to RDataFrame
std::vector<std::vector<std::string>*> m_eventWeightNameReaders = {};

/// Collections, m_Collections[columnIndex][slotIndex]
std::vector<std::vector<const podio::CollectionBase*>> m_Collections = {};

Expand Down
56 changes: 55 additions & 1 deletion src/DataSource.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ void DataSource::SetupInput(int nEvents, const std::vector<std::string>& 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<std::vector<std::string>>(
"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!");
Expand All @@ -60,14 +78,32 @@ void DataSource::SetupInput(int nEvents, const std::vector<std::string>& 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<std::string>");
//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!");
Expand Down Expand Up @@ -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<podio::Frame>(m_podioReaders[slot]->readFrame(podio::Category::Event, entry, m_columnNames));
std::make_unique<podio::Frame>(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));
Expand All @@ -142,6 +178,24 @@ std::vector<void*> 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<void*> columnReaders(m_nSlots);

for (size_t slotIndex = 0; slotIndex < m_nSlots; ++slotIndex) {
columnReaders[slotIndex] =
static_cast<void*>(&m_eventWeightNameReaders[slotIndex]);
}

return columnReaders;
}

auto columnIndex = std::distance(m_columnNames.begin(), itr);
m_activeCollections.emplace_back(columnIndex);

Expand Down
Loading