PODIO v00-16-03
An Event-Data-Model Toolkit for High Energy Physics Experiments
Loading...
Searching...
No Matches
ROOTFrameWriter.cc
Go to the documentation of this file.
3#include "podio/Frame.h"
5#include "podio/podioVersion.h"
6
7#include "rootUtils.h"
8
9#include "TTree.h"
10
11namespace podio {
12
13ROOTFrameWriter::ROOTFrameWriter(const std::string& filename) {
14 m_file = std::make_unique<TFile>(filename.c_str(), "recreate");
15}
16
17void ROOTFrameWriter::writeFrame(const podio::Frame& frame, const std::string& category) {
18 writeFrame(frame, category, frame.getAvailableCollections());
19}
20
21void ROOTFrameWriter::writeFrame(const podio::Frame& frame, const std::string& category,
22 const std::vector<std::string>& collsToWrite) {
23 auto& catInfo = getCategoryInfo(category);
24 // Use the TTree as proxy here to decide whether this category has already
25 // been initialized
26 if (catInfo.tree == nullptr) {
27 catInfo.idTable = frame.getCollectionIDTableForWrite();
28 catInfo.collsToWrite = collsToWrite;
29 catInfo.tree = new TTree(category.c_str(), (category + " data tree").c_str());
30 catInfo.tree->SetDirectory(m_file.get());
31 }
32
33 std::vector<StoreCollection> collections;
34 collections.reserve(catInfo.collsToWrite.size());
35 for (const auto& name : catInfo.collsToWrite) {
36 auto* coll = frame.getCollectionForWrite(name);
37 collections.emplace_back(name, const_cast<podio::CollectionBase*>(coll));
38
39 m_datamodelCollector.registerDatamodelDefinition(coll, name);
40 }
41
42 // We will at least have a parameters branch, even if there are no
43 // collections
44 if (catInfo.branches.empty()) {
45 initBranches(catInfo, collections, const_cast<podio::GenericParameters&>(frame.getParameters()));
46
47 } else {
48 resetBranches(catInfo.branches, collections, &const_cast<podio::GenericParameters&>(frame.getParameters()));
49 }
50
51 catInfo.tree->Fill();
52}
53
54ROOTFrameWriter::CategoryInfo& ROOTFrameWriter::getCategoryInfo(const std::string& category) {
55 if (auto it = m_categories.find(category); it != m_categories.end()) {
56 return it->second;
57 }
58
59 auto [it, _] = m_categories.try_emplace(category, CategoryInfo{});
60 return it->second;
61}
62
63void ROOTFrameWriter::initBranches(CategoryInfo& catInfo, const std::vector<StoreCollection>& collections,
64 /*const*/ podio::GenericParameters& parameters) {
65 catInfo.branches.reserve(collections.size() + 1); // collections + parameters
66
67 // First collections
68 for (auto& [name, coll] : collections) {
69 root_utils::CollectionBranches branches;
70 const auto buffers = coll->getBuffers();
71
72 // data buffer branch, only for non-subset collections
73 if (buffers.data) {
74 auto bufferDataType = "vector<" + coll->getDataTypeName() + ">";
75 branches.data = catInfo.tree->Branch(name.c_str(), bufferDataType.c_str(), buffers.data);
76 }
77
78 // reference collections
79 if (auto refColls = buffers.references) {
80 int i = 0;
81 for (auto& c : (*refColls)) {
82 const auto brName = root_utils::refBranch(name, i++);
83 branches.refs.push_back(catInfo.tree->Branch(brName.c_str(), c.get()));
84 }
85 }
86
87 // vector members
88 if (auto vmInfo = buffers.vectorMembers) {
89 int i = 0;
90 for (auto& [type, vec] : (*vmInfo)) {
91 const auto typeName = "vector<" + type + ">";
92 const auto brName = root_utils::vecBranch(name, i++);
93 branches.vecs.push_back(catInfo.tree->Branch(brName.c_str(), typeName.c_str(), vec));
94 }
95 }
96
97 catInfo.branches.push_back(branches);
98 catInfo.collInfo.emplace_back(catInfo.idTable.collectionID(name), coll->getTypeName(), coll->isSubsetCollection());
99 }
100
101 // Also make branches for the parameters
102 root_utils::CollectionBranches branches;
103 branches.data = catInfo.tree->Branch(root_utils::paramBranchName, &parameters);
104 catInfo.branches.push_back(branches);
105}
106
107void ROOTFrameWriter::resetBranches(std::vector<root_utils::CollectionBranches>& branches,
108 const std::vector<ROOTFrameWriter::StoreCollection>& collections,
109 /*const*/ podio::GenericParameters* parameters) {
110 size_t iColl = 0;
111 for (auto& coll : collections) {
112 const auto& collBranches = branches[iColl];
113 root_utils::setCollectionAddresses(coll.second->getBuffers(), collBranches);
114 iColl++;
115 }
116
117 branches.back().data->SetAddress(&parameters);
118}
119
121 auto* metaTree = new TTree(root_utils::metaTreeName, "metadata tree for podio I/O functionality");
122 metaTree->SetDirectory(m_file.get());
123
124 // Store the collection id table and collection info for reading in the meta tree
125 for (/*const*/ auto& [category, info] : m_categories) {
126 metaTree->Branch(root_utils::idTableName(category).c_str(), &info.idTable);
127 metaTree->Branch(root_utils::collInfoName(category).c_str(), &info.collInfo);
128 }
129
130 // Store the current podio build version into the meta data tree
131 auto podioVersion = podio::version::build_version;
132 metaTree->Branch(root_utils::versionBranchName, &podioVersion);
133
134 auto edmDefinitions = m_datamodelCollector.getDatamodelDefinitionsToWrite();
135 metaTree->Branch(root_utils::edmDefBranchName, &edmDefinitions);
136
137 metaTree->Fill();
138
139 m_file->Write();
140 m_file->Close();
141}
142
143} // namespace podio
std::vector< std::tuple< std::string, std::string > > getDatamodelDefinitionsToWrite() const
Get all the names and JSON definitions that need to be written.
void registerDatamodelDefinition(const podio::CollectionBase *coll, const std::string &name)
podio::CollectionIDTable getCollectionIDTableForWrite() const
Definition: Frame.h:278
std::vector< std::string > getAvailableCollections() const
Definition: Frame.h:252
const podio::GenericParameters & getParameters() const
Definition: Frame.h:238
const podio::CollectionBase * getCollectionForWrite(const std::string &name) const
Definition: Frame.h:269
ROOTFrameWriter(const std::string &filename)
void writeFrame(const podio::Frame &frame, const std::string &category)
std::string refBranch(const std::string &name, size_t index)
Definition: rootUtils.h:75
std::string vecBranch(const std::string &name, size_t index)
Definition: rootUtils.h:79
void setCollectionAddresses(const BufferT &collBuffers, const CollectionBranches &branches)
Definition: rootUtils.h:84
std::string idTableName(const std::string &category)
Definition: rootUtils.h:49
std::string collInfoName(const std::string &category)
Definition: rootUtils.h:58