Skip to content

Commit 8cc4971

Browse files
Create qgTreeCreator.cxx
1 parent da5612f commit 8cc4971

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed

PWGJE/Tasks/qgTreeCreator.cxx

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
#include "Framework/runDataProcessing.h"
2+
#include "Framework/AnalysisTask.h"
3+
#include "Framework/HistogramRegistry.h"
4+
#include "Framework/Configurable.h"
5+
6+
#include "PWGJE/DataModel/Jet.h"
7+
#include "PWGJE/DataModel/JetMatching.h"
8+
#include "Common/DataModel/TrackSelectionTables.h"
9+
#include "Common/DataModel/MCTruthContainer.h"
10+
11+
#include <cmath>
12+
13+
using namespace o2;
14+
using namespace o2::framework;
15+
16+
namespace o2::aod
17+
{
18+
DECLARE_SOA_COLUMN(JetPt, jetPt, float);
19+
DECLARE_SOA_COLUMN(JetEta, jetEta, float);
20+
DECLARE_SOA_COLUMN(JetPhi, jetPhi, float);
21+
DECLARE_SOA_COLUMN(NConst, nConst, int);
22+
DECLARE_SOA_COLUMN(Girth, girth, float);
23+
DECLARE_SOA_COLUMN(PTD, pTD, float);
24+
DECLARE_SOA_COLUMN(MatchDeltaR, matchDeltaR, float);
25+
DECLARE_SOA_COLUMN(PtResponse, ptResponse, float);
26+
DECLARE_SOA_COLUMN(QGLabel, qgLabel, int);
27+
28+
DECLARE_SOA_TABLE(QGJetTable, "AOD", "QGJET",
29+
JetPt,
30+
JetEta,
31+
JetPhi,
32+
NConst,
33+
Girth,
34+
PTD,
35+
MatchDeltaR,
36+
PtResponse,
37+
QGLabel);
38+
}
39+
40+
//------------------------------------------------
41+
// helper functions
42+
//------------------------------------------------
43+
float deltaPhi(float phi1, float phi2)
44+
{
45+
return std::remainder(phi1 - phi2, 2.f * static_cast<float>(M_PI));
46+
}
47+
48+
float deltaR(float eta1, float phi1, float eta2, float phi2)
49+
{
50+
float deta = eta1 - eta2;
51+
float dphi = deltaPhi(phi1, phi2);
52+
return std::sqrt(deta * deta + dphi * dphi);
53+
}
54+
55+
//------------------------------------------------
56+
// find initiating parton by ancestry
57+
//------------------------------------------------
58+
int getInitiatingParton(auto const& particle,
59+
aod::McParticles const& mcParticles)
60+
{
61+
auto p = particle;
62+
int pdg = p.pdgCode();
63+
64+
while (p.has_mothers()) {
65+
auto mothers = p.mothers_as<aod::McParticles>();
66+
if (mothers.size() == 0) {
67+
break;
68+
}
69+
70+
auto mom = mothers.iteratorAt(0);
71+
int mpdg = mom.pdgCode();
72+
73+
// stop at quark or gluon
74+
if (std::abs(mpdg) == 21 || (std::abs(mpdg) >= 1 && std::abs(mpdg) <= 6)) {
75+
pdg = mpdg;
76+
}
77+
78+
p = mom;
79+
}
80+
81+
return pdg;
82+
}
83+
84+
//------------------------------------------------
85+
// main task
86+
//------------------------------------------------
87+
struct QGTreeCreator {
88+
89+
Configurable<float> jetPtMin{"jetPtMin",10.f};
90+
Configurable<float> maxMatchDeltaR{"maxMatchDeltaR",0.3f};
91+
92+
Produces<aod::QGJetTable> qgjets;
93+
94+
void process(aod::ChargedMCDetectorLevelJets const& recoJets,
95+
aod::ChargedMCParticleLevelJets const& truthJets,
96+
aod::ChargedMCDetectorLevelJetsMatchedToChargedMCParticleLevelJets const& matches,
97+
aod::McParticles const& mcParticles)
98+
{
99+
for (auto const& jet : recoJets) {
100+
101+
if (jet.pt() < jetPtMin)
102+
continue;
103+
104+
//----------------------------------
105+
// compute jet observables
106+
//----------------------------------
107+
int nconst = 0;
108+
float sumPt = 0;
109+
float sumPt2 = 0;
110+
float sumPtDr = 0;
111+
112+
for (auto const& c : jet.tracks_as<aod::ChargedMCDetectorLevelJetConstituent>()) {
113+
float pt = c.pt();
114+
float dr = deltaR(c.eta(), c.phi(), jet.eta(), jet.phi());
115+
116+
nconst++;
117+
sumPt += pt;
118+
sumPt2 += pt*pt;
119+
sumPtDr += pt*dr;
120+
}
121+
122+
float girth = sumPt>0 ? sumPtDr/sumPt : -1;
123+
float ptd = sumPt>0 ? std::sqrt(sumPt2)/sumPt : -1;
124+
125+
//----------------------------------
126+
// matching block
127+
//----------------------------------
128+
float matchDr = -1;
129+
float ptResp = -1;
130+
int qg = -1;
131+
132+
for (auto const& match : matches) {
133+
134+
if (match.chargedMCDetectorLevelJetId() != jet.globalIndex())
135+
continue;
136+
137+
auto truthJet = truthJets.iteratorAt(
138+
match.chargedMCParticleLevelJetId());
139+
140+
matchDr = deltaR(jet.eta(), jet.phi(),
141+
truthJet.eta(), truthJet.phi());
142+
143+
if (matchDr > maxMatchDeltaR)
144+
continue;
145+
146+
ptResp = jet.pt() / truthJet.pt();
147+
148+
//----------------------------------
149+
// find initiating parton
150+
//----------------------------------
151+
float maxPt = -1;
152+
int pdg = 0;
153+
154+
for (auto const& tc :
155+
truthJet.tracks_as<aod::ChargedMCParticleLevelJetConstituent>())
156+
{
157+
if (!tc.has_mcParticle())
158+
continue;
159+
160+
auto mc = tc.mcParticle();
161+
162+
if (tc.pt() > maxPt) {
163+
maxPt = tc.pt();
164+
pdg = getInitiatingParton(mc, mcParticles);
165+
}
166+
}
167+
168+
//----------------------------------
169+
// assign q/g label
170+
//----------------------------------
171+
if (std::abs(pdg) == 21)
172+
qg = 1; // gluon
173+
else if (std::abs(pdg) >= 1 && std::abs(pdg) <= 6)
174+
qg = 0; // quark
175+
176+
break;
177+
}
178+
179+
//----------------------------------
180+
// store
181+
//----------------------------------
182+
qgjets(jet.pt(),
183+
jet.eta(),
184+
jet.phi(),
185+
nconst,
186+
girth,
187+
ptd,
188+
matchDr,
189+
ptResp,
190+
qg);
191+
}
192+
}
193+
};
194+
195+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
196+
{
197+
return WorkflowSpec{
198+
adaptAnalysisTask<QGTreeCreator>(cfgc, TaskName{"qg-tree-creator"})};
199+
}

0 commit comments

Comments
 (0)