diff --git a/PWGLF/Tasks/GlobalEventProperties/PseudorapidityDensityMFT.cxx b/PWGLF/Tasks/GlobalEventProperties/PseudorapidityDensityMFT.cxx index ed76d333570..27e11cebe8b 100644 --- a/PWGLF/Tasks/GlobalEventProperties/PseudorapidityDensityMFT.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/PseudorapidityDensityMFT.cxx @@ -400,7 +400,8 @@ struct PseudorapidityDensityMFT { Configurable useTriggerTVX{"useTriggerTVX", true, "Require kIsTriggerTVX in processGenReco"}; Configurable useNoTimeFrameBorderCut{"useNoTimeFrameBorderCut", true, "Require kNoTimeFrameBorder in processGenReco"}; Configurable useNoITSROFrameBorderCut{"useNoITSROFrameBorderCut", true, "Require kNoITSROFrameBorder in processGenReco"}; - + AxisSpec multAxisRecoMFT = {multBinning, "N_{ch}^{reco,MFT}"}; + AxisSpec multAxisGenMFT = {multBinning, "N_{ch}^{gen,MFT}"}; HistogramRegistry registry{ "registry", { @@ -630,6 +631,22 @@ struct PseudorapidityDensityMFT { registry.add({"Purity/reco/PNchMFT_afterCuts", ";N_{trk}^{MFT} (selected);events", {HistType::kTH1F, {multAxis}}}); + // MC P(Nch) objects for MFT multiplicity unfolding/correction. + // Generator multiplicity: primary charged particles in the MFT acceptance, + // with generated INEL>0 defined from the central estimator. + // Reco multiplicity: selected reassociated MFT tracks for matched accepted reco events. + registry.add({"PNchMC/gen_inelgt0", + ";N_{ch}^{gen,MFT};events", + {HistType::kTH1F, {multAxisGenMFT}}}); + + registry.add({"PNchMC/reco_sel8_inelgt0", + ";N_{ch}^{reco,MFT};events", + {HistType::kTH1F, {multAxisRecoMFT}}}); + + registry.add({"PNchMC/responseMatrix", + ";N_{ch}^{reco,MFT};N_{ch}^{gen,MFT};events", + {HistType::kTH2F, {multAxisRecoMFT, multAxisGenMFT}}}); + registry.add({"Purity/DCAyVsDCAx_Right", ";DCA_{x} (cm);DCA_{y} (cm)", {HistType::kTH2F, {dcaXAxis, dcaYAxis}}}); @@ -1214,6 +1231,27 @@ struct PseudorapidityDensityMFT { " ; N_{Trk}^{nonamb}", {HistType::kTH1F, {{701, -0.5, 700.5}}}}); // + // Event-level P(Nch) distributions for reassociated MFT tracks. + // Fill once per collision after counting selected reassociated MFT tracks. + registry.add({"PNch/MFT_sel8", + ";N_{ch}^{MFT};events", + {HistType::kTH1F, {multAxis}}}); + registry.add({"PNch/MFT_sel8_inelgt0", + ";N_{ch}^{MFT};events", + {HistType::kTH1F, {multAxis}}}); + registry.add({"PNch/MFT_sel8_inelfwdgt0", + ";N_{ch}^{MFT};events", + {HistType::kTH1F, {multAxis}}}); + registry.add({"PNch/MFT_sel8_inelgt0_nonamb", + ";N_{ch}^{MFT, nonamb};events", + {HistType::kTH1F, {multAxis}}}); + registry.add({"PNch/MFT_sel8_inelgt0_amb", + ";N_{ch}^{MFT, amb};events", + {HistType::kTH1F, {multAxis}}}); + registry.add({"PNch/MFTZvtx_sel8_inelgt0", + ";N_{ch}^{MFT};#it{z}_{vtx} (cm);events", + {HistType::kTH2F, {multAxis, zAxis}}}); + registry.add({"Tracks/Control/amb/AmbTracksPhiEta", "; #varphi; #eta; tracks", {HistType::kTH2F, {phiAxis, etaBinning}}}); // @@ -1542,6 +1580,10 @@ struct PseudorapidityDensityMFT { std::unordered_set eventsInelMFT; std::unordered_set eventsInel; + int64_t nMFTSelected{0}; + int64_t nMFTSelectedAmb{0}; + int64_t nMFTSelectedNonAmb{0}; + const auto fillDataCut = [&](DataCutBin bin) { registry.fill(HIST("EventSelectionData"), static_cast(bin)); }; @@ -1655,6 +1697,13 @@ struct PseudorapidityDensityMFT { if (failTrackCuts) { continue; } + ++nMFTSelected; + if (retrack.ambDegree() > SingleCompatibleCollision) { + ++nMFTSelectedAmb; + } else if (retrack.ambDegree() == SingleCompatibleCollision) { + ++nMFTSelectedNonAmb; + } + registry.fill(HIST("Tracks/Control/TrackAmbDegree"), retrack.ambDegree()); registry.fill(HIST("Tracks/Control/DCAXY"), retrack.bestDCAXY()); @@ -1771,6 +1820,17 @@ struct PseudorapidityDensityMFT { registry.fill(HIST("Tracks/Control/nonamb/nTrkNonAmb"), j); registry.fill(HIST("Tracks/Control/woOrp/nTrk"), k); registry.fill(HIST("hNumCollisions_Inel"), 1, eventsInel.size()); + + registry.fill(HIST("PNch/MFT_sel8"), nMFTSelected); + if (midtracks.size() > 0) { + registry.fill(HIST("PNch/MFT_sel8_inelgt0"), nMFTSelected); + registry.fill(HIST("PNch/MFTZvtx_sel8_inelgt0"), nMFTSelected, z); + registry.fill(HIST("PNch/MFT_sel8_inelgt0_nonamb"), nMFTSelectedNonAmb); + registry.fill(HIST("PNch/MFT_sel8_inelgt0_amb"), nMFTSelectedAmb); + if (nMFTSelected > 0) { + registry.fill(HIST("PNch/MFT_sel8_inelfwdgt0"), nMFTSelected); + } + } } void processMultReassoc(CollwEv::iterator const& collision, @@ -2413,6 +2473,7 @@ struct PseudorapidityDensityMFT { bool onlyVzGt0 = false; // EtaZvtxGen_gt0t bool atLeastOneSel8Vz = false; // EtaZvtxGen bool atLeastOneSel8VzGt0 = false; // EtaZvtxGen_gt0 + bool hasRecoCollisionForPNch{false}; const auto fillGenRecoCut = [&](GenRecoCutBin bin) { registry.fill(HIST("EventsRecoCuts_GenReco"), static_cast(bin)); @@ -2567,6 +2628,7 @@ struct PseudorapidityDensityMFT { acceptedRecoCols.insert(recoCol); recoCollisionIds.insert(recoCol); trueMCCollisionIds.insert(mcCol); + hasRecoCollisionForPNch = true; if (mcCol >= 0) { recoToMc[recoCol] = mcCol; @@ -2603,7 +2665,9 @@ struct PseudorapidityDensityMFT { int64_t woOrpCount = 0; bool filledRight = false; bool filledWrong = false; - int nMftSelectedAfterCuts = 0; + int64_t nMftSelectedAfterCuts{0}; + int64_t nRecoMFTSelectedForPNch{0}; + int64_t nGenPrimaryChargedMFT{0}; std::unordered_set uniqueBestRecoCols; if (tracks.size() > 0) { @@ -2689,6 +2753,11 @@ struct PseudorapidityDensityMFT { failDCAzCut = useDCAzCut && (std::abs(dcaZCut) > maxDCAz); // std::cout <<" dcaZReco " <= cfgVzCut1) && (mcCollision.posZ() <= cfgVzCut2)) { + if (nChargedCentral > 0) { + + registry.fill(HIST("PNchMC/gen_inelgt0"), + nGenPrimaryChargedMFT); + + if (hasRecoCollisionForPNch) { + registry.fill(HIST("PNchMC/reco_sel8_inelgt0"), + nRecoMFTSelectedForPNch); + + registry.fill(HIST("PNchMC/responseMatrix"), + nRecoMFTSelectedForPNch, + nGenPrimaryChargedMFT); + } } } }