From 048d727ed73211eea88f2891e7491d33aaf10462 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Fri, 9 Oct 2026 23:42:48 +0200 Subject: [PATCH] [PWGEM] reduce memory usage in EMH --- PWGEM/Dilepton/Core/Dilepton.h | 21 ++++++---- PWGEM/Dilepton/Core/DileptonHadronMPC.h | 22 +++++------ PWGEM/Dilepton/Core/DileptonSV.h | 10 ++--- PWGEM/Dilepton/Utils/EventMixingHandler.h | 44 ++++++++++++++++----- PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h | 14 +++---- PWGEM/PhotonMeson/Core/TaggingPi0.h | 10 ++--- PWGEM/PhotonMeson/Tasks/photonhbt.cxx | 12 +++--- 7 files changed, 82 insertions(+), 51 deletions(-) diff --git a/PWGEM/Dilepton/Core/Dilepton.h b/PWGEM/Dilepton/Core/Dilepton.h index a63c927c422..738634eeb3f 100644 --- a/PWGEM/Dilepton/Core/Dilepton.h +++ b/PWGEM/Dilepton/Core/Dilepton.h @@ -1534,11 +1534,11 @@ struct Dilepton { std::pair key_df_collision = std::make_pair(ndf, collision.globalIndex()); // this gives the current event. // make a vector of selected photons in this collision. - auto selected_posTracks_in_this_event = emh_pos->GetTracksPerCollision(key_df_collision); - auto selected_negTracks_in_this_event = emh_neg->GetTracksPerCollision(key_df_collision); + const auto& selected_posTracks_in_this_event = emh_pos->GetTracksPerCollision(key_df_collision); + const auto& selected_negTracks_in_this_event = emh_neg->GetTracksPerCollision(key_df_collision); // LOGF(info, "N selected tracks in current event (%d, %d), zvtx = %f, centrality = %f , npos = %d , nneg = %d, nuls = %d , nlspp = %d, nlsmm = %d", ndf, collision.globalIndex(), collision.posZ(), centralities[cfgCentEstimator], selected_posTracks_in_this_event.size(), selected_negTracks_in_this_event.size(), nuls, nlspp, nlsmm); - auto collisionIds_in_mixing_pool = emh_pos->GetCollisionIdsFromEventPool(key_bin); // pos/neg does not matter. + const auto& collisionIds_in_mixing_pool = emh_pos->GetCollisionIdsFromEventPool(key_bin); // pos/neg does not matter. // LOGF(info, "collisionIds_in_mixing_pool.size() = %d", collisionIds_in_mixing_pool.size()); for (const auto& mix_dfId_collisionId : collisionIds_in_mixing_pool) { @@ -1555,8 +1555,8 @@ struct Dilepton { continue; } - auto posTracks_from_event_pool = emh_pos->GetTracksPerCollision(mix_dfId_collisionId); - auto negTracks_from_event_pool = emh_neg->GetTracksPerCollision(mix_dfId_collisionId); + const auto& posTracks_from_event_pool = emh_pos->GetTracksPerCollision(mix_dfId_collisionId); + const auto& negTracks_from_event_pool = emh_neg->GetTracksPerCollision(mix_dfId_collisionId); // LOGF(info, "Do event mixing: current event (%d, %d) | event pool (%d, %d), npos = %d , nneg = %d", ndf, collision.globalIndex(), mix_dfId, mix_collisionId, posTracks_from_event_pool.size(), negTracks_from_event_pool.size()); for (const auto& pos : selected_posTracks_in_this_event) { // ULS mix @@ -1586,8 +1586,15 @@ struct Dilepton { if (nuls > 0 || nlspp > 0 || nlsmm > 0) { map_mixed_eventId_to_globalBC[key_df_collision] = collision.globalBC(); - emh_pos->AddCollisionIdAtLast(key_bin, key_df_collision); - emh_neg->AddCollisionIdAtLast(key_bin, key_df_collision); + const auto evicted_pos = emh_pos->AddCollisionIdAtLast(key_bin, key_df_collision); + const auto evicted_neg = emh_neg->AddCollisionIdAtLast(key_bin, key_df_collision); + if (evicted_pos != evicted_neg) { + LOGF(fatal, "Positive and negative mixing pools are out of sync"); + } + if (evicted_pos) { + map_mixed_eventId_to_globalBC.erase(*evicted_pos); + } + } // end of if pair exist } // end of collision loop diff --git a/PWGEM/Dilepton/Core/DileptonHadronMPC.h b/PWGEM/Dilepton/Core/DileptonHadronMPC.h index 38b45983fb5..0825c1d2f40 100644 --- a/PWGEM/Dilepton/Core/DileptonHadronMPC.h +++ b/PWGEM/Dilepton/Core/DileptonHadronMPC.h @@ -1178,10 +1178,10 @@ struct DileptonHadronMPC { std::tuple key_bin = std::make_tuple(zbin, centbin, epbin, occbin); // make a vector of selected electrons in this collision. - auto selected_posTracks_in_this_event = emh_pos->GetTracksPerCollision(key_df_collision); - auto selected_negTracks_in_this_event = emh_neg->GetTracksPerCollision(key_df_collision); + const auto& selected_posTracks_in_this_event = emh_pos->GetTracksPerCollision(key_df_collision); + const auto& selected_negTracks_in_this_event = emh_neg->GetTracksPerCollision(key_df_collision); - auto collisionIds_in_mixing_pool = emh_pos->GetCollisionIdsFromEventPool(key_bin); // pos/neg does not matter. + const auto& collisionIds_in_mixing_pool = emh_pos->GetCollisionIdsFromEventPool(key_bin); // pos/neg does not matter. // LOGF(info, "selected_posTracks_in_this_event.size() = %d, selected_negTracks_in_this_event.size() = %d, collisionIds_in_mixing_pool.size() = %d", selected_posTracks_in_this_event.size(), selected_negTracks_in_this_event.size(), collisionIds_in_mixing_pool.size()); @@ -1201,8 +1201,8 @@ struct DileptonHadronMPC { continue; } - auto posTracks_from_event_pool = emh_pos->GetTracksPerCollision(mix_dfId_collisionId); - auto negTracks_from_event_pool = emh_neg->GetTracksPerCollision(mix_dfId_collisionId); + const auto& posTracks_from_event_pool = emh_pos->GetTracksPerCollision(mix_dfId_collisionId); + const auto& negTracks_from_event_pool = emh_neg->GetTracksPerCollision(mix_dfId_collisionId); // LOGF(info, "posTracks_from_event_pool.size() = %d, negTracks_from_event_pool.size() = %d", posTracks_from_event_pool.size(), negTracks_from_event_pool.size()); for (const auto& pos : selected_posTracks_in_this_event) { // ULS mix @@ -1233,8 +1233,8 @@ struct DileptonHadronMPC { } // end of loop over mixed event pool for lepton-lepton if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kAzimuthalCorrelation)) { - auto selected_refTracks_in_this_event = emh_ref->GetTracksPerCollision(key_df_collision); - auto collisionIds_in_mixing_pool_hadron = emh_ref->GetCollisionIdsFromEventPool(key_bin); + const auto& selected_refTracks_in_this_event = emh_ref->GetTracksPerCollision(key_df_collision); + const auto& collisionIds_in_mixing_pool_hadron = emh_ref->GetCollisionIdsFromEventPool(key_bin); // for ULS and hadron mix for (const auto& pos : selected_posTracks_in_this_event) { @@ -1253,7 +1253,7 @@ struct DileptonHadronMPC { continue; } - auto refTracks_from_event_pool = emh_ref->GetTracksPerCollision(mix_dfId_collisionId); + const auto& refTracks_from_event_pool = emh_ref->GetTracksPerCollision(mix_dfId_collisionId); for (const auto& ref : refTracks_from_event_pool) { fillDileptonHadron<1>(pos, neg, cut, ref); } @@ -1283,7 +1283,7 @@ struct DileptonHadronMPC { continue; } - auto refTracks_from_event_pool = emh_ref->GetTracksPerCollision(mix_dfId_collisionId); + const auto& refTracks_from_event_pool = emh_ref->GetTracksPerCollision(mix_dfId_collisionId); for (const auto& ref : refTracks_from_event_pool) { fillDileptonHadron<1>(pos1, pos2, cut, ref); } @@ -1311,7 +1311,7 @@ struct DileptonHadronMPC { continue; } - auto refTracks_from_event_pool = emh_ref->GetTracksPerCollision(mix_dfId_collisionId); + const auto& refTracks_from_event_pool = emh_ref->GetTracksPerCollision(mix_dfId_collisionId); for (const auto& ref : refTracks_from_event_pool) { fillDileptonHadron<1>(neg1, neg2, cut, ref); } @@ -1335,7 +1335,7 @@ struct DileptonHadronMPC { continue; } - auto refTracks_from_event_pool = emh_ref->GetTracksPerCollision(mix_dfId_collisionId); + const auto& refTracks_from_event_pool = emh_ref->GetTracksPerCollision(mix_dfId_collisionId); // LOGF(info, "selected_refTracks_in_this_event.size() = %d, collisionIds_in_mixing_pool_hadron.size() = %d, refTracks_from_event_pool.size() = %d", selected_refTracks_in_this_event.size(), collisionIds_in_mixing_pool_hadron.size(), refTracks_from_event_pool.size()); for (const auto& ref1 : selected_refTracks_in_this_event) { // ref-ref mix for (const auto& ref2 : refTracks_from_event_pool) { diff --git a/PWGEM/Dilepton/Core/DileptonSV.h b/PWGEM/Dilepton/Core/DileptonSV.h index d59725ef917..fb8232e344f 100644 --- a/PWGEM/Dilepton/Core/DileptonSV.h +++ b/PWGEM/Dilepton/Core/DileptonSV.h @@ -1695,11 +1695,11 @@ struct DileptonSV { std::pair key_df_collision = std::make_pair(ndf, collision.globalIndex()); // this gives the current event. // make a vector of selected photons in this collision. - auto selected_posTracks_in_this_event = emh_pos->GetTracksPerCollision(key_df_collision); - auto selected_negTracks_in_this_event = emh_neg->GetTracksPerCollision(key_df_collision); + const auto& selected_posTracks_in_this_event = emh_pos->GetTracksPerCollision(key_df_collision); + const auto& selected_negTracks_in_this_event = emh_neg->GetTracksPerCollision(key_df_collision); // LOGF(info, "N selected tracks in current event (%d, %d), zvtx = %f, centrality = %f , npos = %d , nneg = %d, nuls = %d , nlspp = %d, nlsmm = %d", ndf, collision.globalIndex(), collision.posZ(), centralities[cfgCentEstimator], selected_posTracks_in_this_event.size(), selected_negTracks_in_this_event.size(), nuls, nlspp, nlsmm); - auto collisionIds_in_mixing_pool = emh_pos->GetCollisionIdsFromEventPool(key_bin); // pos/neg does not matter. + const auto& collisionIds_in_mixing_pool = emh_pos->GetCollisionIdsFromEventPool(key_bin); // pos/neg does not matter. // LOGF(info, "collisionIds_in_mixing_pool.size() = %d", collisionIds_in_mixing_pool.size()); for (const auto& mix_dfId_collisionId : collisionIds_in_mixing_pool) { @@ -1717,8 +1717,8 @@ struct DileptonSV { } fRegistry.fill(HIST("Event/hsMixCounter"), collision.posZ(), centrality, ep2, occupancy); - auto posTracks_from_event_pool = emh_pos->GetTracksPerCollision(mix_dfId_collisionId); - auto negTracks_from_event_pool = emh_neg->GetTracksPerCollision(mix_dfId_collisionId); + const auto& posTracks_from_event_pool = emh_pos->GetTracksPerCollision(mix_dfId_collisionId); + const auto& negTracks_from_event_pool = emh_neg->GetTracksPerCollision(mix_dfId_collisionId); // LOGF(info, "Do event mixing: current event (%d, %d) | event pool (%d, %d), npos = %d , nneg = %d", ndf, collision.globalIndex(), mix_dfId, mix_collisionId, posTracks_from_event_pool.size(), negTracks_from_event_pool.size()); for (const auto& pos : selected_posTracks_in_this_event) { // ULS mix diff --git a/PWGEM/Dilepton/Utils/EventMixingHandler.h b/PWGEM/Dilepton/Utils/EventMixingHandler.h index 4698654be49..1c69210490f 100644 --- a/PWGEM/Dilepton/Utils/EventMixingHandler.h +++ b/PWGEM/Dilepton/Utils/EventMixingHandler.h @@ -16,6 +16,8 @@ #define PWGEM_DILEPTON_UTILS_EVENTMIXINGHANDLER_H_ #include +#include +#include #include namespace o2::aod::pwgem::dilepton::utils @@ -36,6 +38,9 @@ class EventMixingHandler fNdepth = ndepth; fMapMixBins.clear(); fMap_Tracks_per_collision.clear(); + if (fNdepth <= 0) { + throw std::invalid_argument("mixing depth must be positive"); + } } ~EventMixingHandler() @@ -44,7 +49,13 @@ class EventMixingHandler fMap_Tracks_per_collision.clear(); } - void SetNdepth(int ndepth) { fNdepth = ndepth; } + void SetNdepth(int ndepth) + { + if (ndepth <= 0) { + throw std::invalid_argument("mixing depth must be positive"); + } + fNdepth = ndepth; + } void ReserveNTracksPerCollision(U key_df_collision, int ntrack) { @@ -56,20 +67,33 @@ class EventMixingHandler fMap_Tracks_per_collision[key_df_collision].emplace_back(obj); } - std::vector GetCollisionIdsFromEventPool(T key_bin) { return fMapMixBins[key_bin]; } - std::vector GetTracksPerCollision(T key_bin, int index) { return fMap_Tracks_per_collision[fMapMixBins[key_bin][index]]; } - std::vector GetTracksPerCollision(U key_df_collision) { return fMap_Tracks_per_collision[key_df_collision]; } + const std::vector& GetCollisionIdsFromEventPool(const T& key_bin) const + { + const auto it = fMapMixBins.find(key_bin); + static const std::vector empty; + return it == fMapMixBins.end() ? empty : it->second; + } + + const std::vector& GetTracksPerCollision(const U& key) const + { + const auto it = fMap_Tracks_per_collision.find(key); + static const std::vector empty; + return it == fMap_Tracks_per_collision.end() ? empty : it->second; + } // call this function at the end of collision loop - void AddCollisionIdAtLast(T key_bin, U key_df_collision) + std::optional AddCollisionIdAtLast(T key_bin, U key_df_collision) { // LOGF(info, "fMapMixBins[key_bin].size() = %d", fMapMixBins[key_bin].size()); - if (static_cast(fMapMixBins[key_bin].size()) >= fNdepth) { - fMap_Tracks_per_collision[fMapMixBins[key_bin][0]].clear(); - fMap_Tracks_per_collision[fMapMixBins[key_bin][0]].shrink_to_fit(); - fMapMixBins[key_bin].erase(fMapMixBins[key_bin].begin()); + auto& ids = fMapMixBins[key_bin]; + std::optional evicted; + if (static_cast(ids.size()) >= fNdepth) { + evicted = ids.front(); + fMap_Tracks_per_collision.erase(*evicted); + ids.erase(ids.begin()); } - fMapMixBins[key_bin].emplace_back(key_df_collision); + ids.emplace_back(key_df_collision); + return evicted; } private: diff --git a/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h b/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h index 9b35b491e03..91818c3f3d2 100644 --- a/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h +++ b/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h @@ -1007,11 +1007,11 @@ struct Pi0EtaToGammaGamma { } // make a vector of selected photons in this collision. - auto selected_photons1_in_this_event = emh1->GetTracksPerCollision(key_df_collision); - auto selected_photons2_in_this_event = emh2->GetTracksPerCollision(key_df_collision); + const auto& selected_photons1_in_this_event = emh1->GetTracksPerCollision(key_df_collision); + const auto& selected_photons2_in_this_event = emh2->GetTracksPerCollision(key_df_collision); - auto collisionIds1_in_mixing_pool = emh1->GetCollisionIdsFromEventPool(key_bin); - auto collisionIds2_in_mixing_pool = emh2->GetCollisionIdsFromEventPool(key_bin); + const auto& collisionIds1_in_mixing_pool = emh1->GetCollisionIdsFromEventPool(key_bin); + const auto& collisionIds2_in_mixing_pool = emh2->GetCollisionIdsFromEventPool(key_bin); if constexpr (pairtype == o2::aod::pwgem::photonmeson::photonpair::PairType::kPCMPCM || pairtype == o2::aod::pwgem::photonmeson::photonpair::PairType::kPHOSPHOS || pairtype == o2::aod::pwgem::photonmeson::photonpair::PairType::kEMCEMC) { // same kinds pairing for (const auto& mix_dfId_collisionId : collisionIds1_in_mixing_pool) { @@ -1029,7 +1029,7 @@ struct Pi0EtaToGammaGamma { continue; } - auto photons1_from_event_pool = emh1->GetTracksPerCollision(mix_dfId_collisionId); + const auto& photons1_from_event_pool = emh1->GetTracksPerCollision(mix_dfId_collisionId); // LOGF(info, "Do event mixing: current event (%d, %d), ngamma = %d | event pool (%d, %d), ngamma = %d", ndf, collision.globalIndex(), selected_photons1_in_this_event.size(), mix_dfId, mix_collisionId, photons1_from_event_pool.size()); for (const auto& g1 : selected_photons1_in_this_event) { @@ -1093,7 +1093,7 @@ struct Pi0EtaToGammaGamma { continue; } - auto photons2_from_event_pool = emh2->GetTracksPerCollision(mix_dfId_collisionId); + const auto& photons2_from_event_pool = emh2->GetTracksPerCollision(mix_dfId_collisionId); // LOGF(info, "Do event mixing: current event (%d, %d), ngamma = %d | event pool (%d, %d), nll = %d", ndf, collision.globalIndex(), selected_photons1_in_this_event.size(), mix_dfId, mix_collisionId, photons2_from_event_pool.size()); for (const auto& g1 : selected_photons1_in_this_event) { @@ -1130,7 +1130,7 @@ struct Pi0EtaToGammaGamma { continue; } - auto photons1_from_event_pool = emh1->GetTracksPerCollision(mix_dfId_collisionId); + const auto& photons1_from_event_pool = emh1->GetTracksPerCollision(mix_dfId_collisionId); // LOGF(info, "Do event mixing: current event (%d, %d), nll = %d | event pool (%d, %d), ngamma = %d", ndf, collision.globalIndex(), selected_photons2_in_this_event.size(), mix_dfId, mix_collisionId, photons1_from_event_pool.size()); for (const auto& g1 : selected_photons2_in_this_event) { diff --git a/PWGEM/PhotonMeson/Core/TaggingPi0.h b/PWGEM/PhotonMeson/Core/TaggingPi0.h index e81d5e3ba9c..64080cd2a2d 100644 --- a/PWGEM/PhotonMeson/Core/TaggingPi0.h +++ b/PWGEM/PhotonMeson/Core/TaggingPi0.h @@ -599,11 +599,11 @@ struct TaggingPi0 { } // make a vector of selected photons in this collision. - auto selected_photons1_in_this_event = emh1->GetTracksPerCollision(key_df_collision); - // auto selected_photons2_in_this_event = emh2->GetTracksPerCollision(key_df_collision); + const auto& selected_photons1_in_this_event = emh1->GetTracksPerCollision(key_df_collision); + // const auto& selected_photons2_in_this_event = emh2->GetTracksPerCollision(key_df_collision); - // auto collisionIds1_in_mixing_pool = emh1->GetCollisionIdsFromEventPool(key_bin); - auto collisionIds2_in_mixing_pool = emh2->GetCollisionIdsFromEventPool(key_bin); + // const auto& collisionIds1_in_mixing_pool = emh1->GetCollisionIdsFromEventPool(key_bin); + const auto& collisionIds2_in_mixing_pool = emh2->GetCollisionIdsFromEventPool(key_bin); for (const auto& mix_dfId_collisionId : collisionIds2_in_mixing_pool) { int mix_dfId = mix_dfId_collisionId.first; @@ -620,7 +620,7 @@ struct TaggingPi0 { continue; } - auto photons2_from_event_pool = emh2->GetTracksPerCollision(mix_dfId_collisionId); + const auto& photons2_from_event_pool = emh2->GetTracksPerCollision(mix_dfId_collisionId); // LOGF(info, "Do event mixing: current event (%d, %d), ngamma = %d | event pool (%d, %d), nll = %d", ndf, collision.globalIndex(), selected_photons1_in_this_event.size(), mix_dfId, mix_collisionId, photons2_from_event_pool.size()); for (const auto& g1 : selected_photons1_in_this_event) { // [photon from event1, dilepton from event2] diff --git a/PWGEM/PhotonMeson/Tasks/photonhbt.cxx b/PWGEM/PhotonMeson/Tasks/photonhbt.cxx index 1bbaab29506..23cb1db4a70 100644 --- a/PWGEM/PhotonMeson/Tasks/photonhbt.cxx +++ b/PWGEM/PhotonMeson/Tasks/photonhbt.cxx @@ -2782,8 +2782,8 @@ struct Photonhbt { if (!mixing.cfgDoMix || ndiphoton == 0) { continue; } - auto selectedPhotons = emh1->GetTracksPerCollision(keyDFCollision); - auto poolIDs = emh1->GetCollisionIdsFromEventPool(keyBin); + const auto& selectedPhotons = emh1->GetTracksPerCollision(keyDFCollision); + const auto& poolIDs = emh1->GetCollisionIdsFromEventPool(keyBin); for (const auto& mixID : poolIDs) { if (mixID.second == collision.globalIndex() && mixID.first == ndf) { continue; @@ -2794,7 +2794,7 @@ struct Photonhbt { if (diffBC < mixing.ndiffBCMix) { continue; } - auto poolPhotons = emh1->GetTracksPerCollision(mixID); + const auto& poolPhotons = emh1->GetTracksPerCollision(mixID); for (const auto& g1 : selectedPhotons) { for (const auto& g2 : poolPhotons) { if (!passAsymmetryCut(g1.pt(), g2.pt())) { @@ -3102,8 +3102,8 @@ struct Photonhbt { if (!mixing.cfgDoMix || ndiphoton == 0) { continue; } - auto selectedPhotons = emh1->GetTracksPerCollision(keyDFCollision); - auto poolIDs = emh1->GetCollisionIdsFromEventPool(keyBin); + const auto& selectedPhotons = emh1->GetTracksPerCollision(keyDFCollision); + const auto& poolIDs = emh1->GetCollisionIdsFromEventPool(keyBin); for (const auto& mixID : poolIDs) { if (mixID.second == collision.globalIndex() && mixID.first == ndf) { continue; @@ -3114,7 +3114,7 @@ struct Photonhbt { if (diffBC < mixing.ndiffBCMix) { continue; } - auto poolPhotons = emh1->GetTracksPerCollision(mixID); + const auto& poolPhotons = emh1->GetTracksPerCollision(mixID); for (const auto& g1 : selectedPhotons) { for (const auto& g2 : poolPhotons) { if (!passAsymmetryCut(g1.pt(), g2.pt())) {