2121#include < CommonConstants/MathConstants.h>
2222
2323#include < array>
24+ #include < bitset>
2425#include < cmath>
2526#include < cstdint>
2627#include < span>
2728
2829namespace o2 ::upgrade
2930{
3031
32+ enum class DecayerBits { ProducedByDecayer = 0 ,
33+ IsPrimary,
34+ IsAlive };
35+
3136class OTFParticle
3237{
3338 public:
@@ -47,20 +52,32 @@ class OTFParticle
4752 mVy = particle.vy ();
4853 mVz = particle.vz ();
4954 mVt = particle.vt ();
55+ mFlag = particle.flags ();
56+ mStatusCode = particle.statusCode ();
5057 mIsFromMcParticles = true ;
5158 if (particle.has_mothers ()) {
5259 mIndicesMother = {particle.mothersIds ().front (), particle.mothersIds ().back ()};
5360 }
61+ if (particle.has_daughters ()) {
62+ mIndicesDaughter = {particle.daughtersIds ().front (), particle.daughtersIds ().back ()};
63+ }
64+ if constexpr (requires { particle.decayerBits (); }) {
65+ mBits = particle.decayerBits ();
66+ } else {
67+ // If we are here, we created particle in the standard workflow -- without secondaries
68+ // Then we should set all particles as physical primaries accordingly
69+ setBitOn (DecayerBits::IsPrimary);
70+ }
5471 }
5572
5673 // Setters
57- void setIsAlive (const bool isAlive) { mIsAlive = isAlive; }
5874 void setIsPrimary (const bool isPrimary) { mIsPrimary = isPrimary; }
5975 void setCollisionId (const int collisionId) { mCollisionId = collisionId; }
6076 void setPDG (const int pdg) { mPdgCode = pdg; }
6177 void setIndicesMother (const int start, const int stop) { mIndicesMother = {start, stop}; }
6278 void setIndicesDaughter (const int start, const int stop) { mIndicesDaughter = {start, stop}; }
6379 void setProductionTime (const float vt) { mVt = vt; }
80+ void setFlags (uint8_t flag) { mFlag = flag; }
6481 void setVxVyVz (const float vx, const float vy, const float vz)
6582 {
6683 mVx = vx;
@@ -74,6 +91,14 @@ class OTFParticle
7491 mPz = pz;
7592 mE = e;
7693 }
94+ void setIndexOffset (const std::size_t offset)
95+ {
96+ static constexpr int NotFound = -1 ;
97+ mIndicesMother [0 ] = (mIndicesMother [0 ] >= 0 ) ? mIndicesMother [0 ] + static_cast <int >(offset) : NotFound;
98+ mIndicesMother [1 ] = (mIndicesMother [1 ] >= 0 ) ? mIndicesMother [1 ] + static_cast <int >(offset) : NotFound;
99+ mIndicesDaughter [0 ] = (mIndicesDaughter [0 ] >= 0 ) ? mIndicesDaughter [0 ] + static_cast <int >(offset) : NotFound;
100+ mIndicesDaughter [1 ] = (mIndicesDaughter [1 ] >= 0 ) ? mIndicesDaughter [1 ] + static_cast <int >(offset) : NotFound;
101+ }
77102
78103 // Getters
79104 int pdgCode () const { return mPdgCode ; }
@@ -87,16 +112,8 @@ class OTFParticle
87112 static constexpr float Weight = 1 .f ;
88113 return Weight;
89114 }
90- uint8_t flags () const
91- {
92- static constexpr uint8_t Flags = 1 ;
93- return Flags; // todo
94- }
95- int statusCode () const
96- {
97- static constexpr int StatusCode = 1 ;
98- return StatusCode; // todo
99- }
115+ uint8_t flags () const { return mFlag ; }
116+ int statusCode () const { return mStatusCode ; }
100117 float vx () const { return mVx ; }
101118 float vy () const { return mVy ; }
102119 float vz () const { return mVz ; }
@@ -112,7 +129,8 @@ class OTFParticle
112129 float phi () const { return o2::constants::math::PI + std::atan2 (-1 .0f * py (), -1 .0f * px ()); }
113130 float eta () const
114131 {
115- // As https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1943
132+ // Conditionally defined to avoid FPEs
133+ // As https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1959
116134 static constexpr float Tolerance = 1e-7f ;
117135 if ((p () - mPz ) < Tolerance) {
118136 return (mPz < 0 .0f ) ? -100 .0f : 100 .0f ;
@@ -122,7 +140,8 @@ class OTFParticle
122140 }
123141 float y () const
124142 {
125- // As https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1922
143+ // Conditionally defined to avoid FPEs
144+ // As https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1980
126145 static constexpr float Tolerance = 1e-7f ;
127146 if ((e () - mPz ) < Tolerance) {
128147 return (mPz < 0 .0f ) ? -100 .0f : 100 .0f ;
@@ -139,8 +158,8 @@ class OTFParticle
139158 std::span<const int > getMotherSpan () const { return hasMothers () ? std::span<const int >(mIndicesMother .data (), 2 ) : std::span<const int >(); }
140159
141160 // Checks
142- bool hasDaughters () const { return (mIndicesDaughter [0 ] > 0 ); }
143- bool hasMothers () const { return (mIndicesMother [0 ] > 0 ); }
161+ bool hasDaughters () const { return (mIndicesDaughter [0 ] >= 0 ); }
162+ bool hasMothers () const { return (mIndicesMother [0 ] >= 0 ); }
144163 bool hasNaN () const
145164 {
146165 return std::isnan (mPx ) || std::isnan (mPy ) || std::isnan (mPz ) || std::isnan (mE ) ||
@@ -151,13 +170,27 @@ class OTFParticle
151170 return (mGlobalIndex != -1 );
152171 }
153172
173+ // Bits
174+ bool checkBit (DecayerBits bit) const { return mBits .test (static_cast <size_t >(bit)); }
175+ void setBit (DecayerBits bit, bool value = true ) { mBits .set (static_cast <size_t >(bit), value); }
176+ void setBitOn (DecayerBits bit) { mBits .set (static_cast <size_t >(bit), true ); }
177+ void setBitOff (DecayerBits bit) { mBits .set (static_cast <size_t >(bit), false ); }
178+
179+ std::bitset<8 > getBits () const { return mBits ; }
180+ uint8_t getBitsValue () const { return static_cast <uint8_t >(mBits .to_ulong ()); }
181+ void setBits (std::bitset<8 > bits) { mBits = bits; }
182+
154183 private:
155184 int mPdgCode {}, mGlobalIndex {-1 };
156- int mCollisionId {};
185+ int mCollisionId {- 1 };
157186 float mVx {}, mVy {}, mVz {}, mVt {};
158187 float mPx {}, mPy {}, mPz {}, mE {};
159188 bool mIsAlive {}, mIsFromMcParticles {false };
160189 bool mIsPrimary {};
190+
191+ int mStatusCode {};
192+ uint8_t mFlag {};
193+ std::bitset<8 > mBits {};
161194 std::array<int , 2 > mIndicesMother {-1 , -1 }, mIndicesDaughter {-1 , -1 };
162195};
163196
0 commit comments