From 391ba2adf948cecdf760848d8c41e29205d23b22 Mon Sep 17 00:00:00 2001 From: Meiyi Chen Date: Thu, 24 Sep 2026 15:41:39 +0200 Subject: [PATCH] Update HadNucleiFemto.cxx --- .../TableProducer/HadNucleiFemto.cxx | 86 +++++++++++++------ 1 file changed, 60 insertions(+), 26 deletions(-) diff --git a/PWGCF/Femto/FemtoNuclei/TableProducer/HadNucleiFemto.cxx b/PWGCF/Femto/FemtoNuclei/TableProducer/HadNucleiFemto.cxx index 09163954b50..fc838b5f3b3 100644 --- a/PWGCF/Femto/FemtoNuclei/TableProducer/HadNucleiFemto.cxx +++ b/PWGCF/Femto/FemtoNuclei/TableProducer/HadNucleiFemto.cxx @@ -84,11 +84,20 @@ using CollBracket = o2::math_utils::Bracket; using HyperCandidates = aod::DataHypCandsWColl; using HyperCandidatesMC = aod::MCHypCandsWColl; using CollisionsFull = soa::Join; +// The standard Femto producer stores multNTracksPV as its collision +// multiplicity. Subscribe to PVMults only in the mixed-event process so the +// same vertex--multiplicity pool definition can optionally be reproduced. +using CollisionsFullWithPVMult = soa::Join; using CollisionsFullMC = soa::Join; using HadHyperCollisionsFull = soa::Join; using HadHyperCollisionsFullMC = soa::Join; using TrackCandidates = soa::Join; using TrackCandidatesMC = soa::Join; +// The DCA-template process explicitly subscribes to the propagated covariance +// table. This makes the propagation service enter the branch where TrackTuner +// corrections can be applied when enabled, without adding that dependency to +// unrelated MC process switches. +using TrackCandidatesMCDca = soa::Join; namespace { @@ -328,6 +337,7 @@ struct HadNucleiFemto { // Event selection and mixing configuration Configurable settingCutVertex{"settingCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable settingNoMixedEvents{"settingNoMixedEvents", 5, "Number of mixed events per event"}; + Configurable settingUseMultiplicityBinning{"settingUseMultiplicityBinning", false, "Use vertex and multNTracksPV for event mixing instead of vertex and centrality"}; Configurable settingRequireBothSpeciesForMixing{"settingRequireBothSpeciesForMixing", false, "Use only events containing at least one selected nucleus and one selected hadron for mixed-event pairing"}; Configurable settingEnableBkgUS{"settingEnableBkgUS", false, "Enable US background"}; Configurable settingSaveUSandLS{"settingSaveUSandLS", true, "Save All Pairs"}; @@ -356,7 +366,9 @@ struct HadNucleiFemto { Configurable settingCutNsigTOFPrMin{"settingCutNsigTOFPrMin", 3.0f, "Minimum TOF Pr Nsigma cut for rejection"}; Configurable settingCutNsigTOFPiMin{"settingCutNsigTOFPiMin", 3.0f, "Minimum TOF Pi Nsigma cut for rejection"}; Configurable settingHadptMin{"settingHadptMin", 0.14f, "Minimum pT for the reference pion track cuts"}; - Configurable settingHadptMax{"settingHadptMax", 2.5f, "Maximum pT for the reference pion track cuts"}; + Configurable settingHadptMax{"settingHadptMax", 4.0f, "Maximum pT for the reference pion track cuts"}; + Configurable settingProtonPtMin{"settingProtonPtMin", 0.5f, "Minimum pT for proton candidates"}; + Configurable settingProtonPtMax{"settingProtonPtMax", 3.0f, "Maximum pT for proton candidates"}; Configurable settingPionITSInnerBarrelMin{"settingPionITSInnerBarrelMin", 3, "Minimum ITS inner barrel clusters for the reference pion track cuts"}; Configurable settingPionITSNClsMin{"settingPionITSNClsMin", 7, "Minimum ITS clusters for the reference pion track cuts"}; Configurable settingPionTPCNClsFoundMin{"settingPionTPCNClsFoundMin", 80, "Minimum found TPC clusters for the reference pion track cuts"}; @@ -388,7 +400,7 @@ struct HadNucleiFemto { struct : o2::framework::ConfigurableGroup { // cppcheck-suppress unusedStructMember std::string prefix{"helium3Pid"}; - Configurable settingRigidityMinHe3{"settingRigidityMinHe3", 0.8f, "Minimum He3 TPC rigidity"}; + Configurable settingRigidityMinHe3{"settingRigidityMinHe3", 0.0f, "Minimum He3 TPC rigidity"}; Configurable settingTPCNClsFoundMinHe3{"settingTPCNClsFoundMinHe3", 110, "Minimum found TPC clusters for He3"}; Configurable settingTPCCrossedRowsMinHe3{"settingTPCCrossedRowsMinHe3", 70, "Minimum crossed TPC rows for He3"}; Configurable settingTPCNSigmaMaxHe3{"settingTPCNSigmaMaxHe3", 3.f, "Maximum absolute TPC n-sigma for He3"}; @@ -435,7 +447,7 @@ struct HadNucleiFemto { struct : o2::framework::ConfigurableGroup { // cppcheck-suppress unusedStructMember std::string prefix{"fractionPurity"}; - Configurable settingHadronDcaFitAbsMax{"settingHadronDcaFitAbsMax", 2.4f, "Maximum absolute pion DCAxy and DCAz stored for the fraction fit"}; + Configurable settingHadronDcaFitAbsMax{"settingHadronDcaFitAbsMax", 2.4f, "Maximum absolute hadron DCAxy and DCAz stored for the fraction fit"}; Configurable settingNucleusDcaFitAbsMax{"settingNucleusDcaFitAbsMax", 1.0f, "Maximum absolute nucleus DCAxy and DCAz stored for the fraction fit"}; Configurable settingRequireRecoMCCollisionMatch{"settingRequireRecoMCCollisionMatch", true, "For the base DCA templates, require the truth particle to belong to the reconstructed collision MC label; detailed templates always store both association classes"}; } fractionPurity; @@ -620,7 +632,9 @@ struct HadNucleiFemto { // binning for EM background ConfigurableAxis axisVertex{"axisVertex", {30, -10, 10}, "Binning for vtxz"}; ConfigurableAxis axisCentrality{"axisCentrality", {40, 0, 100}, "Binning for centrality"}; - using BinningType = ColumnBinningPolicy; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0., 4., 8., 12., 16., 20., 24., 28., 32., 36., 40., 44., 48., 52., 56., 60., 64., 68., 72., 76., 80., 84., 88., 92., 96., 100., 200.}, "Variable-width multNTracksPV bins for event mixing"}; + using CentralityBinningType = ColumnBinningPolicy; + using MultiplicityBinningType = ColumnBinningPolicy; std::array mBBparamsNucleus{}; float mMassHad{0.f}; @@ -688,36 +702,36 @@ struct HadNucleiFemto { // Base inputs for Giorgio-style offline DCA fits. The origin axis is: // 0 primary, 1 weak decay, 2 material (every non-primary, non-decay process). - {"fraction/hDcaDataHad", "Pion DCA-fit input;signed reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {40, 0.f, 100.f}}}}, + {"fraction/hDcaDataHad", "Hadron DCA-fit input;signed reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {40, 0.f, 100.f}}}}, {"fraction/hDcaDataNu", "Nucleus DCA-fit input;signed physical reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {NucleusDcaFitBins, -NucleusDcaFitAxisMax, NucleusDcaFitAxisMax}, {NucleusDcaFitBins, -NucleusDcaFitAxisMax, NucleusDcaFitAxisMax}, {40, 0.f, 100.f}}}}, - {"fraction/hDcaTemplateHad", "Truth pion DCA templates;signed reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality;origin", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {40, 0.f, 100.f}, {NDcaOrigins, -0.5f, static_cast(NDcaOrigins) - 0.5f}}}}, + {"fraction/hDcaTemplateHad", "Truth hadron DCA templates;signed reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality;origin", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {40, 0.f, 100.f}, {NDcaOrigins, -0.5f, static_cast(NDcaOrigins) - 0.5f}}}}, {"fraction/hDcaTemplateNu", "Truth nucleus DCA templates;signed physical reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality;origin", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {NucleusDcaFitBins, -NucleusDcaFitAxisMax, NucleusDcaFitAxisMax}, {NucleusDcaFitBins, -NucleusDcaFitAxisMax, NucleusDcaFitAxisMax}, {40, 0.f, 100.f}, {NDcaOrigins, -0.5f, static_cast(NDcaOrigins) - 0.5f}}}}, // DCA shapes of selected candidates that are not the requested truth // species. They are kept separate from primary/weak/material so that // their normalisation can be fixed or constrained by the PID purity. - {"fraction/hDcaMisidentifiedHad", "Misidentified pion candidates;signed reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality;collision association", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {40, 0.f, 100.f}, {NCollisionAssociations, -0.5f, static_cast(NCollisionAssociations) - 0.5f}}}}, + {"fraction/hDcaMisidentifiedHad", "Misidentified hadron candidates;signed reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality;collision association", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {40, 0.f, 100.f}, {NCollisionAssociations, -0.5f, static_cast(NCollisionAssociations) - 0.5f}}}}, {"fraction/hDcaMisidentifiedNu", "Misidentified nucleus candidates;signed physical reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality;collision association", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {NucleusDcaFitBins, -NucleusDcaFitAxisMax, NucleusDcaFitAxisMax}, {NucleusDcaFitBins, -NucleusDcaFitAxisMax, NucleusDcaFitAxisMax}, {40, 0.f, 100.f}, {NCollisionAssociations, -0.5f, static_cast(NCollisionAssociations) - 0.5f}}}}, - {"fraction/hDcaNoMCLabelHad", "Selected pion candidates without an MC label;signed reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {40, 0.f, 100.f}}}}, + {"fraction/hDcaNoMCLabelHad", "Selected hadron candidates without an MC label;signed reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {40, 0.f, 100.f}}}}, {"fraction/hDcaNoMCLabelNu", "Selected nucleus candidates without an MC label;signed physical reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {NucleusDcaFitBins, -NucleusDcaFitAxisMax, NucleusDcaFitAxisMax}, {NucleusDcaFitBins, -NucleusDcaFitAxisMax, NucleusDcaFitAxisMax}, {40, 0.f, 100.f}}}}, // Superset templates for optional offline refinements. They retain the // same base origin plus collision association, direct-parent category, // and the particle production radius. Projecting away the extra axes // recovers the base shapes; selecting them enables species-specific fits. - {"fraction/hDcaTemplateDetailHad", "Detailed truth pion DCA templates;signed reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality;origin;collision association;parent category;production R_{xy} (cm)", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {40, 0.f, 100.f}, {NDcaOrigins, -0.5f, static_cast(NDcaOrigins) - 0.5f}, {NCollisionAssociations, -0.5f, static_cast(NCollisionAssociations) - 0.5f}, {NParentCategories, -0.5f, static_cast(NParentCategories) - 0.5f}, {200, 0.f, 100.f}}}}, + {"fraction/hDcaTemplateDetailHad", "Detailed truth hadron DCA templates;signed reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality;origin;collision association;parent category;production R_{xy} (cm)", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {40, 0.f, 100.f}, {NDcaOrigins, -0.5f, static_cast(NDcaOrigins) - 0.5f}, {NCollisionAssociations, -0.5f, static_cast(NCollisionAssociations) - 0.5f}, {NParentCategories, -0.5f, static_cast(NParentCategories) - 0.5f}, {200, 0.f, 100.f}}}}, {"fraction/hDcaTemplateDetailNu", "Detailed truth nucleus DCA templates;signed physical reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality;origin;collision association;parent category;production R_{xy} (cm)", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {NucleusDcaFitBins, -NucleusDcaFitAxisMax, NucleusDcaFitAxisMax}, {NucleusDcaFitBins, -NucleusDcaFitAxisMax, NucleusDcaFitAxisMax}, {40, 0.f, 100.f}, {NDcaOrigins, -0.5f, static_cast(NDcaOrigins) - 0.5f}, {NCollisionAssociations, -0.5f, static_cast(NCollisionAssociations) - 0.5f}, {NParentCategories, -0.5f, static_cast(NParentCategories) - 0.5f}, {200, 0.f, 100.f}}}}, // Mother-resolved templates. There is one entry per direct mother (or a // single zero-code entry when no mother is stored). Reconstruct the exact // PDG code offline as sign * (PDG high * 10000 + PDG low). - {"fraction/hDcaMotherPdgHad", "Pion DCA by exact direct-mother PDG; signed reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality;origin;collision association;mother PDG sign;mother PDG high;mother PDG low", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {40, 0.f, 100.f}, {NDcaOrigins, -0.5f, static_cast(NDcaOrigins) - 0.5f}, {NCollisionAssociations, -0.5f, static_cast(NCollisionAssociations) - 0.5f}, {3, -1.5f, 1.5f}, {MotherPdgHighMax + 1, -0.5f, static_cast(MotherPdgHighMax) + 0.5f}, {MotherPdgChunkBase, -0.5f, static_cast(MotherPdgChunkBase) - 0.5f}}}}, + {"fraction/hDcaMotherPdgHad", "Hadron DCA by exact direct-mother PDG; signed reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality;origin;collision association;mother PDG sign;mother PDG high;mother PDG low", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {HadronDcaFitBins, -HadronDcaFitAxisMax, HadronDcaFitAxisMax}, {40, 0.f, 100.f}, {NDcaOrigins, -0.5f, static_cast(NDcaOrigins) - 0.5f}, {NCollisionAssociations, -0.5f, static_cast(NCollisionAssociations) - 0.5f}, {3, -1.5f, 1.5f}, {MotherPdgHighMax + 1, -0.5f, static_cast(MotherPdgHighMax) + 0.5f}, {MotherPdgChunkBase, -0.5f, static_cast(MotherPdgChunkBase) - 0.5f}}}}, {"fraction/hDcaMotherPdgNu", "Nucleus DCA by exact direct-mother PDG; signed physical reconstructed p_{T} (GeV/c);DCA_{xy} (cm);DCA_{z} (cm);centrality;origin;collision association;mother PDG sign;mother PDG high;mother PDG low", {HistType::kTHnSparseF, {{280, -7.f, 7.f}, {NucleusDcaFitBins, -NucleusDcaFitAxisMax, NucleusDcaFitAxisMax}, {NucleusDcaFitBins, -NucleusDcaFitAxisMax, NucleusDcaFitAxisMax}, {40, 0.f, 100.f}, {NDcaOrigins, -0.5f, static_cast(NDcaOrigins) - 0.5f}, {NCollisionAssociations, -0.5f, static_cast(NCollisionAssociations) - 0.5f}, {3, -1.5f, 1.5f}, {MotherPdgHighMax + 1, -0.5f, static_cast(MotherPdgHighMax) + 0.5f}, {MotherPdgChunkBase, -0.5f, static_cast(MotherPdgChunkBase) - 0.5f}}}}, // Hierarchical MC truth purity counters: all = correct species + mis-ID // + no label; correct species = correct collision + wrong collision; // correct collision = primary + weak + material. - {"purityMC/hHadron", "Selected pion truth composition;signed reconstructed p_{T} (GeV/c);category;centrality", {HistType::kTH3F, {{280, -7.f, 7.f}, {NPurityCategories, -0.5f, static_cast(NPurityCategories) - 0.5f}, {40, 0.f, 100.f}}}}, + {"purityMC/hHadron", "Selected hadron truth composition;signed reconstructed p_{T} (GeV/c);category;centrality", {HistType::kTH3F, {{280, -7.f, 7.f}, {NPurityCategories, -0.5f, static_cast(NPurityCategories) - 0.5f}, {40, 0.f, 100.f}}}}, {"purityMC/hNucleus", "Selected nucleus truth composition;signed physical reconstructed p_{T} (GeV/c);category;centrality", {HistType::kTH3F, {{280, -7.f, 7.f}, {NPurityCategories, -0.5f, static_cast(NPurityCategories) - 0.5f}, {40, 0.f, 100.f}}}}, // dE/dx @@ -753,12 +767,12 @@ struct HadNucleiFemto { // Purity {"purity/h2NsigmaNuTPC_preselection", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, {"purity/h2NsigmaNuTPC_preselecComp", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, - {"purity/h2NSigmaNuITS_preselection", "NsigmaNu ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} Nu", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {120, -3.0f, 3.0f}}}}, + {"purity/h2NSigmaNuITS_preselection", "NsigmaNu ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} Nu", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {120, -5.0f, 5.0f}}}}, {"purity/h2NsigmaNuTOF_preselection", "NsigmaNu TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, - {"purity/h2NsigmaNuComb_preselection", "NsigmaNu TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {100, 0.0f, 5.0f}}}}, + {"purity/h2NsigmaNuComb_preselection", "NsigmaNu TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {100, 0.0f, 7.0f}}}}, {"purity/h2NsigmaHadTPC_preselection", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, {"purity/h2NsigmaHadTOF_preselection", "NsigmaHad TOF distribution; #iit{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(p)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, - {"purity/h2NsigmaHadComb_preselection", "NsigmaHad TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(had)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {100, 0.0f, 5.0f}}}}, + {"purity/h2NsigmaHadComb_preselection", "NsigmaHad TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(had)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {100, 0.0f, 7.0f}}}}, // Hypertriton {"hHe3TPCnsigma", "NsigmaHe3 TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(He3)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {200, -5.0f, 5.0f}}}}, @@ -1247,6 +1261,18 @@ struct HadNucleiFemto { candidate.tpcNClsCrossedRows() >= hadronPid.settingPionTPCCrossedRowsMin.value; } + template + bool selectProtonTrackForDcaFit(const Ttrack& candidate) const + { + constexpr float protonEtaMax = 0.8f; + constexpr int protonTPCNClsFoundMin = 90; + constexpr int protonTPCCrossedRowsMin = 80; + return std::abs(candidate.eta()) < protonEtaMax && + std::abs(candidate.pt()) > 0.f && + candidate.tpcNClsFound() > protonTPCNClsFoundMin && + candidate.tpcNClsCrossedRows() > protonTPCCrossedRowsMin; + } + template bool selectTritonTrackForDcaFit(const Ttrack& candidate) const { @@ -1270,9 +1296,11 @@ struct HadNucleiFemto { if (species.settingHadPDGCode.value == static_cast(PDG_t::kPiPlus)) { return selectPionTrackForDcaFit(candidate); } - // The fraction feature is intended for pion-nucleus configurations. Keep - // the nominal selection for other supported hadrons instead of silently - // changing their established cuts. + if (species.settingHadPDGCode.value == static_cast(PDG_t::kProton)) { + return selectProtonTrackForDcaFit(candidate); + } + // Keep the nominal selection for other supported hadrons instead of + // silently changing their established cuts. return selectTrackHadron(candidate); } @@ -1459,8 +1487,6 @@ struct HadNucleiFemto { template bool selectionPIDProton(const Ttrack& candidate) { - constexpr float protonPtMin = 0.5f; - constexpr float protonPtMax = 3.0f; constexpr float protonPCombMin = 0.75f; constexpr float protonTPCNsigmaMax = 3.0f; constexpr float protonCombNsigmaMax = 3.0f; @@ -1468,7 +1494,7 @@ struct HadNucleiFemto { const float tpcNSigmaPr = candidate.tpcNSigmaPr(); mQaRegistry.fill(HIST("h2NsigmaHadTPC_preselection"), candidate.sign() * candidate.tpcInnerParam(), tpcNSigmaPr); - if (std::abs(candidate.pt()) <= protonPtMin || std::abs(candidate.pt()) >= protonPtMax) { + if (std::abs(candidate.pt()) <= hadronPid.settingProtonPtMin || std::abs(candidate.pt()) >= hadronPid.settingProtonPtMax) { return false; } @@ -3065,7 +3091,7 @@ struct HadNucleiFemto { std::unordered_map>& mixingPools, int& mixingRunNumber) { - const BinningType configuredBinningPolicy{{axisVertex, axisCentrality}, true}; + const CentralityBinningType configuredBinningPolicy{{axisVertex, axisCentrality}, true}; for (const auto& collision : collisions) { if (!selectCollision(collision, bcs)) { continue; @@ -3217,10 +3243,11 @@ struct HadNucleiFemto { } PROCESS_SWITCH(HadNucleiFemto, processSameEvent, "Process Same event", false); - void processMixedEvent(const CollisionsFull& collisions, const TrackCandidates& tracks, const aod::BCsWithTimestamps&) + void processMixedEvent(const CollisionsFullWithPVMult& collisions, const TrackCandidates& tracks, const aod::BCsWithTimestamps&) { LOG(debug) << "Processing mixed event"; - const BinningType configuredBinningPolicy{{axisVertex, axisCentrality}, true}; + const CentralityBinningType centralityBinningPolicy{{axisVertex, axisCentrality}, true}; + const MultiplicityBinningType multiplicityBinningPolicy{{axisVertex, axisMultiplicity}, true}; for (const auto& collision : collisions) { mQaRegistry.fill(HIST("hMixedEventSelections"), 0); @@ -3266,7 +3293,12 @@ struct HadNucleiFemto { continue; } - const int poolBin = configuredBinningPolicy.getBin(std::make_tuple(collision.posZ(), collision.centFT0C())); + const int poolBin = eventMixing.settingUseMultiplicityBinning.value + ? multiplicityBinningPolicy.getBin(std::make_tuple(collision.posZ(), collision.multNTracksPV())) + : centralityBinningPolicy.getBin(std::make_tuple(collision.posZ(), collision.centFT0C())); + if (poolBin < 0) { + continue; + } auto& pool = mMixingPools[poolBin]; mQaRegistry.fill(HIST("hMixingPoolOccupancy"), pool.size()); @@ -3453,7 +3485,7 @@ struct HadNucleiFemto { // MC DCA templates use the relaxed-DCA selection. MC purity uses the full // nominal candidate selection, including its DCA requirement. - void processDcaFractionPurityMC(const CollisionsFullMC& collisions, const TrackCandidatesMC& tracks, const aod::McParticles&, const aod::BCsWithTimestamps& bcs) + void processDcaFractionPurityMC(const CollisionsFullMC& collisions, const TrackCandidatesMCDca& tracks, const aod::McParticles&, const aod::BCsWithTimestamps& bcs) { for (const auto& collision : collisions) { if (!selectCollision(collision, bcs)) { @@ -3602,10 +3634,12 @@ struct HadNucleiFemto { } else if (passTrackNu && useHelium3Nucleus()) { const float tpcNSigmaHe3 = computeNSigmaHe3(track); const float signedPtHe3 = track.sign() * 2.f * track.pt(); - mQaRegistry.fill(HIST("purity/h2NsigmaNuTPC_preselection"), signedPtHe3, tpcNSigmaHe3); o2::aod::ITSResponse itsResponse; const float itsNSigmaHe3 = itsResponse.nSigmaITS(track.itsClusterSizes(), track.p(), track.eta()); mQaRegistry.fill(HIST("purity/h2NSigmaNuITS_preselection"), signedPtHe3, itsNSigmaHe3); + if (itsNSigmaHe3 >= helium3Pid.settingITSNSigmaMinHe3) { + mQaRegistry.fill(HIST("purity/h2NsigmaNuTPC_preselection"), signedPtHe3, tpcNSigmaHe3); + } } else if (passTrackNu && useTritonNucleus()) { const float tpcNSigmaTr = track.tpcNSigmaTr(); o2::aod::ITSResponse itsResponse;