Skip to content

Commit 1427acd

Browse files
authored
[ALICE3] fix handling of neutral particles in decayer (#15916)
1 parent 96420d5 commit 1427acd

3 files changed

Lines changed: 263 additions & 79 deletions

File tree

ALICE3/Core/Decayer.h

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,46 +47,49 @@ class Decayer
4747
Decayer() = default;
4848

4949
template <typename TDatabase>
50-
std::vector<o2::upgrade::OTFParticle> decayParticle(const TDatabase& pdgDB, const o2::track::TrackParCov& track, const int pdgCode)
50+
std::vector<o2::upgrade::OTFParticle> decayParticle(const TDatabase& pdgDB, const OTFParticle& particle)
5151
{
52-
const auto& particleInfo = pdgDB->GetParticle(pdgCode);
52+
const auto& particleInfo = pdgDB->GetParticle(particle.pdgCode());
53+
if (!particleInfo) {
54+
return {};
55+
}
56+
5357
const int charge = particleInfo->Charge() / 3;
5458
const double mass = particleInfo->Mass();
55-
std::array<float, 3> mom;
56-
std::array<float, 3> pos;
57-
track.getPxPyPzGlo(mom);
58-
track.getXYZGlo(pos);
5959

60-
const double u = mRand3.Uniform(0, 1);
60+
const double u = mRand3.Uniform(0.001, 0.999);
6161
const double ctau = o2::constants::physics::LightSpeedCm2S * particleInfo->Lifetime(); // cm
62-
const double betaGamma = track.getP() / mass;
62+
const double betaGamma = particle.p() / mass;
6363
const double rxyz = -betaGamma * ctau * std::log(1 - u);
6464
double vx, vy, vz;
6565
double px, py, e;
6666

6767
if (!charge) {
68-
vx = pos[0] + rxyz * (mom[0] / track.getP());
69-
vy = pos[1] + rxyz * (mom[1] / track.getP());
70-
vz = pos[2] + rxyz * (mom[2] / track.getP());
71-
px = mom[0];
72-
py = mom[1];
68+
vx = particle.vx() + rxyz * (particle.px() / particle.p());
69+
vy = particle.vy() + rxyz * (particle.py() / particle.p());
70+
vz = particle.vz() + rxyz * (particle.pz() / particle.p());
71+
px = particle.px();
72+
py = particle.py();
7373
} else {
74-
float sna, csa;
74+
o2::track::TrackParCov track;
7575
o2::math_utils::CircleXYf_t circle;
76+
o2::upgrade::convertOTFParticleToO2Track(particle, track, pdgDB);
77+
78+
float sna, csa;
7679
track.getCircleParams(mBz, circle, sna, csa);
7780
const double rxy = rxyz / std::sqrt(1. + track.getTgl() * track.getTgl());
7881
const double theta = rxy / circle.rC;
7982

80-
vx = ((pos[0] - circle.xC) * std::cos(theta) - (pos[1] - circle.yC) * std::sin(theta)) + circle.xC;
81-
vy = ((pos[1] - circle.yC) * std::cos(theta) + (pos[0] - circle.xC) * std::sin(theta)) + circle.yC;
82-
vz = mom[2] + rxyz * (mom[2] / track.getP());
83+
vx = ((particle.vx() - circle.xC) * std::cos(theta) - (particle.vy() - circle.yC) * std::sin(theta)) + circle.xC;
84+
vy = ((particle.vy() - circle.yC) * std::cos(theta) + (particle.vx() - circle.xC) * std::sin(theta)) + circle.yC;
85+
vz = particle.vz() + rxyz * (particle.pz() / track.getP());
8386

84-
px = mom[0] * std::cos(theta) - mom[1] * std::sin(theta);
85-
py = mom[1] * std::cos(theta) + mom[0] * std::sin(theta);
87+
px = particle.px() * std::cos(theta) - particle.py() * std::sin(theta);
88+
py = particle.py() * std::cos(theta) + particle.px() * std::sin(theta);
8689
}
8790

8891
double brTotal = 0.;
89-
e = std::sqrt(mass * mass + px * px + py * py + mom[2] * mom[2]);
92+
e = std::sqrt(mass * mass + px * px + py * py + particle.pz() * particle.pz());
9093
for (int ch = 0; ch < particleInfo->NDecayChannels(); ++ch) {
9194
brTotal += particleInfo->DecayChannel(ch)->BranchingRatio();
9295
}
@@ -108,7 +111,11 @@ class Decayer
108111
}
109112
}
110113

111-
TLorentzVector tlv(px, py, mom[2], e);
114+
if (dauMasses.empty()) {
115+
return {};
116+
}
117+
118+
TLorentzVector tlv(px, py, particle.pz(), e);
112119
TGenPhaseSpace decay;
113120
decay.SetDecay(tlv, dauMasses.size(), dauMasses.data());
114121
decay.Generate();

ALICE3/Core/TrackUtilities.h

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,20 @@ namespace o2::upgrade
2929

3030
/// Struct to store mc info for the otf decayer
3131
struct OTFParticle {
32-
int mPdgCode;
33-
float mE;
34-
float mVx, mVy, mVz;
35-
float mPx, mPy, mPz;
36-
bool mIsAlive;
32+
OTFParticle() = default;
33+
34+
template <typename TParticle>
35+
explicit OTFParticle(const TParticle& particle)
36+
{
37+
mPdgCode = particle.pdgCode();
38+
mPx = particle.px();
39+
mPy = particle.py();
40+
mPz = particle.pz();
41+
mE = particle.e();
42+
mVx = particle.vx();
43+
mVy = particle.vy();
44+
mVz = particle.vz();
45+
}
3746

3847
// Setters
3948
void setIsAlive(bool isAlive) { mIsAlive = isAlive; }
@@ -62,6 +71,16 @@ struct OTFParticle {
6271
float py() const { return mPy; }
6372
float pz() const { return mPz; }
6473
float e() const { return mE; }
74+
float radius() const { return std::hypot(mVx, mVy); }
75+
float pt() const { return std::hypot(mPx, mPy); }
76+
float p() const { return std::hypot(mPx, mPy, mPz); }
77+
78+
private:
79+
int mPdgCode{};
80+
float mE{};
81+
float mVx{}, mVy{}, mVz{};
82+
float mPx{}, mPy{}, mPz{};
83+
bool mIsAlive{};
6584
};
6685

6786
/// Function to convert a TLorentzVector into a perfect Track

0 commit comments

Comments
 (0)