diff --git a/PhysicsTools/NanoAOD/plugins/BuildFile.xml b/PhysicsTools/NanoAOD/plugins/BuildFile.xml
index bbe8818cfa63a..405928ffd7c53 100644
--- a/PhysicsTools/NanoAOD/plugins/BuildFile.xml
+++ b/PhysicsTools/NanoAOD/plugins/BuildFile.xml
@@ -38,9 +38,7 @@
-
diff --git a/PhysicsTools/NanoAOD/plugins/rntuple/EventStringOutputFields.h b/PhysicsTools/NanoAOD/plugins/rntuple/EventStringOutputFields.h
index 71e502bdd5058..5e86e89582101 100644
--- a/PhysicsTools/NanoAOD/plugins/rntuple/EventStringOutputFields.h
+++ b/PhysicsTools/NanoAOD/plugins/rntuple/EventStringOutputFields.h
@@ -6,7 +6,7 @@
#include "FWCore/Utilities/interface/EDGetToken.h"
#include
-using ROOT::Experimental::RNTupleModel;
+using ROOT::RNTupleModel;
#include "RNTupleFieldPtr.h"
diff --git a/PhysicsTools/NanoAOD/plugins/rntuple/NanoAODRNTupleOutputModule.cc b/PhysicsTools/NanoAOD/plugins/rntuple/NanoAODRNTupleOutputModule.cc
index ca293cbe9e552..26f8aca1ee25e 100644
--- a/PhysicsTools/NanoAOD/plugins/rntuple/NanoAODRNTupleOutputModule.cc
+++ b/PhysicsTools/NanoAOD/plugins/rntuple/NanoAODRNTupleOutputModule.cc
@@ -15,19 +15,9 @@
#include
#include
-#include
-using ROOT::Experimental::RNTupleModel;
-#if ROOT_VERSION_CODE < ROOT_VERSION(6, 31, 0)
-using ROOT::Experimental::RNTupleWriter;
-using ROOT::Experimental::Detail::RPageSinkFile;
-#define MakeRNTupleWriter std::make_unique
-#include
-#else
-using ROOT::Experimental::Internal::RPageSinkFile;
-#define MakeRNTupleWriter ROOT::Experimental::Internal::CreateRNTupleWriter
+using ROOT::RNTupleModel;
#include
-#endif
-using ROOT::Experimental::RNTupleWriteOptions;
+using ROOT::RNTupleWriteOptions;
#include "TObjString.h"
@@ -173,13 +163,15 @@ void NanoAODRNTupleOutputModule::openFile(edm::FileBlock const&) {
const auto& keeps = keptProducts();
for (const auto& keep : keeps[edm::InRun]) {
if (keep.first->className() == "nanoaod::MergeableCounterTable") {
- m_run.registerToken(keep.second);
+ m_run.registerCounterTableToken(keep.second);
} else if (keep.first->className() == "nanoaod::UniqueString" && keep.first->moduleLabel() == "nanoMetadata") {
m_nanoMetadata.emplace_back(keep.first->productInstanceName(), keep.second);
+ } else if (keep.first->className() == "nanoaod::FlatTable") {
+ m_run.registerFlatTableToken(keep.second);
} else {
throw cms::Exception(
"Configuration",
- "NanoAODRNTupleOutputModule cannot handle class " + keep.first->className() + " in Run branch");
+ "NanoAODRNTupleOutputModule cannot handle class " + keep.first->className() + " in Run RNTuple");
}
}
}
@@ -210,10 +202,15 @@ void NanoAODRNTupleOutputModule::initializeNTuple(edm::EventForOutput const& iEv
trigger.createFields(iEvent, *model);
}
m_evstrings.createFields(*model);
- // TODO use Append
+
+ // Model needs to be frozen before we bind buffers
+ model->Freeze();
+
+ m_tables.bindBuffers(*model);
+
RNTupleWriteOptions options;
options.SetCompression(m_file->GetCompressionSettings());
- m_ntuple = MakeRNTupleWriter(std::move(model), std::make_unique("Events", *m_file, options));
+ m_ntuple = RNTupleWriter::Append(std::move(model), "Events", *m_file, options);
}
void NanoAODRNTupleOutputModule::write(edm::EventForOutput const& iEvent) {
diff --git a/PhysicsTools/NanoAOD/plugins/rntuple/NanoAODRNTuples.cc b/PhysicsTools/NanoAOD/plugins/rntuple/NanoAODRNTuples.cc
index 86c367bb95898..707cee0be4215 100644
--- a/PhysicsTools/NanoAOD/plugins/rntuple/NanoAODRNTuples.cc
+++ b/PhysicsTools/NanoAOD/plugins/rntuple/NanoAODRNTuples.cc
@@ -3,21 +3,10 @@
#include "DataFormats/NanoAOD/interface/MergeableCounterTable.h"
#include "FWCore/Framework/interface/RunForOutput.h"
-#include
#include
-#include
-using ROOT::Experimental::RNTupleModel;
-#if ROOT_VERSION_CODE < ROOT_VERSION(6, 31, 0)
-using ROOT::Experimental::RNTupleWriter;
-using ROOT::Experimental::Detail::RPageSinkFile;
-#define MakeRNTupleWriter std::make_unique
-#include
-#else
-using ROOT::Experimental::Internal::RPageSinkFile;
-#define MakeRNTupleWriter ROOT::Experimental::Internal::CreateRNTupleWriter
+using ROOT::RNTupleModel;
#include
-#endif
-using ROOT::Experimental::RNTupleWriteOptions;
+using ROOT::RNTupleWriteOptions;
#include "RNTupleFieldPtr.h"
#include "SummaryTableOutputFields.h"
@@ -26,11 +15,9 @@ void LumiNTuple::createFields(const edm::LuminosityBlockID& id, TFile& file) {
auto model = RNTupleModel::Create();
m_run = RNTupleFieldPtr("run", "", *model);
m_luminosityBlock = RNTupleFieldPtr("luminosityBlock", "", *model);
- // TODO use Append when we bump our RNTuple version:
- // m_ntuple = RNTupleWriter::Append(std::move(model), "LuminosityBlocks", file);
RNTupleWriteOptions options;
options.SetCompression(file.GetCompressionSettings());
- m_ntuple = MakeRNTupleWriter(std::move(model), std::make_unique("LuminosityBlocks", file, options));
+ m_ntuple = RNTupleWriter::Append(std::move(model), "LuminosityBlocks", file, options);
}
void LumiNTuple::fill(const edm::LuminosityBlockID& id, TFile& file) {
@@ -44,23 +31,31 @@ void LumiNTuple::fill(const edm::LuminosityBlockID& id, TFile& file) {
void LumiNTuple::finalizeWrite() { m_ntuple.reset(); }
-void RunNTuple::registerToken(const edm::EDGetToken& token) { m_tokens.push_back(token); }
+void RunNTuple::registerCounterTableToken(const edm::EDGetToken& token) { m_counterTableTokens.push_back(token); }
+
+void RunNTuple::registerFlatTableToken(const edm::EDGetToken& token) { m_flatTableTokens.push_back(token); }
void RunNTuple::createFields(const edm::RunForOutput& iRun, TFile& file) {
auto model = RNTupleModel::Create();
m_run = RNTupleFieldPtr("run", "", *model);
- edm::Handle handle;
- for (const auto& token : m_tokens) {
- iRun.getByToken(token, handle);
- const nanoaod::MergeableCounterTable& tab = *handle;
- m_tables.push_back(SummaryTableOutputFields(tab, *model));
+ edm::Handle counterTableHandle;
+ for (const auto& token : m_counterTableTokens) {
+ iRun.getByToken(token, counterTableHandle);
+ const nanoaod::MergeableCounterTable& tab = *counterTableHandle;
+ m_counterTables.push_back(SummaryTableOutputFields(tab, *model));
+ }
+
+ edm::Handle flatTableHandle;
+ for (const auto& token : m_flatTableTokens) {
+ iRun.getByToken(token, flatTableHandle);
+ m_flatTables.add(token, *flatTableHandle);
}
+ m_flatTables.createFields(iRun, *model);
- // TODO use Append when we bump our RNTuple version
RNTupleWriteOptions options;
options.SetCompression(file.GetCompressionSettings());
- m_ntuple = MakeRNTupleWriter(std::move(model), std::make_unique("Runs", file, options));
+ m_ntuple = RNTupleWriter::Append(std::move(model), "Runs", file, options);
}
void RunNTuple::fill(const edm::RunForOutput& iRun, TFile& file) {
@@ -68,29 +63,28 @@ void RunNTuple::fill(const edm::RunForOutput& iRun, TFile& file) {
createFields(iRun, file);
}
m_run.fill(iRun.id().run());
- edm::Handle handle;
- for (std::size_t i = 0; i < m_tokens.size(); i++) {
- iRun.getByToken(m_tokens.at(i), handle);
- const nanoaod::MergeableCounterTable& tab = *handle;
- m_tables.at(i).fill(tab);
+
+ edm::Handle counterTableHandle;
+ for (std::size_t i = 0; i < m_counterTableTokens.size(); i++) {
+ iRun.getByToken(m_counterTableTokens.at(i), counterTableHandle);
+ const nanoaod::MergeableCounterTable& tab = *counterTableHandle;
+ m_counterTables.at(i).fill(tab);
}
+
+ m_flatTables.fill(iRun);
+
m_ntuple->Fill();
}
void RunNTuple::finalizeWrite() { m_ntuple.reset(); }
void PSetNTuple::createFields(TFile& file) {
- // use a collection to emulate std::pair
- auto pairModel = RNTupleModel::Create();
- m_psetId = RNTupleFieldPtr("first", "", *pairModel);
- m_psetBlob = RNTupleFieldPtr("second", "", *pairModel);
auto model = RNTupleModel::Create();
- m_collection = model->MakeCollection(edm::poolNames::idToParameterSetBlobsBranchName(), std::move(pairModel));
- // TODO use Append when we bump our RNTuple version
+ m_pset = RNTupleFieldPtr(edm::poolNames::idToParameterSetBlobsBranchName(), "", *model);
+
RNTupleWriteOptions options;
options.SetCompression(file.GetCompressionSettings());
- m_ntuple = MakeRNTupleWriter(std::move(model),
- std::make_unique(edm::poolNames::parameterSetsTreeName(), file, options));
+ m_ntuple = RNTupleWriter::Append(std::move(model), edm::poolNames::parameterSetsTreeName(), file, options);
}
void PSetNTuple::fill(edm::pset::Registry* pset, TFile& file) {
@@ -101,28 +95,22 @@ void PSetNTuple::fill(edm::pset::Registry* pset, TFile& file) {
createFields(file);
}
for (const auto& ps : *pset) {
- std::ostringstream oss;
- oss << ps.first;
- m_psetId.fill(oss.str());
- m_psetBlob.fill(ps.second.toString());
- m_collection->Fill();
+ std::string psString;
+ ps.second.toString(psString);
+ edm::ParameterSetBlob psBlob(psString);
+ m_pset.fill(std::make_pair(ps.first, psBlob));
m_ntuple->Fill();
}
}
void PSetNTuple::finalizeWrite() { m_ntuple.reset(); }
-// TODO blocked on RNTuple typedef member field support
void MetadataNTuple::createFields(TFile& file) {
- auto procHistModel = RNTupleModel::Create();
- // ProcessHistory.transients_.phid_ replacement
- m_phId = RNTupleFieldPtr("transients_phid_", "", *procHistModel);
auto model = RNTupleModel::Create();
- m_procHist = model->MakeCollection(edm::poolNames::processHistoryBranchName(), std::move(procHistModel));
+ m_procHist = RNTupleFieldPtr(edm::poolNames::processHistoryBranchName(), "", *model);
RNTupleWriteOptions options;
options.SetCompression(file.GetCompressionSettings());
- m_ntuple = MakeRNTupleWriter(std::move(model),
- std::make_unique(edm::poolNames::metaDataTreeName(), file, options));
+ m_ntuple = RNTupleWriter::Append(std::move(model), edm::poolNames::metaDataTreeName(), file, options);
}
void MetadataNTuple::fill(const edm::ProcessHistoryRegistry& procHist, TFile& file) {
@@ -130,12 +118,9 @@ void MetadataNTuple::fill(const edm::ProcessHistoryRegistry& procHist, TFile& fi
createFields(file);
}
for (const auto& ph : procHist) {
- std::string phid;
- ph.second.id().toString(phid);
- m_phId.fill(phid);
- m_procHist->Fill();
+ m_procHist.fill(ph.second);
+ m_ntuple->Fill();
}
- m_ntuple->Fill();
}
void MetadataNTuple::finalizeWrite() { m_ntuple.reset(); }
diff --git a/PhysicsTools/NanoAOD/plugins/rntuple/NanoAODRNTuples.h b/PhysicsTools/NanoAOD/plugins/rntuple/NanoAODRNTuples.h
index 65843adafe94c..80f8251c26cb6 100644
--- a/PhysicsTools/NanoAOD/plugins/rntuple/NanoAODRNTuples.h
+++ b/PhysicsTools/NanoAOD/plugins/rntuple/NanoAODRNTuples.h
@@ -12,14 +12,8 @@
#include "TFile.h"
#include
-#if ROOT_VERSION_CODE < ROOT_VERSION(6, 31, 0)
-using ROOT::Experimental::RCollectionNTupleWriter;
-#else
#include
-#include
-using ROOT::Experimental::RNTupleCollectionWriter;
-#endif
-using ROOT::Experimental::RNTupleWriter;
+using ROOT::RNTupleWriter;
#include "EventStringOutputFields.h"
#include "RNTupleFieldPtr.h"
@@ -43,16 +37,19 @@ class LumiNTuple {
class RunNTuple {
public:
RunNTuple() = default;
- void registerToken(const edm::EDGetToken& token);
+ void registerCounterTableToken(const edm::EDGetToken& token);
+ void registerFlatTableToken(const edm::EDGetToken& token);
void fill(const edm::RunForOutput& iRun, TFile& file);
void finalizeWrite();
private:
void createFields(const edm::RunForOutput& iRun, TFile& file);
- std::vector m_tokens;
+ std::vector m_counterTableTokens;
+ std::vector m_flatTableTokens;
std::unique_ptr m_ntuple;
RNTupleFieldPtr m_run;
- std::vector m_tables;
+ std::vector m_counterTables;
+ TableCollectionSet m_flatTables;
};
class PSetNTuple {
@@ -62,21 +59,9 @@ class PSetNTuple {
void finalizeWrite();
private:
- // TODO blocked on RNTuple std::pair support
- // using PSetType = std::pair;
- // RNTupleFieldPtr m_pset;
+ using PSetType = std::pair;
+ RNTupleFieldPtr m_pset;
void createFields(TFile& file);
- // TODO blocked on RNTuple typedef member field support:
- // https://github.com/root-project/root/issues/7861
- // RNTupleFieldPtr m_psetId;
- // RNTupleFieldPtr m_psetBlob;
-#if ROOT_VERSION_CODE < ROOT_VERSION(6, 31, 0)
- std::shared_ptr m_collection;
-#else
- std::shared_ptr m_collection;
-#endif
- RNTupleFieldPtr m_psetId;
- RNTupleFieldPtr m_psetBlob;
std::unique_ptr m_ntuple;
};
@@ -88,13 +73,7 @@ class MetadataNTuple {
private:
void createFields(TFile& file);
-#if ROOT_VERSION_CODE < ROOT_VERSION(6, 31, 0)
- std::shared_ptr m_procHist;
-#else
- std::shared_ptr m_procHist;
-#endif
-
- RNTupleFieldPtr m_phId;
+ RNTupleFieldPtr m_procHist;
std::unique_ptr m_ntuple;
};
diff --git a/PhysicsTools/NanoAOD/plugins/rntuple/RNTupleCollection.cc b/PhysicsTools/NanoAOD/plugins/rntuple/RNTupleCollection.cc
new file mode 100644
index 0000000000000..d9e8ca6ad968d
--- /dev/null
+++ b/PhysicsTools/NanoAOD/plugins/rntuple/RNTupleCollection.cc
@@ -0,0 +1,128 @@
+#include "RNTupleCollection.h"
+
+#include
+#include
+#include
+
+using ROOT::REntry;
+using ROOT::RFieldBase;
+using ROOT::RNTupleModel;
+using ROOT::RRecordField;
+using ROOT::RVectorField;
+
+std::string flatTableColumnTypeToString(nanoaod::FlatTable::ColumnType type) {
+ switch (type) {
+ case nanoaod::FlatTable::ColumnType::UInt8:
+ return "std::uint8_t";
+ case nanoaod::FlatTable::ColumnType::Int16:
+ return "std::int16_t";
+ case nanoaod::FlatTable::ColumnType::UInt16:
+ return "std::uint16_t";
+ case nanoaod::FlatTable::ColumnType::Int32:
+ return "std::int32_t";
+ case nanoaod::FlatTable::ColumnType::UInt32:
+ return "std::uint32_t";
+ case nanoaod::FlatTable::ColumnType::Int64:
+ return "std::int64_t";
+ case nanoaod::FlatTable::ColumnType::UInt64:
+ return "std::uint64_t";
+ case nanoaod::FlatTable::ColumnType::Bool:
+ return "bool";
+ case nanoaod::FlatTable::ColumnType::Float:
+ return "float";
+ case nanoaod::FlatTable::ColumnType::Double:
+ return "double";
+ default:
+ throw cms::Exception("LogicError", "Unsupported type");
+ }
+}
+
+std::tuple getColStartAndTypeSize(edm::Handle& table,
+ unsigned int colIdx) {
+ const unsigned char* col_start;
+ switch (table->columnType(colIdx)) {
+ case nanoaod::FlatTable::ColumnType::UInt8:
+ col_start = reinterpret_cast(table->columnData(colIdx).data());
+ return std::make_tuple(col_start, 1);
+ case nanoaod::FlatTable::ColumnType::Int16:
+ col_start = reinterpret_cast(table->columnData(colIdx).data());
+ return std::make_tuple(col_start, 2);
+ case nanoaod::FlatTable::ColumnType::UInt16:
+ col_start = reinterpret_cast(table->columnData(colIdx).data());
+ return std::make_tuple(col_start, 2);
+ case nanoaod::FlatTable::ColumnType::Int32:
+ col_start = reinterpret_cast(table->columnData(colIdx).data());
+ return std::make_tuple(col_start, 4);
+ case nanoaod::FlatTable::ColumnType::UInt32:
+ col_start = reinterpret_cast(table->columnData(colIdx).data());
+ return std::make_tuple(col_start, 4);
+ case nanoaod::FlatTable::ColumnType::Int64:
+ col_start = reinterpret_cast(table->columnData(colIdx).data());
+ return std::make_tuple(col_start, 8);
+ case nanoaod::FlatTable::ColumnType::UInt64:
+ col_start = reinterpret_cast(table->columnData(colIdx).data());
+ return std::make_tuple(col_start, 8);
+ case nanoaod::FlatTable::ColumnType::Bool:
+ col_start = reinterpret_cast(table->columnData(colIdx).data());
+ return std::make_tuple(col_start, 1);
+ case nanoaod::FlatTable::ColumnType::Float:
+ col_start = reinterpret_cast(table->columnData(colIdx).data());
+ return std::make_tuple(col_start, 4);
+ case nanoaod::FlatTable::ColumnType::Double:
+ col_start = reinterpret_cast(table->columnData(colIdx).data());
+ return std::make_tuple(col_start, 8);
+ default:
+ throw cms::Exception("LogicError", "Unsupported type");
+ }
+}
+
+RNTupleCollection::RNTupleCollection(const std::string& name,
+ const std::string& desc,
+ std::vector>& tables,
+ RNTupleModel& model)
+ : m_name(name) {
+ std::vector> subfields;
+ for (auto& table : tables) {
+ for (unsigned int i = 0; i < table->nColumns(); i++) {
+ std::string type = flatTableColumnTypeToString(table->columnType(i));
+ auto field = RFieldBase::Create(table->columnName(i), type).Unwrap();
+ field->SetDescription(table->columnDoc(i));
+ subfields.push_back(std::move(field));
+ }
+ }
+ auto record_field = std::make_unique("_0", std::move(subfields));
+ m_record_size = record_field->GetValueSize();
+ m_record_offsets = record_field->GetOffsets();
+ auto collection_field = RVectorField::CreateUntyped(name, std::move(record_field));
+ collection_field->SetDescription(desc);
+ model.AddField(std::move(collection_field));
+}
+
+void RNTupleCollection::bindBuffer(RNTupleModel& model) {
+ auto& default_entry = model.GetDefaultEntry();
+ default_entry.BindRawPtr(m_name, &m_buffer);
+}
+
+void RNTupleCollection::fill(std::vector>& tables) {
+ unsigned int col_idx = 0;
+ size_t col_size = tables.empty() ? 0 : tables[0]->size();
+
+ m_buffer.resize(m_record_size * col_size);
+
+ for (auto& table : tables) {
+ if (table->size() != col_size) {
+ throw cms::Exception("LogicError",
+ "Mismatch in number of entries between extension and main table for " + m_name);
+ }
+ for (unsigned int i = 0; i < table->nColumns(); i++) {
+ auto [col_start, type_size] = getColStartAndTypeSize(table, i);
+ size_t col_offset = m_record_offsets[col_idx];
+
+ for (unsigned int j = 0; j < col_size; j++) {
+ std::memcpy(m_buffer.data() + (j * m_record_size) + col_offset, col_start + (j * type_size), type_size);
+ }
+
+ col_idx++;
+ }
+ }
+}
diff --git a/PhysicsTools/NanoAOD/plugins/rntuple/RNTupleCollection.h b/PhysicsTools/NanoAOD/plugins/rntuple/RNTupleCollection.h
new file mode 100644
index 0000000000000..e566fa8fa43be
--- /dev/null
+++ b/PhysicsTools/NanoAOD/plugins/rntuple/RNTupleCollection.h
@@ -0,0 +1,30 @@
+#ifndef PhysicsTools_NanoAOD_RNTupleCollection_h
+#define PhysicsTools_NanoAOD_RNTupleCollection_h
+
+#include "DataFormats/NanoAOD/interface/FlatTable.h"
+#include "DataFormats/Common/interface/Handle.h"
+
+#include
+#include
+
+class RNTupleCollection {
+public:
+ RNTupleCollection() = delete;
+ RNTupleCollection(const std::string& name,
+ const std::string& desc,
+ std::vector>& tables,
+ ROOT::RNTupleModel& model);
+
+ const std::string& getFieldName() const { return m_name; }
+
+ void bindBuffer(ROOT::RNTupleModel& model);
+ void fill(std::vector>& tables);
+
+private:
+ std::string m_name;
+ std::size_t m_record_size;
+ std::vector m_record_offsets;
+ std::vector m_buffer;
+};
+
+#endif
diff --git a/PhysicsTools/NanoAOD/plugins/rntuple/RNTupleFieldPtr.h b/PhysicsTools/NanoAOD/plugins/rntuple/RNTupleFieldPtr.h
index ecb303a52c729..a49644e2419b0 100644
--- a/PhysicsTools/NanoAOD/plugins/rntuple/RNTupleFieldPtr.h
+++ b/PhysicsTools/NanoAOD/plugins/rntuple/RNTupleFieldPtr.h
@@ -2,14 +2,14 @@
#define PhysicsTools_NanoAOD_RNTupleFieldPtr_h
#include
-using ROOT::Experimental::RNTupleModel;
+#include
template
class RNTupleFieldPtr {
public:
RNTupleFieldPtr() = default;
- explicit RNTupleFieldPtr(const std::string& name, const std::string& desc, RNTupleModel& model) : m_name(name) {
- m_field = model.MakeField({m_name, desc});
+ explicit RNTupleFieldPtr(const std::string& name, const std::string& desc, ROOT::RNTupleModel& model) : m_name(name) {
+ m_field = model.MakeField(m_name, desc);
}
void fill(const T& value) { *m_field = value; }
const std::string& getFieldName() const { return m_name; }
diff --git a/PhysicsTools/NanoAOD/plugins/rntuple/SummaryTableOutputFields.cc b/PhysicsTools/NanoAOD/plugins/rntuple/SummaryTableOutputFields.cc
index 878bf039c3597..6f2b57b5c38db 100644
--- a/PhysicsTools/NanoAOD/plugins/rntuple/SummaryTableOutputFields.cc
+++ b/PhysicsTools/NanoAOD/plugins/rntuple/SummaryTableOutputFields.cc
@@ -1,12 +1,13 @@
#include "SummaryTableOutputFields.h"
+using ROOT::RNTupleModel;
+
template
std::vector> SummaryTableOutputFields::makeFields(const std::vector &tabcols,
RNTupleModel &model) {
std::vector> fields;
fields.reserve(tabcols.size());
for (const auto &col : tabcols) {
- // TODO field description
fields.emplace_back(RNTupleFieldPtr(col.name, col.doc, model));
}
return fields;
@@ -26,6 +27,7 @@ void SummaryTableOutputFields::fillScalarFields(const std::vector &tabcols,
}
}
+// TODO: maybe we can unify with the function above since now it's the same
template
void SummaryTableOutputFields::fillVectorFields(const std::vector &tabcols,
std::vector> fields) {
@@ -36,22 +38,17 @@ void SummaryTableOutputFields::fillVectorFields(const std::vector &tabcols,
if (tabcols[i].name != fields[i].getFieldName()) {
throw cms::Exception("LogicError", "Mismatch in table columns");
}
- auto data = tabcols[i].values;
- // TODO remove this awful hack when std::int64_t is supported
- // -- turns std::vector into std::vector
- T casted_data(data.begin(), data.end());
- fields[i].fill(casted_data);
+ fields[i].fill(tabcols[i].values);
}
}
SummaryTableOutputFields::SummaryTableOutputFields(const nanoaod::MergeableCounterTable &tab, RNTupleModel &model) {
- // TODO use std::int64_t when supported
- m_intFields = makeFields(tab.intCols(), model);
- m_floatFields = makeFields(tab.floatCols(), model);
- m_floatWithNormFields = makeFields(tab.floatWithNormCols(), model);
- m_vintFields = makeFields>(tab.vintCols(), model);
- m_vfloatFields = makeFields>(tab.vfloatCols(), model);
- m_vfloatWithNormFields = makeFields>(tab.vfloatWithNormCols(), model);
+ m_intFields = makeFields(tab.intCols(), model);
+ m_floatFields = makeFields(tab.floatCols(), model);
+ m_floatWithNormFields = makeFields(tab.floatWithNormCols(), model);
+ m_vintFields = makeFields>(tab.vintCols(), model);
+ m_vfloatFields = makeFields>(tab.vfloatCols(), model);
+ m_vfloatWithNormFields = makeFields>(tab.vfloatWithNormCols(), model);
}
void SummaryTableOutputFields::fill(const nanoaod::MergeableCounterTable &tab) {
diff --git a/PhysicsTools/NanoAOD/plugins/rntuple/SummaryTableOutputFields.h b/PhysicsTools/NanoAOD/plugins/rntuple/SummaryTableOutputFields.h
index 51e6fd52d45c5..8c267b7aa460e 100644
--- a/PhysicsTools/NanoAOD/plugins/rntuple/SummaryTableOutputFields.h
+++ b/PhysicsTools/NanoAOD/plugins/rntuple/SummaryTableOutputFields.h
@@ -8,23 +8,26 @@
class SummaryTableOutputFields {
public:
SummaryTableOutputFields() = default;
- SummaryTableOutputFields(const nanoaod::MergeableCounterTable &tab, RNTupleModel &model);
+ SummaryTableOutputFields(const nanoaod::MergeableCounterTable &tab, ROOT::RNTupleModel &model);
void fill(const nanoaod::MergeableCounterTable &tab);
private:
template
- std::vector> makeFields(const std::vector &tabcols, RNTupleModel &model);
+ std::vector> makeFields(const std::vector &tabcols, ROOT::RNTupleModel &model);
template
static void fillScalarFields(const std::vector &tabcols, std::vector> fields);
template
static void fillVectorFields(const std::vector &tabcols, std::vector> fields);
- std::vector> m_intFields;
- std::vector> m_floatFields;
- std::vector> m_floatWithNormFields;
- std::vector>> m_vfloatFields;
- std::vector>> m_vfloatWithNormFields;
- std::vector>> m_vintFields;
+ using int_accumulator = nanoaod::MergeableCounterTable::int_accumulator;
+ using float_accumulator = nanoaod::MergeableCounterTable::float_accumulator;
+
+ std::vector> m_intFields;
+ std::vector> m_floatFields;
+ std::vector> m_floatWithNormFields;
+ std::vector>> m_vfloatFields;
+ std::vector>> m_vfloatWithNormFields;
+ std::vector>> m_vintFields;
};
#endif
diff --git a/PhysicsTools/NanoAOD/plugins/rntuple/TableOutputFields.cc b/PhysicsTools/NanoAOD/plugins/rntuple/TableOutputFields.cc
index eef3bf0f99a96..27ddded769bb4 100644
--- a/PhysicsTools/NanoAOD/plugins/rntuple/TableOutputFields.cc
+++ b/PhysicsTools/NanoAOD/plugins/rntuple/TableOutputFields.cc
@@ -24,7 +24,9 @@ namespace {
std::cout << "bool,";
break;
default:
- throw cms::Exception("LogicError", "Unsupported type");
+ std::cout << "other,";
+ break;
+ //throw cms::Exception("LogicError", "Unsupported type");
}
std::cout << "\n";
}
@@ -47,7 +49,7 @@ void TableOutputFields::print() const {
}
}
-void TableOutputFields::createFields(const edm::EventForOutput& event, RNTupleModel& model) {
+void TableOutputFields::createFields(const edm::OccurrenceForOutput& event, RNTupleModel& model) {
edm::Handle handle;
event.getByToken(m_token, handle);
const nanoaod::FlatTable& table = *handle;
@@ -66,7 +68,9 @@ void TableOutputFields::createFields(const edm::EventForOutput& event, RNTupleMo
m_boolFields.emplace_back(FlatTableField(table, i, model));
break;
default:
- throw cms::Exception("LogicError", "Unsupported type");
+ std::cout << "Unsupported type in TableOutputFields"
+ << "\n";
+ //throw cms::Exception("LogicError", "Unsupported type");
}
}
}
@@ -88,9 +92,15 @@ void TableOutputFields::fillEntry(const nanoaod::FlatTable& table, std::size_t i
const edm::EDGetToken& TableOutputFields::getToken() const { return m_token; }
+const edm::Handle TableOutputFields::getTable(const edm::OccurrenceForOutput& event) const {
+ edm::Handle handle;
+ event.getByToken(m_token, handle);
+ return handle;
+}
+
///////////////////////////////////////////////////////////////////////////////
-void TableOutputVectorFields::createFields(const edm::EventForOutput& event, RNTupleModel& model) {
+void TableOutputVectorFields::createFields(const edm::OccurrenceForOutput& event, RNTupleModel& model) {
edm::Handle handle;
event.getByToken(m_token, handle);
const nanoaod::FlatTable& table = *handle;
@@ -109,11 +119,13 @@ void TableOutputVectorFields::createFields(const edm::EventForOutput& event, RNT
m_vboolFields.emplace_back(FlatTableField>(table, i, model));
break;
default:
- throw cms::Exception("LogicError", "Unsupported type");
+ std::cout << "Unsupported type in TableOutputVectorFields"
+ << "\n";
+ //throw cms::Exception("LogicError", "Unsupported type");
}
}
}
-void TableOutputVectorFields::fill(const edm::EventForOutput& event) {
+void TableOutputVectorFields::fill(const edm::OccurrenceForOutput& event) {
edm::Handle handle;
event.getByToken(m_token, handle);
const auto& table = *handle;
@@ -147,38 +159,37 @@ void TableCollection::add(const edm::EDGetToken& table_token, const nanoaod::Fla
m_main = TableOutputFields(table_token);
}
-void TableCollection::createFields(const edm::EventForOutput& event, RNTupleModel& eventModel) {
- auto collectionModel = RNTupleModel::Create();
- m_main.createFields(event, *collectionModel);
+void TableCollection::createFields(const edm::OccurrenceForOutput& event, RNTupleModel& eventModel) {
+ std::vector> tables;
+
+ auto main_table = m_main.getTable(event);
+ std::string field_desc = main_table->doc();
+
+ tables.emplace_back(main_table);
+
for (auto& extension : m_extensions) {
- extension.createFields(event, *collectionModel);
+ auto ext_table = extension.getTable(event);
+ tables.emplace_back(ext_table);
}
- edm::Handle handle;
- event.getByToken(m_main.getToken(), handle);
- const nanoaod::FlatTable& table = *handle;
- collectionModel->SetDescription(table.doc());
- m_collection = eventModel.MakeCollection(m_collectionName, std::move(collectionModel));
+ m_collection = std::make_unique(m_collectionName, field_desc, tables, eventModel);
}
-void TableCollection::fill(const edm::EventForOutput& event) {
- edm::Handle handle;
- event.getByToken(m_main.getToken(), handle);
- const auto& main_table = *handle;
- auto table_size = main_table.size();
- for (std::size_t i = 0; i < table_size; i++) {
- m_main.fillEntry(main_table, i);
- for (auto& ext : m_extensions) {
- edm::Handle handle;
- event.getByToken(ext.getToken(), handle);
- const auto& ext_table = *handle;
- if (ext_table.size() != table_size) {
- throw cms::Exception("LogicError",
- "Mismatch in number of entries between extension and main table for " + m_collectionName);
- }
- ext.fillEntry(ext_table, i);
- }
- m_collection->Fill();
+void TableCollection::bindBuffer(RNTupleModel& eventModel) { m_collection->bindBuffer(eventModel); }
+
+void TableCollection::fill(const edm::OccurrenceForOutput& event) {
+ std::vector> tables;
+
+ auto main_table = m_main.getTable(event);
+ std::string field_desc = main_table->doc();
+
+ tables.emplace_back(main_table);
+
+ for (auto& extension : m_extensions) {
+ auto ext_table = extension.getTable(event);
+ tables.emplace_back(ext_table);
}
+
+ m_collection->fill(tables);
}
void TableCollection::print() const {
@@ -237,7 +248,7 @@ void TableCollectionSet::print() const {
}
}
-void TableCollectionSet::createFields(const edm::EventForOutput& event, RNTupleModel& eventModel) {
+void TableCollectionSet::createFields(const edm::OccurrenceForOutput& event, RNTupleModel& eventModel) {
for (auto& collection : m_collections) {
if (!collection.hasMainTable()) {
throw cms::Exception("LogicError",
@@ -254,7 +265,13 @@ void TableCollectionSet::createFields(const edm::EventForOutput& event, RNTupleM
}
}
-void TableCollectionSet::fill(const edm::EventForOutput& event) {
+void TableCollectionSet::bindBuffers(RNTupleModel& eventModel) {
+ for (auto& collection : m_collections) {
+ collection.bindBuffer(eventModel);
+ }
+}
+
+void TableCollectionSet::fill(const edm::OccurrenceForOutput& event) {
for (auto& collection : m_collections) {
collection.fill(event);
}
diff --git a/PhysicsTools/NanoAOD/plugins/rntuple/TableOutputFields.h b/PhysicsTools/NanoAOD/plugins/rntuple/TableOutputFields.h
index 457e00991ff2d..00e9be2e833e3 100644
--- a/PhysicsTools/NanoAOD/plugins/rntuple/TableOutputFields.h
+++ b/PhysicsTools/NanoAOD/plugins/rntuple/TableOutputFields.h
@@ -2,8 +2,9 @@
#define PhysicsTools_NanoAOD_TableOutputFields_h
#include "RNTupleFieldPtr.h"
+#include "RNTupleCollection.h"
-#include "FWCore/Framework/interface/EventForOutput.h"
+#include "FWCore/Framework/interface/OccurrenceForOutput.h"
#include "DataFormats/NanoAOD/interface/FlatTable.h"
#include "FWCore/Utilities/interface/EDGetToken.h"
@@ -11,14 +12,8 @@
#include
#include
-#if ROOT_VERSION_CODE < ROOT_VERSION(6, 31, 0)
-using ROOT::Experimental::RCollectionNTupleWriter;
-#else
-#include
-using ROOT::Experimental::RNTupleCollectionWriter;
-#endif
-using ROOT::Experimental::RNTupleModel;
-using ROOT::Experimental::RNTupleWriter;
+using ROOT::RNTupleModel;
+using ROOT::RNTupleWriter;
template
class FlatTableField {
@@ -70,9 +65,10 @@ class TableOutputFields {
TableOutputFields() = default;
explicit TableOutputFields(const edm::EDGetToken& token) : m_token(token) {}
void print() const;
- void createFields(const edm::EventForOutput& event, RNTupleModel& model);
+ void createFields(const edm::OccurrenceForOutput& event, RNTupleModel& model);
void fillEntry(const nanoaod::FlatTable& table, std::size_t i);
const edm::EDGetToken& getToken() const;
+ const edm::Handle getTable(const edm::OccurrenceForOutput& event) const;
private:
edm::EDGetToken m_token;
@@ -86,8 +82,8 @@ class TableOutputVectorFields {
public:
TableOutputVectorFields() = default;
explicit TableOutputVectorFields(const edm::EDGetToken& token) : m_token(token) {}
- void createFields(const edm::EventForOutput& event, RNTupleModel& model);
- void fill(const edm::EventForOutput& event);
+ void createFields(const edm::OccurrenceForOutput& event, RNTupleModel& model);
+ void fill(const edm::OccurrenceForOutput& event);
private:
edm::EDGetToken m_token;
@@ -107,19 +103,16 @@ class TableCollection {
// Invariants:
// * m_main not null
// * m_collectionName not empty
- void createFields(const edm::EventForOutput& event, RNTupleModel& eventModel);
- void fill(const edm::EventForOutput& event);
+ void createFields(const edm::OccurrenceForOutput& event, RNTupleModel& eventModel);
+ void bindBuffer(RNTupleModel& eventModel);
+ void fill(const edm::OccurrenceForOutput& event);
void print() const;
bool hasMainTable();
const std::string& getCollectionName() const;
private:
std::string m_collectionName;
-#if ROOT_VERSION_CODE < ROOT_VERSION(6, 31, 0)
- std::shared_ptr m_collection;
-#else
- std::shared_ptr m_collection;
-#endif
+ std::unique_ptr m_collection;
TableOutputFields m_main;
std::vector m_extensions;
};
@@ -127,8 +120,9 @@ class TableCollection {
class TableCollectionSet {
public:
void add(const edm::EDGetToken& table_token, const nanoaod::FlatTable& table);
- void createFields(const edm::EventForOutput& event, RNTupleModel& eventModel);
- void fill(const edm::EventForOutput& event);
+ void createFields(const edm::OccurrenceForOutput& event, RNTupleModel& eventModel);
+ void bindBuffers(RNTupleModel& eventModel);
+ void fill(const edm::OccurrenceForOutput& event);
void print() const;
private:
diff --git a/PhysicsTools/NanoAOD/plugins/rntuple/TriggerOutputFields.cc b/PhysicsTools/NanoAOD/plugins/rntuple/TriggerOutputFields.cc
index e1fa1161bf8be..db752038c07e2 100644
--- a/PhysicsTools/NanoAOD/plugins/rntuple/TriggerOutputFields.cc
+++ b/PhysicsTools/NanoAOD/plugins/rntuple/TriggerOutputFields.cc
@@ -13,6 +13,8 @@
#include
+using ROOT::RNTupleModel;
+
namespace {
void trimVersionSuffix(std::string& trigger_name) {
@@ -121,19 +123,14 @@ void TriggerOutputFields::updateTriggerFields(const edm::TriggerResults& trigger
}
}
-void TriggerOutputFields::makeUniqueFieldName(RNTupleModel& model, std::string& name) {
- // Could also use a cache of names in a higher-level object, don't ask the RNTupleModel each time
-#if ROOT_VERSION_CODE < ROOT_VERSION(6, 31, 0)
- auto existing_field = model.Get(name);
-#else
- auto existing_field = model.GetDefaultEntry().GetPtr(name);
-#endif
- if (!existing_field) {
+void TriggerOutputFields::makeUniqueFieldName(const RNTupleModel& model, std::string& name) {
+ bool already_exists = model.GetFieldNames().contains(name);
+
+ if (!already_exists) {
return;
}
- edm::LogWarning("TriggerOutputFields") << "Found a branch with name " << name
- << " already present. Will add suffix _p" << m_processName
- << " to the new branch.\n";
+ edm::LogWarning("TriggerOutputFields") << "Found a field with name " << name << " already present. Will add suffix _p"
+ << m_processName << " to the new field.\n";
name += std::string("_p") + m_processName;
}
diff --git a/PhysicsTools/NanoAOD/plugins/rntuple/TriggerOutputFields.h b/PhysicsTools/NanoAOD/plugins/rntuple/TriggerOutputFields.h
index 592cc51caceb2..3ff026de54d9d 100644
--- a/PhysicsTools/NanoAOD/plugins/rntuple/TriggerOutputFields.h
+++ b/PhysicsTools/NanoAOD/plugins/rntuple/TriggerOutputFields.h
@@ -13,7 +13,7 @@ namespace edm {
class TriggerFieldPtr {
public:
TriggerFieldPtr() = default;
- TriggerFieldPtr(std::string name, int index, std::string fieldName, std::string fieldDesc, RNTupleModel& model);
+ TriggerFieldPtr(std::string name, int index, std::string fieldName, std::string fieldDesc, ROOT::RNTupleModel& model);
void fill(const edm::TriggerResults& triggers);
const std::string& getTriggerName() const { return m_triggerName; }
void setIndex(int newIndex) { m_triggerIndex = newIndex; }
@@ -30,14 +30,14 @@ class TriggerOutputFields {
TriggerOutputFields() = default;
explicit TriggerOutputFields(const std::string& processName, const edm::EDGetToken& token)
: m_token(token), m_lastRun(-1), m_processName(processName) {}
- void createFields(const edm::EventForOutput& event, RNTupleModel& model);
+ void createFields(const edm::EventForOutput& event, ROOT::RNTupleModel& model);
void fill(const edm::EventForOutput& event);
private:
static std::vector getTriggerNames(const edm::TriggerResults& triggerResults);
// Update trigger field information on run boundaries
void updateTriggerFields(const edm::TriggerResults& triggerResults);
- void makeUniqueFieldName(/*const*/ RNTupleModel& model, std::string& name);
+ void makeUniqueFieldName(const ROOT::RNTupleModel& model, std::string& name);
edm::EDGetToken m_token;
long m_lastRun;