gstreamer
Loading...
Searching...
No Matches
gRootTree.cc
Go to the documentation of this file.
1#include "gRootTree.h"
3
4using std::vector;
5
6// Implementation summary:
7// Build ROOT TTrees lazily from sample headers or hits, then clear and refill
8// vector branches on each fill call.
9
10GRootTree::GRootTree([[maybe_unused]] const std::unique_ptr<GEventHeader>& gevent_header,
11 std::shared_ptr<GLogger>& logger) : log(logger) {
12 log->debug(CONSTRUCTOR, "GRootTree", "ROOT tree header");
13
14 root_tree =
16
17 // AutoFlush controls when buffered basket data are pushed to disk.
18 root_tree->SetAutoFlush(20 * 1024 * 1024);
19
20 // AutoSave periodically writes tree metadata snapshots for recoverability.
21 root_tree->SetAutoSave(50 * 1024 * 1024);
22
23 registerVariable("g4localEventNumber", gevent_header->getG4LocalEvn());
24 registerVariable("threadID", gevent_header->getThreadID());
25 registerVariable("timeStamp", gevent_header->getTimeStamp());
26}
27
28// fill the GEventHeader tree
29bool GRootTree::fillTree(const std::unique_ptr<GEventHeader>& gevent_header) {
30 log->info(2, "Filling header tree for local event n. ", gevent_header->getG4LocalEvn(), " threadID ",
31 gevent_header->getThreadID());
32
33 // Clear the vectors backing the branches before writing the next entry.
34 intVarsMap["g4localEventNumber"].clear();
35 intVarsMap["threadID"].clear();
36 stringVarsMap["timeStamp"].clear();
37
38 intVarsMap["g4localEventNumber"].emplace_back(gevent_header->getG4LocalEvn());
39 intVarsMap["threadID"].emplace_back(gevent_header->getThreadID());
40 stringVarsMap["timeStamp"].emplace_back(gevent_header->getTimeStamp());
41
42 root_tree->Fill();
43
44 return true;
45}
46
47// fill the GRunHeader tree
48bool GRootTree::fillTree(const std::unique_ptr<GRunHeader>& grun_header) {
49 log->info(2, "Filling header tree for run n. ", grun_header->getRunID());
50
51 // Clear and refill the vectors backing the run-header branches.
52 intVarsMap["runID"].clear();
53 intVarsMap["runID"].emplace_back(grun_header->getRunID());
54
55 root_tree->Fill();
56
57 return true;
58}
59
60GRootTree::GRootTree([[maybe_unused]] const std::unique_ptr<GRunHeader>& grun_header,
61 std::shared_ptr<GLogger>& logger) : log(logger) {
62 log->debug(CONSTRUCTOR, "GRootTree", "ROOT tree header");
63
64 root_tree =
66 root_tree->SetAutoFlush(20 * 1024 * 1024);
67 root_tree->SetAutoSave(50 * 1024 * 1024);
68
69 registerVariable("runID", grun_header->getRunID());
70}
71
72
73// Implementation summary:
74// Create a true-information detector tree whose branch schema is inferred
75// from the first observed hit.
76GRootTree::GRootTree(const std::string& detectorName,
77 const GTrueInfoData* gdata,
78 std::shared_ptr<GLogger>& logger) : log(logger) {
79 log->debug(CONSTRUCTOR, "GRootTree", "ROOT tree True Info");
80
81 root_tree = std::make_unique<TTree>(detectorName.c_str(), gstreamer::root::TRUEINFOTREENAMEDESC);
82 root_tree->SetAutoFlush(20 * 1024 * 1024);
83 root_tree->SetAutoSave(50 * 1024 * 1024);
84
85 // add identity vars
86 auto identityMap = getIdentityMap(gdata->getIdentity());
87 for (auto& [varname, value] : identityMap) { registerVariable(varname, value); }
88
89 for (auto& [varname, value] : gdata->getDoubleVariablesMap()) { registerVariable(varname, value); }
90 for (auto& [varname, value] : gdata->getStringVariablesMap()) { registerVariable(varname, value); }
91}
92
93GRootTree::GRootTree(const std::string& treeName,
94 [[maybe_unused]] const GGeneratedParticleBank& particles,
95 std::shared_ptr<GLogger>& logger) : log(logger) {
96 log->debug(CONSTRUCTOR, "GRootTree", "ROOT tree Generated Particles");
97
98 root_tree = std::make_unique<TTree>(treeName.c_str(), gstreamer::root::GENERATEDTREENAMEDESC);
99 root_tree->SetAutoFlush(20 * 1024 * 1024);
100 root_tree->SetAutoSave(50 * 1024 * 1024);
101
102 registerVariable("pid", 0);
103 registerVariable("type", 0);
104 registerVariable("multiplicity", 0);
105 registerVariable("p", 0.0);
106 registerVariable("theta", 0.0);
107 registerVariable("phi", 0.0);
108 registerVariable("vx", 0.0);
109 registerVariable("vy", 0.0);
110 registerVariable("vz", 0.0);
111 registerVariable("name", std::string());
112}
113
114GRootTree::GRootTree([[maybe_unused]] const GAncestorBank& ancestors,
115 std::shared_ptr<GLogger>& logger) : log(logger) {
116 log->debug(CONSTRUCTOR, "GRootTree", "ROOT tree Ancestors");
118 root_tree->SetAutoFlush(20 * 1024 * 1024);
119 root_tree->SetAutoSave(50 * 1024 * 1024);
120
121 registerVariable("pid", 0);
122 registerVariable("tid", 0);
123 registerVariable("mtid", 0);
124 registerVariable("trackE", 0.0);
125 registerVariable("px", 0.0);
126 registerVariable("py", 0.0);
127 registerVariable("pz", 0.0);
128 registerVariable("vx", 0.0);
129 registerVariable("vy", 0.0);
130 registerVariable("vz", 0.0);
131}
132
133
134// Implementation summary:
135// Create a digitized detector tree whose branch schema is inferred
136// from the first observed hit.
137GRootTree::GRootTree(const std::string& detectorName,
138 const GDigitizedData* gdata,
139 std::shared_ptr<GLogger>& logger) : log(logger) {
140 log->debug(CONSTRUCTOR, "GRootTree", "ROOT tree Digitized Data");
141
142 root_tree = std::make_unique<TTree>(detectorName.c_str(), gstreamer::root::DIGITIZEDTREENAMEDESC);
143 root_tree->SetAutoFlush(20 * 1024 * 1024);
144 root_tree->SetAutoSave(50 * 1024 * 1024);
145
146 // add identity vars
147 auto identityMap = getIdentityMap(gdata->getIdentity());
148 for (auto& [varname, value] : identityMap) { registerVariable(varname, value, true); }
149
150 for (auto& [varname, value] : gdata->getIntObservablesMap(0)) {
151 registerVariable(varname, value);
152 }
153 for (auto& [varname, value] : gdata->getDblObservablesMap(0)) { registerVariable(varname, value); }
154}
155
156
157// fill the True Info Tree
158bool GRootTree::fillTree(const std::vector<const GTrueInfoData*>& trueInfoData) {
159 // Reset all branch vectors before repopulating them for this detector collection.
160 for (auto& [varname, values] : intVarsMap) { values.clear(); }
161 for (auto& [varname, values] : doubleVarsMap) { values.clear(); }
162 for (auto& [varname, values] : stringVarsMap) { values.clear(); }
163
164
165 for (auto& dataHits : trueInfoData) {
166 // fill identity vars
167 auto identityMap = getIdentityMap(dataHits->getIdentity());
168 for (auto& [varname, value] : identityMap) {
169 intVarsMap[varname].push_back(value);
170 }
171
172 for (auto& [varname, value] : dataHits->getDoubleVariablesMap()) { doubleVarsMap[varname].push_back(value); }
173 for (auto& [varname, value] : dataHits->getStringVariablesMap()) { stringVarsMap[varname].push_back(value); }
174 }
175
176 root_tree->Fill();
177
178 return true;
179}
180
181// fill the Digitized Data Tree
182bool GRootTree::fillTree(const std::vector<const GDigitizedData*>& digitizedData) {
183 // Reset all branch vectors before repopulating them for this detector collection.
184 for (auto& [varname, values] : intVarsMap) { values.clear(); }
185 for (auto& [varname, values] : doubleVarsMap) { values.clear(); }
186 for (auto& [varname, values] : stringVarsMap) { values.clear(); }
187
188
189 for (auto& dataHits : digitizedData) {
190 // fill identity vars
191 auto identityMap = getIdentityMap(dataHits->getIdentity());
192 for (auto& [varname, value] : identityMap) {
193 intVarsMap[varname].push_back(value);
194 }
195
196
197 for (auto& [varname, value] : dataHits->getIntObservablesMap(0)) { intVarsMap[varname].push_back(value); }
198 for (auto& [varname, value] : dataHits->getDblObservablesMap(0)) { doubleVarsMap[varname].push_back(value); }
199 }
200 root_tree->Fill();
201
202 return true;
203}
204
206 for (auto& [varname, values] : intVarsMap) { values.clear(); }
207 for (auto& [varname, values] : doubleVarsMap) { values.clear(); }
208 for (auto& [varname, values] : stringVarsMap) { values.clear(); }
209
210 for (const auto& particle : particles) {
211 intVarsMap["pid"].push_back(particle.pid);
212 intVarsMap["type"].push_back(particle.type);
213 intVarsMap["multiplicity"].push_back(particle.multiplicity);
214 doubleVarsMap["p"].push_back(particle.p);
215 doubleVarsMap["theta"].push_back(particle.theta);
216 doubleVarsMap["phi"].push_back(particle.phi);
217 doubleVarsMap["vx"].push_back(particle.vx);
218 doubleVarsMap["vy"].push_back(particle.vy);
219 doubleVarsMap["vz"].push_back(particle.vz);
220 stringVarsMap["name"].push_back(particle.name);
221 }
222
223 root_tree->Fill();
224 return true;
225}
226
227bool GRootTree::fillTree(const GAncestorBank& ancestors) {
228 for (auto& [varname, values] : intVarsMap) { values.clear(); }
229 for (auto& [varname, values] : doubleVarsMap) { values.clear(); }
230
231 for (const auto& ancestor : ancestors) {
232 intVarsMap["pid"].push_back(ancestor.pid);
233 intVarsMap["tid"].push_back(ancestor.tid);
234 intVarsMap["mtid"].push_back(ancestor.mtid);
235 doubleVarsMap["trackE"].push_back(ancestor.trackE);
236 doubleVarsMap["px"].push_back(ancestor.px);
237 doubleVarsMap["py"].push_back(ancestor.py);
238 doubleVarsMap["pz"].push_back(ancestor.pz);
239 doubleVarsMap["vx"].push_back(ancestor.vx);
240 doubleVarsMap["vy"].push_back(ancestor.vy);
241 doubleVarsMap["vz"].push_back(ancestor.vz);
242 }
243
244 root_tree->Fill();
245 return true;
246}
247
248
249// Implementation summary:
250// Register one branch and bind it to the appropriate backing vector map.
251// The second parameter is used only to select the correct overload.
252
253void GRootTree::registerVariable(const std::string& varname, [[maybe_unused]] int value,
254 bool can_ignore_duplicates) {
255 if (can_ignore_duplicates) {
256 root_tree->Branch(varname.c_str(), &intVarsMap[varname]);
257 }
258 else {
259 if (intVarsMap.find(varname) == intVarsMap.end()) {
260 root_tree->Branch(varname.c_str(), &intVarsMap[varname]);
261 }
262 else {
263 log->error(gstreamer::ERR_GSTREAMERVARIABLEEXISTS, "variable <", varname,
264 "> already registered in the int variable map of tree ", root_tree->GetName());
265 }
266 }
267}
268
269void GRootTree::registerVariable(const std::string& varname, [[maybe_unused]] double value) {
270 if (doubleVarsMap.find(varname) == doubleVarsMap.end()) {
271 root_tree->Branch(varname.c_str(), &doubleVarsMap[varname]);
272 }
273 else {
274 log->error(gstreamer::ERR_GSTREAMERVARIABLEEXISTS, "variable <", varname,
275 "> already registered in the double variable map of tree ", root_tree->GetName());
276 }
277}
278
279void GRootTree::registerVariable(const std::string& varname, [[maybe_unused]] const std::string& value) {
280 if (stringVarsMap.find(varname) == stringVarsMap.end()) {
281 root_tree->Branch(varname.c_str(), &stringVarsMap[varname]);
282 }
283 else {
284 log->error(gstreamer::ERR_GSTREAMERVARIABLEEXISTS, "variable <", varname,
285 "> already registered in the string variable map of tree ", root_tree->GetName());
286 }
287}
const std::vector< GIdentifier > & getIdentity() const
std::map< std::string, int > getIntObservablesMap(int which) const
std::map< std::string, double > getDblObservablesMap(int which) const
GRootTree(const std::unique_ptr< GEventHeader > &gevent_header, std::shared_ptr< GLogger > &log)
Construct an event-header tree and register its branches.
Definition gRootTree.cc:10
bool fillTree(const std::unique_ptr< GEventHeader > &gevent_header)
Fill the event-header tree with one event header entry.
Definition gRootTree.cc:29
std::map< std::string, double > getDoubleVariablesMap() const
const std::vector< GIdentifier > & getIdentity() const
std::map< std::string, std::string > getStringVariablesMap() const
std::vector< GAncestorData > GAncestorBank
std::vector< GGeneratedParticleData > GGeneratedParticleBank
ROOT tree adapter used internally by the ROOT gstreamer plugin.
std::map< std::string, int > getIdentityMap(std::vector< GIdentifier > gidentity)
CONSTRUCTOR
Shared constants and error codes for the gstreamer module.
constexpr char RUNHEADERTREENAMEDESC[]
Definition gRootTree.h:24
constexpr char GENERATEDTREENAMEDESC[]
Definition gRootTree.h:19
constexpr char RUNHEADERTREENAME[]
Definition gRootTree.h:16
constexpr char EVENTHEADERTREENAME[]
Definition gRootTree.h:15
constexpr char ANCESTORTREENAMEDESC[]
Definition gRootTree.h:21
constexpr char EVENTHEADERTREENAMEDESC[]
Definition gRootTree.h:23
constexpr char TRUEINFOTREENAMEDESC[]
Definition gRootTree.h:25
constexpr char ANCESTORTREENAME[]
Definition gRootTree.h:20
constexpr char DIGITIZEDTREENAMEDESC[]
Definition gRootTree.h:26
constexpr int ERR_GSTREAMERVARIABLEEXISTS
Duplicate variable registration was attempted in a streamer-specific schema.