From 0799c0f2633fde78996651bcfaf9594cef6f76e9 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Fri, 29 May 2026 12:13:09 +0200 Subject: [PATCH] [PWGDQ] extend matching features plots The plots of matching features are extended by adding more dimensions: * log of MCH momentum * leading/next-to-leading match score gap * MCH track tagging flag This allows a more refined comparison between data and MC. --- PWGDQ/Tasks/qaMatching.cxx | 119 ++++++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 40 deletions(-) diff --git a/PWGDQ/Tasks/qaMatching.cxx b/PWGDQ/Tasks/qaMatching.cxx index 2870357c5e4..44e003bfa85 100644 --- a/PWGDQ/Tasks/qaMatching.cxx +++ b/PWGDQ/Tasks/qaMatching.cxx @@ -681,27 +681,30 @@ struct QaMatching { MatchFeaturesHistos(std::string path, HistogramRegistry* registry, int numCandidates) { - AxisSpec indexAxis = {numCandidates + 1, 0, static_cast(numCandidates + 1), "ranking index"}; + AxisSpec indexAxis = {numCandidates, 0, static_cast(numCandidates), "ranking index"}; AxisSpec scoreAxis = {100, 0, 1, "match score"}; int matchTypeMax = static_cast(kMatchTypeUndefined) + 1; AxisSpec matchTypeAxis = {matchTypeMax, 0, static_cast(matchTypeMax), "match type"}; - AxisSpec dxAxis = {100, -10, 10, "#Deltax (cm)"}; - AxisSpec dyAxis = {100, -10, 10, "#Deltay (cm)"}; - AxisSpec dpAxis = {100, -10, 10, "#Deltap (GeV/c)"}; - AxisSpec dptAxis = {100, -1, 1, "#Deltap_{T} (GeV/c)"}; - AxisSpec dphiAxis = {100, -1, 1, "#Delta#phi (rad)"}; - AxisSpec dtanlAxis = {100, -10, 10, "#Deltatanl"}; - AxisSpec detaAxis = {100, -1, 1, "#Delta#eta"}; + AxisSpec taggedAxis = {2, 0, 2.0, "is tagged"}; + AxisSpec scoreGapAxis = {100, 0, 1.0, "match score gap"}; + AxisSpec logpAxis = {16, -1, 3, "log_{10}(p)"}; + AxisSpec dxAxis = {100, -20, 20, "#Deltax (cm)"}; + AxisSpec dyAxis = {100, -20, 20, "#Deltay (cm)"}; + AxisSpec dpAxis = {100, -50, 50, "#Deltap (GeV/c)"}; + AxisSpec dptAxis = {100, -5, 5, "#Deltap_{T} (GeV/c)"}; + AxisSpec dphiAxis = {100, -2, 2, "#Delta#phi (rad)"}; + AxisSpec dtanlAxis = {100, -20, 20, "#Deltatanl"}; + AxisSpec detaAxis = {100, -2, 2, "#Delta#eta"}; AxisSpec rabsAxis = {100, 0, 100, "R_{abs}"}; - hDeltaP = registry->add((path + "/deltaP").c_str(), "MFT-MCH #Deltap", {HistType::kTHnSparseF, {dpAxis, scoreAxis, indexAxis, matchTypeAxis}}); - hDeltaPt = registry->add((path + "/deltaPt").c_str(), "MFT-MCH #Deltap_{T}", {HistType::kTHnSparseF, {dptAxis, scoreAxis, indexAxis, matchTypeAxis}}); - hDeltaX = registry->add((path + "/deltaX").c_str(), "MFT-MCH #Deltax", {HistType::kTHnSparseF, {dxAxis, scoreAxis, indexAxis, matchTypeAxis}}); - hDeltaY = registry->add((path + "/deltaY").c_str(), "MFT-MCH #Deltay", {HistType::kTHnSparseF, {dyAxis, scoreAxis, indexAxis, matchTypeAxis}}); - hDeltaPhi = registry->add((path + "/deltaPhi").c_str(), "MFT-MCH #Delta#phi", {HistType::kTHnSparseF, {dphiAxis, scoreAxis, indexAxis, matchTypeAxis}}); - hDeltaTanl = registry->add((path + "/deltaTanl").c_str(), "MFT-MCH #DeltaTanl", {HistType::kTHnSparseF, {dtanlAxis, scoreAxis, indexAxis, matchTypeAxis}}); - hDeltaEta = registry->add((path + "/deltaEta").c_str(), "MFT-MCH #Delta#eta", {HistType::kTHnSparseF, {detaAxis, scoreAxis, indexAxis, matchTypeAxis}}); - hRabs = registry->add((path + "/Rabs").c_str(), "MFT-MCH R_{abs}", {HistType::kTHnSparseF, {rabsAxis, scoreAxis, indexAxis, matchTypeAxis}}); + hDeltaP = registry->add((path + "/deltaP").c_str(), "MFT-MCH #Deltap", {HistType::kTHnSparseF, {dpAxis, logpAxis, scoreAxis, scoreGapAxis, indexAxis, matchTypeAxis, taggedAxis}}); + hDeltaPt = registry->add((path + "/deltaPt").c_str(), "MFT-MCH #Deltap_{T}", {HistType::kTHnSparseF, {dptAxis, logpAxis, scoreAxis, scoreGapAxis, indexAxis, matchTypeAxis, taggedAxis}}); + hDeltaX = registry->add((path + "/deltaX").c_str(), "MFT-MCH #Deltax", {HistType::kTHnSparseF, {dxAxis, logpAxis, scoreAxis, scoreGapAxis, indexAxis, matchTypeAxis, taggedAxis}}); + hDeltaY = registry->add((path + "/deltaY").c_str(), "MFT-MCH #Deltay", {HistType::kTHnSparseF, {dyAxis, logpAxis, scoreAxis, scoreGapAxis, indexAxis, matchTypeAxis, taggedAxis}}); + hDeltaPhi = registry->add((path + "/deltaPhi").c_str(), "MFT-MCH #Delta#phi", {HistType::kTHnSparseF, {dphiAxis, logpAxis, scoreAxis, scoreGapAxis, indexAxis, matchTypeAxis, taggedAxis}}); + hDeltaTanl = registry->add((path + "/deltaTanl").c_str(), "MFT-MCH #DeltaTanl", {HistType::kTHnSparseF, {dtanlAxis, logpAxis, scoreAxis, scoreGapAxis, indexAxis, matchTypeAxis, taggedAxis}}); + hDeltaEta = registry->add((path + "/deltaEta").c_str(), "MFT-MCH #Delta#eta", {HistType::kTHnSparseF, {detaAxis, logpAxis, scoreAxis, scoreGapAxis, indexAxis, matchTypeAxis, taggedAxis}}); + hRabs = registry->add((path + "/Rabs").c_str(), "MFT-MCH R_{abs}", {HistType::kTHnSparseF, {rabsAxis, logpAxis, scoreAxis, scoreGapAxis, indexAxis, matchTypeAxis, taggedAxis}}); } }; @@ -2152,6 +2155,7 @@ struct QaMatching { template void fillMatchingPlots(C const& collision, TMUON const& muonTracks, + const std::vector& taggedMuons, const MatchingCandidates& matchingCandidates, MatchingPlotter* plotter) { @@ -2168,6 +2172,22 @@ struct QaMatching { if (!isGoodGlobalMuon(mchTrack, collision)) continue; + double logp = std::log10(mchTrack.p()); + + int isTagged = 0; + if (std::find(taggedMuons.begin(), taggedMuons.end(), mchIndex) != taggedMuons.end()) { + isTagged = 1; + } + + float scoreGap = 0; + if (globalTracksVector.size() > 1) { + // we have at least two candidates, so we can check the score difference + // between the leading and the sub-leading + auto leadingScore = globalTracksVector[0].matchScore; + auto subleadingScore = globalTracksVector[1].matchScore; + scoreGap = leadingScore - subleadingScore; + } + for (const auto& candidate : globalTracksVector) { double dp = candidate.mchTrackProp.getP() - candidate.mftTrackProp.getP(); double dpt = candidate.mchTrackProp.getPt() - candidate.mftTrackProp.getPt(); @@ -2177,14 +2197,15 @@ struct QaMatching { double dtanl = candidate.mchTrackProp.getTanl() - candidate.mftTrackProp.getTanl(); double deta = candidate.mchTrackProp.getEta() - candidate.mftTrackProp.getEta(); int matchType = static_cast(candidate.matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaP)->Fill(dp, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaPt)->Fill(dpt, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaX)->Fill(dx, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaY)->Fill(dy, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaPhi)->Fill(dphi, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaTanl)->Fill(dtanl, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaEta)->Fill(deta, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hRabs)->Fill(mchTrack.rAtAbsorberEnd(), candidate.matchScore, candidate.matchRanking, matchType); + int ranking = candidate.matchRanking - 1; + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaP)->Fill(dp, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaPt)->Fill(dpt, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaX)->Fill(dx, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaY)->Fill(dy, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaPhi)->Fill(dphi, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaTanl)->Fill(dtanl, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaEta)->Fill(deta, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hRabs)->Fill(mchTrack.rAtAbsorberEnd(), logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); } } @@ -2215,6 +2236,7 @@ struct QaMatching { const CollisionInfo& collisionInfo, TMUON const& muonTracks, TMFT const& mftTracks, + const std::vector& taggedMuons, const MatchingCandidates& matchingCandidates, const MatchingCandidates& matchingCandidatesProd, const std::vector>& matchablePairs, @@ -2315,6 +2337,22 @@ struct QaMatching { } if (isGoodMCH) { + double logp = std::log10(mchTrack.p()); + + int isTagged = 0; + if (std::find(taggedMuons.begin(), taggedMuons.end(), mchIndex) != taggedMuons.end()) { + isTagged = 1; + } + + float scoreGap = 0; + if (globalTracksVector.size()) { + // we have a matchable pair with at least two candidates, so we can check the score difference + // between the leading and the sub-leading + auto leadingScore = globalTracksVector[0].matchScore; + auto subleadingScore = globalTracksVector[1].matchScore; + scoreGap = leadingScore - subleadingScore; + } + for (const auto& candidate : globalTracksVector) { double dp = candidate.mchTrackProp.getP() - candidate.mftTrackProp.getP(); double dpt = candidate.mchTrackProp.getPt() - candidate.mftTrackProp.getPt(); @@ -2324,14 +2362,15 @@ struct QaMatching { double dtanl = candidate.mchTrackProp.getTanl() - candidate.mftTrackProp.getTanl(); double deta = candidate.mchTrackProp.getEta() - candidate.mftTrackProp.getEta(); int matchType = static_cast(candidate.matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaP)->Fill(dp, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaPt)->Fill(dpt, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaX)->Fill(dx, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaY)->Fill(dy, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaPhi)->Fill(dphi, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaTanl)->Fill(dtanl, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaEta)->Fill(deta, candidate.matchScore, candidate.matchRanking, matchType); - std::get>(plotter->fMatchFeaturesGoodMCH->hRabs)->Fill(mchTrack.rAtAbsorberEnd(), candidate.matchScore, candidate.matchRanking, matchType); + int ranking = candidate.matchRanking - 1; + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaP)->Fill(dp, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaPt)->Fill(dpt, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaX)->Fill(dx, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaY)->Fill(dy, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaPhi)->Fill(dphi, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaTanl)->Fill(dtanl, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hDeltaEta)->Fill(deta, logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); + std::get>(plotter->fMatchFeaturesGoodMCH->hRabs)->Fill(mchTrack.rAtAbsorberEnd(), logp, candidate.matchScore, scoreGap, ranking, matchType, isTagged); } } @@ -2937,9 +2976,9 @@ struct QaMatching { // Chi2-based matching from production fillQaMatchingAodTablesForCollision(collision, muonTracks, mftTracks, collisionInfo.matchingCandidates, matchingMethodCounter, collisionInfo.reducedEventId, collisionInfo.reducedMchTrackIds); if constexpr (isMC) { - fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, collisionInfo.matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, cfgMatchingChi2ScoreMftMchLow, fChi2MatchingPlotter.get(), false); + fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, taggedMuons, collisionInfo.matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, cfgMatchingChi2ScoreMftMchLow, fChi2MatchingPlotter.get(), false); } else { - fillMatchingPlots(collision, muonTracks, collisionInfo.matchingCandidates, fChi2MatchingPlotter.get()); + fillMatchingPlots(collision, muonTracks, taggedMuons, collisionInfo.matchingCandidates, fChi2MatchingPlotter.get()); } //------------------------------- @@ -2974,9 +3013,9 @@ struct QaMatching { } } if constexpr (isMC) { - fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, taggedMatchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, cfgMatchingChi2ScoreMftMchLow, fTaggedMuonsMatchingPlotter.get()); + fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, taggedMuons, taggedMatchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, cfgMatchingChi2ScoreMftMchLow, fTaggedMuonsMatchingPlotter.get()); } else { - fillMatchingPlots(collision, muonTracks, taggedMatchingCandidates, fTaggedMuonsMatchingPlotter.get()); + fillMatchingPlots(collision, muonTracks, taggedMuons, taggedMatchingCandidates, fTaggedMuonsMatchingPlotter.get()); } //------------------------------- @@ -2991,9 +3030,9 @@ struct QaMatching { matchingMethodCounter += 1; fillQaMatchingAodTablesForCollision(collision, muonTracks, mftTracks, matchingCandidates, matchingMethodCounter, collisionInfo.reducedEventId, collisionInfo.reducedMchTrackIds); if constexpr (isMC) { - fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter, false); + fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, taggedMuons, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter, false); } else { - fillMatchingPlots(collision, muonTracks, matchingCandidates, plotter); + fillMatchingPlots(collision, muonTracks, taggedMuons, matchingCandidates, plotter); } } @@ -3009,9 +3048,9 @@ struct QaMatching { matchingMethodCounter += 1; fillQaMatchingAodTablesForCollision(collision, muonTracks, mftTracks, matchingCandidates, matchingMethodCounter, collisionInfo.reducedEventId, collisionInfo.reducedMchTrackIds); if constexpr (isMC) { - fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter); + fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, taggedMuons, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter); } else { - fillMatchingPlots(collision, muonTracks, matchingCandidates, plotter); + fillMatchingPlots(collision, muonTracks, taggedMuons, matchingCandidates, plotter); } }