diff --git a/ALICE3/Core/Decayer.h b/ALICE3/Core/Decayer.h index 2280261dd21..7189223573c 100644 --- a/ALICE3/Core/Decayer.h +++ b/ALICE3/Core/Decayer.h @@ -19,6 +19,7 @@ #ifndef ALICE3_CORE_DECAYER_H_ #define ALICE3_CORE_DECAYER_H_ +#include "ALICE3/Core/OTFParticle.h" #include "ALICE3/Core/TrackUtilities.h" #include diff --git a/ALICE3/Core/OTFParticle.h b/ALICE3/Core/OTFParticle.h new file mode 100644 index 00000000000..b6ca1f246c3 --- /dev/null +++ b/ALICE3/Core/OTFParticle.h @@ -0,0 +1,165 @@ +// 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 OTFParticle.h +/// \brief Basic class to hold information regarding a mc particle to be used in fast simulation +/// \author Jesper Karlsson Gumprecht +/// + +#ifndef ALICE3_CORE_OTFPARTICLE_H_ +#define ALICE3_CORE_OTFPARTICLE_H_ + +#include + +#include +#include +#include +#include + +namespace o2::upgrade +{ + +class OTFParticle +{ + public: + OTFParticle() = default; + + template + explicit OTFParticle(const TParticle& particle) + { + mPdgCode = particle.pdgCode(); + mGlobalIndex = particle.globalIndex(); + mCollisionId = particle.mcCollisionId(); + mPx = particle.px(); + mPy = particle.py(); + mPz = particle.pz(); + mE = particle.e(); + mVx = particle.vx(); + mVy = particle.vy(); + mVz = particle.vz(); + mVt = particle.vt(); + mIsFromMcParticles = true; + if (particle.has_mothers()) { + mIndicesMother = {particle.mothersIds().front(), particle.mothersIds().back()}; + } + } + + // Setters + void setIsAlive(const bool isAlive) { mIsAlive = isAlive; } + void setIsPrimary(const bool isPrimary) { mIsPrimary = isPrimary; } + void setCollisionId(const int collisionId) { mCollisionId = collisionId; } + void setPDG(const int pdg) { mPdgCode = pdg; } + void setIndicesMother(const int start, const int stop) { mIndicesMother = {start, stop}; } + void setIndicesDaughter(const int start, const int stop) { mIndicesDaughter = {start, stop}; } + void setProductionTime(const float vt) { mVt = vt; } + void setVxVyVz(const float vx, const float vy, const float vz) + { + mVx = vx; + mVy = vy; + mVz = vz; + } + void setPxPyPzE(const float px, const float py, const float pz, const float e) + { + mPx = px; + mPy = py; + mPz = pz; + mE = e; + } + + // Getters + int pdgCode() const { return mPdgCode; } + int globalIndex() const { return mGlobalIndex; } + int collisionId() const { return mCollisionId; } + bool isAlive() const { return mIsAlive; } + bool isPrimary() const { return mIsPrimary; } + bool isFromMcParticles() const { return mIsFromMcParticles; } + float weight() const + { + static constexpr float Weight = 1.f; + return Weight; + } + uint8_t flags() const + { + static constexpr uint8_t Flags = 1; + return Flags; // todo + } + int statusCode() const + { + static constexpr int StatusCode = 1; + return StatusCode; // todo + } + float vx() const { return mVx; } + float vy() const { return mVy; } + float vz() const { return mVz; } + float vt() const { return mVt; } + float px() const { return mPx; } + float py() const { return mPy; } + float pz() const { return mPz; } + float e() const { return mE; } + float radius() const { return std::hypot(mVx, mVy); } + float r() const { return radius(); } + float pt() const { return std::hypot(mPx, mPy); } + float p() const { return std::hypot(mPx, mPy, mPz); } + float phi() const { return o2::constants::math::PI + std::atan2(-1.0f * py(), -1.0f * px()); } + float eta() const + { + // As https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1943 + static constexpr float Tolerance = 1e-7f; + if ((p() - mPz) < Tolerance) { + return (mPz < 0.0f) ? -100.0f : 100.0f; + } else { + return 0.5f * std::log((p() + mPz) / (p() - mPz)); + } + } + float y() const + { + // As https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1922 + static constexpr float Tolerance = 1e-7f; + if ((e() - mPz) < Tolerance) { + return (mPz < 0.0f) ? -100.0f : 100.0f; + } else { + return 0.5f * std::log((mE + mPz) / (mE - mPz)); + } + } + int getMotherIndexStart() const { return mIndicesMother[0]; } + int getMotherIndexStop() const { return mIndicesMother[1]; } + int getDaughterIndexStart() const { return mIndicesDaughter[0]; } + int getDaughterIndexStop() const { return mIndicesDaughter[1]; } + std::array getMothers() const { return mIndicesMother; } + std::array getDaughters() const { return mIndicesDaughter; } + std::span getMotherSpan() const { return hasMothers() ? std::span(mIndicesMother.data(), 2) : std::span(); } + + // Checks + bool hasDaughters() const { return (mIndicesDaughter[0] > 0); } + bool hasMothers() const { return (mIndicesMother[0] > 0); } + bool hasNaN() const + { + return std::isnan(mPx) || std::isnan(mPy) || std::isnan(mPz) || std::isnan(mE) || + std::isnan(mVx) || std::isnan(mVy) || std::isnan(mVz); + } + bool hasIndex() const + { + return (mGlobalIndex != -1); + } + + private: + int mPdgCode{}, mGlobalIndex{-1}; + int mCollisionId{}; + float mVx{}, mVy{}, mVz{}, mVt{}; + float mPx{}, mPy{}, mPz{}, mE{}; + bool mIsAlive{}, mIsFromMcParticles{false}; + bool mIsPrimary{}; + std::array mIndicesMother{-1, -1}, mIndicesDaughter{-1, -1}; +}; + +} // namespace o2::upgrade +#endif // ALICE3_CORE_OTFPARTICLE_H_ diff --git a/ALICE3/Core/TrackUtilities.h b/ALICE3/Core/TrackUtilities.h index 6e4905672bd..d61c72956cb 100644 --- a/ALICE3/Core/TrackUtilities.h +++ b/ALICE3/Core/TrackUtilities.h @@ -18,6 +18,8 @@ #ifndef ALICE3_CORE_TRACKUTILITIES_H_ #define ALICE3_CORE_TRACKUTILITIES_H_ +#include "ALICE3/Core/OTFParticle.h" + #include #include @@ -30,145 +32,6 @@ namespace o2::upgrade { -class OTFParticle -{ - public: - OTFParticle() = default; - - template - explicit OTFParticle(const TParticle& particle) - { - mPdgCode = particle.pdgCode(); - mGlobalIndex = particle.globalIndex(); - mCollisionId = particle.mcCollisionId(); - mPx = particle.px(); - mPy = particle.py(); - mPz = particle.pz(); - mE = particle.e(); - mVx = particle.vx(); - mVy = particle.vy(); - mVz = particle.vz(); - mIsFromMcParticles = true; - if (particle.has_mothers()) { - mIndicesMother = {particle.mothersIds().front(), particle.mothersIds().back()}; - } - } - - // Setters - void setIsAlive(const bool isAlive) { mIsAlive = isAlive; } - void setIsPrimary(const bool isPrimary) { mIsPrimary = isPrimary; } - void setCollisionId(const int collisionId) { mCollisionId = collisionId; } - void setPDG(const int pdg) { mPdgCode = pdg; } - void setIndicesMother(const int start, const int stop) { mIndicesMother = {start, stop}; } - void setIndicesDaughter(const int start, const int stop) { mIndicesDaughter = {start, stop}; } - void setVxVyVz(const float vx, const float vy, const float vz) - { - mVx = vx; - mVy = vy; - mVz = vz; - } - void setPxPyPzE(const float px, const float py, const float pz, const float e) - { - mPx = px; - mPy = py; - mPz = pz; - mE = e; - } - - // Getters - int pdgCode() const { return mPdgCode; } - int globalIndex() const { return mGlobalIndex; } - int collisionId() const { return mCollisionId; } - bool isAlive() const { return mIsAlive; } - bool isPrimary() const { return mIsPrimary; } - bool isFromMcParticles() const { return mIsFromMcParticles; } - float weight() const - { - static constexpr float Weight = 1.f; - return Weight; - } - uint8_t flags() const - { - static constexpr uint8_t Flags = 1; - return Flags; - } - float vt() const - { - static constexpr float Vt = 1.f; - return Vt; - } - int statusCode() const - { - static constexpr int StatusCode = 1; - return StatusCode; - } - float vx() const { return mVx; } - float vy() const { return mVy; } - float vz() const { return mVz; } - float px() const { return mPx; } - float py() const { return mPy; } - float pz() const { return mPz; } - float e() const { return mE; } - float radius() const { return std::hypot(mVx, mVy); } - float r() const { return radius(); } - float pt() const { return std::hypot(mPx, mPy); } - float p() const { return std::hypot(mPx, mPy, mPz); } - float phi() const { return o2::constants::math::PI + std::atan2(-1.0f * py(), -1.0f * px()); } - float eta() const - { - // As https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1943 - static constexpr float Tolerance = 1e-7f; - if ((p() - mPz) < Tolerance) { - return (mPz < 0.0f) ? -100.0f : 100.0f; - } else { - return 0.5f * std::log((p() + mPz) / (p() - mPz)); - } - } - - float y() const - { - // As https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1922 - static constexpr float Tolerance = 1e-7f; - if ((e() - mPz) < Tolerance) { - return (mPz < 0.0f) ? -100.0f : 100.0f; - } else { - return 0.5f * std::log((mE + mPz) / (mE - mPz)); - } - } - - bool hasDaughters() const { return (mIndicesDaughter[0] > 0); } - bool hasMothers() const { return (mIndicesMother[0] > 0); } - int getMotherIndexStart() const { return mIndicesMother[0]; } - int getMotherIndexStop() const { return mIndicesMother[1]; } - int getDaughterIndexStart() const { return mIndicesDaughter[0]; } - int getDaughterIndexStop() const { return mIndicesDaughter[1]; } - std::array getMothers() const { return mIndicesMother; } - std::array getDaughters() const { return mIndicesDaughter; } - std::span getMotherSpan() const { return hasMothers() ? std::span(mIndicesMother.data(), 2) : std::span(); } - - bool hasNaN() const - { - return std::isnan(mPx) || std::isnan(mPy) || std::isnan(mPz) || std::isnan(mE) || - std::isnan(mVx) || std::isnan(mVy) || std::isnan(mVz); - } - - bool hasIndex() const - { - return (mGlobalIndex != -1); - } - - private: - int mPdgCode{}, mGlobalIndex{-1}; - int mCollisionId{}; - float mE{}; - float mVx{}, mVy{}, mVz{}; - float mPx{}, mPy{}, mPz{}; - bool mIsAlive{}, mIsFromMcParticles{false}; - bool mIsPrimary{}; - - std::array mIndicesMother{-1, -1}, mIndicesDaughter{-1, -1}; -}; - /// Function to convert a TLorentzVector into a perfect Track /// \param charge particle charge (integer) /// \param particle the particle to convert (TLorentzVector) diff --git a/ALICE3/TableProducer/OTF/onTheFlyDecayer.cxx b/ALICE3/TableProducer/OTF/onTheFlyDecayer.cxx index 1d1a301cd3f..38c51110feb 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyDecayer.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyDecayer.cxx @@ -16,6 +16,7 @@ /// #include "ALICE3/Core/Decayer.h" +#include "ALICE3/Core/OTFParticle.h" #include "ALICE3/Core/TrackUtilities.h" #include "ALICE3/DataModel/OTFMCParticle.h"