From 70ba9cf4f572dd15d11492f1133a462c1d17d776 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Fri, 17 Oct 2025 08:37:23 +0200 Subject: [PATCH 1/2] [MUON] process only best matching candidates The MFT-MCH matching task now stores by default multiple matching candidates for each MCH standalone track. In order to properly assess the tracking quality and avoid a large combinatorial background, only the best matching candidate for each MCH track must be processed by the QC tracks task. --- Modules/MUON/Common/src/TrackPlotter.cxx | 35 ++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/Modules/MUON/Common/src/TrackPlotter.cxx b/Modules/MUON/Common/src/TrackPlotter.cxx index 9777d6a0d4..0e74844576 100644 --- a/Modules/MUON/Common/src/TrackPlotter.cxx +++ b/Modules/MUON/Common/src/TrackPlotter.cxx @@ -465,12 +465,41 @@ void TrackPlotter::fillHistograms(const o2::globaltracking::RecoContainer& recoC } if (mSrc == GID::MFTMCH || mSrc == GID::MFTMCHMID) { auto tracksFwd = recoCont.getGlobalFwdTracks(); - for (auto& t : tracksFwd) { - MuonTrack mt(&t, recoCont, mFirstTForbit); + std::map>> matchingCandidates; + // loop over the global forward tracks and collect the matching candidates + for (size_t ti = 0; ti < tracksFwd.size(); ti++) { + auto& t = tracksFwd[ti]; // skip tracks without MID if full matching is requested - if (mSrc == GID::MFTMCHMID && !mt.hasMID()) { + if (mSrc == GID::MFTMCHMID && t.getMIDTrackID() < 0) { continue; } + + // associate the matching candidate to the corresponding MCH standalone track, and store the matching chi2 + int64_t mchTrackIndex = t.getMCHTrackID(); + double matchingChi2 = t.getMFTMCHMatchingChi2(); + auto matchingCandidateIterator = matchingCandidates.find(mchTrackIndex); + if (matchingCandidateIterator != matchingCandidates.end()) { + matchingCandidateIterator->second.push_back(std::make_pair(ti, matchingChi2)); + } else { + matchingCandidates[mchTrackIndex].push_back(std::make_pair(ti, matchingChi2)); + } + } + + // loop over the matching candidate for each standalone MCH track, sort the candidates according to the matching chi2, + // and for each MCH track pick the leading candidate for further processing + for (auto& [mchTrackIndex, matchingCandidatesVector] : matchingCandidates) { + if (matchingCandidates.empty()) { + continue; + } + + // sort the vector of matching candidates in ascending order of the matching chi2 + std::sort(matchingCandidatesVector.begin(), matchingCandidatesVector.end(), + [](const std::pair& t1, const std::pair& t2) -> bool { + return (t1.second < t2.second); + }); + + // store the leading candidate + auto& t = tracksFwd[matchingCandidatesVector[0].first]; mMuonTracks.emplace_back(std::make_pair({ &t, recoCont, mFirstTForbit }, true)); } } From cedf00d0cd7307b93299ab3eab6bf3b37e90cdb4 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Fri, 17 Oct 2025 08:44:23 +0200 Subject: [PATCH 2/2] [MUON] clang formatting --- Modules/MUON/Common/src/TrackPlotter.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/MUON/Common/src/TrackPlotter.cxx b/Modules/MUON/Common/src/TrackPlotter.cxx index 0e74844576..aaca0e135d 100644 --- a/Modules/MUON/Common/src/TrackPlotter.cxx +++ b/Modules/MUON/Common/src/TrackPlotter.cxx @@ -494,9 +494,9 @@ void TrackPlotter::fillHistograms(const o2::globaltracking::RecoContainer& recoC // sort the vector of matching candidates in ascending order of the matching chi2 std::sort(matchingCandidatesVector.begin(), matchingCandidatesVector.end(), - [](const std::pair& t1, const std::pair& t2) -> bool { - return (t1.second < t2.second); - }); + [](const std::pair& t1, const std::pair& t2) -> bool { + return (t1.second < t2.second); + }); // store the leading candidate auto& t = tracksFwd[matchingCandidatesVector[0].first];