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