diff --git a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx index bd09a8f37c7..98f3a1aa513 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx @@ -95,11 +95,14 @@ DECLARE_SOA_COLUMN(Pt, pt, float); DECLARE_SOA_COLUMN(Eta, eta, float); DECLARE_SOA_COLUMN(Phi, phi, float); DECLARE_SOA_COLUMN(Rap, rap, float); +DECLARE_SOA_COLUMN(Px, px, float); +DECLARE_SOA_COLUMN(Py, py, float); +DECLARE_SOA_COLUMN(Pz, pz, float); DECLARE_SOA_COLUMN(Mass, mass, float); DECLARE_SOA_COLUMN(PosTrackId, posTrackId, int64_t); DECLARE_SOA_COLUMN(NegTrackId, negTrackId, int64_t); -DECLARE_SOA_COLUMN(PosTrackKin, posTrackKin, float[3]); -DECLARE_SOA_COLUMN(NegTrackKin, negTrackKin, float[3]); +DECLARE_SOA_COLUMN(PosTrackKin, posTrackKin, std::vector); +DECLARE_SOA_COLUMN(NegTrackKin, negTrackKin, std::vector); DECLARE_SOA_COLUMN(PartType, partType, int8_t); DECLARE_SOA_COLUMN(CorrFact, corrFact, float); } // namespace lambdatrack @@ -109,6 +112,9 @@ DECLARE_SOA_TABLE(LambdaTracks, "AOD", "LAMBDATRACKS", o2::soa::Index<>, lambdatrack::Eta, lambdatrack::Phi, lambdatrack::Rap, + lambdatrack::Px, + lambdatrack::Py, + lambdatrack::Pz, lambdatrack::Mass, lambdatrack::PosTrackId, lambdatrack::NegTrackId, @@ -125,6 +131,9 @@ DECLARE_SOA_COLUMN(Pt, pt, float); DECLARE_SOA_COLUMN(Eta, eta, float); DECLARE_SOA_COLUMN(Phi, phi, float); DECLARE_SOA_COLUMN(Rap, rap, float); +DECLARE_SOA_COLUMN(Px, px, float); +DECLARE_SOA_COLUMN(Py, py, float); +DECLARE_SOA_COLUMN(Pz, pz, float); DECLARE_SOA_COLUMN(Mass, mass, float); DECLARE_SOA_COLUMN(KaonTrackId, kaonTrackId, int64_t); DECLARE_SOA_COLUMN(PartType, partType, int8_t); @@ -136,6 +145,9 @@ DECLARE_SOA_TABLE(KaonTracks, "AOD", "KAONTRACKS", o2::soa::Index<>, kaontrack::Eta, kaontrack::Phi, kaontrack::Rap, + kaontrack::Px, + kaontrack::Py, + kaontrack::Pz, kaontrack::Mass, kaontrack::KaonTrackId, kaontrack::PartType, @@ -177,6 +189,9 @@ DECLARE_SOA_TABLE(LambdaMcGenTracks, "AOD", "LMCGENTRACKS", o2::soa::Index<>, lambdatrack::Eta, lambdatrack::Phi, lambdatrack::Rap, + lambdatrack::Px, + lambdatrack::Py, + lambdatrack::Pz, lambdatrack::Mass, lambdatrack::PosTrackId, lambdatrack::NegTrackId, @@ -194,6 +209,9 @@ DECLARE_SOA_TABLE(KaonMcGenTracks, "AOD", "KMCGENTRACKS", o2::soa::Index<>, kaontrack::Eta, kaontrack::Phi, kaontrack::Rap, + kaontrack::Px, + kaontrack::Py, + kaontrack::Pz, kaontrack::Mass, kaontrack::KaonTrackId, kaontrack::PartType, @@ -213,9 +231,6 @@ enum TrackLabels { kPassV0KinCuts, kPassV0TopoSel, kPassK0ShortMassRej, - kV0IsBothLambdaAntiLambda, - kNotLambdaNotAntiLambda, - kV0IsLambdaOrAntiLambda, kPassV0DauTrackSel, kAllSelPassed, kEffCorrPtCent, @@ -254,10 +269,7 @@ enum ParticlePairType { kLambdaKaonPlus, kLambdaKaonMinus, kAntiLambdaKaonPlus, - kAntiLambdaKaonMinus, - kKaonPlusKaonMinus, - kKaonPlusKaonPlus, - kKaonMinusKaonMinus + kAntiLambdaKaonMinus }; enum ShareDauLambda { @@ -295,18 +307,14 @@ struct LambdaTableProducer { // Collisions Configurable cCentEstimator{"cCentEstimator", 1, "Centrality Estimator : 0-FT0M, 1-FT0C"}; - Configurable cMinZVtx{"cMinZVtx", -7.0, "Min VtxZ cut"}; - Configurable cMaxZVtx{"cMaxZVtx", 7.0, "Max VtxZ cut"}; + Configurable cMinZVtx{"cMinZVtx", -10.0, "Min VtxZ cut"}; + Configurable cMaxZVtx{"cMaxZVtx", 10.0, "Max VtxZ cut"}; Configurable cMinCent{"cMinCent", 0., "Minumum Centrality"}; Configurable cMaxCent{"cMaxCent", 100.0, "Maximum Centrality"}; Configurable cSel8Trig{"cSel8Trig", true, "Sel8 (T0A + T0C) Selection Run3"}; - Configurable cTriggerTvxSel{"cTriggerTvxSel", false, "Trigger Time and Vertex Selection"}; - Configurable cTFBorder{"cTFBorder", false, "Timeframe Border Selection"}; - Configurable cNoItsROBorder{"cNoItsROBorder", false, "No ITSRO Border Cut"}; - Configurable cItsTpcVtx{"cItsTpcVtx", false, "ITS+TPC Vertex Selection"}; - Configurable cPileupReject{"cPileupReject", false, "Pileup rejection"}; - Configurable cZVtxTimeDiff{"cZVtxTimeDiff", false, "z-vtx time diff selection"}; - Configurable cIsGoodITSLayers{"cIsGoodITSLayers", false, "Good ITS Layers All"}; + Configurable cPileupReject{"cPileupReject", true, "Pileup rejection"}; + Configurable cZVtxTimeDiff{"cZVtxTimeDiff", true, "z-vtx time diff selection"}; + Configurable cIsGoodITSLayers{"cIsGoodITSLayers", true, "Good ITS Layers All"}; // Tracks Configurable cTrackMinPt{"cTrackMinPt", 0.1, "p_{T} minimum"}; @@ -316,8 +324,8 @@ struct LambdaTableProducer { Configurable cRemoveAmbiguousTracks{"cRemoveAmbiguousTracks", false, "Remove Ambiguous Tracks"}; // Kaon Tracks - Configurable cKaonMinPt{"cKaonMinPt", 0.4, "Kaon Min pT"}; - Configurable cKaonMaxPt{"cKaonMaxPt", 2.2, "Kaon Max pT"}; + Configurable cKaonMinPt{"cKaonMinPt", 0.3, "Kaon Min pT"}; + Configurable cKaonMaxPt{"cKaonMaxPt", 2.3, "Kaon Max pT"}; Configurable cKaonRapCut{"cKaonRapCut", 0.5, "Kaon |y| cut"}; Configurable cKaonGlobalSel{"cKaonGlobalSel", true, "Global Track"}; Configurable cKaonDcaXYCut{"cKaonDcaXYCut", 0.1, "DcaXY Cut"}; @@ -325,25 +333,29 @@ struct LambdaTableProducer { Configurable cTpcElRejCutMin{"cTpcElRejCutMin", -3., "Electron Rejection Cut Minimum"}; Configurable cTpcElRejCutMax{"cTpcElRejCutMax", 5., "Electron Rejection Cut Maximum"}; Configurable cKaonTpcNSigmaCut{"cKaonTpcNSigmaCut", 2, "TPC Kaon NSigma Cut"}; - Configurable cTpcRejCut{"cTpcRejCut", 3, "TPC Rej Cut"}; + Configurable cTpcRejCut{"cTpcRejCut", 2, "TPC Rej Cut"}; Configurable cKaonTofNSigmaCut{"cKaonTofNSigmaCut", 2, "TOF Kaon NSigma Cut"}; - Configurable cTofRejCut{"cTofRejCut", 3, "TOF Rej Cut"}; - Configurable cKaonTpcPtSel{"cKaonTpcPtSel", 0.6, "Kaon TPC pT cutoff"}; + Configurable cTofRejCut{"cTofRejCut", 2, "TOF Rej Cut"}; + Configurable cKaonTpcPtSel{"cKaonTpcPtSel", 0.7, "Kaon TPC pT cutoff"}; // V0s - Configurable cMinDcaProtonToPV{"cMinDcaProtonToPV", 0.01, "Minimum Proton DCAr to PV"}; - Configurable cMinDcaPionToPV{"cMinDcaPionToPV", 0.1, "Minimum Pion DCAr to PV"}; + Configurable cMinDcaProtonToPV{"cMinDcaProtonToPV", 0.02, "Minimum Proton DCAr to PV"}; + Configurable cMinDcaPionToPV{"cMinDcaPionToPV", 0.06, "Minimum Pion DCAr to PV"}; Configurable cMaxDcaV0Daughters{"cMaxDcaV0Daughters", 1., "Maximum DCA between V0 daughters"}; - Configurable cMaxDcaV0ToPV{"cMaxDcaV0ToPV", 999.0, "Maximum DCA V0 to PV"}; + Configurable cMaxDcaV0ToPV{"cMaxDcaV0ToPV", 0.1, "Maximum DCA V0 to PV"}; Configurable cMinV0TransRadius{"cMinV0TransRadius", 0.5, "Minimum V0 radius from PV"}; Configurable cMaxV0CTau{"cMaxV0CTau", 30.0, "Maximum ctau"}; Configurable cMinV0CosPA{"cMinV0CosPA", 0.995, "Minimum V0 CosPA to PV"}; Configurable cKshortRejMassWindow{"cKshortRejMassWindow", 0.01, "Reject K0Short Candidates"}; + Configurable cArmPodSel{"cArmPodSel", 0.2, "Armentros-Podolanski Selection"}; + + // DCA + Configurable cWeakDecayProcess{"cWeakDecayProcess", 4, "Weak decay process tag for DCA analysis"}; // V0s acceptance Configurable cLambdaMassWindow{"cLambdaMassWindow", 0.007, "Lambda Mass Window"}; - Configurable cLambdaMinPt{"cLambdaMinPt", 0.6, "Minimum Lambda pT"}; - Configurable cLambdaMaxPt{"cLambdaMaxPt", 3.6, "Minimum Lambda pT"}; + Configurable cLambdaMinPt{"cLambdaMinPt", 0.7, "Minimum Lambda pT"}; + Configurable cLambdaMaxPt{"cLambdaMaxPt", 3.7, "Minimum Lambda pT"}; Configurable cLambdaRapCut{"cLambdaRapCut", 0.5, "Lambda |rap| cut"}; Configurable cV0TypeSelection{"cV0TypeSelection", 1, "V0 Type Selection"}; @@ -353,6 +365,10 @@ struct LambdaTableProducer { Configurable cGetMatchEff{"cGetMatchEff", false, "Get Matching Efficiency Flag"}; Configurable cCorrFactHist{"cCorrFactHist", 0, "Efficiency Factor Histogram"}; + // MC + Configurable cSelPrimaryParticle{"cSelPrimaryParticle", false, "Select primary particle"}; + Configurable cSelTrueParticle{"cSelTrueParticle", false, "Select MC PDG matched particle"}; + // CCDB Configurable cUrlCCDB{"cUrlCCDB", "http://alice-ccdb.cern.ch", "ALICE CCDB URL"}; Configurable cPathCCDBRecoEff{"cPathCCDBRecoEff", "Users/y/ypatley/LBF/PP/RecoEfficiency", "Path for ccdb-object for reco efficiency"}; @@ -360,7 +376,7 @@ struct LambdaTableProducer { Configurable nolaterthan{"nolaterthan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; // Initialize CCDB Service - Service ccdb; + Service ccdb{}; o2::parameters::GRPMagField* grpo = nullptr; // Histogram Registry. @@ -372,8 +388,9 @@ struct LambdaTableProducer { // Initialize Global Variables float cent = 0., mult = 0.; - TList *ccdbObjRecoEff, *ccdbObjMatchEff; - static constexpr std::string_view SubDir[] = {"QA/Lambda/", "QA/AntiLambda/", "QA/KaonPlus/", "QA/KaonMinus/"}; + TList* ccdbObjRecoEff = nullptr; + TList* ccdbObjMatchEff = nullptr; + static constexpr auto SubDir = std::array{"QA/Lambda/", "QA/AntiLambda/", "QA/KaonPlus/", "QA/KaonMinus/"}; void init(InitContext const&) { @@ -403,15 +420,18 @@ struct LambdaTableProducer { const AxisSpec axisV0Eta(48, -1.2, 1.2, "#eta"); const AxisSpec axisV0Phi(36, 0., TwoPI, "#phi (rad)"); - const AxisSpec axisRadius(2000, 0, 200, "r(cm)"); - const AxisSpec axisCosPA(300, 0.97, 1.0, "cos(#theta_{PA})"); - const AxisSpec axisDcaV0PV(1000, 0., 10., "dca (cm)"); + const AxisSpec axisRadius(200, 0, 200, "r(cm)"); + const AxisSpec axisCosPA(100, 0.99, 1.0, "cos(#theta_{PA})"); + const AxisSpec axisDcaV0PV(100, 0., 0.1, "dca (cm)"); const AxisSpec axisDcaProngPV(5000, -50., 50., "dca (cm)"); const AxisSpec axisDcaDau(75, 0., 1.5, "Daug DCA (#sigma)"); - const AxisSpec axisCTau(2000, 0, 200, "c#tau (cm)"); + const AxisSpec axisCTau(80, 0, 40, "c#tau (cm)"); const AxisSpec axisAlpha(40, -1, 1, "#alpha"); const AxisSpec axisQtarm(40, 0, 0.4, "q_{T}"); + const AxisSpec axisDcaLambda(100, 0., cMaxDcaV0ToPV, "Dca_{V^{0}}"); + const AxisSpec axisDcaKaon(100, -cKaonDcaXYCut, cKaonDcaXYCut, "Dca_{K}"); + const AxisSpec axisITSTPCTrackPt(100, 0, 10, "p_{T} (GeV/#it{c})"); const AxisSpec axisTrackPt(40, 0, 4, "p_{T} (GeV/#it{c})"); const AxisSpec axisTrackDCA(200, -1, 1, "dca_{XY} (cm)"); @@ -436,7 +456,7 @@ struct LambdaTableProducer { histos.add("Tracks/h2f_itstpctoftrack_centpt", "h2f_itstpctoftrack_centpt", kTH2F, {axisVarCent, axisITSTPCTrackPt}); // QA Lambda - histos.add("QA/Lambda/h3f_centmasspt", "Invariant Mass", kTH3F, {axisCent, axisV0Mass, axisV0Pt}); + histos.add("QA/Lambda/h3f_centmasspt", "Invariant Mass", kTH3F, {axisCent, axisV0Pt, axisV0Mass}); histos.add("QA/Lambda/h2f_qt_vs_alpha", "Armentros-Podolanski Plot", kTH2F, {axisAlpha, axisQtarm}); histos.add("QA/Lambda/h1f_dca_V0_daughters", "DCA between V0 daughters", kTH1F, {axisDcaDau}); histos.add("QA/Lambda/h1f_dca_pos_to_PV", "DCA positive prong to PV", kTH1F, {axisDcaProngPV}); @@ -454,26 +474,25 @@ struct LambdaTableProducer { histos.add("QA/Lambda/h2f_pos_prong_tpc_nsigma_pi_vs_p", "TPC n#sigma Pos Prong", kTH2F, {axisMomPID, axisTrackNsigma}); histos.add("QA/Lambda/h2f_neg_prong_tpc_nsigma_pi_vs_p", "TPC n#sigma Neg Prong", kTH2F, {axisMomPID, axisTrackNsigma}); + // Dca analysis histogram + histos.add("QA/Lambda/DCA/h2f_Dca_vs_pT", "DCA vs pT", kTH2F, {axisV0Pt, axisDcaLambda}); + histos.add("QA/KaonPlus/DCA/h2f_Dca_vs_pT", "DCA vs pT", kTH2F, {axisV0Pt, axisDcaKaon}); + // QA Kaons histos.add("QA/KaonPlus/hdEdX", "dE/dx vs pT", kTH2F, {axisMomPID, axisTrackdEdx}); histos.add("QA/KaonPlus/hTOFSignal", "#beta_{TOF} vs p_{T}", kTH2F, {axisMomPID, axisTrackTofSignal}); histos.add("QA/KaonPlus/hTPCNSigma", "n#sigma_{TPC} vs p_{T}", kTH2F, {axisMomPID, axisTrackNsigma}); histos.add("QA/KaonPlus/hTOFNSigma", "n#sigma_{TOF} vs p_{T}", kTH2F, {axisMomPID, axisTrackNsigma}); - // QA Anti-Lambda - histos.addClone("QA/Lambda/", "QA/AntiLambda/"); - histos.addClone("McRec/Lambda/", "McRec/AntiLambda/"); - - // QA KaonMinus - histos.addClone("QA/KaonPlus/", "QA/KaonMinus/"); - // MC Generated Histograms if (doprocessMCRecoGen || doprocessMCReco) { - // McReco Histos - histos.add("Tracks/h2f_tracks_pid_before_sel", "PIDs", kTH2F, {axisPID, axisV0Pt}); - histos.add("Tracks/h2f_tracks_pid_after_sel", "PIDs", kTH2F, {axisPID, axisV0Pt}); - histos.add("Tracks/h2f_primary_lambda_mothers_pdg", "PIDs", kTH2F, {axisPID, axisV0Pt}); - histos.add("Tracks/h2f_secondary_lambda_mothers_pdg", "PIDs", kTH2F, {axisPID, axisV0Pt}); + // DCA analysis + histos.add("QA/Lambda/DCA/h2f_Prm_Dca_vs_pT", "Primary DCA vs pT", kTH2F, {axisV0Pt, axisDcaLambda}); + histos.add("QA/Lambda/DCA/h2f_Scd_Dca_vs_pT", "Weak Decay DCA vs pT", kTH2F, {axisV0Pt, axisDcaLambda}); + histos.add("QA/Lambda/DCA/h2f_Mat_Dca_vs_pT", "Material DCA vs pT", kTH2F, {axisV0Pt, axisDcaLambda}); + histos.add("QA/KaonPlus/DCA/h2f_Prm_Dca_vs_pT", "Primary DCA vs pT", kTH2F, {axisV0Pt, axisDcaKaon}); + histos.add("QA/KaonPlus/DCA/h2f_Scd_Dca_vs_pT", "Weak Decay DCA vs pT", kTH2F, {axisV0Pt, axisDcaKaon}); + histos.add("QA/KaonPlus/DCA/h2f_Mat_Dca_vs_pT", "Material DCA vs pT", kTH2F, {axisV0Pt, axisDcaKaon}); // McGen Histos histos.add("McGen/h1f_collision_recgen", "# of Reco Collision Associated to One Mc Generator Collision", kTH1F, {axisMult}); @@ -483,8 +502,6 @@ struct LambdaTableProducer { histos.add("McGen/h1f_lambda_daughter_PDG", "PDG Daughters", kTH1F, {axisPID}); histos.add("McGen/h1f_antilambda_daughter_PDG", "PDG Daughters", kTH1F, {axisPID}); - histos.addClone("McRec/", "McGen/"); - // set bin lables specific to MC histos.get(HIST("Events/h1f_collisions_info"))->GetXaxis()->SetBinLabel(CollisionLabels::kTotColBeforeHasMcCollision, "kTotColBeforeHasMcCollision"); histos.get(HIST("McGen/h1f_collisions_info"))->GetXaxis()->SetBinLabel(CollisionLabels::kTotCol, "kTotCol"); @@ -494,14 +511,18 @@ struct LambdaTableProducer { histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kGenLambdaNoDau, "kGenLambdaNoDau"); } + // Clone histograms + // QA Anti-Lambda + histos.addClone("QA/Lambda/", "QA/AntiLambda/"); + + // QA KaonMinus + histos.addClone("QA/KaonPlus/", "QA/KaonMinus/"); + // set bin labels histos.get(HIST("Events/h1f_collisions_info"))->GetXaxis()->SetBinLabel(CollisionLabels::kTotCol, "kTotCol"); histos.get(HIST("Events/h1f_collisions_info"))->GetXaxis()->SetBinLabel(CollisionLabels::kPassSelCol, "kPassSelCol"); histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kAllV0Tracks, "kAllV0Tracks"); histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kPassK0ShortMassRej, "kPassK0ShortMassRej"); - histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kNotLambdaNotAntiLambda, "kNotLambdaNotAntiLambda"); - histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kV0IsBothLambdaAntiLambda, "kV0IsBothLambdaAntiLambda"); - histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kV0IsLambdaOrAntiLambda, "kV0IsLambdaOrAntiLambda"); histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kPassV0DauTrackSel, "kPassV0DauTrackSel"); histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kPassV0KinCuts, "kPassV0KinCuts"); histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kPassV0TopoSel, "kPassV0TopoSel"); @@ -555,22 +576,6 @@ struct LambdaTableProducer { return false; } - if (cTriggerTvxSel && !col.selection_bit(aod::evsel::kIsTriggerTVX)) { - return false; - } - - if (cTFBorder && !col.selection_bit(aod::evsel::kNoTimeFrameBorder)) { - return false; - } - - if (cNoItsROBorder && !col.selection_bit(aod::evsel::kNoITSROFrameBorder)) { - return false; - } - - if (cItsTpcVtx && !col.selection_bit(aod::evsel::kIsVertexITSTPC)) { - return false; - } - if (cPileupReject && !col.selection_bit(aod::evsel::kNoSameBunchPileup)) { return false; } @@ -687,32 +692,20 @@ struct LambdaTableProducer { histos.fill(HIST("Tracks/h1f_tracks_info"), kPassK0ShortMassRej); - // Apply Lambda Mass Hypothesis + // Select Lambda / AntiLambda based on Armenteros-Podolanski bool lambdaFlag = false, antiLambdaFlag = false; + float mass = 0.; - // Check for Lambda - if (std::abs(v0.mLambda() - MassLambda0) < cLambdaMassWindow) { + if (v0.qtarm() < cArmPodSel * std::abs(v0.alpha()) && v0.alpha() > 0) { lambdaFlag = true; partType = kLambda; - } - - // Check for AntiLambda - if (std::abs(v0.mAntiLambda() - MassLambda0) < cLambdaMassWindow) { + mass = v0.mLambda(); + } else { antiLambdaFlag = true; partType = kAntiLambda; + mass = v0.mAntiLambda(); } - // Check if the v0 is both Lambda and Anti-Lambda or neither - if (lambdaFlag && antiLambdaFlag) { - histos.fill(HIST("Tracks/h1f_tracks_info"), kV0IsBothLambdaAntiLambda); - return false; - } else if (!lambdaFlag && !antiLambdaFlag) { - histos.fill(HIST("Tracks/h1f_tracks_info"), kNotLambdaNotAntiLambda); - return false; - } - - histos.fill(HIST("Tracks/h1f_tracks_info"), kV0IsLambdaOrAntiLambda); - // Select Lambda daughters if (!selLambdaDauTracks(v0, postrack, negtrack, partType)) { return false; @@ -725,6 +718,18 @@ struct LambdaTableProducer { return false; } + // Fill invariant mass histograms after all selection + if (lambdaFlag) { + histos.fill(HIST("QA/Lambda/h3f_centmasspt"), cent, v0.pt(), mass); + } else { + histos.fill(HIST("QA/AntiLambda/h3f_centmasspt"), cent, v0.pt(), mass); + } + + // Mass window selection + if ((lambdaFlag && std::abs(v0.mLambda() - MassLambda0) >= cLambdaMassWindow) || (antiLambdaFlag && std::abs(v0.mAntiLambda() - MassLambda0) >= cLambdaMassWindow)) { + return false; + } + // All Selection Criterion Passed return true; } @@ -785,12 +790,12 @@ struct LambdaTableProducer { // Get Efficiency Factor if (cGetEffFact) { - TObject* objEff = reinterpret_cast(ccdbObjRecoEff->FindObject(Form("%s", vCorrFactStrings[cCorrFactHist][part].c_str()))); + auto* objEff = ccdbObjRecoEff->FindObject(Form("%s", vCorrFactStrings[cCorrFactHist][part].c_str())); // check object if (!objEff) { LOGF(fatal, "Reco efficiency object not found !"); } else { - TH1F* histEff = reinterpret_cast(objEff->Clone()); + TH1F* histEff = dynamic_cast(objEff->Clone()); if (histEff->GetDimension() == TwoDimCorr) { histos.fill(HIST("Tracks/h1f_tracks_info"), kEffCorrPtCent); effCorrFact = histEff->GetBinContent(histEff->FindBin(cent, v.pt())); @@ -808,13 +813,13 @@ struct LambdaTableProducer { // Get Matching Efficiency Correction if (cGetMatchEff) { - TObject* objITSTPCMatchEff = reinterpret_cast(ccdbObjMatchEff->FindObject("hITSTPCMatchingEfficiency")); - TObject* objITSTPCTOFMatchEff = reinterpret_cast(ccdbObjMatchEff->FindObject("hITSTPCTOFMatchingEfficiency")); + auto* objITSTPCMatchEff = ccdbObjMatchEff->FindObject("hITSTPCMatchingEfficiency"); + auto* objITSTPCTOFMatchEff = ccdbObjMatchEff->FindObject("hITSTPCTOFMatchingEfficiency"); if (!objITSTPCMatchEff || !objITSTPCTOFMatchEff) { LOGF(fatal, "Matching efficiency object not found !"); } else { - TH1F* histITSTPCMatchEff = reinterpret_cast(objITSTPCMatchEff->Clone()); - TH1F* histITSTPCTOFMatchEff = reinterpret_cast(objITSTPCTOFMatchEff->Clone()); + TH1F* histITSTPCMatchEff = dynamic_cast(objITSTPCMatchEff->Clone()); + TH1F* histITSTPCTOFMatchEff = dynamic_cast(objITSTPCTOFMatchEff->Clone()); // Lambda / Anti-Lambda if constexpr (part == kLambda || part == kAntiLambda) { auto posTrack = v.template posTrack_as(); @@ -847,18 +852,9 @@ struct LambdaTableProducer { auto postrack = v0.template posTrack_as(); auto negtrack = v0.template negTrack_as(); - // Mass - float mass = 0.; - if constexpr (part == kLambda) { - mass = v0.mLambda(); - } else { - mass = v0.mAntiLambda(); - } - // Decay length float ctau = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * MassLambda0; - histos.fill(HIST(SubDir[part]) + HIST("h3f_centmasspt"), cent, mass, v0.pt()); histos.fill(HIST(SubDir[part]) + HIST("h2f_qt_vs_alpha"), v0.alpha(), v0.qtarm()); histos.fill(HIST(SubDir[part]) + HIST("h1f_dca_V0_daughters"), v0.dcaV0daughters()); histos.fill(HIST(SubDir[part]) + HIST("h1f_dca_pos_to_PV"), v0.dcapostopv()); @@ -914,6 +910,27 @@ struct LambdaTableProducer { } } + // Dca analysis + template + void getDcaHist(T const& track, float const& dca) + { + // Fill histograms + histos.fill(HIST(SubDir[part]) + HIST("DCA/h2f_Dca_vs_pT"), track.pt(), dca); + + if constexpr (dmc == kMC) { + auto mcpart = track.mcParticle(); + if (mcpart.isPhysicalPrimary()) { + histos.fill(HIST(SubDir[part]) + HIST("DCA/h2f_Prm_Dca_vs_pT"), track.pt(), dca); + } else { + if (mcpart.getProcess() == cWeakDecayProcess) { // Weak decay + histos.fill(HIST(SubDir[part]) + HIST("DCA/h2f_Scd_Dca_vs_pT"), track.pt(), dca); + } else { // Material + histos.fill(HIST(SubDir[part]) + HIST("DCA/h2f_Mat_Dca_vs_pT"), track.pt(), dca); + } + } + } + } + // Reconstructed Level Tables template void fillLambdaRecoTables(C const& collision, B const&, V const& v0tracks, T const& tracks) @@ -967,26 +984,40 @@ struct LambdaTableProducer { histos.fill(HIST("Tracks/h1f_tracks_info"), kAllSelPassed); histos.fill(HIST("Tracks/h2f_armpod_after_sel"), v0.alpha(), v0.qtarm()); + // MC matching + if constexpr (dmc == kMC) { + auto mcpart = v0.mcParticle(); + if (cSelPrimaryParticle && !mcpart.isPhysicalPrimary()) { // Primary lambda selection + continue; + } + + if (cSelTrueParticle && std::abs(mcpart.pdgCode()) != kLambda0) { // True lambda selection + continue; + } + } + // Get Lambda mass and correction factor lambdaMass = (partType == kLambda) ? v0.mLambda() : v0.mAntiLambda(); if (cGetCorrectionFlag) { lambdaCorrFact = (partType == kLambda) ? getCorrectionFactors(v0, tracks, v0.yLambda()) : getCorrectionFactors(v0, tracks, v0.yLambda()); } - // fill lambda qa + // Fill lambda qa if (partType == kLambda) { + getDcaHist(v0, v0.dcav0topv()); fillLambdaQAHistos(collision, v0, tracks); } else { + getDcaHist(v0, v0.dcav0topv()); fillLambdaQAHistos(collision, v0, tracks); } // Daughter kinematics - std::array posTrackKin = {postrack.pt(), postrack.eta(), postrack.phi()}; - std::array negTrackKin = {negtrack.pt(), negtrack.eta(), negtrack.phi()}; + std::vector posTrackKin = {postrack.pt(), postrack.eta(), postrack.phi()}; + std::vector negTrackKin = {negtrack.pt(), negtrack.eta(), negtrack.phi()}; // Fill Lambda/AntiLambda Table - lambdaTrackTable(lambdaCollisionTable.lastIndex(), v0.pt(), v0.eta(), v0.phi(), v0.yLambda(), lambdaMass, - v0.template posTrack_as().index(), v0.template negTrack_as().index(), posTrackKin.data(), negTrackKin.data(), + lambdaTrackTable(lambdaCollisionTable.lastIndex(), v0.pt(), v0.eta(), v0.phi(), v0.yLambda(), v0.px(), v0.py(), v0.pz(), lambdaMass, + v0.template posTrack_as().index(), v0.template negTrack_as().index(), posTrackKin, negTrackKin, (int8_t)partType, lambdaCorrFact); } @@ -1010,11 +1041,25 @@ struct LambdaTableProducer { continue; } + // MC matching + if constexpr (dmc == kMC) { + auto mcpart = track.mcParticle(); + if (cSelPrimaryParticle && !mcpart.isPhysicalPrimary()) { // Primary kaon selection + continue; + } + + if (cSelTrueParticle && std::abs(mcpart.pdgCode()) != kKPlus) { // True kaon selection + continue; + } + } + // K+ / K- if (track.sign() >= 0) { + getDcaHist(track, track.dcaXY()); fillKaonQA(track); partType = kKaonPlus; } else if (track.sign() <= 0) { + getDcaHist(track, track.dcaXY()); fillKaonQA(track); partType = kKaonMinus; } else { @@ -1027,7 +1072,7 @@ struct LambdaTableProducer { } // Fill table - kaonTrackTable(lambdaCollisionTable.lastIndex(), track.pt(), track.eta(), track.phi(), rap, MassKaonCharged, + kaonTrackTable(lambdaCollisionTable.lastIndex(), track.pt(), track.eta(), track.phi(), rap, track.px(), track.py(), track.pz(), MassKaonCharged, track.globalIndex(), (int8_t)partType, kaonCorrFact); } } @@ -1088,7 +1133,7 @@ struct LambdaTableProducer { histos.fill(HIST("McGen/h1f_antilambda_daughter_PDG"), mcpart.pdgCode()); } // Fill table - lambdaMCGenTrackTable(lambdaMCGenCollisionTable.lastIndex(), mcpart.pt(), mcpart.eta(), mcpart.phi(), mcpart.y(), RecoDecay::m(mcpart.p(), mcpart.e()), + lambdaMCGenTrackTable(lambdaMCGenCollisionTable.lastIndex(), mcpart.pt(), mcpart.eta(), mcpart.phi(), mcpart.y(), mcpart.px(), mcpart.py(), mcpart.pz(), RecoDecay::m(mcpart.p(), mcpart.e()), daughterIDs[0], daughterIDs[1], (int8_t)partType, 1.); } @@ -1099,10 +1144,8 @@ struct LambdaTableProducer { continue; } - // histos.fill(HIST("KaonTracks/h1f_tracks_info"), kGenAccKaon); - // Fill table - kaonMCGenTrackTable(lambdaMCGenCollisionTable.lastIndex(), mcpart.pt(), mcpart.eta(), mcpart.phi(), mcpart.y(), RecoDecay::m(mcpart.p(), mcpart.e()), + kaonMCGenTrackTable(lambdaMCGenCollisionTable.lastIndex(), mcpart.pt(), mcpart.eta(), mcpart.phi(), mcpart.y(), mcpart.px(), mcpart.py(), mcpart.pz(), RecoDecay::m(mcpart.p(), mcpart.e()), mcpart.globalIndex(), (int8_t)partType, 1.); } } @@ -1213,18 +1256,9 @@ struct LambdaTracksExtProducer { Configurable cAcceptAllKaon{"cAcceptAllKaon", false, "Accept all Kaons"}; Configurable cRejAllKaonShaLaDau{"cRejAllKaonShaLaDau", true, "Reject all Kaons sharing Lambda daughters"}; - // Two-track cuts - Configurable cApplyTwoTrackCut{"cApplyTwoTrackCut", false, "Flag for two track cut"}; - Configurable cTpcRadii{"cTpcRadii", 0.80, "TPC Radius for DPhiStar"}; - Configurable cDEtaCut{"cDEtaCut", 0.01, "DEta cut"}; - Configurable cDPhiStarCut{"cDPhiStarCut", 0.01, "DPhiStar cut"}; - // Histogram Registry. HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - // Global objects - float magField = 0.; - void init(InitContext const&) { // Axis Specifications @@ -1251,8 +1285,6 @@ struct LambdaTracksExtProducer { histos.add("h2d_n2_etaphi_KaPLaM", "#rho_{2}", kTH2D, {axisDEta, axisDPhi}); histos.add("h2d_n2_etaphi_KaMLaP", "#rho_{2}", kTH2D, {axisDEta, axisDPhi}); histos.add("h2d_n2_etaphi_KaMLaM", "#rho_{2}", kTH2D, {axisDEta, axisDPhi}); - - histos.add("h2d_n2_detadphi", "#rho_{2}", kTH2D, {axisDEta, axisDPhi}); } void processDummy(aod::LambdaCollisions::iterator const&) {} @@ -1295,12 +1327,8 @@ struct LambdaTracksExtProducer { } } - // Accept/Reject - if (cAcceptAllLambda) { // Accept all lambda - trueLambdaFlag = true; - } else if (cRejAllLambdaShaDau && !lambdaSharingDauFlag) { // Reject all lambda sharing daughter - trueLambdaFlag = true; - } + // Accept / Reject + trueLambdaFlag = cAcceptAllLambda || (cRejAllLambdaShaDau && !lambdaSharingDauFlag); // Multiplicity of selected lambda if (trueLambdaFlag) { @@ -1335,64 +1363,12 @@ struct LambdaTracksExtProducer { PROCESS_SWITCH(LambdaTracksExtProducer, processLambdaTrackExt, "Process for lambda track extension", false); - template - bool checkClosePair(A const& v1, A const& v2, const int& charge1, const int& charge2) - { - // DPhiStar - float dphistar = 0.; - float arg1 = 0.15 * magField * charge1 * cTpcRadii / v1[0]; - float arg2 = 0.15 * magField * charge2 * cTpcRadii / v2[0]; - if (std::abs(arg1) < 1.0 && std::abs(arg2) < 1.0) { - dphistar = v1[2] - v2[2] + std::asin(arg1) - std::asin(arg2); - } else { - dphistar = 99.; - } - - // DEta - float deta = v1[1] - v2[1]; - - // Check close-pair - if (std::abs(deta) < cDEtaCut && std::abs(dphistar) < cDPhiStarCut) { - return true; - } - - return false; - } - - template - bool isClosePair(T const& track, V const& lambda) - { - // Close pair flag - bool retFlag = false; - - // Assign kinematics - std::array trackKin = {track.pt(), track.eta(), track.phi()}; - std::array lambdaPosTrackKin = {lambda.posTrackKin()[0], lambda.posTrackKin()[1], lambda.posTrackKin()[2]}; - std::array lambdaNegTrackKin = {lambda.negTrackKin()[0], lambda.negTrackKin()[1], lambda.negTrackKin()[2]}; - - if (track.partType() == kKaonPlus) { - retFlag = checkClosePair(trackKin, lambdaPosTrackKin, 1, 1) || checkClosePair(trackKin, lambdaNegTrackKin, 1, -1); - } else if (track.partType() == kKaonMinus) { - retFlag = checkClosePair(trackKin, lambdaPosTrackKin, -1, 1) || checkClosePair(trackKin, lambdaNegTrackKin, -1, -1); - } else { - return false; - } - - // Fill QA - if (retFlag) { - histos.fill(HIST("h2d_n2_detadphi"), track.eta() - lambda.eta(), RecoDecay::constrainAngle(track.phi() - lambda.phi(), -PIHalf)); - } - - return retFlag; - } - - void processKaonTrackExt(aod::LambdaCollisions::iterator const& collision, aod::LambdaTracks const& lambdaTracks, aod::KaonTracks const& kaonTracks) + void processKaonTrackExt(aod::LambdaCollisions::iterator const&, aod::LambdaTracks const& lambdaTracks, aod::KaonTracks const& kaonTracks) { - magField = collision.bField(); int nTotKaonPlus = 0, nTotKaonMinus = 0, nSelKaonPlus = 0, nSelKaonMinus = 0; for (auto const& kaonTrack : kaonTracks) { - bool kaonSharingLambdaDauFlag = false, closeTrackPairFlag = false, trueKaonFlag = false; + bool kaonSharingLambdaDauFlag = false, trueKaonFlag = false; std::vector vKaonShareDauLambdaIndex; if (kaonTrack.partType() == kKaonPlus) { @@ -1418,19 +1394,10 @@ struct LambdaTracksExtProducer { histos.fill(HIST("h2d_n2_etaphi_KaMLaM"), kaonTrack.eta() - lambdaTrack.eta(), RecoDecay::constrainAngle(kaonTrack.phi() - lambdaTrack.phi(), -PIHalf)); } } - - // Two-track cuts - if (cApplyTwoTrackCut) { - closeTrackPairFlag |= isClosePair(kaonTrack, lambdaTrack); - } } // Accept / Reject - if (cAcceptAllKaon) { - trueKaonFlag = true; - } else if (cRejAllKaonShaLaDau && !kaonSharingLambdaDauFlag && !closeTrackPairFlag) { - trueKaonFlag = true; - } + trueKaonFlag = cAcceptAllKaon || (cRejAllKaonShaLaDau && !kaonSharingLambdaDauFlag); // Multiplicity of selected kaons if (trueKaonFlag) { @@ -1482,8 +1449,13 @@ struct LambdaR2Correlation { Configurable cAnaPairs{"cAnaPairs", false, "Analyze Pairs Flag"}; // Lambda Kaon femtoscopic correction - Configurable cApplyFemtoPtSel{"cApplyFemtoPtSel", false, "Femto pT selection"}; - Configurable cFemtoPtCut{"cFemtoPtCut", 0.02, "Kaon--Lambda Femto pT cut"}; + Configurable cApplyFemtoSel{"cApplyFemtoSel", false, "Femto qinv selection"}; + Configurable cFemtoCut{"cFemtoCut", 0.02, "Kaon--Lambda Femto qinv cut"}; + + // Lambda Kaon two-track cuts + Configurable cApplyTwoTrackCut{"cApplyTwoTrackCut", false, "Flag for two track cut"}; + Configurable cDEtaCut{"cDEtaCut", 0.02, "DEta cut"}; + Configurable cDPhiStarCut{"cDPhiStarCut", 0.02, "DPhiStar cut"}; // Centrality Axis ConfigurableAxis cCentBins{"cCentBins", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f}, "Variable Mult-Bins"}; @@ -1502,6 +1474,8 @@ struct LambdaR2Correlation { float phibinwidth = 0.; float q = 0., e = 0., qinv = 0.; float cent = 0.; + float magField = 0.; + std::array tpcRadii = {0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4}; void init(InitContext const&) { @@ -1523,6 +1497,8 @@ struct LambdaR2Correlation { const AxisSpec axisCent(cCentBins, "FT0C (%)"); const AxisSpec axisChMult(200, 0, 200, "N_{ch}"); const AxisSpec axisMult(10, 0, 10, "N_{#Lambda}"); + const AxisSpec axisDEta(320, -1.6, 1.6, "#Delta#eta"); + const AxisSpec axisDPhi(640, -PIHalf, 3. * PIHalf, "#Delta#varphi"); const AxisSpec axisMass(100, 1.06, 1.16, "M_{#Lambda} (GeV/#it{c}^{2})"); const AxisSpec axisPtLambda(cLambdaNPtBins, cLambdaPtMin, cLambdaPtMax, "p_{T} (GeV/#it{c})"); const AxisSpec axisPtKaon(cKaonNPtBins, cKaonPtMin, cKaonPtMax, "p_{T} (GeV/#it{c})"); @@ -1537,6 +1513,12 @@ struct LambdaR2Correlation { histos.add("Event/Reco/h1f_ft0m_mult_percentile", "FT0M (%)", kTH1F, {axisCent}); histos.add("Event/Reco/h2f_Mult_vs_Centrality", "N_{ch} vs FT0M(%)", kTProfile, {axisCent}); + // Two track cut + histos.add("QA/TwoTrackCut/Before/h2d_n2_detadphi", "#rho_{2}", kTH2D, {axisDEta, axisDPhi}); + histos.add("QA/TwoTrackCut/After/h2d_n2_detadphi", "#rho_{2}", kTH2D, {axisDEta, axisDPhi}); + histos.add("QA/FemtoCut/Before/h2d_n2_detadphi", "#rho_{2}", kTH2D, {axisDEta, axisDPhi}); + histos.add("QA/FemtoCut/After/h2d_n2_detadphi", "#rho_{2}", kTH2D, {axisDEta, axisDPhi}); + // Efficiency Histograms // Single Particle Efficiencies histos.add("Reco/Efficiency/h2f_n1_centpt_LaP", "#rho_{1}^{#Lambda}", kTH2F, {axisCent, axisPtLambda}); @@ -1572,9 +1554,6 @@ struct LambdaR2Correlation { histos.add("Reco/h3f_n2_rapphi_LaP_KaP", "#rho_{2}^{#LambdaK^{#plus}}", kTH3F, {axisCent, axisRapPhi, axisRapPhi}); histos.add("Reco/h3f_n2_rapphi_LaM_KaM", "#rho_{2}^{#bar{#Lambda}K^{#plus}}", kTH3F, {axisCent, axisRapPhi, axisRapPhi}); histos.add("Reco/h3f_n2_rapphi_LaM_KaP", "#rho_{2}^{#bar{#Lambda}K^{#minus}}", kTH3F, {axisCent, axisRapPhi, axisRapPhi}); - histos.add("Reco/h3f_n2_rapphi_KaP_KaM", "#rho_{2}^{#LambdaK^{#minus}}", kTH3F, {axisCent, axisRapPhi, axisRapPhi}); - histos.add("Reco/h3f_n2_rapphi_KaP_KaP", "#rho_{2}^{#LambdaK^{#plus}}", kTH3F, {axisCent, axisRapPhi, axisRapPhi}); - histos.add("Reco/h3f_n2_rapphi_KaM_KaM", "#rho_{2}^{#bar{#Lambda}K^{#plus}}", kTH3F, {axisCent, axisRapPhi, axisRapPhi}); } // MCGen @@ -1584,47 +1563,103 @@ struct LambdaR2Correlation { } } - // Rap-Phi Bin Index - int getRapPhiBin(float const& rap, float const& phi) + template + bool checkClosePair(A const& v1, A const& v2, int charge1, int charge2) + { + // DPhiStar average over different TPC radius + float dphistar = 0., n = 0.; + for (auto const& radius : tpcRadii) { + float arg1 = 0.15 * magField * radius / v1[0]; + float arg2 = 0.15 * magField * radius / v2[0]; + if (std::abs(arg1) < 1.0 && std::abs(arg2) < 1.0) { + dphistar += v1[2] - v2[2] - (charge1 * std::abs(std::asin(arg1))) + (charge2 * std::abs(std::asin(arg2))); + ++n; + } + } + + // Inf check + if (n == 0) { + return false; + } + + // DPhiStar + dphistar = RecoDecay::constrainAngle(dphistar / n, -PIHalf); + + // DEta + float deta = v1[1] - v2[1]; + + // Return + return (std::abs(deta) < cDEtaCut && std::abs(dphistar) < cDPhiStarCut); + } + + template + bool isClosePair(V const& lambda, T const& track) + { + // Before + histos.fill(HIST("QA/TwoTrackCut/Before/h2d_n2_detadphi"), track.eta() - lambda.eta(), RecoDecay::constrainAngle(track.phi() - lambda.phi(), -PIHalf)); + + // Close pair flag + bool retFlag = false; + + // Assign kinematics + std::array trackKin = {track.pt(), track.eta(), track.phi()}; + std::array lambdaPosTrackKin = {lambda.posTrackKin()[0], lambda.posTrackKin()[1], lambda.posTrackKin()[2]}; + std::array lambdaNegTrackKin = {lambda.negTrackKin()[0], lambda.negTrackKin()[1], lambda.negTrackKin()[2]}; + + if (track.partType() == kKaonPlus) { + retFlag = checkClosePair(trackKin, lambdaPosTrackKin, 1, 1) || checkClosePair(trackKin, lambdaNegTrackKin, 1, -1); + } else if (track.partType() == kKaonMinus) { + retFlag = checkClosePair(trackKin, lambdaPosTrackKin, -1, 1) || checkClosePair(trackKin, lambdaNegTrackKin, -1, -1); + } + + // Fill QA + if (!retFlag) { // Pair accept + histos.fill(HIST("QA/TwoTrackCut/After/h2d_n2_detadphi"), track.eta() - lambda.eta(), RecoDecay::constrainAngle(track.phi() - lambda.phi(), -PIHalf)); + } + + // Pair reject + return retFlag; + } + + template + bool isCloseQinv(V const& p1, T const& p2) { - int rapbin = static_cast((rap - kminrap) / rapbinwidth); - int phibin = static_cast(phi / phibinwidth); + // Before + histos.fill(HIST("QA/FemtoCut/Before/h2d_n2_detadphi"), p1.eta() - p2.eta(), RecoDecay::constrainAngle(p1.phi() - p2.phi(), -PIHalf)); + + // Calculate qinv + q = RecoDecay::p((p1.px() - p2.px()), (p1.py() - p2.py()), (p1.pz() - p2.pz())); + e = RecoDecay::e(p1.px(), p1.py(), p1.pz(), MassLambda0) - RecoDecay::e(p2.px(), p2.py(), p2.pz(), MassKaonCharged); + qinv = std::sqrt(-RecoDecay::m2(q, e)); - int rapphibin = -99; - if (rapbin >= 0 && phibin >= 0 && rapbin < nrapbins && phibin < nphibins) { - rapphibin = rapbin * nphibins + phibin; - return rapphibin; + // Pair accept + if (qinv > cFemtoCut) { + histos.fill(HIST("QA/FemtoCut/After/h2d_n2_detadphi"), p1.eta() - p2.eta(), RecoDecay::constrainAngle(p1.phi() - p2.phi(), -PIHalf)); + return false; } - return rapphibin; + // Pair reject + return true; } template void fillPairHistos(T1& p1, T2& p2) { - static constexpr std::string_view SubDirRecGen[] = {"Reco/", "McGen/"}; - static constexpr std::string_view SubDirHist[] = {"LaP_LaM", "LaP_LaP", "LaM_LaM", "LaP_KaP", "LaP_KaM", "LaM_KaP", "LaM_KaM", "KaP_KaM", "KaP_KaP", "KaM_KaM"}; - - int rapbin1 = static_cast((p1.rap() - kminrap) / rapbinwidth); - int rapbin2 = static_cast((p2.rap() - kminrap) / rapbinwidth); + static constexpr auto SubDirRecGen = std::array{"Reco/", "McGen/"}; + static constexpr auto SubDirHist = std::array{"LaP_LaM", "LaP_LaP", "LaM_LaM", "LaP_KaP", "LaP_KaM", "LaM_KaP", "LaM_KaM", "KaP_KaM", "KaP_KaP", "KaM_KaM"}; - int phibin1 = static_cast(p1.phi() / phibinwidth); - int phibin2 = static_cast(p2.phi() / phibinwidth); + const auto rapbin1 = static_cast((p1.rap() - kminrap) / rapbinwidth); + const auto rapbin2 = static_cast((p2.rap() - kminrap) / rapbinwidth); - float corfac = p1.corrFact() * p2.corrFact(); + const auto phibin1 = static_cast(p1.phi() / phibinwidth); + const auto phibin2 = static_cast(p2.phi() / phibinwidth); - // Lambda-Kaon Femto pT cut - if (cApplyFemtoPtSel && (part_pair == kLambdaKaonPlus || part_pair == kLambdaKaonMinus || part_pair == kAntiLambdaKaonPlus || part_pair == kAntiLambdaKaonMinus)) { - float dpt = p1.pt() - p2.pt(); - if (std::abs(dpt) < cFemtoPtCut) { - return; - } - } + const float corfac = p1.corrFact() * p2.corrFact(); if (rapbin1 >= 0 && rapbin2 >= 0 && phibin1 >= 0 && phibin2 >= 0 && rapbin1 < nrapbins && rapbin2 < nrapbins && phibin1 < nphibins && phibin2 < nphibins) { - int rapphix = rapbin1 * nphibins + phibin1; - int rapphiy = rapbin2 * nphibins + phibin2; + const int rapphix = rapbin1 * nphibins + phibin1; + const int rapphiy = rapbin2 * nphibins + phibin2; histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("h3f_n2_rapphi_") + HIST(SubDirHist[part_pair]), cent, rapphix + 0.5, rapphiy + 0.5, corfac); } @@ -1633,8 +1668,8 @@ struct LambdaR2Correlation { template void analyzeSingles(T const& tracks) { - static constexpr std::string_view SubDirRecGen[] = {"Reco/", "McGen/"}; - static constexpr std::string_view SubDirHist[] = {"LaP", "LaM", "KaP", "KaM"}; + static constexpr auto SubDirRecGen = std::array{"Reco/", "McGen/"}; + static constexpr auto SubDirHist = std::array{"LaP", "LaM", "KaP", "KaM"}; for (auto const& track : tracks) { // Efficiency Plots @@ -1661,6 +1696,22 @@ struct LambdaR2Correlation { if (same && ((trk_1.index() == trk_2.index()))) { continue; } + + // Lambda-Kaon close pair rejection + if constexpr (rec_gen == kRec) { + if constexpr (partpair == kLambdaKaonPlus || partpair == kLambdaKaonMinus || partpair == kAntiLambdaKaonPlus || partpair == kAntiLambdaKaonMinus) { + // Close pair + if (cApplyTwoTrackCut && isClosePair(trk_1, trk_2)) { + continue; + } + // Femto selection + if (cApplyFemtoSel && isCloseQinv(trk_1, trk_2)) { + continue; + } + } + } + + // Fill pair histograms fillPairHistos(trk_1, trk_2); } } @@ -1687,6 +1738,7 @@ struct LambdaR2Correlation { histos.fill(HIST("Event/Reco/h2f_Mult_vs_Centrality"), collision.cent(), collision.mult()); cent = collision.cent(); + magField = collision.bField(); auto lambdaTracks = partLambdaTracks->sliceByCached(aod::lambdatrack::lambdaCollisionId, collision.globalIndex(), cache); auto antiLambdaTracks = partAntiLambdaTracks->sliceByCached(aod::lambdatrack::lambdaCollisionId, collision.globalIndex(), cache); @@ -1707,9 +1759,6 @@ struct LambdaR2Correlation { analyzePairs(lambdaTracks, kaonMinusTracks); analyzePairs(antiLambdaTracks, kaonPlusTracks); analyzePairs(antiLambdaTracks, kaonMinusTracks); - analyzePairs(kaonPlusTracks, kaonMinusTracks); - analyzePairs(kaonPlusTracks, kaonPlusTracks); - analyzePairs(kaonMinusTracks, kaonMinusTracks); } } @@ -1751,9 +1800,6 @@ struct LambdaR2Correlation { analyzePairs(lambdaTracks, kaonMinusTracks); analyzePairs(antiLambdaTracks, kaonPlusTracks); analyzePairs(antiLambdaTracks, kaonMinusTracks); - analyzePairs(kaonPlusTracks, kaonMinusTracks); - analyzePairs(kaonPlusTracks, kaonPlusTracks); - analyzePairs(kaonMinusTracks, kaonMinusTracks); } }