From e34845762a60a93c883fc888cc518157ac26c0cc Mon Sep 17 00:00:00 2001 From: Gyula Bencedi Date: Mon, 13 Oct 2025 19:41:26 +0200 Subject: [PATCH] Add more efficiency histos for reassociation --- PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx | 574 +++++++++++++++++++++++------ 1 file changed, 471 insertions(+), 103 deletions(-) diff --git a/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx b/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx index 85dd80b7bf8..20be3691600 100644 --- a/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx +++ b/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx @@ -85,9 +85,21 @@ enum TrkBestSel { nTrkBestSel }; +enum AmbTrkType { + kNonAmb = 0, + kOrphan = 1, + kNonAmbSame = 2, + kAmb = 3, + kAmbGt1 = 4, + nAmbTrkType +}; + struct DndetaMFTPbPb { SliceCache cache; + std::array, 4> hCollAssoc; + std::array, 4> hReAssoc; + enum OccupancyEst { TrkITS = 1, Ft0C }; @@ -108,6 +120,7 @@ struct DndetaMFTPbPb { Configurable cfgIRSource{"cfgIRSource", "ZNC hadronic", "Estimator of the interaction rate (Pb-Pb: ZNC hadronic)"}; Configurable cfgUseTrackSel{"cfgUseTrackSel", false, "Flag to apply track selection"}; Configurable cfgUseParticleSel{"cfgUseParticleSel", false, "Flag to apply particle selection"}; + Configurable cfgRemoveTrivialAssoc{"cfgRemoveTrivialAssoc", false, "Skip trivial associations"}; struct : ConfigurableGroup { ConfigurableAxis interactionRateBins{"interactionRateBins", {500, 0, 50}, "Binning for the interaction rate (kHz)"}; @@ -121,7 +134,7 @@ struct DndetaMFTPbPb { ConfigurableAxis ptBins{"ptBins", {101, -0.5, 10.5}, "pT binning (GeV/c)"}; ConfigurableAxis multBins{"multBins", {701, -0.5, 700.5}, "Multiplicity binning"}; ConfigurableAxis zvtxBins{"zvtxBins", {60, -30., 30.}, "Z-vtx binning (cm)"}; - ConfigurableAxis deltaZBins{"deltaZBins", {120, -6., 6.}, "Delta Z-vtx binning (cm)"}; + ConfigurableAxis deltaZBins{"deltaZBins", {800, -10., 10.}, "Delta Z-vtx binning (cm)"}; ConfigurableAxis dcaXYBins{"dcaXYBins", {800, -1., 1.}, "DCAxy binning (cm)"}; ConfigurableAxis dcaZBins{"dcaZBins", {800, -1., 1.}, "DCAz binning (cm)"}; ConfigurableAxis phiBins{"phiBins", {629, 0., TwoPI}, "#varphi binning (rad)"}; @@ -397,6 +410,22 @@ struct DndetaMFTPbPb { {"Tracks/ReTracksPhiEta", "; #varphi; #eta; occupancy", {HistType::kTHnSparseF, {phiAxis, etaAxis, occupancyAxis}}}); + qaregistry.add( + {"Tracks/OrigTracksEtaZvtx", + "; #eta; #it{z}_{vtx} (cm); occupancy", + {HistType::kTHnSparseF, {etaAxis, zAxis, occupancyAxis}}}); + qaregistry.add( + {"Tracks/OrigTracksPhiEta", + "; #varphi; #eta; occupancy", + {HistType::kTHnSparseF, {phiAxis, etaAxis, occupancyAxis}}}); + qaregistry.add( + {"Tracks/RestTracksEtaZvtx", + "; #eta; #it{z}_{vtx} (cm); occupancy", + {HistType::kTHnSparseF, {etaAxis, zAxis, occupancyAxis}}}); + qaregistry.add( + {"Tracks/RestTracksPhiEta", + "; #varphi; #eta; occupancy", + {HistType::kTHnSparseF, {phiAxis, etaAxis, occupancyAxis}}}); qaregistry.add({"Tracks/TrackAmbDegree", "; N_{coll}^{comp}; occupancy", {HistType::kTH2F, {{51, -0.5, 50.5}, occupancyAxis}}}); @@ -519,6 +548,22 @@ struct DndetaMFTPbPb { "; #varphi; #eta; occupancy", {HistType::kTHnSparseF, {phiAxis, etaAxis, centralityAxis, occupancyAxis}}}); + qaregistry.add({"Tracks/Centrality/OrigTracksEtaZvtx", + "; #eta; #it{z}_{vtx} (cm); occupancy", + {HistType::kTHnSparseF, + {etaAxis, zAxis, centralityAxis, occupancyAxis}}}); + qaregistry.add({"Tracks/Centrality/OrigTracksPhiEta", + "; #varphi; #eta; occupancy", + {HistType::kTHnSparseF, + {phiAxis, etaAxis, centralityAxis, occupancyAxis}}}); + qaregistry.add({"Tracks/Centrality/RestTracksEtaZvtx", + "; #eta; #it{z}_{vtx} (cm); occupancy", + {HistType::kTHnSparseF, + {etaAxis, zAxis, centralityAxis, occupancyAxis}}}); + qaregistry.add({"Tracks/Centrality/RestTracksPhiEta", + "; #varphi; #eta; occupancy", + {HistType::kTHnSparseF, + {phiAxis, etaAxis, centralityAxis, occupancyAxis}}}); } } @@ -618,6 +663,64 @@ struct DndetaMFTPbPb { {HistType::kTHnSparseF, {multAxis, zAxis, centralityAxis}}}); } + if (doprocessTrkEffIdxBestInlusive) { + qaregistry.add({"Tracks/hPtEtaEffGenBest", + "; p_{T} (GeV/c); #eta", + {HistType::kTH2F, + {ptAxis, etaAxis}}}); + qaregistry.add({"Tracks/hPtEtaEffPrimBest", + "; p_{T} (GeV/c); #eta", + {HistType::kTH2F, + {ptAxis, etaAxis}}}); + qaregistry.add({"Tracks/hPtEtaEffSecBest", + "; p_{T} (GeV/c); #eta", + {HistType::kTH2F, + {ptAxis, etaAxis}}}); + qaregistry.add({"Tracks/hPtEtaEffGenDuplBest", + "; p_{T} (GeV/c); #eta", + {HistType::kTH2F, + {ptAxis, etaAxis}}}); + qaregistry.add({"Tracks/hPtEtaEffDuplBest", + "; p_{T} (GeV/c); #eta", + {HistType::kTH2F, + {ptAxis, etaAxis}}}); + qaregistry.add({"Tracks/NmftTrkPerPartBest", + "; #it{N}_{mft tracks per particle}", + {HistType::kTH1F, {multAxis}}}); + } + + if (doprocessTrkEffIdxBestCentFT0C) { + qaregistry.add( + {"Tracks/Centrality/hPtEtaEffGenBest", + "; p_{T} (GeV/c); #eta; centrality", + {HistType::kTHnSparseF, + {ptAxis, etaAxis, centralityAxis}}}); + qaregistry.add( + {"Tracks/Centrality/hPtEtaEffPrimBest", + "; p_{T} (GeV/c); #eta; centrality", + {HistType::kTHnSparseF, + {ptAxis, etaAxis, centralityAxis}}}); + qaregistry.add( + {"Tracks/Centrality/hPtEtaEffSecBest", + "; p_{T} (GeV/c); #eta; Z_{vtx} (cm)", + {HistType::kTHnSparseF, + {ptAxis, etaAxis, centralityAxis}}}); + qaregistry.add( + {"Tracks/Centrality/hPtEtaEffGenDuplBest", + "; p_{T} (GeV/c); #eta; centrality", + {HistType::kTHnSparseF, + {ptAxis, etaAxis, centralityAxis}}}); + qaregistry.add( + {"Tracks/Centrality/hPtEtaEffDuplBest", + "; p_{T} (GeV/c); #eta; centrality", + {HistType::kTHnSparseF, + {ptAxis, etaAxis, centralityAxis}}}); + qaregistry.add( + {"Tracks/Centrality/NmftTrkPerPartBest", + "; #it{N}_{mft tracks per particle}; centrality", + {HistType::kTHnSparseF, {multAxis, centralityAxis}}}); + } + if (doprocessTrkEffIdxInlusive) { qaregistry.add({"Tracks/hPtEtaEffGen", "; p_{T} (GeV/c); #eta; occupancy", @@ -743,36 +846,71 @@ struct DndetaMFTPbPb { {{100, 0., 1.}, centralityAxis, occupancyAxis}}}); } - if (doprocessCheckAmbiguousMftTracksInclusive) { + if (doprocessCheckAmbiguousMftTracks) { qaregistry.add({"Tracks/hMftTracksAmbDegree", " ; N_{coll}^{comp}", {HistType::kTH1F, {{41, -0.5, 40.5}}}}); - qaregistry.add({"Tracks/hMftTracksAmbDegreeWoTrivial", + qaregistry.add({"Tracks/hMftTracksAmbDegreeWithTrivial", " ; N_{coll}^{comp}", {HistType::kTH1F, {{41, -0.5, 40.5}}}}); - qaregistry.add({"Tracks/hAmbTrackType", - " ; Ambiguous track type; occupancy", - {HistType::kTH1F, {{5, -0.5, 4.5}}}}); - qaregistry.add({"Tracks/histAmbZvtx", - "#it{z}_{vtx} of collisions associated to a " - "track;#it{z}_{vtx} (cm);", - {HistType::kTH1F, {zAxis}}}); - } - - if (doprocessCheckAmbiguousMftTracksCentFT0C) { - qaregistry.add({"Tracks/Centrality/hMftTracksAmbDegree", - " ; N_{coll}^{comp}; centrality", - {HistType::kTH2F, - {{41, -0.5, 40.5}, centralityAxis}}}); - qaregistry.add({"Tracks/Centrality/hMftTracksAmbDegreeWoTrivial", - " ; N_{coll}^{comp}; centrality", - {HistType::kTH2F, - {{41, -0.5, 40.5}, centralityAxis}}}); - qaregistry.add({"Tracks/Centrality/hAmbTrackType", - " ; Ambiguous track type; centrality", - {HistType::kTH2F, - {{5, -0.5, 4.5}, centralityAxis}}}); - } + // qaregistry.add({"Tracks/hAmbTrackType", + // " ; Ambiguous track type", + // {HistType::kTH1F, {{5, -0.5, 4.5}}}}); + + qaregistry.add("Tracks/hAmbTrackType", "hAmbTrackType", {HistType::kTH1F, {{AmbTrkType::nAmbTrkType, -0.5, +AmbTrkType::nAmbTrkType - 0.5}}}); + std::string labelAmbiguity[AmbTrkType::nAmbTrkType]; + labelAmbiguity[AmbTrkType::kOrphan] = "orphan"; + labelAmbiguity[AmbTrkType::kNonAmb] = "nonAmbiguous"; + labelAmbiguity[AmbTrkType::kNonAmbSame] = "trkInCollTabHasSameAssoc"; + labelAmbiguity[AmbTrkType::kAmb] = "trkInCollTabHasDiffAssoc"; + labelAmbiguity[AmbTrkType::kAmbGt1] = "trkInCollTabHasGt1Assoc"; + qaregistry.get(HIST("Tracks/hAmbTrackType"))->SetMinimum(0.1); + + for (int iBin = 0; iBin < AmbTrkType::nAmbTrkType; iBin++) { + qaregistry.get(HIST("Tracks/hAmbTrackType"))->GetXaxis()->SetBinLabel(iBin + 1, labelAmbiguity[iBin].data()); + } + } + + if (doprocessCollAssocMC) { + // tracks not associated to any collision + hCollAssoc[0] = qaregistry.add("TrackToColl/hNonAssocTracks", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis}); + // tracks associasted to a collision + hCollAssoc[1] = qaregistry.add("TrackToColl/hAssocTracks", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis}); + // tracks associated to the correct collision considering only first reco collision (based on the MC collision index) + hCollAssoc[2] = qaregistry.add("TrackToColl/hGoodAssocTracks", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis}); + // tracks associated to the correct collision considering all ambiguous reco collisions (based on the MC collision index) + hCollAssoc[3] = qaregistry.add("TrackToColl/hGoodAssocTracksAmb", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis}); + + qaregistry.add("TrackToColl/histFracTracksFakeMcColl", "Fraction of tracks originating from fake collision; fraction; entries", {HistType::kTH1F, {{101, 0., 1.01}}}); + qaregistry.add("TrackToColl/histFracGoodTracks", "Fraction of tracks originating from the correct collision; fraction; entries", {HistType::kTH1F, {{101, 0., 1.01}}}); + qaregistry.add("TrackToColl/histAmbTrackNumColls", "Number of collisions associated to an ambiguous track; no. collisions; entries", {HistType::kTH1F, {{30, -0.5, 29.5}}}); + } + + if (doprocessReAssocMC) { + // tracks not associated to any collision + hReAssoc[0] = qaregistry.add("ReAssoc/hNonAssocTracks", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis}); + // tracks associasted to a collision + hReAssoc[1] = qaregistry.add("ReAssoc/hAssocTracks", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis}); + // tracks associated to the correct collision considering only first reco collision (based on the MC collision index) + hReAssoc[2] = qaregistry.add("ReAssoc/hGoodAssocTracks", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis}); + // tracks associated to the correct collision considering all ambiguous reco collisions (based on the MC collision index) + hReAssoc[3] = qaregistry.add("ReAssoc/hGoodAssocTracksAmb", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis}); + } + + // if (doprocessCheckAmbiguousMftTracksCentFT0C) { + // qaregistry.add({"Tracks/Centrality/hMftTracksAmbDegree", + // " ; N_{coll}^{comp}; centrality", + // {HistType::kTH2F, + // {{41, -0.5, 40.5}, centralityAxis}}}); + // qaregistry.add({"Tracks/Centrality/hMftTracksAmbDegreeWithTrivial", + // " ; N_{coll}^{comp}; centrality", + // {HistType::kTH2F, + // {{41, -0.5, 40.5}, centralityAxis}}}); + // qaregistry.add({"Tracks/Centrality/hAmbTrackType", + // " ; Ambiguous track type; centrality", + // {HistType::kTH2F, + // {{5, -0.5, 4.5}, centralityAxis}}}); + // } if (doprocessEfficiencyInclusive) { qaregistry.add({"Tracks/hEffRec", @@ -824,6 +962,11 @@ struct DndetaMFTPbPb { qaregistry.add({"Tracks/hDCAzBestPtRec", "; p_{T} (GeV/c) ; DCA_{Z} (cm)", {HistType::kTH2F, {ptAxis, dcazAxis}}}); qaregistry.add({"Tracks/hDCAxyBestRec", "; DCA_{XY} (cm)", {HistType::kTH1F, {dcaxyAxis}}}); qaregistry.add({"Tracks/hDCAzBestRec", "; DCA_{Z} (cm)", {HistType::kTH1F, {dcazAxis}}}); + // + qaregistry.add({"Tracks/THnDCAxyBestGenPrim", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis}}}); + qaregistry.add({"Tracks/THnDCAxyBestGenSecWeak", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis}}}); + qaregistry.add({"Tracks/THnDCAxyBestGenSecMat", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis}}}); + qaregistry.add({"Tracks/THnDCAxyBestRec", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis}}}); } if (doprocessDCAMcCentFT0C) { qaregistry.add({"Tracks/Centrality/hDCAxBestGenPrim", "; DCA_{x}^{gen} (cm); counts", {HistType::kTH1F, {dcaxyAxis}}}); @@ -845,6 +988,11 @@ struct DndetaMFTPbPb { qaregistry.add({"Tracks/Centrality/hDCAzBestPtRec", "; p_{T} (GeV/c) ; DCA_{Z} (cm); centrality", {HistType::kTHnSparseF, {ptAxis, dcazAxis, centralityAxis}}}); qaregistry.add({"Tracks/Centrality/hDCAxyBestRec", "; DCA_{XY} (cm); centrality", {HistType::kTH2F, {dcaxyAxis, centralityAxis}}}); qaregistry.add({"Tracks/Centrality/hDCAzBestRec", "; DCA_{Z} (cm); centrality", {HistType::kTH2F, {dcazAxis, centralityAxis}}}); + // + qaregistry.add({"Tracks/Centrality/THnDCAxyBestGenPrim", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); + qaregistry.add({"Tracks/Centrality/THnDCAxyBestGenSecWeak", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); + qaregistry.add({"Tracks/Centrality/THnDCAxyBestGenSecMat", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); + qaregistry.add({"Tracks/Centrality/THnDCAxyBestRec", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); } } @@ -874,16 +1022,23 @@ struct DndetaMFTPbPb { using CollCentFT0C = CollsCentFT0C::iterator; using CollsGenCentFT0C = soa::Join; + using CollisionsWithMCLabels = soa::Join; + using CollGenCent = CollsGenCentFT0C::iterator; using CollsCorr = soa::Join; // Tracks using MFTTracksLabeled = soa::Join; using MftTracksWColls = soa::Join; + using MftTracksWCollsMC = soa::Join; + + using BestTracksMC = soa::Join; /// Filtered tables using FiltMftTracks = soa::Filtered; using FiltMcMftTracks = soa::Filtered; using FiltBestTracks = soa::Filtered; + using FiltMcBestTracks = soa::Filtered; + using FiltParticles = soa::Filtered; template @@ -1087,30 +1242,43 @@ struct DndetaMFTPbPb { } for (auto const& track : tracks) { - if (std::find(ambiguousTrkIds.begin(), ambiguousTrkIds.end(), track.globalIndex()) != ambiguousTrkIds.end()) { + if (!isTrackSelected(track)) { continue; } - if (std::find(reassignedTrkIds.begin(), reassignedTrkIds.end(), track.globalIndex()) != reassignedTrkIds.end()) { + float phi = track.phi(); + o2::math_utils::bringTo02Pi(phi); + if (phi < kZero || TwoPI < phi) { continue; } - if (!isTrackSelected(track)) { + if (fillHis) { + if constexpr (has_reco_cent) { + qaregistry.fill(HIST("Tracks/Centrality/OrigTracksEtaZvtx"), track.eta(), z, c, occ); + qaregistry.fill(HIST("Tracks/Centrality/OrigTracksPhiEta"), phi, track.eta(), c, occ); + } else { + qaregistry.fill(HIST("Tracks/OrigTracksEtaZvtx"), track.eta(), z, occ); + qaregistry.fill(HIST("Tracks/OrigTracksPhiEta"), phi, track.eta(), occ); + } + } + if (std::find(ambiguousTrkIds.begin(), ambiguousTrkIds.end(), track.globalIndex()) != ambiguousTrkIds.end()) { + continue; + } + if (std::find(reassignedTrkIds.begin(), reassignedTrkIds.end(), track.globalIndex()) != reassignedTrkIds.end()) { continue; } ++nATrk; if (fillHis) { - float phi = track.phi(); - o2::math_utils::bringTo02Pi(phi); - if (phi < kZero || TwoPI < phi) { - continue; - } if constexpr (has_reco_cent) { - registry.fill(HIST("Tracks/Centrality/EtaZvtxBest"), track.eta(), z, c, occ); - registry.fill(HIST("Tracks/Centrality/PhiEtaBest"), phi, track.eta(), c, occ); - qaregistry.fill(HIST("Tracks/Centrality/NclustersEtaBest"), track.nClusters(), track.eta(), c, occ); + qaregistry.fill(HIST("Tracks/Centrality/RestTracksEtaZvtx"), track.eta(), z, c, occ); + qaregistry.fill(HIST("Tracks/Centrality/RestTracksPhiEta"), phi, track.eta(), c, occ); + // registry.fill(HIST("Tracks/Centrality/EtaZvtxBest"), track.eta(), z, c, occ); + // registry.fill(HIST("Tracks/Centrality/PhiEtaBest"), phi, track.eta(), c, occ); + // qaregistry.fill(HIST("Tracks/Centrality/NclustersEtaBest"), track.nClusters(), track.eta(), c, occ); } else { - registry.fill(HIST("Tracks/EtaZvtxBest"), track.eta(), z, occ); - registry.fill(HIST("Tracks/PhiEtaBest"), phi, track.eta(), occ); - qaregistry.fill(HIST("Tracks/NclustersEtaBest"), track.nClusters(), track.eta(), occ); + qaregistry.fill(HIST("Tracks/RestTracksEtaZvtx"), track.eta(), z, occ); + qaregistry.fill(HIST("Tracks/RestTracksPhiEta"), phi, track.eta(), occ); + // registry.fill(HIST("Tracks/EtaZvtxBest"), track.eta(), z, occ); + // registry.fill(HIST("Tracks/PhiEtaBest"), phi, track.eta(), occ); + // qaregistry.fill(HIST("Tracks/NclustersEtaBest"), track.nClusters(), track.eta(), occ); } } } @@ -2011,6 +2179,124 @@ struct DndetaMFTPbPb { using ParticlesI = soa::Join; Partition primariesI = (aod::mcparticle::flags & (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary) == (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary && (aod::mcparticle::eta < trackCuts.maxEta) && (aod::mcparticle::eta > trackCuts.minEta); + Preslice perMCCol = aod::mcparticle::mcCollisionId; + + template + void processTrkEffIdxBest( + typename soa::Join const& collisions, + MC const& /*mccollisions*/, ParticlesI const& /*particles*/, + BestTracksMC const& atracks) + { + for (auto const& collision : collisions) { + if (!isGoodEvent(collision)) { + continue; + } + if (!collision.has_mcCollision()) { + continue; + } + float crec = getRecoCent(collision); + auto mcCollision = collision.mcCollision(); + auto partsPerCol = primariesI->sliceByCached(aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), cache); + partsPerCol.bindExternalIndices(&atracks); + for (auto const& particle : partsPerCol) { + if (!isChrgParticle(particle.pdgCode())) { + continue; + } + // MC gen + if constexpr (has_reco_cent) { + if (particle.eta() > trackCuts.minEta && particle.eta() < trackCuts.maxEta) { + if (std::abs(mcCollision.posZ()) < eventCuts.maxZvtx) { + qaregistry.fill(HIST("Tracks/Centrality/hPtEtaEffGenBest"), particle.pt(), particle.eta(), crec); + } + } + } else { + if (particle.eta() > trackCuts.minEta && particle.eta() < trackCuts.maxEta) { + if (std::abs(mcCollision.posZ()) < eventCuts.maxZvtx) { + qaregistry.fill(HIST("Tracks/hPtEtaEffGenBest"), particle.pt(), particle.eta()); + } + } + } + // MC rec + if (particle.has_mfttracks()) { + auto iscounted = false; + auto ncnt = 0; + auto relatedTracks = particle.template mfttracks_as(); + for (auto const& track : relatedTracks) { + ++ncnt; + + if constexpr (has_reco_cent) { + if (track.eta() > trackCuts.minEta && track.eta() < trackCuts.maxEta) { + if (!iscounted) { // primaries + if (std::abs(mcCollision.posZ()) < eventCuts.maxZvtx) { + qaregistry.fill(HIST("Tracks/Centrality/hPtEtaEffPrimBest"), particle.pt(), particle.eta(), crec); + } + iscounted = true; + } + } + if (ncnt > 1) { // secondaries + if (track.eta() > trackCuts.minEta && track.eta() < trackCuts.maxEta) { + qaregistry.fill(HIST("Tracks/Centrality/hPtEtaEffSecBest"), particle.pt(), particle.eta(), crec); + } + } + } else { + if (track.eta() > trackCuts.minEta && track.eta() < trackCuts.maxEta) { + if (!iscounted) { // primaries + if (std::abs(mcCollision.posZ()) < eventCuts.maxZvtx) { + qaregistry.fill(HIST("Tracks/hPtEtaEffPrimBest"), particle.pt(), particle.eta()); + } + iscounted = true; + } + } + if (ncnt > 1) { // secondaries + if (track.eta() > trackCuts.minEta && track.eta() < trackCuts.maxEta) { + qaregistry.fill(HIST("Tracks/hPtEtaEffSecBest"), particle.pt(), particle.eta()); + } + } + } + + if constexpr (has_reco_cent) { + qaregistry.fill(HIST("Tracks/Centrality/NmftTrkPerPartBest"), ncnt, crec); + } else { + qaregistry.fill(HIST("Tracks/NmftTrkPerPartBest"), ncnt); + } + + if (relatedTracks.size() > 1) { // duplicates + if constexpr (has_reco_cent) { + qaregistry.fill(HIST("Tracks/Centrality/hPtEtaEffGenDuplBest"), particle.pt(), particle.eta(), crec); + for (auto const& track : relatedTracks) { + qaregistry.fill(HIST("Tracks/Centrality/hPtEtaEffDuplBest"), track.pt(), track.eta(), crec); + } + } else { + qaregistry.fill(HIST("Tracks/hPtEtaEffGenDuplBest"), particle.pt(), particle.eta()); + for (auto const& track : relatedTracks) { + qaregistry.fill(HIST("Tracks/hPtEtaEffDuplBest"), track.pt(), track.eta()); + } + } + } + } + } + } + } + } + + void processTrkEffIdxBestInlusive( + soa::Join const& collisions, + aod::McCollisions const& mccollisions, ParticlesI const& particles, + BestTracksMC const& atracks) + { + processTrkEffIdxBest(collisions, mccollisions, particles, atracks); + } + PROCESS_SWITCH(DndetaMFTPbPb, processTrkEffIdxBestInlusive, "Process tracking efficiency best (inclusive, indexed)", false); + + void processTrkEffIdxBestCentFT0C( + soa::Join const& collisions, + aod::McCollisions const& mccollisions, ParticlesI const& particles, + BestTracksMC const& atracks) + { + processTrkEffIdxBest(collisions, mccollisions, particles, atracks); + } + PROCESS_SWITCH(DndetaMFTPbPb, processTrkEffIdxBestCentFT0C, "Process tracking efficiency best (in FT0C centrality bins, indexed)", false); + /// @brief process template function to calculate tracking efficiency (indexed /// as particle-to-MFT-tracks) template @@ -2361,98 +2647,173 @@ struct DndetaMFTPbPb { "Process efficiencies in FT0C centrality bins", false); /// @brief process function to check ambiguous tracks - template - void processCheckAmbiguousMftTracks(typename C::iterator const& collision, - allC const& allcollisions, - MftTracksWColls const& tracks) + void processCheckAmbiguousMftTracks(aod::Collisions const&, MftTracksWColls const& tracks) { - float c = getRecoCent(collision); - bool ambTrk = false; - int typeAmbTrk = -1; - - if (tracks.size() == 0) { - return; - } - for (auto const& track : tracks) { auto trkCollId = track.has_collision() ? track.collisionId() : -1; auto ids = track.compatibleCollIds(); if (ids.empty() || (ids.size() == 1 && trkCollId == ids[0])) { - if constexpr (has_reco_cent) { - qaregistry.fill(HIST("Tracks/Centrality/hMftTracksAmbDegreeWoTrivial"), track.compatibleColl().size(), c); - } else { - qaregistry.fill(HIST("Tracks/hMftTracksAmbDegreeWoTrivial"), track.compatibleColl().size()); + qaregistry.fill(HIST("Tracks/hMftTracksAmbDegreeWithTrivial"), track.compatibleCollIds().size()); + if (ids.empty()) { + qaregistry.fill(HIST("Tracks/hAmbTrackType"), AmbTrkType::kOrphan); + } + if (ids.size() == 1 && trkCollId == ids[0]) { + qaregistry.fill(HIST("Tracks/hAmbTrackType"), AmbTrkType::kNonAmb); } continue; } - - if constexpr (has_reco_cent) { - qaregistry.fill(HIST("Tracks/Centrality/hMftTracksAmbDegree"), - track.compatibleColl().size(), c); - } else { - qaregistry.fill(HIST("Tracks/hMftTracksAmbDegree"), - track.compatibleColl().size()); - } + qaregistry.fill(HIST("Tracks/hMftTracksAmbDegree"), track.compatibleCollIds().size()); if (track.compatibleCollIds().size() > 0) { if (track.compatibleCollIds().size() == 1) { if (track.collisionId() != track.compatibleCollIds()[0]) { - ambTrk = true; - typeAmbTrk = 2; + qaregistry.fill(HIST("Tracks/hAmbTrackType"), AmbTrkType::kAmb); } else { - typeAmbTrk = 1; + qaregistry.fill(HIST("Tracks/hAmbTrackType"), AmbTrkType::kNonAmbSame); } } else { - ambTrk = true; - typeAmbTrk = 3; - - for (const auto& collIdx : track.compatibleCollIds()) { - auto ambColl = allcollisions.rawIteratorAt(collIdx); - qaregistry.fill(HIST("Tracks/histAmbZvtx"), ambColl.posZ()); - } + qaregistry.fill(HIST("Tracks/hAmbTrackType"), AmbTrkType::kAmbGt1); } - } else { - typeAmbTrk = 0; } } + } - if (ambTrk) { - if constexpr (has_reco_cent) { - qaregistry.fill(HIST("Tracks/Centrality/hAmbTrackType"), typeAmbTrk, c); - } else { - qaregistry.fill(HIST("Tracks/hAmbTrackType"), typeAmbTrk); + PROCESS_SWITCH(DndetaMFTPbPb, processCheckAmbiguousMftTracks, "Process checks for Ambiguous MFT tracks (inclusive)", false); + + Partition tracksInAcc = (aod::fwdtrack::eta < trackCuts.maxEta) && (aod::fwdtrack::eta > trackCuts.minEta); + + template + void processCheckAssocMC(C const& collisions, + MftTracksWCollsMC const& tracks, + aod::McParticles const& /*particles*/, + aod::McCollisions const& /*mccollisions*/ + ) + { + for (const auto& collision : collisions) { + if (!collision.has_mcCollision()) { + continue; } - } else { - if constexpr (has_reco_cent) { - qaregistry.fill(HIST("Tracks/Centrality/hAmbTrackType"), typeAmbTrk, c); + // auto mcCollision = collision.template mcCollision_as(); + auto tracksInColl = tracksInAcc->sliceByCached(aod::fwdtrack::collisionId, collision.globalIndex(), cache); + int nTrk = 0, nFakeTrk = 0, nGoodTrk = 0; + for (const auto& track : tracksInColl) { + if (!track.has_mcParticle()) { + continue; + } + nTrk++; + auto particle = track.mcParticle(); + + if ((particle.mcCollisionId() != collision.mcCollision().globalIndex())) { + nFakeTrk++; + continue; + } + if (collision.mcCollisionId() == particle.mcCollisionId()) { + nGoodTrk++; + } + } + float frac = (nTrk > 0) ? static_cast(nGoodTrk) / nTrk : -1.; + qaregistry.fill(HIST("TrackToColl/histFracGoodTracks"), frac); + float fracFake = (nTrk > 0) ? static_cast(nFakeTrk) / nTrk : -1.; + qaregistry.fill(HIST("TrackToColl/histFracTracksFakeMcColl"), fracFake); + } + + for (auto const& track : tracks) { + uint index = uint(track.collisionId() >= 0); + if (track.has_mcParticle()) { + // auto particle = track.mcParticle_as(); + auto particle = track.mcParticle(); + bool isAmbiguous = (track.compatibleCollIds().size() != 1); + if (isAmbiguous) { + qaregistry.fill(HIST("TrackToColl/histAmbTrackNumColls"), track.compatibleCollIds().size()); + } + float deltaZ = -999.f; + if (index) { + auto collision = track.collision_as(); + auto mcCollision = particle.mcCollision_as(); + deltaZ = collision.posZ() - mcCollision.posZ(); + if (collision.has_mcCollision() && collision.mcCollisionId() == particle.mcCollisionId()) { + hCollAssoc[index + 1]->Fill(track.pt(), track.eta(), deltaZ); + } else { + if (isAmbiguous) { + for (const auto& collIdx : track.compatibleCollIds()) { + auto ambCollision = collisions.rawIteratorAt(collIdx); + if (ambCollision.has_mcCollision() && ambCollision.mcCollisionId() == particle.mcCollisionId()) { + hCollAssoc[index + 2]->Fill(track.pt(), track.eta(), deltaZ); + break; + } + } + } + } + } + hCollAssoc[index]->Fill(track.pt(), track.eta(), deltaZ); } else { - qaregistry.fill(HIST("Tracks/hAmbTrackType"), typeAmbTrk); + hCollAssoc[index]->Fill(track.pt(), track.eta(), -999.f); } } } - void processCheckAmbiguousMftTracksInclusive(Colls::iterator const& collision, - Colls const& allcollisions, - MftTracksWColls const& track) + void processCollAssocMC(CollisionsWithMCLabels const& collisions, + MftTracksWCollsMC const& tracks, + aod::McParticles const& particles, + aod::McCollisions const& mccollisions) { - processCheckAmbiguousMftTracks(collision, allcollisions, - track); + processCheckAssocMC(collisions, tracks, particles, mccollisions); } + PROCESS_SWITCH(DndetaMFTPbPb, processCollAssocMC, "Process collision-association information, requires extra table from TrackToCollisionAssociation task (fillTableOfCollIdsPerTrack=true)", false); - PROCESS_SWITCH(DndetaMFTPbPb, processCheckAmbiguousMftTracksInclusive, - "Process checks for Ambiguous MFT tracks (inclusive)", false); - - void processCheckAmbiguousMftTracksCentFT0C( - CollsCentFT0C::iterator const& collision, - CollsCentFT0C const& allcollisions, MftTracksWColls const& track) + template + void processCheckReAssocMC(C const& /*collisions*/, + soa::SmallGroups const& besttracks, + FiltMcMftTracks const& /*tracks*/, + FiltParticles const& /*particles*/, + aod::McCollisions const& /*mccollisions*/ + ) { - processCheckAmbiguousMftTracks( - collision, allcollisions, track); + for (auto const& track : besttracks) { + uint index = uint(track.bestCollisionId() >= 0); // assigned + if (!isBestTrackSelected(track)) { + continue; + } + auto itrack = track.mfttrack_as(); + + if (cfgRemoveTrivialAssoc) { + if (itrack.collisionId() != track.bestCollisionId()) { + continue; + } + } + if (!isTrackSelected(itrack)) { + continue; + } + if (itrack.has_mcParticle()) { + auto particle = itrack.mcParticle_as(); + + float deltaZ = -999.f; + if (index) { + auto collision = itrack.collision_as(); + auto mcCollision = particle.mcCollision_as(); + deltaZ = collision.posZ() - mcCollision.posZ(); + if (collision.has_mcCollision() && collision.mcCollisionId() == particle.mcCollisionId()) { + hReAssoc[index + 1]->Fill(itrack.pt(), itrack.eta(), deltaZ); + } else { + hReAssoc[index + 2]->Fill(itrack.pt(), itrack.eta(), deltaZ); + } + } + hReAssoc[index]->Fill(itrack.pt(), itrack.eta(), deltaZ); + } else { + hReAssoc[index]->Fill(itrack.pt(), itrack.eta(), -999.f); + } + } } - PROCESS_SWITCH(DndetaMFTPbPb, processCheckAmbiguousMftTracksCentFT0C, - "Process checks for Ambiguous MFT tracks (in FT0C centrality bins)", - false); + void processReAssocMC(CollisionsWithMCLabels const& collisions, + soa::SmallGroups const& besttracks, + FiltMcMftTracks const& tracks, + FiltParticles const& particles, + aod::McCollisions const& mccollisions) + { + processCheckReAssocMC(collisions, besttracks, tracks, particles, mccollisions); + } + PROCESS_SWITCH(DndetaMFTPbPb, processReAssocMC, "Process re-association information based on BestCollisionsFwd3d table", false); Preslice filtTrkperCol = o2::aod::fwdtrack::collisionId; @@ -2563,11 +2924,13 @@ struct DndetaMFTPbPb { } if constexpr (has_reco_cent) { + qaregistry.fill(HIST("Tracks/Centrality/THnDCAxyBestRec"), itrack.pt(), itrack.eta(), collision.posZ(), atrack.bestDCAXY(), atrack.bestDCAZ(), crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAxyBestPtRec"), itrack.pt(), atrack.bestDCAXY(), crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAzBestPtRec"), itrack.pt(), atrack.bestDCAZ(), crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAxyBestRec"), atrack.bestDCAXY(), crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAzBestRec"), atrack.bestDCAZ(), crec); } else { + qaregistry.fill(HIST("Tracks/THnDCAxyBestRec"), itrack.pt(), itrack.eta(), collision.posZ(), atrack.bestDCAXY(), atrack.bestDCAZ()); qaregistry.fill(HIST("Tracks/hDCAxyBestPtRec"), itrack.pt(), atrack.bestDCAXY()); qaregistry.fill(HIST("Tracks/hDCAzBestPtRec"), itrack.pt(), atrack.bestDCAZ()); qaregistry.fill(HIST("Tracks/hDCAxyBestRec"), atrack.bestDCAXY()); @@ -2575,11 +2938,10 @@ struct DndetaMFTPbPb { } if (!itrack.has_mcParticle()) { - LOGF(warning, "No MC particle for ambiguous itrack, skip..."); + LOGP(debug, "No MC particle for ambiguous itrack, skip..."); continue; } - // auto particle = track.mcParticle(); auto particle = itrack.mcParticle_as(); if (!isChrgParticle(particle.pdgCode())) { @@ -2600,11 +2962,13 @@ struct DndetaMFTPbPb { if (!particle.isPhysicalPrimary()) { // Secondaries (weak decays and material) if (particle.getProcess() == kNumDecay) { // Particles from decay if constexpr (has_reco_cent) { + qaregistry.fill(HIST("Tracks/Centrality/THnDCAxyBestGenSecWeak"), particle.pt(), particle.eta(), particle.mcCollision().posZ(), dcaXtruth, dcaZtruth, crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAxBestGenSecWeak"), dcaXtruth, crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAyBestGenSecWeak"), dcaYtruth, crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAxyBestGenSecWeak"), dcaXYtruth, crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAzBestGenSecWeak"), dcaZtruth, crec); } else { + qaregistry.fill(HIST("Tracks/THnDCAxyBestGenSecWeak"), particle.pt(), particle.eta(), particle.mcCollision().posZ(), dcaXtruth, dcaZtruth); qaregistry.fill(HIST("Tracks/hDCAxBestGenSecWeak"), dcaXtruth); qaregistry.fill(HIST("Tracks/hDCAyBestGenSecWeak"), dcaYtruth); qaregistry.fill(HIST("Tracks/hDCAxyBestGenSecWeak"), dcaXYtruth); @@ -2612,11 +2976,13 @@ struct DndetaMFTPbPb { } } else { // Particles from the material if constexpr (has_reco_cent) { + qaregistry.fill(HIST("Tracks/Centrality/THnDCAxyBestGenSecMat"), particle.pt(), particle.eta(), particle.mcCollision().posZ(), dcaXtruth, dcaZtruth, crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAxBestGenSecMat"), dcaXtruth, crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAyBestGenSecMat"), dcaYtruth, crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAxyBestGenSecMat"), dcaXYtruth, crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAzBestGenSecMat"), dcaZtruth, crec); } else { + qaregistry.fill(HIST("Tracks/THnDCAxyBestGenSecMat"), particle.pt(), particle.eta(), particle.mcCollision().posZ(), dcaXtruth, dcaZtruth); qaregistry.fill(HIST("Tracks/hDCAxBestGenSecMat"), dcaXtruth); qaregistry.fill(HIST("Tracks/hDCAyBestGenSecMat"), dcaYtruth); qaregistry.fill(HIST("Tracks/hDCAxyBestGenSecMat"), dcaXYtruth); @@ -2625,11 +2991,13 @@ struct DndetaMFTPbPb { } } else { // Primaries if constexpr (has_reco_cent) { + qaregistry.fill(HIST("Tracks/Centrality/THnDCAxyBestGenPrim"), particle.pt(), particle.eta(), particle.mcCollision().posZ(), dcaXtruth, dcaZtruth, crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAxBestGenPrim"), dcaXtruth, crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAyBestGenPrim"), dcaYtruth, crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAxyBestGenPrim"), dcaXYtruth, crec); qaregistry.fill(HIST("Tracks/Centrality/hDCAzBestGenPrim"), dcaZtruth, crec); } else { + qaregistry.fill(HIST("Tracks/THnDCAxyBestGenPrim"), particle.pt(), particle.eta(), particle.mcCollision().posZ(), dcaXtruth, dcaZtruth); qaregistry.fill(HIST("Tracks/hDCAxBestGenPrim"), dcaXtruth); qaregistry.fill(HIST("Tracks/hDCAyBestGenPrim"), dcaYtruth); qaregistry.fill(HIST("Tracks/hDCAxyBestGenPrim"), dcaXYtruth);