From 516595587789df2a73a2d8884958ff6c93ef9733 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Fri, 22 May 2026 20:07:42 +0200 Subject: [PATCH 1/5] [PWGDQ] enable processing of real data in matching tasks The ML training data producer and the matching QA tasks are modified to allow processing real data as well as MC data. A dedicated process function is added to both tasks. --- PWGDQ/Tasks/mftMchMatcher.cxx | 81 ++++-- PWGDQ/Tasks/qaMatching.cxx | 480 ++++++++++++++++++---------------- 2 files changed, 317 insertions(+), 244 deletions(-) diff --git a/PWGDQ/Tasks/mftMchMatcher.cxx b/PWGDQ/Tasks/mftMchMatcher.cxx index 5c8f668e5e8..d69afb2356c 100644 --- a/PWGDQ/Tasks/mftMchMatcher.cxx +++ b/PWGDQ/Tasks/mftMchMatcher.cxx @@ -574,19 +574,13 @@ struct mftMchMatcher { return result; } - void processMC(MyEvents const& collisions, - aod::BCsWithTimestamps const& bcs, - MyMuonsMC const& muonTracks, - MyMFTsMC const& mftTracks, - MyMFTCovariances const& mftCovs, - aod::McParticles const& /*mcParticles*/) + template + void fillTable(TCOLLS const& collisions, + TBCS const& /*bcs*/, + TMUONS const& muonTracks, + TMFTS const& mftTracks, + TCOVS const& mftCovs) { - if (bcs.size() > 0) { - auto bc = bcs.begin(); - initCCDB(bc); - VarManager::SetMatchingPlane(fzMatching.value); - } - registry.get(HIST("acceptedEvents"))->Fill(0); // reject a randomly selected fraction of events if (fSamplingFraction < 1.0) { @@ -600,7 +594,9 @@ struct mftMchMatcher { fillBestMuonMatches(muonTracks); std::vector> matchablePairs; - fillMatchablePairs(muonTracks, mftTracks, matchablePairs); + if constexpr (isMc) { + fillMatchablePairs(muonTracks, mftTracks, matchablePairs); + } mftCovIndexes.clear(); for (auto& mftTrackCov : mftCovs) { @@ -626,10 +622,10 @@ struct mftMchMatcher { } const auto& collision = collisions.rawIteratorAt(muon.collisionId()); - auto bc_coll = collision.bc_as(); + auto bc_coll = collision.template bc_as(); - auto muontrack = muon.template matchMCHTrack_as(); - auto mfttrack = muon.template matchMFTTrack_as(); + auto muontrack = muon.template matchMCHTrack_as(); + auto mfttrack = muon.template matchMFTTrack_as(); auto const& mfttrackcov = mftCovs.rawIteratorAt(mftCovIndexes[mfttrack.globalIndex()]); auto muonTime = muontrack.trackTime() + bc_coll.globalBC() * o2::constants::lhc::LHCBunchSpacingNS; @@ -657,9 +653,21 @@ struct mftMchMatcher { bool IsAmbig = (muon.compatibleCollIds().size() != 1); int MFTMult = collision.mftNtracks(); - auto matchType = getMatchType(muon, muonTracks, mftTracks, matchablePairs, isBestMatch); + auto matchType = kMatchTypeUndefined; + if constexpr (isMc) { + matchType = getMatchType(muon, muonTracks, mftTracks, matchablePairs, isBestMatch); + } bool isSignal = (matchType == kMatchTypeTrueLeading) || (matchType == kMatchTypeTrueNonLeading); + int mcMaskMuon = 0; + int mcMaskMft = 0; + int ncMaskGlob = 0; + if constexpr (isMc) { + mcMaskMuon = muontrack.mcMask(); + mcMaskMft = mfttrack.mcMask(); + ncMaskGlob = muon.mcMask(); + } + registry.get(HIST("matchType"))->Fill(static_cast(matchType)); fwdMatchMLCandidates( @@ -719,15 +727,48 @@ struct mftMchMatcher { muon.fwdDcaY(), IsAmbig, MFTMult, - muontrack.mcMask(), - mfttrack.mcMask(), - muon.mcMask(), + mcMaskMuon, + mcMaskMft, + ncMaskGlob, static_cast(matchType), isSignal); } } + void processMC(MyEvents const& collisions, + aod::BCsWithTimestamps const& bcs, + MyMuonsMC const& muonTracks, + MyMFTsMC const& mftTracks, + MyMFTCovariances const& mftCovs, + aod::McParticles const& /*mcParticles*/) + { + if (bcs.size() > 0) { + auto bc = bcs.begin(); + initCCDB(bc); + VarManager::SetMatchingPlane(fzMatching.value); + } + + fillTable(collisions, bcs, muonTracks, mftTracks, mftCovs); + } + PROCESS_SWITCH(mftMchMatcher, processMC, "process_MC", true); + + void processRD(MyEvents const& collisions, + aod::BCsWithTimestamps const& bcs, + MyMuonsWithCov const& muonTracks, + MyMFTs const& mftTracks, + MyMFTCovariances const& mftCovs) + { + if (bcs.size() > 0) { + auto bc = bcs.begin(); + initCCDB(bc); + VarManager::SetMatchingPlane(fzMatching.value); + } + + fillTable(collisions, bcs, muonTracks, mftTracks, mftCovs); + } + + PROCESS_SWITCH(mftMchMatcher, processRD, "process_RD", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGDQ/Tasks/qaMatching.cxx b/PWGDQ/Tasks/qaMatching.cxx index 6f2056d9c24..7636cfce9b7 100644 --- a/PWGDQ/Tasks/qaMatching.cxx +++ b/PWGDQ/Tasks/qaMatching.cxx @@ -184,6 +184,19 @@ static float chi2ToScore(float chi2, int ndf, float chi2max) return static_cast(result); } +static void SetMatchTypeAxisLabels(TAxis* axis) +{ + axis->SetBinLabel(1, "true (leading)"); + axis->SetBinLabel(2, "wrong (leading)"); + axis->SetBinLabel(3, "decay (leading)"); + axis->SetBinLabel(4, "fake (leading)"); + axis->SetBinLabel(5, "true (non leading)"); + axis->SetBinLabel(6, "wrong (non leading)"); + axis->SetBinLabel(7, "decay (non leading)"); + axis->SetBinLabel(8, "fake (non leading)"); + axis->SetBinLabel(9, "unknown"); +} + struct QaMatching { template @@ -233,6 +246,8 @@ struct QaMatching { MuonMatchType matchType{kMatchTypeUndefined}; }; + Configurable cfgIsMc{"cfgIsMc", true, "Wheter the processed data is from MC simulations"}; + //// Variables for selecting muon tracks Configurable cfgPMchLow{"cfgPMchLow", 0.0f, ""}; Configurable cfgPtMchLow{"cfgPtMchLow", 0.7f, ""}; @@ -717,10 +732,10 @@ struct QaMatching { o2::framework::HistPtr fTrueMatchChi2VsProd; //- - EfficiencyPlotter fMatchingPurityPlotter; - EfficiencyPlotter fPairingEfficiencyPlotter; - EfficiencyPlotter fMatchingEfficiencyPlotter; - EfficiencyPlotter fFakeMatchingEfficiencyPlotter; + std::unique_ptr fMatchingPurityPlotter; + std::unique_ptr fPairingEfficiencyPlotter; + std::unique_ptr fMatchingEfficiencyPlotter; + std::unique_ptr fFakeMatchingEfficiencyPlotter; HistogramRegistry* registry; @@ -728,191 +743,127 @@ struct QaMatching { HistogramRegistry* reg, bool createPdgMomHistograms, int mftMultMax, - int numCandidates) - : fMatchingPurityPlotter(path + "matching-purity/", "Matching purity", *reg, createPdgMomHistograms), - fPairingEfficiencyPlotter(path + "pairing-efficiency/", "Pairing efficiency", *reg, createPdgMomHistograms), - fMatchingEfficiencyPlotter(path + "matching-efficiency/", "Matching efficiency", *reg, createPdgMomHistograms), - fFakeMatchingEfficiencyPlotter(path + "fake-matching-efficiency/", "Fake matching efficiency", *reg, createPdgMomHistograms) + int numCandidates, + bool isMc) { registry = reg; AxisSpec pAxis = {100, 0, 100, "p (GeV/c)"}; AxisSpec ptAxis = {100, 0, 10, "p_{T} (GeV/c)"}; AxisSpec dzAxis = {100, 0, 50, "#Deltaz (cm)"}; AxisSpec indexAxis = {6, 0, 6, "ranking index"}; - - std::string histName = path + "matchRanking"; - std::string histTitle = "True match ranking"; - - fMatchRanking = std::make_unique(path + "matchRanking", "True match ranking", registry, mftMultMax, numCandidates); - fMatchRankingGoodMCH = std::make_unique(path + "matchRankingGoodMCH", "True match ranking (good MCH tracks)", registry, mftMultMax, numCandidates); - fMatchRankingPaired = std::make_unique(path + "matchRankingPaired", "True match ranking (paired MCH tracks)", registry, mftMultMax, numCandidates); - fMatchRankingPairedGoodMCH = std::make_unique(path + "matchRankingPairedGoodMCH", "True match ranking (good paired MCH tracks)", registry, mftMultMax, numCandidates); - - //- - AxisSpec missedMatchAxis = {5, 0, 5, ""}; - histName = path + "missedMatches"; - histTitle = "Missed matches"; - fMissedMatches = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {missedMatchAxis}}); - std::get>(fMissedMatches)->GetXaxis()->SetBinLabel(1, "not paired"); - std::get>(fMissedMatches)->GetXaxis()->SetBinLabel(2, "fake MCH"); - std::get>(fMissedMatches)->GetXaxis()->SetBinLabel(3, "not stored"); - histName = path + "missedMatchesGoodMCH"; - histTitle = "Missed matches - good MCH tracks"; - fMissedMatchesGoodMCH = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {missedMatchAxis}}); - std::get>(fMissedMatchesGoodMCH)->GetXaxis()->SetBinLabel(1, "not paired"); - std::get>(fMissedMatchesGoodMCH)->GetXaxis()->SetBinLabel(2, "fake MCH"); - std::get>(fMissedMatchesGoodMCH)->GetXaxis()->SetBinLabel(3, "not stored"); - - AxisSpec decayRankingAxis = {5, 0, 5, "decay ranking"}; - histName = path + "decayRankingGoodMatches"; - histTitle = "Decay ranking - good matches"; - fDecayRankingGoodMatches = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {decayRankingAxis}}); - histName = path + "decayRankingNonLeadingMatches"; - histTitle = "Decay ranking - non-leading matches"; - fDecayRankingNonLeadingMatches = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {decayRankingAxis}}); - histName = path + "decayRankingMissedMatches"; - histTitle = "Decay ranking - missed matches"; - fDecayRankingMissedMatches = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {decayRankingAxis}}); - - AxisSpec scoreGapAxis = {100, 0, 1, "match score difference"}; - histName = path + "scoreGapLeadingTrueMatches"; - histTitle = "Score gap between leading and subleading matches - good matches"; - fScoreGapLeadingTrueMatches = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {scoreGapAxis}}); - histName = path + "scoreGapNonLeadingTrueMatches"; - histTitle = "Score gap between leading and subleading matches - non-leading matches"; - fScoreGapNonLeadingTrueMatches = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {scoreGapAxis}}); - - //- 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), ""}; - histName = path + "matchType"; - histTitle = "Match type"; - fMatchType = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {matchTypeAxis}}); - std::get>(fMatchType)->GetXaxis()->SetBinLabel(1, "true (leading)"); - std::get>(fMatchType)->GetXaxis()->SetBinLabel(2, "wrong (leading)"); - std::get>(fMatchType)->GetXaxis()->SetBinLabel(3, "decay (leading)"); - std::get>(fMatchType)->GetXaxis()->SetBinLabel(4, "fake (leading)"); - std::get>(fMatchType)->GetXaxis()->SetBinLabel(5, "true (non leading)"); - std::get>(fMatchType)->GetXaxis()->SetBinLabel(6, "wrong (non leading)"); - std::get>(fMatchType)->GetXaxis()->SetBinLabel(7, "decay (non leading)"); - std::get>(fMatchType)->GetXaxis()->SetBinLabel(8, "fake (non leading)"); - std::get>(fMatchType)->GetXaxis()->SetBinLabel(9, "undefined"); - histName = path + "matchTypeVsP"; - histTitle = "Match type vs. p"; - fMatchTypeVsP = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {pAxis, matchTypeAxis}}); - std::get>(fMatchTypeVsP)->GetYaxis()->SetBinLabel(1, "true (leading)"); - std::get>(fMatchTypeVsP)->GetYaxis()->SetBinLabel(2, "wrong (leading)"); - std::get>(fMatchTypeVsP)->GetYaxis()->SetBinLabel(3, "decay (leading)"); - std::get>(fMatchTypeVsP)->GetYaxis()->SetBinLabel(4, "fake (leading)"); - std::get>(fMatchTypeVsP)->GetYaxis()->SetBinLabel(5, "true (non leading)"); - std::get>(fMatchTypeVsP)->GetYaxis()->SetBinLabel(6, "wrong (non leading)"); - std::get>(fMatchTypeVsP)->GetYaxis()->SetBinLabel(7, "decay (non leading)"); - std::get>(fMatchTypeVsP)->GetYaxis()->SetBinLabel(8, "fake (non leading)"); - std::get>(fMatchTypeVsP)->GetYaxis()->SetBinLabel(9, "undefined"); - histName = path + "matchTypeVsPt"; - histTitle = "Match type vs. p_{T}"; - fMatchTypeVsPt = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {ptAxis, matchTypeAxis}}); - std::get>(fMatchTypeVsPt)->GetYaxis()->SetBinLabel(1, "true (leading)"); - std::get>(fMatchTypeVsPt)->GetYaxis()->SetBinLabel(2, "wrong (leading)"); - std::get>(fMatchTypeVsPt)->GetYaxis()->SetBinLabel(3, "decay (leading)"); - std::get>(fMatchTypeVsPt)->GetYaxis()->SetBinLabel(4, "fake (leading)"); - std::get>(fMatchTypeVsPt)->GetYaxis()->SetBinLabel(5, "true (non leading)"); - std::get>(fMatchTypeVsPt)->GetYaxis()->SetBinLabel(6, "wrong (non leading)"); - std::get>(fMatchTypeVsPt)->GetYaxis()->SetBinLabel(7, "decay (non leading)"); - std::get>(fMatchTypeVsPt)->GetYaxis()->SetBinLabel(8, "fake (non leading)"); - std::get>(fMatchTypeVsPt)->GetYaxis()->SetBinLabel(9, "undefined"); - - histName = path + "matchChi2VsType"; - histTitle = "Match #chi^{2} vs. match type"; - fMatchChi2VsType = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {matchTypeAxis, chi2Axis}}); - std::get>(fMatchChi2VsType)->GetXaxis()->SetBinLabel(1, "true (leading)"); - std::get>(fMatchChi2VsType)->GetXaxis()->SetBinLabel(2, "wrong (leading)"); - std::get>(fMatchChi2VsType)->GetXaxis()->SetBinLabel(3, "decay (leading)"); - std::get>(fMatchChi2VsType)->GetXaxis()->SetBinLabel(4, "fake (leading)"); - std::get>(fMatchChi2VsType)->GetXaxis()->SetBinLabel(5, "true (non leading)"); - std::get>(fMatchChi2VsType)->GetXaxis()->SetBinLabel(6, "wrong (non leading)"); - std::get>(fMatchChi2VsType)->GetXaxis()->SetBinLabel(7, "decay (non leading)"); - std::get>(fMatchChi2VsType)->GetXaxis()->SetBinLabel(8, "fake (non leading)"); - std::get>(fMatchChi2VsType)->GetXaxis()->SetBinLabel(9, "undefined"); - histName = path + "matchChi2VsTypeVsP"; - histTitle = "Match #chi^{2} vs. match type vs. p"; - fMatchChi2VsTypeVsP = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH3F, {pAxis, matchTypeAxis, chi2Axis}}); - std::get>(fMatchChi2VsTypeVsP)->GetYaxis()->SetBinLabel(1, "true (leading)"); - std::get>(fMatchChi2VsTypeVsP)->GetYaxis()->SetBinLabel(2, "wrong (leading)"); - std::get>(fMatchChi2VsTypeVsP)->GetYaxis()->SetBinLabel(3, "decay (leading)"); - std::get>(fMatchChi2VsTypeVsP)->GetYaxis()->SetBinLabel(4, "fake (leading)"); - std::get>(fMatchChi2VsTypeVsP)->GetYaxis()->SetBinLabel(5, "true (non leading)"); - std::get>(fMatchChi2VsTypeVsP)->GetYaxis()->SetBinLabel(6, "wrong (non leading)"); - std::get>(fMatchChi2VsTypeVsP)->GetYaxis()->SetBinLabel(7, "decay (non leading)"); - std::get>(fMatchChi2VsTypeVsP)->GetYaxis()->SetBinLabel(8, "fake (non leading)"); - std::get>(fMatchChi2VsTypeVsP)->GetYaxis()->SetBinLabel(9, "undefined"); - histName = path + "matchChi2VsTypeVsPt"; - histTitle = "Match #chi^{2} vs. match type vs. p_{T}"; - fMatchChi2VsTypeVsPt = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH3F, {ptAxis, matchTypeAxis, chi2Axis}}); - std::get>(fMatchChi2VsTypeVsPt)->GetYaxis()->SetBinLabel(1, "true (leading)"); - std::get>(fMatchChi2VsTypeVsPt)->GetYaxis()->SetBinLabel(2, "wrong (leading)"); - std::get>(fMatchChi2VsTypeVsPt)->GetYaxis()->SetBinLabel(3, "decay (leading)"); - std::get>(fMatchChi2VsTypeVsPt)->GetYaxis()->SetBinLabel(4, "fake (leading)"); - std::get>(fMatchChi2VsTypeVsPt)->GetYaxis()->SetBinLabel(5, "true (non leading)"); - std::get>(fMatchChi2VsTypeVsPt)->GetYaxis()->SetBinLabel(6, "wrong (non leading)"); - std::get>(fMatchChi2VsTypeVsPt)->GetYaxis()->SetBinLabel(7, "decay (non leading)"); - std::get>(fMatchChi2VsTypeVsPt)->GetYaxis()->SetBinLabel(8, "fake (non leading)"); - std::get>(fMatchChi2VsTypeVsPt)->GetYaxis()->SetBinLabel(9, "undefined"); - //- - histName = path + "matchScoreVsType"; - histTitle = "Match score vs. match type"; - fMatchScoreVsType = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {matchTypeAxis, scoreAxis}}); - std::get>(fMatchScoreVsType)->GetXaxis()->SetBinLabel(1, "true (leading)"); - std::get>(fMatchScoreVsType)->GetXaxis()->SetBinLabel(2, "wrong (leading)"); - std::get>(fMatchScoreVsType)->GetXaxis()->SetBinLabel(3, "decay (leading)"); - std::get>(fMatchScoreVsType)->GetXaxis()->SetBinLabel(4, "fake (leading)"); - std::get>(fMatchScoreVsType)->GetXaxis()->SetBinLabel(5, "true (non leading)"); - std::get>(fMatchScoreVsType)->GetXaxis()->SetBinLabel(6, "wrong (non leading)"); - std::get>(fMatchScoreVsType)->GetXaxis()->SetBinLabel(7, "decay (non leading)"); - std::get>(fMatchScoreVsType)->GetXaxis()->SetBinLabel(8, "fake (non leading)"); - std::get>(fMatchScoreVsType)->GetXaxis()->SetBinLabel(9, "undefined"); - histName = path + "matchScoreVsTypeVsP"; - histTitle = "Match score vs. match type vs. p"; - fMatchScoreVsTypeVsP = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH3F, {pAxis, matchTypeAxis, scoreAxis}}); - std::get>(fMatchScoreVsTypeVsP)->GetYaxis()->SetBinLabel(1, "true (leading)"); - std::get>(fMatchScoreVsTypeVsP)->GetYaxis()->SetBinLabel(2, "wrong (leading)"); - std::get>(fMatchScoreVsTypeVsP)->GetYaxis()->SetBinLabel(3, "decay (leading)"); - std::get>(fMatchScoreVsTypeVsP)->GetYaxis()->SetBinLabel(4, "fake (leading)"); - std::get>(fMatchScoreVsTypeVsP)->GetYaxis()->SetBinLabel(5, "true (non leading)"); - std::get>(fMatchScoreVsTypeVsP)->GetYaxis()->SetBinLabel(6, "wrong (non leading)"); - std::get>(fMatchScoreVsTypeVsP)->GetYaxis()->SetBinLabel(7, "decay (non leading)"); - std::get>(fMatchScoreVsTypeVsP)->GetYaxis()->SetBinLabel(8, "fake (non leading)"); - std::get>(fMatchScoreVsTypeVsP)->GetYaxis()->SetBinLabel(9, "undefined"); - histName = path + "matchScoreVsTypeVsPt"; - histTitle = "Match score vs. match type vs. p_{T}"; - fMatchScoreVsTypeVsPt = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH3F, {ptAxis, matchTypeAxis, scoreAxis}}); - std::get>(fMatchScoreVsTypeVsPt)->GetYaxis()->SetBinLabel(1, "true (leading)"); - std::get>(fMatchScoreVsTypeVsPt)->GetYaxis()->SetBinLabel(2, "wrong (leading)"); - std::get>(fMatchScoreVsTypeVsPt)->GetYaxis()->SetBinLabel(3, "decay (leading)"); - std::get>(fMatchScoreVsTypeVsPt)->GetYaxis()->SetBinLabel(4, "fake (leading)"); - std::get>(fMatchScoreVsTypeVsPt)->GetYaxis()->SetBinLabel(5, "true (non leading)"); - std::get>(fMatchScoreVsTypeVsPt)->GetYaxis()->SetBinLabel(6, "wrong (non leading)"); - std::get>(fMatchScoreVsTypeVsPt)->GetYaxis()->SetBinLabel(7, "decay (non leading)"); - std::get>(fMatchScoreVsTypeVsPt)->GetYaxis()->SetBinLabel(8, "fake (non leading)"); - std::get>(fMatchScoreVsTypeVsPt)->GetYaxis()->SetBinLabel(9, "undefined"); + + std::string histName; + std::string histTitle; + + if (isMc) { + fMatchRanking = std::make_unique(path + "matchRanking", "True match ranking", registry, mftMultMax, numCandidates); + fMatchRankingGoodMCH = std::make_unique(path + "matchRankingGoodMCH", "True match ranking (good MCH tracks)", registry, mftMultMax, numCandidates); + fMatchRankingPaired = std::make_unique(path + "matchRankingPaired", "True match ranking (paired MCH tracks)", registry, mftMultMax, numCandidates); + fMatchRankingPairedGoodMCH = std::make_unique(path + "matchRankingPairedGoodMCH", "True match ranking (good paired MCH tracks)", registry, mftMultMax, numCandidates); + + fMatchingPurityPlotter = std::make_unique(path + "matching-purity/", "Matching purity", *reg, createPdgMomHistograms); + fPairingEfficiencyPlotter = std::make_unique(path + "pairing-efficiency/", "Pairing efficiency", *reg, createPdgMomHistograms); + fMatchingEfficiencyPlotter = std::make_unique(path + "matching-efficiency/", "Matching efficiency", *reg, createPdgMomHistograms); + fFakeMatchingEfficiencyPlotter = std::make_unique(path + "fake-matching-efficiency/", "Fake matching efficiency", *reg, createPdgMomHistograms); + + //- + AxisSpec missedMatchAxis = {5, 0, 5, ""}; + histName = path + "missedMatches"; + histTitle = "Missed matches"; + fMissedMatches = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {missedMatchAxis}}); + std::get>(fMissedMatches)->GetXaxis()->SetBinLabel(1, "not paired"); + std::get>(fMissedMatches)->GetXaxis()->SetBinLabel(2, "fake MCH"); + std::get>(fMissedMatches)->GetXaxis()->SetBinLabel(3, "not stored"); + histName = path + "missedMatchesGoodMCH"; + histTitle = "Missed matches - good MCH tracks"; + fMissedMatchesGoodMCH = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {missedMatchAxis}}); + std::get>(fMissedMatchesGoodMCH)->GetXaxis()->SetBinLabel(1, "not paired"); + std::get>(fMissedMatchesGoodMCH)->GetXaxis()->SetBinLabel(2, "fake MCH"); + std::get>(fMissedMatchesGoodMCH)->GetXaxis()->SetBinLabel(3, "not stored"); + + AxisSpec decayRankingAxis = {5, 0, 5, "decay ranking"}; + histName = path + "decayRankingGoodMatches"; + histTitle = "Decay ranking - good matches"; + fDecayRankingGoodMatches = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {decayRankingAxis}}); + histName = path + "decayRankingNonLeadingMatches"; + histTitle = "Decay ranking - non-leading matches"; + fDecayRankingNonLeadingMatches = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {decayRankingAxis}}); + histName = path + "decayRankingMissedMatches"; + histTitle = "Decay ranking - missed matches"; + fDecayRankingMissedMatches = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {decayRankingAxis}}); + + AxisSpec scoreGapAxis = {100, 0, 1, "match score difference"}; + histName = path + "scoreGapLeadingTrueMatches"; + histTitle = "Score gap between leading and subleading matches - good matches"; + fScoreGapLeadingTrueMatches = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {scoreGapAxis}}); + histName = path + "scoreGapNonLeadingTrueMatches"; + histTitle = "Score gap between leading and subleading matches - non-leading matches"; + fScoreGapNonLeadingTrueMatches = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {scoreGapAxis}}); + + //- + int matchTypeMax = static_cast(kMatchTypeUndefined) + 1; + 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}}); + SetMatchTypeAxisLabels(std::get>(fMatchType)->GetXaxis()); + histName = path + "matchTypeVsP"; + histTitle = "Match type vs. p"; + fMatchTypeVsP = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {pAxis, matchTypeAxis}}); + SetMatchTypeAxisLabels(std::get>(fMatchTypeVsP)->GetYaxis()); + histName = path + "matchTypeVsPt"; + histTitle = "Match type vs. p_{T}"; + fMatchTypeVsPt = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {ptAxis, matchTypeAxis}}); + SetMatchTypeAxisLabels(std::get>(fMatchTypeVsPt)->GetYaxis()); + + histName = path + "matchChi2VsType"; + histTitle = "Match #chi^{2} vs. match type"; + fMatchChi2VsType = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {matchTypeAxis, chi2Axis}}); + SetMatchTypeAxisLabels(std::get>(fMatchChi2VsType)->GetXaxis()); + histName = path + "matchChi2VsTypeVsP"; + histTitle = "Match #chi^{2} vs. match type vs. p"; + fMatchChi2VsTypeVsP = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH3F, {pAxis, matchTypeAxis, chi2Axis}}); + SetMatchTypeAxisLabels(std::get>(fMatchChi2VsTypeVsP)->GetYaxis()); + histName = path + "matchChi2VsTypeVsPt"; + histTitle = "Match #chi^{2} vs. match type vs. p_{T}"; + fMatchChi2VsTypeVsPt = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH3F, {ptAxis, matchTypeAxis, chi2Axis}}); + SetMatchTypeAxisLabels(std::get>(fMatchChi2VsTypeVsPt)->GetYaxis()); + //- + histName = path + "matchScoreVsType"; + histTitle = "Match score vs. match type"; + fMatchScoreVsType = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {matchTypeAxis, scoreAxis}}); + SetMatchTypeAxisLabels(std::get>(fMatchScoreVsType)->GetXaxis()); + histName = path + "matchScoreVsTypeVsP"; + histTitle = "Match score vs. match type vs. p"; + fMatchScoreVsTypeVsP = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH3F, {pAxis, matchTypeAxis, scoreAxis}}); + SetMatchTypeAxisLabels(std::get>(fMatchScoreVsTypeVsP)->GetYaxis()); + histName = path + "matchScoreVsTypeVsPt"; + histTitle = "Match score vs. match type vs. p_{T}"; + fMatchScoreVsTypeVsPt = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH3F, {ptAxis, matchTypeAxis, scoreAxis}}); + SetMatchTypeAxisLabels(std::get>(fMatchScoreVsTypeVsPt)->GetYaxis()); + } AxisSpec prodScoreAxis = {100, 0, 1, "matching score (prod)"}; histName = path + "matchScoreVsProd"; histTitle = "Match score vs. production"; fMatchScoreVsProd = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {prodScoreAxis, scoreAxis}}); - histName = path + "trueMatchScoreVsProd"; - histTitle = "Match score vs. production - true match"; - fTrueMatchScoreVsProd = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {prodScoreAxis, scoreAxis}}); + if (isMc) { + histName = path + "trueMatchScoreVsProd"; + histTitle = "Match score vs. production - true match"; + fTrueMatchScoreVsProd = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {prodScoreAxis, scoreAxis}}); + } AxisSpec prodChi2Axis = {100, 0, 100, "matching #chi^{2}/NDF (prod)"}; histName = path + "matchChi2VsProd"; histTitle = "Match #chi^{2} vs. production"; fMatchChi2VsProd = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {prodChi2Axis, chi2Axis}}); - histName = path + "trueMatchChi2VsProd"; - histTitle = "Match #chi^{2} vs. production - true match"; - fTrueMatchChi2VsProd = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {{100, 0, 10, "matching #chi^{2} (prod)"}, {100, 0, 10, "matching #chi^{2}"}}}); + if (isMc) { + histName = path + "trueMatchChi2VsProd"; + histTitle = "Match #chi^{2} vs. production - true match"; + fTrueMatchChi2VsProd = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {{100, 0, 10, "matching #chi^{2} (prod)"}, {100, 0, 10, "matching #chi^{2}"}}}); + } } }; std::unique_ptr fChi2MatchingPlotter; @@ -948,7 +899,7 @@ struct QaMatching { } } - void createMatchingHistosMc() + void createMatchingHistos() { AxisSpec chi2Axis = {1000, 0, 1000, "chi^{2}"}; AxisSpec chi2AxisSmall = {200, 0, 100, "chi^{2}"}; @@ -956,7 +907,9 @@ struct QaMatching { AxisSpec pTAxis = {100, 0, 10, "p_{T} (GeV/c)"}; AxisSpec etaAxis = {100, -4, -2, "#eta"}; AxisSpec phiAxis = {90, -180, 180, "#phi (degrees)"}; - std::string histPath = "matching/MC/"; + std::string histPath = cfgIsMc.value ? "matching/MC/" : "matching/"; + + std::cout << std::format("TOTO cfgIsMc: {}", cfgIsMc.value) << std::endl; AxisSpec trackPositionXAtMftAxis = {100, -15, 15, "MFT x (cm)"}; AxisSpec trackPositionYAtMftAxis = {100, -15, 15, "MFT y (cm)"}; @@ -966,18 +919,18 @@ struct QaMatching { registry.add((histPath + "selectedMCHTracksAtMFTTrue").c_str(), "Selected MCH tracks position at MFT end - true", {HistType::kTH2F, {trackPositionXAtMftAxis, trackPositionYAtMftAxis}}); registry.add((histPath + "selectedMCHTracksAtMFTFake").c_str(), "Selected MCH tracks position at MFT end - fake", {HistType::kTH2F, {trackPositionXAtMftAxis, trackPositionYAtMftAxis}}); - fChi2MatchingPlotter = std::make_unique(histPath + "Prod/", ®istryMatching, configQas.cfgCreatePdgMomHistograms, cfgMftTrackMultiplicityMax, cfgNCandidatesMax); + fChi2MatchingPlotter = std::make_unique(histPath + "Prod/", ®istryMatching, configQas.cfgCreatePdgMomHistograms, cfgMftTrackMultiplicityMax, cfgNCandidatesMax, cfgIsMc.value); int registryIndex = 0; for (const auto& [label, func] : matchingChi2Functions) { - fMatchingPlotters[label] = std::make_unique(histPath + label + "/", registryMatchingVec[registryIndex], configQas.cfgCreatePdgMomHistograms, cfgMftTrackMultiplicityMax, cfgNCandidatesMax); + fMatchingPlotters[label] = std::make_unique(histPath + label + "/", registryMatchingVec[registryIndex], configQas.cfgCreatePdgMomHistograms, cfgMftTrackMultiplicityMax, cfgNCandidatesMax, cfgIsMc.value); registryIndex += 1; } for (const auto& [label, response] : matchingMlResponses) { - fMatchingPlotters[label] = std::make_unique(histPath + label + "/", (registryMatchingVec[registryIndex]), configQas.cfgCreatePdgMomHistograms, cfgMftTrackMultiplicityMax, cfgNCandidatesMax); + fMatchingPlotters[label] = std::make_unique(histPath + label + "/", (registryMatchingVec[registryIndex]), configQas.cfgCreatePdgMomHistograms, cfgMftTrackMultiplicityMax, cfgNCandidatesMax, cfgIsMc.value); registryIndex += 1; } - fTaggedMuonsMatchingPlotter = std::make_unique(histPath + "Tagged/", ®istryMatching, configQas.cfgCreatePdgMomHistograms, cfgMftTrackMultiplicityMax, cfgNCandidatesMax); + fTaggedMuonsMatchingPlotter = std::make_unique(histPath + "Tagged/", ®istryMatching, configQas.cfgCreatePdgMomHistograms, cfgMftTrackMultiplicityMax, cfgNCandidatesMax, cfgIsMc.value); } void createDimuonHistos() @@ -1203,7 +1156,7 @@ struct QaMatching { std::get>(matchMethodsHist)->GetXaxis()->SetBinLabel(iLabel + 1, matchMethodLabels[iLabel].c_str()); } - createMatchingHistosMc(); + createMatchingHistos(); createDimuonHistos(); } @@ -1973,7 +1926,7 @@ struct QaMatching { return attempts; } - template + template void fillCollisions(EVT const& collisions, BC const& bcs, TMUON const& muonTracks, @@ -2009,8 +1962,10 @@ struct QaMatching { collisionInfo.bc = bc.globalBC(); collisionInfo.zVertex = collision.posZ(); - if (collisionInfo.matchablePairs.empty()) { - fillMatchablePairs(collisionInfo, muonTracks, mftTracks); + if constexpr ( isMC ) { + if (collisionInfo.matchablePairs.empty()) { + fillMatchablePairs(collisionInfo, muonTracks, mftTracks); + } } if (static_cast(muonTrack.trackType()) > GlobalTrackTypeMax) { @@ -2104,7 +2059,11 @@ struct QaMatching { candidate.matchRanking = ranking; candidate.matchRankingProd = ranking; - candidate.matchType = getMatchType(muonTrack, muonTracks, mftTracks, collisionInfo.matchablePairs, ranking); + if constexpr ( isMC ) { + candidate.matchType = getMatchType(muonTrack, muonTracks, mftTracks, collisionInfo.matchablePairs, ranking); + } else { + candidate.matchType = kMatchTypeUndefined; + } candidate.mftMchMatchAttempts = mftMchMatchAttempts; ranking += 1; } @@ -2112,6 +2071,37 @@ struct QaMatching { } } + template + void fillMatchingPlots(C const& collision, + TMUON const& muonTracks, + const MatchingCandidates& matchingCandidates, + MatchingPlotter* plotter) + { + // ==================================== + // Matching chi2 and score vs. production values + for (const auto& [mchIndex, globalTracksVector] : matchingCandidates) { + if (globalTracksVector.size() < 1) + continue; + + // loop over candidates + int candidateIndex = 1; + for (const auto& candidate : globalTracksVector) { + auto const& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); + + float matchScore = candidate.matchScore; + float matchChi2 = candidate.matchChi2; + + float matchChi2Prod = muonTrack.chi2MatchMCHMFT() / 5.f; + float matchScoreProd = chi2ToScore(muonTrack.chi2MatchMCHMFT(), 5, 50.f); + + std::get>(plotter->fMatchScoreVsProd)->Fill(matchScoreProd, matchScore); + std::get>(plotter->fMatchChi2VsProd)->Fill(matchChi2Prod, matchChi2); + + candidateIndex += 1; + } + } + } + template void fillMatchingPlotsMc(C const& collision, const CollisionInfo& collisionInfo, @@ -2341,13 +2331,10 @@ struct QaMatching { // get the standalone MCH and MFT tracks auto const& mchTrack = muonTracks.rawIteratorAt(mchIndex); - auto const& mftTrack = muonTrack.template matchMFTTrack_as(); // skip global muon tracks that do not pass the MCH and MFT quality cuts if (!isGoodGlobalMuon(mchTrack, collision)) continue; - if (!isGoodMft(mftTrack)) - continue; // skip candidates that do not pass the matching quality cuts if (!isGoodGlobalMatching(muonTrack, matchingScore, matchingScoreCut)) @@ -2363,9 +2350,9 @@ struct QaMatching { motherPDG = motherParticles[1].first; } // fill matching purity plots - plotter->fMatchingPurityPlotter.fill(mchTrack, isTrueMatch); + plotter->fMatchingPurityPlotter->fill(mchTrack, isTrueMatch); if (configQas.cfgCreatePdgMomHistograms) { - plotter->fMatchingPurityPlotter.fill(mchTrack, motherPDG, isTrueMatch); + plotter->fMatchingPurityPlotter->fill(mchTrack, motherPDG, isTrueMatch); } } @@ -2421,17 +2408,17 @@ struct QaMatching { } // fill matching efficiency plots - plotter->fPairingEfficiencyPlotter.fill(mchTrack, goodMatchFound); + plotter->fPairingEfficiencyPlotter->fill(mchTrack, goodMatchFound); if (configQas.cfgCreatePdgMomHistograms) { - plotter->fPairingEfficiencyPlotter.fill(mchTrack, motherPDG, goodMatchFound); + plotter->fPairingEfficiencyPlotter->fill(mchTrack, motherPDG, goodMatchFound); } - plotter->fMatchingEfficiencyPlotter.fill(mchTrack, (goodMatchFound && isTrueMatch)); + plotter->fMatchingEfficiencyPlotter->fill(mchTrack, (goodMatchFound && isTrueMatch)); if (configQas.cfgCreatePdgMomHistograms) { - plotter->fMatchingEfficiencyPlotter.fill(mchTrack, motherPDG, (goodMatchFound && isTrueMatch)); + plotter->fMatchingEfficiencyPlotter->fill(mchTrack, motherPDG, (goodMatchFound && isTrueMatch)); } - plotter->fFakeMatchingEfficiencyPlotter.fill(mchTrack, (goodMatchFound && !isTrueMatch)); + plotter->fFakeMatchingEfficiencyPlotter->fill(mchTrack, (goodMatchFound && !isTrueMatch)); if (configQas.cfgCreatePdgMomHistograms) { - plotter->fFakeMatchingEfficiencyPlotter.fill(mchTrack, motherPDG, (goodMatchFound && !isTrueMatch)); + plotter->fFakeMatchingEfficiencyPlotter->fill(mchTrack, motherPDG, (goodMatchFound && !isTrueMatch)); } } } @@ -2523,7 +2510,7 @@ struct QaMatching { } } - template + template void runChi2Matching(C const& collisions, BC const& bcs, TMUON const& muonTracks, @@ -2548,6 +2535,7 @@ struct QaMatching { auto matchingFunc = mMatchingFunctionMap.at(funcName); for (const auto& [mchIndex, globalTracksVector] : matchingCandidates) { + // get the MCH standalone track auto const& mchTrack = muonTracks.rawIteratorAt(mchIndex); for (const auto& candidate : globalTracksVector) { @@ -2557,11 +2545,9 @@ struct QaMatching { auto collision = collisions.rawIteratorAt(muonTrack.collisionId()); - // get MCH and MFT standalone tracks - // auto mchTrack = muonTrack.template matchMCHTrack_as(); + // get the MFT standalone track auto const& mftTrack = muonTrack.template matchMFTTrack_as(); if (mftTrackCovs.count(mftTrack.globalIndex()) < 1) { - // std::cout << std::format("Covariance matrix for MFT track #{} not found", mftTrack.globalIndex()) << std::endl; continue; } auto const& mftTrackCov = mftCovs.rawIteratorAt(mftTrackCovs[mftTrack.globalIndex()]); @@ -2630,14 +2616,18 @@ struct QaMatching { const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); candidate.matchRanking = ranking; - candidate.matchType = getMatchType(muonTrack, muonTracks, mftTracks, matchablePairs, ranking); + if constexpr ( isMC ) { + candidate.matchType = getMatchType(muonTrack, muonTracks, mftTracks, matchablePairs, ranking); + } else { + candidate.matchType = kMatchTypeUndefined; + } candidate.mftMchMatchAttempts = mftMchMatchAttempts; ranking += 1; } } } - template + template void runChi2Matching(C const& collisions, BC const& bcs, TMUON const& muonTracks, @@ -2668,10 +2658,10 @@ struct QaMatching { auto matchingPlaneZ = matchingPlanesZ[label]; auto extrapMethod = matchingExtrapMethod[label]; - runChi2Matching(collisions, bcs, muonTracks, mftTracks, mftCovs, funcName, matchingPlaneZ, extrapMethod, matchablePairs, matchingCandidates, newMatchingCandidates); + runChi2Matching(collisions, bcs, muonTracks, mftTracks, mftCovs, funcName, matchingPlaneZ, extrapMethod, matchablePairs, matchingCandidates, newMatchingCandidates); } - template + template void runMlMatching(C const& collisions, BC const& bcs, TMUON const& muonTracks, @@ -2700,12 +2690,9 @@ struct QaMatching { // get MFT standalone track auto const& mftTrack = muonTrack.template matchMFTTrack_as(); if (mftTrackCovs.count(mftTrack.globalIndex()) < 1) { - // std::cout << std::format("Covariance matrix for MFT track #{} not found", mftTrack.globalIndex()) << std::endl; continue; } - // std::cout << fmt::format("Getting covariance matrix for MFT track #{} -> {}", mftTrack.globalIndex(), mftTrackCovs[mftTrack.globalIndex()]) << std::endl; auto const& mftTrackCov = mftCovs.rawIteratorAt(mftTrackCovs[mftTrack.globalIndex()]); - // std::cout << fmt::format("Covariance matrix for MFT track #{} retrieved", mftTrack.globalIndex()) << std::endl; // get tracks parameters in O2 format auto mftTrackProp = fwdToTrackPar(mftTrack, mftTrackCov); @@ -2725,7 +2712,6 @@ struct QaMatching { float matchScore = output[0]; float matchChi2Prod = muonTrack.chi2MatchMCHMFT() / MatchingDegreesOfFreedom; float matchScoreProd = chi2ToScore(muonTrack.chi2MatchMCHMFT(), MatchingDegreesOfFreedom, MatchingScoreChi2Max); - // std::cout << std::format("Matching score: {}, Chi2: {}", matchingScore, muonTrack.chi2MatchMCHMFT()) << std::endl; // check if a vector of global muon candidates is already available for the current MCH index // if not, initialize a new one and add the current global muon track @@ -2775,20 +2761,24 @@ struct QaMatching { const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); candidate.matchRanking = ranking; - candidate.matchType = getMatchType(muonTrack, muonTracks, mftTracks, matchablePairs, ranking); + if constexpr ( isMC ) { + candidate.matchType = getMatchType(muonTrack, muonTracks, mftTracks, matchablePairs, ranking); + } else { + candidate.matchType = kMatchTypeUndefined; + } candidate.mftMchMatchAttempts = mftMchMatchAttempts; ranking += 1; } } } - template - void processCollisionMc(const CollisionInfo& collisionInfo, - C const& collisions, - BC const& bcs, - TMUON const& muonTracks, - TMFT const& mftTracks, - CMFT const& mftCovs) + template + void processCollision(const CollisionInfo& collisionInfo, + C const& collisions, + BC const& bcs, + TMUON const& muonTracks, + TMFT const& mftTracks, + CMFT const& mftCovs) { auto collision = collisions.rawIteratorAt(collisionInfo.index); @@ -2807,7 +2797,11 @@ struct QaMatching { //------------------------------- // 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); + if constexpr (isMC) { + fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, collisionInfo.matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, cfgMatchingChi2ScoreMftMchLow, fChi2MatchingPlotter.get(), false); + } else { + fillMatchingPlots(collision, muonTracks, collisionInfo.matchingCandidates, fChi2MatchingPlotter.get()); + } //------------------------------- // Tagged muons @@ -2840,35 +2834,46 @@ struct QaMatching { 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()); + if constexpr (isMC) { + fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, taggedMatchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, cfgMatchingChi2ScoreMftMchLow, fTaggedMuonsMatchingPlotter.get()); + } else { + fillMatchingPlots(collision, muonTracks, taggedMatchingCandidates, 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); + 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); + if constexpr (isMC) { + fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter, false); + } else { + fillMatchingPlots(collision, muonTracks, matchingCandidates, plotter); + } } - // ML-based matching analysis + //------------------------------- + // Custom ML-based matching methods for (const auto& [label, mlResponse] : matchingMlResponses) { MatchingCandidates matchingCandidates; - runMlMatching(collisions, bcs, muonTracks, mftTracks, mftCovs, label, collisionInfo.matchablePairs, collisionInfo.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); + if constexpr (isMC) { + fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter); + } else { + fillMatchingPlots(collision, muonTracks, matchingCandidates, plotter); + } } //------------------------------- @@ -3005,14 +3010,41 @@ struct QaMatching { mftTrackCovs[mftTrackCov.matchMFTTrackId()] = mftTrackCov.globalIndex(); } - fillCollisions(collisions, bcs, muonTracks, mftTracks, fCollisionInfos); + fillCollisions(collisions, bcs, muonTracks, mftTracks, fCollisionInfos); for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) { - processCollisionMc(collisionInfo, collisions, bcs, muonTracks, mftTracks, mftCovs); + processCollision(collisionInfo, collisions, bcs, muonTracks, mftTracks, mftCovs); } } PROCESS_SWITCH(QaMatching, processQAMC, "processQAMC", true); + + void processQA(MyEvents const& collisions, + aod::BCsWithTimestamps const& bcs, + MyMuons const& muonTracks, + MyMFTs const& mftTracks, + MyMFTCovariances const& mftCovs) + { + auto bc = bcs.begin(); + initCcdb(bc); + + for (const auto& muon : muonTracks) { + registry.get(HIST("nTracksPerType"))->Fill(static_cast(muon.trackType())); + } + + mftTrackCovs.clear(); + for (const auto& mftTrackCov : mftCovs) { + mftTrackCovs[mftTrackCov.matchMFTTrackId()] = mftTrackCov.globalIndex(); + } + + fillCollisions(collisions, bcs, muonTracks, mftTracks, fCollisionInfos); + + for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) { + processCollision(collisionInfo, collisions, bcs, muonTracks, mftTracks, mftCovs); + } + } + + PROCESS_SWITCH(QaMatching, processQA, "processQA", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From ef14ae5f650bc0dd67b178d57ddc33ced76e8827 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Fri, 22 May 2026 20:56:14 +0200 Subject: [PATCH 2/5] [PWGDQ] add histograms of MFT-MCH match features in QA task --- PWGDQ/Tasks/qaMatching.cxx | 149 +++++++++++++++++++++++++++++++++---- 1 file changed, 135 insertions(+), 14 deletions(-) diff --git a/PWGDQ/Tasks/qaMatching.cxx b/PWGDQ/Tasks/qaMatching.cxx index 7636cfce9b7..0ce4d9e4523 100644 --- a/PWGDQ/Tasks/qaMatching.cxx +++ b/PWGDQ/Tasks/qaMatching.cxx @@ -184,7 +184,7 @@ static float chi2ToScore(float chi2, int ndf, float chi2max) return static_cast(result); } -static void SetMatchTypeAxisLabels(TAxis* axis) +static void setMatchTypeAxisLabels(TAxis* axis) { axis->SetBinLabel(1, "true (leading)"); axis->SetBinLabel(2, "wrong (leading)"); @@ -230,12 +230,15 @@ struct QaMatching { static constexpr int ExtrapolationMethodVertex = 3; static constexpr int ExtrapolationMethodMftDca = 4; static constexpr int DecayRankingDirect = 2; + static constexpr float MatchingPlaneDefaultZ = -77.5; struct MatchingCandidate { int64_t collisionId{-1}; int64_t globalTrackId{-1}; int64_t muonTrackId{-1}; int64_t mftTrackId{-1}; + o2::track::TrackParCovFwd mftTrackProp; + o2::track::TrackParCovFwd mchTrackProp; double matchScore{-1}; double matchChi2{-1}; int matchRanking{-1}; @@ -649,6 +652,42 @@ struct QaMatching { } }; + struct MatchFeaturesHistos { + o2::framework::HistPtr hDeltaP; + o2::framework::HistPtr hDeltaPt; + o2::framework::HistPtr hDeltaX; + o2::framework::HistPtr hDeltaY; + o2::framework::HistPtr hDeltaPhi; + o2::framework::HistPtr hDeltaTanl; + o2::framework::HistPtr hDeltaEta; + o2::framework::HistPtr hRabs; + + MatchFeaturesHistos(std::string path, HistogramRegistry* registry, int numCandidates) + { + AxisSpec indexAxis = {numCandidates + 1, 0, static_cast(numCandidates + 1), "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 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}}); + } + }; + struct MatchRankingHistos { o2::framework::HistPtr hist; o2::framework::HistPtr histVsP; @@ -695,6 +734,8 @@ struct QaMatching { std::unique_ptr fMatchRankingPaired; std::unique_ptr fMatchRankingPairedGoodMCH; + std::unique_ptr fMatchFeaturesGoodMCH; + //- o2::framework::HistPtr fMissedMatches; o2::framework::HistPtr fMissedMatchesGoodMCH; @@ -757,6 +798,8 @@ struct QaMatching { std::string histName; std::string histTitle; + fMatchFeaturesGoodMCH = std::make_unique(path + "matchFeaturesGoodMCH", registry, numCandidates); + if (isMc) { fMatchRanking = std::make_unique(path + "matchRanking", "True match ranking", registry, mftMultMax, numCandidates); fMatchRankingGoodMCH = std::make_unique(path + "matchRankingGoodMCH", "True match ranking (good MCH tracks)", registry, mftMultMax, numCandidates); @@ -808,41 +851,41 @@ struct QaMatching { histName = path + "matchType"; histTitle = "Match type"; fMatchType = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {matchTypeAxis}}); - SetMatchTypeAxisLabels(std::get>(fMatchType)->GetXaxis()); + setMatchTypeAxisLabels(std::get>(fMatchType)->GetXaxis()); histName = path + "matchTypeVsP"; histTitle = "Match type vs. p"; fMatchTypeVsP = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {pAxis, matchTypeAxis}}); - SetMatchTypeAxisLabels(std::get>(fMatchTypeVsP)->GetYaxis()); + setMatchTypeAxisLabels(std::get>(fMatchTypeVsP)->GetYaxis()); histName = path + "matchTypeVsPt"; histTitle = "Match type vs. p_{T}"; fMatchTypeVsPt = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {ptAxis, matchTypeAxis}}); - SetMatchTypeAxisLabels(std::get>(fMatchTypeVsPt)->GetYaxis()); + setMatchTypeAxisLabels(std::get>(fMatchTypeVsPt)->GetYaxis()); histName = path + "matchChi2VsType"; histTitle = "Match #chi^{2} vs. match type"; fMatchChi2VsType = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {matchTypeAxis, chi2Axis}}); - SetMatchTypeAxisLabels(std::get>(fMatchChi2VsType)->GetXaxis()); + setMatchTypeAxisLabels(std::get>(fMatchChi2VsType)->GetXaxis()); histName = path + "matchChi2VsTypeVsP"; histTitle = "Match #chi^{2} vs. match type vs. p"; fMatchChi2VsTypeVsP = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH3F, {pAxis, matchTypeAxis, chi2Axis}}); - SetMatchTypeAxisLabels(std::get>(fMatchChi2VsTypeVsP)->GetYaxis()); + setMatchTypeAxisLabels(std::get>(fMatchChi2VsTypeVsP)->GetYaxis()); histName = path + "matchChi2VsTypeVsPt"; histTitle = "Match #chi^{2} vs. match type vs. p_{T}"; fMatchChi2VsTypeVsPt = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH3F, {ptAxis, matchTypeAxis, chi2Axis}}); - SetMatchTypeAxisLabels(std::get>(fMatchChi2VsTypeVsPt)->GetYaxis()); + setMatchTypeAxisLabels(std::get>(fMatchChi2VsTypeVsPt)->GetYaxis()); //- histName = path + "matchScoreVsType"; histTitle = "Match score vs. match type"; fMatchScoreVsType = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH2F, {matchTypeAxis, scoreAxis}}); - SetMatchTypeAxisLabels(std::get>(fMatchScoreVsType)->GetXaxis()); + setMatchTypeAxisLabels(std::get>(fMatchScoreVsType)->GetXaxis()); histName = path + "matchScoreVsTypeVsP"; histTitle = "Match score vs. match type vs. p"; fMatchScoreVsTypeVsP = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH3F, {pAxis, matchTypeAxis, scoreAxis}}); - SetMatchTypeAxisLabels(std::get>(fMatchScoreVsTypeVsP)->GetYaxis()); + setMatchTypeAxisLabels(std::get>(fMatchScoreVsTypeVsP)->GetYaxis()); histName = path + "matchScoreVsTypeVsPt"; histTitle = "Match score vs. match type vs. p_{T}"; fMatchScoreVsTypeVsPt = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH3F, {ptAxis, matchTypeAxis, scoreAxis}}); - SetMatchTypeAxisLabels(std::get>(fMatchScoreVsTypeVsPt)->GetYaxis()); + setMatchTypeAxisLabels(std::get>(fMatchScoreVsTypeVsPt)->GetYaxis()); } AxisSpec prodScoreAxis = {100, 0, 1, "matching score (prod)"}; @@ -909,8 +952,6 @@ struct QaMatching { AxisSpec phiAxis = {90, -180, 180, "#phi (degrees)"}; std::string histPath = cfgIsMc.value ? "matching/MC/" : "matching/"; - std::cout << std::format("TOTO cfgIsMc: {}", cfgIsMc.value) << std::endl; - AxisSpec trackPositionXAtMftAxis = {100, -15, 15, "MFT x (cm)"}; AxisSpec trackPositionYAtMftAxis = {100, -15, 15, "MFT y (cm)"}; registry.add((histPath + "pairedMCHTracksAtMFT").c_str(), "Paired MCH tracks position at MFT end", {HistType::kTH2F, {trackPositionXAtMftAxis, trackPositionYAtMftAxis}}); @@ -1931,6 +1972,7 @@ struct QaMatching { BC const& bcs, TMUON const& muonTracks, TMFT const& mftTracks, + MyMFTCovariances const& mftCovs, CollisionInfos& collisionInfos) { collisionInfos.clear(); @@ -1982,6 +2024,18 @@ struct QaMatching { auto const& mftTrack = muonTrack.template matchMFTTrack_as(); int64_t mftTrackIndex = mftTrack.globalIndex(); + // get MFT track covariances + if (mftTrackCovs.count(mftTrack.globalIndex()) < 1) { + continue; + } + auto const& mftTrackCov = mftCovs.rawIteratorAt(mftTrackCovs[mftTrack.globalIndex()]); + + // propagate MCH and MFT tracks to matching plane + auto mchTrackProp = fwdToTrackPar(mchTrack, mchTrack); + mchTrackProp = propagateToMatchingPlaneMch(mchTrack, mftTrack, mftTrackCov, collision, MatchingPlaneDefaultZ, 0); + auto mftTrackProp = fwdToTrackPar(mftTrack, mftTrackCov); + mftTrackProp = propagateToMatchingPlaneMft(mchTrack, mftTrack, mftTrackCov, collision, MatchingPlaneDefaultZ, 0); + // check if a vector of global muon candidates is already available for the current MCH index // if not, initialize a new one and add the current global muon track // bool globalMuonTrackFound = false; @@ -1992,6 +2046,8 @@ struct QaMatching { muonTrackIndex, mchTrackIndex, mftTrackIndex, + mftTrackProp, + mchTrackProp, matchScore, matchChi2, -1, @@ -2006,6 +2062,8 @@ struct QaMatching { muonTrackIndex, mchTrackIndex, mftTrackIndex, + mftTrackProp, + mchTrackProp, matchScore, matchChi2, -1, @@ -2077,6 +2135,39 @@ struct QaMatching { const MatchingCandidates& matchingCandidates, MatchingPlotter* plotter) { + // ==================================== + // Matching properties + for (const auto& [mchIndex, globalTracksVector] : matchingCandidates) { + if (globalTracksVector.size() < 1) + continue; + + // get the standalone MCH track + auto const& mchTrack = muonTracks.rawIteratorAt(mchIndex); + + // skip global muon tracks that do not pass the MCH and MFT quality cuts + if (!isGoodGlobalMuon(mchTrack, collision)) + continue; + + for (const auto& candidate : globalTracksVector) { + double dp = candidate.mchTrackProp.getP() - candidate.mftTrackProp.getP(); + double dpt = candidate.mchTrackProp.getPt() - candidate.mftTrackProp.getPt(); + double dx = candidate.mchTrackProp.getX() - candidate.mftTrackProp.getX(); + double dy = candidate.mchTrackProp.getY() - candidate.mftTrackProp.getY(); + double dphi = candidate.mchTrackProp.getPhi() - candidate.mftTrackProp.getPhi(); + 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); + } + } + // ==================================== // Matching chi2 and score vs. production values for (const auto& [mchIndex, globalTracksVector] : matchingCandidates) { @@ -2206,6 +2297,28 @@ struct QaMatching { std::get>(plotter->fMatchRankingPairedGoodMCH->histVsDeltaChi2)->Fill(dchi2, trueMatchIndex); } + if (isGoodMCH) { + for (const auto& candidate : globalTracksVector) { + double dp = candidate.mchTrackProp.getP() - candidate.mftTrackProp.getP(); + double dpt = candidate.mchTrackProp.getPt() - candidate.mftTrackProp.getPt(); + double dx = candidate.mchTrackProp.getX() - candidate.mftTrackProp.getX(); + double dy = candidate.mchTrackProp.getY() - candidate.mftTrackProp.getY(); + double dphi = candidate.mchTrackProp.getPhi() - candidate.mftTrackProp.getPhi(); + 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(deta, candidate.matchScore, candidate.matchRanking, matchType); + std::get>(plotter->fMatchFeaturesGoodMCH->hRabs)->Fill(mchTrack.rAtAbsorberEnd(), candidate.matchScore, candidate.matchRanking, matchType); + } + } + if (trueMatchIndex == 0) { // missed matches if (!isPairedMCH) { @@ -2577,6 +2690,8 @@ struct QaMatching { candidate.globalTrackId, mchIndex, mftTrack.globalIndex(), + mftTrackProp, + mchTrackProp, matchScore, matchChi2, -1, @@ -2590,6 +2705,8 @@ struct QaMatching { candidate.globalTrackId, mchIndex, mftTrack.globalIndex(), + mftTrackProp, + mchTrackProp, matchScore, matchChi2, -1, @@ -2722,6 +2839,8 @@ struct QaMatching { candidate.globalTrackId, mchIndex, mftTrack.globalIndex(), + mftTrackProp, + mchTrackProp, matchScore, -1, -1, @@ -2735,6 +2854,8 @@ struct QaMatching { candidate.globalTrackId, mchIndex, mftTrack.globalIndex(), + mftTrackProp, + mchTrackProp, matchScore, -1, -1, @@ -3010,7 +3131,7 @@ struct QaMatching { mftTrackCovs[mftTrackCov.matchMFTTrackId()] = mftTrackCov.globalIndex(); } - fillCollisions(collisions, bcs, muonTracks, mftTracks, fCollisionInfos); + fillCollisions(collisions, bcs, muonTracks, mftTracks, mftCovs, fCollisionInfos); for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) { processCollision(collisionInfo, collisions, bcs, muonTracks, mftTracks, mftCovs); @@ -3037,7 +3158,7 @@ struct QaMatching { mftTrackCovs[mftTrackCov.matchMFTTrackId()] = mftTrackCov.globalIndex(); } - fillCollisions(collisions, bcs, muonTracks, mftTracks, fCollisionInfos); + fillCollisions(collisions, bcs, muonTracks, mftTracks, mftCovs, fCollisionInfos); for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) { processCollision(collisionInfo, collisions, bcs, muonTracks, mftTracks, mftCovs); From 276b990633ab9b3ecbf2fd49edf984b3683cc732 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Fri, 22 May 2026 21:08:40 +0200 Subject: [PATCH 3/5] [PWGDQ] added match chi2 column to QA derived tables --- PWGDQ/Tasks/qaMatching.cxx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/PWGDQ/Tasks/qaMatching.cxx b/PWGDQ/Tasks/qaMatching.cxx index 0ce4d9e4523..0257af0a15e 100644 --- a/PWGDQ/Tasks/qaMatching.cxx +++ b/PWGDQ/Tasks/qaMatching.cxx @@ -95,6 +95,7 @@ DECLARE_SOA_COLUMN(Phi, phi, float); DECLARE_SOA_COLUMN(MatchLabel, matchLabel, int8_t); DECLARE_SOA_COLUMN(TrackId, trackId, int64_t); DECLARE_SOA_COLUMN(MatchType, matchType, int8_t); +DECLARE_SOA_COLUMN(MatchChi2, matchChi2, float); DECLARE_SOA_COLUMN(MatchScore, matchScore, float); DECLARE_SOA_COLUMN(MatchRanking, matchRanking, int32_t); DECLARE_SOA_COLUMN(MftMultiplicity, mftMultiplicity, int32_t); @@ -152,7 +153,7 @@ DECLARE_SOA_TABLE(QaMatchingCandidates, "AOD", "QAMCAND", qamatching::MatchLabel, qamatching::TrackId, qamatching::P, qamatching::Pt, qamatching::Eta, qamatching::Phi, - qamatching::MatchType, qamatching::MatchScore, qamatching::MatchRanking, + qamatching::MatchType, qamatching::MatchChi2, qamatching::MatchScore, qamatching::MatchRanking, qamatching::XAtVtx, qamatching::YAtVtx, qamatching::ZAtVtx, @@ -2004,7 +2005,7 @@ struct QaMatching { collisionInfo.bc = bc.globalBC(); collisionInfo.zVertex = collision.posZ(); - if constexpr ( isMC ) { + if constexpr (isMC) { if (collisionInfo.matchablePairs.empty()) { fillMatchablePairs(collisionInfo, muonTracks, mftTracks); } @@ -2117,7 +2118,7 @@ struct QaMatching { candidate.matchRanking = ranking; candidate.matchRankingProd = ranking; - if constexpr ( isMC ) { + if constexpr (isMC) { candidate.matchType = getMatchType(muonTrack, muonTracks, mftTracks, collisionInfo.matchablePairs, ranking); } else { candidate.matchType = kMatchTypeUndefined; @@ -2733,7 +2734,7 @@ struct QaMatching { const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); candidate.matchRanking = ranking; - if constexpr ( isMC ) { + if constexpr (isMC) { candidate.matchType = getMatchType(muonTrack, muonTracks, mftTracks, matchablePairs, ranking); } else { candidate.matchType = kMatchTypeUndefined; @@ -2882,7 +2883,7 @@ struct QaMatching { const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); candidate.matchRanking = ranking; - if constexpr ( isMC ) { + if constexpr (isMC) { candidate.matchType = getMatchType(muonTrack, muonTracks, mftTracks, matchablePairs, ranking); } else { candidate.matchType = kMatchTypeUndefined; @@ -3031,6 +3032,7 @@ struct QaMatching { static_cast(candidateTrack.eta()), static_cast(candidateTrack.phi()), static_cast(candidate.matchType), + static_cast(candidate.matchChi2), static_cast(candidate.matchScore), static_cast(candidate.matchRanking), static_cast(candidateTrackAtVertex.getX()), From 92cbbb3718d2fb7936777e63f9f29bbb4e3fb84a Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Fri, 22 May 2026 21:19:10 +0200 Subject: [PATCH 4/5] [PWGDQ] removed duplicated histo filling --- PWGDQ/Tasks/qaMatching.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/PWGDQ/Tasks/qaMatching.cxx b/PWGDQ/Tasks/qaMatching.cxx index 0257af0a15e..7bd36b15772 100644 --- a/PWGDQ/Tasks/qaMatching.cxx +++ b/PWGDQ/Tasks/qaMatching.cxx @@ -2315,7 +2315,6 @@ struct QaMatching { 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(deta, candidate.matchScore, candidate.matchRanking, matchType); std::get>(plotter->fMatchFeaturesGoodMCH->hRabs)->Fill(mchTrack.rAtAbsorberEnd(), candidate.matchScore, candidate.matchRanking, matchType); } } From 8defcb5651966c9de703b3e1ca33334060f6c300 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Fri, 22 May 2026 22:35:49 +0200 Subject: [PATCH 5/5] [PWGDQ] fixed build error --- PWGDQ/Tasks/qaMatching.cxx | 3 --- 1 file changed, 3 deletions(-) diff --git a/PWGDQ/Tasks/qaMatching.cxx b/PWGDQ/Tasks/qaMatching.cxx index 7bd36b15772..5da0840fcc2 100644 --- a/PWGDQ/Tasks/qaMatching.cxx +++ b/PWGDQ/Tasks/qaMatching.cxx @@ -2176,7 +2176,6 @@ struct QaMatching { continue; // loop over candidates - int candidateIndex = 1; for (const auto& candidate : globalTracksVector) { auto const& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); @@ -2188,8 +2187,6 @@ struct QaMatching { std::get>(plotter->fMatchScoreVsProd)->Fill(matchScoreProd, matchScore); std::get>(plotter->fMatchChi2VsProd)->Fill(matchChi2Prod, matchChi2); - - candidateIndex += 1; } } }