Skip to content

Commit b41be29

Browse files
authored
[ALICE3] Switch from McPartWithDaus to McParticles with --aod-origin-replace in otf decayer (#16448)
1 parent 5088778 commit b41be29

9 files changed

Lines changed: 177 additions & 247 deletions

File tree

ALICE3/Core/Decayer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ class Decayer
126126
particle.setPDG(pdgCodesDaughters[i]);
127127
particle.setVxVyVz(mVx, mVy, mVz);
128128
particle.setPxPyPzE(dau.Px(), dau.Py(), dau.Pz(), dau.E());
129+
particle.setBitOn(o2::upgrade::DecayerBits::ProducedByDecayer);
129130
decayProducts.push_back(particle);
130131
}
131132

ALICE3/Core/OTFParticle.h

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,18 @@
2121
#include <CommonConstants/MathConstants.h>
2222

2323
#include <array>
24+
#include <bitset>
2425
#include <cmath>
2526
#include <cstdint>
2627
#include <span>
2728

2829
namespace o2::upgrade
2930
{
3031

32+
enum class DecayerBits { ProducedByDecayer = 0,
33+
IsPrimary,
34+
IsAlive };
35+
3136
class OTFParticle
3237
{
3338
public:
@@ -47,20 +52,29 @@ 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 constexpr (requires { particle.decayerBits(); }) {
62+
mBits = particle.decayerBits();
63+
} else {
64+
// If we are here, we created particle in the standard workflow -- without secondaries
65+
// Then we should set all particles as physical primaries accordingly
66+
setBitOn(DecayerBits::IsPrimary);
67+
}
5468
}
5569

5670
// Setters
57-
void setIsAlive(const bool isAlive) { mIsAlive = isAlive; }
5871
void setIsPrimary(const bool isPrimary) { mIsPrimary = isPrimary; }
5972
void setCollisionId(const int collisionId) { mCollisionId = collisionId; }
6073
void setPDG(const int pdg) { mPdgCode = pdg; }
6174
void setIndicesMother(const int start, const int stop) { mIndicesMother = {start, stop}; }
6275
void setIndicesDaughter(const int start, const int stop) { mIndicesDaughter = {start, stop}; }
6376
void setProductionTime(const float vt) { mVt = vt; }
77+
void setFlags(uint8_t flag) { mFlag = flag; }
6478
void setVxVyVz(const float vx, const float vy, const float vz)
6579
{
6680
mVx = vx;
@@ -87,16 +101,8 @@ class OTFParticle
87101
static constexpr float Weight = 1.f;
88102
return Weight;
89103
}
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-
}
104+
uint8_t flags() const { return mFlag; }
105+
int statusCode() const { return mStatusCode; }
100106
float vx() const { return mVx; }
101107
float vy() const { return mVy; }
102108
float vz() const { return mVz; }
@@ -112,7 +118,8 @@ class OTFParticle
112118
float phi() const { return o2::constants::math::PI + std::atan2(-1.0f * py(), -1.0f * px()); }
113119
float eta() const
114120
{
115-
// As https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1943
121+
// Conditionally defined to avoid FPEs
122+
// As https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1959
116123
static constexpr float Tolerance = 1e-7f;
117124
if ((p() - mPz) < Tolerance) {
118125
return (mPz < 0.0f) ? -100.0f : 100.0f;
@@ -122,7 +129,8 @@ class OTFParticle
122129
}
123130
float y() const
124131
{
125-
// As https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1922
132+
// Conditionally defined to avoid FPEs
133+
// As https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1980
126134
static constexpr float Tolerance = 1e-7f;
127135
if ((e() - mPz) < Tolerance) {
128136
return (mPz < 0.0f) ? -100.0f : 100.0f;
@@ -151,13 +159,27 @@ class OTFParticle
151159
return (mGlobalIndex != -1);
152160
}
153161

162+
// Bits
163+
bool checkBit(DecayerBits bit) const { return mBits.test(static_cast<size_t>(bit)); }
164+
void setBit(DecayerBits bit, bool value = true) { mBits.set(static_cast<size_t>(bit), value); }
165+
void setBitOn(DecayerBits bit) { mBits.set(static_cast<size_t>(bit), true); }
166+
void setBitOff(DecayerBits bit) { mBits.set(static_cast<size_t>(bit), false); }
167+
168+
std::bitset<8> getBits() const { return mBits; }
169+
uint8_t getBitsValue() const { return static_cast<uint8_t>(mBits.to_ulong()); }
170+
void setBits(std::bitset<8> bits) { mBits = bits; }
171+
154172
private:
155173
int mPdgCode{}, mGlobalIndex{-1};
156174
int mCollisionId{};
157175
float mVx{}, mVy{}, mVz{}, mVt{};
158176
float mPx{}, mPy{}, mPz{}, mE{};
159177
bool mIsAlive{}, mIsFromMcParticles{false};
160178
bool mIsPrimary{};
179+
180+
int mStatusCode{};
181+
uint8_t mFlag{};
182+
std::bitset<8> mBits{};
161183
std::array<int, 2> mIndicesMother{-1, -1}, mIndicesDaughter{-1, -1};
162184
};
163185

ALICE3/DataModel/OTFMCParticle.h

Lines changed: 0 additions & 94 deletions
This file was deleted.

ALICE3/DataModel/tracksAlice3.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,15 @@ namespace mcparticle_alice3
5050
{
5151
DECLARE_SOA_COLUMN(NHits, nHits, int); //! number of silicon hits
5252
DECLARE_SOA_COLUMN(Charge, charge, float); //! particle charge
53+
DECLARE_SOA_BITMAP_COLUMN(DecayerBits, decayerBits, 8); //! Bit mask for particle produced by the OTF decayer
5354
} // namespace mcparticle_alice3
5455
DECLARE_SOA_TABLE(MCParticlesExtraA3, "AOD", "MCParticlesExtraA3",
5556
mcparticle_alice3::NHits,
5657
mcparticle_alice3::Charge);
5758
using MCParticleExtraA3 = MCParticlesExtraA3::iterator;
59+
60+
DECLARE_SOA_TABLE(OTFDecayerBits, "AOD", "OTFDecayerBits", mcparticle_alice3::DecayerBits);
61+
5862
} // namespace o2::aod
5963

6064
#endif // ALICE3_DATAMODEL_TRACKSALICE3_H_

ALICE3/TableProducer/OTF/onTheFlyDecayer.cxx

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include "ALICE3/Core/Decayer.h"
1919
#include "ALICE3/Core/OTFParticle.h"
2020
#include "ALICE3/Core/TrackUtilities.h"
21-
#include "ALICE3/DataModel/OTFMCParticle.h"
21+
#include "ALICE3/DataModel/tracksAlice3.h"
2222

2323
#include <Framework/AnalysisDataModel.h>
2424
#include <Framework/AnalysisHelpers.h>
@@ -40,7 +40,6 @@
4040
#include <array>
4141
#include <cmath>
4242
#include <cstdlib>
43-
#include <map>
4443
#include <string>
4544
#include <vector>
4645

@@ -67,12 +66,18 @@ static const std::vector<int> pdgCodes{PDG_t::kK0Short,
6766
PDG_t::kOmegaMinus,
6867
PDG_t::kOmegaPlusBar};
6968

69+
namespace o2::aod
70+
{
71+
O2ORIGIN("TMP");
72+
}
73+
7074
struct OnTheFlyDecayer {
71-
Produces<aod::McPartWithDaus> tableMcParticlesWithDau;
75+
Produces<aod::McCollisions_001> tableMcCollisions;
76+
Produces<aod::StoredMcParticles_001> tableMcParticles;
77+
Produces<aod::OTFDecayerBits> tableOTFDecayerBits;
7278

7379
o2::upgrade::Decayer decayer;
7480
Service<o2::framework::O2DatabasePDG> pdgDB;
75-
std::map<int, std::vector<o2::upgrade::OTFParticle>> mDecayDaughters;
7681
HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject};
7782

7883
Configurable<int> seed{"seed", 0, "Set seed for particle decayer"};
@@ -117,18 +122,18 @@ struct OnTheFlyDecayer {
117122
void decayParticles(const int start, const int stop)
118123
{
119124
int ndau = 0;
120-
for (int i = start; i < stop; i++) {
125+
for (int i = start; i < stop; ++i) {
121126
o2::upgrade::OTFParticle& particle = allParticles[i];
122127
if (particle.isFromMcParticles()) {
123-
particle.setIsPrimary(true);
124-
particle.setIsAlive(true);
128+
particle.setBitOn(o2::upgrade::DecayerBits::IsPrimary);
129+
particle.setBitOn(o2::upgrade::DecayerBits::IsAlive);
125130
}
126131

127132
if (!canDecay(particle)) {
128133
continue;
129134
}
130135

131-
particle.setIsAlive(false);
136+
particle.setBitOff(o2::upgrade::DecayerBits::IsAlive);
132137
std::vector<o2::upgrade::OTFParticle> decayStack = decayer.decayParticle(pdgDB, particle);
133138
const float decayRadius = decayer.getDecayRadius();
134139
const float trackVelocity = o2::upgrade::computeParticleVelocity(particle.p(), pdgDB->GetParticle(particle.pdgCode())->Mass());
@@ -150,8 +155,8 @@ struct OnTheFlyDecayer {
150155
for (o2::upgrade::OTFParticle daughter : decayStack) {
151156
daughter.setIndicesMother(i, i);
152157
daughter.setCollisionId(mCollisionId);
153-
daughter.setIsAlive(true);
154-
daughter.setIsPrimary(false);
158+
daughter.setBitOn(o2::upgrade::DecayerBits::IsAlive);
159+
daughter.setBitOff(o2::upgrade::DecayerBits::IsPrimary);
155160
daughter.setProductionTime(trackTimeNS);
156161
allParticles.push_back(daughter);
157162
ndau++;
@@ -165,42 +170,54 @@ struct OnTheFlyDecayer {
165170
decayParticles(stop, stop + ndau);
166171
}
167172

168-
void process(aod::McCollision const& collision, aod::McParticles const& mcParticles)
173+
void process(aod::McCollisions_001From<aod::Hash<"TMP"_h>>::iterator const& collision, aod::McParticles_001From<aod::Hash<"TMP"_h>> const& mcParticles)
169174
{
170-
mCollisionId = collision.globalIndex();
171175
allParticles.clear();
172176

177+
// Reproduce collision table to have AOD origin
178+
mCollisionId = collision.globalIndex();
179+
tableMcCollisions(collision.bcId(),
180+
collision.generatorsID(),
181+
collision.posX(),
182+
collision.posY(),
183+
collision.posZ(),
184+
collision.t(),
185+
collision.weight(),
186+
collision.impactParameter(),
187+
collision.eventPlaneAngle());
188+
173189
// First we copy the particles from the table into a vector that is extendable
174-
for (int index{0}; index < static_cast<int>(mcParticles.size()); ++index) {
175-
const auto& mcParticle = mcParticles.rawIteratorAt(index);
176-
allParticles.push_back(o2::upgrade::OTFParticle{mcParticle});
190+
for (const auto& particle : mcParticles) {
191+
allParticles.emplace_back(o2::upgrade::OTFParticle{particle});
177192
}
178193

179194
// Do all decays
180195
decayParticles(0, allParticles.size());
181196

182197
// Fill output table
183-
for (int index{0}; index < static_cast<int>(allParticles.size()); ++index) {
184-
const auto& otfParticle = allParticles[index];
185-
198+
for (const auto& otfParticle : allParticles) {
186199
if (otfParticle.hasNaN()) {
187200
histos.fill(HIST("hNaNBookkeeping"), 1);
188201
} else {
189202
histos.fill(HIST("hNaNBookkeeping"), 0);
190203
}
191204

192-
// todo: status codes
193-
tableMcParticlesWithDau(otfParticle.collisionId(), otfParticle.pdgCode(), otfParticle.statusCode(),
194-
otfParticle.flags(), otfParticle.getMotherSpan(), otfParticle.getDaughters().data(), otfParticle.weight(),
195-
otfParticle.px(), otfParticle.py(), otfParticle.pz(), otfParticle.e(),
196-
otfParticle.vx(), otfParticle.vy(), otfParticle.vz(), otfParticle.vt(),
197-
otfParticle.phi(), otfParticle.eta(), otfParticle.pt(), otfParticle.p(), otfParticle.y(),
198-
otfParticle.isAlive(), otfParticle.isPrimary());
205+
tableOTFDecayerBits(otfParticle.getBitsValue());
206+
tableMcParticles(otfParticle.collisionId(), otfParticle.pdgCode(), otfParticle.statusCode(), otfParticle.flags(),
207+
otfParticle.getMotherSpan(), otfParticle.getDaughters().data(), otfParticle.weight(),
208+
otfParticle.px(), otfParticle.py(), otfParticle.pz(), otfParticle.e(),
209+
otfParticle.vx(), otfParticle.vy(), otfParticle.vz(), otfParticle.vt());
199210
}
200211
}
201212
};
202213

214+
struct OnTheFlyDecayerExtensionSpawner {
215+
Spawns<aod::McParticles_001Extension> spawnMcParticlesExtensions;
216+
void init(o2::framework::InitContext&) {}
217+
};
218+
203219
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
204220
{
205-
return WorkflowSpec{adaptAnalysisTask<OnTheFlyDecayer>(cfgc)};
221+
return WorkflowSpec{adaptAnalysisTask<OnTheFlyDecayer>(cfgc),
222+
adaptAnalysisTask<OnTheFlyDecayerExtensionSpawner>(cfgc)};
206223
}

0 commit comments

Comments
 (0)