Skip to content

Commit 07f9cfc

Browse files
committed
MCUtils: functionality to query ALICE properties on MCtracks/particles
1 parent 1c8fa05 commit 07f9cfc

3 files changed

Lines changed: 201 additions & 0 deletions

File tree

DataFormats/simulation/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ o2_add_library(SimulationDataFormat
1818
src/StackParam.cxx
1919
src/MCEventHeader.cxx
2020
src/CustomStreamers.cxx
21+
src/MCUtils.cxx
2122
PUBLIC_LINK_LIBRARIES Microsoft.GSL::GSL
2223
O2::DetectorsCommonDataFormats
2324
O2::GPUCommon O2::DetectorsBase
@@ -40,6 +41,7 @@ o2_target_root_dictionary(
4041
include/SimulationDataFormat/MCEventHeader.h
4142
include/SimulationDataFormat/MCEventStats.h
4243
include/SimulationDataFormat/IOMCTruthContainerView.h
44+
include/SimulationDataFormat/MCUtils.h
4345
LINKDEF src/SimulationDataLinkDef.h)
4446
# note the explicit LINKDEF as the linkdef in src is
4547
#
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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 MCUtils.h
13+
/// \brief Utility functions for MC particles
14+
/// \author S. Wenzel - November 2021
15+
16+
#ifndef O2_MCUTILS_H
17+
#define O2_MCUTILS_H
18+
19+
#include <SimulationDataFormat/MCTrack.h>
20+
#include "TPDGCode.h"
21+
22+
namespace o2
23+
{
24+
namespace mcutils
25+
{
26+
/// Function to determine if a MC track/particle p is a primary according to physics criteria.
27+
/// Needs the particle as input, as well as the whole navigable container of particles
28+
/// (of which p needs to be a part itself). The container can be fetched via MCKinematicsReader.
29+
bool isPhysicalPrimary(o2::MCTrack const& p, std::vector<o2::MCTrack> const& pcontainer);
30+
31+
/// Determine if a particle (identified by pdg) is stable
32+
inline bool isStable(int pdg)
33+
{
34+
//
35+
// Decide whether particle (pdg) is stable
36+
//
37+
38+
// All ions/nucleons are considered as stable
39+
// Nuclear code is 10LZZZAAAI
40+
if (pdg > 1000000000) {
41+
return true;
42+
}
43+
44+
const int kNstable = 18;
45+
int pdgStable[kNstable] = {
46+
kGamma, // Photon
47+
kElectron, // Electron
48+
kMuonPlus, // Muon
49+
kPiPlus, // Pion
50+
kKPlus, // Kaon
51+
kK0Short, // K0s
52+
kK0Long, // K0l
53+
kProton, // Proton
54+
kNeutron, // Neutron
55+
kLambda0, // Lambda_0
56+
kSigmaMinus, // Sigma Minus
57+
kSigmaPlus, // Sigma Plus
58+
3312, // Xsi Minus
59+
3322, // Xsi
60+
3334, // Omega
61+
kNuE, // Electron Neutrino
62+
kNuMu, // Muon Neutrino
63+
kNuTau // Tau Neutrino
64+
};
65+
66+
// this is linear search ---> a hash map or binary search should be more appropriate??
67+
for (int i = 0; i < kNstable; ++i) {
68+
if (pdg == std::abs(pdgStable[i])) {
69+
return true;
70+
}
71+
}
72+
return false;
73+
}
74+
75+
} // namespace mcutils
76+
} // namespace o2
77+
78+
#endif //O2_MCUTILS_H
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
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+
//
13+
// Created by Sandro Wenzel on 03.11.21.
14+
//
15+
16+
#include <SimulationDataFormat/MCUtils.h>
17+
18+
using namespace o2::mcutils;
19+
20+
// taken from AliRoot and adapted to use of o2::MCTrack class
21+
bool isPhysicalPrimary(o2::MCTrack const& p, std::vector<o2::MCTrack> const& pcontainer)
22+
{
23+
// Test if a particle is a physical primary according to the following definition:
24+
// Particles produced in the collision including products of strong and
25+
// electromagnetic decay and excluding feed-down from weak decays of strange
26+
// particles.
27+
//
28+
29+
const int ist = p.getStatusCode(); // the generator status code
30+
const int pdg = std::abs(p.GetPdgCode());
31+
//
32+
// Initial state particle
33+
// Solution for K0L decayed by Pythia6
34+
// ->
35+
// ist > 1 --> essentially means unstable
36+
if ((ist > 1) && (pdg != 130) && p.isPrimary()) {
37+
return false;
38+
}
39+
if ((ist > 1) && p.isSecondary()) {
40+
return false;
41+
}
42+
// <-
43+
44+
if (!isStable(pdg)) {
45+
return false;
46+
}
47+
48+
if (p.isPrimary()) {
49+
//
50+
// Particle produced by generator
51+
// Solution for K0L decayed by Pythia6
52+
// ->
53+
const int ipm = p.getMotherTrackId();
54+
if (ipm > -1) {
55+
const auto& ppm = pcontainer[ipm];
56+
if (std::abs(ppm.GetPdgCode()) == 130) {
57+
return false;
58+
}
59+
}
60+
// <-
61+
// check for direct photon in parton shower
62+
// ->
63+
const int ipd = p.getFirstDaughterTrackId();
64+
if (pdg == 22 && ipd > -1) {
65+
const auto& ppd = pcontainer[ipd];
66+
if (ppd.GetPdgCode() == 22) {
67+
return false;
68+
}
69+
}
70+
// <-
71+
return true;
72+
} else {
73+
//
74+
// Particle produced during transport
75+
//
76+
77+
int imo = p.getMotherTrackId();
78+
auto pm = &(pcontainer[imo]);
79+
int mpdg = std::abs(pm->GetPdgCode());
80+
// Check for Sigma0
81+
if ((mpdg == 3212) && pm->isPrimary()) {
82+
return true;
83+
}
84+
85+
//
86+
// Check if it comes from a pi0 decay
87+
//
88+
if ((mpdg == kPi0) && pm->isPrimary()) {
89+
return true;
90+
}
91+
92+
// Check if this is a heavy flavor decay product
93+
int mfl = int(mpdg / std::pow(10, int(std::log10(mpdg))));
94+
//
95+
// Light hadron
96+
if (mfl < 4) {
97+
return false;
98+
}
99+
100+
//
101+
// Heavy flavor hadron produced by generator
102+
if (pm->isPrimary()) {
103+
return true;
104+
}
105+
106+
// To be sure that heavy flavor has not been produced in a secondary interaction
107+
// Loop back to the generated mother
108+
while (!pm->isPrimary()) {
109+
imo = pm->getMotherTrackId();
110+
pm = &(pcontainer[imo]);
111+
}
112+
mpdg = std::abs(pm->GetPdgCode());
113+
mfl = int(mpdg / std::pow(10, int(std::log10(mpdg))));
114+
115+
if (mfl < 4) {
116+
return false;
117+
} else {
118+
return true;
119+
}
120+
} // end else branch produced by generator
121+
}

0 commit comments

Comments
 (0)