Project
Loading...
Searching...
No Matches
VisualisationEventROOTSerializer.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
16
18#include <fairlogger/Logger.h>
19#include <iostream>
20
21#include <TFile.h>
22#include <TTree.h>
23#include <TKey.h>
24#include <TParameter.h>
25#include <TNtuple.h>
26
27namespace o2
28{
29namespace event_visualisation
30{
31constexpr int ROOT_FILE_VERSION = 1;
32
33void VisualisationEventROOTSerializer::save(const char* name, const std::string& value)
34{
35 TNamed obj(name, value);
36 obj.Write();
37}
38
39std::string VisualisationEventROOTSerializer::readString(TFile& f, const char* name)
40{
41 auto* v = (TNamed*)f.Get(name);
42 if (v == nullptr) {
43 return "";
44 }
45 std::string result = v->GetTitle();
46 free(v);
47 return result;
48}
49
50void VisualisationEventROOTSerializer::saveInt(const char* name, int value)
51{
52 TParameter<int> obj;
53 obj.SetVal(value);
54 obj.Write(name);
55}
56
57void VisualisationEventROOTSerializer::saveUInt64(const char* name, uint64_t value)
58{
59 TParameter<long> obj;
60 obj.SetVal((long)value);
61 obj.Write(name);
62}
63
64int VisualisationEventROOTSerializer::readInt(TFile& f, const char* name)
65{
66 auto v = (TParameter<int>*)f.Get(name);
67 if (v == nullptr) {
68 return 0;
69 }
70 int result = v->GetVal();
71 free(v);
72 return result;
73}
74
75uint64_t VisualisationEventROOTSerializer::readUInt64(TFile& f, const char* name)
76{
77 auto v = (TParameter<uint64_t>*)f.Get(name);
78 if (v == nullptr) {
79 return 0;
80 }
81 uint64_t result = v->GetVal();
82 free(v);
83 return result;
84}
85
86bool VisualisationEventROOTSerializer::existUInt64(TFile& f, const char* name)
87{
88 auto v = (TParameter<uint64_t>*)f.Get(name);
89 if (v == nullptr) {
90 return false;
91 }
92 free(v);
93 return true;
94}
95
97{
98 std::string fileName = location.fileName();
99 TFile f(fileName.c_str(), "recreate");
100 if (f.IsZombie()) {
101 LOGF(error, "Could not create output file %s", fileName.c_str());
102 return;
103 }
104
105 saveInt("runNumber", event.mRunNumber);
106 saveInt("runType", event.mRunType);
107 saveInt("clMask", event.mClMask);
108 saveInt("trkMask", event.mTrkMask);
109 saveInt("tfCounter", event.mTfCounter);
110 saveInt("firstTForbit", event.mFirstTForbit);
111 saveInt("primaryVertex", event.mPrimaryVertex);
112 saveUInt64("creationTime", event.mCreationTime);
113 std::string version = std::to_string(event.mEveVersion / 100.0);
114 save("eveVersion", version); // obsolete
115 saveInt("version", event.mEveVersion);
116 // save("workflowParameters", event.mWorkflowParameters);
117
118 // clusters
119 TNtuple xyz("xyz", "xyz", "x:y:z");
120 long xyzPos = 0L;
121
122 TTree clusters("clusters", "Clusters");
123 long cluster_xyz;
124 unsigned cluster_bgid;
125 float cluster_time;
126 clusters.Branch("BGID", &cluster_bgid);
127 clusters.Branch("time", &cluster_time);
128 clusters.Branch("xyz", &cluster_xyz);
129 for (auto cluster : event.getClustersSpan()) {
130 cluster_time = cluster.Time();
131 cluster_bgid = serialize(cluster.mBGID);
132 cluster_xyz = xyzPos;
133 xyz.Fill(cluster.X(), cluster.Y(), cluster.Z());
134 xyzPos++;
135 clusters.Fill();
136 }
137
138 // Tracks
139 long track_xyz; // first track point
140 int track_points; // number of track points
141 int track_clusters; // number of track clusters
142 unsigned track_BGID; // binary GID
143 float track_time;
144 int track_charge;
145 float track_theta;
146 float track_phi;
147 float track_eta;
148 int track_PID;
149
150 TTree tracks("tracks", "Tracks");
151 tracks.Branch("xyz", &track_xyz);
152 tracks.Branch("time", &track_time);
153 tracks.Branch("charge", &track_charge);
154 tracks.Branch("theta", &track_theta);
155 tracks.Branch("phi", &track_phi);
156 tracks.Branch("eta", &track_eta);
157 tracks.Branch("PID", &track_PID);
158 tracks.Branch("BGID", &track_BGID);
159 tracks.Branch("points", &track_points);
160 tracks.Branch("clusters", &track_clusters);
161
162 for (auto track : event.getTracksSpan()) {
163 track_xyz = xyzPos;
164 track_time = std::isnan(track.mTime) ? 0 : track.mTime;
165 track_charge = track.mCharge;
166 track_theta = std::isnan(track.mTheta) ? 0 : track.mTheta;
167 track_phi = std::isnan(track.mPhi) ? 0 : track.mPhi;
168 track_eta = std::isnan(track.mEta) ? 0 : track.mEta;
169 track_PID = track.mPID;
170 track_BGID = serialize(track.mBGID);
171
172 xyz.Fill(track.mStartCoordinates[0], track.mStartCoordinates[1], track.mStartCoordinates[2]);
173 xyzPos++;
174 track_points = track.getPointCount();
175
176 for (size_t i = 0; i < track.getPointCount(); i++) {
177 xyz.Fill(track.mPolyX[i], track.mPolyY[i], track.mPolyZ[i]);
178 xyzPos++;
179 }
180 track_clusters = track.getClusterCount();
181 for (auto cluster : track.getClustersSpan()) {
182 xyz.Fill(cluster.X(), cluster.Y(), cluster.Z());
183 xyzPos++;
184 }
185 tracks.Fill();
186 }
187
188 clusters.Write();
189
190 // calorimeters
191 TTree calo("calo", "Calorimeters");
192 float calo_time;
193 float calo_energy;
194 float calo_eta;
195 float calo_phi;
196 int calo_PID;
197 unsigned calo_BGID;
198
199 calo.Branch("time", &calo_time);
200 calo.Branch("energy", &calo_energy);
201 calo.Branch("eta", &calo_eta);
202 calo.Branch("phi", &calo_phi);
203 calo.Branch("BGID", &calo_BGID);
204 calo.Branch("PID", &calo_PID);
205
206 for (const auto& calorimeter : event.getCalorimetersSpan()) {
207 calo_time = calorimeter.getTime();
208 calo_energy = calorimeter.getEnergy();
209 calo_eta = calorimeter.getEta();
210 calo_phi = calorimeter.getPhi();
211 calo_BGID = serialize(calorimeter.mBGID);
212 calo_PID = calorimeter.getPID();
213 calo.Fill();
214 }
215 calo.Write();
216
217 tracks.Write();
218
219 xyz.Write();
220}
221
223{
224 // LOGF(info, "VisualisationEventROOTSerializer <- %s ", fileName);
225 event.mTracks.clear();
226 event.mClusters.clear();
227 event.mCalo.clear();
228
229 TFile f(fileName.c_str());
230
231 event.setRunNumber(readInt(f, "runNumber"));
232 event.setRunType(static_cast<parameters::GRPECS::RunType>(readInt(f, "runType")));
233 event.setClMask(readInt(f, "clMask"));
234 event.setTrkMask(readInt(f, "trkMask"));
235 event.setTfCounter(readInt(f, "tfCounter"));
236 event.setFirstTForbit(readInt(f, "firstTForbit"));
237 event.mPrimaryVertex = readInt(f, "primaryVertex");
238
239 if (existUInt64(f, "creationTime")) {
240 event.setCreationTime(readInt(f, "creationTime"));
241 } else {
242 auto collisionTime = readString(f, "collisionTime");
243 event.mCreationTime = parseDateTime(collisionTime.c_str());
244 }
245
246 event.mEveVersion = 0;
247 if (f.Get("version") != nullptr) {
248 event.mEveVersion = readInt(f, "version");
249 } else {
250 std::string version = readString(f, "eveVersion");
251 event.mEveVersion = (int)(100 * std::stof(version));
252 }
253
254 // xyz
255 auto* xyz = (TNtuple*)f.Get("xyz");
256 if (xyz == nullptr) {
257 return false;
258 }
259
260 // tracks
261 auto* tracks = (TTree*)f.Get("tracks");
262 if (tracks == nullptr) {
263 delete xyz;
264 return false;
265 }
266
267 long track_xyz; // first track point
268 int track_points; // number of track points
269 int track_clusters; // number of track clusters
270 int track_source; // obsolete
271 std::string* track_GID = nullptr;
272 unsigned track_BGID;
273 float track_time;
274 int track_charge;
275 float track_theta;
276 float track_phi;
277 float track_eta;
278 int track_PID;
279
280 tracks->SetBranchAddress("xyz", &track_xyz);
281 tracks->SetBranchAddress("time", &track_time);
282 tracks->SetBranchAddress("charge", &track_charge);
283 tracks->SetBranchAddress("theta", &track_theta);
284 tracks->SetBranchAddress("phi", &track_phi);
285 tracks->SetBranchAddress("eta", &track_eta);
286 tracks->SetBranchAddress("PID", &track_PID);
287 auto gid = tracks->GetBranch("GID"); // obsolete
288 if (gid != nullptr) {
289 tracks->SetBranchAddress("GID", &track_GID);
290 }
291 auto bgid = tracks->GetBranch("BGID");
292 if (bgid != nullptr) {
293 tracks->SetBranchAddress("BGID", &track_BGID);
294 }
295 auto source = tracks->GetBranch("source"); // obsolete
296 if (source != nullptr) {
297 tracks->SetBranchAddress("source", &track_source);
298 }
299 tracks->SetBranchAddress("points", &track_points);
300 tracks->SetBranchAddress("clusters", &track_clusters);
301
302 auto tracksNoOfEntries = (Int_t)tracks->GetEntries();
303 for (Int_t i = 0; i < tracksNoOfEntries; i++) {
304 tracks->GetEntry(i);
305 VisualisationTrack track;
306 track.mTime = track_time;
307 track.mCharge = track_charge;
308 track.mTheta = track_theta;
309 track.mPhi = track_phi;
310 track.mEta = track_eta;
311 track.mPID = track_PID;
312 if (bgid) {
313 track.mBGID = deserialize(track_BGID);
314 } else {
315 track.mBGID = gidFromString(*track_GID);
316 }
317 xyz->GetEntry(track_xyz);
318 track.addStartCoordinates(xyz->GetArgs());
319 for (int p = 0; p < track_points; p++) {
320 xyz->GetEntry(track_xyz + 1 + p);
321 track.addPolyPoint(xyz->GetArgs());
322 }
323 for (size_t it = 0; it < track_clusters; it++) {
324 xyz->GetEntry(track_xyz + 1 + track_points + it);
325 VisualisationCluster cluster(xyz->GetArgs(), track.mTime, track.mBGID);
326 track.mClusters.emplace_back(cluster);
327 }
328 event.mTracks.emplace_back(track);
329 }
330
331 if (gid != nullptr) {
332 delete track_GID;
333 track_GID = nullptr;
334 }
335
336 if (!readClusters(event, f, xyz)) {
337 delete xyz;
338 delete tracks;
339 return false;
340 }
341
342 if (!readCalo(event, f)) {
343 delete xyz;
344 delete tracks;
345 return false;
346 }
347
348 delete tracks;
349 delete xyz;
350
351 event.afterLoading();
352 return true;
353}
354
355bool VisualisationEventROOTSerializer::readClusters(VisualisationEvent& event, TFile& f, TNtuple* xyz)
356{
357 auto* clusters = (TTree*)f.Get("clusters");
358 if (clusters == nullptr) {
359 return false;
360 }
361
362 long cluster_xyz;
363 int cluster_source;
364 unsigned cluster_BGID;
365
366 float cluster_time;
367 auto source = clusters->GetBranch("source"); // obsolete
368 if (source != nullptr) {
369 clusters->SetBranchAddress("source", &cluster_source);
370 }
371
372 auto bgid = clusters->GetBranch("BGID");
373 if (bgid != nullptr) {
374 clusters->SetBranchAddress("BGID", &cluster_BGID);
375 }
376
377 clusters->SetBranchAddress("time", &cluster_time);
378 clusters->SetBranchAddress("xyz", &cluster_xyz);
379 auto clustersNoOfEntries = (Int_t)clusters->GetEntries();
380 for (Int_t i = 0; i < clustersNoOfEntries; i++) {
381 clusters->GetEntry(i);
382 xyz->GetEntry(cluster_xyz);
383 dataformats::GlobalTrackID gid = 0;
384 if (bgid) {
385 gid = deserialize(cluster_BGID);
386 } else if (source) {
387 gid = deserialize(cluster_source, 0, 0);
388 }
389 VisualisationCluster cluster(xyz->GetArgs(), cluster_time, gid);
390 event.mClusters.emplace_back(cluster);
391 }
392 delete clusters;
393 return true;
394}
395
396bool VisualisationEventROOTSerializer::readCalo(VisualisationEvent& event, TFile& f)
397{
398 auto* calo = (TTree*)f.Get("calo");
399 if (calo == nullptr) {
400 return false;
401 }
402
403 int calo_source;
404 float calo_time;
405 float calo_energy;
406 float calo_eta;
407 float calo_phi;
408 unsigned calo_BGID;
409 int calo_PID;
410
411 auto source = calo->GetBranch("source");
412 if (source != nullptr) {
413 calo->SetBranchAddress("source", &calo_source);
414 }
415 auto bgid = calo->GetBranch("BGID");
416 if (bgid != nullptr) {
417 calo->SetBranchAddress("BGID", &calo_BGID);
418 }
419
420 calo->SetBranchAddress("time", &calo_time);
421 calo->SetBranchAddress("energy", &calo_energy);
422 calo->SetBranchAddress("eta", &calo_eta);
423 calo->SetBranchAddress("phi", &calo_phi);
424 calo->SetBranchAddress("PID", &calo_PID);
425
426 auto nentries = (Int_t)calo->GetEntries();
427 for (Int_t i = 0; i < nentries; i++) {
428 calo->GetEntry(i);
429 VisualisationCalo calorimeter;
430 calorimeter.mTime = calo_time;
431 calorimeter.mEnergy = calo_energy;
432 calorimeter.mEta = calo_eta;
433 calorimeter.mPhi = calo_phi;
434 if (bgid) {
435 calorimeter.mBGID = deserialize(calo_BGID);
436 } else {
437 calorimeter.mBGID = deserialize(calo_source, 0, 0);
438 }
439 calorimeter.mPID = calo_PID;
440 event.mCalo.emplace_back(calorimeter);
441 }
442 delete calo;
443 return true;
444}
445
446} // namespace event_visualisation
447} // namespace o2
int32_t i
bool fromFile(VisualisationEvent &event, std::string fileName) override
void toFile(const VisualisationEvent &event, Location &location) override
static unsigned serialize(o2::dataformats::GlobalTrackID gidValue)
static o2::dataformats::GlobalTrackID deserialize(unsigned seralizedValue)
static o2::dataformats::GlobalTrackID gidFromString(const std::string &gid)
void addPolyPoint(float x, float y, float z)
struct _cl_event * event
Definition glcorearb.h:2982
GLuint64EXT * result
Definition glcorearb.h:5662
const GLdouble * v
Definition glcorearb.h:832
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
GLsizei GLsizei GLchar * source
Definition glcorearb.h:798
GLsizei const GLfloat * value
Definition glcorearb.h:819
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
std::vector< Cluster > clusters