diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx b/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx index 5a11c2ae50d..e6bbb5e8d7f 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx +++ b/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx @@ -207,6 +207,9 @@ struct LongrangeMaker { Configurable minV0DcaPiLambda{"minV0DcaPiLambda", 0.2f, "Min V0 pion DCA for Lambda"}; Configurable minV0DcaPr{"minV0DcaPr", 0.07f, "Min V0 proton DCA for Lambda"}; Configurable maxLambdaLifeTime{"maxLambdaLifeTime", 30.0f, "Maximum Lambda lifetime (in cm)"}; + + Configurable rejK0sMassWindow{"rejK0sMassWindow", 0.012f, "K0s mass rejection window for Lambda (12 MeV/c^2)"}; + Configurable cfgQAV0Mask{"cfgQAV0Mask", 7, "Bitmask for V0 QA: 1=K0s, 2=Lambda, 4=ALambda, 7=All"}; } cfgv0trksel; struct : ConfigurableGroup { @@ -216,6 +219,23 @@ struct LongrangeMaker { ConfigurableAxis axisMFTAmbDegree{"axisMFTAmbDegree", {50, -0.5, 49.5}, "Track Ambiguity axis"}; ConfigurableAxis axisEta = {"axisEta", {100, -5, 5}, "eta axis"}; ConfigurableAxis axisPhi{"axisPhi", {72, 0, TwoPI}, "#phi axis"}; + + ConfigurableAxis axisV0Species{"axisV0Species", {3, -0.5, 2.5}, "V0 Species (0=K0s, 1=#Lambda, 2=#bar{#Lambda})"}; + ConfigurableAxis axisAlpha{"axisAlpha", {100, -1.0, 1.0}, "Armenteros #alpha"}; + ConfigurableAxis axisQt{"axisQt", {100, 0.0, 0.42}, "Armenteros q_{T} (GeV/c)"}; + ConfigurableAxis axisV0Pt{"axisV0Pt", {100, 0.0, 10.0}, "V0 p_{T} (GeV/c)"}; + ConfigurableAxis axisMass{"axisMass", {150, 0.4, 1.2}, "Invariant Mass (GeV/c^{2})"}; + ConfigurableAxis axisDcaV0Dau{"axisDcaV0Dau", {100, 0.0, 1.5}, "DCA between V0 Daughters (cm)"}; + ConfigurableAxis axisDcaPosToPv{"axisDcaPosToPv", {100, 0.0, 10.0}, "DCA Pos-Prong to PV (cm)"}; + ConfigurableAxis axisDcaNegToPv{"axisDcaNegToPv", {100, 0.0, 10.0}, "DCA Neg-Prong to PV (cm)"}; + ConfigurableAxis axisDcaV0ToPv{"axisDcaV0ToPv", {100, 0.0, 5.0}, "DCA V0 to PV (cm)"}; + ConfigurableAxis axisCosPA{"axisCosPA", {100, 0.97, 1.0}, "Cosine of Pointing Angle (cos#theta_{PA})"}; + ConfigurableAxis axisRadius{"axisRadius", {100, 0.0, 100.0}, "V0 2D Decay Radius (cm)"}; + ConfigurableAxis axisCtau{"axisCtau", {100, 0.0, 50.0}, "Proper Lifetime c#tau (cm)"}; + + ConfigurableAxis axisPQA{"axisPQA", {100, 0.0, 10.0}, "p (GeV/c)"}; + ConfigurableAxis axisTpcSignal{"axisTpcSignal", {250, 0, 250}, "TPC dE/dx (a.u.)"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 15, 25, 30, 40, 50, 60, 80, 100, 150, 200}, "Multiplicity / Centrality"}; } cfgAxis; Configurable> itsNsigmaPidCut{"itsNsigmaPidCut", std::vector{3, 2.5, 2, -3, -2.5, -2}, "ITS n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma"}; @@ -228,7 +248,7 @@ struct LongrangeMaker { Service pdg; o2::ccdb::CcdbApi ccdbApi; o2::ft0::Geometry ft0Det; - std::vector* offsetFT0; + std::vector* offsetFT0{nullptr}; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; TrackSelection myTrackFilter; @@ -315,6 +335,17 @@ struct LongrangeMaker { histos.add("FT0C_Channel_vs_phi", "FT0C_Channel_vs_phi", kTH2D, {cfgAxis.axisPhi, cfgAxis.axisChannel}); histos.add("h3DVtxZetaPhi", "", kTH3D, {{20, -10, 10}, {16, -0.8, +0.8}, {100, 0., TwoPI}}); + histos.add("hArmenteros_before", "Armenteros-Podolanski (Before Cuts);#alpha;q_{T} (GeV/c)", kTH2D, {cfgAxis.axisAlpha, cfgAxis.axisQt}); + histos.add("hArmenteros_after", "Armenteros-Podolanski (After Cuts);V0 Species;#alpha;q_{T} (GeV/c)", kTH3D, {cfgAxis.axisV0Species, cfgAxis.axisAlpha, cfgAxis.axisQt}); + histos.add("hTopoQA", "V0 Topological and Kinematic QA;V0 Species;DCA between V0 Daughters (cm);DCA Pos-Prong to PV (cm);DCA Neg-Prong to PV (cm);DCA V0 to PV (cm);Cosine of Pointing Angle (cos#theta_{PA});V0 2D Decay Radius (cm);Proper Lifetime c#tau (cm);V0 p_{T} (GeV/c);Invariant Mass (GeV/c^{2})", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisDcaV0Dau, cfgAxis.axisDcaPosToPv, cfgAxis.axisDcaNegToPv, cfgAxis.axisDcaV0ToPv, cfgAxis.axisCosPA, cfgAxis.axisRadius, cfgAxis.axisCtau, cfgAxis.axisV0Pt, cfgAxis.axisMass}); + + // V0 Daughter dE/dx Histograms + histos.add("hTpcdEdx_pos_before", "Pos-prong dE/dx Before PID;V0 Species;Multiplicity;p (GeV/c);TPC dE/dx", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisMultiplicity, cfgAxis.axisPQA, cfgAxis.axisTpcSignal}); + histos.add("hTpcdEdx_neg_before", "Neg-prong dE/dx Before PID;V0 Species;Multiplicity;p (GeV/c);TPC dE/dx", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisMultiplicity, cfgAxis.axisPQA, cfgAxis.axisTpcSignal}); + + histos.add("hTpcdEdx_pos_after", "Pos-prong dE/dx After PID;V0 Species;Multiplicity;p (GeV/c);TPC dE/dx", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisMultiplicity, cfgAxis.axisPQA, cfgAxis.axisTpcSignal}); + histos.add("hTpcdEdx_neg_after", "Neg-prong dE/dx After PID;V0 Species;Multiplicity;p (GeV/c);TPC dE/dx", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisMultiplicity, cfgAxis.axisPQA, cfgAxis.axisTpcSignal}); + myTrackFilter = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, TrackSelection::GlobalTrackRun3DCAxyCut::Default); myTrackFilter.SetPtRange(cfgtrksel.cfgPtCutMin, cfgtrksel.cfgPtCutMax); @@ -816,9 +847,9 @@ struct LongrangeMaker { } } auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex()); - float multiplicity = countNTracks(recTracksPart, RecCol.posZ()); + float recMultiplicity = countNTracks(recTracksPart, RecCol.posZ()); float centrality = selColCent(RecCol); - lrcollision(bc.runNumber(), RecCol.posZ(), multiplicity, centrality, bc.timestamp()); + lrcollision(bc.runNumber(), RecCol.posZ(), recMultiplicity, centrality, bc.timestamp()); lrcollisionMcLabel(RecCol.mcCollisionId()); // track loop @@ -1004,6 +1035,86 @@ struct LongrangeMaker { } } + void processV0QA(CollTable::iterator const& col, aod::V0Datas const& V0s, TrksTable const& tracks) + { + if (!isEventSelected(col)) { + return; + } + + float multiplicity = selColCent(col); + if (multiplicity == -1) { + multiplicity = countNTracks(tracks, col.posZ()); + } + + bool checkK0s = (cfgv0trksel.cfgQAV0Mask & 1); + bool checkLam = (cfgv0trksel.cfgQAV0Mask & 2); + bool checkALam = (cfgv0trksel.cfgQAV0Mask & 4); + + for (const auto& v0 : V0s) { + if (!isSelectV0Track(v0)) { + continue; + } + + auto posTrack = v0.template posTrack_as(); + auto negTrack = v0.template negTrack_as(); + float posP = posTrack.p(); + float negP = negTrack.p(); + float posSignal = posTrack.tpcSignal(); + float negSignal = negTrack.tpcSignal(); + + histos.fill(HIST("hArmenteros_before"), v0.alpha(), v0.qtarm()); + + // Evaluate topology ONLY (PID disabled) + bool isK0sTopoOnly = checkK0s && isSelectK0s(col, v0, false); + bool isLamTopoOnly = checkLam && isSelectLambda(col, v0, false); + bool isAlamTopoOnly = checkALam && isSelectLambda(col, v0, false); + + // Evaluate full selection (PID enabled) + bool isK0sTag = checkK0s && isSelectK0s(col, v0, true); + bool lambdaTag = checkLam && isSelectLambda(col, v0, true); + bool antilambdaTag = checkALam && isSelectLambda(col, v0, true); + + // ---------------- K0s ---------------- + if (isK0sTopoOnly) { + histos.fill(HIST("hTpcdEdx_pos_before"), 0.0f, multiplicity, posP, posSignal); + histos.fill(HIST("hTpcdEdx_neg_before"), 0.0f, multiplicity, negP, negSignal); + } + if (isK0sTag) { + histos.fill(HIST("hTpcdEdx_pos_after"), 0.0f, multiplicity, posP, posSignal); + histos.fill(HIST("hTpcdEdx_neg_after"), 0.0f, multiplicity, negP, negSignal); + histos.fill(HIST("hArmenteros_after"), 0.0f, v0.alpha(), v0.qtarm()); + float ctau = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * o2::constants::physics::MassK0; + histos.fill(HIST("hTopoQA"), 0.0f, v0.dcaV0daughters(), std::abs(v0.dcapostopv()), std::abs(v0.dcanegtopv()), std::abs(v0.dcav0topv()), v0.v0cosPA(), v0.v0radius(), ctau, v0.pt(), v0.mK0Short()); + } + + // -------------- Lambda --------------- + if (isLamTopoOnly) { + histos.fill(HIST("hTpcdEdx_pos_before"), 1.0f, multiplicity, posP, posSignal); + histos.fill(HIST("hTpcdEdx_neg_before"), 1.0f, multiplicity, negP, negSignal); + } + if (lambdaTag) { + histos.fill(HIST("hTpcdEdx_pos_after"), 1.0f, multiplicity, posP, posSignal); + histos.fill(HIST("hTpcdEdx_neg_after"), 1.0f, multiplicity, negP, negSignal); + histos.fill(HIST("hArmenteros_after"), 1.0f, v0.alpha(), v0.qtarm()); + float ctau = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * o2::constants::physics::MassLambda; + histos.fill(HIST("hTopoQA"), 1.0f, v0.dcaV0daughters(), std::abs(v0.dcapostopv()), std::abs(v0.dcanegtopv()), std::abs(v0.dcav0topv()), v0.v0cosPA(), v0.v0radius(), ctau, v0.pt(), v0.mLambda()); + } + + // ----------- Anti-Lambda ------------- + if (isAlamTopoOnly) { + histos.fill(HIST("hTpcdEdx_pos_before"), 2.0f, multiplicity, posP, posSignal); + histos.fill(HIST("hTpcdEdx_neg_before"), 2.0f, multiplicity, negP, negSignal); + } + if (antilambdaTag) { + histos.fill(HIST("hTpcdEdx_pos_after"), 2.0f, multiplicity, posP, posSignal); + histos.fill(HIST("hTpcdEdx_neg_after"), 2.0f, multiplicity, negP, negSignal); + histos.fill(HIST("hArmenteros_after"), 2.0f, v0.alpha(), v0.qtarm()); + float ctau = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * o2::constants::physics::MassLambda; + histos.fill(HIST("hTopoQA"), 2.0f, v0.dcaV0daughters(), std::abs(v0.dcapostopv()), std::abs(v0.dcanegtopv()), std::abs(v0.dcav0topv()), v0.v0cosPA(), v0.v0radius(), ctau, v0.pt(), v0.mAntiLambda()); + } + } + } + template bool isGenPartSelected(CheckGenPart const& particle) { @@ -1306,7 +1417,7 @@ struct LongrangeMaker { } template - bool isSelectK0s(Collision const& col, const V0candidate& v0) + bool isSelectK0s(Collision const& col, const V0candidate& v0, bool applyPidCut = true) { const auto& posTrack = v0.template posTrack_as(); const auto& negTrack = v0.template negTrack_as(); @@ -1316,7 +1427,7 @@ struct LongrangeMaker { if (v0.mK0Short() < cfgv0trksel.minK0sMass || v0.mK0Short() > cfgv0trksel.maxK0sMass) { return false; } - if ((v0.qtarm() / std::abs(v0.alpha())) < cfgv0trksel.minqtArmenterosForK0s) { + if (v0.qtarm() < (cfgv0trksel.minqtArmenterosForK0s * std::abs(v0.alpha()))) { return false; } if (v0.v0radius() > cfgv0trksel.maxK0sRadius || v0.v0radius() < cfgv0trksel.minK0sRadius) { @@ -1331,25 +1442,40 @@ struct LongrangeMaker { if (std::abs(ctauK0s) > cfgv0trksel.maxK0sLifeTime) { return false; } - if (((std::abs(posTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts))) { - return false; + if (applyPidCut) { + if (std::abs(posTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts || + std::abs(negTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts) { + return false; + } } - if ((std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPiK0s || std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPiK0s)) { + if (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPiK0s || + std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPiK0s) { return false; } return true; } template - bool isSelectLambda(Collision const& col, const V0candidate& v0) + bool isSelectLambda(Collision const& col, const V0candidate& v0, bool applyPidCut = true) { const auto& posTrack = v0.template posTrack_as(); const auto& negTrack = v0.template negTrack_as(); float ctauLambda = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * o2::constants::physics::MassLambda; - if ((v0.mLambda() < cfgv0trksel.minLambdaMass || v0.mLambda() > cfgv0trksel.maxLambdaMass) && - (v0.mAntiLambda() < cfgv0trksel.minLambdaMass || v0.mAntiLambda() > cfgv0trksel.maxLambdaMass)) { + + if constexpr (pid == KindOfV0::kLambda) { + if (v0.mLambda() < cfgv0trksel.minLambdaMass || v0.mLambda() > cfgv0trksel.maxLambdaMass) { + return false; + } + } else if constexpr (pid == KindOfV0::kAntiLambda) { + if (v0.mAntiLambda() < cfgv0trksel.minLambdaMass || v0.mAntiLambda() > cfgv0trksel.maxLambdaMass) { + return false; + } + } + + if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0) < cfgv0trksel.rejK0sMassWindow) { return false; } + if (v0.v0radius() > cfgv0trksel.maxLambdaRadius || v0.v0radius() < cfgv0trksel.minLambdaRadius) { return false; } @@ -1359,17 +1485,29 @@ struct LongrangeMaker { if (v0.dcaV0daughters() > cfgv0trksel.maxDcaV0DauLambda) { return false; } - if (pid == KindOfV0::kLambda && (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPr || std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPiLambda)) { - return false; - } - if (pid == KindOfV0::kAntiLambda && (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPiLambda || std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPr)) { - return false; - } - if (pid == KindOfV0::kLambda && ((std::abs(posTrack.tpcNSigmaPr()) > cfgv0trksel.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts))) { - return false; + if constexpr (pid == KindOfV0::kLambda) { + if (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPr || + std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPiLambda) { + return false; + } + } else if constexpr (pid == KindOfV0::kAntiLambda) { + if (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPiLambda || + std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPr) { + return false; + } } - if (pid == KindOfV0::kAntiLambda && ((std::abs(posTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPr()) > cfgv0trksel.daughPIDCuts))) { - return false; + if (applyPidCut) { + if constexpr (pid == KindOfV0::kLambda) { + if (std::abs(posTrack.tpcNSigmaPr()) > cfgv0trksel.daughPIDCuts || + std::abs(negTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts) { + return false; + } + } else if constexpr (pid == KindOfV0::kAntiLambda) { + if (std::abs(posTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts || + std::abs(negTrack.tpcNSigmaPr()) > cfgv0trksel.daughPIDCuts) { + return false; + } + } } if (std::abs(ctauLambda) > cfgv0trksel.maxLambdaLifeTime) { return false; @@ -1387,7 +1525,7 @@ struct LongrangeMaker { if (hTrkEff == nullptr) { LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgtrksel.cfgEffccdbPath.value.c_str()); } - LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgtrksel.cfgEffccdbPath.value.c_str(), (void*)hTrkEff); + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgtrksel.cfgEffccdbPath.value.c_str(), static_cast(hTrkEff)); } fLoadTrkEffCorr = true; } @@ -1411,6 +1549,7 @@ struct LongrangeMaker { PROCESS_SWITCH(LongrangeMaker, processUpc, "process UPC collisions", false); PROCESS_SWITCH(LongrangeMaker, processMCGen, "process MC generated collisions", false); PROCESS_SWITCH(LongrangeMaker, processMCRec, "process MC both gen and rec collisions", false); + PROCESS_SWITCH(LongrangeMaker, processV0QA, "process V0 QA histograms", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx b/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx index 7471acec39b..cdc9e8568a2 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx @@ -45,6 +45,7 @@ #include #include +#include #include #include @@ -159,6 +160,9 @@ struct LongrangecorrDerived { ConfigurableAxis axisNsigmaTOF{"axisNsigmaTOF", {80, -5, 5}, "nsigmaTOF axis"}; ConfigurableAxis axisTpcSignal{"axisTpcSignal", {250, 0, 250}, "dEdx axis for TPC"}; + ConfigurableAxis axisMcPt{"axisMcPt", {100, 0.2, 10.0}, "p_{T} (GeV/c)"}; + ConfigurableAxis axisMcEta{"axisMcEta", {100, -0.8, 0.8}, "#eta"}; + ConfigurableAxis axisMcPhi{"axisMcPhi", {100, 0., TwoPI}, "#phi"}; } cfgAxis; Configurable cfgFv0Cut{"cfgFv0Cut", 50.0f, "FV0A threshold"}; @@ -246,7 +250,7 @@ struct LongrangecorrDerived { histos.add("Trig_pt", "Trig_pt", kTH1D, {cfgAxis.axisPtTrigger}); histos.add("Trig_pt_corrected", "Trig_pt_corrected", kTH1D, {cfgAxis.axisPtTrigger}); histos.add("Trig_invMass", "Trig_invMass", kTH1D, {cfgAxis.axisInvMassQA}); - histos.add("Trig_hist", "Trig_hist", kTHnSparseF, {cfgAxis.axisSample, cfgAxis.axisVtxZ, cfgAxis.axisMultiplicity, cfgAxis.axisPtTrigger, cfgAxis.axisInvMass}); + histos.add("Trig_hist", "Trigger Track Properties;Sample;Vertex Z (cm);Multiplicity;p_{T} (GeV/c);Invariant Mass (GeV/c^{2})", kTHnSparseF, {cfgAxis.axisSample, cfgAxis.axisVtxZ, cfgAxis.axisMultiplicity, cfgAxis.axisPtTrigger, cfgAxis.axisInvMass}); histos.add("Trig_amp", "Trig_amp", kTH1D, {cfgAxis.axisAmplitude}); histos.add("Channel_vs_Trig_amp", "Channel_vs_Trig_amp", kTH2D, {cfgAxis.axisChannel, cfgAxis.axisAmplitude}); @@ -275,6 +279,11 @@ struct LongrangecorrDerived { if (doprocessTPCtrackEff) { histos.add("hGenMCdndpt", "hGenMCdndpt", kTH3D, {cfgAxis.axisVtxZ, cfgAxis.axisEtaEfficiency, cfgAxis.axisPtEfficiency}); histos.add("hRecMCdndpt", "hRecMCdndpt", kTH3D, {cfgAxis.axisVtxZ, cfgAxis.axisEtaEfficiency, cfgAxis.axisPtEfficiency}); + + if (cfgSel.cfgPidMask == KPidMaskPion || cfgSel.cfgPidMask == KPidMaskKaon || cfgSel.cfgPidMask == KPidMaskProton) { + histos.add("hMCGen_PidPtEtaPhi", "MC Gen Target", kTH3D, {cfgAxis.axisMcPt, cfgAxis.axisMcEta, cfgAxis.axisMcPhi}); + histos.add("hMCRec_PidPtEtaPhi", "MC Rec Target", kTH3D, {cfgAxis.axisMcPt, cfgAxis.axisMcEta, cfgAxis.axisMcPhi}); + } } myTrackFilter = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, @@ -770,6 +779,16 @@ struct LongrangecorrDerived { processSame(col, tracks, ft0as); } + void processV0ft0cSE(CollsTable::iterator const& col, V0TrksTable const& tracks, Ft0cTrksTable const& ft0cs) + { + processSame(col, tracks, ft0cs); + } + + void processV0tpcSE(CollsTable::iterator const& col, V0TrksTable const& v0s, TrksTable const& tracks) + { + processSame(col, v0s, tracks); + } + void processV0mftSE(CollsTable::iterator const& col, V0TrksTable const& tracks, MftTrksTable const& mfts) { processSame(col, tracks, mfts); @@ -805,6 +824,16 @@ struct LongrangecorrDerived { processMixed(cols, tracks, ft0as); } + void processV0ft0cME(CollsTable const& cols, V0TrksTable const& tracks, Ft0cTrksTable const& ft0cs) + { + processMixed(cols, tracks, ft0cs); + } + + void processV0tpcME(CollsTable const& cols, V0TrksTable const& v0s, TrksTable const& tracks) + { + processMixed(cols, v0s, tracks); + } + void processV0mftME(CollsTable const& cols, V0TrksTable const& tracks, MftTrksTable const& mfts) { processMixed(cols, tracks, mfts); @@ -855,6 +884,11 @@ struct LongrangecorrDerived { processSame(col, tracks, ft0as); } + void processUpcV0ft0cSE(UpcCollsTable::iterator const& col, V0TrksUpcTable const& tracks, Ft0cTrksUpcTable const& ft0cs) + { + processSame(col, tracks, ft0cs); + } + void processUpcV0mftSE(UpcCollsTable::iterator const& col, V0TrksUpcTable const& tracks, MftTrksUpcTable const& mfts) { if (!isUpcEventSelected(col)) { @@ -888,6 +922,11 @@ struct LongrangecorrDerived { processMixed(cols, tracks, ft0as); } + void processUpcV0ft0cME(UpcCollsTable const& cols, V0TrksUpcTable const& tracks, Ft0cTrksUpcTable const& ft0cs) + { + processMixed(cols, tracks, ft0cs); + } + void processUpcV0mftME(UpcCollsTable const& cols, V0TrksUpcTable const& tracks, MftTrksUpcTable const& mfts) { processMixed(cols, tracks, mfts); @@ -963,6 +1002,16 @@ struct LongrangecorrDerived { processMcGenSame(mccollision, mfts, ft0as); } + void processMcGenV0ft0aSE(McCollsTable::iterator const& mccollision, McTrksTable const& tracks, McFt0aTrksTable const& ft0as) + { + processMcGenSame(mccollision, tracks, ft0as); + } + + void processMcGenV0ft0cSE(McCollsTable::iterator const& mccollision, McTrksTable const& tracks, McFt0cTrksTable const& ft0cs) + { + processMcGenSame(mccollision, tracks, ft0cs); + } + void processMcGenFt0aft0cSE(McCollsTable::iterator const& mccollision, McFt0aTrksTable const& ft0as, McFt0cTrksTable const& ft0cs) { processMcGenSame(mccollision, ft0as, ft0cs); @@ -988,6 +1037,16 @@ struct LongrangecorrDerived { processMcGenMixed(mccollisions, mfts, ft0as); } + void processMcGenV0ft0aME(McCollsTable const& mccollisions, McTrksTable const& tracks, McFt0aTrksTable const& ft0as) + { + processMcGenMixed(mccollisions, tracks, ft0as); + } + + void processMcGenV0ft0cME(McCollsTable const& mccollisions, McTrksTable const& tracks, McFt0cTrksTable const& ft0cs) + { + processMcGenMixed(mccollisions, tracks, ft0cs); + } + void processMcGenFt0aft0cME(McCollsTable const& mccollisions, McFt0aTrksTable const& ft0as, McFt0cTrksTable const& ft0cs) { processMcGenMixed(mccollisions, ft0as, ft0cs); @@ -995,7 +1054,7 @@ struct LongrangecorrDerived { using ColMCTrueTable = soa::Join; using ColMCRecTable = soa::SmallGroups>; - using TrksMCRecTable = soa::Join; + using TrksMCRecTable = soa::Join; Preslice perColMidtrack = aod::track::collisionId; template @@ -1039,7 +1098,6 @@ struct LongrangecorrDerived { continue; if (RecCol.globalIndex() != mcCollision.bestCollisionIndex()) continue; - auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex()); atLeastOne = true; } for (const auto& particle : mcparticles) { @@ -1048,9 +1106,23 @@ struct LongrangecorrDerived { particle.pt() < cfgSel.cfgPtCutMin || particle.pt() > cfgSel.cfgPtCutMax) continue; - if (atLeastOne) + if (atLeastOne) { histos.fill(HIST("hGenMCdndpt"), mcCollision.posZ(), particle.eta(), particle.pt()); + + if (cfgSel.cfgPidMask == KPidMaskPion || cfgSel.cfgPidMask == KPidMaskKaon || cfgSel.cfgPidMask == KPidMaskProton) { + auto pdgcode = std::abs(particle.pdgCode()); + + bool isTargetGen = (cfgSel.cfgPidMask == KPidMaskPion && pdgcode == PDG_t::kPiPlus) || + (cfgSel.cfgPidMask == KPidMaskKaon && pdgcode == PDG_t::kKPlus) || + (cfgSel.cfgPidMask == KPidMaskProton && pdgcode == PDG_t::kProton); + + if (isTargetGen) { + histos.fill(HIST("hMCGen_PidPtEtaPhi"), particle.pt(), particle.eta(), particle.phi()); + } + } + } } + for (const auto& RecCol : RecCols) { if (!isEventSelected(RecCol)) continue; @@ -1069,6 +1141,40 @@ struct LongrangecorrDerived { continue; if (particle.isPhysicalPrimary()) { histos.fill(HIST("hRecMCdndpt"), mcCollision.posZ(), particle.eta(), particle.pt()); + + bool isTpcPion = (track.tpcNSigmaPi() > cfgSel.cfgPidNsigmaMin && track.tpcNSigmaPi() < cfgSel.cfgPidNsigmaMax); + bool isTpcKaon = (track.tpcNSigmaKa() > cfgSel.cfgPidNsigmaMin && track.tpcNSigmaKa() < cfgSel.cfgPidNsigmaMax); + bool isTpcProton = (track.tpcNSigmaPr() > cfgSel.cfgPidNsigmaMin && track.tpcNSigmaPr() < cfgSel.cfgPidNsigmaMax); + + bool isTofPion = (track.tofNSigmaPi() > cfgSel.cfgPidNsigmaMin && track.tofNSigmaPi() < cfgSel.cfgPidNsigmaMax); + bool isTofKaon = (track.tofNSigmaKa() > cfgSel.cfgPidNsigmaMin && track.tofNSigmaKa() < cfgSel.cfgPidNsigmaMax); + bool isTofProton = (track.tofNSigmaPr() > cfgSel.cfgPidNsigmaMin && track.tofNSigmaPr() < cfgSel.cfgPidNsigmaMax); + + bool isPion = false, isKaon = false, isProton = false; + + if (track.pt() > cfgSel.cfgTofPidPtCut && track.hasTOF()) { + isPion = isTofPion && isTpcPion; + isKaon = isTofKaon && isTpcKaon; + isProton = isTofProton && isTpcProton; + } else if (!(track.pt() > cfgSel.cfgTofPidPtCut && !track.hasTOF())) { + isPion = isTpcPion; + isKaon = isTpcKaon; + isProton = isTpcProton; + } + + if ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton)) { + isPion = isKaon = isProton = false; + } + + if (cfgSel.cfgPidMask == KPidMaskPion || cfgSel.cfgPidMask == KPidMaskKaon || cfgSel.cfgPidMask == KPidMaskProton) { + bool isTargetRec = (cfgSel.cfgPidMask == KPidMaskPion && isPion) || + (cfgSel.cfgPidMask == KPidMaskKaon && isKaon) || + (cfgSel.cfgPidMask == KPidMaskProton && isProton); + + if (isTargetRec) { + histos.fill(HIST("hMCRec_PidPtEtaPhi"), particle.pt(), particle.eta(), particle.phi()); + } + } } } } @@ -1170,6 +1276,10 @@ struct LongrangecorrDerived { PROCESS_SWITCH(LongrangecorrDerived, processMftft0aME, "mixed event MFT vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processV0ft0aSE, "same event V0 vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processV0ft0aME, "mixed event V0 vs FT0A", false); + PROCESS_SWITCH(LongrangecorrDerived, processV0ft0cSE, "same event V0 vs FT0C", false); + PROCESS_SWITCH(LongrangecorrDerived, processV0ft0cME, "mixed event V0 vs FT0C", false); + PROCESS_SWITCH(LongrangecorrDerived, processV0tpcSE, "same event V0 vs TPC", false); + PROCESS_SWITCH(LongrangecorrDerived, processV0tpcME, "mixed event V0 vs TPC", false); PROCESS_SWITCH(LongrangecorrDerived, processV0mftSE, "same event V0 vs MFT", false); PROCESS_SWITCH(LongrangecorrDerived, processV0mftME, "mixed event V0 vs MFT", false); PROCESS_SWITCH(LongrangecorrDerived, processFt0aft0cSE, "same event FT0A vs FT0C", false); @@ -1184,6 +1294,8 @@ struct LongrangecorrDerived { PROCESS_SWITCH(LongrangecorrDerived, processUpcMftft0aME, "mixed UPC event MFT vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processUpcV0ft0aSE, "same UPC event V0 vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processUpcV0ft0aME, "mixed UPC event V0 vs FT0A", false); + PROCESS_SWITCH(LongrangecorrDerived, processUpcV0ft0cSE, "same UPC event V0 vs FT0C", false); + PROCESS_SWITCH(LongrangecorrDerived, processUpcV0ft0cME, "mixed UPC event V0 vs FT0C", false); PROCESS_SWITCH(LongrangecorrDerived, processUpcV0mftSE, "same UPC event V0 vs MFT", false); PROCESS_SWITCH(LongrangecorrDerived, processUpcV0mftME, "mixed UPC event V0 vs MFT", false); PROCESS_SWITCH(LongrangecorrDerived, processMcTpcft0aSE, "same MC event TPC vs FT0A", false); @@ -1204,6 +1316,10 @@ struct LongrangecorrDerived { PROCESS_SWITCH(LongrangecorrDerived, processMcGenTpcmftME, "mixed MC gen event TPC vs MFT", false); PROCESS_SWITCH(LongrangecorrDerived, processMcGenMftft0aSE, "same MC gen event MFT vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processMcGenMftft0aME, "mixed MC gen event MFT vs FT0A", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcGenV0ft0aSE, "same MC gen event V0 vs FT0A", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcGenV0ft0aME, "mixed MC gen event V0 vs FT0A", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcGenV0ft0cSE, "same MC gen event V0 vs FT0C", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcGenV0ft0cME, "mixed MC gen event V0 vs FT0C", false); PROCESS_SWITCH(LongrangecorrDerived, processMcGenFt0aft0cSE, "same MC gen event FT0A vs FT0C", false); PROCESS_SWITCH(LongrangecorrDerived, processMcGenFt0aft0cME, "mixed MC gen event FT0A vs FT0C", false); PROCESS_SWITCH(LongrangecorrDerived, processTPCtrackEff, "process TPC track efficiency", false);