@@ -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,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
21822360WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments