Skip to content

Commit f537df4

Browse files
committed
Add function to compute jet pt resolution
1 parent 85604b4 commit f537df4

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed

PWGLF/Tasks/Nuspex/antinucleiInJets.cxx

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@ struct ReducedParticle {
128128
}
129129
};
130130

131+
// Jet Matching
132+
struct JetMatching {
133+
double distance;
134+
double ptTrue;
135+
double ptDiff;
136+
};
137+
131138
struct AntinucleiInJets {
132139

133140
// Histogram registries for data, MC, quality control, multiplicity and correlations
@@ -145,6 +152,7 @@ struct AntinucleiInJets {
145152
Configurable<double> cfgAreaFrac{"cfgAreaFrac", 0.6, "fraction of jet area"};
146153
Configurable<double> cfgEtaJetMax{"cfgEtaJetMax", 0.5, "max jet eta"};
147154
Configurable<double> cfgMinPtTrack{"cfgMinPtTrack", 0.15, "minimum pt of tracks for jet reconstruction"};
155+
Configurable<double> alpha{"alpha", 0.3, "parameter to control jet matching"};
148156

149157
// Event selection criteria
150158
Configurable<bool> rejectITSROFBorder{"rejectITSROFBorder", true, "Reject events near the ITS ROF border"};
@@ -501,6 +509,11 @@ struct AntinucleiInJets {
501509
registryMC.add("antiproton_coal_ue", "antiproton_coal_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}});
502510
}
503511

512+
// jet pt resolution
513+
if (doprocessJetPtResolution) {
514+
registryMC.add("jetPtResolution", "jet Pt Resolution", HistType::kTH2F, {{200, 0, 20, "#it{p}^{jet}_{T,true} (GeV/#it{c})"}}, {{1000, -5, 5, "#Delta #it{p}^{jet}_{T} (GeV/#it{c})"}});
515+
}
516+
504517
// Coalescence and Correlation analysis
505518
if (doprocessCoalescenceCorr) {
506519

@@ -3912,6 +3925,154 @@ struct AntinucleiInJets {
39123925
}
39133926
}
39143927
PROCESS_SWITCH(AntinucleiInJets, processCoalescenceCorr, "process coalescence correlation", false);
3928+
3929+
3930+
// Jet Pt resolution
3931+
void processJetPtResolution(RecCollisionsMc const& collisions, AntiNucleiTracksMc const& mcTracks, aod::McParticles const& mcParticles)
3932+
{
3933+
// Define per-event particle containers
3934+
std::vector<fastjet::PseudoJet> fjParticles;
3935+
std::vector<fastjet::PseudoJet> fjTracks;
3936+
3937+
// Jet and area definitions
3938+
fastjet::JetDefinition jetDef(fastjet::antikt_algorithm, rJet);
3939+
fastjet::AreaDefinition areaDef(fastjet::active_area, fastjet::GhostedAreaSpec(1.0));
3940+
3941+
// Loop over all reconstructed collisions
3942+
for (const auto& collision : collisions) {
3943+
3944+
// Clear containers at the start of the event loop
3945+
fjParticles.clear();
3946+
fjTracks.clear();
3947+
3948+
// Reject reconstructed collisions with no simulated collision
3949+
if (!collision.has_mcCollision())
3950+
continue;
3951+
3952+
// Apply event selection: require sel8 and vertex position to be within the allowed z range
3953+
if (!collision.sel8() || std::fabs(collision.posZ()) > zVtx)
3954+
continue;
3955+
3956+
// Reject events near the ITS Read-Out Frame border
3957+
if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder))
3958+
continue;
3959+
3960+
// Reject events at the Time Frame border
3961+
if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder))
3962+
continue;
3963+
3964+
// Require at least one ITS-TPC matched track
3965+
if (requireVtxITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC))
3966+
continue;
3967+
3968+
// Reject events with same-bunch pileup
3969+
if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup))
3970+
continue;
3971+
3972+
// Require consistent FT0 vs PV z-vertex
3973+
if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV))
3974+
continue;
3975+
3976+
// Require TOF match for at least one vertex track
3977+
if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched))
3978+
continue;
3979+
3980+
// Get tracks and particles in this MC collision
3981+
const auto mcTracksThisMcColl = mcTracks.sliceBy(mcTracksPerMcCollision, collision.globalIndex());
3982+
const auto mcParticlesThisMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, collision.globalIndex());
3983+
3984+
// Loop over reconstructed tracks
3985+
for (auto const& track : mcTracksThisMcColl) {
3986+
3987+
// Apply track selection for jet reconstruction
3988+
if (!passedTrackSelectionForJetReconstruction(track))
3989+
continue;
3990+
3991+
// 4-momentum representation of a particle
3992+
fastjet::PseudoJet fourMomentum(track.px(), track.py(), track.pz(), track.energy(MassPionCharged));
3993+
fjTracks.emplace_back(fourMomentum);
3994+
}
3995+
3996+
// Loop over MC particles
3997+
for (const auto& particle : mcParticlesThisMcColl) {
3998+
3999+
// Select physical primary particles or HF decay products
4000+
if (!isPhysicalPrimaryOrFromHF(particle, mcParticles))
4001+
continue;
4002+
4003+
// Select particles within acceptance
4004+
if (particle.eta() < minEta || particle.eta() > maxEta || particle.pt() < cfgMinPtTrack)
4005+
continue;
4006+
4007+
// 4-momentum representation of a particle
4008+
double energy = std::sqrt(particle.p() * particle.p() + MassPionCharged * MassPionCharged);
4009+
fastjet::PseudoJet fourMomentum(particle.px(), particle.py(), particle.pz(), energy);
4010+
fjParticles.emplace_back(fourMomentum);
4011+
}
4012+
4013+
// Reject empty events
4014+
if (fjTracks.empty() || fjParticles.empty())
4015+
continue;
4016+
4017+
// Cluster particles using the anti-kt algorithm
4018+
fastjet::ClusterSequenceArea csRec(fjTracks, jetDef, areaDef);
4019+
std::vector<fastjet::PseudoJet> jetsRec = fastjet::sorted_by_pt(csRec.inclusive_jets());
4020+
4021+
fastjet::ClusterSequenceArea csGen(fjParticles, jetDef, areaDef);
4022+
std::vector<fastjet::PseudoJet> jetsGen = fastjet::sorted_by_pt(csGen.inclusive_jets());
4023+
4024+
// Loop over reconstructed jets
4025+
std::vector<JetMatching> jetGenRec;
4026+
for (const auto& jetRec : jetsRec) {
4027+
4028+
// Jet must be fully contained in the acceptance
4029+
if ((std::fabs(jetRec.eta()) + rJet) > (maxEta - deltaEtaEdge))
4030+
continue;
4031+
4032+
// Apply area cut if required
4033+
if (applyAreaCut && (jetRec.area() / (PI * rJet * rJet)) > maxNormalizedJetArea)
4034+
continue;
4035+
4036+
// Clear jet-pair container
4037+
jetGenRec.clear();
4038+
4039+
for (const auto& jetGen : jetsGen) {
4040+
4041+
// Jet must be fully contained in the acceptance
4042+
if ((std::fabs(jetGen.eta()) + rJet) > (maxEta - deltaEtaEdge))
4043+
continue;
4044+
4045+
// Apply area cut if required
4046+
if (applyAreaCut && (jetGen.area() / (PI * rJet * rJet)) > maxNormalizedJetArea)
4047+
continue;
4048+
4049+
double deltaEta = jetGen.eta() - jetRec.eta();
4050+
double deltaPhi = getDeltaPhi(jetGen.phi(), jetRec.phi());
4051+
double deltaR = std::sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi);
4052+
if (deltaR < rJet)
4053+
jetGenRec.emplace_back({deltaR, jetGen.pt(), jetGen.pt() - jetRec.pt()});
4054+
}
4055+
if (jetGenRec.empty())
4056+
continue;
4057+
4058+
double distanceMin(1e+06);
4059+
double diffPt(0);
4060+
double ptJetTrue(0);
4061+
for (const auto& jetPair : jetGenRec) {
4062+
if (jetPair.distance < distanceMin) {
4063+
distanceMin = jetPair.distance;
4064+
diffPt = jetPair.ptDiff;
4065+
ptJetTrue = jetPair.ptTrue;
4066+
}
4067+
}
4068+
4069+
if (distanceMin < alpha * rJet) {
4070+
registryMC.fill(HIST("jetPtResolution"), ptJetTrue, diffPt);
4071+
}
4072+
}
4073+
}
4074+
}
4075+
PROCESS_SWITCH(AntinucleiInJets, processJetPtResolution, "process jet pt resolution", false);
39154076
};
39164077

39174078
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)

0 commit comments

Comments
 (0)