Skip to content

Commit 1a439d4

Browse files
committed
Add proto OTF decayer
1 parent 9093217 commit 1a439d4

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

ALICE3/TableProducer/OTF/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ o2physics_add_dpl_workflow(on-the-fly-tracker-pid
2828
SOURCES onTheFlyTrackerPid.cxx
2929
PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::ReconstructionDataFormats O2::DetectorsCommonDataFormats O2Physics::ALICE3Core
3030
COMPONENT_NAME Analysis)
31+
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file onTheFlyDecayer.cxx
13+
///
14+
/// \brief Task to decay long lived particles and to propagate the information to other tasks
15+
///
16+
/// \author Nicolò Jacazio <nicolo.jacazio@cern.ch>, UniUPO
17+
///
18+
19+
#include "Framework/O2DatabasePDGPlugin.h"
20+
21+
22+
using namespace o2;
23+
using namespace o2::framework;
24+
using std::array;
25+
26+
struct OnTheFlyDecayer {
27+
Service<o2::framework::O2DatabasePDG> pdgDB;
28+
29+
void init(o2::framework::InitContext&)
30+
{
31+
}
32+
33+
template <typename ParticleType>
34+
bool decayParticle(const auto & particle){
35+
36+
37+
bool canDecay = false;
38+
39+
switch(particle.pdgCode()){
40+
case 3312:
41+
canDecay = true;
42+
}
43+
if(!canDecay){
44+
return false;
45+
}
46+
// Check that it does not have daughters
47+
if(particle.hasDaughters()){
48+
LOG(fatal) << "Particle has daughters";
49+
}
50+
51+
52+
const auto& pdgInfo = pdgDB->GetParticle(particle.pdgCode());
53+
if (!pdgInfo) {
54+
LOG(fatal) << "PDG code " << particle.pdgCode() << " not found in the database";
55+
}
56+
57+
58+
59+
60+
const double u = rand.Uniform(0, 1);
61+
double xi_mass = o2::constants::physics::MassXiMinus;
62+
double la_mass = o2::constants::physics::MassLambda;
63+
double pi_mass = o2::constants::physics::MassPionCharged;
64+
double pr_mass = o2::constants::physics::MassProton;
65+
66+
double mass = 0.;
67+
double tau = 0.;
68+
// Compute channel
69+
switch (particle.pdgCode())
70+
{
71+
case 3312:
72+
mass = xi_mass;
73+
tau = 4.91;
74+
break;
75+
}
76+
77+
const double gamma = 1 / sqrt(1 + (particle.p() * particle.p()) / (mass * mass));
78+
const double ctau = tau * gamma;
79+
const double rxyz = (-ctau * log(1.0 - u));
80+
// If the particle is charged, then propagate in the mag field
81+
o2::math_utils::CircleXYf_t circle;
82+
if (pdgInfo->Charge() != 0) {
83+
float sna, csa;
84+
track.getCircleParams(magneticField, circle, sna, csa);
85+
}
86+
else{ // Neutral particles
87+
88+
}
89+
const double rxy = rxyz / sqrt(1. + track.getTgl() * track.getTgl());
90+
const double theta = rxy / circle.rC;
91+
const double newX = ((particle.vx() - circle.xC) * std::cos(theta) - (particle.vy() - circle.yC) * std::sin(theta)) + circle.xC;
92+
const double newY = ((particle.vy() - circle.yC) * std::cos(theta) + (particle.vx() - circle.xC) * std::sin(theta)) + circle.yC;
93+
const double newPx = particle.px() * std::cos(theta) - particle.py() * std::sin(theta);
94+
const double newPy = particle.py() * std::cos(theta) + particle.px() * std::sin(theta);
95+
xiDecayVertex.push_back(newX);
96+
xiDecayVertex.push_back(newY);
97+
xiDecayVertex.push_back(particle.vz() + rxyz * (particle.pz() / particle.p()));
98+
99+
std::vector<double> xiDaughters = {la_mass, pi_mass};
100+
TLorentzVector xi(newPx, newPy, particle.pz(), particle.e());
101+
TGenPhaseSpace xiDecay;
102+
xiDecay.SetDecay(xi, 2, xiDaughters.data());
103+
xiDecay.Generate();
104+
decayDaughters.push_back(*xiDecay.GetDecay(1));
105+
return true;
106+
107+
TLorentzVector la = *xiDecay.GetDecay(0);
108+
109+
double la_gamma = 1 / sqrt(1 + (la.P() * la.P()) / (la_mass * la_mass));
110+
double la_ctau = 7.89 * la_gamma;
111+
std::vector<double> laDaughters = {pi_mass, pr_mass};
112+
double la_rxyz = (-la_ctau * log(1 - u));
113+
laDecayVertex.push_back(xiDecayVertex[0] + la_rxyz * (xiDecay.GetDecay(0)->Px() / xiDecay.GetDecay(0)->P()));
114+
laDecayVertex.push_back(xiDecayVertex[1] + la_rxyz * (xiDecay.GetDecay(0)->Py() / xiDecay.GetDecay(0)->P()));
115+
laDecayVertex.push_back(xiDecayVertex[2] + la_rxyz * (xiDecay.GetDecay(0)->Pz() / xiDecay.GetDecay(0)->P()));
116+
117+
TGenPhaseSpace laDecay;
118+
laDecay.SetDecay(la, 2, laDaughters.data());
119+
laDecay.Generate();
120+
decayDaughters.push_back(*laDecay.GetDecay(0));
121+
decayDaughters.push_back(*laDecay.GetDecay(1));
122+
123+
}
124+
125+
126+
void process(aod::McCollision const& mcCollision,
127+
aod::McParticles const& mcParticles)
128+
{
129+
for(const auto & particle : mcParticles) {
130+
decayParticle(particle);
131+
}
132+
};
133+
134+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
135+
{
136+
return WorkflowSpec{adaptAnalysisTask<OnTheFlyDecayer>(cfgc)};
137+
}

0 commit comments

Comments
 (0)