Project
Loading...
Searching...
No Matches
VisualisationEventJSONSerializer.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#include <iomanip>
22
23#include "rapidjson/document.h"
24#include "rapidjson/prettywriter.h"
25#include "rapidjson/stringbuffer.h"
26
27using namespace rapidjson;
28
30{
31
33{
34 std::string json = toJson(event);
35 std::ofstream out(fileName);
36 out << json;
37 out.close();
38}
39
41{
42 LOGF(info, "VisualisationEventJSONSerializer <- %s", fileName);
43 if (FILE* file = fopen(fileName.c_str(), "r")) {
44 fclose(file); // file exists
45 } else {
46 return false;
47 }
48 std::ifstream inFile;
49 inFile.open(fileName);
50
51 std::stringstream strStream;
52 strStream << inFile.rdbuf(); // read the file
53 inFile.close();
54 std::string str = strStream.str(); // str holds the content of the file
55 fromJson(event, str);
56 return true;
57}
58
59std::string VisualisationEventJSONSerializer::toJson(const VisualisationEvent& event) const
60{
61 Document tree(kObjectType);
62 Document::AllocatorType& allocator = tree.GetAllocator();
63
64 // compatibility verification
65 tree.AddMember("runNumber", rapidjson::Value().SetInt(event.mRunNumber), allocator);
66 tree.AddMember("runType", rapidjson::Value().SetInt(event.mRunType), allocator);
67 tree.AddMember("clMask", rapidjson::Value().SetInt(event.mClMask), allocator);
68 tree.AddMember("trkMask", rapidjson::Value().SetInt(event.mTrkMask), allocator);
69 tree.AddMember("tfCounter", rapidjson::Value().SetInt(event.mTfCounter), allocator);
70 tree.AddMember("firstTForbit", rapidjson::Value().SetInt(event.mFirstTForbit), allocator);
71 tree.AddMember("primaryVertex", rapidjson::Value().SetInt(event.mPrimaryVertex), allocator);
72 std::string collisionTime = DateTime(event.mCreationTime);
73 tree.AddMember("collisionTime", rapidjson::Value().SetString(collisionTime.c_str(), collisionTime.size()), allocator);
74 tree.AddMember("creationTime", rapidjson::Value().SetUint64(event.mCreationTime), allocator);
75 tree.AddMember("version", rapidjson::Value().SetUint64(event.mEveVersion), allocator);
76 std::string version = std::to_string(event.mEveVersion / 100.0);
77 version = version.substr(0, version.find('.') + 3);
78 tree.AddMember("eveVersion", rapidjson::Value().SetString(version.c_str(), version.size()), allocator); // obsolete
79 std::string workflowParameters = collisionTime + " t:" + bits(event.mTrkMask) + " c:" + bits(event.mClMask);
80 tree.AddMember("workflowParameters", rapidjson::Value().SetString(workflowParameters.c_str(), workflowParameters.size()), allocator);
81 // Tracks
82 tree.AddMember("trackCount", rapidjson::Value().SetInt(event.getTrackCount()), allocator);
83
84 Value jsonTracks(kArrayType);
85 for (auto track : event.getTracksSpan()) {
86 jsonTracks.PushBack(jsonTree(track, allocator), allocator);
87 }
88 tree.AddMember("mTracks", jsonTracks, allocator);
89
90 // Clusters
91 rapidjson::Value clusterCount(rapidjson::kNumberType);
92 clusterCount.SetInt(event.getClusterCount());
93 tree.AddMember("clusterCount", clusterCount, allocator);
94 Value jsonClusters(kArrayType);
95 for (auto cluster : event.getClustersSpan()) {
96 jsonClusters.PushBack(jsonTree(cluster, allocator, nullptr), allocator);
97 }
98 tree.AddMember("mClusters", jsonClusters, allocator);
99
100 // Calorimeters
101 rapidjson::Value caloCount(rapidjson::kNumberType);
102 caloCount.SetInt(event.getCaloCount());
103 tree.AddMember("caloCount", caloCount, allocator);
104 Value jsonCalos(kArrayType);
105 for (auto calo : event.getCalorimetersSpan()) {
106 jsonCalos.PushBack(jsonTree(calo, allocator), allocator);
107 }
108 tree.AddMember("mCalo", jsonCalos, allocator);
109
110 // stringify
111 rapidjson::StringBuffer buffer;
112 rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
113 tree.Accept(writer);
114 std::string json_str = std::string(buffer.GetString(), buffer.GetSize());
115 return json_str;
116}
117
118int VisualisationEventJSONSerializer::getIntOrDefault(rapidjson::Value& tree, const char* key, int defaultValue)
119{
120 if (tree.HasMember(key)) {
121 rapidjson::Value& jsonValue = tree[key];
122 return jsonValue.GetInt();
123 }
124 return defaultValue;
125}
126uint64_t VisualisationEventJSONSerializer::getUIntOrDefault(Value& tree, const char* key, uint64_t defaultValue)
127{
128 if (tree.HasMember(key)) {
129 rapidjson::Value& jsonValue = tree[key];
130 return jsonValue.GetUint64();
131 }
132 return defaultValue;
133}
134
135float VisualisationEventJSONSerializer::getFloatOrDefault(rapidjson::Value& tree, const char* key, float defaultValue)
136{
137 if (tree.HasMember(key)) {
138 rapidjson::Value& jsonValue = tree[key];
139 return jsonValue.GetFloat();
140 }
141 return defaultValue;
142}
143
144std::string VisualisationEventJSONSerializer::getStringOrDefault(rapidjson::Value& tree, const char* key, const char* defaultValue)
145{
146 if (tree.HasMember(key)) {
147 rapidjson::Value& jsonValue = tree[key];
148 return jsonValue.GetString();
149 }
150 return defaultValue;
151}
152
153void VisualisationEventJSONSerializer::fromJson(VisualisationEvent& event, std::string json)
154{
155 event.mTracks.clear();
156 event.mClusters.clear();
157 event.mCalo.clear();
158
159 rapidjson::Document tree;
160 tree.Parse(json.c_str());
161
162 event.setRunNumber(getIntOrDefault(tree, "runNumber", 0));
163 event.setRunType(static_cast<parameters::GRPECS::RunType>(getIntOrDefault(tree, "runType", 0)));
164 event.setClMask(getIntOrDefault(tree, "clMask"));
165 event.setTrkMask(getIntOrDefault(tree, "trkMask"));
166 event.setTfCounter(getIntOrDefault(tree, "tfCounter"));
167 event.setFirstTForbit(getIntOrDefault(tree, "firstTForbit"));
168 event.setPrimaryVertex(getIntOrDefault(tree, "primaryVertex"));
169 if (tree.HasMember("creationTime")) {
170 event.setCreationTime(getUIntOrDefault(tree, "creationTime"));
171 }
172 if (event.mCreationTime == 0) {
173 auto collisionTime = getStringOrDefault(tree, "collisionTime", "not specified");
174 event.mCreationTime = parseDateTime(collisionTime.c_str());
175 }
176 event.mEveVersion = getIntOrDefault(tree, "version", 0);
177 if (event.mEveVersion == 0) {
178 std::string version = getStringOrDefault(tree, "eveVersion", "0.0");
179 event.mEveVersion = (int)(100 * std::stof(version));
180 }
181 // event.setWorkflowParameters(getStringOrDefault(tree, "workflowParameters", "1.0"));
182
183 rapidjson::Value& trackCount = tree["trackCount"];
184 event.mTracks.reserve(trackCount.GetInt());
185 rapidjson::Value& jsonTracks = tree["mTracks"];
186 for (auto& v : jsonTracks.GetArray()) {
187 event.mTracks.emplace_back(trackFromJSON(v));
188 }
189
190 if (tree.HasMember("caloCount")) {
191 rapidjson::Value& caloCount = tree["caloCount"];
192 event.mCalo.reserve(caloCount.GetInt());
193 rapidjson::Value& jsonCalo = tree["mCalo"];
194 for (auto& v : jsonCalo.GetArray()) {
195 event.mCalo.emplace_back(caloFromJSON(v));
196 }
197 }
198
199 rapidjson::Value& clusterCount = tree["clusterCount"];
200 event.mClusters.reserve(clusterCount.GetInt());
201 rapidjson::Value& jsonClusters = tree["mClusters"];
202 for (auto& v : jsonClusters.GetArray()) {
203 event.mClusters.emplace_back(clusterFromJSON(v, nullptr));
204 }
205 event.afterLoading();
206}
207
208VisualisationCluster VisualisationEventJSONSerializer::clusterFromJSON(rapidjson::Value& tree, const VisualisationTrack* track)
209{
210 float XYZ[3];
211 float time;
213 rapidjson::Value& jsonX = tree["X"];
214 rapidjson::Value& jsonY = tree["Y"];
215 rapidjson::Value& jsonZ = tree["Z"];
216
217 XYZ[0] = jsonX.GetDouble();
218 XYZ[1] = jsonY.GetDouble();
219 XYZ[2] = jsonZ.GetDouble();
220
221 if (track) {
222 time = track->mTime;
223 gid = track->mBGID;
224 } else {
225 rapidjson::Value& jsonTime = tree["time"];
226 rapidjson::Value& jsonBGID = tree["bgid"];
227 time = jsonTime.GetDouble();
228 gid = deserialize(jsonBGID.GetUint64());
229 }
230
231 VisualisationCluster cluster(XYZ, time, gid);
232 return cluster;
233}
234
235rapidjson::Value VisualisationEventJSONSerializer::jsonTree(const VisualisationCluster& cluster, MemoryPoolAllocator<>& allocator, const VisualisationTrack* track) const
236{
237 rapidjson::Value tree(rapidjson::kObjectType);
238 rapidjson::Value jsonX(rapidjson::kNumberType);
239 rapidjson::Value jsonY(rapidjson::kNumberType);
240 rapidjson::Value jsonZ(rapidjson::kNumberType);
241 jsonX.SetDouble(cluster.mCoordinates[0]);
242 jsonY.SetDouble(cluster.mCoordinates[1]);
243 jsonZ.SetDouble(cluster.mCoordinates[2]);
244 tree.AddMember("X", jsonX, allocator);
245 tree.AddMember("Y", jsonY, allocator);
246 tree.AddMember("Z", jsonZ, allocator);
247 if (track == nullptr) {
248 unsigned bgid = serialize(cluster.mBGID);
249 tree.AddMember("bgid", rapidjson::Value().SetUint(bgid), allocator); // proper (binary) gid storing
250 tree.AddMember("time", rapidjson::Value().SetFloat(std::isnan(cluster.mTime) ? 0 : cluster.mTime), allocator);
251 }
252 return tree;
253}
254
255VisualisationCalo VisualisationEventJSONSerializer::caloFromJSON(rapidjson::Value& tree)
256{
257 VisualisationCalo calo;
258 calo.mTime = tree["time"].GetFloat();
259 calo.mEnergy = tree["energy"].GetFloat();
260 calo.mEta = tree["eta"].GetFloat();
261 calo.mPhi = tree["phi"].GetFloat();
262 if (tree.HasMember("bgid")) {
263 unsigned bgid = tree["bgid"].GetUint();
264 calo.mBGID = deserialize(bgid);
265 } else {
266 auto source = tree["source"].GetUint();
267 calo.mBGID = deserialize(source, 0, 0);
268 }
269 calo.mPID = tree["PID"].GetInt();
270 return calo;
271}
272
273rapidjson::Value VisualisationEventJSONSerializer::jsonTree(const VisualisationCalo& calo, rapidjson::MemoryPoolAllocator<>& allocator) const
274{
275 rapidjson::Value tree(rapidjson::kObjectType);
276 // tree.AddMember("source", rapidjson::Value().SetInt(calo.mSource), allocator);
277 tree.AddMember("time", rapidjson::Value().SetFloat(std::isnan(calo.mTime) ? 0 : calo.mTime), allocator);
278 tree.AddMember("energy", rapidjson::Value().SetFloat(calo.mEnergy), allocator);
279 tree.AddMember("eta", rapidjson::Value().SetFloat(std::isnan(calo.mEta) ? 0 : calo.mEta), allocator);
280 tree.AddMember("phi", rapidjson::Value().SetFloat(std::isnan(calo.mPhi) ? 0 : calo.mPhi), allocator);
281 unsigned bgid = serialize(calo.mBGID);
282 tree.AddMember("bgid", rapidjson::Value().SetUint(bgid), allocator);
283 tree.AddMember("source", rapidjson::Value().SetUint(calo.mBGID.getSource()), allocator);
284 tree.AddMember("PID", rapidjson::Value().SetInt(calo.mPID), allocator);
285 return tree;
286}
287
288VisualisationTrack VisualisationEventJSONSerializer::trackFromJSON(rapidjson::Value& tree)
289{
290 VisualisationTrack track;
291 track.mClusters.clear();
292 rapidjson::Value& jsonStartingXYZ = tree["jsonStartingXYZ"];
293 rapidjson::Value& jsonPolyX = tree["mPolyX"];
294 rapidjson::Value& jsonPolyY = tree["mPolyY"];
295 rapidjson::Value& jsonPolyZ = tree["mPolyZ"];
296 rapidjson::Value& count = tree["count"];
297 track.mCharge = getIntOrDefault(tree, "charge", 0);
298 track.mTheta = getFloatOrDefault(tree, "theta", 0);
299 track.mPhi = getFloatOrDefault(tree, "phi", 0);
300 track.mEta = getFloatOrDefault(tree, "eta", 0);
301 // track.mSource = (o2::dataformats::GlobalTrackID::Source)getIntOrDefault(tree, "source", (int)o2::dataformats::GlobalTrackID::TPC);
302 track.mPID = getIntOrDefault(tree, "PID", 0);
303 track.mTime = tree["time"].GetFloat();
304 track.mBGID = 0;
305 if (tree.HasMember("bgid")) {
306 track.mBGID = deserialize(getUIntOrDefault(tree, "bgid", 0));
307 } else {
308 std::string gid = getStringOrDefault(tree, "gid", "track");
309 if (gid != "track") {
310 track.mBGID = gidFromString(gid); // json uses text gid format only
311 }
312 }
313 track.mPolyX.reserve(count.GetInt());
314 track.mPolyY.reserve(count.GetInt());
315 track.mPolyZ.reserve(count.GetInt());
316 auto startingXYZ = jsonStartingXYZ.GetArray();
317 track.mStartCoordinates[0] = startingXYZ[0].GetFloat();
318 track.mStartCoordinates[1] = startingXYZ[1].GetFloat();
319 track.mStartCoordinates[2] = startingXYZ[2].GetFloat();
320 for (auto& v : jsonPolyX.GetArray()) {
321 track.mPolyX.push_back(v.GetDouble());
322 }
323 for (auto& v : jsonPolyY.GetArray()) {
324 track.mPolyY.push_back(v.GetDouble());
325 }
326 for (auto& v : jsonPolyZ.GetArray()) {
327 track.mPolyZ.push_back(v.GetDouble());
328 }
329 if (tree.HasMember("mClusters")) {
330 rapidjson::Value& jsonClusters = tree["mClusters"];
331 auto jsonArray = jsonClusters.GetArray();
332 track.mClusters.reserve(jsonArray.Size());
333 for (auto& v : jsonClusters.GetArray()) {
334 track.mClusters.emplace_back(clusterFromJSON(v, &track));
335 }
336 }
337 return track;
338}
339
340rapidjson::Value VisualisationEventJSONSerializer::jsonTree(const VisualisationTrack& track, rapidjson::Document::AllocatorType& allocator) const
341{
342 rapidjson::Value tree(rapidjson::kObjectType);
343 rapidjson::Value jsonPolyX(rapidjson::kArrayType);
344 rapidjson::Value jsonPolyY(rapidjson::kArrayType);
345 rapidjson::Value jsonPolyZ(rapidjson::kArrayType);
346 rapidjson::Value jsonStartCoordinates(rapidjson::kArrayType);
347
348 tree.AddMember("count", rapidjson::Value().SetInt(track.getPointCount()), allocator);
349
350 rapidjson::Value gid;
351 std::string stringGID = track.mBGID.asString();
352 gid.SetString(stringGID.c_str(), stringGID.size(), allocator); // obsolete - for compatibility
353 tree.AddMember("gid", gid, allocator);
354 unsigned bgid = serialize(track.mBGID);
355 tree.AddMember("bgid", rapidjson::Value().SetUint(bgid), allocator); // proper (binary) gid storing
356
357 tree.AddMember("time", rapidjson::Value().SetFloat(std::isnan(track.mTime) ? 0 : track.mTime), allocator);
358 tree.AddMember("charge", rapidjson::Value().SetInt(track.mCharge), allocator);
359 tree.AddMember("theta", rapidjson::Value().SetFloat(std::isnan(track.mTheta) ? 0 : track.mTheta), allocator);
360 tree.AddMember("phi", rapidjson::Value().SetFloat(std::isnan(track.mPhi) ? 0 : track.mPhi), allocator);
361 tree.AddMember("eta", rapidjson::Value().SetFloat(std::isnan(track.mEta) ? 0 : track.mEta), allocator);
362 tree.AddMember("PID", rapidjson::Value().SetInt(track.mPID), allocator);
363
364 jsonStartCoordinates.PushBack((float)track.mStartCoordinates[0], allocator);
365 jsonStartCoordinates.PushBack((float)track.mStartCoordinates[1], allocator);
366 jsonStartCoordinates.PushBack((float)track.mStartCoordinates[2], allocator);
367 tree.AddMember("jsonStartingXYZ", jsonStartCoordinates, allocator);
368
369 for (size_t i = 0; i < track.getPointCount(); i++) {
370 jsonPolyX.PushBack((float)track.mPolyX[i], allocator);
371 jsonPolyY.PushBack((float)track.mPolyY[i], allocator);
372 jsonPolyZ.PushBack((float)track.mPolyZ[i], allocator);
373 }
374 tree.AddMember("mPolyX", jsonPolyX, allocator);
375 tree.AddMember("mPolyY", jsonPolyY, allocator);
376 tree.AddMember("mPolyZ", jsonPolyZ, allocator);
377
378 rapidjson::Value jsonClusters(rapidjson::kArrayType);
379
380 for (auto cluster : track.getClustersSpan()) {
381 jsonClusters.PushBack(jsonTree(cluster, allocator, &track), allocator);
382 }
383 tree.AddMember("mClusters", jsonClusters, allocator);
384
385 return tree;
386}
387
388} // namespace o2::event_visualisation
o2::monitoring::tags::Value Value
int16_t time
Definition RawEventData.h:4
int32_t i
Global index for barrel track: provides provenance (detectors combination), index in respective array...
nlohmann::json json
StringRef key
void toFile(const VisualisationEvent &event, std::string fileName) override
static int getIntOrDefault(rapidjson::Value &tree, const char *key, int defaultValue=0)
static std::string getStringOrDefault(rapidjson::Value &tree, const char *key, const char *defaultValue="")
static uint64_t getUIntOrDefault(rapidjson::Value &tree, const char *key, uint64_t defaultValue=0)
static float getFloatOrDefault(rapidjson::Value &tree, const char *key, float defaultValue=0.0f)
bool fromFile(VisualisationEvent &event, std::string fileName) override
static unsigned serialize(o2::dataformats::GlobalTrackID gidValue)
static o2::dataformats::GlobalTrackID deserialize(unsigned seralizedValue)
static o2::dataformats::GlobalTrackID gidFromString(const std::string &gid)
struct _cl_event * event
Definition glcorearb.h:2982
GLint GLsizei count
Definition glcorearb.h:399
GLuint buffer
Definition glcorearb.h:655
const GLdouble * v
Definition glcorearb.h:832
GLsizei GLsizei GLchar * source
Definition glcorearb.h:798
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
Definition glcorearb.h:4150
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))
const std::string str