19#include <unordered_map>
29#include <TEveManager.h>
31#include <TEveTrackPropagator.h>
32#include <TEveElement.h>
33#include <TGListTree.h>
35#include <fairlogger/Logger.h>
36#include <rapidjson/document.h>
37#include <rapidjson/stringbuffer.h>
38#include <rapidjson/writer.h>
41#define elemof(e) (unsigned int)(sizeof(e) / sizeof(e[0]))
44using namespace rapidjson;
48namespace event_visualisation
51EventManager* EventManager::instance =
nullptr;
55 if (instance ==
nullptr) {
63 LOGF(info,
"Initializing TEveManager");
67 vizSettings.firstEvent =
true;
70 vizSettings.trackVisibility[
i] =
true;
71 vizSettings.trackColor[
i] = settings.GetValue(
"tracks.byType.unknown", kMagenta);
72 vizSettings.trackStyle[
i] = 1;
73 vizSettings.trackWidth[
i] = 1;
74 vizSettings.clusterVisibility[
i] =
true;
75 vizSettings.clusterColor[
i] = settings.GetValue(
"clusters.byType.unknown", kBlue);
76 vizSettings.clusterStyle[
i] = 20;
77 vizSettings.clusterSize[
i] = 1.0f;
83 auto start = std::chrono::high_resolution_clock::now();
87 if (!vizSettings.firstEvent) {
88 saveVisualisationSettings();
91 multiView->destroyAllEvents();
105 for (
auto it = displayList.begin(); it != displayList.end(); ++it) {
112 multiView->registerElements(dataTypeLists, dataTypeListsPhi);
114 if (vizSettings.firstEvent) {
115 ifstream s(TEMP_SETTINGS_PATH);
117 restoreVisualisationSettings();
119 saveVisualisationSettings();
121 vizSettings.firstEvent =
false;
123 restoreVisualisationSettings();
129 multiView->getAnnotationTop()->SetText(
130 TString::Format(
"Run %d %s\n%s", dataSource->
getRunNumber(),
131 std::string(parameters::GRPECS::RunTypeNames[dataSource->
getRunType()]).c_str(),
132 creationTime.c_str()));
134 multiView->getAnnotationTop()->SetText(TString::Format(
"Run %d", dataSource->
getRunNumber()));
137 multiView->getAnnotationBottom()->SetText(
140 multiView->getAnnotationTop()->SetText(
"No Available Data to Display");
143 multiView->redraw3D();
144 auto stop = std::chrono::high_resolution_clock::now();
145 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop -
start);
187 delete this->dataSource;
188 this->dataSource =
nullptr;
193 TEveEventManager::AfterNewEventLoaded();
198 TEveEventManager::AddNewEventCommand(cmd);
203 TEveEventManager::RemoveNewEventCommand(cmd);
208 TEveEventManager::ClearNewEventCommands();
211EventManager::~EventManager()
227 auto*
list =
new TEveTrackList(detectorName.c_str());
228 list->IncDenyDestroy();
231 auto* point_list =
new TEvePointSet(detectorName.c_str());
232 point_list->IncDenyDestroy();
233 point_list->SetMarkerColor(settings.GetValue(
"clusters.byType.unknown", kBlue));
238 t.fSign = track.
getCharge() > 0 ? 1 : -1;
239 auto* vistrack =
new TEveTrack(&t, &TEveTrackPropagator::fgDefault);
240 vistrack->SetLineColor(settings.GetValue(
"tracks.byType.unknown", kMagenta));
243 vistrack->Reset(pointCount);
246 for (
size_t j = 0;
j < pointCount; ++
j) {
248 if (point[2] > eta || point[2] < -1 * eta) {
249 vistrack->SetNextPoint(point[0], point[1], point[2]);
254 list->AddElement(vistrack);
259 VisualisationCluster cluster = track.
getCluster(
i);
260 if (cluster.Z() > eta || cluster.Z() < -1 * eta) {
261 point_list->SetNextPoint(cluster.X(), cluster.Y(), cluster.Z());
269 if (detectorName !=
"MCH" && detectorName !=
"MFT" && detectorName !=
"MID") {
275 for (
size_t i = 0;
i <
event.getClusterCount(); ++
i) {
276 VisualisationCluster cluster =
event.getCluster(
i);
277 if (cluster.Z() > eta || cluster.Z() < -1 * eta) {
278 point_list->SetNextPoint(cluster.X(), cluster.Y(), cluster.Z());
285 if (detectorName !=
"MCH" && detectorName !=
"MFT" && detectorName !=
"MID") {
290 LOGF(info,
"tracks: ",
trackCount,
" detector: ", detectorName,
":",
292 LOGF(info,
"clusters: ",
clusterCount,
" detector: ", detectorName,
":",
296void EventManager::displayCalorimeters(VisualisationEvent&
event,
const std::string& detectorName)
298 if (
event.getCaloCount() > 0) {
301 std::string configColor;
303 std::string configSizeEta;
305 std::string configSizePhi;
307 std::string configNoise;
309 std::string configTransparency;
310 int defaultTransparency;
311 std::string configBarrelRadius;
312 int defaultBarrelRadius;
313 std::string configTowerMaxHeight;
314 float defaultTowerMaxHeight;
315 std::string configMaxValAbs;
316 float defaultMaxValAbs;
320 static const std::unordered_map<o2::dataformats::GlobalTrackID::Source, CaloInfo> caloInfos =
322 {
o2::dataformats::GlobalTrackID::EMC, {
"emcal",
"emcal.tower.color", kYellow,
"emcal.tower.size.eta", 0.0143,
"emcal.tower.size.phi", 0.0143,
"emcal.tower.noise", 0,
"emcal.tower.transparency", 101,
"emcal.barrel.radius", 500,
"emcal.tower.max.height", 80,
"emcal.tower.max.val.abs", 100}},
323 {
o2::dataformats::GlobalTrackID::PHS, {
"phos",
"phos.tower.color", kYellow,
"phos.tower.size.eta", 0.0046,
"phos.tower.size.phi", 0.00478,
"phos.tower.noise", 200,
"phos.tower.transparency", 101,
"phos.barrel.radius", 550,
"phos.tower.max.height", 80,
"phos.tower.max.val.abs", 100}},
326 auto data =
new TEveCaloDataVec(1);
327 data->IncDenyDestroy();
330 const CaloInfo& info = caloInfos.at(
key);
331 data->RefSliceInfo(0).Setup(info.name.c_str(),
332 settings.GetValue(info.configNoise.c_str(), info.defaultNoise),
333 settings.GetValue(info.configColor.c_str(), info.defaultColor),
334 settings.GetValue(info.configTransparency.c_str(), info.defaultTransparency));
336 const auto dEta = settings.GetValue(info.configSizeEta.c_str(), info.sizeEta) / 2.0;
337 const auto dPhi = settings.GetValue(info.configSizePhi.c_str(), info.sizePhi) / 2.0;
338 const float barrelRadius = settings.GetValue(info.configBarrelRadius.c_str(), info.defaultBarrelRadius);
341 std::size_t operator()(
const std::pair<float, float>& pair)
const
343 return std::hash<float>()(pair.first + 1000.0 * pair.second);
346 std::unordered_map<std::pair<float, float>,
float, pair_hash> map;
347 for (
const auto& calo :
event.getCalorimetersSpan()) {
348 map[std::make_pair(calo.getEta(), calo.getPhi())] += calo.getEnergy();
351 for (
const auto&
entry : map) {
353 data->AddTower(eta - dEta, eta + dEta, phi - dPhi, phi + dPhi);
358 data->AddTower(-0.5, 0.5, -1.574 - 0.1, -1.574 + 0.1);
359 data->AddTower(-0.5, 0.5, 1.574 - 0.1, 1.574 + 0.1);
360 data->AddTower(-0.5, 0.5, -0.593 - 0.1, -0.593 + 0.1);
361 data->AddTower(-0.5, 0.5, -0.726 - 0.1, -0.726 + 0.1);
362 data->AddTower(-0.5, 0.5, -3.028 - 0.1, -3.028 + 0.1);
363 data->AddTower(-0.5, 0.5, -1.915 - 0.1, -1.915 + 0.1);
366 data->SetAxisFromBins();
368 auto calo3d =
new TEveCalo3D(
data);
369 calo3d->SetName(detectorName.c_str());
370 calo3d->SetScaleAbs(kTRUE);
371 calo3d->SetMaxTowerH(settings.GetValue(info.configTowerMaxHeight.c_str(), info.defaultTowerMaxHeight));
372 calo3d->SetMaxValAbs(settings.GetValue(info.configMaxValAbs.c_str(), info.defaultMaxValAbs));
375 calo3d->SetBarrelRadius(barrelRadius);
376 calo3d->SetEndCapPos(barrelRadius);
377 calo3d->SetRnrFrame(
false,
false);
384void EventManager::saveVisualisationSettings()
388 for (
auto elm :
tracks.RefChildren()) {
389 auto trackList =
static_cast<TEveTrackList*
>(elm);
390 int i = findGroupIndex(trackList->GetElementName());
393 vizSettings.trackVisibility[
i] = trackList->GetRnrSelf();
394 vizSettings.trackColor[
i] = trackList->GetLineColor();
395 vizSettings.trackStyle[
i] = trackList->GetLineStyle();
396 vizSettings.trackWidth[
i] = trackList->GetLineWidth();
402 for (
auto elm :
clusters.RefChildren()) {
403 auto clusterSet =
static_cast<TEvePointSet*
>(elm);
404 int i = findGroupIndex(clusterSet->GetElementName());
407 vizSettings.clusterVisibility[
i] = clusterSet->GetRnrSelf();
408 vizSettings.clusterColor[
i] = clusterSet->GetMarkerColor();
409 vizSettings.clusterStyle[
i] = clusterSet->GetMarkerStyle();
410 vizSettings.clusterSize[
i] = clusterSet->GetMarkerSize();
414 ofstream settings(TEMP_SETTINGS_PATH);
416 if (settings.good()) {
419 auto& allocator = d.GetAllocator();
421 auto jsonArray = [](
const auto&
array,
auto& allocator) {
422 Value arr(kArrayType);
425 arr.PushBack(
value, allocator);
431 d.AddMember(
"version", rapidjson::Value().SetString(
version.c_str(),
version.length()), allocator);
432 d.AddMember(
"trackVisibility", jsonArray(vizSettings.trackVisibility, allocator), allocator);
433 d.AddMember(
"trackColor", jsonArray(vizSettings.trackColor, allocator), allocator);
434 d.AddMember(
"trackStyle", jsonArray(vizSettings.trackStyle, allocator), allocator);
435 d.AddMember(
"trackWidth", jsonArray(vizSettings.trackWidth, allocator), allocator);
436 d.AddMember(
"clusterVisibility", jsonArray(vizSettings.clusterVisibility, allocator), allocator);
437 d.AddMember(
"clusterColor", jsonArray(vizSettings.clusterColor, allocator), allocator);
438 d.AddMember(
"clusterStyle", jsonArray(vizSettings.clusterStyle, allocator), allocator);
439 d.AddMember(
"clusterSize", jsonArray(vizSettings.clusterSize, allocator), allocator);
442 Value obj(kObjectType);
446 const gsl::span baseSpan(camera.RefCamBase().CArr(), 16);
447 obj.AddMember(
"base", jsonArray(baseSpan, allocator), allocator);
449 const gsl::span transSpan(camera.GetCamTrans().CArr(), 16);
450 obj.AddMember(
"trans", jsonArray(transSpan, allocator), allocator);
452 if (camera.IsOrthographic()) {
453 obj.AddMember(
"zoom",
dynamic_cast<TGLOrthoCamera&
>(camera).GetZoom(), allocator);
454 }
else if (camera.IsPerspective()) {
455 obj.AddMember(
"fov",
dynamic_cast<TGLPerspectiveCamera&
>(camera).GetFOV(), allocator);
466 Writer<StringBuffer> writer(strbuf);
469 settings << strbuf.GetString();
473void EventManager::restoreVisualisationSettings()
475 ifstream settings(TEMP_SETTINGS_PATH);
477 if (settings.good()) {
478 string json((istreambuf_iterator<char>(settings)), istreambuf_iterator<char>());
480 d.Parse(
json.c_str());
484 LOGF(info,
"visualisation settings has wrong version and was not restored");
488 auto updateArray = [](
auto&
array,
const auto& document,
const char*
name,
const auto& accessor) {
494 auto getBool = [](
const GenericValue<UTF8<char>>&
v) {
return v.GetBool(); };
495 auto getUint = [](
const GenericValue<UTF8<char>>&
v) {
return v.GetUint(); };
496 auto getFloat = [](
const GenericValue<UTF8<char>>&
v) {
return v.GetFloat(); };
498 updateArray(vizSettings.trackVisibility, d,
"trackVisibility", getBool);
499 updateArray(vizSettings.trackColor, d,
"trackColor", getUint);
500 updateArray(vizSettings.trackStyle, d,
"trackStyle", getUint);
501 updateArray(vizSettings.trackWidth, d,
"trackWidth", getUint);
502 updateArray(vizSettings.clusterVisibility, d,
"clusterVisibility", getBool);
503 updateArray(vizSettings.clusterColor, d,
"clusterColor", getUint);
504 updateArray(vizSettings.clusterStyle, d,
"clusterStyle", getUint);
505 updateArray(vizSettings.clusterSize, d,
"clusterSize", getFloat);
510 std::array<Double_t, 16>
values;
512 for (
size_t i = 0;
i <
values.size(); ++
i) {
515 camera.RefCamBase() = TGLMatrix(
values.data());
517 for (
size_t i = 0;
i <
values.size(); ++
i) {
520 camera.RefCamTrans() = TGLMatrix(
values.data());
522 if (camera.IsOrthographic()) {
523 dynamic_cast<TGLOrthoCamera&
>(camera).SetZoom(getFloat(document[
name][
"zoom"]));
524 }
else if (camera.IsPerspective()) {
525 dynamic_cast<TGLPerspectiveCamera&
>(camera).SetFOV(getFloat(document[
name][
"fov"]));
528 camera.IncTimeStamp();
538 for (
auto elm :
tracks.RefChildren()) {
539 auto trackList =
static_cast<TEveTrackList*
>(elm);
540 int i = findGroupIndex(trackList->GetElementName());
543 const auto viz = vizSettings.trackVisibility[
i];
544 trackList->SetRnrSelfChildren(viz, viz);
545 trackList->SetLineColor(vizSettings.trackColor[
i]);
546 trackList->SetLineStyle(vizSettings.trackStyle[
i]);
547 trackList->SetLineWidth(vizSettings.trackWidth[
i]);
553 for (
auto elm :
clusters.RefChildren()) {
554 auto clusterSet =
static_cast<TEvePointSet*
>(elm);
555 int i = findGroupIndex(clusterSet->GetElementName());
558 const auto viz = vizSettings.clusterVisibility[
i];
559 clusterSet->SetRnrSelfChildren(viz, viz);
560 clusterSet->SetMarkerColor(vizSettings.clusterColor[
i]);
561 clusterSet->SetMarkerStyle(vizSettings.clusterStyle[
i]);
562 clusterSet->SetMarkerSize(vizSettings.clusterSize[
i]);
o2::monitoring::tags::Value Value
Grouping reading from file(s)
GUI (bottom buttons) for visualisation.
static std::string getNames(mask_t mask, char delimiter=',')
static ConfigurationManager & getInstance()
Returns an instance of ConfigurationManager.
void getConfig(TEnv &settings) const
Returns current event display configuration.
virtual int getRunNumber() const
virtual Int_t getCurrentEvent()
virtual int getEventCount()
virtual std::vector< std::pair< VisualisationEvent, EVisualisationGroup > > getVisualisationList(int no, float minTime, float maxTime, float range)=0
virtual int getFirstTForbit() const
virtual o2::detectors::DetID::mask_t getDetectorsMask()=0
virtual void setCurrentEvent(Int_t)
virtual o2::parameters::GRPECS::RunType getRunType()
std::string getCreationTimeAsString() const
static EventManagerFrame & getInstance()
Returns an instance of EventManagerFrame.
static EventManager & getInstance()
Returns an instance of EventManager.
DataSource * getDataSource()
void RemoveNewEventCommand(const TString &cmd) override
void AfterNewEventLoaded() override
void ClearNewEventCommands() override
void PrevEvent() override
void GotoEvent(Int_t) override
void displayCurrentEvent()
void NextEvent() override
void AddNewEventCommand(const TString &cmd) override
static MultiView * getInstance()
Returns an instance of the MultiView.
TEveViewer * getView(EViews view)
Returns pointer to specific view.
static std::string getStringOrDefault(rapidjson::Value &tree, const char *key, const char *defaultValue="")
size_t getClusterCount() const
std::array< float, 3 > getPoint(size_t i) const
std::string getGIDAsString() const
const VisualisationCluster & getCluster(int i) const
size_t getPointCount() const
GLuint const GLchar * name
GLsizei const GLfloat * value
GLenum GLsizei GLsizei GLint * values
std::string detectors(const std::vector< std::string > &det, unsigned mask)
const std::string gVisualisationGroupName[NvisualisationGroups]
@ Tracks
Event Summary Data.
@ Clusters
Reconstructed clusters (RecPoints)
@ Calorimeters
Calorimeters.
@ NdataTypes
number of supported data types
const std::string gDataTypeNames[NdataTypes]
struct o2::upgrades_utils::@454 tracks
structure to keep trigger-related info
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
std::string to_string(gsl::span< T, Size > span)
std::vector< Cluster > clusters