@@ -138,8 +138,7 @@ DECLARE_SOA_TABLE(ResoMLCandidates, "AOD", "RESOMLCANDIDATES",
138138 resomlcandidates::Phi,
139139 resomlcandidates::Eta,
140140 resomlcandidates::Y,
141- resomlcandidates::Sign,
142- resomlcandidates::IsPhi);
141+ resomlcandidates::Sign);
143142
144143namespace resomlselection
145144{
@@ -185,6 +184,9 @@ struct resonanceTreeCreator {
185184 // Necessary to flag INEL>0 events in GenMC
186185 Service<o2::framework::O2DatabasePDG> pdgDB;
187186
187+ // Cache for manual slicing
188+ SliceCache cache;
189+
188190 enum ParticleType {
189191 Pi,
190192 Ka,
@@ -244,8 +246,9 @@ struct resonanceTreeCreator {
244246 return mother;
245247 }
246248
247- template <bool isMC, typename T1, typename T2>
248- void fillCandidateTree (const T1& collision, const T2& track1, const T2& track2, float masstrack1, float masstrack2)
249+ template <typename T1, typename T2>
250+ void fillCandidateTree (const T1& collision, const T2& track1, const T2& track2, float masstrack1, float masstrack2
251+ /* std::optional<std::reference_wrapper<const aod::McParticles>> mcParticles = std::nullopt*/ )
249252 {
250253 auto tpctofPi1 = combineNSigma<Pi>(track1);
251254 auto tpctofKa1 = combineNSigma<Ka>(track1);
@@ -260,39 +263,43 @@ struct resonanceTreeCreator {
260263 return ;
261264 }
262265
263- bool isPhi = false ;
264- if constexpr (isMC) {
265- if (track1.has_mcParticle () && track2.has_mcParticle ()) {
266- auto mcTrack1 = track1.template mcParticle_as <aod::McParticles>();
267- auto mcTrack2 = track2.template mcParticle_as <aod::McParticles>();
268-
269- auto mothersOfMcTrack1 = mcTrack1.template mothers_as <aod::McParticles>();
270- auto mothersOfMcTrack2 = mcTrack2.template mothers_as <aod::McParticles>();
271-
272- for (const auto & motherOfMcTrack1 : mothersOfMcTrack1) {
273- for (const auto & motherOfMcTrack2 : mothersOfMcTrack2) {
274- if (mcTrack1.pdgCode () == PDG_t::kKPlus && mcTrack2.pdgCode () == PDG_t::kKMinus &&
275- motherOfMcTrack1.pdgCode () == motherOfMcTrack2.pdgCode () && motherOfMcTrack1.pdgCode () == o2::constants::physics::Pdg::kPhi ) {
276- isPhi = true ;
277- break ;
278- }
279- }
280- }
281- }
282-
283- if (fillOnlySignal && !isPhi)
284- return ; // Skip filling if only signal is requested and not a phi candidate
285- if (fillOnlyBackground && isPhi)
286- return ; // Skip filling if only background is requested and a phi candidate
287- }
288-
289266 resoMLCandidates (collision.centFT0M (),
290267 track1.pt (), track1.p (), track1.phi (), track1.eta (), track1.rapidity (masstrack1), track1.dcaXY (), track1.dcaZ (),
291268 track1.tpcNSigmaPi (), track1.tpcNSigmaKa (), track1.tofNSigmaPi (), track1.tofNSigmaKa (), tpctofPi1, tpctofKa1,
292269 track2.pt (), track2.p (), track2.phi (), track2.eta (), track2.rapidity (masstrack2), track2.dcaXY (), track2.dcaZ (),
293270 track2.tpcNSigmaPi (), track2.tpcNSigmaKa (), track2.tofNSigmaPi (), track2.tofNSigmaKa (), tpctofPi2, tpctofKa2,
294271 recCandidate.M (), recCandidate.Pt (), recCandidate.P (), recCandidate.Phi (),
295- recCandidate.Eta (), recCandidate.Rapidity (), track1.sign () + track2.sign (), isPhi);
272+ recCandidate.Eta (), recCandidate.Rapidity (), track1.sign () + track2.sign ());
273+ }
274+
275+ template <typename T>
276+ bool isMCPhi (const T& track1, const T& track2, const aod::McParticles& mcParticles)
277+ {
278+ if (!track1.has_mcParticle () || !track2.has_mcParticle ())
279+ return false ; // Skip filling if no MC truth is available for both tracks
280+
281+ auto mcTrack1 = mcParticles.rawIteratorAt (track1.mcParticleId ());
282+ auto mcTrack2 = mcParticles.rawIteratorAt (track2.mcParticleId ());
283+
284+ if (mcTrack1.pdgCode () != PDG_t::kKPlus || !mcTrack1.isPhysicalPrimary ())
285+ return false ; // Skip filling if the first track is not a primary K+
286+ if (mcTrack2.pdgCode () != PDG_t::kKMinus || !mcTrack2.isPhysicalPrimary ())
287+ return false ; // Skip filling if the second track is not a primary K-
288+
289+ const auto mcTrack1MotherIndexes = mcTrack1.mothersIds ();
290+ const auto mcTrack2MotherIndexes = mcTrack2.mothersIds ();
291+
292+ for (const auto & mcTrack1MotherIndex : mcTrack1MotherIndexes) {
293+ for (const auto & mcTrack2MotherIndex : mcTrack2MotherIndexes) {
294+ if (mcTrack1MotherIndex != mcTrack2MotherIndex)
295+ continue ;
296+
297+ const auto mother = mcParticles.rawIteratorAt (mcTrack1MotherIndex);
298+ if (mother.pdgCode () == o2::constants::physics::Pdg::kPhi )
299+ return true ;
300+ }
301+ }
302+ return false ;
296303 }
297304
298305 void processData (SelCollisions::iterator const & collision, FullTracks const &)
@@ -302,29 +309,28 @@ struct resonanceTreeCreator {
302309
303310 for (const auto & track1 : posThisColl) {
304311 for (const auto & track2 : negThisColl) {
305- if (track1.globalIndex () == track2.globalIndex ())
306- continue ; // condition to avoid double counting of pair
307-
308312 // Fill the ResoMLCandidates table with candidates in Data
309- fillCandidateTree< false > (collision, track1, track2, massKa, massKa);
313+ fillCandidateTree (collision, track1, track2, massKa, massKa);
310314 }
311315 }
312316 }
313317
314318 PROCESS_SWITCH (resonanceTreeCreator, processData, " Fill ResoMLCandidates in Data" , true );
315319
316- void processMC (SimCollisions::iterator const & collision, FullMCTracks const &, aod::McParticles const &)
320+ void processMC (SimCollisions::iterator const & collision, FullMCTracks const &, aod::McParticles const & mcParticles )
317321 {
318322 auto posThisColl = posMCTracks->sliceByCached (aod::track::collisionId, collision.globalIndex (), cache);
319323 auto negThisColl = negMCTracks->sliceByCached (aod::track::collisionId, collision.globalIndex (), cache);
320324
321325 for (const auto & track1 : posThisColl) {
322326 for (const auto & track2 : negThisColl) {
323- if (track1.globalIndex () == track2.globalIndex ())
324- continue ; // condition to avoid double counting of pair
327+ if (fillOnlySignal && !isMCPhi (track1, track2, mcParticles))
328+ return ; // Skip filling if only signal is requested and not a phi in MC truth
329+ if (fillOnlyBackground && isMCPhi (track1, track2, mcParticles))
330+ return ; // Skip filling if only background is requested and a phi in MC truth
325331
326332 // Fill the ResoMLCandidates table with candidates in MC
327- fillCandidateTree< true > (collision, track1, track2, massKa, massKa);
333+ fillCandidateTree (collision, track1, track2, massKa, massKa);
328334 }
329335 }
330336 }
0 commit comments