From 43f229d466078371c67ec37e8d2d56562b77aa01 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Thu, 21 May 2026 11:36:14 +0200 Subject: [PATCH] [PWGDQ] improve matching QA table filling and muon tagging Instead of using an hard-coded list of matching methods and corresponding indexes when filling the derived tables, the filling is done using a dynamic list of methods and correspoding indexes that is based on what is actually requested in the configuration. The horizontal bin labels of a dedicated TH1 histogram provide the correspondance between method labels and their indexes, to be used when reading back the derived tables to generate final histograms. An "isTagged" column is also added to the derived MCH table to flag the tracks that have good quality and cross the active area of the MFT, and therefore are expected to have a matchable MFT track. The tagging does not rely on MC truth, and can therefore be also applied to real data. --- PWGDQ/Tasks/qaMatching.cxx | 248 +++++++++++++++---------------------- 1 file changed, 99 insertions(+), 149 deletions(-) diff --git a/PWGDQ/Tasks/qaMatching.cxx b/PWGDQ/Tasks/qaMatching.cxx index 4ca6f69ecd4..6f2056d9c24 100644 --- a/PWGDQ/Tasks/qaMatching.cxx +++ b/PWGDQ/Tasks/qaMatching.cxx @@ -100,6 +100,7 @@ DECLARE_SOA_COLUMN(MatchRanking, matchRanking, int32_t); DECLARE_SOA_COLUMN(MftMultiplicity, mftMultiplicity, int32_t); DECLARE_SOA_COLUMN(TrackType, trackType, int8_t); DECLARE_SOA_COLUMN(MftMatchAttempts, mftMatchAttempts, int32_t); +DECLARE_SOA_COLUMN(IsTagged, isTagged, bool); DECLARE_SOA_COLUMN(XAtVtx, xAtVtx, float); DECLARE_SOA_COLUMN(YAtVtx, yAtVtx, float); DECLARE_SOA_COLUMN(ZAtVtx, zAtVtx, float); @@ -138,6 +139,7 @@ DECLARE_SOA_TABLE(QaMatchingMCHTrack, "AOD", "QAMCHTRK", qamatching::Eta, qamatching::Phi, qamatching::MftMatchAttempts, + qamatching::IsTagged, qamatching::XAtVtx, qamatching::YAtVtx, qamatching::ZAtVtx, @@ -261,6 +263,10 @@ struct QaMatching { Configurable cfgMuonTaggingRabsLow{"cfgMuonTaggingRabsLow", 17.6f, ""}; Configurable cfgMuonTaggingRabsUp{"cfgMuonTaggingRabsUp", 89.5f, ""}; Configurable cfgMuonTaggingPdcaUp{"cfgMuonTaggingPdcaUp", 4.f, ""}; + Configurable cfgMuonTaggingRadiusAtMftFrontLow{"cfgMuonTaggingRadiusAtMftFrontLow", 3.f, ""}; + Configurable cfgMuonTaggingRadiusAtMftFrontUp{"cfgMuonTaggingRadiusAtMftFrontUp", 9.f, ""}; + Configurable cfgMuonTaggingRadiusAtMftBackLow{"cfgMuonTaggingRadiusAtMftBackLow", 5.f, ""}; + Configurable cfgMuonTaggingRadiusAtMftBackUp{"cfgMuonTaggingRadiusAtMftBackUp", 12.f, ""}; Configurable cfgMuonTaggingChi2DiffLow{"cfgMuonTaggingChi2DiffLow", 100.f, ""}; //// Variables for ccdb @@ -422,6 +428,8 @@ struct QaMatching { struct CollisionInfo { int64_t index{0}; + // internal index of this collision in the derived table + int64_t reducedEventId{0}; uint64_t bc{0}; // z position of the collision double zVertex{0}; @@ -778,7 +786,7 @@ struct QaMatching { AxisSpec chi2Axis = {100, 0, 100, "matching #chi^{2}/NDF"}; AxisSpec scoreAxis = {100, 0, 1, "matching score"}; int matchTypeMax = static_cast(kMatchTypeUndefined) + 1; - AxisSpec matchTypeAxis = {matchTypeMax, 0, static_cast(matchTypeMax), "match type"}; + AxisSpec matchTypeAxis = {matchTypeMax, 0, static_cast(matchTypeMax), ""}; histName = path + "matchType"; histTitle = "Match type"; fMatchType = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {matchTypeAxis}}); @@ -911,7 +919,6 @@ struct QaMatching { std::map> fMatchingHistogramRegistries; std::map> fMatchingPlotters; std::unique_ptr fTaggedMuonsMatchingPlotter; - std::unique_ptr fSelectedMuonsMatchingPlotter; CollisionInfos fCollisionInfos; @@ -971,7 +978,6 @@ struct QaMatching { } fTaggedMuonsMatchingPlotter = std::make_unique(histPath + "Tagged/", ®istryMatching, configQas.cfgCreatePdgMomHistograms, cfgMftTrackMultiplicityMax, cfgNCandidatesMax); - fSelectedMuonsMatchingPlotter = std::make_unique(histPath + "Selected/", ®istryMatching, configQas.cfgCreatePdgMomHistograms, cfgMftTrackMultiplicityMax, cfgNCandidatesMax); } void createDimuonHistos() @@ -1127,6 +1133,8 @@ struct QaMatching { ccdbManager->get(geoPath); } + std::vector matchMethodLabels{"Prod"}; + // Matching functions initMatchingFunctions(); for (size_t funcId = 0; funcId < Chi2FunctionsNum; funcId++) { @@ -1137,13 +1145,15 @@ struct QaMatching { auto extrapMethod = configChi2MatchingOptions.matchingExtrapMethods[funcId]->value; if (label == "" || funcName == "") - break; + continue; matchingChi2Functions[label] = funcName; matchingScoreCuts[label] = scoreMin; matchingPlanesZ[label] = matchingPlaneZ; matchingExtrapMethod[label] = extrapMethod; + + matchMethodLabels.push_back(label); } // Matching ML models @@ -1163,7 +1173,7 @@ struct QaMatching { auto extrapMethod = configMlOptions.matchingExtrapMethods[modelId]->value; if (label == "" || modelPath == "" || inputFeatures.empty() || modelName == "") - break; + continue; matchingMlResponses[label].configure(binsPtMl, mycutsMl, cutDirMl, 1); matchingMlResponses[label].setModelPathsCCDB(std::vector{modelName}, fCCDBApi, std::vector{modelPath}, configCcdb.cfgCcdbNoLaterThan.value); @@ -1173,6 +1183,8 @@ struct QaMatching { matchingScoreCuts[label] = scoreMin; matchingPlanesZ[label] = matchingPlaneZ; matchingExtrapMethod[label] = extrapMethod; + + matchMethodLabels.push_back(label); } int nTrackTypes = static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::MCHStandaloneTrack) + 1; @@ -1183,6 +1195,14 @@ struct QaMatching { registry.add("tracksMultiplicityMFT", "MFT tracks multiplicity", {HistType::kTH1F, {tracksMultiplicityAxis}}); registry.add("tracksMultiplicityMCH", "MCH tracks multiplicity", {HistType::kTH1F, {tracksMultiplicityAxis}}); + // Histogram for storing the index and label of the matching methods in the horizontal axis. + // This is needed in order to associate the proper label to the match method index in the derived tables. + AxisSpec matchMethodAxis = {static_cast(matchMethodLabels.size()), 0.0, static_cast(matchMethodLabels.size()), ""}; + auto matchMethodsHist = registry.add("matchMethods", "Match methods", {HistType::kTH1F, {matchMethodAxis}}); + for (size_t iLabel = 0; iLabel < matchMethodLabels.size(); iLabel++) { + std::get>(matchMethodsHist)->GetXaxis()->SetBinLabel(iLabel + 1, matchMethodLabels[iLabel].c_str()); + } + createMatchingHistosMc(); createDimuonHistos(); } @@ -1726,7 +1746,7 @@ struct QaMatching { } template - bool IsMuon(const TMCH& mchTrack, + bool isMuon(const TMCH& mchTrack, const TMFT& mftTrack) { // skip tracks that do not have an associated MC particle @@ -1748,7 +1768,7 @@ struct QaMatching { } template - bool IsMuon(const TMUON& muonTrack, + bool isMuon(const TMUON& muonTrack, TMUONS const& /*muonTracks*/, TMFTS const& /*mftTracks*/) { @@ -1758,7 +1778,7 @@ struct QaMatching { auto const& mchTrack = muonTrack.template matchMCHTrack_as(); auto const& mftTrack = muonTrack.template matchMFTTrack_as(); - return IsMuon(mchTrack, mftTrack); + return isMuon(mchTrack, mftTrack); } template @@ -1793,14 +1813,14 @@ struct QaMatching { return result; } - // for each MCH standalone track, collect the associated matching candidates + // tag muons based on the track quality and the track position at the front and back MFT planes template - void getSelectedMuons(const CollisionInfo& collisionInfo, - C const& collisions, - TMUON const& muonTracks, - std::vector& selectedMuons) + void getTaggedMuons(const CollisionInfo& collisionInfo, + C const& collisions, + TMUON const& muonTracks, + std::vector& taggedMuons) { - selectedMuons.clear(); + taggedMuons.clear(); for (const auto& muonTrack : muonTracks) { // only consider MCH-MID matches @@ -1833,52 +1853,17 @@ struct QaMatching { // propagate the track from the vertex to the first MFT plane const auto& extrapToMFTfirst = propagateToZMch(mchTrackAtVertex, o2::mft::constants::mft::LayerZCoordinate()[0]); double rFront = std::sqrt(extrapToMFTfirst.getX() * extrapToMFTfirst.getX() + extrapToMFTfirst.getY() * extrapToMFTfirst.getY()); - double rMinFront = 3.f; - double rMaxFront = 9.f; - if (rFront < rMinFront || rFront > rMaxFront) + if (rFront < cfgMuonTaggingRadiusAtMftFrontLow.value || rFront > cfgMuonTaggingRadiusAtMftFrontUp.value) continue; // propagate the track from the vertex to the last MFT plane const auto& extrapToMFTlast = propagateToZMch(mchTrackAtVertex, o2::mft::constants::mft::LayerZCoordinate()[9]); double rBack = std::sqrt(extrapToMFTlast.getX() * extrapToMFTlast.getX() + extrapToMFTlast.getY() * extrapToMFTlast.getY()); - double rMinBack = 5.f; - double rMaxBack = 12.f; - if (rBack < rMinBack || rBack > rMaxBack) + if (rBack < cfgMuonTaggingRadiusAtMftBackLow.value || rBack > cfgMuonTaggingRadiusAtMftBackUp.value) continue; int64_t muonTrackIndex = muonTrack.globalIndex(); - selectedMuons.emplace_back(muonTrackIndex); - } - } - - // for each MCH standalone track, collect the associated matching candidates - template - void getTaggedMuons(const CollisionInfo& collisionInfo, - TMUON const& muonTracks, - const std::vector& selectedMuons, - std::vector& taggedMuons) - { - taggedMuons.clear(); - for (const auto& [mchIndex, globalTracksVector] : collisionInfo.matchingCandidates) { - - // check if the current muon is selected - if (std::find(selectedMuons.begin(), selectedMuons.end(), mchIndex) == selectedMuons.end()) - continue; - - // if there is only one candidate, mark the muon as select - if (globalTracksVector.size() == 1) { - taggedMuons.emplace_back(mchIndex); - continue; - } - - auto const& muonTrack0 = muonTracks.rawIteratorAt(globalTracksVector[0].globalTrackId); - auto const& muonTrack1 = muonTracks.rawIteratorAt(globalTracksVector[1].globalTrackId); - - double chi2diff = muonTrack1.chi2MatchMCHMFT() - muonTrack0.chi2MatchMCHMFT(); - if (chi2diff < cfgMuonTaggingChi2DiffLow) - continue; - - taggedMuons.emplace_back(mchIndex); + taggedMuons.emplace_back(muonTrackIndex); } } @@ -2103,18 +2088,18 @@ struct QaMatching { return (track1.matchChi2 < track2.matchChi2); }; - for (auto collisionInfoIt = collisionInfos.begin(); collisionInfoIt != collisionInfos.end(); ++collisionInfoIt) { - auto& collisionInfo = collisionInfoIt->second; - for (auto matchingCandidatesIt = collisionInfo.matchingCandidates.begin(); matchingCandidatesIt != collisionInfo.matchingCandidates.end(); ++matchingCandidatesIt) { - auto& mchIndex = matchingCandidatesIt->first; - auto& globalTracksVector = matchingCandidatesIt->second; + int64_t reducedEventCounter{0}; + for (auto& [collisionIndex, collisionInfo] : collisionInfos) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) + // set the internal collision index + collisionInfo.reducedEventId = reducedEventCounter; + reducedEventCounter += 1; + for (auto& [mchIndex, globalTracksVector] : collisionInfo.matchingCandidates) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) std::sort(globalTracksVector.begin(), globalTracksVector.end(), compareMatchingChi2); const auto& mchTrack = muonTracks.rawIteratorAt(mchIndex); auto mftMchMatchAttempts = getMftMchMatchAttempts(collisions, bcs, mchTrack, mftTracks); int ranking = 1; - for (auto candidateIt = globalTracksVector.begin(); candidateIt != globalTracksVector.end(); ++candidateIt) { - auto& candidate = *candidateIt; + for (auto& candidate : globalTracksVector) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); candidate.matchRanking = ranking; @@ -2635,16 +2620,13 @@ struct QaMatching { return (track1.matchChi2 < track2.matchChi2); }; - for (auto matchingCandidatesIt = newMatchingCandidates.begin(); matchingCandidatesIt != newMatchingCandidates.end(); ++matchingCandidatesIt) { - auto& mchIndex = matchingCandidatesIt->first; - auto& globalTracksVector = matchingCandidatesIt->second; + for (auto& [mchIndex, globalTracksVector] : newMatchingCandidates) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) std::sort(globalTracksVector.begin(), globalTracksVector.end(), compareMatchingChi2); const auto& mchTrack = muonTracks.rawIteratorAt(mchIndex); auto mftMchMatchAttempts = getMftMchMatchAttempts(collisions, bcs, mchTrack, mftTracks); int ranking = 1; - for (auto candidateIt = globalTracksVector.begin(); candidateIt != globalTracksVector.end(); ++candidateIt) { - auto& candidate = *candidateIt; + for (auto& candidate : globalTracksVector) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); candidate.matchRanking = ranking; @@ -2783,16 +2765,13 @@ struct QaMatching { return (track1.matchScore > track2.matchScore); }; - for (auto matchingCandidatesIt = newMatchingCandidates.begin(); matchingCandidatesIt != newMatchingCandidates.end(); ++matchingCandidatesIt) { - auto& mchIndex = matchingCandidatesIt->first; - auto& globalTracksVector = matchingCandidatesIt->second; + for (auto& [mchIndex, globalTracksVector] : newMatchingCandidates) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) std::sort(globalTracksVector.begin(), globalTracksVector.end(), compareMatchingScore); const auto& mchTrack = muonTracks.rawIteratorAt(mchIndex); auto mftMchMatchAttempts = getMftMchMatchAttempts(collisions, bcs, mchTrack, mftTracks); int ranking = 1; - for (auto candidateIt = globalTracksVector.begin(); candidateIt != globalTracksVector.end(); ++candidateIt) { - auto& candidate = *candidateIt; + for (auto& candidate : globalTracksVector) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); candidate.matchRanking = ranking; @@ -2813,33 +2792,25 @@ struct QaMatching { { auto collision = collisions.rawIteratorAt(collisionInfo.index); - registry.get(HIST("tracksMultiplicityMFT"))->Fill(collisionInfo.mftTracks.size()); - registry.get(HIST("tracksMultiplicityMCH"))->Fill(collisionInfo.mchTracks.size()); - - // Chi2-based matching analysis - fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, collisionInfo.matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, cfgMatchingChi2ScoreMftMchLow, fChi2MatchingPlotter.get(), false); - for (const auto& [label, func] : matchingChi2Functions) { - MatchingCandidates matchingCandidates; - runChi2Matching(collisions, bcs, muonTracks, mftTracks, mftCovs, label, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates); + std::vector taggedMuons; + getTaggedMuons(collisionInfo, collisions, muonTracks, taggedMuons); - auto* plotter = fMatchingPlotters.at(label).get(); - double matchingScoreCut = matchingScoreCuts.at(label); + int debugCounter{0}; + fillQaMatchingAodEventForCollision(collisionInfo, collision, collisionInfo.reducedEventId, debugCounter); + fillQaMatchingMchTracksForCollision(collisionInfo, collisions, collision, muonTracks, mftTracks, bcs, taggedMuons, collisionInfo.reducedEventId); - fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter, false); - } + registry.get(HIST("tracksMultiplicityMFT"))->Fill(collisionInfo.mftTracks.size()); + registry.get(HIST("tracksMultiplicityMCH"))->Fill(collisionInfo.mchTracks.size()); - // ML-based matching analysis - for (const auto& [label, mlResponse] : matchingMlResponses) { - MatchingCandidates matchingCandidates; - runMlMatching(collisions, bcs, muonTracks, mftTracks, mftCovs, label, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates); + int matchingMethodCounter{0}; - auto* plotter = fMatchingPlotters.at(label).get(); - double matchingScoreCut = matchingScoreCuts.at(label); - - fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter); - } + //------------------------------- + // Chi2-based matching from production + fillQaMatchingAodTablesForCollision(collision, muonTracks, collisionInfo.matchingCandidates, matchingMethodCounter, collisionInfo.reducedEventId); + fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, collisionInfo.matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, cfgMatchingChi2ScoreMftMchLow, fChi2MatchingPlotter.get(), false); - // Muons tagging + //------------------------------- + // Tagged muons for (const auto& [mchIndex, mftIndex] : collisionInfo.matchablePairs) { auto const& mchTrack = muonTracks.rawIteratorAt(mchIndex); if (!mchTrack.has_collision()) @@ -2863,28 +2834,44 @@ struct QaMatching { registry.get(HIST("matching/MC/pairedMFTTracksAtMFT"))->Fill(mftTrackProp.getX(), mftTrackProp.getY()); } - std::vector selectedMuons; - getSelectedMuons(collisionInfo, collisions, muonTracks, selectedMuons); - - MatchingCandidates selectedMatchingCandidates; - for (const auto& [mchIndex, globalTracksVector] : collisionInfo.matchingCandidates) { - if (std::find(selectedMuons.begin(), selectedMuons.end(), mchIndex) != selectedMuons.end()) { - selectedMatchingCandidates[mchIndex] = globalTracksVector; - } - } - fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, selectedMatchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, cfgMatchingChi2ScoreMftMchLow, fSelectedMuonsMatchingPlotter.get()); - - std::vector taggedMuons; - getTaggedMuons(collisionInfo, muonTracks, selectedMuons, taggedMuons); - MatchingCandidates taggedMatchingCandidates; for (const auto& [mchIndex, globalTracksVector] : collisionInfo.matchingCandidates) { if (std::find(taggedMuons.begin(), taggedMuons.end(), mchIndex) != taggedMuons.end()) { taggedMatchingCandidates[mchIndex] = globalTracksVector; } } + matchingMethodCounter += 1; + fillQaMatchingAodTablesForCollision(collision, muonTracks, collisionInfo.matchingCandidates, matchingMethodCounter, collisionInfo.reducedEventId); fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, taggedMatchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, cfgMatchingChi2ScoreMftMchLow, fTaggedMuonsMatchingPlotter.get()); + //------------------------------- + // Custom chi2-based matching methods + for (const auto& [label, func] : matchingChi2Functions) { + MatchingCandidates matchingCandidates; + runChi2Matching(collisions, bcs, muonTracks, mftTracks, mftCovs, label, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates); + + auto* plotter = fMatchingPlotters.at(label).get(); + double matchingScoreCut = matchingScoreCuts.at(label); + + matchingMethodCounter += 1; + fillQaMatchingAodTablesForCollision(collision, muonTracks, matchingCandidates, matchingMethodCounter, collisionInfo.reducedEventId); + fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter, false); + } + + // ML-based matching analysis + for (const auto& [label, mlResponse] : matchingMlResponses) { + MatchingCandidates matchingCandidates; + runMlMatching(collisions, bcs, muonTracks, mftTracks, mftCovs, label, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates); + + auto* plotter = fMatchingPlotters.at(label).get(); + double matchingScoreCut = matchingScoreCuts.at(label); + + matchingMethodCounter += 1; + fillQaMatchingAodTablesForCollision(collision, muonTracks, matchingCandidates, matchingMethodCounter, collisionInfo.reducedEventId); + fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter); + } + + //------------------------------- // Di-muon analysis fillDimuonPlotsMc(collisionInfo, collisions, muonTracks, mftTracks); } @@ -2956,6 +2943,7 @@ struct QaMatching { TMUON const& muonTracks, TMFT const& mftTracks, TBC const& bcs, + const std::vector& taggedMuons, int32_t reducedEventId) { std::vector mchIds; @@ -2975,6 +2963,10 @@ struct QaMatching { auto const& mchTrack = muonTracks.rawIteratorAt(mchIndex); int mftMchMatchAttempts = getMftMchMatchAttempts(collisions, bcs, mchTrack, mftTracks); auto mchTrackAtVertex = VarManager::PropagateMuon(mchTrack, collision, VarManager::kToVertex); + bool isTagged = false; + if (std::find(taggedMuons.begin(), taggedMuons.end(), mchIndex) != taggedMuons.end()) { + isTagged = true; + } qaMatchingMCHTrack( reducedEventId, mchIndex, @@ -2984,6 +2976,7 @@ struct QaMatching { static_cast(mchTrack.eta()), static_cast(mchTrack.phi()), static_cast(mftMchMatchAttempts), + isTagged, static_cast(mchTrackAtVertex.getX()), static_cast(mchTrackAtVertex.getY()), static_cast(mchTrackAtVertex.getZ()), @@ -3007,55 +3000,12 @@ struct QaMatching { registry.get(HIST("nTracksPerType"))->Fill(static_cast(muon.trackType())); } - fillCollisions(collisions, bcs, muonTracks, mftTracks, fCollisionInfos); - mftTrackCovs.clear(); for (const auto& mftTrackCov : mftCovs) { mftTrackCovs[mftTrackCov.matchMFTTrackId()] = mftTrackCov.globalIndex(); } - std::unordered_map reducedEventIds; - int32_t reducedEventCounter = 0; - for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) { - reducedEventIds.emplace(collisionInfo.index, reducedEventCounter); - reducedEventCounter += 1; - } - - int debugCounter = 0; - for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) { - auto it = reducedEventIds.find(collisionInfo.index); - if (it == reducedEventIds.end()) { - continue; - } - int32_t reducedEventId = it->second; - auto collision = collisions.rawIteratorAt(collisionInfo.index); - fillQaMatchingAodEventForCollision(collisionInfo, collision, reducedEventId, debugCounter); - fillQaMatchingMchTracksForCollision(collisionInfo, collisions, collision, muonTracks, mftTracks, bcs, reducedEventId); - } - - struct AodLabel { - const char* name; - int8_t id; - }; - std::array aodLabels{{{"ProdAll", 0}, {"MatchXYPhiTanl", 1}, {"MatchXYPhiTanlMom", 2}}}; - for (const auto& aodLabel : aodLabels) { - if (matchingChi2Functions.find(aodLabel.name) == matchingChi2Functions.end()) { - LOGF(warn, "[AO2D] Chi2 label not found: %s", aodLabel.name); - continue; - } - debugCounter = 0; - for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) { - auto it = reducedEventIds.find(collisionInfo.index); - if (it == reducedEventIds.end()) { - continue; - } - int32_t reducedEventId = it->second; - MatchingCandidates matchingCandidates; - runChi2Matching(collisions, bcs, muonTracks, mftTracks, mftCovs, aodLabel.name, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates); - auto collision = collisions.rawIteratorAt(collisionInfo.index); - fillQaMatchingAodTablesForCollision(collision, muonTracks, matchingCandidates, aodLabel.id, reducedEventId); - } - } + fillCollisions(collisions, bcs, muonTracks, mftTracks, fCollisionInfos); for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) { processCollisionMc(collisionInfo, collisions, bcs, muonTracks, mftTracks, mftCovs);