From b6adf2a03e5e56154aabc6bcc0d3fa6f6bd183f2 Mon Sep 17 00:00:00 2001 From: jmyrcha Date: Wed, 10 Jul 2024 17:33:25 +0200 Subject: [PATCH] o2-eve: implementation of *.eve binary format, many fixes (#13241) * o2-eve: implementation of *.eve binary format, many fixes * formatting * remove std::quick_exit * clang format * missed call to quick_exit removed * clang * clang * requested changes * clang --------- Co-authored-by: Julian Myrcha --- EventVisualisation/Base/CMakeLists.txt | 1 + .../ConfigurationManager.h | 2 +- .../EventVisualisationBase/DataSource.h | 6 +- .../EventVisualisationBase/DataSourceOnline.h | 5 +- EventVisualisation/Base/src/DataSource.cxx | 34 ++ .../Base/src/DataSourceOnline.cxx | 5 +- .../DataConverter/CMakeLists.txt | 2 + .../VisualisationCalo.h | 81 +-- .../VisualisationCluster.h | 21 +- .../VisualisationEvent.h | 47 +- .../VisualisationEventJSONSerializer.h | 7 +- .../VisualisationEventOpenGLSerializer.h | 48 ++ .../VisualisationEventROOTSerializer.h | 10 +- .../VisualisationEventSerializer.h | 10 + .../VisualisationTrack.h | 21 +- .../DataConverter/src/VisualisationCalo.cxx | 9 +- .../src/VisualisationCluster.cxx | 5 +- .../DataConverter/src/VisualisationEvent.cxx | 47 +- .../src/VisualisationEventJSONSerializer.cxx | 111 +++- .../VisualisationEventOpenGLSerializer.cxx | 517 ++++++++++++++++++ .../src/VisualisationEventROOTSerializer.cxx | 242 +++++--- .../src/VisualisationEventSerializer.cxx | 93 +++- .../DataConverter/src/VisualisationTrack.cxx | 12 +- .../DataConverter/src/converter.cxx | 134 ++++- EventVisualisation/View/src/EventManager.cxx | 9 +- .../View/src/EventManagerFrame.cxx | 4 +- EventVisualisation/View/src/Initializer.cxx | 3 +- .../include/EveWorkflow/EveWorkflowHelper.h | 30 +- .../Workflow/src/AO2DConverter.cxx | 3 +- .../Workflow/src/EveWorkflowHelper.cxx | 154 +++--- .../Workflow/src/O2DPLDisplay.cxx | 12 +- 31 files changed, 1310 insertions(+), 375 deletions(-) create mode 100644 EventVisualisation/Base/src/DataSource.cxx create mode 100644 EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventOpenGLSerializer.h create mode 100644 EventVisualisation/DataConverter/src/VisualisationEventOpenGLSerializer.cxx diff --git a/EventVisualisation/Base/CMakeLists.txt b/EventVisualisation/Base/CMakeLists.txt index 48a5830f95b19..9b7a5a231de67 100644 --- a/EventVisualisation/Base/CMakeLists.txt +++ b/EventVisualisation/Base/CMakeLists.txt @@ -11,6 +11,7 @@ o2_add_library(EventVisualisationBase SOURCES src/ConfigurationManager.cxx + src/DataSource.cxx src/DataSourceOnline.cxx src/DataSourceOffline.cxx src/GeometryManager.cxx diff --git a/EventVisualisation/Base/include/EventVisualisationBase/ConfigurationManager.h b/EventVisualisation/Base/include/EventVisualisationBase/ConfigurationManager.h index f9abc00774298..9fd5a16ea8112 100644 --- a/EventVisualisation/Base/include/EventVisualisationBase/ConfigurationManager.h +++ b/EventVisualisation/Base/include/EventVisualisationBase/ConfigurationManager.h @@ -25,7 +25,7 @@ namespace o2 namespace event_visualisation { /// Version of the software -const static std::string o2_eve_version = "1.70"; +const static int o2_eve_version = 171; /// Configuration Manager allows an easy access to the config file. /// diff --git a/EventVisualisation/Base/include/EventVisualisationBase/DataSource.h b/EventVisualisation/Base/include/EventVisualisationBase/DataSource.h index 919bd3c139f9f..5650751977c11 100644 --- a/EventVisualisation/Base/include/EventVisualisationBase/DataSource.h +++ b/EventVisualisation/Base/include/EventVisualisationBase/DataSource.h @@ -35,6 +35,7 @@ class DataSource DataReader* mDataReader = nullptr; float mTimeFrameMinTrackTime = 0; float mTimeFrameMaxTrackTime = 0; + framework::DataProcessingHeader::CreationTime mCreationTime; public: float getTimeFrameMinTrackTime() const @@ -76,8 +77,9 @@ class DataSource virtual std::string getEventAbsoluteFilePath() { return ""; }; virtual int getFirstTForbit() const { return 0; } virtual void setFirstTForbit(int) {} - virtual std::string getCollisionTime() const { return "not specified"; } - virtual void setCollisionTime(std::string) {} + void setCreationTime(framework::DataProcessingHeader::CreationTime mCreationTime) { this->mCreationTime = mCreationTime; } + framework::DataProcessingHeader::CreationTime getCreationTime() const { return mCreationTime; } + std::string getCreationTimeAsString() const; virtual std::string getFileTime() const { return "not specified"; } virtual void setFileTime(std::string) {} virtual int getTrackMask() const { return 0; } diff --git a/EventVisualisation/Base/include/EventVisualisationBase/DataSourceOnline.h b/EventVisualisation/Base/include/EventVisualisationBase/DataSourceOnline.h index d8b1f7fc91aba..593d35053f2d5 100644 --- a/EventVisualisation/Base/include/EventVisualisationBase/DataSourceOnline.h +++ b/EventVisualisation/Base/include/EventVisualisationBase/DataSourceOnline.h @@ -39,7 +39,8 @@ class DataSourceOnline : public DataSource int mFirstTForbit; int mTrackMask; int mClusterMask; - std::string mCollisionTime; + + protected: std::string mFileTime; public: @@ -69,8 +70,6 @@ class DataSourceOnline : public DataSource std::string getEventAbsoluteFilePath() override { return mFileWatcher.currentFilePath(); }; int getFirstTForbit() const override { return this->mFirstTForbit; } void setFirstTForbit(int firstTForbit) override { this->mFirstTForbit = firstTForbit; } - std::string getCollisionTime() const override { return this->mCollisionTime; } - void setCollisionTime(std::string collisionTime) override { this->mCollisionTime = collisionTime; } std::string getFileTime() const override { return this->mFileTime; } void setFileTime(std::string fileTime) override { this->mFileTime = fileTime; } int getTrackMask() const override { return this->mTrackMask; } diff --git a/EventVisualisation/Base/src/DataSource.cxx b/EventVisualisation/Base/src/DataSource.cxx new file mode 100644 index 0000000000000..12918f4d59cd5 --- /dev/null +++ b/EventVisualisation/Base/src/DataSource.cxx @@ -0,0 +1,34 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file DataSource.cxx +/// \brief reading from file(s) base class +/// \author j.myrcha@cern.ch + +#include + +#include +// #include + +namespace o2::event_visualisation +{ + +std::string DataSource::getCreationTimeAsString() const +{ + char buffer[90]; + time_t time = this->mCreationTime; + const char* format = "%a %b %-d %H:%M:%S %Y"; + struct tm* timeinfo = localtime(&time); + strftime(buffer, sizeof(buffer), format, timeinfo); + return buffer; +} + +} // namespace o2::event_visualisation diff --git a/EventVisualisation/Base/src/DataSourceOnline.cxx b/EventVisualisation/Base/src/DataSourceOnline.cxx index d6ed7c9adcb72..fa31b245d1e76 100644 --- a/EventVisualisation/Base/src/DataSourceOnline.cxx +++ b/EventVisualisation/Base/src/DataSourceOnline.cxx @@ -30,7 +30,7 @@ namespace o2 { namespace event_visualisation { -std::vector DataSourceOnline::sourceFilextensions = {".json", ".root"}; +std::vector DataSourceOnline::sourceFilextensions = {".json", ".root", ".eve"}; std::vector> DataSourceOnline::getVisualisationList(int no, float minTime, float maxTime, float range) @@ -51,7 +51,8 @@ std::vector> this->setRunNumber(vEvent.getRunNumber()); this->setRunType(vEvent.getRunType()); this->setFirstTForbit(vEvent.getFirstTForbit()); - this->setCollisionTime(vEvent.getCollisionTime()); + this->setCreationTime(vEvent.getCreationTime()); + this->setTrackMask(vEvent.getTrkMask()); this->setClusterMask(vEvent.getClMask()); diff --git a/EventVisualisation/DataConverter/CMakeLists.txt b/EventVisualisation/DataConverter/CMakeLists.txt index 15d838fe18226..778a3b6182aaf 100644 --- a/EventVisualisation/DataConverter/CMakeLists.txt +++ b/EventVisualisation/DataConverter/CMakeLists.txt @@ -17,6 +17,7 @@ o2_add_library(EventVisualisationDataConverter src/VisualisationEventSerializer.cxx src/VisualisationEventJSONSerializer.cxx src/VisualisationEventROOTSerializer.cxx + src/VisualisationEventOpenGLSerializer.cxx PUBLIC_LINK_LIBRARIES RapidJSON::RapidJSON O2::ReconstructionDataFormats O2::DataFormatsParameters @@ -28,6 +29,7 @@ o2_add_executable(eve-convert src/VisualisationEventSerializer.cxx src/VisualisationEventJSONSerializer.cxx src/VisualisationEventROOTSerializer.cxx + src/VisualisationEventOpenGLSerializer.cxx src/VisualisationTrack.cxx src/VisualisationCluster.cxx src/VisualisationCalo.cxx diff --git a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationCalo.h b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationCalo.h index e7c00064a909b..a18aef314b237 100644 --- a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationCalo.h +++ b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationCalo.h @@ -20,98 +20,47 @@ #include "rapidjson/document.h" #include "ReconstructionDataFormats/GlobalTrackID.h" -namespace o2 -{ -namespace event_visualisation +namespace o2::event_visualisation { + class VisualisationCalo { friend class VisualisationEventJSONSerializer; friend class VisualisationEventROOTSerializer; public: - // Default constructor VisualisationCalo(); /// constructor parametrisation (Value Object) for VisualisationCalo class - /// - /// Simplifies passing parameters to constructor of VisualisationCalo - /// by providing their names struct VisualisationCaloVO { float time = 0; float energy = 0.0f; float phi = 0; float eta = 0; int PID = 0; - std::string gid = ""; - o2::dataformats::GlobalTrackID::Source source; + o2::dataformats::GlobalTrackID gid = 0; }; - - // Constructor with properties initialisation explicit VisualisationCalo(const VisualisationCaloVO& vo); VisualisationCalo(const VisualisationCalo& src); - // Energy getter - float getEnergy() const - { - return mEnergy; - } - - // Time getter - float getTime() const - { - return mTime; - } - - // PID (particle identification code) getter - int getPID() const - { - return mPID; - } - - // GID getter - std::string getGIDAsString() const - { - return mGID; - } - - // Source Getter - o2::dataformats::GlobalTrackID::Source getSource() const - { - return mSource; - } - - // Phi getter - float getPhi() const - { - return mPhi; - } - - // Theta getter - float getEta() const - { - return mEta; - } + [[nodiscard]] float getEnergy() const { return mEnergy; } + [[nodiscard]] float getTime() const { return mTime; } + [[nodiscard]] int getPID() const { return mPID; } + [[nodiscard]] o2::dataformats::GlobalTrackID getGID() const { return mBGID; } + [[nodiscard]] o2::dataformats::GlobalTrackID::Source getSource() const { return static_cast(mBGID.getSource()); } + [[nodiscard]] float getPhi() const { return mPhi; } + [[nodiscard]] float getEta() const { return mEta; } private: - // Set coordinates of the beginning of the track - void addStartCoordinates(const float xyz[3]); - float mTime; /// time float mEnergy; /// Energy of the particle - - int mPID; /// PDG code of the particle - std::string mGID; /// String representation of gid - - float mEta; /// An angle from Z-axis to the radius vector pointing to the particle - float mPhi; /// An angle from X-axis to the radius vector pointing to the particle - - // std::vector mChildrenIDs; /// Unique IDs of children particles - o2::dataformats::GlobalTrackID::Source mSource; /// data source of the track (debug) + int mPID; /// PDG code of the particle + float mEta; /// An angle from Z-axis to the radius vector pointing to the particle + float mPhi; /// An angle from X-axis to the radius vector pointing to the particle + o2::dataformats::GlobalTrackID mBGID; }; -} // namespace event_visualisation -} // namespace o2 +} // namespace o2::event_visualisation #endif // O2EVE_VISUALISATIONCALO_H diff --git a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationCluster.h b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationCluster.h index da07dcf39ce68..398904a763ab2 100644 --- a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationCluster.h +++ b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationCluster.h @@ -24,9 +24,7 @@ #include #include -namespace o2 -{ -namespace event_visualisation +namespace o2::event_visualisation { /// Minimalistic description of a cluster @@ -39,17 +37,19 @@ class VisualisationCluster { friend class VisualisationEventJSONSerializer; friend class VisualisationEventROOTSerializer; + friend class VisualisationEventOpenGLSerializer; + friend class VisualisationEvent; public: // Default constructor - VisualisationCluster(float XYZ[], float time); + VisualisationCluster(const float XYZ[], float time, o2::dataformats::GlobalTrackID gid); VisualisationCluster(TVector3 xyz) { mTime = 0; + mBGID = 0; mCoordinates[0] = xyz[0]; mCoordinates[1] = xyz[1]; mCoordinates[2] = xyz[2]; - mSource = o2::dataformats::GlobalTrackID::HMP; } float X() const { return mCoordinates[0]; } @@ -57,15 +57,12 @@ class VisualisationCluster float Z() const { return mCoordinates[2]; } float Time() const { return mTime; } - // GID getter - int getSource() const { return mSource; } - private: - void setCoordinates(float xyz[3]); + void setCoordinates(const float xyz[3]); float mCoordinates[3]; /// Vector of cluster's coordinates float mTime; /// time asociated with cluster - o2::dataformats::GlobalTrackID::Source mSource; /// data source of the cluster (debug) + o2::dataformats::GlobalTrackID mBGID; }; -} // namespace event_visualisation -} // namespace o2 +} // namespace o2::event_visualisation + #endif // ALICE_O2_DATACONVERTER_VISUALISATIONCLUSTER_H diff --git a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEvent.h b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEvent.h index 5e01e665a0f93..684b9442d4565 100644 --- a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEvent.h +++ b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEvent.h @@ -24,6 +24,7 @@ #include "EventVisualisationDataConverter/VisualisationCalo.h" #include "EventVisualisationDataConverter/VisualisationConstants.h" #include "DataFormatsParameters/ECSDataAdapters.h" +#include "Framework/DataProcessingHeader.h" #include #include #include @@ -44,6 +45,7 @@ class VisualisationEvent { friend class VisualisationEventJSONSerializer; friend class VisualisationEventROOTSerializer; + friend class VisualisationEventOpenGLSerializer; public: struct GIDVisualisation { @@ -66,7 +68,7 @@ class VisualisationEvent time_t collisionTime; }; // Default constructor - VisualisationEvent(const VisualisationEventVO vo); + explicit VisualisationEvent(const VisualisationEventVO vo); void appendAnotherEventCalo(const VisualisationEvent& another); @@ -75,23 +77,23 @@ class VisualisationEvent mTracks.emplace_back(vo); return &mTracks.back(); } - void remove_last_track() { mTracks.pop_back(); } // used to remove track assigned optimistically - // Adds visualisation cluster inside visualisation event - VisualisationCluster& addCluster(float XYZ[], float trackTime) + VisualisationCluster& addCluster(const float* xyz) { - return mTracks.back().addCluster(XYZ); + // float pos[] = {X, Y, Z}; + return mTracks.back().addCluster(xyz); } - VisualisationCluster& addCluster(float X, float Y, float Z, float trackTime) + void addGlobalCluster(float* xyz, float time, o2::dataformats::GlobalTrackID gid) { - float pos[] = {X, Y, Z}; - return mTracks.back().addCluster(pos); + mClusters.emplace_back(xyz, time, gid); } - VisualisationCluster& addGlobalCluster(const TVector3& xyz) + void addGlobalCluster(const TVector3& xyz, o2::dataformats::GlobalTrackID gid, float time) { - return mClusters.emplace_back(xyz); + auto result = mClusters.emplace_back(xyz); + result.mBGID = gid; + result.mTime = time; } VisualisationCalo* addCalo(VisualisationCalo::VisualisationCaloVO vo) @@ -107,7 +109,7 @@ class VisualisationEvent } // Returns track with index i - const VisualisationTrack& getTrack(int i) const + [[nodiscard]] const VisualisationTrack& getTrack(int i) const { return mTracks[i]; }; @@ -172,12 +174,15 @@ class VisualisationEvent const VisualisationCluster& getCluster(int i) const { return mClusters[i]; }; size_t getClusterCount() const { return mClusters.size(); } // Returns number of clusters - void setWorkflowParameters(const std::string& workflowParameters) { this->mWorkflowParameters = workflowParameters; } + // void setWorkflowParameters(const std::string& workflowParameters) { this->mWorkflowParameters = workflowParameters; } - std::string getCollisionTime() const { return this->mCollisionTime; } - void setCollisionTime(std::string collisionTime) { this->mCollisionTime = collisionTime; } + // std::string getCollisionTime() const { return DateTime(this->mCreationTime); } + // void setCollisionTime(std::string collisionTime) { this->mCreationTime = this->parseDateTime(collisionTime.c_str()); } - void setEveVersion(std::string eveVersion) { this->mEveVersion = eveVersion; } + o2::framework::DataProcessingHeader::CreationTime getCreationTime() const { return this->mCreationTime; } + void setCreationTime(o2::framework::DataProcessingHeader::CreationTime creationTime) { this->mCreationTime = creationTime; } + + void setEveVersion(int eveVersion) { this->mEveVersion = eveVersion; } float getMinTimeOfTracks() const { return this->mMinTimeOfTracks; } float getMaxTimeOfTracks() const { return this->mMaxTimeOfTracks; } /// maximum time of tracks in the event @@ -199,12 +204,16 @@ class VisualisationEvent o2::header::DataHeader::TFCounterType getTfCounter() const { return this->mTfCounter; } void setTfCounter(o2::header::DataHeader::TFCounterType value) { this->mTfCounter = value; } - o2::header::DataHeader::TForbitType getFirstTForbit() const { return this->mFirstTForbit; } + [[nodiscard]] o2::header::DataHeader::TForbitType getFirstTForbit() const { return this->mFirstTForbit; } void setFirstTForbit(o2::header::DataHeader::TForbitType value) { this->mFirstTForbit = value; } + std::size_t getPrimaryVertex() const { return this->mPrimaryVertex; } void setPrimaryVertex(std::size_t pv) { this->mPrimaryVertex = pv; } + VisualisationEvent limit(std::size_t maximum_number_of_items); + private: + o2::framework::DataProcessingHeader::CreationTime mCreationTime; /// creation time in binary format int mClMask; /// clusters requested during aquisition int mTrkMask; /// tracks requested during aquisition o2::header::DataHeader::RunNumberType mRunNumber; /// run number @@ -215,13 +224,13 @@ class VisualisationEvent float mMinTimeOfTracks; /// minimum time of tracks in the event float mMaxTimeOfTracks; /// maximum time of tracks in the event - std::string mEveVersion; /// workflow version used to generate this Event - std::string mWorkflowParameters; /// workflow parameters used to generate this Event + int mEveVersion; /// workflow version used to generate this Event (120 -> 1.20) + // std::string mWorkflowParameters; /// workflow parameters used to generate this Event int mEventNumber; /// event number in file double mEnergy; /// energy of the collision int mMultiplicity; /// number of particles reconstructed std::string mCollidingSystem; /// colliding system (e.g. proton-proton) - std::string mCollisionTime; /// collision timestamp + // std::string mCollisionTime; /// collision timestamp std::vector mTracks; /// an array of visualisation tracks std::vector mClusters; /// an array of visualisation clusters std::vector mCalo; /// an array of visualisation calorimeters diff --git a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventJSONSerializer.h b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventJSONSerializer.h index 233d43651db67..c08009215d9fe 100644 --- a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventJSONSerializer.h +++ b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventJSONSerializer.h @@ -29,7 +29,10 @@ namespace event_visualisation class VisualisationEventJSONSerializer : public VisualisationEventSerializer { public: + const std::string serializerName() const override { return std::string("VisualisationEventJSONSerializer"); } static int getIntOrDefault(rapidjson::Value& tree, const char* key, int defaultValue = 0); + 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); static std::string getStringOrDefault(rapidjson::Value& tree, const char* key, const char* defaultValue = ""); @@ -43,8 +46,8 @@ class VisualisationEventJSONSerializer : public VisualisationEventSerializer rapidjson::Value jsonTree(const VisualisationCalo& calo, rapidjson::Document::AllocatorType& allocator) const; // create cluster from their JSON representation - VisualisationCluster clusterFromJSON(rapidjson::Value& tree); - rapidjson::Value jsonTree(const VisualisationCluster& cluster, rapidjson::Document::AllocatorType& allocator) const; + VisualisationCluster clusterFromJSON(rapidjson::Value& tree, const VisualisationTrack* track); + rapidjson::Value jsonTree(const VisualisationCluster& cluster, rapidjson::Document::AllocatorType& allocator, const VisualisationTrack* track) const; // create track from their JSON representation VisualisationTrack trackFromJSON(rapidjson::Value& tree); diff --git a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventOpenGLSerializer.h b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventOpenGLSerializer.h new file mode 100644 index 0000000000000..4730cc75f1c64 --- /dev/null +++ b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventOpenGLSerializer.h @@ -0,0 +1,48 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file VisualisationEventOpenGLSerializer.h +/// \author Julian Myrcha +/// + +#ifndef O2EVE_VISUALISATIONEVENTOPENGLSERIALIZER_H +#define O2EVE_VISUALISATIONEVENTOPENGLSERIALIZER_H + +#include "EventVisualisationDataConverter/VisualisationEventSerializer.h" +#include "EventVisualisationDataConverter/VisualisationTrack.h" +#include + +namespace o2 +{ +namespace event_visualisation +{ + +class VisualisationEventOpenGLSerializer : public VisualisationEventSerializer +{ + static void* createChunk(const char* lbl, unsigned size); + static unsigned int* asUnsigned(void* chunk) { return (unsigned*)((char*)chunk + 8); } + static float* asFloat(void* chunk) { return (float*)((char*)chunk + 8); } + static unsigned char* asByte(void* chunk) { return (unsigned char*)((char*)chunk + 8); } + static signed char* asSignedByte(void* chunk) { return (signed char*)((char*)chunk + 8); } + unsigned chunkSize(void* chunk); + + public: + const std::string serializerName() const override { return std::string("VisualisationEventOpenGLSerializer"); } + bool fromFile(VisualisationEvent& event, std::string fileName) override; + void toFile(const VisualisationEvent& event, std::string fileName) override; + ~VisualisationEventOpenGLSerializer() override = default; +}; + +} // namespace event_visualisation +} // namespace o2 + +#endif // O2EVE_VISUALISATIONEVENTOPENGLSERIALIZER_H diff --git a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventROOTSerializer.h b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventROOTSerializer.h index 040bc6e7071e6..e6408fb1c6c3f 100644 --- a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventROOTSerializer.h +++ b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventROOTSerializer.h @@ -21,6 +21,7 @@ #include "EventVisualisationDataConverter/VisualisationTrack.h" #include #include +#include namespace o2 { @@ -29,12 +30,19 @@ namespace event_visualisation class VisualisationEventROOTSerializer : public VisualisationEventSerializer { - static void save(const char* name, int value); + static void saveInt(const char* name, int value); + static void saveUInt64(const char* name, uint64_t value); static int readInt(TFile& f, const char* name); + static uint64_t readUInt64(TFile& f, const char* name); + static bool existUInt64(TFile& f, const char* name); static void save(const char* name, const std::string& value); static std::string readString(TFile& f, const char* name); + bool readClusters(VisualisationEvent& event, TFile& f, TNtuple* xyz); + bool readCalo(VisualisationEvent& event, TFile& f); + public: + [[nodiscard]] const std::string serializerName() const override { return std::string("VisualisationEventROOTSerializer"); } bool fromFile(VisualisationEvent& event, std::string fileName) override; void toFile(const VisualisationEvent& event, std::string fileName) override; ~VisualisationEventROOTSerializer() override = default; diff --git a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventSerializer.h b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventSerializer.h index 33d5aae08d8ab..5a6d902084ebf 100644 --- a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventSerializer.h +++ b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventSerializer.h @@ -32,11 +32,21 @@ class VisualisationEventSerializer protected: VisualisationEventSerializer() = default; static std::string fileNameIndexed(const std::string fileName, const int index); + static o2::dataformats::GlobalTrackID deserialize(unsigned seralizedValue); + + static unsigned serialize(o2::dataformats::GlobalTrackID gidValue); + + static time_t parseDateTime(const char* datetimeString); + static std::string DateTime(time_t time); + static std::string bits(unsigned number); public: + static o2::dataformats::GlobalTrackID gidFromString(const std::string& gid); + static o2::dataformats::GlobalTrackID deserialize(unsigned source, unsigned index, unsigned flags); static VisualisationEventSerializer* getInstance(std::string ext) { return instances[ext]; } virtual bool fromFile(VisualisationEvent& event, std::string fileName) = 0; virtual void toFile(const VisualisationEvent& event, std::string fileName) = 0; + virtual const std::string serializerName() const = 0; virtual ~VisualisationEventSerializer() = default; }; diff --git a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationTrack.h b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationTrack.h index b08ac465c9ba6..591b02ae3fc54 100644 --- a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationTrack.h +++ b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationTrack.h @@ -46,6 +46,7 @@ class VisualisationTrack { friend class VisualisationEventJSONSerializer; friend class VisualisationEventROOTSerializer; + friend class VisualisationEventOpenGLSerializer; public: // Default constructor @@ -63,11 +64,10 @@ class VisualisationTrack float phi = 0; float theta = 0; float eta = 0; - std::string gid = ""; - o2::dataformats::GlobalTrackID::Source source; + o2::dataformats::GlobalTrackID gid = 0; }; // Constructor with properties initialisation - VisualisationTrack(const VisualisationTrackVO& vo); + explicit VisualisationTrack(const VisualisationTrackVO& vo); VisualisationTrack(const VisualisationTrack& src); @@ -77,17 +77,17 @@ class VisualisationTrack void addPolyPoint(float x, float y, float z); void addPolyPoint(const float p[]); // Time getter - float getTime() const { return mTime; } + [[nodiscard]] float getTime() const { return mTime; } // Charge getter int getCharge() const { return mCharge; } // PID (particle identification code) getter int getPID() const { return mPID; } // GID getter - std::string getGIDAsString() const { return mGID; } + std::string getGIDAsString() const { return mBGID.asString(); } // Source Getter - o2::dataformats::GlobalTrackID::Source getSource() const { return mSource; } + [[nodiscard]] o2::dataformats::GlobalTrackID::Source getSource() const { return static_cast(mBGID.getSource()); } // Phi getter - float getPhi() const { return mPhi; } + [[nodiscard]] float getPhi() const { return mPhi; } // Theta getter float getTheta() const { return mTheta; } // @@ -96,7 +96,7 @@ class VisualisationTrack size_t getPointCount() const { return mPolyX.size(); } std::array getPoint(size_t i) const { return std::array{mPolyX[i], mPolyY[i], mPolyZ[i]}; } - VisualisationCluster& addCluster(float pos[]); + VisualisationCluster& addCluster(const float pos[]); const VisualisationCluster& getCluster(int i) const { return mClusters[i]; }; size_t getClusterCount() const { return mClusters.size(); } // Returns number of clusters gsl::span getClustersSpan() const @@ -112,7 +112,8 @@ class VisualisationTrack int mCharge; /// Charge of the particle int mPID; /// PDG code of the particle - std::string mGID; /// String representation of gid + // std::string mGID_obsolete; /// String representation of gid (obsolete) + o2::dataformats::GlobalTrackID mBGID; // binary representation of gid float mStartCoordinates[3]; /// Vector of track's start coordinates @@ -121,7 +122,7 @@ class VisualisationTrack float mEta; // std::vector mChildrenIDs; /// Uniqe IDs of children particles - o2::dataformats::GlobalTrackID::Source mSource; /// data source of the track (debug) + // o2::dataformats::GlobalTrackID::Source mSource; /// data source of the track (debug) /// Polylines -- array of points along the trajectory of the track std::vector mPolyX; diff --git a/EventVisualisation/DataConverter/src/VisualisationCalo.cxx b/EventVisualisation/DataConverter/src/VisualisationCalo.cxx index e0fd267f5dd54..c4440fce5bad7 100644 --- a/EventVisualisation/DataConverter/src/VisualisationCalo.cxx +++ b/EventVisualisation/DataConverter/src/VisualisationCalo.cxx @@ -24,23 +24,24 @@ VisualisationCalo::VisualisationCalo() = default; VisualisationCalo::VisualisationCalo(const VisualisationCaloVO& vo) { - this->mSource = vo.source; + // this->mSource = vo.source; this->mTime = vo.time; this->mEnergy = vo.energy; this->mEta = vo.eta; this->mPhi = vo.phi; - this->mGID = vo.gid; + this->mPID = vo.PID; + this->mBGID = vo.gid; } VisualisationCalo::VisualisationCalo(const VisualisationCalo& src) { - this->mSource = src.mSource; + // this->mSource = src.mSource; this->mTime = src.mTime; this->mEnergy = src.mEnergy; this->mEta = src.mEta; this->mPhi = src.mPhi; - this->mGID = src.mGID; + this->mBGID = src.mBGID; this->mPID = src.mPID; } diff --git a/EventVisualisation/DataConverter/src/VisualisationCluster.cxx b/EventVisualisation/DataConverter/src/VisualisationCluster.cxx index 1a7406e7d573c..ae9068940ef28 100644 --- a/EventVisualisation/DataConverter/src/VisualisationCluster.cxx +++ b/EventVisualisation/DataConverter/src/VisualisationCluster.cxx @@ -24,13 +24,14 @@ namespace o2 namespace event_visualisation { -VisualisationCluster::VisualisationCluster(float XYZ[], float time) +VisualisationCluster::VisualisationCluster(const float XYZ[], float time, o2::dataformats::GlobalTrackID gid) { setCoordinates(XYZ); this->mTime = time; + this->mBGID = gid; } -void VisualisationCluster::setCoordinates(float xyz[3]) +void VisualisationCluster::setCoordinates(const float xyz[3]) { for (int i = 0; i < 3; i++) { mCoordinates[i] = xyz[i]; diff --git a/EventVisualisation/DataConverter/src/VisualisationEvent.cxx b/EventVisualisation/DataConverter/src/VisualisationEvent.cxx index 24448ae5e88dd..e59f939be4557 100644 --- a/EventVisualisation/DataConverter/src/VisualisationEvent.cxx +++ b/EventVisualisation/DataConverter/src/VisualisationEvent.cxx @@ -21,6 +21,7 @@ #include #include #include +#include using namespace std; using namespace rapidjson; @@ -94,16 +95,19 @@ VisualisationEvent::GIDVisualisation VisualisationEvent::mVis = [] { }(); /// Ctor -- set the minimalistic event up -VisualisationEvent::VisualisationEvent(VisualisationEventVO vo) +VisualisationEvent::VisualisationEvent(const VisualisationEventVO vo) { this->mEventNumber = vo.eventNumber; this->mRunNumber = vo.runNumber; this->mEnergy = vo.energy; this->mMultiplicity = vo.multiplicity; this->mCollidingSystem = vo.collidingSystem; - this->mCollisionTime = vo.collisionTime; + this->mCreationTime = vo.collisionTime; this->mMinTimeOfTracks = numeric_limits::max(); this->mMaxTimeOfTracks = numeric_limits::min(); + this->mClMask = 0; + this->mTrkMask = 0; + this->mTfCounter = 0; } void VisualisationEvent::appendAnotherEventCalo(const VisualisationEvent& another) @@ -116,18 +120,18 @@ void VisualisationEvent::appendAnotherEventCalo(const VisualisationEvent& anothe VisualisationEvent::VisualisationEvent(const VisualisationEvent& source, EVisualisationGroup filter, float minTime, float maxTime) { for (auto it = source.mTracks.begin(); it != source.mTracks.end(); ++it) { - if (it->getTime() < minTime) { - continue; - } - if (it->getTime() > maxTime) { - continue; - } + // if (it->getTime() < minTime) { + // continue; + // } + // if (it->getTime() > maxTime) { + // continue; + // } if (VisualisationEvent::mVis.contains[it->getSource()][filter]) { this->mTracks.push_back(*it); } } for (auto it = source.mClusters.begin(); it != source.mClusters.end(); ++it) { - if (VisualisationEvent::mVis.contains[it->getSource()][filter]) { + if (VisualisationEvent::mVis.contains[o2::dataformats::GlobalTrackID::HMP][filter]) { // only HMP can be standalone clusters this->mClusters.push_back(*it); } } @@ -140,7 +144,9 @@ VisualisationEvent::VisualisationEvent(const VisualisationEvent& source, EVisual VisualisationEvent::VisualisationEvent() { - this->mCollisionTime = ""; // collision time not set + this->mRunNumber = 0; + this->mClMask = 0; + this->mTracks.clear(); } void VisualisationEvent::afterLoading() @@ -153,4 +159,25 @@ void VisualisationEvent::afterLoading() } } +VisualisationEvent VisualisationEvent::limit(std::size_t maximum_number_of_items) +{ + VisualisationEvent result = *this; + result.mTracks.clear(); + result.mCalo.clear(); + result.mClusters.clear(); + size_t count = 0; + do { + if (count < mTracks.size()) { + result.mTracks.push_back(mTracks[count]); + } + if (count < mClusters.size()) { + result.mClusters.push_back(mClusters[count]); + } + if (count < mCalo.size()) { + result.mCalo.push_back(mCalo[count]); + } + } while (count++ < maximum_number_of_items); + return result; +} + } // namespace o2 diff --git a/EventVisualisation/DataConverter/src/VisualisationEventJSONSerializer.cxx b/EventVisualisation/DataConverter/src/VisualisationEventJSONSerializer.cxx index e9de16551303d..612ddaf8717f4 100644 --- a/EventVisualisation/DataConverter/src/VisualisationEventJSONSerializer.cxx +++ b/EventVisualisation/DataConverter/src/VisualisationEventJSONSerializer.cxx @@ -18,6 +18,7 @@ #include #include #include +#include "ReconstructionDataFormats/GlobalTrackID.h" #include "rapidjson/document.h" #include "rapidjson/prettywriter.h" @@ -38,7 +39,7 @@ void VisualisationEventJSONSerializer::toFile(const VisualisationEvent& event, s bool VisualisationEventJSONSerializer::fromFile(VisualisationEvent& event, std::string fileName) { - LOGF(info, "VisualisationEventJSONSerializer <- ", fileName); + LOGF(info, "VisualisationEventJSONSerializer <- %s", fileName); if (FILE* file = fopen(fileName.c_str(), "r")) { fclose(file); // file exists } else { @@ -68,10 +69,15 @@ std::string VisualisationEventJSONSerializer::toJson(const VisualisationEvent& e tree.AddMember("tfCounter", rapidjson::Value().SetInt(event.mTfCounter), allocator); tree.AddMember("firstTForbit", rapidjson::Value().SetInt(event.mFirstTForbit), allocator); tree.AddMember("primaryVertex", rapidjson::Value().SetInt(event.mPrimaryVertex), allocator); - - tree.AddMember("collisionTime", rapidjson::Value().SetString(event.mCollisionTime.c_str(), event.mCollisionTime.size()), allocator); - tree.AddMember("eveVersion", rapidjson::Value().SetString(event.mEveVersion.c_str(), event.mEveVersion.size()), allocator); - tree.AddMember("workflowParameters", rapidjson::Value().SetString(event.mWorkflowParameters.c_str(), event.mWorkflowParameters.size()), allocator); + std::string collisionTime = DateTime(event.mCreationTime); + tree.AddMember("collisionTime", rapidjson::Value().SetString(collisionTime.c_str(), collisionTime.size()), allocator); + tree.AddMember("creationTime", rapidjson::Value().SetUint64(event.mCreationTime), allocator); + tree.AddMember("version", rapidjson::Value().SetUint64(event.mEveVersion), allocator); + std::string version = std::to_string(event.mEveVersion / 100.0); + version = version.substr(0, version.find('.') + 3); + tree.AddMember("eveVersion", rapidjson::Value().SetString(version.c_str(), version.size()), allocator); // obsolete + std::string workflowParameters = collisionTime + " t:" + bits(event.mTrkMask) + " c:" + bits(event.mClMask); + tree.AddMember("workflowParameters", rapidjson::Value().SetString(workflowParameters.c_str(), workflowParameters.size()), allocator); // Tracks tree.AddMember("trackCount", rapidjson::Value().SetInt(event.getTrackCount()), allocator); @@ -87,7 +93,7 @@ std::string VisualisationEventJSONSerializer::toJson(const VisualisationEvent& e tree.AddMember("clusterCount", clusterCount, allocator); Value jsonClusters(kArrayType); for (auto cluster : event.getClustersSpan()) { - jsonClusters.PushBack(jsonTree(cluster, allocator), allocator); + jsonClusters.PushBack(jsonTree(cluster, allocator, nullptr), allocator); } tree.AddMember("mClusters", jsonClusters, allocator); @@ -117,6 +123,14 @@ int VisualisationEventJSONSerializer::getIntOrDefault(rapidjson::Value& tree, co } return defaultValue; } +uint64_t VisualisationEventJSONSerializer::getUIntOrDefault(Value& tree, const char* key, uint64_t defaultValue) +{ + if (tree.HasMember(key)) { + rapidjson::Value& jsonValue = tree[key]; + return jsonValue.GetUint64(); + } + return defaultValue; +} float VisualisationEventJSONSerializer::getFloatOrDefault(rapidjson::Value& tree, const char* key, float defaultValue) { @@ -152,9 +166,19 @@ void VisualisationEventJSONSerializer::fromJson(VisualisationEvent& event, std:: event.setTfCounter(getIntOrDefault(tree, "tfCounter")); event.setFirstTForbit(getIntOrDefault(tree, "firstTForbit")); event.setPrimaryVertex(getIntOrDefault(tree, "primaryVertex")); - event.setCollisionTime(getStringOrDefault(tree, "collisionTime", "not specified")); - event.mEveVersion = getStringOrDefault(tree, "eveVersion", "0.0"); - event.setWorkflowParameters(getStringOrDefault(tree, "workflowParameters", "1.0")); + if (tree.HasMember("creationTime")) { + event.setCreationTime(getUIntOrDefault(tree, "creationTime")); + } + if (event.mCreationTime == 0) { + auto collisionTime = getStringOrDefault(tree, "collisionTime", "not specified"); + event.mCreationTime = parseDateTime(collisionTime.c_str()); + } + event.mEveVersion = getIntOrDefault(tree, "version", 0); + if (event.mEveVersion == 0) { + std::string version = getStringOrDefault(tree, "eveVersion", "0.0"); + event.mEveVersion = (int)(100 * std::stof(version)); + } + // event.setWorkflowParameters(getStringOrDefault(tree, "workflowParameters", "1.0")); rapidjson::Value& trackCount = tree["trackCount"]; event.mTracks.reserve(trackCount.GetInt()); @@ -176,14 +200,16 @@ void VisualisationEventJSONSerializer::fromJson(VisualisationEvent& event, std:: event.mClusters.reserve(clusterCount.GetInt()); rapidjson::Value& jsonClusters = tree["mClusters"]; for (auto& v : jsonClusters.GetArray()) { - event.mClusters.emplace_back(clusterFromJSON(v)); + event.mClusters.emplace_back(clusterFromJSON(v, nullptr)); } event.afterLoading(); } -VisualisationCluster VisualisationEventJSONSerializer::clusterFromJSON(rapidjson::Value& tree) +VisualisationCluster VisualisationEventJSONSerializer::clusterFromJSON(rapidjson::Value& tree, const VisualisationTrack* track) { float XYZ[3]; + float time; + o2::dataformats::GlobalTrackID gid; rapidjson::Value& jsonX = tree["X"]; rapidjson::Value& jsonY = tree["Y"]; rapidjson::Value& jsonZ = tree["Z"]; @@ -192,12 +218,21 @@ VisualisationCluster VisualisationEventJSONSerializer::clusterFromJSON(rapidjson XYZ[1] = jsonY.GetDouble(); XYZ[2] = jsonZ.GetDouble(); - VisualisationCluster cluster(XYZ, 0); - cluster.mSource = o2::dataformats::GlobalTrackID::HMP; + if (track) { + time = track->mTime; + gid = track->mBGID; + } else { + rapidjson::Value& jsonTime = tree["time"]; + rapidjson::Value& jsonBGID = tree["bgid"]; + time = jsonTime.GetDouble(); + gid = deserialize(jsonBGID.GetUint64()); + } + + VisualisationCluster cluster(XYZ, time, gid); return cluster; } -rapidjson::Value VisualisationEventJSONSerializer::jsonTree(const VisualisationCluster& cluster, MemoryPoolAllocator<>& allocator) const +rapidjson::Value VisualisationEventJSONSerializer::jsonTree(const VisualisationCluster& cluster, MemoryPoolAllocator<>& allocator, const VisualisationTrack* track) const { rapidjson::Value tree(rapidjson::kObjectType); rapidjson::Value jsonX(rapidjson::kNumberType); @@ -209,18 +244,28 @@ rapidjson::Value VisualisationEventJSONSerializer::jsonTree(const VisualisationC tree.AddMember("X", jsonX, allocator); tree.AddMember("Y", jsonY, allocator); tree.AddMember("Z", jsonZ, allocator); + if (track == nullptr) { + unsigned bgid = serialize(cluster.mBGID); + tree.AddMember("bgid", rapidjson::Value().SetUint(bgid), allocator); // proper (binary) gid storing + tree.AddMember("time", rapidjson::Value().SetFloat(std::isnan(cluster.mTime) ? 0 : cluster.mTime), allocator); + } return tree; } VisualisationCalo VisualisationEventJSONSerializer::caloFromJSON(rapidjson::Value& tree) { VisualisationCalo calo; - calo.mSource = (o2::dataformats::GlobalTrackID::Source)tree["source"].GetInt(); calo.mTime = tree["time"].GetFloat(); calo.mEnergy = tree["energy"].GetFloat(); calo.mEta = tree["eta"].GetFloat(); calo.mPhi = tree["phi"].GetFloat(); - calo.mGID = tree["gid"].GetString(); + if (tree.HasMember("bgid")) { + unsigned bgid = tree["bgid"].GetUint(); + calo.mBGID = deserialize(bgid); + } else { + auto source = tree["source"].GetUint(); + calo.mBGID = deserialize(source, 0, 0); + } calo.mPID = tree["PID"].GetInt(); return calo; } @@ -228,16 +273,14 @@ VisualisationCalo VisualisationEventJSONSerializer::caloFromJSON(rapidjson::Valu rapidjson::Value VisualisationEventJSONSerializer::jsonTree(const VisualisationCalo& calo, rapidjson::MemoryPoolAllocator<>& allocator) const { rapidjson::Value tree(rapidjson::kObjectType); - tree.AddMember("source", rapidjson::Value().SetInt(calo.mSource), allocator); + // tree.AddMember("source", rapidjson::Value().SetInt(calo.mSource), allocator); tree.AddMember("time", rapidjson::Value().SetFloat(std::isnan(calo.mTime) ? 0 : calo.mTime), allocator); tree.AddMember("energy", rapidjson::Value().SetFloat(calo.mEnergy), allocator); tree.AddMember("eta", rapidjson::Value().SetFloat(std::isnan(calo.mEta) ? 0 : calo.mEta), allocator); tree.AddMember("phi", rapidjson::Value().SetFloat(std::isnan(calo.mPhi) ? 0 : calo.mPhi), allocator); - - rapidjson::Value gid; - gid.SetString(calo.mGID.c_str(), calo.mGID.size(), allocator); - tree.AddMember("gid", gid, allocator); - + unsigned bgid = serialize(calo.mBGID); + tree.AddMember("bgid", rapidjson::Value().SetUint(bgid), allocator); + tree.AddMember("source", rapidjson::Value().SetUint(calo.mBGID.getSource()), allocator); tree.AddMember("PID", rapidjson::Value().SetInt(calo.mPID), allocator); return tree; } @@ -255,10 +298,18 @@ VisualisationTrack VisualisationEventJSONSerializer::trackFromJSON(rapidjson::Va track.mTheta = getFloatOrDefault(tree, "theta", 0); track.mPhi = getFloatOrDefault(tree, "phi", 0); track.mEta = getFloatOrDefault(tree, "eta", 0); - track.mSource = (o2::dataformats::GlobalTrackID::Source)getIntOrDefault(tree, "source", (int)o2::dataformats::GlobalTrackID::TPC); + // track.mSource = (o2::dataformats::GlobalTrackID::Source)getIntOrDefault(tree, "source", (int)o2::dataformats::GlobalTrackID::TPC); track.mPID = getIntOrDefault(tree, "PID", 0); track.mTime = tree["time"].GetFloat(); - track.mGID = getStringOrDefault(tree, "gid", "track"); + track.mBGID = 0; + if (tree.HasMember("bgid")) { + track.mBGID = deserialize(getUIntOrDefault(tree, "bgid", 0)); + } else { + std::string gid = getStringOrDefault(tree, "gid", "track"); + if (gid != "track") { + track.mBGID = gidFromString(gid); // json uses text gid format only + } + } track.mPolyX.reserve(count.GetInt()); track.mPolyY.reserve(count.GetInt()); track.mPolyZ.reserve(count.GetInt()); @@ -280,7 +331,7 @@ VisualisationTrack VisualisationEventJSONSerializer::trackFromJSON(rapidjson::Va auto jsonArray = jsonClusters.GetArray(); track.mClusters.reserve(jsonArray.Size()); for (auto& v : jsonClusters.GetArray()) { - track.mClusters.emplace_back(clusterFromJSON(v)); + track.mClusters.emplace_back(clusterFromJSON(v, &track)); } } return track; @@ -295,10 +346,14 @@ rapidjson::Value VisualisationEventJSONSerializer::jsonTree(const VisualisationT rapidjson::Value jsonStartCoordinates(rapidjson::kArrayType); tree.AddMember("count", rapidjson::Value().SetInt(track.getPointCount()), allocator); - tree.AddMember("source", rapidjson::Value().SetInt(track.mSource), allocator); + rapidjson::Value gid; - gid.SetString(track.mGID.c_str(), track.mGID.size(), allocator); + std::string stringGID = track.mBGID.asString(); + gid.SetString(stringGID.c_str(), stringGID.size(), allocator); // obsolete - for compatibility tree.AddMember("gid", gid, allocator); + unsigned bgid = serialize(track.mBGID); + tree.AddMember("bgid", rapidjson::Value().SetUint(bgid), allocator); // proper (binary) gid storing + tree.AddMember("time", rapidjson::Value().SetFloat(std::isnan(track.mTime) ? 0 : track.mTime), allocator); tree.AddMember("charge", rapidjson::Value().SetInt(track.mCharge), allocator); tree.AddMember("theta", rapidjson::Value().SetFloat(std::isnan(track.mTheta) ? 0 : track.mTheta), allocator); @@ -323,7 +378,7 @@ rapidjson::Value VisualisationEventJSONSerializer::jsonTree(const VisualisationT rapidjson::Value jsonClusters(rapidjson::kArrayType); for (auto cluster : track.getClustersSpan()) { - jsonClusters.PushBack(jsonTree(cluster, allocator), allocator); + jsonClusters.PushBack(jsonTree(cluster, allocator, &track), allocator); } tree.AddMember("mClusters", jsonClusters, allocator); diff --git a/EventVisualisation/DataConverter/src/VisualisationEventOpenGLSerializer.cxx b/EventVisualisation/DataConverter/src/VisualisationEventOpenGLSerializer.cxx new file mode 100644 index 0000000000000..a1c4ed7758f05 --- /dev/null +++ b/EventVisualisation/DataConverter/src/VisualisationEventOpenGLSerializer.cxx @@ -0,0 +1,517 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file VisualisationEventOpenGLSerializer.cxx +/// \brief ROOT serialization +/// \author julian.myrcha@cern.ch + +#include "EventVisualisationDataConverter/VisualisationEventOpenGLSerializer.h" +#include "ReconstructionDataFormats/GlobalTrackID.h" +#include +#include +#include +#include + +namespace o2 +{ +namespace event_visualisation +{ + +enum Header : uint8_t { + version, + runNumber, + creationTime, + firstTForbit, + runType, + trkMask, + clMask, + trackCount, + clusterCount, + phsCount, + emcCount, + primaryVertex, + tfCounter, + last // number of fields +}; + +std::string detectors(const std::vector& det, unsigned mask) +{ + std::string result; + std::string delim; + int bit = 1; + for (const auto& i : det) { + if (mask & bit) { + result += delim + i; + delim = ","; + } + bit = bit << 1; + } + return result; +} + +const auto HEAD = "HEAD"; +const auto TTYP = "TTYP"; +const auto CELM = "CELM"; +const auto TELM = "TELM"; +const auto TIME = "TIME"; // track time +const auto SXYZ = "SXYZ"; // track start xyz +const auto CRGE = "CRGE"; // charge for track +const auto ATPE = "ATPE"; // angles: theta,phi,eta for track +const auto TGID = "TGID"; // track GID +const auto TPID = "TPID"; // track PID +const auto TXYZ = "TXYZ"; // track poinst x,y,z +const auto CXYZ = "CXYZ"; // track clusters x,y,z + +const auto UXYZ = "UXYZ"; // global clusters x,y,z +const auto UGID = "UGID"; // global GID +const auto UTIM = "UTIM"; // global Time + +const auto CALO = "CALO"; // calo phi,eta,enargy +const auto CALP = "CALP"; // calo PID +const auto CALG = "CALG"; // calo GID +const auto CALT = "CALT"; // calo PID + +const auto FINE = "FINE"; // + +void VisualisationEventOpenGLSerializer::toFile(const VisualisationEvent& event, std::string fileName) +{ + static const std::vector det_coma = { + "ITS", "TPC", "TRD", "TOF", "PHS", "CPV", "EMC", "HMP", "MFT", "MCH", "MID", "ZDC", "FT0", "FV0", "FDD", "ITS-TPC", + "TPC-TOF", "TPC-TRD", "MFT-MCH", "ITS-TPC-TRD", "ITS-TPC-TOF", "TPC-TRD-TOF", "MFT-MCH-MID", "ITS-TPC-TRD-TOF", "ITS-AB", "CTP", + "MCH-MID"}; + std::ostringstream buf; + const auto SIGSIZE = 512; + unsigned char data[SIGSIZE]; + std::ofstream out(fileName, std::ios::out | std::ios::binary); + // head --bytes 512 fileName.eve + buf << "eve" << std::endl; + buf << "version=1.00" << std::endl; + buf << "run=" << event.getRunNumber() << std::endl; + buf << "firstTForbit=" << event.getFirstTForbit() << std::endl; + buf << "detectors=" << detectors(det_coma, event.getTrkMask()) << std::endl; + buf << "preview='" + << "dd if=thisFileName.eve of=thisFileName.png skip=20 bs=1 count=6000000" << std::endl; + buf << std::string(SIGSIZE, ' '); + memcpy((char*)&data[0], buf.str().c_str(), SIGSIZE); + data[SIGSIZE - 2] = '\n'; + data[SIGSIZE - 1] = 0; + out.write((char*)&data[0], SIGSIZE); // <----0 SIGN + + const auto trackNo = event.getTracksSpan().size(); + int phsCount = 0; + int emcCount = 0; + { + for (const auto& calo : event.getCalorimetersSpan()) { + if (calo.getSource() == o2::dataformats::GlobalTrackID::PHS) { + phsCount++; + } + if (calo.getSource() == o2::dataformats::GlobalTrackID::EMC) { + emcCount++; + } + } + } + + // header + { + const auto chunkHEAD = createChunk(HEAD, Header::last * 4); + const auto head = asUnsigned(chunkHEAD); + head[Header::version] = event.mEveVersion; + head[Header::runNumber] = event.getRunNumber(); + head[Header::creationTime] = event.getCreationTime(); + head[Header::firstTForbit] = event.getFirstTForbit(); + head[Header::runType] = event.getRunType(); + head[Header::trkMask] = event.getTrkMask(); + head[Header::clMask] = event.getClMask(); + head[Header::trackCount] = event.getTrackCount(); + head[Header::clusterCount] = event.getClusterCount(); // clusterno + head[Header::phsCount] = phsCount; + head[Header::emcCount] = emcCount; + head[Header::primaryVertex] = event.getPrimaryVertex(); + head[Header::tfCounter] = event.getTfCounter(); + out.write((char*)chunkHEAD, chunkSize(chunkHEAD)); // <----1 HEAD + free(chunkHEAD); + } + + // information about number of track by type + unsigned totalPoints = 0; + unsigned totalClusters = 0; + { + const auto chunkTELM = createChunk(TELM, trackNo); // number of track points for each track + const auto telm = asByte(chunkTELM); + const auto chunkTGID = createChunk(TGID, 4 * trackNo); // number of track points for each track + const auto tgid = asUnsigned(chunkTGID); + const auto chunkTPID = createChunk(TPID, 4 * trackNo); // number of track points for each track + const auto tpid = asUnsigned(chunkTPID); + const auto chunkCELM = createChunk(CELM, trackNo); // number of track clusters for each track + const auto celm = asByte(chunkCELM); + + const auto chunkTTYP = createChunk(TTYP, 4 * 27); + const auto ttyp = asUnsigned(chunkTTYP); + unsigned index = 0; + for (const auto& track : event.getTracksSpan()) { + tgid[index] = track.mBGID; + tpid[index] = track.mPID; + const auto ttypeidx = track.mBGID.getSource(); + ttyp[ttypeidx]++; + totalPoints += track.getPointCount(); // here to pre-compute (performance) + totalClusters += track.getClusterCount(); // here to pre-compute (performance) + telm[index] = track.getPointCount(); + celm[index] = track.getClusterCount(); + index++; + } + out.write((char*)chunkTTYP, chunkSize(chunkTTYP)); // <----2 TTYP + free(chunkTTYP); + out.write((char*)chunkTELM, chunkSize(chunkTELM)); // <----3 TELM + free(chunkTELM); + out.write((char*)chunkCELM, chunkSize(chunkCELM)); // <----3 CELM + free(chunkCELM); + out.write((char*)chunkTGID, chunkSize(chunkTGID)); // <----3 GIND + free(chunkTGID); + out.write((char*)chunkTPID, chunkSize(chunkTPID)); // <----3 TPID (tracks pid) + free(chunkTPID); + } + + { + const auto chunkTXYZ = createChunk(TXYZ, totalPoints * 4 * 3); + const auto txyz = asFloat(chunkTXYZ); + unsigned tidx = 0; // track elem (point coordinate)positions + + const auto chunkTIME = createChunk(TIME, trackNo * 4); + const auto time = asFloat(chunkTIME); + unsigned tno = 0; // track positions + + const auto chunkSXYZ = createChunk(SXYZ, trackNo * 4 * 3); + const auto sxyz = asFloat(chunkSXYZ); + unsigned sxyzidx = 0; // starting point track positions + + const auto chunkATPE = createChunk(ATPE, trackNo * 4 * 3); + const auto atpe = asFloat(chunkATPE); + unsigned atpeidx = 0; // starting point track positions + + const auto chunkCRGE = createChunk(CRGE, trackNo); + const auto crge = asSignedByte(chunkCRGE); + + const auto chunkCXYZ = createChunk(CXYZ, totalClusters * 4 * 3); + const auto cxyz = asFloat(chunkCXYZ); + unsigned cidx = 0; // cluster positions + + for (const auto& track : event.getTracksSpan()) { + time[tno] = track.getTime(); + crge[tno] = track.getCharge(); + tno++; + sxyz[sxyzidx++] = track.getStartCoordinates()[0]; + sxyz[sxyzidx++] = track.getStartCoordinates()[1]; + sxyz[sxyzidx++] = track.getStartCoordinates()[2]; + + atpe[atpeidx++] = track.getTheta(); + atpe[atpeidx++] = track.getPhi(); + atpe[atpeidx++] = track.mEta; + + for (unsigned i = 0; i < track.mPolyX.size(); i++) { + txyz[tidx++] = track.mPolyX[i]; + txyz[tidx++] = track.mPolyY[i]; + txyz[tidx++] = track.mPolyZ[i]; + } + for (unsigned i = 0; i < track.getClusterCount(); i++) { + cxyz[cidx++] = track.getClustersSpan()[i].X(); + cxyz[cidx++] = track.getClustersSpan()[i].Y(); + cxyz[cidx++] = track.getClustersSpan()[i].Z(); + } + } + out.write((char*)chunkTXYZ, chunkSize(chunkTXYZ)); // <----4 TXYZ + free(chunkTXYZ); + out.write((char*)chunkCXYZ, chunkSize(chunkCXYZ)); // <----4 CXYZ + free(chunkCXYZ); + out.write((char*)chunkTIME, chunkSize(chunkTIME)); // <----4 TIME + free(chunkTIME); + out.write((char*)chunkSXYZ, chunkSize(chunkSXYZ)); // <----4 SXYZ + free(chunkSXYZ); + out.write((char*)chunkCRGE, chunkSize(chunkCRGE)); // <----4 CRGE + free(chunkCRGE); + out.write((char*)chunkATPE, chunkSize(chunkATPE)); // <----4 CRGE + free(chunkATPE); + } + + { + const auto chunkUXYZ = createChunk(UXYZ, clusterCount * 4 * 3); // X,Y,Z + const auto uxyz = asFloat(chunkUXYZ); + const auto chunkUTIM = createChunk(UTIM, clusterCount * 4); // time + const auto utim = asFloat(chunkUTIM); + const auto chunkUGID = createChunk(UGID, clusterCount * 4); // time + const auto ugid = asUnsigned(chunkUGID); + unsigned idx = 0; // positions + + for (const auto& c : event.getClustersSpan()) { + utim[idx / 3] = c.mTime; + ugid[idx / 3] = serialize(c.mBGID); + uxyz[idx++] = c.X(); + uxyz[idx++] = c.Y(); + uxyz[idx++] = c.Z(); + } + out.write((char*)chunkUGID, chunkSize(chunkUGID)); // + free(chunkUGID); + out.write((char*)chunkUTIM, chunkSize(chunkUTIM)); // + free(chunkUTIM); + out.write((char*)chunkUXYZ, chunkSize(chunkUXYZ)); // + free(chunkUXYZ); + } + + { + const auto chunkCALO = createChunk(CALO, (phsCount + emcCount) * 4 * 3); // phi, eta, energy + const auto calo = asFloat(chunkCALO); + const auto chunkCALP = createChunk(CALP, (phsCount + emcCount) * 4); // PID + const auto calp = asUnsigned(chunkCALP); + const auto chunkCALG = createChunk(CALG, (phsCount + emcCount) * 4); // PID + const auto calg = asUnsigned(chunkCALG); + const auto chunkCALT = createChunk(CALT, (phsCount + emcCount) * 4); // PID + const auto calt = asFloat(chunkCALT); + unsigned idx = 0; // positions + + for (const auto& c : event.getCalorimetersSpan()) { + if (c.getSource() == o2::dataformats::GlobalTrackID::PHS) { + calt[idx / 3] = c.getTime(); + calp[idx / 3] = serialize(c.getPID()); + calg[idx / 3] = serialize(c.getGID()); + calo[idx++] = c.getPhi(); + calo[idx++] = c.getEta(); + calo[idx++] = c.getEnergy(); + } + } + for (const auto& c : event.getCalorimetersSpan()) { + if (c.getSource() == o2::dataformats::GlobalTrackID::EMC) { + calt[idx / 3] = c.getTime(); + calp[idx / 3] = serialize(c.getPID()); + calg[idx / 3] = serialize(c.getGID()); + calo[idx++] = c.getPhi(); + calo[idx++] = c.getEta(); + calo[idx++] = c.getEnergy(); + } + } + + out.write((char*)chunkCALO, chunkSize(chunkCALO)); // + free(chunkCALO); + out.write((char*)chunkCALP, chunkSize(chunkCALP)); // + free(chunkCALP); + out.write((char*)chunkCALG, chunkSize(chunkCALG)); // + free(chunkCALG); + out.write((char*)chunkCALT, chunkSize(chunkCALT)); // + free(chunkCALT); + } + + { + const auto chunkFINE = createChunk(FINE, 0); + out.write((char*)chunkFINE, chunkSize(chunkFINE)); // <----5 FINE + free(chunkFINE); + } + out.close(); +} + +void* VisualisationEventOpenGLSerializer::createChunk(const char* lbl, unsigned size) +{ + auto result = (unsigned char*)calloc(4 * ((size + 3) / 4) + 8, 1); + result[0] = lbl[0]; + result[1] = lbl[1]; + result[2] = lbl[2]; + result[3] = lbl[3]; + auto uResult = (unsigned*)&result[4]; + *uResult = 4 * ((size + 3) / 4); + return result; +} + +unsigned VisualisationEventOpenGLSerializer::chunkSize(void* chunk) +{ + auto uResult = (unsigned*)((char*)chunk + 4); + return *uResult + 8; +} + +bool VisualisationEventOpenGLSerializer::fromFile(VisualisationEvent& event, std::string fileName) +{ + + std::filesystem::path inputFilePath{fileName}; + auto length = (long)std::filesystem::file_size(inputFilePath); + if (length == 0) { + return {}; // empty vector + } + std::vector buffer(length); + std::ifstream inputFile(fileName, std::ios_base::binary); + inputFile.read(reinterpret_cast(buffer.data()), length); + inputFile.close(); + + long position = 512; + char type[5]; + type[0] = 0; + type[4] = 0; // ending 0 for string + + auto trackCount = 0L; + auto clusterCount = 0L; + unsigned char* telm = nullptr; + unsigned char* celm = nullptr; + unsigned int* ttyp = nullptr; + float* txyz = nullptr; + float* cxyz = nullptr; + + float* time = nullptr; + float* sxyz = nullptr; + signed char* crge = nullptr; + float* atpe = nullptr; + unsigned* tgid = nullptr; + unsigned* tpid = nullptr; + + float* calo = nullptr; + unsigned* calp = nullptr; + unsigned* calg = nullptr; + float* calt = nullptr; + + unsigned* ugid = nullptr; + float* utim = nullptr; + float* uxyz = nullptr; + + unsigned phsCaloCount = 0; + unsigned emcCaloCount = 0; + + while (true) { + for (auto c = 0; c < 4; c++) { + type[c] = (char)buffer.at(position + c); + } + auto* words = (unsigned*)(buffer.data() + position + 4); + position = position + *words + 8; + words++; + if (std::string(type) == HEAD) { + auto head = words; + event.mEveVersion = head[Header::version]; + event.setRunNumber(head[Header::runNumber]); + event.setCreationTime(head[Header::creationTime]); + event.setFirstTForbit(head[Header::firstTForbit]); + event.setRunType((parameters::GRPECS::RunType)head[Header::runType]); + event.setTrkMask((int)head[Header::trkMask]); + phsCaloCount = head[Header::phsCount]; + emcCaloCount = head[Header::emcCount]; + event.setClMask((int)head[Header::clMask]); + trackCount = head[Header::trackCount]; + clusterCount = head[Header::clusterCount]; + event.setPrimaryVertex(head[11]); + event.setTfCounter(head[12]); + } else if (std::string(type) == TELM) { + telm = (unsigned char*)words; + } else if (std::string(type) == CELM) { + celm = (unsigned char*)words; + } else if (std::string(type) == TTYP) { + ttyp = (unsigned int*)words; + } else if (std::string(type) == TIME) { + time = (float*)words; + } else if (std::string(type) == TXYZ) { + txyz = (float*)words; + } else if (std::string(type) == CXYZ) { + cxyz = (float*)words; + } else if (std::string(type) == SXYZ) { + sxyz = (float*)words; + } else if (std::string(type) == CRGE) { + crge = (signed char*)words; + } else if (std::string(type) == ATPE) { + atpe = (float*)words; + } else if (std::string(type) == TGID) { + tgid = (unsigned*)words; + } else if (std::string(type) == TPID) { + tpid = (unsigned*)words; + } else if (std::string(type) == UXYZ) { + uxyz = (float*)words; + } else if (std::string(type) == UGID) { + ugid = (unsigned*)words; + } else if (std::string(type) == UTIM) { + utim = (float*)words; + } else if (std::string(type) == CALO) { + calo = (float*)words; + } else if (std::string(type) == CALP) { + calp = (unsigned*)words; + } else if (std::string(type) == CALG) { + calg = (unsigned*)words; + } else if (std::string(type) == CALT) { + calt = (float*)words; + } else if (std::string(type) == FINE) { + assert(telm != nullptr); + assert(celm != nullptr); + assert(ttyp != nullptr); + assert(txyz != nullptr); + assert(cxyz != nullptr); + assert(time != nullptr); + assert(sxyz != nullptr); + assert(crge != nullptr); + assert(atpe != nullptr); + assert(tgid != nullptr); + assert(tpid != nullptr); + assert(uxyz != nullptr); + assert(ugid != nullptr); + assert(utim != nullptr); + assert(calo != nullptr); + assert(calp != nullptr); + assert(calg != nullptr); + assert(calt != nullptr); + int ttypidx = 0; // tracks are stored in order ITS,TPC,... where ttyp cointains a number + int txyzidx = 0; // coordinates + int cxyzidx = 0; // coordinates + // TRACKS + for (auto t = 0; t < trackCount; t++) { + while (ttyp[ttypidx] == 0) { + ttypidx++; + } + ttyp[ttypidx]--; + auto track = event.addTrack({.time = time[t], + .charge = crge[t], + .PID = (int)tpid[t], + .startXYZ = {sxyz[3 * t + 0], sxyz[3 * t + 1], sxyz[3 * t + 2]}, + .phi = atpe[3 * t + 1], + .theta = atpe[3 * t + 0], + .eta = atpe[3 * t + 2], + .gid = deserialize(tgid[t])}); + track->mPolyX.reserve(telm[t]); + track->mPolyY.reserve(telm[t]); + track->mPolyZ.reserve(telm[t]); + while (telm[t]-- > 0) { + track->mPolyX.push_back(txyz[txyzidx++]); + track->mPolyY.push_back(txyz[txyzidx++]); + track->mPolyZ.push_back(txyz[txyzidx++]); + } + track->mClusters.reserve(celm[t]); + while (celm[t]-- > 0) { + VisualisationCluster cluster(cxyz + cxyzidx, 0, 0); + cxyzidx += 3; + track->mClusters.push_back(cluster); + } + } + + // Clusters + for (auto c = 0u; c < clusterCount; c++) { + event.addGlobalCluster(uxyz + 3 * c, utim[c], deserialize(ugid[c])); + } + + // Calos + auto idx = 0; + for (auto c = 0u; c < phsCaloCount + emcCaloCount; c++) { + auto phi = calo[idx++]; + auto eta = calo[idx++]; + auto energy = calo[idx++]; + event.addCalo({.time = calt[c], + .energy = energy, + .phi = phi, + .eta = eta, + .PID = deserialize(calp[c]), + .gid = deserialize(calg[c])}); + } + + break; + } + } + return false; +} + +} // namespace event_visualisation +} // namespace o2 diff --git a/EventVisualisation/DataConverter/src/VisualisationEventROOTSerializer.cxx b/EventVisualisation/DataConverter/src/VisualisationEventROOTSerializer.cxx index fd9e70aa02153..730af08b5fd61 100644 --- a/EventVisualisation/DataConverter/src/VisualisationEventROOTSerializer.cxx +++ b/EventVisualisation/DataConverter/src/VisualisationEventROOTSerializer.cxx @@ -38,7 +38,7 @@ void VisualisationEventROOTSerializer::save(const char* name, const std::string& std::string VisualisationEventROOTSerializer::readString(TFile& f, const char* name) { - TNamed* v = (TNamed*)f.Get(name); + auto* v = (TNamed*)f.Get(name); if (v == nullptr) { return ""; } @@ -47,16 +47,23 @@ std::string VisualisationEventROOTSerializer::readString(TFile& f, const char* n return result; } -void VisualisationEventROOTSerializer::save(const char* name, int value) +void VisualisationEventROOTSerializer::saveInt(const char* name, int value) { TParameter obj; obj.SetVal(value); obj.Write(name); } +void VisualisationEventROOTSerializer::saveUInt64(const char* name, uint64_t value) +{ + TParameter obj; + obj.SetVal((long)value); + obj.Write(name); +} + int VisualisationEventROOTSerializer::readInt(TFile& f, const char* name) { - TParameter* v = (TParameter*)f.Get(name); + auto v = (TParameter*)f.Get(name); if (v == nullptr) { return 0; } @@ -65,34 +72,58 @@ int VisualisationEventROOTSerializer::readInt(TFile& f, const char* name) return result; } +uint64_t VisualisationEventROOTSerializer::readUInt64(TFile& f, const char* name) +{ + auto v = (TParameter*)f.Get(name); + if (v == nullptr) { + return 0; + } + uint64_t result = v->GetVal(); + free(v); + return result; +} + +bool VisualisationEventROOTSerializer::existUInt64(TFile& f, const char* name) +{ + auto v = (TParameter*)f.Get(name); + if (v == nullptr) { + return false; + } + free(v); + return true; +} + void VisualisationEventROOTSerializer::toFile(const VisualisationEvent& event, std::string fileName) { TFile f(fileName.c_str(), "recreate"); - save("runNumber", event.mRunNumber); - save("runType", event.mRunType); - save("clMask", event.mClMask); - save("trkMask", event.mTrkMask); - save("tfCounter", event.mTfCounter); - save("firstTForbit", event.mFirstTForbit); - save("primaryVertex", event.mPrimaryVertex); - save("collisionTime", event.mCollisionTime); - save("eveVersion", event.mEveVersion); - save("workflowParameters", event.mWorkflowParameters); + saveInt("runNumber", event.mRunNumber); + saveInt("runType", event.mRunType); + saveInt("clMask", event.mClMask); + saveInt("trkMask", event.mTrkMask); + saveInt("tfCounter", event.mTfCounter); + saveInt("firstTForbit", event.mFirstTForbit); + saveInt("primaryVertex", event.mPrimaryVertex); + saveUInt64("creationTime", event.mCreationTime); + std::string version = std::to_string(event.mEveVersion / 100.0); + save("eveVersion", version); // obsolete + saveInt("version", event.mEveVersion); + // save("workflowParameters", event.mWorkflowParameters); // clusters TNtuple xyz("xyz", "xyz", "x:y:z"); long xyzPos = 0L; + TTree clusters("clusters", "Clusters"); long cluster_xyz; - int cluster_source; + unsigned cluster_bgid; float cluster_time; - clusters.Branch("source", &cluster_source); + clusters.Branch("BGID", &cluster_bgid); clusters.Branch("time", &cluster_time); clusters.Branch("xyz", &cluster_xyz); for (auto cluster : event.getClustersSpan()) { - cluster_source = cluster.getSource(); cluster_time = cluster.Time(); + cluster_bgid = serialize(cluster.mBGID); cluster_xyz = xyzPos; xyz.Fill(cluster.X(), cluster.Y(), cluster.Z()); xyzPos++; @@ -103,8 +134,7 @@ void VisualisationEventROOTSerializer::toFile(const VisualisationEvent& event, s long track_xyz; // first track point int track_points; // number of track points int track_clusters; // number of track clusters - int track_source; - std::string track_GID; + unsigned track_BGID; // binary GID float track_time; int track_charge; float track_theta; @@ -120,8 +150,7 @@ void VisualisationEventROOTSerializer::toFile(const VisualisationEvent& event, s tracks.Branch("phi", &track_phi); tracks.Branch("eta", &track_eta); tracks.Branch("PID", &track_PID); - tracks.Branch("GID", &track_GID); - tracks.Branch("source", &track_source); + tracks.Branch("BGID", &track_BGID); tracks.Branch("points", &track_points); tracks.Branch("clusters", &track_clusters); @@ -133,8 +162,7 @@ void VisualisationEventROOTSerializer::toFile(const VisualisationEvent& event, s track_phi = std::isnan(track.mPhi) ? 0 : track.mPhi; track_eta = std::isnan(track.mEta) ? 0 : track.mEta; track_PID = track.mPID; - track_GID = track.mGID; - track_source = track.mSource; + track_BGID = serialize(track.mBGID); xyz.Fill(track.mStartCoordinates[0], track.mStartCoordinates[1], track.mStartCoordinates[2]); xyzPos++; @@ -152,43 +180,43 @@ void VisualisationEventROOTSerializer::toFile(const VisualisationEvent& event, s tracks.Fill(); } + clusters.Write(); + // calorimeters TTree calo("calo", "Calorimeters"); - int calo_source; float calo_time; float calo_energy; float calo_eta; float calo_phi; - std::string calo_GID; int calo_PID; + unsigned calo_BGID; - calo.Branch("source", &calo_source); calo.Branch("time", &calo_time); calo.Branch("energy", &calo_energy); calo.Branch("eta", &calo_eta); calo.Branch("phi", &calo_phi); - calo.Branch("GID", &calo_GID); + calo.Branch("BGID", &calo_BGID); calo.Branch("PID", &calo_PID); - for (auto calorimeter : event.getCalorimetersSpan()) { - calo_source = calorimeter.getSource(); + for (const auto& calorimeter : event.getCalorimetersSpan()) { calo_time = calorimeter.getTime(); calo_energy = calorimeter.getEnergy(); calo_eta = calorimeter.getEta(); calo_phi = calorimeter.getPhi(); - calo_GID = calorimeter.getGIDAsString(); + calo_BGID = serialize(calorimeter.mBGID); calo_PID = calorimeter.getPID(); calo.Fill(); } - tracks.Write(); - clusters.Write(); calo.Write(); + + tracks.Write(); + xyz.Write(); } bool VisualisationEventROOTSerializer::fromFile(VisualisationEvent& event, std::string fileName) { - LOGF(info, "VisualisationEventROOTSerializer <- ", fileName); + // LOGF(info, "VisualisationEventROOTSerializer <- %s ", fileName); event.mTracks.clear(); event.mClusters.clear(); event.mCalo.clear(); @@ -203,18 +231,29 @@ bool VisualisationEventROOTSerializer::fromFile(VisualisationEvent& event, std:: event.setFirstTForbit(readInt(f, "firstTForbit")); event.mPrimaryVertex = readInt(f, "primaryVertex"); - event.setCollisionTime(readString(f, "collisionTime")); - event.mEveVersion = readString(f, "eveVersion"); - event.mWorkflowParameters = readString(f, "workflowParameters"); + if (existUInt64(f, "creationTime")) { + event.setCreationTime(readInt(f, "creationTime")); + } else { + auto collisionTime = readString(f, "collisionTime"); + event.mCreationTime = parseDateTime(collisionTime.c_str()); + } + + event.mEveVersion = 0; + if (f.Get("version") != nullptr) { + event.mEveVersion = readInt(f, "version"); + } else { + std::string version = readString(f, "eveVersion"); + event.mEveVersion = (int)(100 * std::stof(version)); + } // xyz - TNtuple* xyz = (TNtuple*)f.Get("xyz"); + auto* xyz = (TNtuple*)f.Get("xyz"); if (xyz == nullptr) { return false; } // tracks - TTree* tracks = (TTree*)f.Get("tracks"); + auto* tracks = (TTree*)f.Get("tracks"); if (tracks == nullptr) { delete xyz; return false; @@ -223,8 +262,9 @@ bool VisualisationEventROOTSerializer::fromFile(VisualisationEvent& event, std:: long track_xyz; // first track point int track_points; // number of track points int track_clusters; // number of track clusters - int track_source; + int track_source; // obsolete std::string* track_GID = nullptr; + unsigned track_BGID; float track_time; int track_charge; float track_theta; @@ -239,12 +279,22 @@ bool VisualisationEventROOTSerializer::fromFile(VisualisationEvent& event, std:: tracks->SetBranchAddress("phi", &track_phi); tracks->SetBranchAddress("eta", &track_eta); tracks->SetBranchAddress("PID", &track_PID); - tracks->SetBranchAddress("GID", &track_GID); - tracks->SetBranchAddress("source", &track_source); + auto gid = tracks->GetBranch("GID"); // obsolete + if (gid != nullptr) { + tracks->SetBranchAddress("GID", &track_GID); + } + auto bgid = tracks->GetBranch("BGID"); + if (bgid != nullptr) { + tracks->SetBranchAddress("BGID", &track_BGID); + } + auto source = tracks->GetBranch("source"); // obsolete + if (source != nullptr) { + tracks->SetBranchAddress("source", &track_source); + } tracks->SetBranchAddress("points", &track_points); tracks->SetBranchAddress("clusters", &track_clusters); - Int_t tracksNoOfEntries = (Int_t)tracks->GetEntries(); + auto tracksNoOfEntries = (Int_t)tracks->GetEntries(); for (Int_t i = 0; i < tracksNoOfEntries; i++) { tracks->GetEntry(i); VisualisationTrack track; @@ -254,97 +304,137 @@ bool VisualisationEventROOTSerializer::fromFile(VisualisationEvent& event, std:: track.mPhi = track_phi; track.mEta = track_eta; track.mPID = track_PID; - track.mGID = *track_GID; - track.mSource = (o2::dataformats::GlobalTrackID::Source)track_source; + if (bgid) { + track.mBGID = deserialize(track_BGID); + } else { + track.mBGID = gidFromString(*track_GID); + } xyz->GetEntry(track_xyz); track.addStartCoordinates(xyz->GetArgs()); - for (size_t i = 0; i < track_points; i++) { - xyz->GetEntry(track_xyz + 1 + i); + for (int p = 0; p < track_points; p++) { + xyz->GetEntry(track_xyz + 1 + p); track.addPolyPoint(xyz->GetArgs()); } - for (size_t i = 0; i < track_clusters; i++) { - xyz->GetEntry(track_xyz + 1 + track_points + i); - VisualisationCluster cluster(xyz->GetArgs(), track.mTime); - cluster.mSource = track.mSource; + for (size_t it = 0; it < track_clusters; it++) { + xyz->GetEntry(track_xyz + 1 + track_points + it); + VisualisationCluster cluster(xyz->GetArgs(), track.mTime, track.mBGID); track.mClusters.emplace_back(cluster); } event.mTracks.emplace_back(track); } - if (track_GID != nullptr) { + + if (gid != nullptr) { delete track_GID; track_GID = nullptr; } - TTree* clusters = (TTree*)f.Get("clusters"); - if (clusters == nullptr) { + if (!readClusters(event, f, xyz)) { delete xyz; delete tracks; return false; } + if (!readCalo(event, f)) { + delete xyz; + delete tracks; + return false; + } + + delete tracks; + delete xyz; + + event.afterLoading(); + return true; +} + +bool VisualisationEventROOTSerializer::readClusters(VisualisationEvent& event, TFile& f, TNtuple* xyz) +{ + auto* clusters = (TTree*)f.Get("clusters"); + if (clusters == nullptr) { + return false; + } + long cluster_xyz; int cluster_source; + unsigned cluster_BGID; + float cluster_time; - clusters->SetBranchAddress("source", &cluster_source); + auto source = clusters->GetBranch("source"); // obsolete + if (source != nullptr) { + clusters->SetBranchAddress("source", &cluster_source); + } + + auto bgid = clusters->GetBranch("BGID"); + if (bgid != nullptr) { + clusters->SetBranchAddress("BGID", &cluster_BGID); + } + clusters->SetBranchAddress("time", &cluster_time); clusters->SetBranchAddress("xyz", &cluster_xyz); - Int_t clustersNoOfEntries = (Int_t)clusters->GetEntries(); + auto clustersNoOfEntries = (Int_t)clusters->GetEntries(); for (Int_t i = 0; i < clustersNoOfEntries; i++) { clusters->GetEntry(i); xyz->GetEntry(cluster_xyz); - VisualisationCluster cluster(xyz->GetArgs(), cluster_time); - cluster.mSource = (o2::dataformats::GlobalTrackID::Source)cluster_source; + dataformats::GlobalTrackID gid = 0; + if (bgid) { + gid = deserialize(cluster_BGID); + } else if (source) { + gid = deserialize(cluster_source, 0, 0); + } + VisualisationCluster cluster(xyz->GetArgs(), cluster_time, gid); event.mClusters.emplace_back(cluster); } + delete clusters; + return true; +} - // calorimeters - TTree* calo = (TTree*)f.Get("calo"); +bool VisualisationEventROOTSerializer::readCalo(VisualisationEvent& event, TFile& f) +{ + auto* calo = (TTree*)f.Get("calo"); if (calo == nullptr) { - delete xyz; - delete tracks; - delete clusters; return false; } + int calo_source; float calo_time; float calo_energy; float calo_eta; float calo_phi; - std::string* calo_GID = nullptr; + unsigned calo_BGID; int calo_PID; - calo->SetBranchAddress("source", &calo_source); + auto source = calo->GetBranch("source"); + if (source != nullptr) { + calo->SetBranchAddress("source", &calo_source); + } + auto bgid = calo->GetBranch("BGID"); + if (bgid != nullptr) { + calo->SetBranchAddress("BGID", &calo_BGID); + } + calo->SetBranchAddress("time", &calo_time); calo->SetBranchAddress("energy", &calo_energy); calo->SetBranchAddress("eta", &calo_eta); calo->SetBranchAddress("phi", &calo_phi); - calo->SetBranchAddress("GID", &calo_GID); calo->SetBranchAddress("PID", &calo_PID); - Int_t nentries = (Int_t)calo->GetEntries(); + auto nentries = (Int_t)calo->GetEntries(); for (Int_t i = 0; i < nentries; i++) { calo->GetEntry(i); VisualisationCalo calorimeter; - calorimeter.mSource = (o2::dataformats::GlobalTrackID::Source)calo_source; calorimeter.mTime = calo_time; calorimeter.mEnergy = calo_energy; calorimeter.mEta = calo_eta; calorimeter.mPhi = calo_phi; - if (calo_GID) { - calorimeter.mGID = *calo_GID; + if (bgid) { + calorimeter.mBGID = deserialize(calo_BGID); + } else { + calorimeter.mBGID = deserialize(calo_source, 0, 0); } calorimeter.mPID = calo_PID; event.mCalo.emplace_back(calorimeter); } - if (calo_GID != nullptr) { - delete calo_GID; - calo_GID = nullptr; - } delete calo; - delete tracks; - delete xyz; - delete clusters; - event.afterLoading(); return true; } diff --git a/EventVisualisation/DataConverter/src/VisualisationEventSerializer.cxx b/EventVisualisation/DataConverter/src/VisualisationEventSerializer.cxx index 03818458864b3..286be66f3891d 100644 --- a/EventVisualisation/DataConverter/src/VisualisationEventSerializer.cxx +++ b/EventVisualisation/DataConverter/src/VisualisationEventSerializer.cxx @@ -17,15 +17,18 @@ #include "EventVisualisationDataConverter/VisualisationEventSerializer.h" #include "EventVisualisationDataConverter/VisualisationEventJSONSerializer.h" #include "EventVisualisationDataConverter/VisualisationEventROOTSerializer.h" +#include "EventVisualisationDataConverter/VisualisationEventOpenGLSerializer.h" #include #include #include +#include namespace o2::event_visualisation { std::map VisualisationEventSerializer::instances = { {".json", new o2::event_visualisation::VisualisationEventJSONSerializer()}, - {".root", new o2::event_visualisation::VisualisationEventROOTSerializer()}}; + {".root", new o2::event_visualisation::VisualisationEventROOTSerializer()}, + {".eve", new o2::event_visualisation::VisualisationEventOpenGLSerializer()}}; std::string VisualisationEventSerializer::fileNameIndexed(const std::string fileName, const int index) { @@ -34,4 +37,92 @@ std::string VisualisationEventSerializer::fileNameIndexed(const std::string file return buffer.str(); } +o2::dataformats::GlobalTrackID VisualisationEventSerializer::deserialize(unsigned int serializedValue) +{ + o2::dataformats::GlobalTrackID result; + *((unsigned*)&(result)) = serializedValue; + return result; +} + +unsigned VisualisationEventSerializer::serialize(o2::dataformats::GlobalTrackID gidValue) +{ + unsigned result; + result = *((unsigned*)&(gidValue)); + return result; +} + +o2::dataformats::GlobalTrackID + VisualisationEventSerializer::deserialize(unsigned int source, unsigned int index, unsigned int flags) +{ + return serialize(index + source * (1 << 25) + flags * (1 << 30)); +} + +o2::dataformats::GlobalTrackID VisualisationEventSerializer::gidFromString(const std::string& gid) +{ + static std::map sources = { + {"ITS", 0}, + {"TPC", 1}, + {"TRD", 2}, + {"TOF", 3}, + {"PHS", 4}, + {"CPV", 5}, + {"EMC", 6}, + {"HMP", 7}, + {"MFT", 8}, + {"MCH", 9}, + {"MID", 10}, + {"ZDC", 11}, + {"FT0", 12}, + {"FV0", 13}, + {"FDD", 14}, + {"ITS-TPC", 15}, + {"TPC-TOF", 16}, + {"TPC-TRD", 17}, + {"MFT-MCH", 18}, + {"ITS-TPC-TRD", 19}, + {"ITS-TPC-TOF", 20}, + {"TPC-TRD-TOF", 21}, + {"MFT-MCH-MID", 22}, + {"ITS-TPC-TRD-TOF", 23}, // full barrel track + {"ITSAB", 24}, // ITS AfterBurner tracklets + {"CTP", 25}}; + const auto first = gid.find('/'); + const auto second = gid.find('/', first + 1); + auto source = sources[gid.substr(1, first - 1)]; + auto index = std::stoi(gid.substr(first + 1, second - 1)); + auto flags = std::stoi(gid.substr(second + 1, gid.size() - 1)); + return index + source * (1 << 25) + flags * (1 << 30); +} + +time_t VisualisationEventSerializer::parseDateTime(const char* datetimeString) +{ + std::string date(datetimeString); + date += " GMT"; + const char* format = "%A %B %d %H:%M:%S %Y %Z"; + struct tm tmStruct; + strptime(datetimeString, format, &tmStruct); + return mktime(&tmStruct); +} + +std::string VisualisationEventSerializer::DateTime(time_t time) +{ + char buffer[90]; + const char* format = "%a %b %-d %H:%M:%S %Y"; + struct tm* timeinfo = localtime(&time); + strftime(buffer, sizeof(buffer), format, timeinfo); + return buffer; +} + +std::string VisualisationEventSerializer::bits(unsigned number) +{ + char result[33]; + result[32] = 0; + unsigned mask = 1; + for (int i = 31; i >= 0; i--) { + result[i] = (mask & number) ? '1' : '0'; + mask <<= 1; + } + return result; +} + } // namespace o2::event_visualisation diff --git a/EventVisualisation/DataConverter/src/VisualisationTrack.cxx b/EventVisualisation/DataConverter/src/VisualisationTrack.cxx index f8ccce685a86f..bc8d2adc07260 100644 --- a/EventVisualisation/DataConverter/src/VisualisationTrack.cxx +++ b/EventVisualisation/DataConverter/src/VisualisationTrack.cxx @@ -29,12 +29,12 @@ VisualisationTrack::VisualisationTrack(const VisualisationTrackVO& vo) { this->mCharge = vo.charge; this->mPID = vo.PID; - this->mGID = vo.gid; + this->mBGID = vo.gid; this->mTheta = vo.theta; this->mPhi = vo.phi; this->mEta = vo.eta; this->addStartCoordinates(vo.startXYZ); - this->mSource = vo.source; + // this->mSource = vo.source; this->mTime = vo.time; } @@ -42,12 +42,12 @@ VisualisationTrack::VisualisationTrack(const VisualisationTrack& src) { this->mCharge = src.mCharge; this->mPID = src.mPID; - this->mGID = src.mGID; + this->mBGID = src.mBGID; this->mTheta = src.mTheta; this->mPhi = src.mPhi; this->mEta = src.mEta; this->addStartCoordinates(src.getStartCoordinates()); - this->mSource = src.mSource; + // this->mSource = src.mSource; this->mTime = src.mTime; this->mPolyX = src.mPolyX; @@ -77,9 +77,9 @@ void VisualisationTrack::addPolyPoint(const float p[]) mPolyZ.push_back(p[2]); } -VisualisationCluster& VisualisationTrack::addCluster(float pos[]) +VisualisationCluster& VisualisationTrack::addCluster(const float pos[]) { - mClusters.emplace_back(pos, 0); + mClusters.emplace_back(pos, this->mTime, this->mBGID); return mClusters.back(); } diff --git a/EventVisualisation/DataConverter/src/converter.cxx b/EventVisualisation/DataConverter/src/converter.cxx index f33638f686d5c..a0820d2e6feef 100644 --- a/EventVisualisation/DataConverter/src/converter.cxx +++ b/EventVisualisation/DataConverter/src/converter.cxx @@ -13,45 +13,145 @@ /// \file converter.cxx /// \author julian.myrcha@cern.ch +#include "EventVisualisationDataConverter/VisualisationEvent.h" #include "EventVisualisationView/Initializer.h" #include "EventVisualisationView/Options.h" -#include #include #include +#include +#include #include #include #include #include #include +#include +#include +#include -int main(int argc, char** argv) -{ - LOGF(info, "Welcome in O2 event conversion tool"); - if (argc != 3) { - LOGF(error, "two filename required, second should point to not existent file"); - exit(-1); - } - - std::string src = argv[1]; - std::string dst = argv[2]; +using namespace std::chrono_literals; +// source file name, destination (not existing) file name, if limit > 0 then limit EACH type of data +int singleFileConversion(const std::string& src, const std::string& dst, const int limit = -1) +{ + LOGF(info, "Translate: %s -> %s", src, dst); o2::event_visualisation::VisualisationEvent vEvent; - auto srcSerializer = o2::event_visualisation::VisualisationEventSerializer::getInstance(std::filesystem::path(src).extension()); - auto dstSerializer = o2::event_visualisation::VisualisationEventSerializer::getInstance(std::filesystem::path(dst).extension()); + auto srcSerializer = o2::event_visualisation::VisualisationEventSerializer::getInstance( + std::filesystem::path(src).extension()); + auto dstSerializer = o2::event_visualisation::VisualisationEventSerializer::getInstance( + std::filesystem::path(dst).extension()); std::chrono::time_point currentTime = std::chrono::high_resolution_clock::now(); std::chrono::time_point endTime = std::chrono::high_resolution_clock::now(); srcSerializer->fromFile(vEvent, src); endTime = std::chrono::high_resolution_clock::now(); - LOGF(info, "read took ", - std::chrono::duration_cast(endTime - currentTime).count() * 1e-6); + // LOGF(info, "read took %f", std::chrono::duration_cast(endTime - currentTime).count() * 1e-6); + if (limit > 0) { + vEvent = vEvent.limit(limit); + } currentTime = std::chrono::high_resolution_clock::now(); dstSerializer->toFile(vEvent, dst); endTime = std::chrono::high_resolution_clock::now(); - LOGF(info, "write took ", - std::chrono::duration_cast(endTime - currentTime).count() * 1e-6); + // LOGF(info, "write took %f", std::chrono::duration_cast(endTime - currentTime).count() * 1e-6); return 0; } + +// reads source folder files, find missing files in destination folder and convert them +// source folder (/path-to-folder/.ext1) , destination folder (/path-to-folder/.ext2) +int folderConversion(const std::string& srcFolder, const std::string& dstFolder) +{ + std::vector supported = {".json", ".root", ".eve"}; + auto ext1 = srcFolder.substr(srcFolder.rfind('.')); + auto ext2 = dstFolder.substr(dstFolder.rfind('.')); + + if (supported.end() == std::find(supported.begin(), supported.end(), ext1)) { + LOGF(error, "source folder should end with source extension: /path-to-folder/.ext1 "); + exit(-1); + } + if (supported.end() == std::find(supported.begin(), supported.end(), ext2)) { + LOGF(error, "destination folder should end with destination extension: /path-to-folder/.ext2 "); + return -1; + } + auto src = srcFolder.substr(0, srcFolder.size() - std::string(ext1).size()); + auto dst = dstFolder.substr(0, dstFolder.size() - std::string(ext2).size()); + + if (src == dst) { + LOGF(error, "source folder same as destination folder "); + return -1; + } + if (!std::filesystem::is_directory(src)) { + LOGF(error, "source folder do not exist "); + return -1; + } + if (!std::filesystem::is_directory(dst)) { + LOGF(error, "destination folder do not exist "); + return -1; + } + std::vector vExt1 = {ext1}; + auto sourceList = o2::event_visualisation::DirectoryLoader::load(src, "_", vExt1); + std::vector vExt2 = {ext2}; + auto destinationList = o2::event_visualisation::DirectoryLoader::load(dst, "_", vExt2); + + // first delete destination files which has not corresponding source files + for (auto& e : destinationList) { + auto match = e.substr(0, e.size() - ext2.size()) + ext1; + if (sourceList.end() == std::find(sourceList.begin(), sourceList.end(), match)) { + auto path = std::filesystem::path(dst + "" + e); + std::filesystem::remove(path); + } + } + + // second translate source files which has not corresponding destination files + for (auto& e : sourceList) { + auto match = e.substr(0, e.size() - ext1.size()) + ext2; + if (destinationList.end() == std::find(destinationList.begin(), destinationList.end(), match)) { + // LOGF(info, "translate %s ->%s", src+e, dst+match); + singleFileConversion(src + e, dst + match); + } + } + + return 0; +} + +void my_handler(int s) +{ + printf("Caught signal %d\n", s); + exit(1); +} + +int main(int argc, char** argv) +{ + struct sigaction sigIntHandler { + }; + sigIntHandler.sa_handler = my_handler; + sigemptyset(&sigIntHandler.sa_mask); + sigIntHandler.sa_flags = 0; + + sigaction(SIGINT, &sigIntHandler, nullptr); + LOGF(info, "Welcome in O2 event conversion tool"); + + if (argc == 3) { + singleFileConversion(argv[1], argv[2]); // std::quick_exit(... + return 0; + } + if (argc == 4 and std::string(argv[1]) == std::string("-l")) { + singleFileConversion(argv[2], argv[3], 3); // std::quick_exit(... + return 0; + } + if (argc == 4 and std::string(argv[1]) == std::string("-f")) { + folderConversion(argv[2], argv[3]); // std::quick_exit(... + return 0; + } + if (argc == 4 and std::string(argv[1]) == std::string("-c")) { + while (true) { + std::this_thread::sleep_for(2000ms); + folderConversion(argv[2], argv[3]); + } + return 0; + } + LOGF(error, "two filename required, second should point to not existent file"); + return -1; // std::quick_exit(-1); +} diff --git a/EventVisualisation/View/src/EventManager.cxx b/EventVisualisation/View/src/EventManager.cxx index 0c0756583aa83..695a4467cbf61 100644 --- a/EventVisualisation/View/src/EventManager.cxx +++ b/EventVisualisation/View/src/EventManager.cxx @@ -125,10 +125,11 @@ void EventManager::displayCurrentEvent() if (dataSource->getRunNumber() != -1) { if (this->mShowDate) { + std::string creationTime = dataSource->getCreationTimeAsString(); multiView->getAnnotationTop()->SetText( TString::Format("Run %d %s\n%s", dataSource->getRunNumber(), std::string(parameters::GRPECS::RunTypeNames[dataSource->getRunType()]).c_str(), - dataSource->getFileTime().c_str())); + creationTime.c_str())); } else { multiView->getAnnotationTop()->SetText(TString::Format("Run %d", dataSource->getRunNumber())); } @@ -426,7 +427,8 @@ void EventManager::saveVisualisationSettings() return arr; }; - d.AddMember("version", rapidjson::Value().SetString(o2_eve_version.c_str(), o2_eve_version.length()), allocator); + std::string version = std::to_string(o2_eve_version / 100.0); + d.AddMember("version", rapidjson::Value().SetString(version.c_str(), version.length()), allocator); // obsolete d.AddMember("trackVisibility", jsonArray(vizSettings.trackVisibility, allocator), allocator); d.AddMember("trackColor", jsonArray(vizSettings.trackColor, allocator), allocator); d.AddMember("trackStyle", jsonArray(vizSettings.trackStyle, allocator), allocator); @@ -477,7 +479,8 @@ void EventManager::restoreVisualisationSettings() Document d; d.Parse(json.c_str()); - if (VisualisationEventJSONSerializer::getStringOrDefault(d, "version", "0.0") != o2_eve_version) { + std::string version = std::to_string(o2_eve_version / 100.0); + if (VisualisationEventJSONSerializer::getStringOrDefault(d, "version", "0.0") != version) { LOGF(info, "visualisation settings has wrong version and was not restored"); return; } diff --git a/EventVisualisation/View/src/EventManagerFrame.cxx b/EventVisualisation/View/src/EventManagerFrame.cxx index ff5ee59047abb..6af49953d7e40 100644 --- a/EventVisualisation/View/src/EventManagerFrame.cxx +++ b/EventVisualisation/View/src/EventManagerFrame.cxx @@ -360,7 +360,7 @@ void EventManagerFrame::DoScreenshot() this->mEventManager->getDataSource()->getDetectorsMask(), this->mEventManager->getDataSource()->getRunNumber(), this->mEventManager->getDataSource()->getFirstTForbit(), - this->mEventManager->getDataSource()->getCollisionTime()); + this->mEventManager->getDataSource()->getCreationTimeAsString()); fileName.replace_extension( std::filesystem::path(mEventManager->getDataSource()->getEventAbsoluteFilePath()).extension()); std::error_code ec; @@ -416,7 +416,7 @@ void EventManagerFrame::createOutreachScreenshot() Screenshot::perform("outreach", fileName, this->mEventManager->getDataSource()->getDetectorsMask(), this->mEventManager->getDataSource()->getRunNumber(), this->mEventManager->getDataSource()->getFirstTForbit(), - this->mEventManager->getDataSource()->getCollisionTime()); + this->mEventManager->getDataSource()->getCreationTimeAsString()); } skipCounter = (int)ConfigurationManager::getOutreachFrequencyInRefreshRates(); } diff --git a/EventVisualisation/View/src/Initializer.cxx b/EventVisualisation/View/src/Initializer.cxx index e9572e24f991d..92bfa93e0d738 100644 --- a/EventVisualisation/View/src/Initializer.cxx +++ b/EventVisualisation/View/src/Initializer.cxx @@ -83,7 +83,8 @@ void Initializer::setup() // Setup windows size, fullscreen and focus TEveBrowser* browser = gEve->GetBrowser(); - std::string title = std::string("o2-eve v:") + o2_eve_version; + std::string title = std::string("o2-eve version:") + std::to_string(o2_eve_version / 100.0); + title = title.substr(0, title.find('.') + 3); browser->SetWindowName(title.c_str()); browser->GetTabRight()->SetTab(1); browser->MoveResize(0, 0, gClient->GetDisplayWidth(), gClient->GetDisplayHeight() - 32); diff --git a/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h b/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h index f8bef1100227f..66bf6a38987b9 100644 --- a/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h +++ b/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h @@ -167,17 +167,17 @@ class EveWorkflowHelper void drawAODMFT(AODMFTTrack const& track, float trackTime); void drawAODFwd(AODForwardTrack const& track, float trackTime); - void drawMFTTrack(o2::track::TrackParFwd track, float trackTime); - void drawForwardTrack(mch::TrackParam track, const std::string& gidString, GID::Source source, float startZ, float endZ, float trackTime); - void drawITSClusters(GID gid, float trackTime); - void drawTPCClusters(GID gid, float trackTime); - void drawMFTClusters(GID gid, float trackTime); - void drawMCHClusters(GID gid, float trackTime); - void drawMIDClusters(GID gid, float trackTime); - void drawTRDClusters(const o2::trd::TrackTRD& trc, float trackTime); - void drawTOFClusters(GID gid, float trackTime); - void drawPoint(float x, float y, float z, float trackTime) { mEvent.addCluster(x, y, z, trackTime); } - void drawGlobalPoint(const TVector3& xyx) { mEvent.addGlobalCluster(xyx); } + void drawMFTTrack(GID gid, o2::track::TrackParFwd track, float trackTime); + void drawForwardTrack(GID gid, mch::TrackParam track, float startZ, float endZ, float trackTime); + void drawITSClusters(GID gid); + void drawTPCClusters(GID gid); + void drawMFTClusters(GID gid); + void drawMCHClusters(GID gid); + void drawMIDClusters(GID gid); + void drawTRDClusters(const o2::trd::TrackTRD& trc); + void drawTOFClusters(GID gid); + void drawPoint(const float xyz[]) { mEvent.addCluster(xyz); } + void drawGlobalPoint(const TVector3& xyx, GID gid, float time) { mEvent.addGlobalCluster(xyx, gid, time); } void prepareITSClusters(const o2::itsmft::TopologyDictionary* dict); // fills mITSClustersArray void prepareMFTClusters(const o2::itsmft::TopologyDictionary* dict); // fills mMFTClustersArray void clear() { mEvent.clear(); } @@ -192,13 +192,7 @@ class EveWorkflowHelper bool isInsideITSROF(float t); bool isInsideTimeBracket(float t); - void save(const std::string& jsonPath, - const std::string& ext, - int numberOfFiles, - o2::dataformats::GlobalTrackID::mask_t trkMask, - o2::dataformats::GlobalTrackID::mask_t clMask, - o2::header::DataHeader::RunNumberType runNumber, - o2::framework::DataProcessingHeader::CreationTime creationTime); + void save(const std::string& jsonPath, const std::string& ext, int numberOfFiles); FilterSet mEnabledFilters; std::size_t mMaxNTracks; diff --git a/EventVisualisation/Workflow/src/AO2DConverter.cxx b/EventVisualisation/Workflow/src/AO2DConverter.cxx index a1ae1b1c5623f..d339b150265de 100644 --- a/EventVisualisation/Workflow/src/AO2DConverter.cxx +++ b/EventVisualisation/Workflow/src/AO2DConverter.cxx @@ -73,8 +73,9 @@ struct AO2DConverter { mHelper->mEvent.setRunNumber(mRunNumber); mHelper->mEvent.setTfCounter(mTfCounter); mHelper->mEvent.setFirstTForbit(mTfOrbit); + mHelper->mEvent.setCreationTime(collision.collisionTime()); - mHelper->save(jsonPath, ".root", -1, GlobalTrackID::MASK_ALL, GlobalTrackID::MASK_NONE, mRunNumber, collision.collisionTime()); + mHelper->save(jsonPath, ".root", -1); mHelper->clear(); } }; diff --git a/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx b/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx index 51a8a44634142..4a8fe684d9f29 100644 --- a/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx +++ b/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx @@ -462,22 +462,9 @@ void EveWorkflowHelper::draw(std::size_t primaryVertexIdx, bool sortTracks) } } -void EveWorkflowHelper::save(const std::string& jsonPath, const std::string& ext, int numberOfFiles, - o2::dataformats::GlobalTrackID::mask_t trkMask, o2::dataformats::GlobalTrackID::mask_t clMask, - o2::header::DataHeader::RunNumberType runNumber, o2::framework::DataProcessingHeader::CreationTime creation) +void EveWorkflowHelper::save(const std::string& jsonPath, const std::string& ext, int numberOfFiles) { mEvent.setEveVersion(o2_eve_version); - mEvent.setRunNumber(runNumber); - std::time_t timeStamp = std::time(nullptr); - std::string asciiTimeStamp = std::asctime(std::localtime(&timeStamp)); - asciiTimeStamp.pop_back(); // remove trailing \n - mEvent.setWorkflowParameters(asciiTimeStamp + " t:" + trkMask.to_string() + " c:" + clMask.to_string()); - - std::time_t creationTime = creation / 1000; // convert to seconds - std::string asciiCreationTime = std::asctime(std::localtime(&creationTime)); - asciiCreationTime.pop_back(); // remove trailing \n - mEvent.setCollisionTime(asciiCreationTime); - FileProducer producer(jsonPath, ext, numberOfFiles); VisualisationEventSerializer::getInstance(ext)->toFile(mEvent, producer.newFileName()); } @@ -543,8 +530,7 @@ void EveWorkflowHelper::addTrackToEvent(const o2::track::TrackPar& tr, GID gid, .phi = tr.getPhi(), .theta = tr.getTheta(), .eta = tr.getEta(), - .gid = gid.asString(), - .source = source}); + .gid = gid}); const auto it = propagationRanges.find(source); @@ -604,7 +590,7 @@ void EveWorkflowHelper::drawHMP(GID gid) double y = cluster.y(); TVector3 vec3 = pParam->lors2Mars(module, x, y); - drawGlobalPoint(vec3); + drawGlobalPoint(vec3, gid, time); } } @@ -631,8 +617,7 @@ void EveWorkflowHelper::drawPHS(GID gid) .phi = (float)gPos.Phi(), .eta = (float)gPos.Eta(), .PID = 0, - .gid = GID::getSourceName(GID::PHS), - .source = GID::PHS}); + .gid = gid}); } } @@ -686,8 +671,7 @@ void EveWorkflowHelper::drawEMC(GID gid) .phi = (float)vPos.Phi(), .eta = (float)vPos.Eta(), .PID = 0, - .gid = GID::getSourceName(GID::EMC), - .source = GID::EMC}); + .gid = gid}); } } @@ -696,17 +680,17 @@ void EveWorkflowHelper::drawITSTPC(GID gid, float trackTime, GID::Source source) // LOG(info) << "EveWorkflowHelper::drawITSTPC " << gid; const auto& track = mRecoCont->getTPCITSTrack(gid); addTrackToEvent(track, gid, trackTime, 0., source); - drawITSClusters(track.getRefITS(), trackTime); - drawTPCClusters(track.getRefTPC(), trackTime * mMUS2TPCTimeBins); + drawITSClusters(track.getRefITS()); // trackTime + drawTPCClusters(track.getRefTPC()); // trackTime * mMUS2TPCTimeBins } void EveWorkflowHelper::drawITSTPCTOF(GID gid, float trackTime, GID::Source source) { const auto& track = mRecoCont->getITSTPCTOFTrack(gid); addTrackToEvent(track, gid, trackTime, 0., source); - drawITSClusters(track.getRefITS(), trackTime); - drawTPCClusters(track.getRefTPC(), trackTime * mMUS2TPCTimeBins); - drawTOFClusters(gid, trackTime); + drawITSClusters(track.getRefITS()); // trackTime + drawTPCClusters(track.getRefTPC()); // trackTime * mMUS2TPCTimeBins + drawTOFClusters(gid); } void EveWorkflowHelper::drawTPCTRD(GID gid, float trackTime, GID::Source source) @@ -714,8 +698,8 @@ void EveWorkflowHelper::drawTPCTRD(GID gid, float trackTime, GID::Source source) // LOG(info) << "EveWorkflowHelper::drawTPCTRD " << gid; const auto& tpcTrdTrack = mRecoCont->getTPCTRDTrack(gid); addTrackToEvent(tpcTrdTrack, gid, trackTime, 0., source); - drawTPCClusters(tpcTrdTrack.getRefGlobalTrackId(), trackTime * mMUS2TPCTimeBins); - drawTRDClusters(tpcTrdTrack, trackTime); + drawTPCClusters(tpcTrdTrack.getRefGlobalTrackId()); // trackTime * mMUS2TPCTimeBins + drawTRDClusters(tpcTrdTrack); // tracktime } void EveWorkflowHelper::drawITSTPCTRD(GID gid, float trackTime, GID::Source source) @@ -723,7 +707,7 @@ void EveWorkflowHelper::drawITSTPCTRD(GID gid, float trackTime, GID::Source sour // LOG(info) << "EveWorkflowHelper::drawITSTPCTRD " << gid; const auto& itsTpcTrdTrack = mRecoCont->getITSTPCTRDTrack(gid); drawITSTPC(itsTpcTrdTrack.getRefGlobalTrackId(), trackTime, source); - drawTRDClusters(itsTpcTrdTrack, trackTime); + drawTRDClusters(itsTpcTrdTrack); // trackTime } void EveWorkflowHelper::drawITSTPCTRDTOF(GID gid, float trackTime) @@ -732,7 +716,7 @@ void EveWorkflowHelper::drawITSTPCTRDTOF(GID gid, float trackTime) const auto& match = mRecoCont->getITSTPCTRDTOFMatches()[gid.getIndex()]; auto gidITSTPCTRD = match.getTrackRef(); drawITSTPCTRD(gidITSTPCTRD, trackTime, GID::ITSTPCTRDTOF); - drawTOFClusters(gid, trackTime); + drawTOFClusters(gid); // trackTime } void EveWorkflowHelper::drawTPCTRDTOF(GID gid, float trackTime) @@ -741,7 +725,7 @@ void EveWorkflowHelper::drawTPCTRDTOF(GID gid, float trackTime) const auto& match = mRecoCont->getTPCTRDTOFMatches()[gid.getIndex()]; auto gidTPCTRD = match.getTrackRef(); drawTPCTRD(gidTPCTRD, trackTime, GID::TPCTRDTOF); - drawTOFClusters(gid, trackTime); + drawTOFClusters(gid); // trackTime } void EveWorkflowHelper::drawTPCTOF(GID gid, float trackTime) @@ -750,8 +734,8 @@ void EveWorkflowHelper::drawTPCTOF(GID gid, float trackTime) const auto& trTPCTOF = mRecoCont->getTPCTOFTrack(gid); const auto& match = mRecoCont->getTPCTOFMatch(gid.getIndex()); addTrackToEvent(trTPCTOF, gid, trackTime, 0); - drawTPCClusters(match.getTrackRef(), trackTime * mMUS2TPCTimeBins); - drawTOFClusters(gid, trackTime); + drawTPCClusters(match.getTrackRef()); // trackTime * mMUS2TPCTimeBins + drawTOFClusters(gid); // trackTime } void EveWorkflowHelper::drawMFTMCH(GID gid, float trackTime) @@ -766,10 +750,10 @@ void EveWorkflowHelper::drawMFTMCH(GID gid, float trackTime) const auto endZ = findLastMCHClusterPosition(mchTrack); - drawForwardTrack(trackParam, gid.asString(), static_cast(gid.getSource()), mftZPositions.front(), endZ, trackTime); + drawForwardTrack(gid, trackParam, mftZPositions.front(), endZ, trackTime); - drawMFTClusters(GID{static_cast(trMFTMCH.getMFTTrackID()), GID::MFT}, trackTime); - drawMCHClusters(mchGID, trackTime); + drawMFTClusters(GID{static_cast(trMFTMCH.getMFTTrackID()), GID::MFT}); // tracktime + drawMCHClusters(mchGID); // tracktime } void EveWorkflowHelper::drawMFTMCHMID(GID gid, float trackTime) @@ -784,11 +768,11 @@ void EveWorkflowHelper::drawMFTMCHMID(GID gid, float trackTime) const auto endZ = findLastMIDClusterPosition(midTrack); - drawForwardTrack(trackParam, gid.asString(), static_cast(gid.getSource()), mftZPositions.front(), endZ, trackTime); + drawForwardTrack(gid, trackParam, mftZPositions.front(), endZ, trackTime); - drawMFTClusters(GID{static_cast(trMFTMCHMID.getMFTTrackID()), GID::MFT}, trackTime); - drawMCHClusters(GID{static_cast(trMFTMCHMID.getMCHTrackID()), GID::MCH}, trackTime); - drawMIDClusters(midGID, trackTime); + drawMFTClusters(GID{static_cast(trMFTMCHMID.getMFTTrackID()), GID::MFT}); // trackTime + drawMCHClusters(GID{static_cast(trMFTMCHMID.getMCHTrackID()), GID::MCH}); // trackTime + drawMIDClusters(midGID); // tracktime } void EveWorkflowHelper::drawMCHMID(GID gid, float trackTime) @@ -801,10 +785,10 @@ void EveWorkflowHelper::drawMCHMID(GID gid, float trackTime) const auto endZ = findLastMIDClusterPosition(midTrack); - drawForwardTrack(trackParam, gid.asString(), static_cast(gid.getSource()), trackParam.getZ(), endZ, trackTime); + drawForwardTrack(gid, trackParam, trackParam.getZ(), endZ, trackTime); - drawMCHClusters(match.getMCHRef(), trackTime); - drawMIDClusters(match.getMIDRef(), trackTime); + drawMCHClusters(match.getMCHRef()); // tracktime + drawMIDClusters(match.getMIDRef()); // tracktime } void EveWorkflowHelper::drawAODBarrel(EveWorkflowHelper::AODBarrelTrack const& track, float trackTime) @@ -823,8 +807,7 @@ void EveWorkflowHelper::drawAODMFT(AODMFTTrack const& track, float trackTime) tr.setZ(track.z()); tr.setParameters({track.x(), track.y(), track.phi(), track.tgl(), track.signed1Pt()}); - - drawMFTTrack(tr, trackTime); + drawMFTTrack(VisualisationEventSerializer::deserialize(dataformats::GlobalTrackID::Source::MFT, 0, 0), tr, trackTime); } void EveWorkflowHelper::drawAODFwd(AODForwardTrack const& track, float trackTime) @@ -858,10 +841,10 @@ void EveWorkflowHelper::drawAODFwd(AODForwardTrack const& track, float trackTime break; } - drawForwardTrack(trackParam, gid.asString(), static_cast(gid.getSource()), trackParam.getZ(), endZ, trackTime); + drawForwardTrack(gid, trackParam, trackParam.getZ(), endZ, trackTime); } -void EveWorkflowHelper::drawMFTTrack(o2::track::TrackParFwd tr, float trackTime) +void EveWorkflowHelper::drawMFTTrack(GID gid, o2::track::TrackParFwd tr, float trackTime) { tr.propagateParamToZlinear(mftZPositions.front()); // Fix the track starting position. @@ -872,8 +855,7 @@ void EveWorkflowHelper::drawMFTTrack(o2::track::TrackParFwd tr, float trackTime) .phi = (float)tr.getPhi(), .theta = (float)tr.getTheta(), .eta = (float)tr.getEta(), - .gid = GID::getSourceName(GID::MFT), - .source = GID::MFT}); + .gid = gid}); for (auto zPos : mftZPositions) { tr.propagateParamToZlinear(zPos); @@ -881,7 +863,7 @@ void EveWorkflowHelper::drawMFTTrack(o2::track::TrackParFwd tr, float trackTime) } } -void EveWorkflowHelper::drawForwardTrack(mch::TrackParam track, const std::string& gidString, GID::Source source, float startZ, float endZ, float trackTime) +void EveWorkflowHelper::drawForwardTrack(GID gid, mch::TrackParam track, float startZ, float endZ, float trackTime) { auto vTrack = mEvent.addTrack({.time = static_cast(trackTime), .charge = 0, @@ -890,8 +872,7 @@ void EveWorkflowHelper::drawForwardTrack(mch::TrackParam track, const std::strin .phi = (float)0, .theta = (float)0, .eta = (float)0, - .gid = gidString, - .source = source}); + .gid = gid}); static constexpr auto stepDensity = 50.; // one vertex per 50 cm should be sufficiently dense @@ -906,7 +887,7 @@ void EveWorkflowHelper::drawForwardTrack(mch::TrackParam track, const std::strin } } -void EveWorkflowHelper::drawTOFClusters(GID gid, float trackTime) +void EveWorkflowHelper::drawTOFClusters(GID gid) { auto tOFClustersArray = mRecoCont->getTOFClusters(); if (!gid.includesDet(o2::dataformats::GlobalTrackID::Source::TOF)) { @@ -921,17 +902,16 @@ void EveWorkflowHelper::drawTOFClusters(GID gid, float trackTime) // rotation float alpha = o2::math_utils::sector2Angle(sector); - float xGlb = x * cos(alpha) - y * sin(alpha); - float yGlb = y * cos(alpha) + x * sin(alpha); - float zGlb = z; - drawPoint(xGlb, yGlb, zGlb, trackTime); + float xyzGlb[3]; + xyzGlb[0] = x * cos(alpha) - y * sin(alpha); + xyzGlb[1] = y * cos(alpha) + x * sin(alpha); + xyzGlb[2] = z; + drawPoint(xyzGlb); } -void EveWorkflowHelper::drawITSClusters(GID gid, float trackTime) +void EveWorkflowHelper::drawITSClusters(GID gid) // float trackTime { - // LOG(info) << "EveWorkflowHelper::drawITSClusters" << gid; if (gid.getSource() == GID::ITS) { // this is for for full standalone tracks - // LOG(info) << "EveWorkflowHelper::drawITSClusters ITS " << gid; const auto& trc = mRecoCont->getITSTrack(gid); auto refs = mRecoCont->getITSTracksClusterRefs(); int ncl = trc.getNumberOfClusters(); @@ -939,10 +919,10 @@ void EveWorkflowHelper::drawITSClusters(GID gid, float trackTime) for (int icl = 0; icl < ncl; icl++) { const auto& pnt = mITSClustersArray[refs[icl + offset]]; const auto glo = mITSGeom->getMatrixT2G(pnt.getSensorID()) * pnt.getXYZ(); - drawPoint(glo.X(), glo.Y(), glo.Z(), trackTime); + float xyz[] = {glo.X(), glo.Y(), glo.Z()}; + drawPoint(xyz); // trackTime; } } else if (gid.getSource() == GID::ITSAB) { // this is for ITS tracklets from ITS-TPC afterburner - // LOG(info) << "EveWorkflowHelper::drawITSClusters ITSAB " << gid; const auto& trc = mRecoCont->getITSABRef(gid); const auto& refs = mRecoCont->getITSABClusterRefs(); int ncl = trc.getNClusters(); @@ -950,13 +930,14 @@ void EveWorkflowHelper::drawITSClusters(GID gid, float trackTime) for (int icl = 0; icl < ncl; icl++) { const auto& pnt = mITSClustersArray[refs[icl + offset]]; const auto glo = mITSGeom->getMatrixT2G(pnt.getSensorID()) * pnt.getXYZ(); - drawPoint(glo.X(), glo.Y(), glo.Z(), trackTime); + float xyz[] = {glo.X(), glo.Y(), glo.Z()}; + drawPoint(xyz); //, trackTime } } } // TPC cluseters for given TPC track (gid) -void EveWorkflowHelper::drawTPCClusters(GID gid, float trackTimeTB) +void EveWorkflowHelper::drawTPCClusters(GID gid) // , float trackTimeTB { const auto& trc = mRecoCont->getTPCTrack(gid); auto mTPCTracksClusIdx = mRecoCont->getTPCTracksClusterRefs(); @@ -970,11 +951,11 @@ void EveWorkflowHelper::drawTPCClusters(GID gid, float trackTimeTB) std::array xyz; this->mTPCFastTransform->TransformIdeal(sector, row, clTPC.getPad(), clTPC.getTime(), xyz[0], xyz[1], xyz[2], trc.getTime0()); // in sector coordinate o2::math_utils::rotateZ(xyz, o2::math_utils::sector2Angle(sector % o2::tpc::SECTORSPERSIDE)); // lab coordinate (global) - mEvent.addCluster(xyz[0], xyz[1], xyz[2], trackTimeTB / mMUS2TPCTimeBins); + mEvent.addCluster(xyz.data()); // trackTimeTB / mMUS2TPCTimeBins } } -void EveWorkflowHelper::drawMFTClusters(GID gid, float trackTime) +void EveWorkflowHelper::drawMFTClusters(GID gid) // float trackTime { const auto& mftTrack = mRecoCont->getMFTTrack(gid); auto noOfClusters = mftTrack.getNumberOfPoints(); // number of clusters in MFT Track @@ -982,7 +963,8 @@ void EveWorkflowHelper::drawMFTClusters(GID gid, float trackTime) auto refs = mRecoCont->getMFTTracksClusterRefs(); // list of references to clusters, offset:offset+no for (int icl = noOfClusters - 1; icl > -1; --icl) { const auto& thisCluster = mMFTClustersArray[refs[offset + icl]]; - drawPoint(thisCluster.getX(), thisCluster.getY(), thisCluster.getZ(), trackTime); + float xyz[] = {thisCluster.getX(), thisCluster.getY(), thisCluster.getZ()}; + drawPoint(xyz); // tracktime } } @@ -996,7 +978,7 @@ void EveWorkflowHelper::drawTPC(GID gid, float trackTime) addTrackToEvent(tr, gid, trackTime, 4.f, GID::TPC); - drawTPCClusters(gid, trackTime); + drawTPCClusters(gid); // trackTime } void EveWorkflowHelper::drawITS(GID gid, float trackTime) @@ -1004,7 +986,7 @@ void EveWorkflowHelper::drawITS(GID gid, float trackTime) const auto& tr = mRecoCont->getITSTrack(gid); addTrackToEvent(tr, gid, trackTime, 1.f, GID::ITS); - drawITSClusters(gid, trackTime); + drawITSClusters(gid); // tracktime } void EveWorkflowHelper::drawMFT(GID gid, float trackTime) @@ -1012,8 +994,8 @@ void EveWorkflowHelper::drawMFT(GID gid, float trackTime) // LOG(info) << "EveWorkflowHelper::drawMFT " << gid; auto tr = mRecoCont->getMFTTrack(gid); - drawMFTTrack(tr, trackTime); - drawMFTClusters(gid, trackTime); + drawMFTTrack(gid, tr, trackTime); + drawMFTClusters(gid); // tracktime } void EveWorkflowHelper::drawMCH(GID gid, float trackTime) @@ -1024,12 +1006,12 @@ void EveWorkflowHelper::drawMCH(GID gid, float trackTime) const auto endZ = findLastMCHClusterPosition(track); - drawForwardTrack(trackParam, gid.asString(), GID::MCH, track.getZ(), endZ, trackTime); + drawForwardTrack(gid, trackParam, track.getZ(), endZ, trackTime); - drawMCHClusters(gid, trackTime); + drawMCHClusters(gid); // tracktime } -void EveWorkflowHelper::drawMCHClusters(GID gid, float trackTime) +void EveWorkflowHelper::drawMCHClusters(GID gid) // trackTime { const auto& mchTrack = mRecoCont->getMCHTrack(gid); auto noOfClusters = mchTrack.getNClusters(); // number of clusters in MCH Track @@ -1037,7 +1019,8 @@ void EveWorkflowHelper::drawMCHClusters(GID gid, float trackTime) const auto& mchClusters = mRecoCont->getMCHTrackClusters(); // list of references to clusters, offset:offset+no for (int icl = noOfClusters - 1; icl > -1; --icl) { const auto& cluster = mchClusters[offset + icl]; - drawPoint(cluster.x, cluster.y, cluster.z, trackTime); + float glo[] = {cluster.x, cluster.y, cluster.z}; + drawPoint(glo); // tracktime } } @@ -1054,8 +1037,7 @@ void EveWorkflowHelper::drawMID(GID gid, float trackTime) .phi = (float)0, .theta = (float)0, .eta = (float)0, - .gid = gid.asString(), - .source = GID::MID}); + .gid = gid}); for (int ich = 0; ich < 4; ++ich) { auto icl = midTrack.getClusterMatched(ich); @@ -1064,10 +1046,10 @@ void EveWorkflowHelper::drawMID(GID gid, float trackTime) vTrack->addPolyPoint(cluster.xCoor, cluster.yCoor, cluster.zCoor); } } - drawMIDClusters(gid, trackTime); + drawMIDClusters(gid); // tracktime } -void EveWorkflowHelper::drawMIDClusters(GID gid, float trackTime) +void EveWorkflowHelper::drawMIDClusters(GID gid) // , float trackTime { const auto& midTrack = mRecoCont->getMIDTrack(gid); // MID track const auto& midClusters = mRecoCont->getMIDTrackClusters(); // MID clusters @@ -1076,12 +1058,13 @@ void EveWorkflowHelper::drawMIDClusters(GID gid, float trackTime) auto icl = midTrack.getClusterMatched(ich); if (icl >= 0) { auto& cluster = midClusters[icl]; - drawPoint(cluster.xCoor, cluster.yCoor, cluster.zCoor, trackTime); + float glo[] = {cluster.xCoor, cluster.yCoor, cluster.zCoor}; + drawPoint(glo); // tracktime } } } -void EveWorkflowHelper::drawTRDClusters(const o2::trd::TrackTRD& tpcTrdTrack, float trackTime) +void EveWorkflowHelper::drawTRDClusters(const o2::trd::TrackTRD& tpcTrdTrack) // tracktime { const auto& tpcTrdTracks = mRecoCont->getTPCTRDTracks(); const auto& tpcTrdTriggerRecords = mRecoCont->getTPCTRDTriggers(); @@ -1103,10 +1086,11 @@ void EveWorkflowHelper::drawTRDClusters(const o2::trd::TrackTRD& tpcTrdTrack, fl int sector = iChamber / 30; float alpha = o2::math_utils::sector2Angle(sector); // now the rotation is simply - float xGlb = x * cos(alpha) - y * sin(alpha); - float yGlb = y * cos(alpha) + x * sin(alpha); - float zGlb = z; - drawPoint(xGlb, yGlb, zGlb, trackTime); + float glo[3]; + glo[0] = x * cos(alpha) - y * sin(alpha); + glo[1] = y * cos(alpha) + x * sin(alpha); + glo[2] = z; + drawPoint(glo); // tracktime } } } diff --git a/EventVisualisation/Workflow/src/O2DPLDisplay.cxx b/EventVisualisation/Workflow/src/O2DPLDisplay.cxx index 1f80afdd6ca83..af8c8a353514d 100644 --- a/EventVisualisation/Workflow/src/O2DPLDisplay.cxx +++ b/EventVisualisation/Workflow/src/O2DPLDisplay.cxx @@ -59,7 +59,8 @@ void customize(std::vector& workflowOptions) { std::vector options{ {"jsons-folder", VariantType::String, "jsons", {"name of the folder to store json files"}}, - {"use-json-format", VariantType::Bool, false, {"instead of root format (default) use json format"}}, + {"use-json-format", VariantType::Bool, false, {"instead of eve format (default) use json format"}}, + {"use-root-format", VariantType::Bool, false, {"instead of eve format (default) use root format"}}, {"eve-hostname", VariantType::String, "", {"name of the host allowed to produce files (empty means no limit)"}}, {"eve-dds-collection-index", VariantType::Int, -1, {"number of dpl collection allowed to produce files (-1 means no limit)"}}, {"number-of_files", VariantType::Int, 150, {"maximum number of json files in folder"}}, @@ -218,7 +219,8 @@ void O2DPLDisplaySpec::run(ProcessingContext& pc) helper.mEvent.setFirstTForbit(tinfo.firstTForbit); helper.mEvent.setRunType(this->mRunType); helper.mEvent.setPrimaryVertex(pv); - helper.save(this->mJsonPath, this->mExt, this->mNumberOfFiles, this->mTrkMask, this->mClMask, tinfo.runNumber, tinfo.creation); + helper.mEvent.setCreationTime(tinfo.creation); + helper.save(this->mJsonPath, this->mExt, this->mNumberOfFiles); filesSaved++; currentTime = std::chrono::high_resolution_clock::now(); // time AFTER save this->mTimeStamp = currentTime; // next run AFTER period counted from last save @@ -309,11 +311,15 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) WorkflowSpec specs; auto jsonFolder = cfgc.options().get("jsons-folder"); - std::string ext = ".root"; // root files are default format + std::string ext = ".eve"; // root files are default format auto useJsonFormat = cfgc.options().get("use-json-format"); if (useJsonFormat) { ext = ".json"; } + auto useROOTFormat = cfgc.options().get("use-root-format"); + if (useROOTFormat) { + ext = ".root"; + } auto eveHostName = cfgc.options().get("eve-hostname"); o2::conf::ConfigurableParam::updateFromString(cfgc.options().get("configKeyValues")); bool useMC = !cfgc.options().get("disable-mc");