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