@@ -55,8 +55,14 @@ namespace o2::aod
5555{
5656// Parent table: one row per collision stored in the MiniAOD
5757DECLARE_SOA_COLUMN (MiniCollTag, miniCollTag, uint8_t );
58+ DECLARE_SOA_COLUMN (MiniCollMcCollisionId, miniCollMcCollisionId, int64_t );
59+ DECLARE_SOA_COLUMN (MiniCollWeight, miniCollWeight, float );
60+ DECLARE_SOA_COLUMN (MiniCollPtHard, miniCollPtHard, float );
5861DECLARE_SOA_TABLE (MiniCollisions, " AOD" , " MINICOLL" ,
59- MiniCollTag);
62+ MiniCollTag,
63+ MiniCollMcCollisionId,
64+ MiniCollWeight,
65+ MiniCollPtHard);
6066
6167// MiniJets -> MiniCollisions
6268DECLARE_SOA_INDEX_COLUMN_CUSTOM (MiniCollision, miniCollision, " MINICOLLS" );
@@ -148,6 +154,12 @@ struct JetMatchInfo {
148154 float otherPt{};
149155};
150156
157+ struct McEventInfo {
158+ int64_t mcCollisionId{-1 };
159+ float weight{1 .f };
160+ float ptHard{-1 .f };
161+ };
162+
151163inline float deltaPhi (float phi1, float phi2)
152164{
153165 return RecoDecay::constrainAngle (phi1 - phi2, -o2::constants::math::PI);
@@ -405,6 +417,9 @@ struct JetLundPlaneUnfolding {
405417 (aod::jet::eta < jetEtaMax.node()) &&
406418 (aod::jet::r == nround(jetR.node() * 100 .f));
407419
420+ // Reconstructed collisions grouped by their associated MC collision.
421+ PresliceUnsorted<soa::Filtered<aod::JetCollisionsMCD>> CollisionsPerMCPCollision = aod::jmccollisionlb::mcCollisionId;
422+
408423 // Type aliases
409424 using RecoJets = soa::Join<aod::ChargedJets, aod::ChargedJetConstituents>;
410425 using DetJetsMatched = soa::Join<aod::ChargedMCDetectorLevelJets,
@@ -530,7 +545,7 @@ struct JetLundPlaneUnfolding {
530545
531546 int miniCollIdx = -1 ;
532547 if (writeMiniAOD.value ) {
533- outMiniCollisions (static_cast <uint8_t >(0 ));
548+ outMiniCollisions (static_cast <uint8_t >(0 ), int64_t {- 1 }, 1 . f , - 1 . f );
534549 miniCollIdx = outMiniCollisions.lastIndex ();
535550 }
536551 for (auto const & jet : jets) {
@@ -559,9 +574,10 @@ struct JetLundPlaneUnfolding {
559574
560575 // MC PROCESSING (det + part + response)
561576
562- void processMC (DetJetsMatched const & detJets,
563- PartJetsMatched const & partJets,
564- aod::JetCollisions const &,
577+ void processMC (soa::Filtered<DetJetsMatched> const & detJets,
578+ soa::Filtered<PartJetsMatched> const & partJets,
579+ soa::Filtered<aod::JetCollisionsMCD> const & collisions,
580+ aod::JetMcCollisions const & mcCollisions,
565581 aod::JetTracks const & tracks,
566582 aod::JetParticles const & particles)
567583 {
@@ -571,6 +587,7 @@ struct JetLundPlaneUnfolding {
571587 std::unordered_map<uint64_t , bool > truthMatchedById;
572588 std::unordered_map<uint64_t , std::vector<SplittingObs>> truthSplittingsById;
573589 std::unordered_map<uint64_t , JetMatchInfo> truthBestDet;
590+ std::unordered_set<uint64_t > acceptedTruthJetKeys;
574591 std::unordered_set<uint64_t > detSplittingsWritten;
575592 std::unordered_set<uint64_t > truthSplittingsWritten;
576593 auto h6 = registry.get <THnSparse>(HIST (" hLundResponse6D" ));
@@ -583,6 +600,21 @@ struct JetLundPlaneUnfolding {
583600 std::unordered_map<uint64_t , int > detJetToMiniJetIdx;
584601 std::unordered_map<uint64_t , int > partJetToMiniJetIdx;
585602
603+ std::unordered_map<int64_t , McEventInfo> mcEventInfoById;
604+ for (auto const & mcCollision : mcCollisions) {
605+ const int64_t mcCollisionId = mcCollision.globalIndex ();
606+ mcEventInfoById.emplace (mcCollisionId,
607+ McEventInfo{mcCollisionId, mcCollision.weight (), mcCollision.ptHard ()});
608+ }
609+
610+ std::unordered_map<int64_t , McEventInfo> mcEventInfoByDetCollisionId;
611+ for (auto const & collision : collisions) {
612+ auto mcInfoIt = mcEventInfoById.find (collision.mcCollisionId ());
613+ if (mcInfoIt != mcEventInfoById.end ()) {
614+ mcEventInfoByDetCollisionId.emplace (collision.globalIndex (), mcInfoIt->second );
615+ }
616+ }
617+
586618 // --- Truth pass ---
587619 // Fill inclusive truth histograms, cache truth splittings, write all accepted
588620 // truth jets to MiniJets, and determine the best detector candidate for each truth jet.
@@ -591,10 +623,22 @@ struct JetLundPlaneUnfolding {
591623 continue ;
592624 }
593625
626+ auto collisionsPerMCPJet = collisions.sliceBy (CollisionsPerMCPCollision, partJet.mcCollisionId ());
627+ if (collisionsPerMCPJet.size () < 1 ) {
628+ continue ;
629+ }
630+
631+ auto partMcInfoIt = mcEventInfoById.find (partJet.mcCollisionId ());
632+ if (partMcInfoIt == mcEventInfoById.end ()) {
633+ continue ;
634+ }
635+ const auto partMcInfo = partMcInfoIt->second ;
636+
594637 registry.fill (HIST (" hJetPtTruthAll" ), partJet.pt ());
595638 fillJetCountSummary (4 );
596639
597640 const uint64_t truthJetKey = partJet.globalIndex ();
641+ acceptedTruthJetKeys.insert (truthJetKey);
598642 auto spl = getPrimarySplittings (partJet, particles);
599643 truthSplittingsById[truthJetKey] = spl;
600644
@@ -607,7 +651,7 @@ struct JetLundPlaneUnfolding {
607651 int partMiniCollIdx = -1 ;
608652 auto collIt = partMiniCollByKey.find (partCollKey);
609653 if (collIt == partMiniCollByKey.end ()) {
610- outMiniCollisions (static_cast <uint8_t >(0 ));
654+ outMiniCollisions (static_cast <uint8_t >(0 ), partMcInfo. mcCollisionId , partMcInfo. weight , partMcInfo. ptHard );
611655 partMiniCollIdx = outMiniCollisions.lastIndex ();
612656 partMiniCollByKey.emplace (partCollKey, partMiniCollIdx);
613657 } else {
@@ -629,7 +673,7 @@ struct JetLundPlaneUnfolding {
629673
630674 JetMatchInfo bestDet{};
631675 bool foundDet = false ;
632- for (auto const & candDetJet : partJet.template matchedJetGeo_as <DetJetsMatched>()) {
676+ for (auto const & candDetJet : partJet.template matchedJetGeo_as <soa::Filtered< DetJetsMatched> >()) {
633677 if (!passJetFiducial (candDetJet, rWanted)) {
634678 continue ;
635679 }
@@ -659,13 +703,19 @@ struct JetLundPlaneUnfolding {
659703 }
660704
661705 // --- Detector loop ---
662- // Write all accepted detector jets to MiniJets. A final matched pair is accepted only
706+ // Write accepted detector jets to MiniJets. A final matched pair is accepted only
663707 // if the detector jet and truth jet are mutual best matches under the same cuts.
664708 for (auto const & detJet : detJets) {
665709 if (!passJetFiducial (detJet, rWanted)) {
666710 continue ;
667711 }
668712
713+ auto detMcInfoIt = mcEventInfoByDetCollisionId.find (detJet.collisionId ());
714+ if (detMcInfoIt == mcEventInfoByDetCollisionId.end ()) {
715+ continue ;
716+ }
717+ const auto detMcInfo = detMcInfoIt->second ;
718+
669719 registry.fill (HIST (" hJetPtRecoAll" ), detJet.pt ());
670720 fillJetCountSummary (1 );
671721
@@ -680,7 +730,7 @@ struct JetLundPlaneUnfolding {
680730 int detMiniCollIdx = -1 ;
681731 auto collIt = detMiniCollByKey.find (detCollKey);
682732 if (collIt == detMiniCollByKey.end ()) {
683- outMiniCollisions (static_cast <uint8_t >(0 ));
733+ outMiniCollisions (static_cast <uint8_t >(0 ), detMcInfo. mcCollisionId , detMcInfo. weight , detMcInfo. ptHard );
684734 detMiniCollIdx = outMiniCollisions.lastIndex ();
685735 detMiniCollByKey.emplace (detCollKey, detMiniCollIdx);
686736 } else {
@@ -706,7 +756,12 @@ struct JetLundPlaneUnfolding {
706756 bool foundMatch = false ;
707757 std::vector<SplittingObs> bestPartSpl;
708758
709- for (auto const & candPartJet : detJet.template matchedJetGeo_as <PartJetsMatched>()) {
759+ for (auto const & candPartJet : detJet.template matchedJetGeo_as <soa::Filtered<PartJetsMatched>>()) {
760+ const uint64_t candTruthKey = candPartJet.globalIndex ();
761+ if (acceptedTruthJetKeys.find (candTruthKey) == acceptedTruthJetKeys.end ()) {
762+ continue ;
763+ }
764+
710765 if (!passJetFiducial (candPartJet, rWanted)) {
711766 continue ;
712767 }
@@ -723,7 +778,6 @@ struct JetLundPlaneUnfolding {
723778 }
724779
725780 if (!foundMatch || dR < bestTruth.dR ) {
726- const uint64_t candTruthKey = candPartJet.globalIndex ();
727781 bestTruth.otherKey = candTruthKey;
728782 bestTruth.dR = dR;
729783 bestTruth.relPt = rel;
@@ -813,6 +867,15 @@ struct JetLundPlaneUnfolding {
813867 continue ;
814868 }
815869
870+ auto collisionsPerMCPJet = collisions.sliceBy (CollisionsPerMCPCollision, partJet.mcCollisionId ());
871+ if (collisionsPerMCPJet.size () < 1 ) {
872+ continue ;
873+ }
874+
875+ if (mcEventInfoById.find (partJet.mcCollisionId ()) == mcEventInfoById.end ()) {
876+ continue ;
877+ }
878+
816879 const uint64_t truthJetKey = partJet.globalIndex ();
817880 if (!truthMatchedById[truthJetKey]) {
818881 registry.fill (HIST (" hJetPtTruthMiss" ), partJet.pt ());
0 commit comments