Skip to content

Commit 576f4de

Browse files
committed
[PWGLF] Add study of jet pt bias from K0s daughters
1 parent 93e4fbf commit 576f4de

File tree

1 file changed

+185
-7
lines changed

1 file changed

+185
-7
lines changed

PWGLF/Tasks/Strangeness/strangenessInJets.cxx

Lines changed: 185 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,14 @@ struct ParticlePositionWithRespectToJet {
126126
};
127127
double ParticlePositionWithRespectToJet::mJetRadius = 0.0;
128128

129+
// Reduced particle container with pions from K0s
130+
struct PionsFromK0 {
131+
double ptRec;
132+
double ptGen;
133+
int pdgCode;
134+
int idParent;
135+
};
136+
129137
struct StrangenessInJets {
130138

131139
// Instantiate the CCDB service and API interface
@@ -366,6 +374,13 @@ struct StrangenessInJets {
366374
}
367375
}
368376

377+
// Histograms for MC K0 short in jets
378+
if (doprocessMCK0shortInJets) {
379+
registryMC.add("ptSpectrumK0DaughtersAll", "ptSpectrumK0DaughtersAll", HistType::kTH1D, {{1000, 0, 100, "p_{T}"}});
380+
registryMC.add("fractionJetPtCarriedByK0", "fractionJetPtCarriedByK0", HistType::kTH1D, {{1000, 0, 1, "fraction"}});
381+
registryMC.add("ptSpectrumK0DaughtersInJet", "ptSpectrumK0DaughtersInJet", HistType::kTH1D, {{1000, 0, 100, "p_{T}"}});
382+
}
383+
369384
// Histograms for mc reconstructed
370385
if (doprocessMCreconstructed) {
371386

@@ -2029,7 +2044,7 @@ struct StrangenessInJets {
20292044
}
20302045

20312046
// PID selections
2032-
Bool_t isPIDK0s = false, isPIDLam = false, isPIDALam = false;
2047+
bool isPIDK0s = false, isPIDLam = false, isPIDALam = false;
20332048

20342049
// PID selections (TPC) -- K0s
20352050
if (v0.ntpcsigmapospi() >= nsigmaTPCmin && v0.ntpcsigmapospi() <= nsigmaTPCmax &&
@@ -2106,10 +2121,10 @@ struct StrangenessInJets {
21062121
continue;
21072122

21082123
// PID selection
2109-
Bool_t isPIDXiminus = false, isPIDXiplus = false, isPIDOmminus = false, isPIDOmplus = false;
2124+
bool isPIDXiminus = false, isPIDXiplus = false, isPIDOmminus = false, isPIDOmplus = false;
21102125

21112126
// PID selection bachelor
2112-
Bool_t isPIDLam = false, isPIDALam = false;
2127+
bool isPIDLam = false, isPIDALam = false;
21132128
if (casc.sign() > 0) {
21142129
// antiLambda: (p-)neg + (pi+)pos
21152130
if (casc.ntpcsigmanegpr() >= nsigmaTPCmin && casc.ntpcsigmanegpr() <= nsigmaTPCmax &&
@@ -2132,15 +2147,15 @@ struct StrangenessInJets {
21322147
continue;
21332148

21342149
// PID selection on bachelor
2135-
const Bool_t isBachPi =
2150+
const bool isBachPi =
21362151
(casc.ntpcsigmabachpi() >= nsigmaTPCmin && casc.ntpcsigmabachpi() <= nsigmaTPCmax);
21372152

2138-
const Bool_t isBachKa =
2153+
const bool isBachKa =
21392154
(casc.ntpcsigmabachka() >= nsigmaTPCmin && casc.ntpcsigmabachka() <= nsigmaTPCmax);
21402155

21412156
// Cross-contamination rejection flags
2142-
const Bool_t isOmegaLike = (std::fabs(casc.massomega() - o2::constants::physics::MassOmegaMinus) < deltaMassOmega);
2143-
const Bool_t isXiLike = (std::fabs(casc.massxi() - o2::constants::physics::MassXiMinus) < deltaMassXi);
2157+
const bool isOmegaLike = (std::fabs(casc.massomega() - o2::constants::physics::MassOmegaMinus) < deltaMassOmega);
2158+
const bool isXiLike = (std::fabs(casc.massxi() - o2::constants::physics::MassXiMinus) < deltaMassXi);
21442159

21452160
// Final PID flags
21462161
if (casc.sign() > 0) {
@@ -2177,6 +2192,169 @@ struct StrangenessInJets {
21772192
}
21782193
}
21792194
PROCESS_SWITCH(StrangenessInJets, processDerivedAnalysis, "Postprocessing for derived data analysis", false);
2195+
2196+
// Process MC K0 short in jets
2197+
void processMCK0shortInJets(SimCollisions const& collisions, soa::Join<aod::McCollisions, aod::McCentFT0Ms> const&,
2198+
DaughterTracksMC const& mcTracks, aod::V0Datas const& fullV0s, aod::McParticles const& mcParticles)
2199+
{
2200+
// Define particle container for FastJet and array of vectors for selected jets
2201+
std::vector<fastjet::PseudoJet> fjParticles;
2202+
std::vector<TVector3> selectedJet;
2203+
2204+
// Jet and area definitions
2205+
fastjet::JetDefinition jetDef(fastjet::antikt_algorithm, rJet);
2206+
fastjet::AreaDefinition areaDef(fastjet::active_area, fastjet::GhostedAreaSpec(1.0));
2207+
2208+
// Loop over all reconstructed collisions
2209+
for (const auto& collision : collisions) {
2210+
2211+
// Clear containers at the start of the event loop
2212+
fjParticles.clear();
2213+
selectedJet.clear();
2214+
2215+
// Apply event selection: require sel8 and vertex position to be within 10 cm from ALICE center
2216+
if (!collision.sel8() || std::fabs(collision.posZ()) > zVtx)
2217+
continue;
2218+
2219+
// Reject events near the ITS Read-Out Frame border
2220+
if (!collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder))
2221+
continue;
2222+
2223+
// Reject events at the Time Frame border
2224+
if (!collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder))
2225+
continue;
2226+
2227+
// Require at least one ITS-TPC matched track
2228+
if (!collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC))
2229+
continue;
2230+
2231+
// Reject events with same-bunch pileup
2232+
if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup))
2233+
continue;
2234+
2235+
// Require consistent FT0 vs PV z-vertex
2236+
if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV))
2237+
continue;
2238+
2239+
// Loop over reconstructed tracks
2240+
int id(-1);
2241+
for (auto const& track : perCollisionTrk) {
2242+
id++;
2243+
2244+
// Ensure tracks have corresponding MC particles
2245+
if (!track.has_mcParticle())
2246+
continue;
2247+
2248+
// Apply track selection for jet reconstruction
2249+
if (!passedTrackSelectionForJetReconstruction(track))
2250+
continue;
2251+
2252+
// Store particle in particle container
2253+
fastjet::PseudoJet fourMomentum(track.px(), track.py(), track.pz(), track.energy(o2::constants::physics::MassPionCharged));
2254+
fourMomentum.set_user_index(id);
2255+
fjParticles.emplace_back(fourMomentum);
2256+
}
2257+
2258+
// Reject empty events
2259+
if (fjParticles.empty())
2260+
continue;
2261+
2262+
// Cluster particles using the anti-kt algorithm
2263+
fastjet::ClusterSequenceArea cs(fjParticles, jetDef, areaDef);
2264+
std::vector<fastjet::PseudoJet> jets = fastjet::sorted_by_pt(cs.inclusive_jets());
2265+
auto [rhoPerp, rhoMPerp] = jetutilities::estimateRhoPerpCone(fjParticles, jets[0], rJet);
2266+
2267+
// Loop over reconstructed jets
2268+
for (const auto& jet : jets) {
2269+
2270+
// Jet must be fully contained in the acceptance
2271+
if ((std::fabs(jet.eta()) + rJet) > (maxEta - deltaEtaEdge))
2272+
continue;
2273+
2274+
// Jet pt must be larger than threshold
2275+
auto jetForSub = jet;
2276+
fastjet::PseudoJet jetMinusBkg = backgroundSub.doRhoAreaSub(jetForSub, rhoPerp, rhoMPerp);
2277+
if (jetMinusBkg.pt() < minJetPt)
2278+
continue;
2279+
2280+
// Jet axis
2281+
TVector3 jetAxis(jet.px(), jet.py(), jet.pz());
2282+
selectedJet.emplace_back(jetAxis);
2283+
2284+
// Containers
2285+
std::vector<PionsFromK0> pions;
2286+
std::vector<fastjet::PseudoJet> jetConstituents = jet.constituents();
2287+
2288+
// Loop over jet constituents
2289+
for (const auto& particle : jetConstituents) {
2290+
2291+
auto const& track = perCollisionTrk.iteratorAt(particle.user_index());
2292+
const auto mcparticle = track.mcParticle();
2293+
if (std::abs(mcparticle.pdgCode()) != PDG_t::kPiPlus)
2294+
continue;
2295+
2296+
auto motherId = mcparticle.mothersIds()[0];
2297+
if (motherId < 0)
2298+
continue;
2299+
2300+
auto mother = mcParticles.iteratorAt(motherId);
2301+
if (std::abs(mother.pdgCode()) != kK0Short)
2302+
continue;
2303+
2304+
pions.push_back({track.pt(), mcparticle.pt(), mcparticle.pdgCode(), motherId});
2305+
}
2306+
2307+
const int minimumSize = 2;
2308+
if (static_cast<int>(pions.size()) < minimumSize)
2309+
continue;
2310+
2311+
for (int i=0 ; i < pions.size() ; i++) {
2312+
for (int j=i+1 ; j < pions.size() ; j++) {
2313+
2314+
if (pions[i].idParent != pions[j].idParent)
2315+
continue;
2316+
if (pions[i].pdgCode == pions[j].pdgCode)
2317+
continue;
2318+
2319+
registryMC.fill(HIST("fractionJetPtCarriedByK0"), (pions[i].ptRec + pions[j].ptRec) / jetMinusBkg.pt());
2320+
registryMC.fill(HIST("ptSpectrumK0DaughtersInJet"), pions[i].ptGen + pions[j].ptGen);
2321+
}
2322+
}
2323+
}// end loop over jets
2324+
2325+
for (int i = 0; i < static_cast<int>(selectedJet.size()); i++) {
2326+
for (const auto& v0 : v0sPerColl) {
2327+
const auto& pos = v0.posTrack_as<DaughterTracksMC>();
2328+
const auto& neg = v0.negTrack_as<DaughterTracksMC>();
2329+
2330+
// Get MC particles
2331+
if (!pos.has_mcParticle() || !neg.has_mcParticle())
2332+
continue;
2333+
const auto& posParticle = pos.mcParticle_as<aod::McParticles>();
2334+
const auto& negParticle = neg.mcParticle_as<aod::McParticles>();
2335+
if (!posParticle.has_mothers() || !negParticle.has_mothers())
2336+
continue;
2337+
2338+
// Select particles originating from the same parent
2339+
if (posParticle.mothersIds()[0] != negParticle.mothersIds()[0])
2340+
continue;
2341+
2342+
const auto& mother = mcParticles.iteratorAt(posParticle.mothersIds()[0]);
2343+
if (mother.pdgCode() != kK0Short)
2344+
continue;
2345+
2346+
TVector3 v0dir(v0.px(), v0.py(), v0.pz());
2347+
float deltaEtaJet = v0dir.Eta() - selectedJet[i].Eta();
2348+
float deltaPhiJet = getDeltaPhi(v0dir.Phi(), selectedJet[i].Phi());
2349+
float deltaRjet = std::sqrt(deltaEtaJet * deltaEtaJet + deltaPhiJet * deltaPhiJet);
2350+
2351+
if (deltaRjet < rJet && passedK0ShortSelection(v0, pos, neg))
2352+
registryMC.fill(HIST("ptSpectrumK0DaughtersAll"), mother.pt());
2353+
}// end loop on V0s
2354+
}// end loop on selected jets
2355+
}// end loop on collisions
2356+
}
2357+
PROCESS_SWITCH(StrangenessInJets, processMCK0shortInJets, "process reconstructed events", false);
21802358
};
21812359

21822360
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)

0 commit comments

Comments
 (0)