@@ -126,6 +126,14 @@ struct ParticlePositionWithRespectToJet {
126126};
127127double 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+
129137struct 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,172 @@ 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+ const auto & v0sPerColl = fullV0s.sliceBy (perCollisionV0, collision.globalIndex ());
2240+ const auto & tracksPerColl = mcTracks.sliceBy (perCollisionTrk, collision.globalIndex ());
2241+
2242+ // Loop over reconstructed tracks
2243+ int id (-1 );
2244+ for (auto const & track : tracksPerColl) {
2245+ id++;
2246+
2247+ // Ensure tracks have corresponding MC particles
2248+ if (!track.has_mcParticle ())
2249+ continue ;
2250+
2251+ // Apply track selection for jet reconstruction
2252+ if (!passedTrackSelectionForJetReconstruction (track))
2253+ continue ;
2254+
2255+ // Store particle in particle container
2256+ fastjet::PseudoJet fourMomentum (track.px (), track.py (), track.pz (), track.energy (o2::constants::physics::MassPionCharged));
2257+ fourMomentum.set_user_index (id);
2258+ fjParticles.emplace_back (fourMomentum);
2259+ }
2260+
2261+ // Reject empty events
2262+ if (fjParticles.empty ())
2263+ continue ;
2264+
2265+ // Cluster particles using the anti-kt algorithm
2266+ fastjet::ClusterSequenceArea cs (fjParticles, jetDef, areaDef);
2267+ std::vector<fastjet::PseudoJet> jets = fastjet::sorted_by_pt (cs.inclusive_jets ());
2268+ auto [rhoPerp, rhoMPerp] = jetutilities::estimateRhoPerpCone (fjParticles, jets[0 ], rJet);
2269+
2270+ // Loop over reconstructed jets
2271+ for (const auto & jet : jets) {
2272+
2273+ // Jet must be fully contained in the acceptance
2274+ if ((std::fabs (jet.eta ()) + rJet) > (etaMax - deltaEtaEdge))
2275+ continue ;
2276+
2277+ // Jet pt must be larger than threshold
2278+ auto jetForSub = jet;
2279+ fastjet::PseudoJet jetMinusBkg = backgroundSub.doRhoAreaSub (jetForSub, rhoPerp, rhoMPerp);
2280+ if (jetMinusBkg.pt () < minJetPt)
2281+ continue ;
2282+
2283+ // Jet axis
2284+ TVector3 jetAxis (jet.px (), jet.py (), jet.pz ());
2285+ selectedJet.emplace_back (jetAxis);
2286+
2287+ // Containers
2288+ std::vector<PionsFromK0> pions;
2289+ std::vector<fastjet::PseudoJet> jetConstituents = jet.constituents ();
2290+
2291+ // Loop over jet constituents
2292+ for (const auto & particle : jetConstituents) {
2293+
2294+ auto const & track = mcTracks.iteratorAt (particle.user_index ());
2295+ const auto mcparticle = track.mcParticle ();
2296+ if (std::abs (mcparticle.pdgCode ()) != PDG_t::kPiPlus )
2297+ continue ;
2298+
2299+ auto motherId = mcparticle.mothersIds ()[0 ];
2300+ if (motherId < 0 )
2301+ continue ;
2302+
2303+ auto mother = mcParticles.iteratorAt (motherId);
2304+ if (std::abs (mother.pdgCode ()) != kK0Short )
2305+ continue ;
2306+
2307+ pions.push_back ({track.pt (), mcparticle.pt (), mcparticle.pdgCode (), motherId});
2308+ }
2309+
2310+ const int minimumSize = 2 ;
2311+ if (static_cast <int >(pions.size ()) < minimumSize)
2312+ continue ;
2313+
2314+ for (int i = 0 ; i < static_cast <int >(pions.size ()); i++) {
2315+ for (int j = i + 1 ; j < static_cast <int >(pions.size ()); j++) {
2316+
2317+ if (pions[i].idParent != pions[j].idParent )
2318+ continue ;
2319+ if (pions[i].pdgCode == pions[j].pdgCode )
2320+ continue ;
2321+
2322+ registryMC.fill (HIST (" fractionJetPtCarriedByK0" ), (pions[i].ptRec + pions[j].ptRec ) / jetMinusBkg.pt ());
2323+ registryMC.fill (HIST (" ptSpectrumK0DaughtersInJet" ), pions[i].ptGen + pions[j].ptGen );
2324+ }
2325+ }
2326+ } // end loop over jets
2327+
2328+ for (int i = 0 ; i < static_cast <int >(selectedJet.size ()); i++) {
2329+ for (const auto & v0 : v0sPerColl) {
2330+ const auto & pos = v0.posTrack_as <DaughterTracksMC>();
2331+ const auto & neg = v0.negTrack_as <DaughterTracksMC>();
2332+
2333+ // Get MC particles
2334+ if (!pos.has_mcParticle () || !neg.has_mcParticle ())
2335+ continue ;
2336+ const auto & posParticle = pos.mcParticle_as <aod::McParticles>();
2337+ const auto & negParticle = neg.mcParticle_as <aod::McParticles>();
2338+ if (!posParticle.has_mothers () || !negParticle.has_mothers ())
2339+ continue ;
2340+
2341+ // Select particles originating from the same parent
2342+ if (posParticle.mothersIds ()[0 ] != negParticle.mothersIds ()[0 ])
2343+ continue ;
2344+
2345+ const auto & mother = mcParticles.iteratorAt (posParticle.mothersIds ()[0 ]);
2346+ if (mother.pdgCode () != kK0Short )
2347+ continue ;
2348+
2349+ TVector3 v0dir (v0.px (), v0.py (), v0.pz ());
2350+ float deltaEtaJet = v0dir.Eta () - selectedJet[i].Eta ();
2351+ float deltaPhiJet = ParticlePositionWithRespectToJet::getDeltaPhi (v0dir.Phi (), selectedJet[i].Phi ());
2352+ float deltaRjet = std::sqrt (deltaEtaJet * deltaEtaJet + deltaPhiJet * deltaPhiJet);
2353+
2354+ if (deltaRjet < rJet && passedK0ShortSelection (v0, pos, neg))
2355+ registryMC.fill (HIST (" ptSpectrumK0DaughtersAll" ), mother.pt ());
2356+ } // end loop on V0s
2357+ } // end loop on selected jets
2358+ } // end loop on collisions
2359+ }
2360+ PROCESS_SWITCH (StrangenessInJets, processMCK0shortInJets, " process reconstructed events" , false );
21802361};
21812362
21822363WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments