Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a750f5f
Update CMakeLists.txt
Physicistdana Mar 27, 2026
bf392dd
Update CMakeLists.txt
Physicistdana Mar 28, 2026
d4b81eb
Create qgTreeCreator.cxx
Physicistdana Mar 28, 2026
da5612f
Delete PWGJE/qgTreeCreator.cxx
Physicistdana Mar 28, 2026
8cc4971
Create qgTreeCreator.cxx
Physicistdana Mar 28, 2026
332def0
Merge branch 'AliceO2Group:master' into createqgTreeCreator
Physicistdana Mar 28, 2026
65d1d22
Update qgTreeCreator.cxx
Physicistdana Mar 28, 2026
874b775
Update CMakeLists.txt
Physicistdana Mar 28, 2026
7f83f26
Update CMakeLists.txt
Physicistdana Mar 28, 2026
c9665a1
Merge branch 'AliceO2Group:master' into createqgTreeCreator
Physicistdana Mar 28, 2026
f23ad14
Merge branch 'AliceO2Group:master' into createqgTreeCreator
Physicistdana Mar 28, 2026
9bbf97f
Update CMakeLists.txt
Physicistdana Mar 28, 2026
6747b9b
Update qgTreeCreator.cxx
Physicistdana Mar 28, 2026
391e1c7
Update qgTreeCreator.cxx
Physicistdana Mar 28, 2026
836aba4
Update CMakeLists.txt
Physicistdana Mar 28, 2026
9420cc2
Update CMakeLists.txt
Physicistdana Mar 28, 2026
9e50c17
Merge branch 'AliceO2Group:master' into createqgTreeCreator
Physicistdana Mar 28, 2026
6f9c472
Update o2-linter.yml
Physicistdana Mar 28, 2026
b6545de
Update qgTreeCreator.cxx
Physicistdana Mar 28, 2026
10f4842
Update o2-linter.yml
Physicistdana Mar 28, 2026
5226b16
Update qgTreeCreator.cxx
Physicistdana Mar 28, 2026
040af13
Update CMakeLists.txt
Physicistdana Mar 28, 2026
6d008b9
Update qgTreeCreator.cxx
Physicistdana Mar 28, 2026
60aeffb
Update qgTreeCreator.cxx
Physicistdana Mar 28, 2026
c4ef955
Update qgTreeCreator.cxx
Physicistdana Mar 28, 2026
6db5360
Update qgTreeCreator.cxx
Physicistdana Mar 28, 2026
5ae5f73
Update qgTreeCreator.cxx
Physicistdana Mar 29, 2026
c415b12
Merge branch 'AliceO2Group:master' into createqgTreeCreator
Physicistdana Mar 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/o2-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
name: O2 linter

#"on": [pull_request_target, push]
on:
pull_request_target:
permissions: {}
env:
BRANCH_MAIN: master
Expand Down
9 changes: 9 additions & 0 deletions PWGJE/Tasks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -403,4 +403,13 @@ if(FastJet_FOUND)
SOURCES bjetCentMult.cxx
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore
COMPONENT_NAME Analysis)

o2physics_add_dpl_workflow(qg-tree-creator
SOURCES qgTreeCreator.cxx
PUBLIC_LINK_LIBRARIES
O2::Framework
O2Physics::AnalysisCore
O2Physics::PWGJECore
COMPONENT_NAME Analysis)

endif()
209 changes: 209 additions & 0 deletions PWGJE/Tasks/qgTreeCreator.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

#include "PWGJE/DataModel/Jet.h"
#include "PWGJE/DataModel/JetMatching.h"

#include "Common/DataModel/MCTruthContainer.h"
#include "Common/DataModel/TrackSelectionTables.h"

#include "Framework/AnalysisTask.h"
#include "Framework/Configurable.h"
#include "Framework/HistogramRegistry.h"
#include "Framework/runDataProcessing.h"

#include <cmath>

using namespace o2;
using namespace o2::framework;

namespace o2::aod
{
DECLARE_SOA_COLUMN(JetPt, jetPt, float);
DECLARE_SOA_COLUMN(JetEta, jetEta, float);
DECLARE_SOA_COLUMN(JetPhi, jetPhi, float);
DECLARE_SOA_COLUMN(NConst, nConst, int);
DECLARE_SOA_COLUMN(Girth, girth, float);
DECLARE_SOA_COLUMN(PTD, pTD, float);
DECLARE_SOA_COLUMN(MatchDeltaR, matchDeltaR, float);
DECLARE_SOA_COLUMN(PtResponse, ptResponse, float);
DECLARE_SOA_COLUMN(QGLabel, qgLabel, int);

DECLARE_SOA_TABLE(QGJetTable, "AOD", "QGJET",
JetPt,
JetEta,
JetPhi,
NConst,
Girth,
PTD,
MatchDeltaR,
PtResponse,
QGLabel);
} // namespace o2::aod

//------------------------------------------------
// helper functions
//------------------------------------------------
float deltaPhi(float phi1, float phi2)
{
return std::remainder(phi1 - phi2, 2.f * static_cast<float>(M_PI));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is RecoDecay::constrainAngle for this.

}

float deltaR(float eta1, float phi1, float eta2, float phi2)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this an existing method?

{
float deta = eta1 - eta2;
float dphi = deltaPhi(phi1, phi2);
return std::sqrt(deta * deta + dphi * dphi);
}

//------------------------------------------------
// find initiating parton by ancestry
//------------------------------------------------
int getInitiatingParton(auto const& particle,
aod::McParticles const& mcParticles)
{
auto p = particle;
int pdg = p.pdgCode();

while (p.has_mothers()) {
auto mothers = p.mothers_as<aod::McParticles>();
if (mothers.size() == 0) {
break;
}

auto mom = mothers.iteratorAt(0);
int mpdg = mom.pdgCode();

// stop at quark or gluon
if (std::abs(mpdg) == 21 || (std::abs(mpdg) >= 1 && std::abs(mpdg) <= 6)) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use magic numbers.

pdg = mpdg;
}

p = mom;
}

return pdg;
}

//------------------------------------------------
// main task
//------------------------------------------------
struct QGTreeCreator {
Configurable<float> jetPtMin{"jetPtMin", 10.f};
Configurable<float> maxMatchDeltaR{"maxMatchDeltaR", 0.3f};

Produces<aod::QGJetTable> qgjets;

void process(aod::ChargedMCDetectorLevelJets const& recoJets,
aod::ChargedMCParticleLevelJets const& truthJets,
aod::ChargedMCDetectorLevelJetsMatchedToChargedMCParticleLevelJets const& matches,
aod::McParticles const& mcParticles)
{
for (auto const& jet : recoJets) {
if (jet.pt() < jetPtMin) {
continue;
}

//----------------------------------
// compute jet observables
//----------------------------------
int nconst = 0;
float sumPt = 0;
float sumPt2 = 0;
float sumPtDr = 0;

for (auto const& c : jet.tracks_as<aod::ChargedMCDetectorLevelJetConstituent>()) {
float pt = c.pt();
float dr = deltaR(c.eta(), c.phi(), jet.eta(), jet.phi());

nconst++;
sumPt += pt;
sumPt2 += pt * pt;
sumPtDr += pt * dr;
}

float girth = sumPt > 0 ? sumPtDr / sumPt : -1;
float ptd = sumPt > 0 ? std::sqrt(sumPt2) / sumPt : -1;

//----------------------------------
// matching block
//----------------------------------
float matchDr = -1;
float ptResp = -1;
int qg = -1;

for (auto const& match : matches) {
if (match.chargedMCDetectorLevelJetId() != jet.globalIndex()) {
continue;
}

auto truthJet = truthJets.iteratorAt(
match.chargedMCParticleLevelJetId());

matchDr = deltaR(jet.eta(), jet.phi(),
truthJet.eta(), truthJet.phi());

if (matchDr > maxMatchDeltaR) {
continue;
}

ptResp = jet.pt() / truthJet.pt();

//----------------------------------
// find initiating parton
//----------------------------------
float maxPt = -1;
int pdg = 0;

for (auto const& tc :
truthJet.tracks_as<aod::ChargedMCParticleLevelJetConstituent>()) {
if (!tc.has_mcParticle()) {
continue;
}

auto mc = tc.mcParticle();

if (tc.pt() > maxPt) {
maxPt = tc.pt();
pdg = getInitiatingParton(mc, mcParticles);
}
}

//----------------------------------
// assign q/g label
//----------------------------------
if (std::abs(pdg) == 21) {
qg = 1; // gluon
} else if (std::abs(pdg) >= 1 && std::abs(pdg) <= 6) {
qg = 0; // quark
}

break;
}

qgjets(jet.pt(),
jet.eta(),
jet.phi(),
nconst,
girth,
ptd,
matchDr,
ptResp,
qg);
}
}
};

WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
{
return WorkflowSpec{
adaptAnalysisTask<QGTreeCreator>(cfgc, TaskName{"qg-tree-creator"})};
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need TaskName?

}
Loading