From 46af0658d3f09ffe967df2371cac94373f67815e Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Thu, 11 Feb 2021 16:16:26 +0100 Subject: [PATCH 01/24] First implementation of D0-D0bar correlation code (data/MC-reco/MC-kine) --- Analysis/Tasks/PWGHF/CMakeLists.txt | 5 + Analysis/Tasks/PWGHF/HFDDbar_corr.cxx | 823 ++++++++++++++++++++++++++ 2 files changed, 828 insertions(+) create mode 100644 Analysis/Tasks/PWGHF/HFDDbar_corr.cxx diff --git a/Analysis/Tasks/PWGHF/CMakeLists.txt b/Analysis/Tasks/PWGHF/CMakeLists.txt index 513e40ff5da68..b54f47ce0aa0e 100644 --- a/Analysis/Tasks/PWGHF/CMakeLists.txt +++ b/Analysis/Tasks/PWGHF/CMakeLists.txt @@ -87,3 +87,8 @@ o2_add_dpl_workflow(hf-task-bplus SOURCES taskBPlus.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-ddbar_corr + SOURCES HFDDbar_corr.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) diff --git a/Analysis/Tasks/PWGHF/HFDDbar_corr.cxx b/Analysis/Tasks/PWGHF/HFDDbar_corr.cxx new file mode 100644 index 0000000000000..580c535ddb3a8 --- /dev/null +++ b/Analysis/Tasks/PWGHF/HFDDbar_corr.cxx @@ -0,0 +1,823 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file HFDDbar_corr.cxx +/// \brief D0-D0bar analysis task - data-like, MC-reco and MC-kine analyses. For ULS and LS pairs +/// +/// \author Fabio Colamaria , INFN Bari + +#include + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "AnalysisDataModel/HFSecondaryVertex.h" +#include "AnalysisDataModel/HFCandidateSelectionTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::aod::hf_cand_prong2; +using namespace o2::framework::expressions; +using namespace o2::constants::math; + +// the following is needed to extend the standard candidate table, and allow grouping candidate table by collisions +namespace o2::aod +{ +namespace hf_2prong_correl +{ +DECLARE_SOA_INDEX_COLUMN(Collision, collision); +} // namespace hf_2prong_correl +DECLARE_SOA_TABLE(HF2ProngCollis, "AOD", "COLLID_2PR", aod::hf_2prong_correl::CollisionId); + +using Big2Prong = soa::Join; +using Big2ProngMC = soa::Join; +} // namespace o2::aod + +// preliminary task to fill the column index to the extended candidate table +struct CreateBig2Prong { + + Produces create2ProngIndexCollColumn; + void process(aod::HfCandProng2 const& candidates, aod::Tracks const& tracks) + { + for (auto& candidate : candidates) { + int indexColl = candidate.index0_as().collisionId(); //takes index of collision from first D daughter + create2ProngIndexCollColumn(indexColl); + } + } +}; + +void customize(std::vector& workflowOptions) +{ + ConfigParamSpec optionDoMC{"doMC", VariantType::Bool, false, {"Run MC-dedicated tasks."}}; + workflowOptions.push_back(optionDoMC); +} + +#include "Framework/runDataProcessing.h" + +double getDeltaPhi(double phiD, double phiDbar) +{ + double dPhi = phiDbar - phiD; + + if (dPhi < -o2::constants::math::PI / 2.) + dPhi = dPhi + 2 * o2::constants::math::PI; + if (dPhi > 3. * o2::constants::math::PI / 2.) + dPhi = dPhi - 2 * o2::constants::math::PI; + + return dPhi; +} + +double EvaluatePhiByVertex(double x_vtx1, double x_vtx2, double y_vtx1, double y_vtx2) +{ + double phi = std::atan2((y_vtx2 - y_vtx1), (x_vtx2 - x_vtx1)); + + if (phi < 0) + phi = phi + 2 * o2::constants::math::PI; + if (phi > 2 * o2::constants::math::PI) + phi = phi - 2 * o2::constants::math::PI; + + return phi; +} + +/// D0 analysis task - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) +struct TaskD0 { + + double maxEtaCut = 5., PtTrh_forMaxEtaCut = 10.; //for hDDbar_vs_EtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 + + HistogramRegistry registry{ + "registry", + //NOTE: use hmassD0 for normalisation, and hmass2D_correlPairs for 2D-sideband-subtraction purposes + {{"hmass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hmassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hmassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hmass2D_correlPairs", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, + {"hptcand", "D0,D0bar candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong0", "D0,D0bar candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong1", "D0,D0bar candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hselectionstatus", "D0,D0bar candidates;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, + {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhi", "D0,D0bar candidates;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hY", "D0,D0bar candidates;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDeltaEta_pTint", "D0,D0bar candidates;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhi_pTint", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2D_pTint", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEta_vsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhi_vsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPt_D_Dbar", "D0,D0bar candidates;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPt_Max_Min", "D0,D0bar candidates;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, + {"hDDbar_vs_EtaCut", "D0,D0bar pairs vs #eta cut;#eta_{max};entries", {HistType::kTH2F, {{10 * maxEtaCut, 0., maxEtaCut}, {2 * PtTrh_forMaxEtaCut, 0., PtTrh_forMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and PtTrh_forMaxEtaCut instead + + Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) + { + for (auto& candidate1 : candidates) { + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + continue; + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + //fill invariant mass plots and generic info from all D0/D0bar candidates + if (candidate1.isSelD0() >= d_selectionFlagD0) { + registry.fill(HIST("hmass"), InvMassD0(candidate1)); + registry.fill(HIST("hmassD0"), InvMassD0(candidate1)); + } + if (candidate1.isSelD0bar() >= d_selectionFlagD0bar) { + registry.fill(HIST("hmass"), InvMassD0bar(candidate1)); + registry.fill(HIST("hmassD0bar"), InvMassD0bar(candidate1)); + } + registry.fill(HIST("hptcand"), candidate1.pt()); + registry.fill(HIST("hptprong0"), candidate1.ptProng0()); + registry.fill(HIST("hptprong1"), candidate1.ptProng1()); + registry.fill(HIST("hEta"), candidate1.eta()); + registry.fill(HIST("hPhi"), candidate1.phi()); + registry.fill(HIST("hY"), YD0(candidate1)); + registry.fill(HIST("hselectionstatus"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); + + //D-Dbar correlation dedicated section + //if the candidate is a D0, search for D0bar and evaluate correlations + if (candidate1.isSelD0() >= d_selectionFlagD0) { + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (candidate2.isSelD0bar() >= d_selectionFlagD0bar) { + if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + continue; + //Excluding trigger self-correlations (possible in case of both mass hypotheses accepted) + if (candidate1.mRowIndex == candidate2.mRowIndex) + continue; + double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); + registry.fill(HIST("hmass2D_correlPairs"), InvMassD0(candidate1), InvMassD0bar(candidate2)); + registry.fill(HIST("hDeltaEta_pTint"), eta2 - eta1); + registry.fill(HIST("hDeltaPhi_pTint"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2D_pTint"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEta_vsPt"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhi_vsPt"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPt_D_Dbar"), pt2 - pt1); + registry.fill(HIST("hDeltaPt_Max_Min"), std::max(pt2, pt1) - std::min(pt2, pt1)); + double etacut = 0.; + double ptcut = 0.; + do { //fill pairs vs etaCut plot + ptcut = 0.; + etacut += 0.1; + do { //fill pairs vs etaCut plot + if (std::abs(candidate1.eta()) < etacut && std::abs(candidate2.eta()) < etacut && candidate1.pt() > ptcut && candidate2.pt() > ptcut) + registry.fill(HIST("hDDbar_vs_EtaCut"), etacut - 0.01, ptcut + 0.01); + ptcut += 0.5; + } while (ptcut < PtTrh_forMaxEtaCut - 0.05); + } while (etacut < maxEtaCut - 0.05); + } + //note: candidates selected as both D0 and D0bar are used, and considered in both situation (but not auto-correlated): reflections could play a relevant role. + //another, more restrictive, option, could be to consider only candidates selected with a single option (D0 xor D0bar) + + } // end inner loop (Dbars) + } + + } //end outer loop + } +}; + +/// D0 analysis task - for MC reco-level analysis (candidates matched to true signal only) +struct TaskD0MCrec { + + double maxEtaCut = 5., PtTrh_forMaxEtaCut = 10.; //for hDDbar_vs_EtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 + + HistogramRegistry registry{ + "registry", + //NOTE: use hmassD0_MCRec for normalisation, and hmass2D_correlPairs_MCRec for 2D-sideband-subtraction purposes + {{"hmassD0_MCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, + {"hmassD0bar_MCRec", "D0,D0bar candidates - MC reco;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, + {"hmass2D_correlPairs_MCRec", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, + {"hptcand_MCRec", "D0,D0bar candidates - MC reco;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong0_MCRec", "D0,D0bar candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong1_MCRec", "D0,D0bar candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hEta_MCRec", "D0,D0bar candidates - MC reco;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhi_MCRec", "D0,D0bar candidates - MC reco;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hY_MCRec", "D0,D0bar candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDeltaEta_pTint_MCRec", "D0,D0bar candidates - MC reco;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhi_pTint_MCRec", "D0,D0bar candidates - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2D_pTint_MCRec", "D0,D0bar candidates - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEta_vsPt_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhi_vsPt_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPt_D_Dbar_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPt_Max_Min_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, + {"hDDbar_vs_EtaCut_MCRec", "D0,D0bar pairs vs #eta cut - MC reco;#eta_{max};entries", {HistType::kTH2F, {{10 * maxEtaCut, 0., maxEtaCut}, {2 * PtTrh_forMaxEtaCut, 0., PtTrh_forMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and PtTrh_forMaxEtaCut instead + + Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) + { + //MC reco level + for (auto& candidate1 : candidates) { + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + continue; + if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { + //fill invariant mass plots and generic info from all D0/D0bar candidates + if (candidate1.isSelD0() >= d_selectionFlagD0 && candidate1.flagMCMatchRec() == 1 << D0ToPiK) { //only reco and matched as D0 + registry.fill(HIST("hmassD0_MCRec"), InvMassD0(candidate1)); + } + if (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == -1 << D0ToPiK) { //only reco and matched as D0bar + registry.fill(HIST("hmassD0bar_MCRec"), InvMassD0bar(candidate1)); + } + registry.fill(HIST("hptcand_MCRec"), candidate1.pt()); + registry.fill(HIST("hptprong0_MCRec"), candidate1.ptProng0()); + registry.fill(HIST("hptprong1_MCRec"), candidate1.ptProng1()); + registry.fill(HIST("hEta_MCRec"), candidate1.eta()); + registry.fill(HIST("hPhi_MCRec"), candidate1.phi()); + registry.fill(HIST("hY_MCRec"), YD0(candidate1)); + + //D-Dbar correlation dedicated section + //if the candidate is a D0, search for D0bar and evaluate correlations + if (candidate1.isSelD0() >= d_selectionFlagD0 && candidate1.flagMCMatchRec() == 1 << D0ToPiK) { //selected as D0 (particle) && matched to D0 (particle) + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (candidate2.isSelD0bar() >= d_selectionFlagD0bar && candidate2.flagMCMatchRec() == -1 << D0ToPiK) { //selected as D0bar (antiparticle) && matched to D0bar (antiparticle) + if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + continue; + double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); + registry.fill(HIST("hmass2D_correlPairs_MCRec"), InvMassD0(candidate1), InvMassD0bar(candidate2)); + registry.fill(HIST("hDeltaEta_pTint_MCRec"), eta2 - eta1); + registry.fill(HIST("hDeltaPhi_pTint_MCRec"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2D_pTint_MCRec"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEta_vsPt_MCRec"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhi_vsPt_MCRec"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPt_D_Dbar_MCRec"), pt2 - pt1); + registry.fill(HIST("hDeltaPt_Max_Min_MCRec"), std::max(pt2, pt1) - std::min(pt2, pt1)); + double etacut = 0.; + double ptcut = 0.; + do { //fill pairs vs etaCut plot + ptcut = 0.; + etacut += 0.1; + do { //fill pairs vs etaCut plot + if (std::abs(candidate1.eta()) < etacut && std::abs(candidate2.eta()) < etacut && candidate1.pt() > ptcut && candidate2.pt() > ptcut) + registry.fill(HIST("hDDbar_vs_EtaCut_MCRec"), etacut - 0.01, ptcut + 0.01); + ptcut += 0.5; + } while (ptcut < PtTrh_forMaxEtaCut - 0.05); + } while (etacut < maxEtaCut - 0.05); + } //end inner if (MC match) + + } // end inner loop (Dbars) + } + } //end outer if (MC match) + } //end outer loop + } +}; + +/// D0 analysis task - for MC gen-level analysis (no filter/selection, only true signal) +struct TaskD0MCgen { + + double maxEtaCut = 5., PtTrh_forMaxEtaCut = 10.; //for hDDbar_vs_EtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 + + HistogramRegistry registry{ + "registry", + {{"hMCEvt_count", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hptcand_MCGen", "D0,D0bar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hcountD0triggers_MCGen", "D0 trigger particles - MC gen;;N of trigger D0", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hEta_MCGen", "D0,D0bar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhi_MCGen", "D0,D0bar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hY_MCGen", "D0,D0bar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDeltaEta_pTint_MCGen", "D0,D0bar particles - MC gen;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhi_pTint_MCGen", "D0,D0bar particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2D_pTint_MCGen", "D0,D0bar particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEta_vsPt_MCGen", "D0,D0bar candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhi_vsPt_MCGen", "D0,D0bar candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPt_D_Dbar_MCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPt_Max_Min_MCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, + {"hDDbar_vs_EtaCut_MCGen", "D0,D0bar pairs vs #eta cut - MC gen;#eta_{max};entries", {HistType::kTH2F, {{10 * maxEtaCut, 0., maxEtaCut}, {2 * PtTrh_forMaxEtaCut, 0., PtTrh_forMaxEtaCut}}}}, //don't modify the binning from here: act on maxEtaCut and PtTrh_forMaxEtaCut instead + {"hcount_D0D0bar_perEvent", "D0,D0bar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 10.}}}}}}; + + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + void process(aod::McCollision const& mccollision, soa::Join const& particlesMC) + { + int counterD0D0bar = 0; + registry.fill(HIST("hMCEvt_count"), 0); + //MC gen level + for (auto& particle1 : particlesMC) { + if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) + continue; + //just checking if the particle is D0 or D0bar, for now + if (std::abs(particle1.pdgCode()) == 421) { + registry.fill(HIST("hptcand_MCGen"), particle1.pt()); + registry.fill(HIST("hEta_MCGen"), particle1.eta()); + registry.fill(HIST("hPhi_MCGen"), particle1.phi()); + registry.fill(HIST("hY_MCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); + counterD0D0bar++; + + //D-Dbar correlation dedicated section + //if it's a D0 particle, search for D0bar and evaluate correlations + if (particle1.pdgCode() == 421) { //just checking the particle PDG, not the decay channel (differently from Reco: you have a BR factor btw such levels!) + registry.fill(HIST("hcountD0triggers_MCGen"), 0); //to count trigger D0 (for normalisation) + for (auto& particle2 : particlesMC) { + if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) + continue; + if (particle2.pdgCode() == -421) { + double eta1 = particle1.eta(), eta2 = particle2.eta(), pt1 = particle1.pt(), pt2 = particle2.pt(), phi1 = particle1.phi(), phi2 = particle2.phi(); + registry.fill(HIST("hDeltaEta_pTint_MCGen"), eta2 - eta1); + registry.fill(HIST("hDeltaPhi_pTint_MCGen"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2D_pTint_MCGen"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEta_vsPt_MCGen"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhi_vsPt_MCGen"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPt_D_Dbar_MCGen"), pt2 - pt1); + registry.fill(HIST("hDeltaPt_Max_Min_MCGen"), std::max(pt2, pt1) - std::min(pt2, pt1)); + double etacut = 0.; + double ptcut = 0.; + do { //fill pairs vs etaCut plot + ptcut = 0.; + etacut += 0.1; + do { //fill pairs vs etaCut plot + if (std::abs(particle1.eta()) < etacut && std::abs(particle2.eta()) < etacut && particle1.pt() > ptcut && particle2.pt() > ptcut) + registry.fill(HIST("hDDbar_vs_EtaCut_MCGen"), etacut - 0.01, ptcut + 0.01); + ptcut += 0.5; + } while (ptcut < PtTrh_forMaxEtaCut - 0.05); + } while (etacut < maxEtaCut - 0.05); + } // end D0bar check + } //end inner loop + } //end D0 check + } //end outer if (MC check D0/D0bar) + + } //end outer loop + registry.fill(HIST("hcount_D0D0bar_perEvent"), counterD0D0bar); + } +}; + +/// D0 analysis task - LIKE SIGN - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) +struct TaskD0_LS { + + HistogramRegistry registry{ + "registry", + //NOTE: use hmassD0 for normalisation, and hmass2D_correlPairs for 2D-sideband-subtraction purposes + {{"hmass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hmassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hmassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hmass2D_correlPairs", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, + {"hptcand", "D0,D0bar candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong0", "D0,D0bar candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong1", "D0,D0bar candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hselectionstatus", "D0,D0bar candidates;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, + {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhi", "D0,D0bar candidates;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hY", "D0,D0bar candidates;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDeltaEta_pTint", "D0,D0bar candidates;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhi_pTint", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2D_pTint", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEta_vsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhi_vsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPt_D_Dbar", "D0,D0bar candidates;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPt_Max_Min", "D0,D0bar candidates;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}}}; + + Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) + { + for (auto& candidate1 : candidates) { + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + continue; + //fill invariant mass plots and generic info from all D0/D0bar candidates + if (candidate1.isSelD0() >= d_selectionFlagD0) { + registry.fill(HIST("hmass"), InvMassD0(candidate1)); + registry.fill(HIST("hmassD0"), InvMassD0(candidate1)); + } + if (candidate1.isSelD0bar() >= d_selectionFlagD0bar) { + registry.fill(HIST("hmass"), InvMassD0bar(candidate1)); + registry.fill(HIST("hmassD0bar"), InvMassD0bar(candidate1)); + } + registry.fill(HIST("hptcand"), candidate1.pt()); + registry.fill(HIST("hptprong0"), candidate1.ptProng0()); + registry.fill(HIST("hptprong1"), candidate1.ptProng1()); + registry.fill(HIST("hEta"), candidate1.eta()); + registry.fill(HIST("hPhi"), candidate1.phi()); + registry.fill(HIST("hY"), YD0(candidate1)); + registry.fill(HIST("hselectionstatus"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); + + double pt_part1 = candidate1.pt(); //trigger particle is the largest-pT one + + //D-Dbar correlation dedicated section + //For like-sign, first loop on both D0 and D0bars. First candidate is for sure a D0 and D0bars (checked before, so don't re-check anything on it) + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { + continue; + } + //for the associated, has to have smaller pT, and pass D0sel if trigger passes D0sel, or D0barsel if trigger passes D0barsel + if (candidate2.pt() < pt_part1 && ((candidate1.isSelD0() >= d_selectionFlagD0 && candidate2.isSelD0() >= d_selectionFlagD0) || (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate2.isSelD0bar() >= d_selectionFlagD0bar))) { + if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + continue; + //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) + if (candidate1.mRowIndex == candidate2.mRowIndex) + continue; + double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); + registry.fill(HIST("hmass2D_correlPairs"), InvMassD0(candidate1), InvMassD0bar(candidate2)); + registry.fill(HIST("hDeltaEta_pTint"), eta2 - eta1); + registry.fill(HIST("hDeltaPhi_pTint"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2D_pTint"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEta_vsPt"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhi_vsPt"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPt_D_Dbar"), pt2 - pt1); + registry.fill(HIST("hDeltaPt_Max_Min"), std::max(pt2, pt1) - std::min(pt2, pt1)); + } + //note: candidates selected as both D0 and D0bar are used, and considered in both situation (but not auto-correlated): reflections could play a relevant role. + //another, more restrictive, option, could be to consider only candidates selected with a single option (D0 xor D0bar) + + } // end inner loop (Dbars) + + } //end outer loop + } +}; + +/// D0 analysis task - LIKE SIGN - for MC reco analysis (data-like but matching to true DO and D0bar) +struct TaskD0MCrec_LS { + + HistogramRegistry registry{ + "registry", + //NOTE: use hmassD0_MCRec for normalisation, and hmass2D_correlPairs_MCRec for 2D-sideband-subtraction purposes + {{"hmassD0_MCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, + {"hmassD0bar_MCRec", "D0,D0bar candidates - MC reco;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, + {"hmass2D_correlPairs_MCRec", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, + {"hptcand_MCRec", "D0,D0bar candidates - MC reco;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong0_MCRec", "D0,D0bar candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong1_MCRec", "D0,D0bar candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hEta_MCRec", "D0,D0bar candidates - MC reco;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhi_MCRec", "D0,D0bar candidates - MC reco;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hY_MCRec", "D0,D0bar candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDeltaEta_pTint_MCRec", "D0,D0bar candidates - MC reco;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhi_pTint_MCRec", "D0,D0bar candidates - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2D_pTint_MCRec", "D0,D0bar candidates - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEta_vsPt_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhi_vsPt_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPt_D_Dbar_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPt_Max_Min_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}}}; + + Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) + { + //MC reco level + for (auto& candidate1 : candidates) { + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + continue; + if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { + //fill invariant mass plots and generic info from all D0/D0bar candidates + if (candidate1.isSelD0() >= d_selectionFlagD0 && candidate1.flagMCMatchRec() == D0ToPiK) { //only reco and matched as D0 + registry.fill(HIST("hmassD0_MCRec"), InvMassD0(candidate1)); + } + if (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == D0ToPiK) { //only reco and matched as D0bar + registry.fill(HIST("hmassD0bar_MCRec"), InvMassD0bar(candidate1)); + } + registry.fill(HIST("hptcand_MCRec"), candidate1.pt()); + registry.fill(HIST("hptprong0_MCRec"), candidate1.ptProng0()); + registry.fill(HIST("hptprong1_MCRec"), candidate1.ptProng1()); + registry.fill(HIST("hEta_MCRec"), candidate1.eta()); + registry.fill(HIST("hPhi_MCRec"), candidate1.phi()); + registry.fill(HIST("hY_MCRec"), YD0(candidate1)); + + double pt_part1 = candidate1.pt(); //trigger particle is the largest pT one + + //D-Dbar correlation dedicated section + //For like-sign, first loop on both D0 and D0bars. First candidate is for sure a D0 and D0bars (looping on filtered) and was already matched, so don't re-check anything on it) + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { + continue; + } + bool condLS_D0 = (candidate1.isSelD0() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == 1 << D0ToPiK) && (candidate2.isSelD0() >= d_selectionFlagD0bar && candidate2.flagMCMatchRec() == 1 << D0ToPiK); + bool condLS_D0bar = (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == -1 << D0ToPiK) && (candidate2.isSelD0bar() >= d_selectionFlagD0bar && candidate2.flagMCMatchRec() == -1 << D0ToPiK); + if (candidate2.pt() < pt_part1 && (condLS_D0 || condLS_D0bar)) { //LS pair (of D0 or of D0bar) + pt2= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + continue; + //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) + if (candidate1.mRowIndex == candidate2.mRowIndex) + continue; + double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); + registry.fill(HIST("hmass2D_correlPairs_MCRec"), InvMassD0(candidate1), InvMassD0bar(candidate2)); + registry.fill(HIST("hDeltaEta_pTint_MCRec"), eta2 - eta1); + registry.fill(HIST("hDeltaPhi_pTint_MCRec"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2D_pTint_MCRec"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEta_vsPt_MCRec"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhi_vsPt_MCRec"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPt_D_Dbar_MCRec"), pt2 - pt1); + registry.fill(HIST("hDeltaPt_Max_Min_MCRec"), std::max(pt2, pt1) - std::min(pt2, pt1)); + } //end inner if (MC match) + + } // end inner loop (Dbars) + } //end outer if (MC match) + } //end outer loop + } +}; + +/// D0 analysis task - for MC gen-level analysis, like sign particles +struct TaskD0MCgen_LS { + + HistogramRegistry registry{ + "registry", + {{"hMCEvt_count", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hptcand_MCGen", "D0,D0bar LS particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hcountD0triggers_MCGen", "D0,D0bar LS trigger particles (to be divided by two) - MC gen;;N of triggers", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hEta_MCGen", "D0,D0bar LS particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhi_MCGen", "D0,D0bar LS particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hY_MCGen", "D0,D0bar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDeltaEta_pTint_MCGen", "D0,D0bar LS particles - MC gen;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhi_pTint_MCGen", "D0,D0bar LS particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2D_pTint_MCGen", "D0,D0bar LS particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEta_vsPt_MCGen", "D0,D0bar LS LS candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhi_vsPt_MCGen", "D0,D0bar LS candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPt_D_Dbar_MCGen", "D0,D0bar LS particles - MC gen;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPt_Max_Min_MCGen", "D0,D0bar LS particles - MC gen;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, + {"hcount_D0D0bar_perEvent", "D0,D0bar LS particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 20.}}}}}}; + + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + void process(aod::McCollision const& mccollision, soa::Join const& particlesMC) + { + int counterD0D0bar = 0; + registry.fill(HIST("hMCEvt_count"), 0); + //MC gen level + for (auto& particle1 : particlesMC) { + if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) + continue; + + double pt_part1 = particle1.pt(); //trigger particle is the largest pT one + + //Check whether particle is D0 or D0bar (and not the decay chain) + if (std::abs(particle1.pdgCode()) == 421) { + registry.fill(HIST("hptcand_MCGen"), particle1.pt()); + registry.fill(HIST("hEta_MCGen"), particle1.eta()); + registry.fill(HIST("hPhi_MCGen"), particle1.phi()); + registry.fill(HIST("hY_MCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); + counterD0D0bar++; + //D-Dbar correlation dedicated section + //if it's D0, search for D0bar and evaluate correlations. + registry.fill(HIST("hcountD0triggers_MCGen"), 0); //to count trigger D0 (normalisation) + for (auto& particle2 : particlesMC) { + if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) + continue; + if (particle2.pt() < pt_part1 && particle2.pdgCode() == particle1.pdgCode()) { //like-sign condition (both 421 or both -421) and pT_Trig>pT_assoc + //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) + if (particle1.mRowIndex == particle2.mRowIndex) + continue; + double eta1 = particle1.eta(), eta2 = particle2.eta(), pt1 = particle1.pt(), pt2 = particle2.pt(), phi1 = particle1.phi(), phi2 = particle2.phi(); + registry.fill(HIST("hDeltaEta_pTint_MCGen"), eta2 - eta1); + registry.fill(HIST("hDeltaPhi_pTint_MCGen"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2D_pTint_MCGen"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEta_vsPt_MCGen"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhi_vsPt_MCGen"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPt_D_Dbar_MCGen"), pt2 - pt1); + registry.fill(HIST("hDeltaPt_Max_Min_MCGen"), std::max(pt2, pt1) - std::min(pt2, pt1)); + } + } // end inner loop (Dbars) + } //end outer if (MC check D0) + } //end outer loop + registry.fill(HIST("hcount_D0D0bar_perEvent"), counterD0D0bar); + } +}; + +/// c-cbar correlation task analysis task - for MC gen-level analysis +struct TaskCCbarMCgen { + + HistogramRegistry registry{ + "registry", + {{"hMCEvt_count", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hptcand_MCGen", "c,cbar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hcountD0triggers_MCGen", "c trigger particles - MC gen;;N of trigger c", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hEta_MCGen", "c,cbar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhi_MCGen", "c,cbar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hDeltaEta_pTint_MCGen", "c,cbar particles - MC gen;#it{#eta}^{cbar}-#it{#eta}^{c};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhi_pTint_MCGen", "c,cbar particles - MC gen;#it{#varphi}^{cbar}-#it{#varphi}^{c};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2D_pTint_MCGen", "c,cbar particles - MC gen;#it{#varphi}^{cbar}-#it{#varphi}^{c};#it{#eta}^{cbar}-#it{#eta}^{c};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEta_vsPt_MCGen", "c,cbar candidates - MC gen;#it{p}_{T}^{c};#it{p}_{T}^{c}bar};#it{#eta}^{D0bar}-#it{#eta}^{c};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhi_vsPt_MCGen", "c,cbar candidates - MC gen;#it{p}_{T}^{c};#it{p}_{T}^{cbar};#it{#varphi}^{D0bar}-#it{#varphi}^{c};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPt_D_Dbar_MCGen", "c,cbar particles - MC gen;#it{p}_{T}^{cbar}-#it{p}_{T}^{c};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPt_Max_Min_MCGen", "c,cbar particles - MC gen;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, + {"hcount_ccbar_perEvent", "c,cbar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 20.}}}}, + {"hcount_ccbar_preEtasel_perEvent", "c,cbar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 20.}}}}}}; + + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + void process(aod::McCollision const& mccollision, soa::Join const& particlesMC) + { + registry.fill(HIST("hMCEvt_count"), 0); + int counterccbar = 0, counterccbar_preEtasel = 0; + + //loop over particles at MC gen level + for (auto& particle1 : particlesMC) { + if (std::abs(particle1.pdgCode()) == 4) { //c or cbar quark found + int partMothPDG = particlesMC.iteratorAt(particle1.mother0()).pdgCode(); + if (std::abs(partMothPDG) != 4) + counterccbar_preEtasel++; //count c or cbar when it doesn't come from itself via fragmenatation (c->c+X) + if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) + continue; + registry.fill(HIST("hptcand_MCGen"), particle1.pt()); + registry.fill(HIST("hEta_MCGen"), particle1.eta()); + registry.fill(HIST("hPhi_MCGen"), particle1.phi()); + if (std::abs(partMothPDG) != 4) + counterccbar++; //count if c or cbar don't come from themselves during fragmenatation (after kinematic selection) + + //c-cbar correlation dedicated section + //if it's c, search for cbar and evaluate correlations. + if (particle1.pdgCode() == 4) { + //check whether mothers of quark c are still '4' particles - in that case the c quark comes from its own fragmentation, skip it + if (partMothPDG == 4) + continue; + registry.fill(HIST("hcountD0triggers_MCGen"), 0); //to count trigger c quark (for normalisation) + + for (auto& particle2 : particlesMC) { + if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) + continue; + if (particle2.pdgCode() == -4) { + //check whether mothers of quark cbar are still '-4' particles - in that case the cbar quark comes from its own fragmentation, skip it + if (particlesMC.iteratorAt(particle2.mother0()).pdgCode() == -4) + continue; + double eta1 = particle1.eta(), eta2 = particle2.eta(), pt1 = particle1.pt(), pt2 = particle2.pt(), phi1 = particle1.phi(), phi2 = particle2.phi(); + registry.fill(HIST("hDeltaEta_pTint_MCGen"), eta2 - eta1); + registry.fill(HIST("hDeltaPhi_pTint_MCGen"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2D_pTint_MCGen"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEta_vsPt_MCGen"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhi_vsPt_MCGen"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPt_D_Dbar_MCGen"), pt2 - pt1); + registry.fill(HIST("hDeltaPt_Max_Min_MCGen"), std::max(particle2.pt(), particle1.pt()) - std::min(particle2.pt(), particle1.pt())); + } // end outer if (check cbar) + } // end inner loop + } //end outer if (check c) + } //end c/cbar if + } //end outer loop + registry.fill(HIST("hcount_ccbar_perEvent"), counterccbar); + registry.fill(HIST("hcount_ccbar_preEtasel_perEvent"), counterccbar_preEtasel); + } +}; + +/// checks phi resolution for standard definition and sec-vtx based definition +struct TaskD0_CheckPhiResolution { + + HistogramRegistry registry{ + "registry", + {{"hmass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhi_std", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, 0., 2. * o2::constants::math::PI}, {50, 0., 50.}}}}, + {"hPhi_byvtx", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, 0., 2. * o2::constants::math::PI}, {50, 0., 50.}}}}, + {"hPhi_difference_2meth", "D0,D0bar candidates;candidate #it{#Delta#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {50, 0., 50.}}}}, + {"hDiff_GenPhi_stdPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {50, 0., 50.}}}}, + {"hDiff_GenPhi_byvtxPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {50, 0., 50.}}}}, + {"hDeltaPhi_pTint_std", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPhi_pTint_byvtx", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPhi_vsPt_std", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPhi_vsPt_byvtx", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}}}; + + Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::McParticles const& particlesMC, aod::BigTracksMC const& tracksMC) + { + for (auto& candidate1 : candidates) { + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + continue; + registry.fill(HIST("hmass"), InvMassD0(candidate1)); + registry.fill(HIST("hEta"), candidate1.eta()); + + //D-Dbar correlation dedicated section + //if it's a candidate D0, search for D0bar and evaluate correlations + if (candidate1.isSelD0() >= d_selectionFlagD0) { + double primVtx_x = candidate1.index0_as().collision().posX(), primVtx_y = candidate1.index0_as().collision().posY(); + double pt1 = candidate1.pt(), phi1_std = candidate1.phi(); + double phi1_vtx = EvaluatePhiByVertex(primVtx_x, candidate1.xSecondaryVertex(), primVtx_y, candidate1.ySecondaryVertex()); + registry.fill(HIST("hPhi_std"), phi1_std, pt1); + registry.fill(HIST("hPhi_byvtx"), phi1_vtx, pt1); //trick to have correct Phi range + registry.fill(HIST("hPhi_difference_2meth"), getDeltaPhi(phi1_vtx, phi1_std), pt1); + + //get corresponding gen-level D0, if exists, and evaluate gen-rec phi-difference with two approaches + if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { //ok to keep both D0 and D0bar + int indexGen = RecoDecay::getMother(particlesMC, candidate1.index0_as().label(), 421, true); //MC-gen corresponding index for MC-reco candidate + if (indexGen > 0) { + double phi1_gen = particlesMC.iteratorAt(indexGen).phi(); + registry.fill(HIST("hDiff_GenPhi_stdPhi"), getDeltaPhi(phi1_std, phi1_gen), pt1); + registry.fill(HIST("hDiff_GenPhi_byvtxPhi"), getDeltaPhi(phi1_vtx, phi1_gen), pt1); + } + } + + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (candidate2.isSelD0bar() >= d_selectionFlagD0bar) { //accept only D0bar candidates + if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + continue; + //Excluding self-correlations (could happen in case of reflections) + if (candidate1.mRowIndex == candidate2.mRowIndex) + continue; + double pt2 = candidate2.pt(), phi2_std = candidate2.phi(); + double phi2_vtx = EvaluatePhiByVertex(primVtx_x, candidate2.xSecondaryVertex(), primVtx_y, candidate2.ySecondaryVertex()); + registry.fill(HIST("hDeltaPhi_pTint_std"), getDeltaPhi(phi2_std, phi1_std)); + registry.fill(HIST("hDeltaPhi_pTint_byvtx"), getDeltaPhi(phi2_vtx, phi1_vtx)); + registry.fill(HIST("hDeltaPhi_vsPt_std"), pt1, pt2, getDeltaPhi(phi2_std, phi1_std)); + registry.fill(HIST("hDeltaPhi_vsPt_byvtx"), pt1, pt2, getDeltaPhi(phi2_vtx, phi1_vtx)); + } + } // end inner loop (Dbars) + } + } //end outer loop + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask("add-collision-id"), + adaptAnalysisTask("hf-task-d0"), + adaptAnalysisTask("hf-task-d0-ls")}; + //MC-based tasks + const bool doMC = cfgc.options().get("doMC"); + if (doMC) { + workflow.push_back(adaptAnalysisTask("hf-task-d0-mc-rec")); + workflow.push_back(adaptAnalysisTask("hf-task-d0-mc-gen")); + workflow.push_back(adaptAnalysisTask("hf-task-d0-mc-rec-ls")); + workflow.push_back(adaptAnalysisTask("hf-task-d0-mc-gen-ls")); + workflow.push_back(adaptAnalysisTask("hf-task-ccbar-mc-gen")); + workflow.push_back(adaptAnalysisTask("hf-task-d0-crosscheck-phi")); + } + return workflow; +} From 5da5d21b171b4871674027ddb4094038cb6e44f3 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Fri, 12 Feb 2021 15:34:36 +0100 Subject: [PATCH 02/24] Modified task names --- Analysis/Tasks/PWGHF/CMakeLists.txt | 2 +- Analysis/Tasks/PWGHF/HFDDbar_corr.cxx | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Analysis/Tasks/PWGHF/CMakeLists.txt b/Analysis/Tasks/PWGHF/CMakeLists.txt index b54f47ce0aa0e..9f85848da11e5 100644 --- a/Analysis/Tasks/PWGHF/CMakeLists.txt +++ b/Analysis/Tasks/PWGHF/CMakeLists.txt @@ -88,7 +88,7 @@ o2_add_dpl_workflow(hf-task-bplus PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) -o2_add_dpl_workflow(hf-ddbar_corr +o2_add_dpl_workflow(hf-task-ddbar-corr SOURCES HFDDbar_corr.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) diff --git a/Analysis/Tasks/PWGHF/HFDDbar_corr.cxx b/Analysis/Tasks/PWGHF/HFDDbar_corr.cxx index 580c535ddb3a8..da86fa3861cdd 100644 --- a/Analysis/Tasks/PWGHF/HFDDbar_corr.cxx +++ b/Analysis/Tasks/PWGHF/HFDDbar_corr.cxx @@ -807,17 +807,17 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ adaptAnalysisTask("add-collision-id"), - adaptAnalysisTask("hf-task-d0"), - adaptAnalysisTask("hf-task-d0-ls")}; + adaptAnalysisTask("hf-task-d0d0bar"), + adaptAnalysisTask("hf-task-d0d0bar-ls")}; //MC-based tasks const bool doMC = cfgc.options().get("doMC"); if (doMC) { - workflow.push_back(adaptAnalysisTask("hf-task-d0-mc-rec")); - workflow.push_back(adaptAnalysisTask("hf-task-d0-mc-gen")); - workflow.push_back(adaptAnalysisTask("hf-task-d0-mc-rec-ls")); - workflow.push_back(adaptAnalysisTask("hf-task-d0-mc-gen-ls")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-mc-rec")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-mc-gen")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-mc-rec-ls")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-mc-gen-ls")); workflow.push_back(adaptAnalysisTask("hf-task-ccbar-mc-gen")); - workflow.push_back(adaptAnalysisTask("hf-task-d0-crosscheck-phi")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-crosscheck-phi")); } return workflow; } From 7e324dccf5d4a42435de7a55c58b893cbc0b0ce8 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Thu, 18 Feb 2021 19:28:52 +0100 Subject: [PATCH 03/24] Renamed tasks and source file according to conventions --- Analysis/Tasks/PWGHF/CMakeLists.txt | 4 +-- .../{HFDDbar_corr.cxx => taskD0D0barCorr.cxx} | 32 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) rename Analysis/Tasks/PWGHF/{HFDDbar_corr.cxx => taskD0D0barCorr.cxx} (98%) diff --git a/Analysis/Tasks/PWGHF/CMakeLists.txt b/Analysis/Tasks/PWGHF/CMakeLists.txt index 9f85848da11e5..81b117c1f7d86 100644 --- a/Analysis/Tasks/PWGHF/CMakeLists.txt +++ b/Analysis/Tasks/PWGHF/CMakeLists.txt @@ -88,7 +88,7 @@ o2_add_dpl_workflow(hf-task-bplus PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) -o2_add_dpl_workflow(hf-task-ddbar-corr - SOURCES HFDDbar_corr.cxx +o2_add_dpl_workflow(hf-task-d0d0bar-corr + SOURCES taskD0D0barCorr.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) diff --git a/Analysis/Tasks/PWGHF/HFDDbar_corr.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorr.cxx similarity index 98% rename from Analysis/Tasks/PWGHF/HFDDbar_corr.cxx rename to Analysis/Tasks/PWGHF/taskD0D0barCorr.cxx index da86fa3861cdd..fba38b7865a99 100644 --- a/Analysis/Tasks/PWGHF/HFDDbar_corr.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorr.cxx @@ -85,7 +85,7 @@ double EvaluatePhiByVertex(double x_vtx1, double x_vtx2, double y_vtx1, double y } /// D0 analysis task - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) -struct TaskD0 { +struct TaskD0D0barCorr { double maxEtaCut = 5., PtTrh_forMaxEtaCut = 10.; //for hDDbar_vs_EtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 @@ -195,7 +195,7 @@ struct TaskD0 { }; /// D0 analysis task - for MC reco-level analysis (candidates matched to true signal only) -struct TaskD0MCrec { +struct TaskD0D0barCorr_MCrec { double maxEtaCut = 5., PtTrh_forMaxEtaCut = 10.; //for hDDbar_vs_EtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 @@ -297,7 +297,7 @@ struct TaskD0MCrec { }; /// D0 analysis task - for MC gen-level analysis (no filter/selection, only true signal) -struct TaskD0MCgen { +struct TaskD0D0barCorr_MCgen { double maxEtaCut = 5., PtTrh_forMaxEtaCut = 10.; //for hDDbar_vs_EtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 @@ -380,7 +380,7 @@ struct TaskD0MCgen { }; /// D0 analysis task - LIKE SIGN - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) -struct TaskD0_LS { +struct TaskD0D0barCorr_LS { HistogramRegistry registry{ "registry", @@ -477,7 +477,7 @@ struct TaskD0_LS { }; /// D0 analysis task - LIKE SIGN - for MC reco analysis (data-like but matching to true DO and D0bar) -struct TaskD0MCrec_LS { +struct TaskD0D0barCorr_MCrec_LS { HistogramRegistry registry{ "registry", @@ -570,7 +570,7 @@ struct TaskD0MCrec_LS { }; /// D0 analysis task - for MC gen-level analysis, like sign particles -struct TaskD0MCgen_LS { +struct TaskD0D0barCorr_MCgen_LS { HistogramRegistry registry{ "registry", @@ -641,7 +641,7 @@ struct TaskD0MCgen_LS { }; /// c-cbar correlation task analysis task - for MC gen-level analysis -struct TaskCCbarMCgen { +struct TaskCCbarCorr_MCgen { HistogramRegistry registry{ "registry", @@ -720,7 +720,7 @@ struct TaskCCbarMCgen { }; /// checks phi resolution for standard definition and sec-vtx based definition -struct TaskD0_CheckPhiResolution { +struct TaskD0D0barCorr_CheckPhiResolution { HistogramRegistry registry{ "registry", @@ -807,17 +807,17 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ adaptAnalysisTask("add-collision-id"), - adaptAnalysisTask("hf-task-d0d0bar"), - adaptAnalysisTask("hf-task-d0d0bar-ls")}; + adaptAnalysisTask("hf-task-d0d0bar-corr"), + adaptAnalysisTask("hf-task-d0d0bar-corr-ls")}; //MC-based tasks const bool doMC = cfgc.options().get("doMC"); if (doMC) { - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-mc-rec")); - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-mc-gen")); - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-mc-rec-ls")); - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-mc-gen-ls")); - workflow.push_back(adaptAnalysisTask("hf-task-ccbar-mc-gen")); - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-crosscheck-phi")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-corr-mc-rec")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-corr-mc-gen")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-corr-mc-rec-ls")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-corr-mc-gen-ls")); + workflow.push_back(adaptAnalysisTask("hf-task-ccbar-corr-mc-gen")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-corr-crosscheck-phi")); } return workflow; } From 29060c945b11830ebc9b4de3a0363f280352d520 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Fri, 19 Feb 2021 11:30:19 +0100 Subject: [PATCH 04/24] Updates to complying to code conventions --- Analysis/Tasks/PWGHF/CMakeLists.txt | 4 +- Analysis/Tasks/PWGHF/taskD0D0barCorr.cxx | 823 ------------------ .../Tasks/PWGHF/taskD0D0barCorrelation.cxx | 823 ++++++++++++++++++ 3 files changed, 825 insertions(+), 825 deletions(-) delete mode 100644 Analysis/Tasks/PWGHF/taskD0D0barCorr.cxx create mode 100644 Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx diff --git a/Analysis/Tasks/PWGHF/CMakeLists.txt b/Analysis/Tasks/PWGHF/CMakeLists.txt index 81b117c1f7d86..70de51f4be5ce 100644 --- a/Analysis/Tasks/PWGHF/CMakeLists.txt +++ b/Analysis/Tasks/PWGHF/CMakeLists.txt @@ -88,7 +88,7 @@ o2_add_dpl_workflow(hf-task-bplus PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) -o2_add_dpl_workflow(hf-task-d0d0bar-corr - SOURCES taskD0D0barCorr.cxx +o2_add_dpl_workflow(hf-task-d0d0bar-correlation + SOURCES taskD0D0barCorrelation.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorr.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorr.cxx deleted file mode 100644 index fba38b7865a99..0000000000000 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorr.cxx +++ /dev/null @@ -1,823 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file HFDDbar_corr.cxx -/// \brief D0-D0bar analysis task - data-like, MC-reco and MC-kine analyses. For ULS and LS pairs -/// -/// \author Fabio Colamaria , INFN Bari - -#include - -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "AnalysisDataModel/HFSecondaryVertex.h" -#include "AnalysisDataModel/HFCandidateSelectionTables.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::aod::hf_cand_prong2; -using namespace o2::framework::expressions; -using namespace o2::constants::math; - -// the following is needed to extend the standard candidate table, and allow grouping candidate table by collisions -namespace o2::aod -{ -namespace hf_2prong_correl -{ -DECLARE_SOA_INDEX_COLUMN(Collision, collision); -} // namespace hf_2prong_correl -DECLARE_SOA_TABLE(HF2ProngCollis, "AOD", "COLLID_2PR", aod::hf_2prong_correl::CollisionId); - -using Big2Prong = soa::Join; -using Big2ProngMC = soa::Join; -} // namespace o2::aod - -// preliminary task to fill the column index to the extended candidate table -struct CreateBig2Prong { - - Produces create2ProngIndexCollColumn; - void process(aod::HfCandProng2 const& candidates, aod::Tracks const& tracks) - { - for (auto& candidate : candidates) { - int indexColl = candidate.index0_as().collisionId(); //takes index of collision from first D daughter - create2ProngIndexCollColumn(indexColl); - } - } -}; - -void customize(std::vector& workflowOptions) -{ - ConfigParamSpec optionDoMC{"doMC", VariantType::Bool, false, {"Run MC-dedicated tasks."}}; - workflowOptions.push_back(optionDoMC); -} - -#include "Framework/runDataProcessing.h" - -double getDeltaPhi(double phiD, double phiDbar) -{ - double dPhi = phiDbar - phiD; - - if (dPhi < -o2::constants::math::PI / 2.) - dPhi = dPhi + 2 * o2::constants::math::PI; - if (dPhi > 3. * o2::constants::math::PI / 2.) - dPhi = dPhi - 2 * o2::constants::math::PI; - - return dPhi; -} - -double EvaluatePhiByVertex(double x_vtx1, double x_vtx2, double y_vtx1, double y_vtx2) -{ - double phi = std::atan2((y_vtx2 - y_vtx1), (x_vtx2 - x_vtx1)); - - if (phi < 0) - phi = phi + 2 * o2::constants::math::PI; - if (phi > 2 * o2::constants::math::PI) - phi = phi - 2 * o2::constants::math::PI; - - return phi; -} - -/// D0 analysis task - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) -struct TaskD0D0barCorr { - - double maxEtaCut = 5., PtTrh_forMaxEtaCut = 10.; //for hDDbar_vs_EtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 - - HistogramRegistry registry{ - "registry", - //NOTE: use hmassD0 for normalisation, and hmass2D_correlPairs for 2D-sideband-subtraction purposes - {{"hmass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, - {"hmassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, - {"hmassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, - {"hmass2D_correlPairs", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, - {"hptcand", "D0,D0bar candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong0", "D0,D0bar candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong1", "D0,D0bar candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hselectionstatus", "D0,D0bar candidates;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, - {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hPhi", "D0,D0bar candidates;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, - {"hY", "D0,D0bar candidates;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hDeltaEta_pTint", "D0,D0bar candidates;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, - {"hDeltaPhi_pTint", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hCorrel2D_pTint", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, - {"hDeltaEta_vsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, - {"hDeltaPhi_vsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hDeltaPt_D_Dbar", "D0,D0bar candidates;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, - {"hDeltaPt_Max_Min", "D0,D0bar candidates;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, - {"hDDbar_vs_EtaCut", "D0,D0bar pairs vs #eta cut;#eta_{max};entries", {HistType::kTH2F, {{10 * maxEtaCut, 0., maxEtaCut}, {2 * PtTrh_forMaxEtaCut, 0., PtTrh_forMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and PtTrh_forMaxEtaCut instead - - Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; - Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; - Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; - - Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); - - void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) - { - for (auto& candidate1 : candidates) { - if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) - continue; - //check decay channel flag for candidate1 - if (!(candidate1.hfflag() & 1 << D0ToPiK)) { - continue; - } - //fill invariant mass plots and generic info from all D0/D0bar candidates - if (candidate1.isSelD0() >= d_selectionFlagD0) { - registry.fill(HIST("hmass"), InvMassD0(candidate1)); - registry.fill(HIST("hmassD0"), InvMassD0(candidate1)); - } - if (candidate1.isSelD0bar() >= d_selectionFlagD0bar) { - registry.fill(HIST("hmass"), InvMassD0bar(candidate1)); - registry.fill(HIST("hmassD0bar"), InvMassD0bar(candidate1)); - } - registry.fill(HIST("hptcand"), candidate1.pt()); - registry.fill(HIST("hptprong0"), candidate1.ptProng0()); - registry.fill(HIST("hptprong1"), candidate1.ptProng1()); - registry.fill(HIST("hEta"), candidate1.eta()); - registry.fill(HIST("hPhi"), candidate1.phi()); - registry.fill(HIST("hY"), YD0(candidate1)); - registry.fill(HIST("hselectionstatus"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); - - //D-Dbar correlation dedicated section - //if the candidate is a D0, search for D0bar and evaluate correlations - if (candidate1.isSelD0() >= d_selectionFlagD0) { - for (auto& candidate2 : candidates) { - //check decay channel flag for candidate2 - if (!(candidate1.hfflag() & 1 << D0ToPiK)) { - continue; - } - if (candidate2.isSelD0bar() >= d_selectionFlagD0bar) { - if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) - continue; - //Excluding trigger self-correlations (possible in case of both mass hypotheses accepted) - if (candidate1.mRowIndex == candidate2.mRowIndex) - continue; - double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); - registry.fill(HIST("hmass2D_correlPairs"), InvMassD0(candidate1), InvMassD0bar(candidate2)); - registry.fill(HIST("hDeltaEta_pTint"), eta2 - eta1); - registry.fill(HIST("hDeltaPhi_pTint"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2D_pTint"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEta_vsPt"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhi_vsPt"), pt1, pt2, getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hDeltaPt_D_Dbar"), pt2 - pt1); - registry.fill(HIST("hDeltaPt_Max_Min"), std::max(pt2, pt1) - std::min(pt2, pt1)); - double etacut = 0.; - double ptcut = 0.; - do { //fill pairs vs etaCut plot - ptcut = 0.; - etacut += 0.1; - do { //fill pairs vs etaCut plot - if (std::abs(candidate1.eta()) < etacut && std::abs(candidate2.eta()) < etacut && candidate1.pt() > ptcut && candidate2.pt() > ptcut) - registry.fill(HIST("hDDbar_vs_EtaCut"), etacut - 0.01, ptcut + 0.01); - ptcut += 0.5; - } while (ptcut < PtTrh_forMaxEtaCut - 0.05); - } while (etacut < maxEtaCut - 0.05); - } - //note: candidates selected as both D0 and D0bar are used, and considered in both situation (but not auto-correlated): reflections could play a relevant role. - //another, more restrictive, option, could be to consider only candidates selected with a single option (D0 xor D0bar) - - } // end inner loop (Dbars) - } - - } //end outer loop - } -}; - -/// D0 analysis task - for MC reco-level analysis (candidates matched to true signal only) -struct TaskD0D0barCorr_MCrec { - - double maxEtaCut = 5., PtTrh_forMaxEtaCut = 10.; //for hDDbar_vs_EtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 - - HistogramRegistry registry{ - "registry", - //NOTE: use hmassD0_MCRec for normalisation, and hmass2D_correlPairs_MCRec for 2D-sideband-subtraction purposes - {{"hmassD0_MCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, - {"hmassD0bar_MCRec", "D0,D0bar candidates - MC reco;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, - {"hmass2D_correlPairs_MCRec", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, - {"hptcand_MCRec", "D0,D0bar candidates - MC reco;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong0_MCRec", "D0,D0bar candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong1_MCRec", "D0,D0bar candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hEta_MCRec", "D0,D0bar candidates - MC reco;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hPhi_MCRec", "D0,D0bar candidates - MC reco;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, - {"hY_MCRec", "D0,D0bar candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hDeltaEta_pTint_MCRec", "D0,D0bar candidates - MC reco;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, - {"hDeltaPhi_pTint_MCRec", "D0,D0bar candidates - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hCorrel2D_pTint_MCRec", "D0,D0bar candidates - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, - {"hDeltaEta_vsPt_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, - {"hDeltaPhi_vsPt_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hDeltaPt_D_Dbar_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, - {"hDeltaPt_Max_Min_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, - {"hDDbar_vs_EtaCut_MCRec", "D0,D0bar pairs vs #eta cut - MC reco;#eta_{max};entries", {HistType::kTH2F, {{10 * maxEtaCut, 0., maxEtaCut}, {2 * PtTrh_forMaxEtaCut, 0., PtTrh_forMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and PtTrh_forMaxEtaCut instead - - Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; - Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; - Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; - - Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); - - void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) - { - //MC reco level - for (auto& candidate1 : candidates) { - //check decay channel flag for candidate1 - if (!(candidate1.hfflag() & 1 << D0ToPiK)) { - continue; - } - if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) - continue; - if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { - //fill invariant mass plots and generic info from all D0/D0bar candidates - if (candidate1.isSelD0() >= d_selectionFlagD0 && candidate1.flagMCMatchRec() == 1 << D0ToPiK) { //only reco and matched as D0 - registry.fill(HIST("hmassD0_MCRec"), InvMassD0(candidate1)); - } - if (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == -1 << D0ToPiK) { //only reco and matched as D0bar - registry.fill(HIST("hmassD0bar_MCRec"), InvMassD0bar(candidate1)); - } - registry.fill(HIST("hptcand_MCRec"), candidate1.pt()); - registry.fill(HIST("hptprong0_MCRec"), candidate1.ptProng0()); - registry.fill(HIST("hptprong1_MCRec"), candidate1.ptProng1()); - registry.fill(HIST("hEta_MCRec"), candidate1.eta()); - registry.fill(HIST("hPhi_MCRec"), candidate1.phi()); - registry.fill(HIST("hY_MCRec"), YD0(candidate1)); - - //D-Dbar correlation dedicated section - //if the candidate is a D0, search for D0bar and evaluate correlations - if (candidate1.isSelD0() >= d_selectionFlagD0 && candidate1.flagMCMatchRec() == 1 << D0ToPiK) { //selected as D0 (particle) && matched to D0 (particle) - for (auto& candidate2 : candidates) { - //check decay channel flag for candidate2 - if (!(candidate2.hfflag() & 1 << D0ToPiK)) { - continue; - } - if (candidate2.isSelD0bar() >= d_selectionFlagD0bar && candidate2.flagMCMatchRec() == -1 << D0ToPiK) { //selected as D0bar (antiparticle) && matched to D0bar (antiparticle) - if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) - continue; - double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); - registry.fill(HIST("hmass2D_correlPairs_MCRec"), InvMassD0(candidate1), InvMassD0bar(candidate2)); - registry.fill(HIST("hDeltaEta_pTint_MCRec"), eta2 - eta1); - registry.fill(HIST("hDeltaPhi_pTint_MCRec"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2D_pTint_MCRec"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEta_vsPt_MCRec"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhi_vsPt_MCRec"), pt1, pt2, getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hDeltaPt_D_Dbar_MCRec"), pt2 - pt1); - registry.fill(HIST("hDeltaPt_Max_Min_MCRec"), std::max(pt2, pt1) - std::min(pt2, pt1)); - double etacut = 0.; - double ptcut = 0.; - do { //fill pairs vs etaCut plot - ptcut = 0.; - etacut += 0.1; - do { //fill pairs vs etaCut plot - if (std::abs(candidate1.eta()) < etacut && std::abs(candidate2.eta()) < etacut && candidate1.pt() > ptcut && candidate2.pt() > ptcut) - registry.fill(HIST("hDDbar_vs_EtaCut_MCRec"), etacut - 0.01, ptcut + 0.01); - ptcut += 0.5; - } while (ptcut < PtTrh_forMaxEtaCut - 0.05); - } while (etacut < maxEtaCut - 0.05); - } //end inner if (MC match) - - } // end inner loop (Dbars) - } - } //end outer if (MC match) - } //end outer loop - } -}; - -/// D0 analysis task - for MC gen-level analysis (no filter/selection, only true signal) -struct TaskD0D0barCorr_MCgen { - - double maxEtaCut = 5., PtTrh_forMaxEtaCut = 10.; //for hDDbar_vs_EtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 - - HistogramRegistry registry{ - "registry", - {{"hMCEvt_count", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, - {"hptcand_MCGen", "D0,D0bar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hcountD0triggers_MCGen", "D0 trigger particles - MC gen;;N of trigger D0", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, - {"hEta_MCGen", "D0,D0bar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hPhi_MCGen", "D0,D0bar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, - {"hY_MCGen", "D0,D0bar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hDeltaEta_pTint_MCGen", "D0,D0bar particles - MC gen;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, - {"hDeltaPhi_pTint_MCGen", "D0,D0bar particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hCorrel2D_pTint_MCGen", "D0,D0bar particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, - {"hDeltaEta_vsPt_MCGen", "D0,D0bar candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, - {"hDeltaPhi_vsPt_MCGen", "D0,D0bar candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hDeltaPt_D_Dbar_MCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, - {"hDeltaPt_Max_Min_MCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, - {"hDDbar_vs_EtaCut_MCGen", "D0,D0bar pairs vs #eta cut - MC gen;#eta_{max};entries", {HistType::kTH2F, {{10 * maxEtaCut, 0., maxEtaCut}, {2 * PtTrh_forMaxEtaCut, 0., PtTrh_forMaxEtaCut}}}}, //don't modify the binning from here: act on maxEtaCut and PtTrh_forMaxEtaCut instead - {"hcount_D0D0bar_perEvent", "D0,D0bar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 10.}}}}}}; - - Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; - Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; - - void process(aod::McCollision const& mccollision, soa::Join const& particlesMC) - { - int counterD0D0bar = 0; - registry.fill(HIST("hMCEvt_count"), 0); - //MC gen level - for (auto& particle1 : particlesMC) { - if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) - continue; - //just checking if the particle is D0 or D0bar, for now - if (std::abs(particle1.pdgCode()) == 421) { - registry.fill(HIST("hptcand_MCGen"), particle1.pt()); - registry.fill(HIST("hEta_MCGen"), particle1.eta()); - registry.fill(HIST("hPhi_MCGen"), particle1.phi()); - registry.fill(HIST("hY_MCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); - counterD0D0bar++; - - //D-Dbar correlation dedicated section - //if it's a D0 particle, search for D0bar and evaluate correlations - if (particle1.pdgCode() == 421) { //just checking the particle PDG, not the decay channel (differently from Reco: you have a BR factor btw such levels!) - registry.fill(HIST("hcountD0triggers_MCGen"), 0); //to count trigger D0 (for normalisation) - for (auto& particle2 : particlesMC) { - if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) - continue; - if (particle2.pdgCode() == -421) { - double eta1 = particle1.eta(), eta2 = particle2.eta(), pt1 = particle1.pt(), pt2 = particle2.pt(), phi1 = particle1.phi(), phi2 = particle2.phi(); - registry.fill(HIST("hDeltaEta_pTint_MCGen"), eta2 - eta1); - registry.fill(HIST("hDeltaPhi_pTint_MCGen"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2D_pTint_MCGen"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEta_vsPt_MCGen"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhi_vsPt_MCGen"), pt1, pt2, getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hDeltaPt_D_Dbar_MCGen"), pt2 - pt1); - registry.fill(HIST("hDeltaPt_Max_Min_MCGen"), std::max(pt2, pt1) - std::min(pt2, pt1)); - double etacut = 0.; - double ptcut = 0.; - do { //fill pairs vs etaCut plot - ptcut = 0.; - etacut += 0.1; - do { //fill pairs vs etaCut plot - if (std::abs(particle1.eta()) < etacut && std::abs(particle2.eta()) < etacut && particle1.pt() > ptcut && particle2.pt() > ptcut) - registry.fill(HIST("hDDbar_vs_EtaCut_MCGen"), etacut - 0.01, ptcut + 0.01); - ptcut += 0.5; - } while (ptcut < PtTrh_forMaxEtaCut - 0.05); - } while (etacut < maxEtaCut - 0.05); - } // end D0bar check - } //end inner loop - } //end D0 check - } //end outer if (MC check D0/D0bar) - - } //end outer loop - registry.fill(HIST("hcount_D0D0bar_perEvent"), counterD0D0bar); - } -}; - -/// D0 analysis task - LIKE SIGN - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) -struct TaskD0D0barCorr_LS { - - HistogramRegistry registry{ - "registry", - //NOTE: use hmassD0 for normalisation, and hmass2D_correlPairs for 2D-sideband-subtraction purposes - {{"hmass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, - {"hmassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, - {"hmassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, - {"hmass2D_correlPairs", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, - {"hptcand", "D0,D0bar candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong0", "D0,D0bar candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong1", "D0,D0bar candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hselectionstatus", "D0,D0bar candidates;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, - {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hPhi", "D0,D0bar candidates;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, - {"hY", "D0,D0bar candidates;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hDeltaEta_pTint", "D0,D0bar candidates;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, - {"hDeltaPhi_pTint", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hCorrel2D_pTint", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, - {"hDeltaEta_vsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, - {"hDeltaPhi_vsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hDeltaPt_D_Dbar", "D0,D0bar candidates;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, - {"hDeltaPt_Max_Min", "D0,D0bar candidates;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}}}; - - Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; - Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; - Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; - - Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); - - void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) - { - for (auto& candidate1 : candidates) { - //check decay channel flag for candidate1 - if (!(candidate1.hfflag() & 1 << D0ToPiK)) { - continue; - } - if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) - continue; - //fill invariant mass plots and generic info from all D0/D0bar candidates - if (candidate1.isSelD0() >= d_selectionFlagD0) { - registry.fill(HIST("hmass"), InvMassD0(candidate1)); - registry.fill(HIST("hmassD0"), InvMassD0(candidate1)); - } - if (candidate1.isSelD0bar() >= d_selectionFlagD0bar) { - registry.fill(HIST("hmass"), InvMassD0bar(candidate1)); - registry.fill(HIST("hmassD0bar"), InvMassD0bar(candidate1)); - } - registry.fill(HIST("hptcand"), candidate1.pt()); - registry.fill(HIST("hptprong0"), candidate1.ptProng0()); - registry.fill(HIST("hptprong1"), candidate1.ptProng1()); - registry.fill(HIST("hEta"), candidate1.eta()); - registry.fill(HIST("hPhi"), candidate1.phi()); - registry.fill(HIST("hY"), YD0(candidate1)); - registry.fill(HIST("hselectionstatus"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); - - double pt_part1 = candidate1.pt(); //trigger particle is the largest-pT one - - //D-Dbar correlation dedicated section - //For like-sign, first loop on both D0 and D0bars. First candidate is for sure a D0 and D0bars (checked before, so don't re-check anything on it) - for (auto& candidate2 : candidates) { - //check decay channel flag for candidate2 - if (!(candidate2.hfflag() & 1 << D0ToPiK)) { - continue; - } - //for the associated, has to have smaller pT, and pass D0sel if trigger passes D0sel, or D0barsel if trigger passes D0barsel - if (candidate2.pt() < pt_part1 && ((candidate1.isSelD0() >= d_selectionFlagD0 && candidate2.isSelD0() >= d_selectionFlagD0) || (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate2.isSelD0bar() >= d_selectionFlagD0bar))) { - if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) - continue; - //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) - if (candidate1.mRowIndex == candidate2.mRowIndex) - continue; - double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); - registry.fill(HIST("hmass2D_correlPairs"), InvMassD0(candidate1), InvMassD0bar(candidate2)); - registry.fill(HIST("hDeltaEta_pTint"), eta2 - eta1); - registry.fill(HIST("hDeltaPhi_pTint"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2D_pTint"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEta_vsPt"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhi_vsPt"), pt1, pt2, getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hDeltaPt_D_Dbar"), pt2 - pt1); - registry.fill(HIST("hDeltaPt_Max_Min"), std::max(pt2, pt1) - std::min(pt2, pt1)); - } - //note: candidates selected as both D0 and D0bar are used, and considered in both situation (but not auto-correlated): reflections could play a relevant role. - //another, more restrictive, option, could be to consider only candidates selected with a single option (D0 xor D0bar) - - } // end inner loop (Dbars) - - } //end outer loop - } -}; - -/// D0 analysis task - LIKE SIGN - for MC reco analysis (data-like but matching to true DO and D0bar) -struct TaskD0D0barCorr_MCrec_LS { - - HistogramRegistry registry{ - "registry", - //NOTE: use hmassD0_MCRec for normalisation, and hmass2D_correlPairs_MCRec for 2D-sideband-subtraction purposes - {{"hmassD0_MCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, - {"hmassD0bar_MCRec", "D0,D0bar candidates - MC reco;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, - {"hmass2D_correlPairs_MCRec", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, - {"hptcand_MCRec", "D0,D0bar candidates - MC reco;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong0_MCRec", "D0,D0bar candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong1_MCRec", "D0,D0bar candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hEta_MCRec", "D0,D0bar candidates - MC reco;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hPhi_MCRec", "D0,D0bar candidates - MC reco;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, - {"hY_MCRec", "D0,D0bar candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hDeltaEta_pTint_MCRec", "D0,D0bar candidates - MC reco;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, - {"hDeltaPhi_pTint_MCRec", "D0,D0bar candidates - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hCorrel2D_pTint_MCRec", "D0,D0bar candidates - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, - {"hDeltaEta_vsPt_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, - {"hDeltaPhi_vsPt_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hDeltaPt_D_Dbar_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, - {"hDeltaPt_Max_Min_MCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}}}; - - Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; - Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; - Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; - - Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); - - void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) - { - //MC reco level - for (auto& candidate1 : candidates) { - //check decay channel flag for candidate1 - if (!(candidate1.hfflag() & 1 << D0ToPiK)) { - continue; - } - if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) - continue; - if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { - //fill invariant mass plots and generic info from all D0/D0bar candidates - if (candidate1.isSelD0() >= d_selectionFlagD0 && candidate1.flagMCMatchRec() == D0ToPiK) { //only reco and matched as D0 - registry.fill(HIST("hmassD0_MCRec"), InvMassD0(candidate1)); - } - if (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == D0ToPiK) { //only reco and matched as D0bar - registry.fill(HIST("hmassD0bar_MCRec"), InvMassD0bar(candidate1)); - } - registry.fill(HIST("hptcand_MCRec"), candidate1.pt()); - registry.fill(HIST("hptprong0_MCRec"), candidate1.ptProng0()); - registry.fill(HIST("hptprong1_MCRec"), candidate1.ptProng1()); - registry.fill(HIST("hEta_MCRec"), candidate1.eta()); - registry.fill(HIST("hPhi_MCRec"), candidate1.phi()); - registry.fill(HIST("hY_MCRec"), YD0(candidate1)); - - double pt_part1 = candidate1.pt(); //trigger particle is the largest pT one - - //D-Dbar correlation dedicated section - //For like-sign, first loop on both D0 and D0bars. First candidate is for sure a D0 and D0bars (looping on filtered) and was already matched, so don't re-check anything on it) - for (auto& candidate2 : candidates) { - //check decay channel flag for candidate2 - if (!(candidate2.hfflag() & 1 << D0ToPiK)) { - continue; - } - bool condLS_D0 = (candidate1.isSelD0() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == 1 << D0ToPiK) && (candidate2.isSelD0() >= d_selectionFlagD0bar && candidate2.flagMCMatchRec() == 1 << D0ToPiK); - bool condLS_D0bar = (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == -1 << D0ToPiK) && (candidate2.isSelD0bar() >= d_selectionFlagD0bar && candidate2.flagMCMatchRec() == -1 << D0ToPiK); - if (candidate2.pt() < pt_part1 && (condLS_D0 || condLS_D0bar)) { //LS pair (of D0 or of D0bar) + pt2= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) - continue; - //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) - if (candidate1.mRowIndex == candidate2.mRowIndex) - continue; - double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); - registry.fill(HIST("hmass2D_correlPairs_MCRec"), InvMassD0(candidate1), InvMassD0bar(candidate2)); - registry.fill(HIST("hDeltaEta_pTint_MCRec"), eta2 - eta1); - registry.fill(HIST("hDeltaPhi_pTint_MCRec"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2D_pTint_MCRec"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEta_vsPt_MCRec"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhi_vsPt_MCRec"), pt1, pt2, getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hDeltaPt_D_Dbar_MCRec"), pt2 - pt1); - registry.fill(HIST("hDeltaPt_Max_Min_MCRec"), std::max(pt2, pt1) - std::min(pt2, pt1)); - } //end inner if (MC match) - - } // end inner loop (Dbars) - } //end outer if (MC match) - } //end outer loop - } -}; - -/// D0 analysis task - for MC gen-level analysis, like sign particles -struct TaskD0D0barCorr_MCgen_LS { - - HistogramRegistry registry{ - "registry", - {{"hMCEvt_count", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, - {"hptcand_MCGen", "D0,D0bar LS particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hcountD0triggers_MCGen", "D0,D0bar LS trigger particles (to be divided by two) - MC gen;;N of triggers", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, - {"hEta_MCGen", "D0,D0bar LS particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hPhi_MCGen", "D0,D0bar LS particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, - {"hY_MCGen", "D0,D0bar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hDeltaEta_pTint_MCGen", "D0,D0bar LS particles - MC gen;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, - {"hDeltaPhi_pTint_MCGen", "D0,D0bar LS particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hCorrel2D_pTint_MCGen", "D0,D0bar LS particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, - {"hDeltaEta_vsPt_MCGen", "D0,D0bar LS LS candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, - {"hDeltaPhi_vsPt_MCGen", "D0,D0bar LS candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hDeltaPt_D_Dbar_MCGen", "D0,D0bar LS particles - MC gen;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, - {"hDeltaPt_Max_Min_MCGen", "D0,D0bar LS particles - MC gen;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, - {"hcount_D0D0bar_perEvent", "D0,D0bar LS particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 20.}}}}}}; - - Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; - Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; - - void process(aod::McCollision const& mccollision, soa::Join const& particlesMC) - { - int counterD0D0bar = 0; - registry.fill(HIST("hMCEvt_count"), 0); - //MC gen level - for (auto& particle1 : particlesMC) { - if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) - continue; - - double pt_part1 = particle1.pt(); //trigger particle is the largest pT one - - //Check whether particle is D0 or D0bar (and not the decay chain) - if (std::abs(particle1.pdgCode()) == 421) { - registry.fill(HIST("hptcand_MCGen"), particle1.pt()); - registry.fill(HIST("hEta_MCGen"), particle1.eta()); - registry.fill(HIST("hPhi_MCGen"), particle1.phi()); - registry.fill(HIST("hY_MCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); - counterD0D0bar++; - //D-Dbar correlation dedicated section - //if it's D0, search for D0bar and evaluate correlations. - registry.fill(HIST("hcountD0triggers_MCGen"), 0); //to count trigger D0 (normalisation) - for (auto& particle2 : particlesMC) { - if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) - continue; - if (particle2.pt() < pt_part1 && particle2.pdgCode() == particle1.pdgCode()) { //like-sign condition (both 421 or both -421) and pT_Trig>pT_assoc - //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) - if (particle1.mRowIndex == particle2.mRowIndex) - continue; - double eta1 = particle1.eta(), eta2 = particle2.eta(), pt1 = particle1.pt(), pt2 = particle2.pt(), phi1 = particle1.phi(), phi2 = particle2.phi(); - registry.fill(HIST("hDeltaEta_pTint_MCGen"), eta2 - eta1); - registry.fill(HIST("hDeltaPhi_pTint_MCGen"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2D_pTint_MCGen"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEta_vsPt_MCGen"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhi_vsPt_MCGen"), pt1, pt2, getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hDeltaPt_D_Dbar_MCGen"), pt2 - pt1); - registry.fill(HIST("hDeltaPt_Max_Min_MCGen"), std::max(pt2, pt1) - std::min(pt2, pt1)); - } - } // end inner loop (Dbars) - } //end outer if (MC check D0) - } //end outer loop - registry.fill(HIST("hcount_D0D0bar_perEvent"), counterD0D0bar); - } -}; - -/// c-cbar correlation task analysis task - for MC gen-level analysis -struct TaskCCbarCorr_MCgen { - - HistogramRegistry registry{ - "registry", - {{"hMCEvt_count", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, - {"hptcand_MCGen", "c,cbar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hcountD0triggers_MCGen", "c trigger particles - MC gen;;N of trigger c", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, - {"hEta_MCGen", "c,cbar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hPhi_MCGen", "c,cbar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, - {"hDeltaEta_pTint_MCGen", "c,cbar particles - MC gen;#it{#eta}^{cbar}-#it{#eta}^{c};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, - {"hDeltaPhi_pTint_MCGen", "c,cbar particles - MC gen;#it{#varphi}^{cbar}-#it{#varphi}^{c};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hCorrel2D_pTint_MCGen", "c,cbar particles - MC gen;#it{#varphi}^{cbar}-#it{#varphi}^{c};#it{#eta}^{cbar}-#it{#eta}^{c};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, - {"hDeltaEta_vsPt_MCGen", "c,cbar candidates - MC gen;#it{p}_{T}^{c};#it{p}_{T}^{c}bar};#it{#eta}^{D0bar}-#it{#eta}^{c};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, - {"hDeltaPhi_vsPt_MCGen", "c,cbar candidates - MC gen;#it{p}_{T}^{c};#it{p}_{T}^{cbar};#it{#varphi}^{D0bar}-#it{#varphi}^{c};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hDeltaPt_D_Dbar_MCGen", "c,cbar particles - MC gen;#it{p}_{T}^{cbar}-#it{p}_{T}^{c};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, - {"hDeltaPt_Max_Min_MCGen", "c,cbar particles - MC gen;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, - {"hcount_ccbar_perEvent", "c,cbar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 20.}}}}, - {"hcount_ccbar_preEtasel_perEvent", "c,cbar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 20.}}}}}}; - - Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; - Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; - - void process(aod::McCollision const& mccollision, soa::Join const& particlesMC) - { - registry.fill(HIST("hMCEvt_count"), 0); - int counterccbar = 0, counterccbar_preEtasel = 0; - - //loop over particles at MC gen level - for (auto& particle1 : particlesMC) { - if (std::abs(particle1.pdgCode()) == 4) { //c or cbar quark found - int partMothPDG = particlesMC.iteratorAt(particle1.mother0()).pdgCode(); - if (std::abs(partMothPDG) != 4) - counterccbar_preEtasel++; //count c or cbar when it doesn't come from itself via fragmenatation (c->c+X) - if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) - continue; - registry.fill(HIST("hptcand_MCGen"), particle1.pt()); - registry.fill(HIST("hEta_MCGen"), particle1.eta()); - registry.fill(HIST("hPhi_MCGen"), particle1.phi()); - if (std::abs(partMothPDG) != 4) - counterccbar++; //count if c or cbar don't come from themselves during fragmenatation (after kinematic selection) - - //c-cbar correlation dedicated section - //if it's c, search for cbar and evaluate correlations. - if (particle1.pdgCode() == 4) { - //check whether mothers of quark c are still '4' particles - in that case the c quark comes from its own fragmentation, skip it - if (partMothPDG == 4) - continue; - registry.fill(HIST("hcountD0triggers_MCGen"), 0); //to count trigger c quark (for normalisation) - - for (auto& particle2 : particlesMC) { - if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) - continue; - if (particle2.pdgCode() == -4) { - //check whether mothers of quark cbar are still '-4' particles - in that case the cbar quark comes from its own fragmentation, skip it - if (particlesMC.iteratorAt(particle2.mother0()).pdgCode() == -4) - continue; - double eta1 = particle1.eta(), eta2 = particle2.eta(), pt1 = particle1.pt(), pt2 = particle2.pt(), phi1 = particle1.phi(), phi2 = particle2.phi(); - registry.fill(HIST("hDeltaEta_pTint_MCGen"), eta2 - eta1); - registry.fill(HIST("hDeltaPhi_pTint_MCGen"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2D_pTint_MCGen"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEta_vsPt_MCGen"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhi_vsPt_MCGen"), pt1, pt2, getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hDeltaPt_D_Dbar_MCGen"), pt2 - pt1); - registry.fill(HIST("hDeltaPt_Max_Min_MCGen"), std::max(particle2.pt(), particle1.pt()) - std::min(particle2.pt(), particle1.pt())); - } // end outer if (check cbar) - } // end inner loop - } //end outer if (check c) - } //end c/cbar if - } //end outer loop - registry.fill(HIST("hcount_ccbar_perEvent"), counterccbar); - registry.fill(HIST("hcount_ccbar_preEtasel_perEvent"), counterccbar_preEtasel); - } -}; - -/// checks phi resolution for standard definition and sec-vtx based definition -struct TaskD0D0barCorr_CheckPhiResolution { - - HistogramRegistry registry{ - "registry", - {{"hmass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, - {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hPhi_std", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, 0., 2. * o2::constants::math::PI}, {50, 0., 50.}}}}, - {"hPhi_byvtx", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, 0., 2. * o2::constants::math::PI}, {50, 0., 50.}}}}, - {"hPhi_difference_2meth", "D0,D0bar candidates;candidate #it{#Delta#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {50, 0., 50.}}}}, - {"hDiff_GenPhi_stdPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {50, 0., 50.}}}}, - {"hDiff_GenPhi_byvtxPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {50, 0., 50.}}}}, - {"hDeltaPhi_pTint_std", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hDeltaPhi_pTint_byvtx", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hDeltaPhi_vsPt_std", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, - {"hDeltaPhi_vsPt_byvtx", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}}}; - - Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; - Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; - Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; - - Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); - - void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::McParticles const& particlesMC, aod::BigTracksMC const& tracksMC) - { - for (auto& candidate1 : candidates) { - //check decay channel flag for candidate1 - if (!(candidate1.hfflag() & 1 << D0ToPiK)) { - continue; - } - if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) - continue; - registry.fill(HIST("hmass"), InvMassD0(candidate1)); - registry.fill(HIST("hEta"), candidate1.eta()); - - //D-Dbar correlation dedicated section - //if it's a candidate D0, search for D0bar and evaluate correlations - if (candidate1.isSelD0() >= d_selectionFlagD0) { - double primVtx_x = candidate1.index0_as().collision().posX(), primVtx_y = candidate1.index0_as().collision().posY(); - double pt1 = candidate1.pt(), phi1_std = candidate1.phi(); - double phi1_vtx = EvaluatePhiByVertex(primVtx_x, candidate1.xSecondaryVertex(), primVtx_y, candidate1.ySecondaryVertex()); - registry.fill(HIST("hPhi_std"), phi1_std, pt1); - registry.fill(HIST("hPhi_byvtx"), phi1_vtx, pt1); //trick to have correct Phi range - registry.fill(HIST("hPhi_difference_2meth"), getDeltaPhi(phi1_vtx, phi1_std), pt1); - - //get corresponding gen-level D0, if exists, and evaluate gen-rec phi-difference with two approaches - if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { //ok to keep both D0 and D0bar - int indexGen = RecoDecay::getMother(particlesMC, candidate1.index0_as().label(), 421, true); //MC-gen corresponding index for MC-reco candidate - if (indexGen > 0) { - double phi1_gen = particlesMC.iteratorAt(indexGen).phi(); - registry.fill(HIST("hDiff_GenPhi_stdPhi"), getDeltaPhi(phi1_std, phi1_gen), pt1); - registry.fill(HIST("hDiff_GenPhi_byvtxPhi"), getDeltaPhi(phi1_vtx, phi1_gen), pt1); - } - } - - for (auto& candidate2 : candidates) { - //check decay channel flag for candidate2 - if (!(candidate2.hfflag() & 1 << D0ToPiK)) { - continue; - } - if (candidate2.isSelD0bar() >= d_selectionFlagD0bar) { //accept only D0bar candidates - if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) - continue; - //Excluding self-correlations (could happen in case of reflections) - if (candidate1.mRowIndex == candidate2.mRowIndex) - continue; - double pt2 = candidate2.pt(), phi2_std = candidate2.phi(); - double phi2_vtx = EvaluatePhiByVertex(primVtx_x, candidate2.xSecondaryVertex(), primVtx_y, candidate2.ySecondaryVertex()); - registry.fill(HIST("hDeltaPhi_pTint_std"), getDeltaPhi(phi2_std, phi1_std)); - registry.fill(HIST("hDeltaPhi_pTint_byvtx"), getDeltaPhi(phi2_vtx, phi1_vtx)); - registry.fill(HIST("hDeltaPhi_vsPt_std"), pt1, pt2, getDeltaPhi(phi2_std, phi1_std)); - registry.fill(HIST("hDeltaPhi_vsPt_byvtx"), pt1, pt2, getDeltaPhi(phi2_vtx, phi1_vtx)); - } - } // end inner loop (Dbars) - } - } //end outer loop - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - WorkflowSpec workflow{ - adaptAnalysisTask("add-collision-id"), - adaptAnalysisTask("hf-task-d0d0bar-corr"), - adaptAnalysisTask("hf-task-d0d0bar-corr-ls")}; - //MC-based tasks - const bool doMC = cfgc.options().get("doMC"); - if (doMC) { - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-corr-mc-rec")); - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-corr-mc-gen")); - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-corr-mc-rec-ls")); - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-corr-mc-gen-ls")); - workflow.push_back(adaptAnalysisTask("hf-task-ccbar-corr-mc-gen")); - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-corr-crosscheck-phi")); - } - return workflow; -} diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx new file mode 100644 index 0000000000000..84fff5dd1910a --- /dev/null +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -0,0 +1,823 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file taskD0D0barCorrelation.cxx +/// \brief D0-D0bar analysis task - data-like, MC-reco and MC-kine analyses. For ULS and LS pairs +/// +/// \author Fabio Colamaria , INFN Bari + +#include + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "AnalysisDataModel/HFSecondaryVertex.h" +#include "AnalysisDataModel/HFCandidateSelectionTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::aod::hf_cand_prong2; +using namespace o2::framework::expressions; +using namespace o2::constants::math; + +// the following is needed to extend the standard candidate table, and allow grouping candidate table by collisions +namespace o2::aod +{ +namespace hf_2prong_correlation +{ +DECLARE_SOA_INDEX_COLUMN(Collision, collision); +} // namespace hf_2prong_correlation +DECLARE_SOA_TABLE(HF2ProngCollis, "AOD", "COLLID_2PR", aod::hf_2prong_correlation::CollisionId); + +using Big2Prong = soa::Join; +using Big2ProngMC = soa::Join; +} // namespace o2::aod + +// preliminary task to fill the column index to the extended candidate table +struct CreateBig2Prong { + + Produces create2ProngIndexCollColumn; + void process(aod::HfCandProng2 const& candidates, aod::Tracks const& tracks) + { + for (auto& candidate : candidates) { + int indexColl = candidate.index0_as().collisionId(); //takes index of collision from first D daughter + create2ProngIndexCollColumn(indexColl); + } + } +}; + +void customize(std::vector& workflowOptions) +{ + ConfigParamSpec optionDoMC{"doMC", VariantType::Bool, false, {"Run MC-dedicated tasks."}}; + workflowOptions.push_back(optionDoMC); +} + +#include "Framework/runDataProcessing.h" + +double getDeltaPhi(double phiD, double phiDbar) +{ + double dPhi = phiDbar - phiD; + + if (dPhi < -o2::constants::math::PI / 2.) + dPhi = dPhi + 2. * o2::constants::math::PI; + if (dPhi > 3. * o2::constants::math::PI / 2.) + dPhi = dPhi - 2. * o2::constants::math::PI; + + return dPhi; +} + +double evaluatePhiByVertex(double xVertex1, double xVertex2, double yVertex1, double yVertex2) +{ + double phi = std::atan2((yVertex2 - yVertex1), (xVertex2 - xVertex1)); + + if (phi < 0.) + phi = phi + 2. * o2::constants::math::PI; + if (phi > 2. * o2::constants::math::PI) + phi = phi - 2. * o2::constants::math::PI; + + return phi; +} + +/// D0 analysis task - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) +struct TaskD0D0barCorrelation { + + double maxEtaCut = 5., PtThresholdForMaxEtaCut = 10.; //for hDDbarVsEtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 + + HistogramRegistry registry{ + "registry", + //NOTE: use hmassD0 for normalisation, and hmass2DCorrelationPairs for 2D-sideband-subtraction purposes + {{"hmass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hmassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hmassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hmass2DCorrelationPairs", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, + {"hptcand", "D0,D0bar candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong0", "D0,D0bar candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong1", "D0,D0bar candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hselectionstatus", "D0,D0bar candidates;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, + {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhi", "D0,D0bar candidates;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hY", "D0,D0bar candidates;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDeltaEtaPtInt", "D0,D0bar candidates;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhiPtInt", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2DPtInt", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEtaVsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhiVsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPtDDbar", "D0,D0bar candidates;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPtMaxMin", "D0,D0bar candidates;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, + {"hDDbarVsEtaCut", "D0,D0bar pairs vs #eta cut;#eta_{max};entries", {HistType::kTH2F, {{(int)(10 * maxEtaCut), 0., maxEtaCut}, {(int)(2 * PtThresholdForMaxEtaCut), 0., PtThresholdForMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and PtThresholdForMaxEtaCut instead + + Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) + { + for (auto& candidate1 : candidates) { + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + continue; + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + //fill invariant mass plots and generic info from all D0/D0bar candidates + if (candidate1.isSelD0() >= d_selectionFlagD0) { + registry.fill(HIST("hmass"), InvMassD0(candidate1)); + registry.fill(HIST("hmassD0"), InvMassD0(candidate1)); + } + if (candidate1.isSelD0bar() >= d_selectionFlagD0bar) { + registry.fill(HIST("hmass"), InvMassD0bar(candidate1)); + registry.fill(HIST("hmassD0bar"), InvMassD0bar(candidate1)); + } + registry.fill(HIST("hptcand"), candidate1.pt()); + registry.fill(HIST("hptprong0"), candidate1.ptProng0()); + registry.fill(HIST("hptprong1"), candidate1.ptProng1()); + registry.fill(HIST("hEta"), candidate1.eta()); + registry.fill(HIST("hPhi"), candidate1.phi()); + registry.fill(HIST("hY"), YD0(candidate1)); + registry.fill(HIST("hselectionstatus"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); + + //D-Dbar correlation dedicated section + //if the candidate is a D0, search for D0bar and evaluate correlations + if (candidate1.isSelD0() >= d_selectionFlagD0) { + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (candidate2.isSelD0bar() >= d_selectionFlagD0bar) { + if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + continue; + //Excluding trigger self-correlations (possible in case of both mass hypotheses accepted) + if (candidate1.mRowIndex == candidate2.mRowIndex) + continue; + double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); + registry.fill(HIST("hmass2DCorrelationPairs"), InvMassD0(candidate1), InvMassD0bar(candidate2)); + registry.fill(HIST("hDeltaEtaPtInt"), eta2 - eta1); + registry.fill(HIST("hDeltaPhiPtInt"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2DPtInt"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEtaVsPt"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhiVsPt"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPtDDbar"), pt2 - pt1); + registry.fill(HIST("hDeltaPtMaxMin"), std::max(pt2, pt1) - std::min(pt2, pt1)); + double etaCut = 0.; + double ptCut = 0.; + do { //fill pairs vs etaCut plot + ptCut = 0.; + etaCut += 0.1; + do { //fill pairs vs etaCut plot + if (std::abs(candidate1.eta()) < etaCut && std::abs(candidate2.eta()) < etaCut && candidate1.pt() > ptCut && candidate2.pt() > ptCut) + registry.fill(HIST("hDDbarVsEtaCut"), etaCut - 0.01, ptCut + 0.01); + ptCut += 0.5; + } while (ptCut < PtThresholdForMaxEtaCut - 0.05); + } while (etaCut < maxEtaCut - 0.05); + } + //note: candidates selected as both D0 and D0bar are used, and considered in both situation (but not auto-correlated): reflections could play a relevant role. + //another, more restrictive, option, could be to consider only candidates selected with a single option (D0 xor D0bar) + + } // end inner loop (Dbars) + } + + } //end outer loop + } +}; + +/// D0 analysis task - for MC reco-level analysis (candidates matched to true signal only) +struct TaskD0D0barCorrelationMCRec { + + double maxEtaCut = 5., PtThresholdForMaxEtaCut = 10.; //for hDDbarVsEtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 + + HistogramRegistry registry{ + "registry", + //NOTE: use hmassD0MCRec for normalisation, and hmass2DCorrelationPairsMCRec for 2D-sideband-subtraction purposes + {{"hmassD0MCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, + {"hmassD0barMCRec", "D0,D0bar candidates - MC reco;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, + {"hmass2DCorrelationPairsMCRec", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, + {"hptcandMCRec", "D0,D0bar candidates - MC reco;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong0MCRec", "D0,D0bar candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong1MCRec", "D0,D0bar candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hEtaMCRec", "D0,D0bar candidates - MC reco;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhiMCRec", "D0,D0bar candidates - MC reco;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hYMCRec", "D0,D0bar candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDeltaEtaPtIntMCRec", "D0,D0bar candidates - MC reco;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhiPtIntMCRec", "D0,D0bar candidates - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2DPtIntMCRec", "D0,D0bar candidates - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEtaVsPtMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhiVsPtMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPtDDbarMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPtMaxMinMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, + {"hDDbarVsEtaCutMCRec", "D0,D0bar pairs vs #eta cut - MC reco;#eta_{max};entries", {HistType::kTH2F, {{(int)(10 * maxEtaCut), 0., maxEtaCut}, {(int)(2 * PtThresholdForMaxEtaCut), 0., PtThresholdForMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and PtThresholdForMaxEtaCut instead + + Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) + { + //MC reco level + for (auto& candidate1 : candidates) { + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + continue; + if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { + //fill invariant mass plots and generic info from all D0/D0bar candidates + if (candidate1.isSelD0() >= d_selectionFlagD0 && candidate1.flagMCMatchRec() == 1 << D0ToPiK) { //only reco and matched as D0 + registry.fill(HIST("hmassD0MCRec"), InvMassD0(candidate1)); + } + if (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == -1 << D0ToPiK) { //only reco and matched as D0bar + registry.fill(HIST("hmassD0barMCRec"), InvMassD0bar(candidate1)); + } + registry.fill(HIST("hptcandMCRec"), candidate1.pt()); + registry.fill(HIST("hptprong0MCRec"), candidate1.ptProng0()); + registry.fill(HIST("hptprong1MCRec"), candidate1.ptProng1()); + registry.fill(HIST("hEtaMCRec"), candidate1.eta()); + registry.fill(HIST("hPhiMCRec"), candidate1.phi()); + registry.fill(HIST("hYMCRec"), YD0(candidate1)); + + //D-Dbar correlation dedicated section + //if the candidate is a D0, search for D0bar and evaluate correlations + if (candidate1.isSelD0() >= d_selectionFlagD0 && candidate1.flagMCMatchRec() == 1 << D0ToPiK) { //selected as D0 (particle) && matched to D0 (particle) + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (candidate2.isSelD0bar() >= d_selectionFlagD0bar && candidate2.flagMCMatchRec() == -1 << D0ToPiK) { //selected as D0bar (antiparticle) && matched to D0bar (antiparticle) + if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + continue; + double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); + registry.fill(HIST("hmass2DCorrelationPairsMCRec"), InvMassD0(candidate1), InvMassD0bar(candidate2)); + registry.fill(HIST("hDeltaEtaPtIntMCRec"), eta2 - eta1); + registry.fill(HIST("hDeltaPhiPtIntMCRec"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2DPtIntMCRec"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEtaVsPtMCRec"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhiVsPtMCRec"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPtDDbarMCRec"), pt2 - pt1); + registry.fill(HIST("hDeltaPtMaxMinMCRec"), std::max(pt2, pt1) - std::min(pt2, pt1)); + double etaCut = 0.; + double ptCut = 0.; + do { //fill pairs vs etaCut plot + ptCut = 0.; + etaCut += 0.1; + do { //fill pairs vs etaCut plot + if (std::abs(candidate1.eta()) < etaCut && std::abs(candidate2.eta()) < etaCut && candidate1.pt() > ptCut && candidate2.pt() > ptCut) + registry.fill(HIST("hDDbarVsEtaCutMCRec"), etaCut - 0.01, ptCut + 0.01); + ptCut += 0.5; + } while (ptCut < PtThresholdForMaxEtaCut - 0.05); + } while (etaCut < maxEtaCut - 0.05); + } //end inner if (MC match) + + } // end inner loop (Dbars) + } + } //end outer if (MC match) + } //end outer loop + } +}; + +/// D0 analysis task - for MC gen-level analysis (no filter/selection, only true signal) +struct TaskD0D0barCorrelationMCGen { + + double maxEtaCut = 5., PtThresholdForMaxEtaCut = 10.; //for hDDbarVsEtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 + + HistogramRegistry registry{ + "registry", + {{"hMCEvtCount", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hptcandMCGen", "D0,D0bar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hcountD0triggersMCGen", "D0 trigger particles - MC gen;;N of trigger D0", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hEtaMCGen", "D0,D0bar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhiMCGen", "D0,D0bar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hYMCGen", "D0,D0bar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDeltaEtaPtIntMCGen", "D0,D0bar particles - MC gen;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhiPtIntMCGen", "D0,D0bar particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2DPtIntMCGen", "D0,D0bar particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEtaVsPtMCGen", "D0,D0bar candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhiVsPtMCGen", "D0,D0bar candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPtDDbarMCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPtMaxMinMCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, + {"hDDbarVsEtaCutMCGen", "D0,D0bar pairs vs #eta cut - MC gen;#eta_{max};entries", {HistType::kTH2F, {{(int)(10 * maxEtaCut), 0., maxEtaCut}, {(int)(2 * PtThresholdForMaxEtaCut), 0., PtThresholdForMaxEtaCut}}}}, //don't modify the binning from here: act on maxEtaCut and PtThresholdForMaxEtaCut instead + {"hcountD0D0barPerEvent", "D0,D0bar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 10.}}}}}}; + + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + void process(aod::McCollision const& mccollision, soa::Join const& particlesMC) + { + int counterD0D0bar = 0; + registry.fill(HIST("hMCEvtCount"), 0); + //MC gen level + for (auto& particle1 : particlesMC) { + if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) + continue; + //just checking if the particle is D0 or D0bar, for now + if (std::abs(particle1.pdgCode()) == 421) { + registry.fill(HIST("hptcandMCGen"), particle1.pt()); + registry.fill(HIST("hEtaMCGen"), particle1.eta()); + registry.fill(HIST("hPhiMCGen"), particle1.phi()); + registry.fill(HIST("hYMCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); + counterD0D0bar++; + + //D-Dbar correlation dedicated section + //if it's a D0 particle, search for D0bar and evaluate correlations + if (particle1.pdgCode() == 421) { //just checking the particle PDG, not the decay channel (differently from Reco: you have a BR factor btw such levels!) + registry.fill(HIST("hcountD0triggersMCGen"), 0); //to count trigger D0 (for normalisation) + for (auto& particle2 : particlesMC) { + if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) + continue; + if (particle2.pdgCode() == -421) { + double eta1 = particle1.eta(), eta2 = particle2.eta(), pt1 = particle1.pt(), pt2 = particle2.pt(), phi1 = particle1.phi(), phi2 = particle2.phi(); + registry.fill(HIST("hDeltaEtaPtIntMCGen"), eta2 - eta1); + registry.fill(HIST("hDeltaPhiPtIntMCGen"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2DPtIntMCGen"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEtaVsPtMCGen"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhiVsPtMCGen"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPtDDbarMCGen"), pt2 - pt1); + registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::max(pt2, pt1) - std::min(pt2, pt1)); + double etaCut = 0.; + double ptCut = 0.; + do { //fill pairs vs etaCut plot + ptCut = 0.; + etaCut += 0.1; + do { //fill pairs vs etaCut plot + if (std::abs(particle1.eta()) < etaCut && std::abs(particle2.eta()) < etaCut && particle1.pt() > ptCut && particle2.pt() > ptCut) + registry.fill(HIST("hDDbarVsEtaCutMCGen"), etaCut - 0.01, ptCut + 0.01); + ptCut += 0.5; + } while (ptCut < PtThresholdForMaxEtaCut - 0.05); + } while (etaCut < maxEtaCut - 0.05); + } // end D0bar check + } //end inner loop + } //end D0 check + } //end outer if (MC check D0/D0bar) + + } //end outer loop + registry.fill(HIST("hcountD0D0barPerEvent"), counterD0D0bar); + } +}; + +/// D0 analysis task - LIKE SIGN - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) +struct TaskD0D0barCorrelationLS { + + HistogramRegistry registry{ + "registry", + //NOTE: use hmassD0 for normalisation, and hmass2DCorrelationPairs for 2D-sideband-subtraction purposes + {{"hmass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hmassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hmassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hmass2DCorrelationPairs", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, + {"hptcand", "D0,D0bar candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong0", "D0,D0bar candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong1", "D0,D0bar candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hselectionstatus", "D0,D0bar candidates;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, + {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhi", "D0,D0bar candidates;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hY", "D0,D0bar candidates;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDeltaEtaPtInt", "D0,D0bar candidates;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhiPtInt", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2DPtInt", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEtaVsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhiVsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPtDDbar", "D0,D0bar candidates;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPtMaxMin", "D0,D0bar candidates;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}}}; + + Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) + { + for (auto& candidate1 : candidates) { + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + continue; + //fill invariant mass plots and generic info from all D0/D0bar candidates + if (candidate1.isSelD0() >= d_selectionFlagD0) { + registry.fill(HIST("hmass"), InvMassD0(candidate1)); + registry.fill(HIST("hmassD0"), InvMassD0(candidate1)); + } + if (candidate1.isSelD0bar() >= d_selectionFlagD0bar) { + registry.fill(HIST("hmass"), InvMassD0bar(candidate1)); + registry.fill(HIST("hmassD0bar"), InvMassD0bar(candidate1)); + } + registry.fill(HIST("hptcand"), candidate1.pt()); + registry.fill(HIST("hptprong0"), candidate1.ptProng0()); + registry.fill(HIST("hptprong1"), candidate1.ptProng1()); + registry.fill(HIST("hEta"), candidate1.eta()); + registry.fill(HIST("hPhi"), candidate1.phi()); + registry.fill(HIST("hY"), YD0(candidate1)); + registry.fill(HIST("hselectionstatus"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); + + double ptParticle1 = candidate1.pt(); //trigger particle is the largest-pT one + + //D-Dbar correlation dedicated section + //For like-sign, first loop on both D0 and D0bars. First candidate is for sure a D0 and D0bars (checked before, so don't re-check anything on it) + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { + continue; + } + //for the associated, has to have smaller pT, and pass D0sel if trigger passes D0sel, or D0barsel if trigger passes D0barsel + if (candidate2.pt() < ptParticle1 && ((candidate1.isSelD0() >= d_selectionFlagD0 && candidate2.isSelD0() >= d_selectionFlagD0) || (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate2.isSelD0bar() >= d_selectionFlagD0bar))) { + if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + continue; + //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) + if (candidate1.mRowIndex == candidate2.mRowIndex) + continue; + double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); + registry.fill(HIST("hmass2DCorrelationPairs"), InvMassD0(candidate1), InvMassD0bar(candidate2)); + registry.fill(HIST("hDeltaEtaPtInt"), eta2 - eta1); + registry.fill(HIST("hDeltaPhiPtInt"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2DPtInt"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEtaVsPt"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhiVsPt"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPtDDbar"), pt2 - pt1); + registry.fill(HIST("hDeltaPtMaxMin"), std::max(pt2, pt1) - std::min(pt2, pt1)); + } + //note: candidates selected as both D0 and D0bar are used, and considered in both situation (but not auto-correlated): reflections could play a relevant role. + //another, more restrictive, option, could be to consider only candidates selected with a single option (D0 xor D0bar) + + } // end inner loop (Dbars) + + } //end outer loop + } +}; + +/// D0 analysis task - LIKE SIGN - for MC reco analysis (data-like but matching to true DO and D0bar) +struct TaskD0D0barCorrelationMCRecLS { + + HistogramRegistry registry{ + "registry", + //NOTE: use hmassD0MCRec for normalisation, and hmass2DCorrelationPairsMCRec for 2D-sideband-subtraction purposes + {{"hmassD0MCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, + {"hmassD0barMCRec", "D0,D0bar candidates - MC reco;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, + {"hmass2DCorrelationPairsMCRec", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, + {"hptcandMCRec", "D0,D0bar candidates - MC reco;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong0MCRec", "D0,D0bar candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hptprong1MCRec", "D0,D0bar candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hEtaMCRec", "D0,D0bar candidates - MC reco;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhiMCRec", "D0,D0bar candidates - MC reco;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hYMCRec", "D0,D0bar candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDeltaEtaPtIntMCRec", "D0,D0bar candidates - MC reco;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhiPtIntMCRec", "D0,D0bar candidates - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2DPtIntMCRec", "D0,D0bar candidates - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEtaVsPtMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhiVsPtMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPtDDbarMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPtMaxMinMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}}}; + + Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) + { + //MC reco level + for (auto& candidate1 : candidates) { + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + continue; + if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { + //fill invariant mass plots and generic info from all D0/D0bar candidates + if (candidate1.isSelD0() >= d_selectionFlagD0 && candidate1.flagMCMatchRec() == D0ToPiK) { //only reco and matched as D0 + registry.fill(HIST("hmassD0MCRec"), InvMassD0(candidate1)); + } + if (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == D0ToPiK) { //only reco and matched as D0bar + registry.fill(HIST("hmassD0barMCRec"), InvMassD0bar(candidate1)); + } + registry.fill(HIST("hptcandMCRec"), candidate1.pt()); + registry.fill(HIST("hptprong0MCRec"), candidate1.ptProng0()); + registry.fill(HIST("hptprong1MCRec"), candidate1.ptProng1()); + registry.fill(HIST("hEtaMCRec"), candidate1.eta()); + registry.fill(HIST("hPhiMCRec"), candidate1.phi()); + registry.fill(HIST("hYMCRec"), YD0(candidate1)); + + double ptParticle1 = candidate1.pt(); //trigger particle is the largest pT one + + //D-Dbar correlation dedicated section + //For like-sign, first loop on both D0 and D0bars. First candidate is for sure a D0 and D0bars (looping on filtered) and was already matched, so don't re-check anything on it) + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { + continue; + } + bool conditionLSForD0 = (candidate1.isSelD0() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == 1 << D0ToPiK) && (candidate2.isSelD0() >= d_selectionFlagD0bar && candidate2.flagMCMatchRec() == 1 << D0ToPiK); + bool conditionLSForD0bar = (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == -1 << D0ToPiK) && (candidate2.isSelD0bar() >= d_selectionFlagD0bar && candidate2.flagMCMatchRec() == -1 << D0ToPiK); + if (candidate2.pt() < ptParticle1 && (conditionLSForD0 || conditionLSForD0bar)) { //LS pair (of D0 or of D0bar) + pt2= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + continue; + //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) + if (candidate1.mRowIndex == candidate2.mRowIndex) + continue; + double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); + registry.fill(HIST("hmass2DCorrelationPairsMCRec"), InvMassD0(candidate1), InvMassD0bar(candidate2)); + registry.fill(HIST("hDeltaEtaPtIntMCRec"), eta2 - eta1); + registry.fill(HIST("hDeltaPhiPtIntMCRec"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2DPtIntMCRec"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEtaVsPtMCRec"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhiVsPtMCRec"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPtDDbarMCRec"), pt2 - pt1); + registry.fill(HIST("hDeltaPtMaxMinMCRec"), std::max(pt2, pt1) - std::min(pt2, pt1)); + } //end inner if (MC match) + + } // end inner loop (Dbars) + } //end outer if (MC match) + } //end outer loop + } +}; + +/// D0 analysis task - for MC gen-level analysis, like sign particles +struct TaskD0D0barCorrelationMCGenLS { + + HistogramRegistry registry{ + "registry", + {{"hMCEvtCount", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hptcandMCGen", "D0,D0bar LS particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hcountD0triggersMCGen", "D0,D0bar LS trigger particles (to be divided by two) - MC gen;;N of triggers", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hEtaMCGen", "D0,D0bar LS particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhiMCGen", "D0,D0bar LS particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hYMCGen", "D0,D0bar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDeltaEtaPtIntMCGen", "D0,D0bar LS particles - MC gen;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhiPtIntMCGen", "D0,D0bar LS particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2DPtIntMCGen", "D0,D0bar LS particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEtaVsPtMCGen", "D0,D0bar LS LS candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhiVsPtMCGen", "D0,D0bar LS candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPtDDbarMCGen", "D0,D0bar LS particles - MC gen;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPtMaxMinMCGen", "D0,D0bar LS particles - MC gen;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, + {"hcountD0D0barPerEvent", "D0,D0bar LS particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 20.}}}}}}; + + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + void process(aod::McCollision const& mccollision, soa::Join const& particlesMC) + { + int counterD0D0bar = 0; + registry.fill(HIST("hMCEvtCount"), 0); + //MC gen level + for (auto& particle1 : particlesMC) { + if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) + continue; + + double ptParticle1 = particle1.pt(); //trigger particle is the largest pT one + + //Check whether particle is D0 or D0bar (and not the decay chain) + if (std::abs(particle1.pdgCode()) == 421) { + registry.fill(HIST("hptcandMCGen"), particle1.pt()); + registry.fill(HIST("hEtaMCGen"), particle1.eta()); + registry.fill(HIST("hPhiMCGen"), particle1.phi()); + registry.fill(HIST("hYMCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); + counterD0D0bar++; + //D-Dbar correlation dedicated section + //if it's D0, search for D0bar and evaluate correlations. + registry.fill(HIST("hcountD0triggersMCGen"), 0); //to count trigger D0 (normalisation) + for (auto& particle2 : particlesMC) { + if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) + continue; + if (particle2.pt() < ptParticle1 && particle2.pdgCode() == particle1.pdgCode()) { //like-sign condition (both 421 or both -421) and pT_Trig>pT_assoc + //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) + if (particle1.mRowIndex == particle2.mRowIndex) + continue; + double eta1 = particle1.eta(), eta2 = particle2.eta(), pt1 = particle1.pt(), pt2 = particle2.pt(), phi1 = particle1.phi(), phi2 = particle2.phi(); + registry.fill(HIST("hDeltaEtaPtIntMCGen"), eta2 - eta1); + registry.fill(HIST("hDeltaPhiPtIntMCGen"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2DPtIntMCGen"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEtaVsPtMCGen"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhiVsPtMCGen"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPtDDbarMCGen"), pt2 - pt1); + registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::max(pt2, pt1) - std::min(pt2, pt1)); + } + } // end inner loop (Dbars) + } //end outer if (MC check D0) + } //end outer loop + registry.fill(HIST("hcountD0D0barPerEvent"), counterD0D0bar); + } +}; + +/// c-cbar correlation task analysis task - for MC gen-level analysis +struct TaskCCbarCorrelationMCGen { + + HistogramRegistry registry{ + "registry", + {{"hMCEvtCount", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hptcandMCGen", "c,cbar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hcountD0triggersMCGen", "c trigger particles - MC gen;;N of trigger c", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hEtaMCGen", "c,cbar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhiMCGen", "c,cbar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hDeltaEtaPtIntMCGen", "c,cbar particles - MC gen;#it{#eta}^{cbar}-#it{#eta}^{c};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhiPtIntMCGen", "c,cbar particles - MC gen;#it{#varphi}^{cbar}-#it{#varphi}^{c};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2DPtIntMCGen", "c,cbar particles - MC gen;#it{#varphi}^{cbar}-#it{#varphi}^{c};#it{#eta}^{cbar}-#it{#eta}^{c};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaEtaVsPtMCGen", "c,cbar candidates - MC gen;#it{p}_{T}^{c};#it{p}_{T}^{c}bar};#it{#eta}^{D0bar}-#it{#eta}^{c};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {200, -10., 10.}}}}, + {"hDeltaPhiVsPtMCGen", "c,cbar candidates - MC gen;#it{p}_{T}^{c};#it{p}_{T}^{cbar};#it{#varphi}^{D0bar}-#it{#varphi}^{c};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPtDDbarMCGen", "c,cbar particles - MC gen;#it{p}_{T}^{cbar}-#it{p}_{T}^{c};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPtMaxMinMCGen", "c,cbar particles - MC gen;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, + {"hcountCCbarPerEvent", "c,cbar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 20.}}}}, + {"hcountCCbarPerEventPreEtaCut", "c,cbar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 20.}}}}}}; + + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + void process(aod::McCollision const& mccollision, soa::Join const& particlesMC) + { + registry.fill(HIST("hMCEvtCount"), 0); + int counterccbar = 0, counterccbarPreEtasel = 0; + + //loop over particles at MC gen level + for (auto& particle1 : particlesMC) { + if (std::abs(particle1.pdgCode()) == 4) { //c or cbar quark found + int partMothPDG = particlesMC.iteratorAt(particle1.mother0()).pdgCode(); + if (std::abs(partMothPDG) != 4) + counterccbarPreEtasel++; //count c or cbar when it doesn't come from itself via fragmenatation (c->c+X) + if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) + continue; + registry.fill(HIST("hptcandMCGen"), particle1.pt()); + registry.fill(HIST("hEtaMCGen"), particle1.eta()); + registry.fill(HIST("hPhiMCGen"), particle1.phi()); + if (std::abs(partMothPDG) != 4) + counterccbar++; //count if c or cbar don't come from themselves during fragmenatation (after kinematic selection) + + //c-cbar correlation dedicated section + //if it's c, search for cbar and evaluate correlations. + if (particle1.pdgCode() == 4) { + //check whether mothers of quark c are still '4' particles - in that case the c quark comes from its own fragmentation, skip it + if (partMothPDG == 4) + continue; + registry.fill(HIST("hcountD0triggersMCGen"), 0); //to count trigger c quark (for normalisation) + + for (auto& particle2 : particlesMC) { + if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) + continue; + if (particle2.pdgCode() == -4) { + //check whether mothers of quark cbar are still '-4' particles - in that case the cbar quark comes from its own fragmentation, skip it + if (particlesMC.iteratorAt(particle2.mother0()).pdgCode() == -4) + continue; + double eta1 = particle1.eta(), eta2 = particle2.eta(), pt1 = particle1.pt(), pt2 = particle2.pt(), phi1 = particle1.phi(), phi2 = particle2.phi(); + registry.fill(HIST("hDeltaEtaPtIntMCGen"), eta2 - eta1); + registry.fill(HIST("hDeltaPhiPtIntMCGen"), getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hCorrel2DPtIntMCGen"), getDeltaPhi(phi2, phi1), eta2 - eta1); + registry.fill(HIST("hDeltaEtaVsPtMCGen"), pt1, pt2, eta2 - eta1); + registry.fill(HIST("hDeltaPhiVsPtMCGen"), pt1, pt2, getDeltaPhi(phi2, phi1)); + registry.fill(HIST("hDeltaPtDDbarMCGen"), pt2 - pt1); + registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::max(particle2.pt(), particle1.pt()) - std::min(particle2.pt(), particle1.pt())); + } // end outer if (check cbar) + } // end inner loop + } //end outer if (check c) + } //end c/cbar if + } //end outer loop + registry.fill(HIST("hcountCCbarPerEvent"), counterccbar); + registry.fill(HIST("hcountCCbarPerEventPreEtaCut"), counterccbarPreEtasel); + } +}; + +/// checks phi resolution for standard definition and sec-vtx based definition +struct TaskD0D0barCorrelationCheckPhiResolution { + + HistogramRegistry registry{ + "registry", + {{"hmass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhiStdPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, 0., 2. * o2::constants::math::PI}, {50, 0., 50.}}}}, + {"hPhiByVtxPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, 0., 2. * o2::constants::math::PI}, {50, 0., 50.}}}}, + {"hPhiDifferenceTwoMethods", "D0,D0bar candidates;candidate #it{#Delta#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {50, 0., 50.}}}}, + {"hDifferenceGenPhiStdPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {50, 0., 50.}}}}, + {"hDifferenceGenPhiByVtxPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {50, 0., 50.}}}}, + {"hDeltaPhiPtIntStdPhi", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPhiPtIntByVtxPhi", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPhiVsPtStdPhi", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPhiVsPtByVtxPhi", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}}}; + + Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::McParticles const& particlesMC, aod::BigTracksMC const& tracksMC) + { + for (auto& candidate1 : candidates) { + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + continue; + registry.fill(HIST("hmass"), InvMassD0(candidate1)); + registry.fill(HIST("hEta"), candidate1.eta()); + + //D-Dbar correlation dedicated section + //if it's a candidate D0, search for D0bar and evaluate correlations + if (candidate1.isSelD0() >= d_selectionFlagD0) { + double xPrimaryVertex = candidate1.index0_as().collision().posX(), yPrimaryVertex = candidate1.index0_as().collision().posY(); + double pt1 = candidate1.pt(), phi1Std = candidate1.phi(); + double phi1ByVtx = evaluatePhiByVertex(xPrimaryVertex, candidate1.xSecondaryVertex(), yPrimaryVertex, candidate1.ySecondaryVertex()); + registry.fill(HIST("hPhiStdPhi"), phi1Std, pt1); + registry.fill(HIST("hPhiByVtxPhi"), phi1ByVtx, pt1); //trick to have correct Phi range + registry.fill(HIST("hPhiDifferenceTwoMethods"), getDeltaPhi(phi1ByVtx, phi1Std), pt1); + + //get corresponding gen-level D0, if exists, and evaluate gen-rec phi-difference with two approaches + if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { //ok to keep both D0 and D0bar + int indexGen = RecoDecay::getMother(particlesMC, candidate1.index0_as().label(), 421, true); //MC-gen corresponding index for MC-reco candidate + if (indexGen > 0) { + double phi1Gen = particlesMC.iteratorAt(indexGen).phi(); + registry.fill(HIST("hDifferenceGenPhiStdPhi"), getDeltaPhi(phi1Std, phi1Gen), pt1); + registry.fill(HIST("hDifferenceGenPhiByVtxPhi"), getDeltaPhi(phi1ByVtx, phi1Gen), pt1); + } + } + + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (candidate2.isSelD0bar() >= d_selectionFlagD0bar) { //accept only D0bar candidates + if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + continue; + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + continue; + //Excluding self-correlations (could happen in case of reflections) + if (candidate1.mRowIndex == candidate2.mRowIndex) + continue; + double pt2 = candidate2.pt(), phi2Std = candidate2.phi(); + double phi2ByVtx = evaluatePhiByVertex(xPrimaryVertex, candidate2.xSecondaryVertex(), yPrimaryVertex, candidate2.ySecondaryVertex()); + registry.fill(HIST("hDeltaPhiPtIntStdPhi"), getDeltaPhi(phi2Std, phi1Std)); + registry.fill(HIST("hDeltaPhiPtIntByVtxPhi"), getDeltaPhi(phi2ByVtx, phi1ByVtx)); + registry.fill(HIST("hDeltaPhiVsPtStdPhi"), pt1, pt2, getDeltaPhi(phi2Std, phi1Std)); + registry.fill(HIST("hDeltaPhiVsPtByVtxPhi"), pt1, pt2, getDeltaPhi(phi2ByVtx, phi1ByVtx)); + } + } // end inner loop (Dbars) + } + } //end outer loop + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask("add-collision-id"), + adaptAnalysisTask("hf-task-d0d0bar-correlation"), + adaptAnalysisTask("hf-task-d0d0bar-correlation-ls")}; + //MC-based tasks + const bool doMC = cfgc.options().get("doMC"); + if (doMC) { + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-correlation-mc-rec")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-correlation-mc-gen")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-correlation-mc-rec-ls")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-correlation-mc-gen-ls")); + workflow.push_back(adaptAnalysisTask("hf-task-ccbar-correlation-mc-gen")); + workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-correlation-crosscheck-phi")); + } + return workflow; +} From 10bd1e0de39d98eea99f3e47df796647e4c4358f Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Tue, 23 Feb 2021 19:17:20 +0100 Subject: [PATCH 05/24] Updated tasks according to Vit's comments --- .../Tasks/PWGHF/taskD0D0barCorrelation.cxx | 560 ++++++++++-------- 1 file changed, 303 insertions(+), 257 deletions(-) diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index 84fff5dd1910a..5d06fcee32da2 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -60,46 +60,43 @@ void customize(std::vector& workflowOptions) #include "Framework/runDataProcessing.h" +/// +/// Returns deltaPhi value in range [-pi/2., 3.*pi/2], typically used for correlation studies +/// double getDeltaPhi(double phiD, double phiDbar) { - double dPhi = phiDbar - phiD; - - if (dPhi < -o2::constants::math::PI / 2.) - dPhi = dPhi + 2. * o2::constants::math::PI; - if (dPhi > 3. * o2::constants::math::PI / 2.) - dPhi = dPhi - 2. * o2::constants::math::PI; - - return dPhi; + return RecoDecay::constrainAngle(phiDbar - phiD, -o2::constants::math::PI / 2.); } +/// +/// Returns phi of candidate/particle evaluated from x and y components of segment connecting primary and secondary vertices +/// double evaluatePhiByVertex(double xVertex1, double xVertex2, double yVertex1, double yVertex2) { - double phi = std::atan2((yVertex2 - yVertex1), (xVertex2 - xVertex1)); - - if (phi < 0.) - phi = phi + 2. * o2::constants::math::PI; - if (phi > 2. * o2::constants::math::PI) - phi = phi - 2. * o2::constants::math::PI; - - return phi; + return RecoDecay::Phi(xVertex2 - xVertex1, yVertex2 - yVertex1); } +/// definition of variables for D0D0bar pairs vs eta acceptance studies (hDDbarVsEtaCut, in data-like, MC-reco and MC-kine tasks) +const double maxEtaCut = 5.; +const double PtThresholdForMaxEtaCut = 10.; +const double incrementEtaCut = 0.1; +const double incrementPtThreshold = 0.5; +const double epsilon = 10E-5; + /// D0 analysis task - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) struct TaskD0D0barCorrelation { - double maxEtaCut = 5., PtThresholdForMaxEtaCut = 10.; //for hDDbarVsEtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 - HistogramRegistry registry{ "registry", - //NOTE: use hmassD0 for normalisation, and hmass2DCorrelationPairs for 2D-sideband-subtraction purposes - {{"hmass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, - {"hmassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, - {"hmassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, - {"hmass2DCorrelationPairs", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, - {"hptcand", "D0,D0bar candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong0", "D0,D0bar candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong1", "D0,D0bar candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hselectionstatus", "D0,D0bar candidates;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, + //NOTE: use hMassD0 for normalisation, and hMass2DCorrelationPairs for 2D-sideband-subtraction purposes + {{"hMass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hMassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hMassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hMass2DCorrelationPairs", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, + {"hPtCand", "D0,D0bar candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hPtProng0", "D0,D0bar candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hPtProng1", "D0,D0bar candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hSelectionStatus", "D0,D0bar candidates;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hPhi", "D0,D0bar candidates;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, {"hY", "D0,D0bar candidates;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, @@ -110,79 +107,86 @@ struct TaskD0D0barCorrelation { {"hDeltaPhiVsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, {"hDeltaPtDDbar", "D0,D0bar candidates;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, {"hDeltaPtMaxMin", "D0,D0bar candidates;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, - {"hDDbarVsEtaCut", "D0,D0bar pairs vs #eta cut;#eta_{max};entries", {HistType::kTH2F, {{(int)(10 * maxEtaCut), 0., maxEtaCut}, {(int)(2 * PtThresholdForMaxEtaCut), 0., PtThresholdForMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and PtThresholdForMaxEtaCut instead + {"hDDbarVsEtaCut", "D0,D0bar pairs vs #eta cut;#eta_{max};entries", {HistType::kTH2F, {{(int)(maxEtaCut / incrementEtaCut), 0., maxEtaCut}, {(int)(PtThresholdForMaxEtaCut / incrementPtThreshold), 0., PtThresholdForMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and PtThresholdForMaxEtaCut instead - Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable dSelectionFlagD0{"dSelectionFlagD0", 1, "Selection Flag for D0"}; + Configurable dSelectionFlagD0bar{"dSelectionFlagD0bar", 1, "Selection Flag for D0bar"}; Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; - Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); - void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) + void process(aod::Collision const& collision, soa::Filtered const& candidates) { for (auto& candidate1 : candidates) { - if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { continue; + } //check decay channel flag for candidate1 if (!(candidate1.hfflag() & 1 << D0ToPiK)) { continue; } //fill invariant mass plots and generic info from all D0/D0bar candidates - if (candidate1.isSelD0() >= d_selectionFlagD0) { - registry.fill(HIST("hmass"), InvMassD0(candidate1)); - registry.fill(HIST("hmassD0"), InvMassD0(candidate1)); + if (candidate1.isSelD0() >= dSelectionFlagD0) { + registry.fill(HIST("hMass"), InvMassD0(candidate1)); + registry.fill(HIST("hMassD0"), InvMassD0(candidate1)); } - if (candidate1.isSelD0bar() >= d_selectionFlagD0bar) { - registry.fill(HIST("hmass"), InvMassD0bar(candidate1)); - registry.fill(HIST("hmassD0bar"), InvMassD0bar(candidate1)); + if (candidate1.isSelD0bar() >= dSelectionFlagD0bar) { + registry.fill(HIST("hMass"), InvMassD0bar(candidate1)); + registry.fill(HIST("hMassD0bar"), InvMassD0bar(candidate1)); } - registry.fill(HIST("hptcand"), candidate1.pt()); - registry.fill(HIST("hptprong0"), candidate1.ptProng0()); - registry.fill(HIST("hptprong1"), candidate1.ptProng1()); + registry.fill(HIST("hPtCand"), candidate1.pt()); + registry.fill(HIST("hPtProng0"), candidate1.ptProng0()); + registry.fill(HIST("hPtProng1"), candidate1.ptProng1()); registry.fill(HIST("hEta"), candidate1.eta()); registry.fill(HIST("hPhi"), candidate1.phi()); registry.fill(HIST("hY"), YD0(candidate1)); - registry.fill(HIST("hselectionstatus"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); + registry.fill(HIST("hSelectionStatus"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); //D-Dbar correlation dedicated section //if the candidate is a D0, search for D0bar and evaluate correlations - if (candidate1.isSelD0() >= d_selectionFlagD0) { + if (candidate1.isSelD0() >= dSelectionFlagD0) { for (auto& candidate2 : candidates) { //check decay channel flag for candidate2 if (!(candidate1.hfflag() & 1 << D0ToPiK)) { continue; } - if (candidate2.isSelD0bar() >= d_selectionFlagD0bar) { - if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + if (candidate2.isSelD0bar() >= dSelectionFlagD0bar) { + if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { continue; + } //Excluding trigger self-correlations (possible in case of both mass hypotheses accepted) - if (candidate1.mRowIndex == candidate2.mRowIndex) + if (candidate1.mRowIndex == candidate2.mRowIndex) { continue; + } double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); - registry.fill(HIST("hmass2DCorrelationPairs"), InvMassD0(candidate1), InvMassD0bar(candidate2)); - registry.fill(HIST("hDeltaEtaPtInt"), eta2 - eta1); - registry.fill(HIST("hDeltaPhiPtInt"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2DPtInt"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEtaVsPt"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhiVsPt"), pt1, pt2, getDeltaPhi(phi2, phi1)); + double deltaEta = eta2 - eta1; + double deltaPhi = getDeltaPhi(phi2, phi1); + registry.fill(HIST("hMass2DCorrelationPairs"), InvMassD0(candidate1), InvMassD0bar(candidate2)); + registry.fill(HIST("hDeltaEtaPtInt"), deltaEta); + registry.fill(HIST("hDeltaPhiPtInt"), deltaPhi); + registry.fill(HIST("hCorrel2DPtInt"), deltaPhi, deltaEta); + registry.fill(HIST("hDeltaEtaVsPt"), pt1, pt2, deltaEta); + registry.fill(HIST("hDeltaPhiVsPt"), pt1, pt2, deltaPhi); registry.fill(HIST("hDeltaPtDDbar"), pt2 - pt1); - registry.fill(HIST("hDeltaPtMaxMin"), std::max(pt2, pt1) - std::min(pt2, pt1)); + registry.fill(HIST("hDeltaPtMaxMin"), std::abs(pt2 - pt1)); double etaCut = 0.; double ptCut = 0.; do { //fill pairs vs etaCut plot ptCut = 0.; - etaCut += 0.1; + etaCut += incrementEtaCut; do { //fill pairs vs etaCut plot if (std::abs(candidate1.eta()) < etaCut && std::abs(candidate2.eta()) < etaCut && candidate1.pt() > ptCut && candidate2.pt() > ptCut) - registry.fill(HIST("hDDbarVsEtaCut"), etaCut - 0.01, ptCut + 0.01); - ptCut += 0.5; - } while (ptCut < PtThresholdForMaxEtaCut - 0.05); - } while (etaCut < maxEtaCut - 0.05); + registry.fill(HIST("hDDbarVsEtaCut"), etaCut - epsilon, ptCut + epsilon); + ptCut += incrementPtThreshold; + } while (ptCut < PtThresholdForMaxEtaCut - epsilon); + } while (etaCut < maxEtaCut - epsilon); } //note: candidates selected as both D0 and D0bar are used, and considered in both situation (but not auto-correlated): reflections could play a relevant role. //another, more restrictive, option, could be to consider only candidates selected with a single option (D0 xor D0bar) @@ -197,17 +201,15 @@ struct TaskD0D0barCorrelation { /// D0 analysis task - for MC reco-level analysis (candidates matched to true signal only) struct TaskD0D0barCorrelationMCRec { - double maxEtaCut = 5., PtThresholdForMaxEtaCut = 10.; //for hDDbarVsEtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 - HistogramRegistry registry{ "registry", - //NOTE: use hmassD0MCRec for normalisation, and hmass2DCorrelationPairsMCRec for 2D-sideband-subtraction purposes - {{"hmassD0MCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, - {"hmassD0barMCRec", "D0,D0bar candidates - MC reco;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, - {"hmass2DCorrelationPairsMCRec", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, - {"hptcandMCRec", "D0,D0bar candidates - MC reco;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong0MCRec", "D0,D0bar candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong1MCRec", "D0,D0bar candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + //NOTE: use hMassD0MCRec for normalisation, and hMass2DCorrelationPairsMCRec for 2D-sideband-subtraction purposes + {{"hMassD0MCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, + {"hMassD0barMCRec", "D0,D0bar candidates - MC reco;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, + {"hMass2DCorrelationPairsMCRec", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, + {"hPtCandMCRec", "D0,D0bar candidates - MC reco;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hPtProng0MCRec", "D0,D0bar candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hPtProng1MCRec", "D0,D0bar candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, {"hEtaMCRec", "D0,D0bar candidates - MC reco;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hPhiMCRec", "D0,D0bar candidates - MC reco;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, {"hYMCRec", "D0,D0bar candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, @@ -218,16 +220,16 @@ struct TaskD0D0barCorrelationMCRec { {"hDeltaPhiVsPtMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, {"hDeltaPtDDbarMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, {"hDeltaPtMaxMinMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, - {"hDDbarVsEtaCutMCRec", "D0,D0bar pairs vs #eta cut - MC reco;#eta_{max};entries", {HistType::kTH2F, {{(int)(10 * maxEtaCut), 0., maxEtaCut}, {(int)(2 * PtThresholdForMaxEtaCut), 0., PtThresholdForMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and PtThresholdForMaxEtaCut instead + {"hDDbarVsEtaCutMCRec", "D0,D0bar pairs vs #eta cut - MC reco;#eta_{max};entries", {HistType::kTH2F, {{(int)(maxEtaCut / incrementEtaCut), 0., maxEtaCut}, {(int)(PtThresholdForMaxEtaCut / incrementPtThreshold), 0., PtThresholdForMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and PtThresholdForMaxEtaCut instead - Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable dSelectionFlagD0{"dSelectionFlagD0", 1, "Selection Flag for D0"}; + Configurable dSelectionFlagD0bar{"dSelectionFlagD0bar", 1, "Selection Flag for D0bar"}; Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; - Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); - void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) + void process(aod::Collision const& collision, soa::Filtered const& candidates) { //MC reco level for (auto& candidate1 : candidates) { @@ -235,58 +237,64 @@ struct TaskD0D0barCorrelationMCRec { if (!(candidate1.hfflag() & 1 << D0ToPiK)) { continue; } - if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { continue; + } if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { //fill invariant mass plots and generic info from all D0/D0bar candidates - if (candidate1.isSelD0() >= d_selectionFlagD0 && candidate1.flagMCMatchRec() == 1 << D0ToPiK) { //only reco and matched as D0 - registry.fill(HIST("hmassD0MCRec"), InvMassD0(candidate1)); + if (candidate1.isSelD0() >= dSelectionFlagD0 && candidate1.flagMCMatchRec() == 1 << D0ToPiK) { //only reco and matched as D0 + registry.fill(HIST("hMassD0MCRec"), InvMassD0(candidate1)); } - if (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == -1 << D0ToPiK) { //only reco and matched as D0bar - registry.fill(HIST("hmassD0barMCRec"), InvMassD0bar(candidate1)); + if (candidate1.isSelD0bar() >= dSelectionFlagD0bar && candidate1.flagMCMatchRec() == -1 << D0ToPiK) { //only reco and matched as D0bar + registry.fill(HIST("hMassD0barMCRec"), InvMassD0bar(candidate1)); } - registry.fill(HIST("hptcandMCRec"), candidate1.pt()); - registry.fill(HIST("hptprong0MCRec"), candidate1.ptProng0()); - registry.fill(HIST("hptprong1MCRec"), candidate1.ptProng1()); + registry.fill(HIST("hPtCandMCRec"), candidate1.pt()); + registry.fill(HIST("hPtProng0MCRec"), candidate1.ptProng0()); + registry.fill(HIST("hPtProng1MCRec"), candidate1.ptProng1()); registry.fill(HIST("hEtaMCRec"), candidate1.eta()); registry.fill(HIST("hPhiMCRec"), candidate1.phi()); registry.fill(HIST("hYMCRec"), YD0(candidate1)); //D-Dbar correlation dedicated section //if the candidate is a D0, search for D0bar and evaluate correlations - if (candidate1.isSelD0() >= d_selectionFlagD0 && candidate1.flagMCMatchRec() == 1 << D0ToPiK) { //selected as D0 (particle) && matched to D0 (particle) + if (candidate1.isSelD0() >= dSelectionFlagD0 && candidate1.flagMCMatchRec() == 1 << D0ToPiK) { //selected as D0 (particle) && matched to D0 (particle) for (auto& candidate2 : candidates) { //check decay channel flag for candidate2 if (!(candidate2.hfflag() & 1 << D0ToPiK)) { continue; } - if (candidate2.isSelD0bar() >= d_selectionFlagD0bar && candidate2.flagMCMatchRec() == -1 << D0ToPiK) { //selected as D0bar (antiparticle) && matched to D0bar (antiparticle) - if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + if (candidate2.isSelD0bar() >= dSelectionFlagD0bar && candidate2.flagMCMatchRec() == -1 << D0ToPiK) { //selected as D0bar (antiparticle) && matched to D0bar (antiparticle) + if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { continue; + } double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); - registry.fill(HIST("hmass2DCorrelationPairsMCRec"), InvMassD0(candidate1), InvMassD0bar(candidate2)); - registry.fill(HIST("hDeltaEtaPtIntMCRec"), eta2 - eta1); - registry.fill(HIST("hDeltaPhiPtIntMCRec"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2DPtIntMCRec"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEtaVsPtMCRec"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhiVsPtMCRec"), pt1, pt2, getDeltaPhi(phi2, phi1)); + double deltaEta = eta2 - eta1; + double deltaPhi = getDeltaPhi(phi2, phi1); + registry.fill(HIST("hMass2DCorrelationPairsMCRec"), InvMassD0(candidate1), InvMassD0bar(candidate2)); + registry.fill(HIST("hDeltaEtaPtIntMCRec"), deltaEta); + registry.fill(HIST("hDeltaPhiPtIntMCRec"), deltaPhi); + registry.fill(HIST("hCorrel2DPtIntMCRec"), deltaPhi, deltaEta); + registry.fill(HIST("hDeltaEtaVsPtMCRec"), pt1, pt2, deltaEta); + registry.fill(HIST("hDeltaPhiVsPtMCRec"), pt1, pt2, deltaPhi); registry.fill(HIST("hDeltaPtDDbarMCRec"), pt2 - pt1); - registry.fill(HIST("hDeltaPtMaxMinMCRec"), std::max(pt2, pt1) - std::min(pt2, pt1)); + registry.fill(HIST("hDeltaPtMaxMinMCRec"), std::abs(pt2 - pt1)); double etaCut = 0.; double ptCut = 0.; do { //fill pairs vs etaCut plot ptCut = 0.; - etaCut += 0.1; + etaCut += incrementEtaCut; do { //fill pairs vs etaCut plot if (std::abs(candidate1.eta()) < etaCut && std::abs(candidate2.eta()) < etaCut && candidate1.pt() > ptCut && candidate2.pt() > ptCut) - registry.fill(HIST("hDDbarVsEtaCutMCRec"), etaCut - 0.01, ptCut + 0.01); - ptCut += 0.5; - } while (ptCut < PtThresholdForMaxEtaCut - 0.05); - } while (etaCut < maxEtaCut - 0.05); + registry.fill(HIST("hDDbarVsEtaCutMCRec"), etaCut - epsilon, ptCut + epsilon); + ptCut += incrementPtThreshold; + } while (ptCut < PtThresholdForMaxEtaCut - epsilon); + } while (etaCut < maxEtaCut - epsilon); } //end inner if (MC match) } // end inner loop (Dbars) @@ -299,12 +307,10 @@ struct TaskD0D0barCorrelationMCRec { /// D0 analysis task - for MC gen-level analysis (no filter/selection, only true signal) struct TaskD0D0barCorrelationMCGen { - double maxEtaCut = 5., PtThresholdForMaxEtaCut = 10.; //for hDDbarVsEtaCut, gives eta increment of 0.1 and pt thr increments of 0.5 - HistogramRegistry registry{ "registry", {{"hMCEvtCount", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, - {"hptcandMCGen", "D0,D0bar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hPtCandMCGen", "D0,D0bar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, {"hcountD0triggersMCGen", "D0 trigger particles - MC gen;;N of trigger D0", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, {"hEtaMCGen", "D0,D0bar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hPhiMCGen", "D0,D0bar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, @@ -316,7 +322,7 @@ struct TaskD0D0barCorrelationMCGen { {"hDeltaPhiVsPtMCGen", "D0,D0bar candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, {"hDeltaPtDDbarMCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, {"hDeltaPtMaxMinMCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, - {"hDDbarVsEtaCutMCGen", "D0,D0bar pairs vs #eta cut - MC gen;#eta_{max};entries", {HistType::kTH2F, {{(int)(10 * maxEtaCut), 0., maxEtaCut}, {(int)(2 * PtThresholdForMaxEtaCut), 0., PtThresholdForMaxEtaCut}}}}, //don't modify the binning from here: act on maxEtaCut and PtThresholdForMaxEtaCut instead + {"hDDbarVsEtaCutMCGen", "D0,D0bar pairs vs #eta cut - MC gen;#eta_{max};entries", {HistType::kTH2F, {{(int)(maxEtaCut / incrementEtaCut), 0., maxEtaCut}, {(int)(PtThresholdForMaxEtaCut / incrementPtThreshold), 0., PtThresholdForMaxEtaCut}}}}, //don't modify the binning from here: act on maxEtaCut and PtThresholdForMaxEtaCut instead {"hcountD0D0barPerEvent", "D0,D0bar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 10.}}}}}}; Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; @@ -328,13 +334,15 @@ struct TaskD0D0barCorrelationMCGen { registry.fill(HIST("hMCEvtCount"), 0); //MC gen level for (auto& particle1 : particlesMC) { - if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) + if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) { continue; + } //just checking if the particle is D0 or D0bar, for now if (std::abs(particle1.pdgCode()) == 421) { - registry.fill(HIST("hptcandMCGen"), particle1.pt()); + registry.fill(HIST("hPtCandMCGen"), particle1.pt()); registry.fill(HIST("hEtaMCGen"), particle1.eta()); registry.fill(HIST("hPhiMCGen"), particle1.phi()); registry.fill(HIST("hYMCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); @@ -345,30 +353,34 @@ struct TaskD0D0barCorrelationMCGen { if (particle1.pdgCode() == 421) { //just checking the particle PDG, not the decay channel (differently from Reco: you have a BR factor btw such levels!) registry.fill(HIST("hcountD0triggersMCGen"), 0); //to count trigger D0 (for normalisation) for (auto& particle2 : particlesMC) { - if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) + if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) { continue; + } if (particle2.pdgCode() == -421) { double eta1 = particle1.eta(), eta2 = particle2.eta(), pt1 = particle1.pt(), pt2 = particle2.pt(), phi1 = particle1.phi(), phi2 = particle2.phi(); - registry.fill(HIST("hDeltaEtaPtIntMCGen"), eta2 - eta1); - registry.fill(HIST("hDeltaPhiPtIntMCGen"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2DPtIntMCGen"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEtaVsPtMCGen"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhiVsPtMCGen"), pt1, pt2, getDeltaPhi(phi2, phi1)); + double deltaEta = eta2 - eta1; + double deltaPhi = getDeltaPhi(phi2, phi1); + registry.fill(HIST("hDeltaEtaPtIntMCGen"), deltaEta); + registry.fill(HIST("hDeltaPhiPtIntMCGen"), deltaPhi); + registry.fill(HIST("hCorrel2DPtIntMCGen"), deltaPhi, deltaEta); + registry.fill(HIST("hDeltaEtaVsPtMCGen"), pt1, pt2, deltaEta); + registry.fill(HIST("hDeltaPhiVsPtMCGen"), pt1, pt2, deltaPhi); registry.fill(HIST("hDeltaPtDDbarMCGen"), pt2 - pt1); - registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::max(pt2, pt1) - std::min(pt2, pt1)); + registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::abs(pt2 - pt1)); double etaCut = 0.; double ptCut = 0.; do { //fill pairs vs etaCut plot ptCut = 0.; - etaCut += 0.1; + etaCut += incrementEtaCut; do { //fill pairs vs etaCut plot if (std::abs(particle1.eta()) < etaCut && std::abs(particle2.eta()) < etaCut && particle1.pt() > ptCut && particle2.pt() > ptCut) - registry.fill(HIST("hDDbarVsEtaCutMCGen"), etaCut - 0.01, ptCut + 0.01); - ptCut += 0.5; - } while (ptCut < PtThresholdForMaxEtaCut - 0.05); - } while (etaCut < maxEtaCut - 0.05); + registry.fill(HIST("hDDbarVsEtaCutMCGen"), etaCut - epsilon, ptCut + epsilon); + ptCut += incrementPtThreshold; + } while (ptCut < PtThresholdForMaxEtaCut - epsilon); + } while (etaCut < maxEtaCut - epsilon); } // end D0bar check } //end inner loop } //end D0 check @@ -384,15 +396,15 @@ struct TaskD0D0barCorrelationLS { HistogramRegistry registry{ "registry", - //NOTE: use hmassD0 for normalisation, and hmass2DCorrelationPairs for 2D-sideband-subtraction purposes - {{"hmass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, - {"hmassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, - {"hmassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, - {"hmass2DCorrelationPairs", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, - {"hptcand", "D0,D0bar candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong0", "D0,D0bar candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong1", "D0,D0bar candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hselectionstatus", "D0,D0bar candidates;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, + //NOTE: use hMassD0 for normalisation, and hMass2DCorrelationPairs for 2D-sideband-subtraction purposes + {{"hMass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hMassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hMassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {"hMass2DCorrelationPairs", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, + {"hPtCand", "D0,D0bar candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hPtProng0", "D0,D0bar candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hPtProng1", "D0,D0bar candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hSelectionStatus", "D0,D0bar candidates;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hPhi", "D0,D0bar candidates;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, {"hY", "D0,D0bar candidates;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, @@ -404,40 +416,42 @@ struct TaskD0D0barCorrelationLS { {"hDeltaPtDDbar", "D0,D0bar candidates;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, {"hDeltaPtMaxMin", "D0,D0bar candidates;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}}}; - Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable dSelectionFlagD0{"dSelectionFlagD0", 1, "Selection Flag for D0"}; + Configurable dSelectionFlagD0bar{"dSelectionFlagD0bar", 1, "Selection Flag for D0bar"}; Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; - Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); - void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) + void process(aod::Collision const& collision, soa::Filtered const& candidates) { for (auto& candidate1 : candidates) { //check decay channel flag for candidate1 if (!(candidate1.hfflag() & 1 << D0ToPiK)) { continue; } - if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { continue; + } //fill invariant mass plots and generic info from all D0/D0bar candidates - if (candidate1.isSelD0() >= d_selectionFlagD0) { - registry.fill(HIST("hmass"), InvMassD0(candidate1)); - registry.fill(HIST("hmassD0"), InvMassD0(candidate1)); + if (candidate1.isSelD0() >= dSelectionFlagD0) { + registry.fill(HIST("hMass"), InvMassD0(candidate1)); + registry.fill(HIST("hMassD0"), InvMassD0(candidate1)); } - if (candidate1.isSelD0bar() >= d_selectionFlagD0bar) { - registry.fill(HIST("hmass"), InvMassD0bar(candidate1)); - registry.fill(HIST("hmassD0bar"), InvMassD0bar(candidate1)); + if (candidate1.isSelD0bar() >= dSelectionFlagD0bar) { + registry.fill(HIST("hMass"), InvMassD0bar(candidate1)); + registry.fill(HIST("hMassD0bar"), InvMassD0bar(candidate1)); } - registry.fill(HIST("hptcand"), candidate1.pt()); - registry.fill(HIST("hptprong0"), candidate1.ptProng0()); - registry.fill(HIST("hptprong1"), candidate1.ptProng1()); + registry.fill(HIST("hPtCand"), candidate1.pt()); + registry.fill(HIST("hPtProng0"), candidate1.ptProng0()); + registry.fill(HIST("hPtProng1"), candidate1.ptProng1()); registry.fill(HIST("hEta"), candidate1.eta()); registry.fill(HIST("hPhi"), candidate1.phi()); registry.fill(HIST("hY"), YD0(candidate1)); - registry.fill(HIST("hselectionstatus"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); + registry.fill(HIST("hSelectionStatus"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); double ptParticle1 = candidate1.pt(); //trigger particle is the largest-pT one @@ -449,23 +463,28 @@ struct TaskD0D0barCorrelationLS { continue; } //for the associated, has to have smaller pT, and pass D0sel if trigger passes D0sel, or D0barsel if trigger passes D0barsel - if (candidate2.pt() < ptParticle1 && ((candidate1.isSelD0() >= d_selectionFlagD0 && candidate2.isSelD0() >= d_selectionFlagD0) || (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate2.isSelD0bar() >= d_selectionFlagD0bar))) { - if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + if (candidate2.pt() < ptParticle1 && ((candidate1.isSelD0() >= dSelectionFlagD0 && candidate2.isSelD0() >= dSelectionFlagD0) || (candidate1.isSelD0bar() >= dSelectionFlagD0bar && candidate2.isSelD0bar() >= dSelectionFlagD0bar))) { + if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { continue; + } //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) - if (candidate1.mRowIndex == candidate2.mRowIndex) + if (candidate1.mRowIndex == candidate2.mRowIndex) { continue; + } double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); - registry.fill(HIST("hmass2DCorrelationPairs"), InvMassD0(candidate1), InvMassD0bar(candidate2)); - registry.fill(HIST("hDeltaEtaPtInt"), eta2 - eta1); - registry.fill(HIST("hDeltaPhiPtInt"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2DPtInt"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEtaVsPt"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhiVsPt"), pt1, pt2, getDeltaPhi(phi2, phi1)); + double deltaEta = eta2 - eta1; + double deltaPhi = getDeltaPhi(phi2, phi1); + registry.fill(HIST("hMass2DCorrelationPairs"), InvMassD0(candidate1), InvMassD0bar(candidate2)); + registry.fill(HIST("hDeltaEtaPtInt"), deltaEta); + registry.fill(HIST("hDeltaPhiPtInt"), deltaPhi); + registry.fill(HIST("hCorrel2DPtInt"), deltaPhi, deltaEta); + registry.fill(HIST("hDeltaEtaVsPt"), pt1, pt2, deltaEta); + registry.fill(HIST("hDeltaPhiVsPt"), pt1, pt2, deltaPhi); registry.fill(HIST("hDeltaPtDDbar"), pt2 - pt1); - registry.fill(HIST("hDeltaPtMaxMin"), std::max(pt2, pt1) - std::min(pt2, pt1)); + registry.fill(HIST("hDeltaPtMaxMin"), std::abs(pt2 - pt1)); } //note: candidates selected as both D0 and D0bar are used, and considered in both situation (but not auto-correlated): reflections could play a relevant role. //another, more restrictive, option, could be to consider only candidates selected with a single option (D0 xor D0bar) @@ -481,13 +500,13 @@ struct TaskD0D0barCorrelationMCRecLS { HistogramRegistry registry{ "registry", - //NOTE: use hmassD0MCRec for normalisation, and hmass2DCorrelationPairsMCRec for 2D-sideband-subtraction purposes - {{"hmassD0MCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, - {"hmassD0barMCRec", "D0,D0bar candidates - MC reco;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, - {"hmass2DCorrelationPairsMCRec", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, - {"hptcandMCRec", "D0,D0bar candidates - MC reco;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong0MCRec", "D0,D0bar candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, - {"hptprong1MCRec", "D0,D0bar candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + //NOTE: use hMassD0MCRec for normalisation, and hMass2DCorrelationPairsMCRec for 2D-sideband-subtraction purposes + {{"hMassD0MCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, + {"hMassD0barMCRec", "D0,D0bar candidates - MC reco;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}, + {"hMass2DCorrelationPairsMCRec", "D0,D0bar candidates 2D;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{200, 1., 3.}, {200, 1., 3.}}}}, + {"hPtCandMCRec", "D0,D0bar candidates - MC reco;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hPtprong0MCRec", "D0,D0bar candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hPtprong1MCRec", "D0,D0bar candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, {"hEtaMCRec", "D0,D0bar candidates - MC reco;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hPhiMCRec", "D0,D0bar candidates - MC reco;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, {"hYMCRec", "D0,D0bar candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, @@ -499,14 +518,14 @@ struct TaskD0D0barCorrelationMCRecLS { {"hDeltaPtDDbarMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, {"hDeltaPtMaxMinMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}}}; - Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable dSelectionFlagD0{"dSelectionFlagD0", 1, "Selection Flag for D0"}; + Configurable dSelectionFlagD0bar{"dSelectionFlagD0bar", 1, "Selection Flag for D0bar"}; Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; - Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); - void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::BigTracks const& tracks) + void process(aod::Collision const& collision, soa::Filtered const& candidates) { //MC reco level for (auto& candidate1 : candidates) { @@ -514,21 +533,23 @@ struct TaskD0D0barCorrelationMCRecLS { if (!(candidate1.hfflag() & 1 << D0ToPiK)) { continue; } - if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { continue; + } if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { //fill invariant mass plots and generic info from all D0/D0bar candidates - if (candidate1.isSelD0() >= d_selectionFlagD0 && candidate1.flagMCMatchRec() == D0ToPiK) { //only reco and matched as D0 - registry.fill(HIST("hmassD0MCRec"), InvMassD0(candidate1)); + if (candidate1.isSelD0() >= dSelectionFlagD0 && candidate1.flagMCMatchRec() == D0ToPiK) { //only reco and matched as D0 + registry.fill(HIST("hMassD0MCRec"), InvMassD0(candidate1)); } - if (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == D0ToPiK) { //only reco and matched as D0bar - registry.fill(HIST("hmassD0barMCRec"), InvMassD0bar(candidate1)); + if (candidate1.isSelD0bar() >= dSelectionFlagD0bar && candidate1.flagMCMatchRec() == D0ToPiK) { //only reco and matched as D0bar + registry.fill(HIST("hMassD0barMCRec"), InvMassD0bar(candidate1)); } - registry.fill(HIST("hptcandMCRec"), candidate1.pt()); - registry.fill(HIST("hptprong0MCRec"), candidate1.ptProng0()); - registry.fill(HIST("hptprong1MCRec"), candidate1.ptProng1()); + registry.fill(HIST("hPtCandMCRec"), candidate1.pt()); + registry.fill(HIST("hPtprong0MCRec"), candidate1.ptProng0()); + registry.fill(HIST("hPtprong1MCRec"), candidate1.ptProng1()); registry.fill(HIST("hEtaMCRec"), candidate1.eta()); registry.fill(HIST("hPhiMCRec"), candidate1.phi()); registry.fill(HIST("hYMCRec"), YD0(candidate1)); @@ -542,25 +563,30 @@ struct TaskD0D0barCorrelationMCRecLS { if (!(candidate2.hfflag() & 1 << D0ToPiK)) { continue; } - bool conditionLSForD0 = (candidate1.isSelD0() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == 1 << D0ToPiK) && (candidate2.isSelD0() >= d_selectionFlagD0bar && candidate2.flagMCMatchRec() == 1 << D0ToPiK); - bool conditionLSForD0bar = (candidate1.isSelD0bar() >= d_selectionFlagD0bar && candidate1.flagMCMatchRec() == -1 << D0ToPiK) && (candidate2.isSelD0bar() >= d_selectionFlagD0bar && candidate2.flagMCMatchRec() == -1 << D0ToPiK); + bool conditionLSForD0 = (candidate1.isSelD0() >= dSelectionFlagD0bar && candidate1.flagMCMatchRec() == 1 << D0ToPiK) && (candidate2.isSelD0() >= dSelectionFlagD0bar && candidate2.flagMCMatchRec() == 1 << D0ToPiK); + bool conditionLSForD0bar = (candidate1.isSelD0bar() >= dSelectionFlagD0bar && candidate1.flagMCMatchRec() == -1 << D0ToPiK) && (candidate2.isSelD0bar() >= dSelectionFlagD0bar && candidate2.flagMCMatchRec() == -1 << D0ToPiK); if (candidate2.pt() < ptParticle1 && (conditionLSForD0 || conditionLSForD0bar)) { //LS pair (of D0 or of D0bar) + pt2= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { continue; + } //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) - if (candidate1.mRowIndex == candidate2.mRowIndex) + if (candidate1.mRowIndex == candidate2.mRowIndex) { continue; + } double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); - registry.fill(HIST("hmass2DCorrelationPairsMCRec"), InvMassD0(candidate1), InvMassD0bar(candidate2)); - registry.fill(HIST("hDeltaEtaPtIntMCRec"), eta2 - eta1); - registry.fill(HIST("hDeltaPhiPtIntMCRec"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2DPtIntMCRec"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEtaVsPtMCRec"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhiVsPtMCRec"), pt1, pt2, getDeltaPhi(phi2, phi1)); + double deltaEta = eta2 - eta1; + double deltaPhi = getDeltaPhi(phi2, phi1); + registry.fill(HIST("hMass2DCorrelationPairsMCRec"), InvMassD0(candidate1), InvMassD0bar(candidate2)); + registry.fill(HIST("hDeltaEtaPtIntMCRec"), deltaEta); + registry.fill(HIST("hDeltaPhiPtIntMCRec"), deltaPhi); + registry.fill(HIST("hCorrel2DPtIntMCRec"), deltaPhi, deltaEta); + registry.fill(HIST("hDeltaEtaVsPtMCRec"), pt1, pt2, deltaEta); + registry.fill(HIST("hDeltaPhiVsPtMCRec"), pt1, pt2, deltaPhi); registry.fill(HIST("hDeltaPtDDbarMCRec"), pt2 - pt1); - registry.fill(HIST("hDeltaPtMaxMinMCRec"), std::max(pt2, pt1) - std::min(pt2, pt1)); + registry.fill(HIST("hDeltaPtMaxMinMCRec"), std::abs(pt2 - pt1)); } //end inner if (MC match) } // end inner loop (Dbars) @@ -575,7 +601,7 @@ struct TaskD0D0barCorrelationMCGenLS { HistogramRegistry registry{ "registry", {{"hMCEvtCount", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, - {"hptcandMCGen", "D0,D0bar LS particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hPtCandMCGen", "D0,D0bar LS particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, {"hcountD0triggersMCGen", "D0,D0bar LS trigger particles (to be divided by two) - MC gen;;N of triggers", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, {"hEtaMCGen", "D0,D0bar LS particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hPhiMCGen", "D0,D0bar LS particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, @@ -598,16 +624,18 @@ struct TaskD0D0barCorrelationMCGenLS { registry.fill(HIST("hMCEvtCount"), 0); //MC gen level for (auto& particle1 : particlesMC) { - if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) + if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) { continue; + } double ptParticle1 = particle1.pt(); //trigger particle is the largest pT one //Check whether particle is D0 or D0bar (and not the decay chain) if (std::abs(particle1.pdgCode()) == 421) { - registry.fill(HIST("hptcandMCGen"), particle1.pt()); + registry.fill(HIST("hPtCandMCGen"), particle1.pt()); registry.fill(HIST("hEtaMCGen"), particle1.eta()); registry.fill(HIST("hPhiMCGen"), particle1.phi()); registry.fill(HIST("hYMCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); @@ -616,22 +644,27 @@ struct TaskD0D0barCorrelationMCGenLS { //if it's D0, search for D0bar and evaluate correlations. registry.fill(HIST("hcountD0triggersMCGen"), 0); //to count trigger D0 (normalisation) for (auto& particle2 : particlesMC) { - if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) + if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) { continue; + } if (particle2.pt() < ptParticle1 && particle2.pdgCode() == particle1.pdgCode()) { //like-sign condition (both 421 or both -421) and pT_Trig>pT_assoc //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) - if (particle1.mRowIndex == particle2.mRowIndex) + if (particle1.mRowIndex == particle2.mRowIndex) { continue; + } double eta1 = particle1.eta(), eta2 = particle2.eta(), pt1 = particle1.pt(), pt2 = particle2.pt(), phi1 = particle1.phi(), phi2 = particle2.phi(); - registry.fill(HIST("hDeltaEtaPtIntMCGen"), eta2 - eta1); - registry.fill(HIST("hDeltaPhiPtIntMCGen"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2DPtIntMCGen"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEtaVsPtMCGen"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhiVsPtMCGen"), pt1, pt2, getDeltaPhi(phi2, phi1)); + double deltaEta = eta2 - eta1; + double deltaPhi = getDeltaPhi(phi2, phi1); + registry.fill(HIST("hDeltaEtaPtIntMCGen"), deltaEta); + registry.fill(HIST("hDeltaPhiPtIntMCGen"), deltaPhi); + registry.fill(HIST("hCorrel2DPtIntMCGen"), deltaPhi, deltaEta); + registry.fill(HIST("hDeltaEtaVsPtMCGen"), pt1, pt2, deltaEta); + registry.fill(HIST("hDeltaPhiVsPtMCGen"), pt1, pt2, deltaPhi); registry.fill(HIST("hDeltaPtDDbarMCGen"), pt2 - pt1); - registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::max(pt2, pt1) - std::min(pt2, pt1)); + registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::abs(pt2 - pt1)); } } // end inner loop (Dbars) } //end outer if (MC check D0) @@ -646,7 +679,7 @@ struct TaskCCbarCorrelationMCGen { HistogramRegistry registry{ "registry", {{"hMCEvtCount", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, - {"hptcandMCGen", "c,cbar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, + {"hPtcandMCGen", "c,cbar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}}, {"hcountD0triggersMCGen", "c trigger particles - MC gen;;N of trigger c", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, {"hEtaMCGen", "c,cbar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hPhiMCGen", "c,cbar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, @@ -670,50 +703,58 @@ struct TaskCCbarCorrelationMCGen { //loop over particles at MC gen level for (auto& particle1 : particlesMC) { - if (std::abs(particle1.pdgCode()) == 4) { //c or cbar quark found - int partMothPDG = particlesMC.iteratorAt(particle1.mother0()).pdgCode(); - if (std::abs(partMothPDG) != 4) - counterccbarPreEtasel++; //count c or cbar when it doesn't come from itself via fragmenatation (c->c+X) - if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) - continue; - registry.fill(HIST("hptcandMCGen"), particle1.pt()); - registry.fill(HIST("hEtaMCGen"), particle1.eta()); - registry.fill(HIST("hPhiMCGen"), particle1.phi()); - if (std::abs(partMothPDG) != 4) - counterccbar++; //count if c or cbar don't come from themselves during fragmenatation (after kinematic selection) - - //c-cbar correlation dedicated section - //if it's c, search for cbar and evaluate correlations. - if (particle1.pdgCode() == 4) { - //check whether mothers of quark c are still '4' particles - in that case the c quark comes from its own fragmentation, skip it - if (partMothPDG == 4) - continue; - registry.fill(HIST("hcountD0triggersMCGen"), 0); //to count trigger c quark (for normalisation) + if (!std::abs(particle1.pdgCode()) == 4) { //search c or cbar particles + continue; + } + int partMothPDG = particlesMC.iteratorAt(particle1.mother0()).pdgCode(); + //check whether mothers of quark c/cbar are still '4'/'-4' particles - in that case the c/cbar quark comes from its own fragmentation, skip it + if (partMothPDG == particle1.pdgCode()) { + continue; + } + counterccbarPreEtasel++; //count c or cbar (before kinematic selection) + if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) { + continue; + } + registry.fill(HIST("hPtcandMCGen"), particle1.pt()); + registry.fill(HIST("hEtaMCGen"), particle1.eta()); + registry.fill(HIST("hPhiMCGen"), particle1.phi()); + counterccbar++; //count if c or cbar don't come from themselves during fragmentation (after kinematic selection) - for (auto& particle2 : particlesMC) { - if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) - continue; - if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) + //c-cbar correlation dedicated section + //if it's c, search for cbar and evaluate correlations. + if (particle1.pdgCode() == 4) { + + registry.fill(HIST("hcountD0triggersMCGen"), 0); //to count trigger c quark (for normalisation) + + for (auto& particle2 : particlesMC) { + if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) { + continue; + } + if (particle2.pdgCode() == -4) { + //check whether mothers of quark cbar (from associated loop) are still '-4' particles - in that case the cbar quark comes from its own fragmentation, skip it + if (particlesMC.iteratorAt(particle2.mother0()).pdgCode() == -4) { continue; - if (particle2.pdgCode() == -4) { - //check whether mothers of quark cbar are still '-4' particles - in that case the cbar quark comes from its own fragmentation, skip it - if (particlesMC.iteratorAt(particle2.mother0()).pdgCode() == -4) - continue; - double eta1 = particle1.eta(), eta2 = particle2.eta(), pt1 = particle1.pt(), pt2 = particle2.pt(), phi1 = particle1.phi(), phi2 = particle2.phi(); - registry.fill(HIST("hDeltaEtaPtIntMCGen"), eta2 - eta1); - registry.fill(HIST("hDeltaPhiPtIntMCGen"), getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hCorrel2DPtIntMCGen"), getDeltaPhi(phi2, phi1), eta2 - eta1); - registry.fill(HIST("hDeltaEtaVsPtMCGen"), pt1, pt2, eta2 - eta1); - registry.fill(HIST("hDeltaPhiVsPtMCGen"), pt1, pt2, getDeltaPhi(phi2, phi1)); - registry.fill(HIST("hDeltaPtDDbarMCGen"), pt2 - pt1); - registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::max(particle2.pt(), particle1.pt()) - std::min(particle2.pt(), particle1.pt())); - } // end outer if (check cbar) - } // end inner loop - } //end outer if (check c) - } //end c/cbar if - } //end outer loop + } + double eta1 = particle1.eta(), eta2 = particle2.eta(), pt1 = particle1.pt(), pt2 = particle2.pt(), phi1 = particle1.phi(), phi2 = particle2.phi(); + double deltaEta = eta2 - eta1; + double deltaPhi = getDeltaPhi(phi2, phi1); + registry.fill(HIST("hDeltaEtaPtIntMCGen"), deltaEta); + registry.fill(HIST("hDeltaPhiPtIntMCGen"), deltaPhi); + registry.fill(HIST("hCorrel2DPtIntMCGen"), deltaPhi, deltaEta); + registry.fill(HIST("hDeltaEtaVsPtMCGen"), pt1, pt2, deltaEta); + registry.fill(HIST("hDeltaPhiVsPtMCGen"), pt1, pt2, deltaPhi); + registry.fill(HIST("hDeltaPtDDbarMCGen"), pt2 - pt1); + registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::max(particle2.pt(), particle1.pt()) - std::min(particle2.pt(), particle1.pt())); + } // end outer if (check cbar) + } // end inner loop + } //end outer if (check c) + } //end outer loop registry.fill(HIST("hcountCCbarPerEvent"), counterccbar); registry.fill(HIST("hcountCCbarPerEventPreEtaCut"), counterccbarPreEtasel); } @@ -724,7 +765,7 @@ struct TaskD0D0barCorrelationCheckPhiResolution { HistogramRegistry registry{ "registry", - {{"hmass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, + {{"hMass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{200, 1., 3.}}}}, {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hPhiStdPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, 0., 2. * o2::constants::math::PI}, {50, 0., 50.}}}}, {"hPhiByVtxPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, 0., 2. * o2::constants::math::PI}, {50, 0., 50.}}}}, @@ -736,12 +777,12 @@ struct TaskD0D0barCorrelationCheckPhiResolution { {"hDeltaPhiVsPtStdPhi", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, {"hDeltaPhiVsPtByVtxPhi", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}}}; - Configurable d_selectionFlagD0{"d_selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable d_selectionFlagD0bar{"d_selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable dSelectionFlagD0{"dSelectionFlagD0", 1, "Selection Flag for D0"}; + Configurable dSelectionFlagD0bar{"dSelectionFlagD0bar", 1, "Selection Flag for D0bar"}; Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; - Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= d_selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= d_selectionFlagD0bar); + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::McParticles const& particlesMC, aod::BigTracksMC const& tracksMC) { @@ -750,16 +791,18 @@ struct TaskD0D0barCorrelationCheckPhiResolution { if (!(candidate1.hfflag() & 1 << D0ToPiK)) { continue; } - if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) + if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { continue; - registry.fill(HIST("hmass"), InvMassD0(candidate1)); + } + registry.fill(HIST("hMass"), InvMassD0(candidate1)); registry.fill(HIST("hEta"), candidate1.eta()); //D-Dbar correlation dedicated section //if it's a candidate D0, search for D0bar and evaluate correlations - if (candidate1.isSelD0() >= d_selectionFlagD0) { + if (candidate1.isSelD0() >= dSelectionFlagD0) { double xPrimaryVertex = candidate1.index0_as().collision().posX(), yPrimaryVertex = candidate1.index0_as().collision().posY(); double pt1 = candidate1.pt(), phi1Std = candidate1.phi(); double phi1ByVtx = evaluatePhiByVertex(xPrimaryVertex, candidate1.xSecondaryVertex(), yPrimaryVertex, candidate1.ySecondaryVertex()); @@ -770,7 +813,7 @@ struct TaskD0D0barCorrelationCheckPhiResolution { //get corresponding gen-level D0, if exists, and evaluate gen-rec phi-difference with two approaches if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { //ok to keep both D0 and D0bar int indexGen = RecoDecay::getMother(particlesMC, candidate1.index0_as().label(), 421, true); //MC-gen corresponding index for MC-reco candidate - if (indexGen > 0) { + if (indexGen > -1) { double phi1Gen = particlesMC.iteratorAt(indexGen).phi(); registry.fill(HIST("hDifferenceGenPhiStdPhi"), getDeltaPhi(phi1Std, phi1Gen), pt1); registry.fill(HIST("hDifferenceGenPhiByVtxPhi"), getDeltaPhi(phi1ByVtx, phi1Gen), pt1); @@ -782,14 +825,17 @@ struct TaskD0D0barCorrelationCheckPhiResolution { if (!(candidate2.hfflag() & 1 << D0ToPiK)) { continue; } - if (candidate2.isSelD0bar() >= d_selectionFlagD0bar) { //accept only D0bar candidates - if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) + if (candidate2.isSelD0bar() >= dSelectionFlagD0bar) { //accept only D0bar candidates + if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) { continue; - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) + } + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { continue; + } //Excluding self-correlations (could happen in case of reflections) - if (candidate1.mRowIndex == candidate2.mRowIndex) + if (candidate1.mRowIndex == candidate2.mRowIndex) { continue; + } double pt2 = candidate2.pt(), phi2Std = candidate2.phi(); double phi2ByVtx = evaluatePhiByVertex(xPrimaryVertex, candidate2.xSecondaryVertex(), yPrimaryVertex, candidate2.ySecondaryVertex()); registry.fill(HIST("hDeltaPhiPtIntStdPhi"), getDeltaPhi(phi2Std, phi1Std)); From d870e9d6f6227bd1514a36e57e12b79eca6c08d8 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Tue, 2 Mar 2021 09:12:55 +0100 Subject: [PATCH 06/24] Further updates to D0-D0bar correlation task, from code review --- .../Tasks/PWGHF/taskD0D0barCorrelation.cxx | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index 5d06fcee32da2..fa695b02198e7 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -68,6 +68,14 @@ double getDeltaPhi(double phiD, double phiDbar) return RecoDecay::constrainAngle(phiDbar - phiD, -o2::constants::math::PI / 2.); } +/// +/// Returns deltaPhi value in range [-pi, pi], for resolution distributions +/// +double getDeltaPhiForResolution(double phiD, double phiDbar) +{ + return RecoDecay::constrainAngle(phiDbar - phiD, -o2::constants::math::PI); +} + /// /// Returns phi of candidate/particle evaluated from x and y components of segment connecting primary and secondary vertices /// @@ -703,7 +711,7 @@ struct TaskCCbarCorrelationMCGen { //loop over particles at MC gen level for (auto& particle1 : particlesMC) { - if (!std::abs(particle1.pdgCode()) == 4) { //search c or cbar particles + if (std::abs(particle1.pdgCode()) != 4) { //search c or cbar particles continue; } int partMothPDG = particlesMC.iteratorAt(particle1.mother0()).pdgCode(); @@ -750,7 +758,7 @@ struct TaskCCbarCorrelationMCGen { registry.fill(HIST("hDeltaEtaVsPtMCGen"), pt1, pt2, deltaEta); registry.fill(HIST("hDeltaPhiVsPtMCGen"), pt1, pt2, deltaPhi); registry.fill(HIST("hDeltaPtDDbarMCGen"), pt2 - pt1); - registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::max(particle2.pt(), particle1.pt()) - std::min(particle2.pt(), particle1.pt())); + registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::abs(pt2 - pt1)); } // end outer if (check cbar) } // end inner loop } //end outer if (check c) @@ -769,9 +777,9 @@ struct TaskD0D0barCorrelationCheckPhiResolution { {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hPhiStdPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, 0., 2. * o2::constants::math::PI}, {50, 0., 50.}}}}, {"hPhiByVtxPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, 0., 2. * o2::constants::math::PI}, {50, 0., 50.}}}}, - {"hPhiDifferenceTwoMethods", "D0,D0bar candidates;candidate #it{#Delta#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {50, 0., 50.}}}}, - {"hDifferenceGenPhiStdPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {50, 0., 50.}}}}, - {"hDifferenceGenPhiByVtxPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {50, 0., 50.}}}}, + {"hPhiDifferenceTwoMethods", "D0,D0bar candidates;candidate #it{#Delta#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI, o2::constants::math::PI}, {50, 0., 50.}}}}, + {"hDifferenceGenPhiStdPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI, o2::constants::math::PI}, {50, 0., 50.}}}}, + {"hDifferenceGenPhiByVtxPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI, o2::constants::math::PI}, {50, 0., 50.}}}}, {"hDeltaPhiPtIntStdPhi", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, {"hDeltaPhiPtIntByVtxPhi", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, {"hDeltaPhiVsPtStdPhi", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, @@ -807,17 +815,15 @@ struct TaskD0D0barCorrelationCheckPhiResolution { double pt1 = candidate1.pt(), phi1Std = candidate1.phi(); double phi1ByVtx = evaluatePhiByVertex(xPrimaryVertex, candidate1.xSecondaryVertex(), yPrimaryVertex, candidate1.ySecondaryVertex()); registry.fill(HIST("hPhiStdPhi"), phi1Std, pt1); - registry.fill(HIST("hPhiByVtxPhi"), phi1ByVtx, pt1); //trick to have correct Phi range - registry.fill(HIST("hPhiDifferenceTwoMethods"), getDeltaPhi(phi1ByVtx, phi1Std), pt1); + registry.fill(HIST("hPhiByVtxPhi"), phi1ByVtx, pt1); + registry.fill(HIST("hPhiDifferenceTwoMethods"), getDeltaPhiForResolution(phi1ByVtx, phi1Std), pt1); //get corresponding gen-level D0, if exists, and evaluate gen-rec phi-difference with two approaches if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { //ok to keep both D0 and D0bar int indexGen = RecoDecay::getMother(particlesMC, candidate1.index0_as().label(), 421, true); //MC-gen corresponding index for MC-reco candidate - if (indexGen > -1) { - double phi1Gen = particlesMC.iteratorAt(indexGen).phi(); - registry.fill(HIST("hDifferenceGenPhiStdPhi"), getDeltaPhi(phi1Std, phi1Gen), pt1); - registry.fill(HIST("hDifferenceGenPhiByVtxPhi"), getDeltaPhi(phi1ByVtx, phi1Gen), pt1); - } + double phi1Gen = particlesMC.iteratorAt(indexGen).phi(); + registry.fill(HIST("hDifferenceGenPhiStdPhi"), getDeltaPhiForResolution(phi1Std, phi1Gen), pt1); + registry.fill(HIST("hDifferenceGenPhiByVtxPhi"), getDeltaPhiForResolution(phi1ByVtx, phi1Gen), pt1); } for (auto& candidate2 : candidates) { From 23d2c4f3cb64e2a079ec5505bcb0319c5b55a237 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Tue, 2 Mar 2021 10:39:46 +0100 Subject: [PATCH 07/24] Solving conflicts for CMakeLists.txt --- Analysis/Tasks/PWGHF/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Analysis/Tasks/PWGHF/CMakeLists.txt b/Analysis/Tasks/PWGHF/CMakeLists.txt index 70de51f4be5ce..5c062d38c4302 100644 --- a/Analysis/Tasks/PWGHF/CMakeLists.txt +++ b/Analysis/Tasks/PWGHF/CMakeLists.txt @@ -92,3 +92,8 @@ o2_add_dpl_workflow(hf-task-d0d0bar-correlation SOURCES taskD0D0barCorrelation.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-mc-validation + SOURCES HFMCValidation.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) From 8ebb50a8f92738f8fcf41daf074a0ee1b4606ae1 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Thu, 4 Mar 2021 14:47:18 +0100 Subject: [PATCH 08/24] Comply to adaptAnalysisTask core modifications --- .../Tasks/PWGHF/taskD0D0barCorrelation.cxx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index fa695b02198e7..e57df1df99b9a 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -858,18 +858,18 @@ struct TaskD0D0barCorrelationCheckPhiResolution { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ - adaptAnalysisTask("add-collision-id"), - adaptAnalysisTask("hf-task-d0d0bar-correlation"), - adaptAnalysisTask("hf-task-d0d0bar-correlation-ls")}; + adaptAnalysisTask(cfgc, "add-collision-id"), + adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation"), + adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation-ls")}; //MC-based tasks const bool doMC = cfgc.options().get("doMC"); if (doMC) { - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-correlation-mc-rec")); - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-correlation-mc-gen")); - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-correlation-mc-rec-ls")); - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-correlation-mc-gen-ls")); - workflow.push_back(adaptAnalysisTask("hf-task-ccbar-correlation-mc-gen")); - workflow.push_back(adaptAnalysisTask("hf-task-d0d0bar-correlation-crosscheck-phi")); + workflow.push_back(adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation-mc-rec")); + workflow.push_back(adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation-mc-gen")); + workflow.push_back(adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation-mc-rec-ls")); + workflow.push_back(adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation-mc-gen-ls")); + workflow.push_back(adaptAnalysisTask(cfgc, "hf-task-ccbar-correlation-mc-gen")); + workflow.push_back(adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation-crosscheck-phi")); } return workflow; } From 1ad153bf1328db89ff7eae85eadab013d46e1c09 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Fri, 5 Mar 2021 10:35:37 +0100 Subject: [PATCH 09/24] Modified label() to mcParticle() call, to comply to PR5566 --- Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index e57df1df99b9a..829b5c63c799e 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -820,7 +820,7 @@ struct TaskD0D0barCorrelationCheckPhiResolution { //get corresponding gen-level D0, if exists, and evaluate gen-rec phi-difference with two approaches if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { //ok to keep both D0 and D0bar - int indexGen = RecoDecay::getMother(particlesMC, candidate1.index0_as().label(), 421, true); //MC-gen corresponding index for MC-reco candidate + int indexGen = RecoDecay::getMother(particlesMC, candidate1.index0_as().mcParticle(), 421, true); //MC-gen corresponding index for MC-reco candidate double phi1Gen = particlesMC.iteratorAt(indexGen).phi(); registry.fill(HIST("hDifferenceGenPhiStdPhi"), getDeltaPhiForResolution(phi1Std, phi1Gen), pt1); registry.fill(HIST("hDifferenceGenPhiByVtxPhi"), getDeltaPhiForResolution(phi1ByVtx, phi1Gen), pt1); From c4fcec659aac86018584fa8f6153487a5805ec7b Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Fri, 5 Mar 2021 10:45:33 +0100 Subject: [PATCH 10/24] Clang fix --- Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index 829b5c63c799e..eeb60bdd512e3 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -819,7 +819,7 @@ struct TaskD0D0barCorrelationCheckPhiResolution { registry.fill(HIST("hPhiDifferenceTwoMethods"), getDeltaPhiForResolution(phi1ByVtx, phi1Std), pt1); //get corresponding gen-level D0, if exists, and evaluate gen-rec phi-difference with two approaches - if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { //ok to keep both D0 and D0bar + if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { //ok to keep both D0 and D0bar int indexGen = RecoDecay::getMother(particlesMC, candidate1.index0_as().mcParticle(), 421, true); //MC-gen corresponding index for MC-reco candidate double phi1Gen = particlesMC.iteratorAt(indexGen).phi(); registry.fill(HIST("hDifferenceGenPhiStdPhi"), getDeltaPhiForResolution(phi1Std, phi1Gen), pt1); From 7b4f9413890585e24022c24f121990f575675deb Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Mon, 8 Mar 2021 11:38:25 +0100 Subject: [PATCH 11/24] Solved conflict in PWGHF/CMakeLists.txt --- Analysis/Tasks/PWGHF/CMakeLists.txt | 104 ++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 Analysis/Tasks/PWGHF/CMakeLists.txt diff --git a/Analysis/Tasks/PWGHF/CMakeLists.txt b/Analysis/Tasks/PWGHF/CMakeLists.txt new file mode 100644 index 0000000000000..3ee2de172a953 --- /dev/null +++ b/Analysis/Tasks/PWGHF/CMakeLists.txt @@ -0,0 +1,104 @@ +# Copyright CERN and copyright holders of ALICE O2. This software is distributed +# under the terms of the GNU General Public License v3 (GPL Version 3), copied +# verbatim in the file "COPYING". +# +# See http://alice-o2.web.cern.ch/license for full licensing information. +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization or +# submit itself to any jurisdiction. + +o2_add_dpl_workflow(qatask + SOURCES qaTask.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(qa-efficiency + SOURCES qaTaskEfficiency.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(qa-simple + SOURCES qaTaskSimple.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-track-index-skims-creator + SOURCES HFTrackIndexSkimsCreator.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing ROOT::EG + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-candidate-creator-2prong + SOURCES HFCandidateCreator2Prong.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing ROOT::EG + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-tree-creator-d0-tokpi + SOURCES HFTreeCreatorD0ToKPi.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing ROOT::EG + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-candidate-creator-3prong + SOURCES HFCandidateCreator3Prong.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing ROOT::EG + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-tree-creator-lc-topkpi + SOURCES HFTreeCreatorLcToPKPi.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing ROOT::EG + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-d0-candidate-selector + SOURCES HFD0CandidateSelector.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-dplus-topikpi-candidate-selector + SOURCES HFDplusToPiKPiCandidateSelector.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-lc-candidate-selector + SOURCES HFLcCandidateSelector.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-jpsi-toee-candidate-selector + SOURCES HFJpsiToEECandidateSelector.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-task-d0 + SOURCES taskD0.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-task-dplus + SOURCES taskDPlus.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-task-lc + SOURCES taskLc.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-task-jpsi + SOURCES taskJpsi.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-task-bplus + SOURCES taskBPlus.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-task-d0d0bar-correlation + SOURCES taskD0D0barCorrelation.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-mc-validation + SOURCES HFMCValidation.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) From 14eaa5adc4c1bf8a987bc8a6e1e98f05cfce9611 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Tue, 9 Mar 2021 14:32:59 +0100 Subject: [PATCH 12/24] Further round of comments implemented --- .../Tasks/PWGHF/taskD0D0barCorrelation.cxx | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index eeb60bdd512e3..c7d5ad1ca1dc1 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -86,10 +86,10 @@ double evaluatePhiByVertex(double xVertex1, double xVertex2, double yVertex1, do /// definition of variables for D0D0bar pairs vs eta acceptance studies (hDDbarVsEtaCut, in data-like, MC-reco and MC-kine tasks) const double maxEtaCut = 5.; -const double PtThresholdForMaxEtaCut = 10.; +const double ptThresholdForMaxEtaCut = 10.; const double incrementEtaCut = 0.1; const double incrementPtThreshold = 0.5; -const double epsilon = 10E-5; +const double epsilon = 1E-5; /// D0 analysis task - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) struct TaskD0D0barCorrelation { @@ -115,7 +115,7 @@ struct TaskD0D0barCorrelation { {"hDeltaPhiVsPt", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, {"hDeltaPtDDbar", "D0,D0bar candidates;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, {"hDeltaPtMaxMin", "D0,D0bar candidates;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, - {"hDDbarVsEtaCut", "D0,D0bar pairs vs #eta cut;#eta_{max};entries", {HistType::kTH2F, {{(int)(maxEtaCut / incrementEtaCut), 0., maxEtaCut}, {(int)(PtThresholdForMaxEtaCut / incrementPtThreshold), 0., PtThresholdForMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and PtThresholdForMaxEtaCut instead + {"hDDbarVsEtaCut", "D0,D0bar pairs vs #eta cut;#eta_{max};entries", {HistType::kTH2F, {{(int)(maxEtaCut / incrementEtaCut), 0., maxEtaCut}, {(int)(ptThresholdForMaxEtaCut / incrementPtThreshold), 0., ptThresholdForMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and ptThresholdForMaxEtaCut instead Configurable dSelectionFlagD0{"dSelectionFlagD0", 1, "Selection Flag for D0"}; Configurable dSelectionFlagD0bar{"dSelectionFlagD0bar", 1, "Selection Flag for D0bar"}; @@ -130,7 +130,7 @@ struct TaskD0D0barCorrelation { if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && candidate1.pt() < cutPtCandMin) { continue; } //check decay channel flag for candidate1 @@ -166,7 +166,7 @@ struct TaskD0D0barCorrelation { if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && candidate2.pt() < cutPtCandMin) { continue; } //Excluding trigger self-correlations (possible in case of both mass hypotheses accepted) @@ -193,7 +193,7 @@ struct TaskD0D0barCorrelation { if (std::abs(candidate1.eta()) < etaCut && std::abs(candidate2.eta()) < etaCut && candidate1.pt() > ptCut && candidate2.pt() > ptCut) registry.fill(HIST("hDDbarVsEtaCut"), etaCut - epsilon, ptCut + epsilon); ptCut += incrementPtThreshold; - } while (ptCut < PtThresholdForMaxEtaCut - epsilon); + } while (ptCut < ptThresholdForMaxEtaCut - epsilon); } while (etaCut < maxEtaCut - epsilon); } //note: candidates selected as both D0 and D0bar are used, and considered in both situation (but not auto-correlated): reflections could play a relevant role. @@ -228,7 +228,7 @@ struct TaskD0D0barCorrelationMCRec { {"hDeltaPhiVsPtMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, {"hDeltaPtDDbarMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, {"hDeltaPtMaxMinMCRec", "D0,D0bar candidates - MC reco;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, - {"hDDbarVsEtaCutMCRec", "D0,D0bar pairs vs #eta cut - MC reco;#eta_{max};entries", {HistType::kTH2F, {{(int)(maxEtaCut / incrementEtaCut), 0., maxEtaCut}, {(int)(PtThresholdForMaxEtaCut / incrementPtThreshold), 0., PtThresholdForMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and PtThresholdForMaxEtaCut instead + {"hDDbarVsEtaCutMCRec", "D0,D0bar pairs vs #eta cut - MC reco;#eta_{max};entries", {HistType::kTH2F, {{(int)(maxEtaCut / incrementEtaCut), 0., maxEtaCut}, {(int)(ptThresholdForMaxEtaCut / incrementPtThreshold), 0., ptThresholdForMaxEtaCut}}}}}}; //don't modify the binning from here: act on maxEtaCut and ptThresholdForMaxEtaCut instead Configurable dSelectionFlagD0{"dSelectionFlagD0", 1, "Selection Flag for D0"}; Configurable dSelectionFlagD0bar{"dSelectionFlagD0bar", 1, "Selection Flag for D0bar"}; @@ -248,7 +248,7 @@ struct TaskD0D0barCorrelationMCRec { if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && candidate1.pt() < cutPtCandMin) { continue; } if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { @@ -278,7 +278,7 @@ struct TaskD0D0barCorrelationMCRec { if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && candidate2.pt() < cutPtCandMin) { continue; } double eta1 = candidate1.eta(), eta2 = candidate2.eta(), pt1 = candidate1.pt(), pt2 = candidate2.pt(), phi1 = candidate1.phi(), phi2 = candidate2.phi(); @@ -301,7 +301,7 @@ struct TaskD0D0barCorrelationMCRec { if (std::abs(candidate1.eta()) < etaCut && std::abs(candidate2.eta()) < etaCut && candidate1.pt() > ptCut && candidate2.pt() > ptCut) registry.fill(HIST("hDDbarVsEtaCutMCRec"), etaCut - epsilon, ptCut + epsilon); ptCut += incrementPtThreshold; - } while (ptCut < PtThresholdForMaxEtaCut - epsilon); + } while (ptCut < ptThresholdForMaxEtaCut - epsilon); } while (etaCut < maxEtaCut - epsilon); } //end inner if (MC match) @@ -330,7 +330,7 @@ struct TaskD0D0barCorrelationMCGen { {"hDeltaPhiVsPtMCGen", "D0,D0bar candidates - MC gen;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{100, 0., 10.}, {100, 0., 10.}, {32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, {"hDeltaPtDDbarMCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, {"hDeltaPtMaxMinMCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, - {"hDDbarVsEtaCutMCGen", "D0,D0bar pairs vs #eta cut - MC gen;#eta_{max};entries", {HistType::kTH2F, {{(int)(maxEtaCut / incrementEtaCut), 0., maxEtaCut}, {(int)(PtThresholdForMaxEtaCut / incrementPtThreshold), 0., PtThresholdForMaxEtaCut}}}}, //don't modify the binning from here: act on maxEtaCut and PtThresholdForMaxEtaCut instead + {"hDDbarVsEtaCutMCGen", "D0,D0bar pairs vs #eta cut - MC gen;#eta_{max};entries", {HistType::kTH2F, {{(int)(maxEtaCut / incrementEtaCut), 0., maxEtaCut}, {(int)(ptThresholdForMaxEtaCut / incrementPtThreshold), 0., ptThresholdForMaxEtaCut}}}}, //don't modify the binning from here: act on maxEtaCut and ptThresholdForMaxEtaCut instead {"hcountD0D0barPerEvent", "D0,D0bar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 10.}}}}}}; Configurable cutEtaCandMax{"cutEtaCandMax", -1., "max. cand. pseudorapidity"}; @@ -345,7 +345,7 @@ struct TaskD0D0barCorrelationMCGen { if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && particle1.pt() < cutPtCandMin) { continue; } //just checking if the particle is D0 or D0bar, for now @@ -364,7 +364,7 @@ struct TaskD0D0barCorrelationMCGen { if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && particle2.pt() < cutPtCandMin) { continue; } if (particle2.pdgCode() == -421) { @@ -387,7 +387,7 @@ struct TaskD0D0barCorrelationMCGen { if (std::abs(particle1.eta()) < etaCut && std::abs(particle2.eta()) < etaCut && particle1.pt() > ptCut && particle2.pt() > ptCut) registry.fill(HIST("hDDbarVsEtaCutMCGen"), etaCut - epsilon, ptCut + epsilon); ptCut += incrementPtThreshold; - } while (ptCut < PtThresholdForMaxEtaCut - epsilon); + } while (ptCut < ptThresholdForMaxEtaCut - epsilon); } while (etaCut < maxEtaCut - epsilon); } // end D0bar check } //end inner loop @@ -441,7 +441,7 @@ struct TaskD0D0barCorrelationLS { if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && candidate1.pt() < cutPtCandMin) { continue; } //fill invariant mass plots and generic info from all D0/D0bar candidates @@ -475,7 +475,7 @@ struct TaskD0D0barCorrelationLS { if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && candidate2.pt() < cutPtCandMin) { continue; } //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) @@ -544,7 +544,7 @@ struct TaskD0D0barCorrelationMCRecLS { if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && candidate1.pt() < cutPtCandMin) { continue; } if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { @@ -577,7 +577,7 @@ struct TaskD0D0barCorrelationMCRecLS { if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && candidate2.pt() < cutPtCandMin) { continue; } //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) @@ -635,7 +635,7 @@ struct TaskD0D0barCorrelationMCGenLS { if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && particle1.pt() < cutPtCandMin) { continue; } @@ -655,7 +655,7 @@ struct TaskD0D0barCorrelationMCGenLS { if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && particle2.pt() < cutPtCandMin) { continue; } if (particle2.pt() < ptParticle1 && particle2.pdgCode() == particle1.pdgCode()) { //like-sign condition (both 421 or both -421) and pT_Trig>pT_assoc @@ -723,7 +723,7 @@ struct TaskCCbarCorrelationMCGen { if (cutEtaCandMax >= 0. && std::abs(particle1.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && particle1.pt() < cutPtCandMin) { continue; } registry.fill(HIST("hPtcandMCGen"), particle1.pt()); @@ -741,7 +741,7 @@ struct TaskCCbarCorrelationMCGen { if (cutEtaCandMax >= 0. && std::abs(particle2.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && particle2.pt() < cutPtCandMin) { continue; } if (particle2.pdgCode() == -4) { @@ -802,7 +802,7 @@ struct TaskD0D0barCorrelationCheckPhiResolution { if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && candidate1.pt() < cutPtCandMin) { continue; } registry.fill(HIST("hMass"), InvMassD0(candidate1)); @@ -835,7 +835,7 @@ struct TaskD0D0barCorrelationCheckPhiResolution { if (cutEtaCandMax >= 0. && std::abs(candidate2.eta()) > cutEtaCandMax) { continue; } - if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { + if (cutPtCandMin >= 0. && candidate2.pt() < cutPtCandMin) { continue; } //Excluding self-correlations (could happen in case of reflections) From 53d2c7a98aa964906f3e2dd0815fd0d2bfe14757 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Wed, 10 Mar 2021 09:35:18 +0100 Subject: [PATCH 13/24] Complying to further adaptAnalysisTask updates --- Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index c7d5ad1ca1dc1..799df81b150e6 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -859,17 +859,17 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ adaptAnalysisTask(cfgc, "add-collision-id"), - adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation"), - adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation-ls")}; + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; //MC-based tasks const bool doMC = cfgc.options().get("doMC"); if (doMC) { - workflow.push_back(adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation-mc-rec")); - workflow.push_back(adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation-mc-gen")); - workflow.push_back(adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation-mc-rec-ls")); - workflow.push_back(adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation-mc-gen-ls")); - workflow.push_back(adaptAnalysisTask(cfgc, "hf-task-ccbar-correlation-mc-gen")); - workflow.push_back(adaptAnalysisTask(cfgc, "hf-task-d0d0bar-correlation-crosscheck-phi")); + workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc)); } return workflow; } From fc3d69947d2a66cbaf041d5eb1558bdbc80ffbb7 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Wed, 10 Mar 2021 09:53:47 +0100 Subject: [PATCH 14/24] Missed to update one task in last commit --- Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index 799df81b150e6..eeb9b4c9ce5fe 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -858,7 +858,7 @@ struct TaskD0D0barCorrelationCheckPhiResolution { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ - adaptAnalysisTask(cfgc, "add-collision-id"), + adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc)}; //MC-based tasks From 9d2330df19086da75d761ecdf455bea720297117 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Thu, 18 Mar 2021 14:57:49 +0100 Subject: [PATCH 15/24] Removed the pre-task inserting CollisionId to candidate table (now added centrally) --- .../Tasks/PWGHF/taskD0D0barCorrelation.cxx | 39 +++---------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index eeb9b4c9ce5fe..02de4b3bb2960 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -26,32 +26,6 @@ using namespace o2::aod::hf_cand_prong2; using namespace o2::framework::expressions; using namespace o2::constants::math; -// the following is needed to extend the standard candidate table, and allow grouping candidate table by collisions -namespace o2::aod -{ -namespace hf_2prong_correlation -{ -DECLARE_SOA_INDEX_COLUMN(Collision, collision); -} // namespace hf_2prong_correlation -DECLARE_SOA_TABLE(HF2ProngCollis, "AOD", "COLLID_2PR", aod::hf_2prong_correlation::CollisionId); - -using Big2Prong = soa::Join; -using Big2ProngMC = soa::Join; -} // namespace o2::aod - -// preliminary task to fill the column index to the extended candidate table -struct CreateBig2Prong { - - Produces create2ProngIndexCollColumn; - void process(aod::HfCandProng2 const& candidates, aod::Tracks const& tracks) - { - for (auto& candidate : candidates) { - int indexColl = candidate.index0_as().collisionId(); //takes index of collision from first D daughter - create2ProngIndexCollColumn(indexColl); - } - } -}; - void customize(std::vector& workflowOptions) { ConfigParamSpec optionDoMC{"doMC", VariantType::Bool, false, {"Run MC-dedicated tasks."}}; @@ -124,7 +98,7 @@ struct TaskD0D0barCorrelation { Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); - void process(aod::Collision const& collision, soa::Filtered const& candidates) + void process(aod::Collision const& collision, soa::Filtered> const& candidates) { for (auto& candidate1 : candidates) { if (cutEtaCandMax >= 0. && std::abs(candidate1.eta()) > cutEtaCandMax) { @@ -237,7 +211,7 @@ struct TaskD0D0barCorrelationMCRec { Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); - void process(aod::Collision const& collision, soa::Filtered const& candidates) + void process(aod::Collision const& collision, soa::Filtered> const& candidates) { //MC reco level for (auto& candidate1 : candidates) { @@ -431,7 +405,7 @@ struct TaskD0D0barCorrelationLS { Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); - void process(aod::Collision const& collision, soa::Filtered const& candidates) + void process(aod::Collision const& collision, soa::Filtered> const& candidates) { for (auto& candidate1 : candidates) { //check decay channel flag for candidate1 @@ -533,7 +507,7 @@ struct TaskD0D0barCorrelationMCRecLS { Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); - void process(aod::Collision const& collision, soa::Filtered const& candidates) + void process(aod::Collision const& collision, soa::Filtered> const& candidates) { //MC reco level for (auto& candidate1 : candidates) { @@ -792,7 +766,7 @@ struct TaskD0D0barCorrelationCheckPhiResolution { Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); - void process(aod::Collision const& collision, soa::Filtered const& candidates, aod::McParticles const& particlesMC, aod::BigTracksMC const& tracksMC) + void process(aod::Collision const& collision, soa::Filtered> const& candidates, aod::McParticles const& particlesMC, aod::BigTracksMC const& tracksMC) { for (auto& candidate1 : candidates) { //check decay channel flag for candidate1 @@ -811,7 +785,7 @@ struct TaskD0D0barCorrelationCheckPhiResolution { //D-Dbar correlation dedicated section //if it's a candidate D0, search for D0bar and evaluate correlations if (candidate1.isSelD0() >= dSelectionFlagD0) { - double xPrimaryVertex = candidate1.index0_as().collision().posX(), yPrimaryVertex = candidate1.index0_as().collision().posY(); + double xPrimaryVertex = candidate1.posX(), yPrimaryVertex = candidate1.posY(); double pt1 = candidate1.pt(), phi1Std = candidate1.phi(); double phi1ByVtx = evaluatePhiByVertex(xPrimaryVertex, candidate1.xSecondaryVertex(), yPrimaryVertex, candidate1.ySecondaryVertex()); registry.fill(HIST("hPhiStdPhi"), phi1Std, pt1); @@ -858,7 +832,6 @@ struct TaskD0D0barCorrelationCheckPhiResolution { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc)}; //MC-based tasks From cd41206a136e0026c63b9784ef8c80dfc491117f Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Thu, 25 Mar 2021 09:37:29 +0100 Subject: [PATCH 16/24] Fixed typo in new version of code --- Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index 02de4b3bb2960..9e4abeea23e25 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -133,7 +133,7 @@ struct TaskD0D0barCorrelation { if (candidate1.isSelD0() >= dSelectionFlagD0) { for (auto& candidate2 : candidates) { //check decay channel flag for candidate2 - if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { continue; } if (candidate2.isSelD0bar() >= dSelectionFlagD0bar) { From 877a13eb36c61d3bc732f3fc6366e50b03bbdd83 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Thu, 25 Mar 2021 14:45:03 +0100 Subject: [PATCH 17/24] Removed cmath header, no longer needed --- Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index 9e4abeea23e25..50fd6f0bf7cbb 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -13,8 +13,6 @@ /// /// \author Fabio Colamaria , INFN Bari -#include - #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "AnalysisDataModel/HFSecondaryVertex.h" From 5763aa201e6ecdd84b7d37cb3d645def61ac87e8 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Tue, 30 Mar 2021 10:24:52 +0200 Subject: [PATCH 18/24] Committing D0-D0bar codes with new structure --- .../AnalysisDataModel/HFSecondaryVertex.h | 20 + Analysis/Tasks/PWGHF/CMakeLists.txt | 10 + Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx | 822 ++++++++++++++++++ .../Tasks/PWGHF/taskD0D0barCorrelation.cxx | 435 +++++++++ 4 files changed, 1287 insertions(+) create mode 100644 Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx create mode 100644 Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx diff --git a/Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h b/Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h index b897517fc465a..ec7ea0e33da91 100644 --- a/Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h +++ b/Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h @@ -485,6 +485,26 @@ DECLARE_SOA_TABLE(HfCandProng3MCGen, "AOD", "HFCANDP3MCGEN", hf_cand_prong3::OriginMCGen, hf_cand_prong3::FlagMCDecayChanGen); +// definition of columns and tables for D0-D0bar correlation pairs +namespace hf_d0d0bar_correlation +{ +DECLARE_SOA_COLUMN(DeltaPhi, deltaPhi, float); +DECLARE_SOA_COLUMN(DeltaEta, deltaEta, float); +DECLARE_SOA_COLUMN(PtD0, ptD0, float); +DECLARE_SOA_COLUMN(PtD0bar, ptD0bar, float); +DECLARE_SOA_COLUMN(MD0, mD0, float); +DECLARE_SOA_COLUMN(MD0bar, mD0bar, float); +DECLARE_SOA_COLUMN(SignalStatus, signalStatus, int); +} // namespace hf_d0d0bar_correlation +DECLARE_SOA_TABLE(D0D0barPair, "AOD", "D0D0BARPAIR", + aod::hf_d0d0bar_correlation::DeltaPhi, + aod::hf_d0d0bar_correlation::DeltaEta, + aod::hf_d0d0bar_correlation::PtD0, + aod::hf_d0d0bar_correlation::PtD0bar); +DECLARE_SOA_TABLE(D0D0barRecoInfo, "AOD", "D0D0BARRECOINFO", + aod::hf_d0d0bar_correlation::MD0, + aod::hf_d0d0bar_correlation::MD0bar, + aod::hf_d0d0bar_correlation::SignalStatus); } // namespace o2::aod #endif // O2_ANALYSIS_HFSECONDARYVERTEX_H_ diff --git a/Analysis/Tasks/PWGHF/CMakeLists.txt b/Analysis/Tasks/PWGHF/CMakeLists.txt index 6fb285562c45d..58e51f2421987 100644 --- a/Analysis/Tasks/PWGHF/CMakeLists.txt +++ b/Analysis/Tasks/PWGHF/CMakeLists.txt @@ -108,6 +108,16 @@ o2_add_dpl_workflow(hf-task-x PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) +o2_add_dpl_workflow(hf-d0d0bar-correlator + SOURCES D0D0barCorrelator.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(hf-task-d0d0bar-correlation + SOURCES taskD0D0barCorrelation.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + o2_add_dpl_workflow(hf-mc-validation SOURCES HFMCValidation.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing diff --git a/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx b/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx new file mode 100644 index 0000000000000..73df2fb792ec2 --- /dev/null +++ b/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx @@ -0,0 +1,822 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file taskD0D0barCorrelation.cxx +/// \brief D0-D0bar analysis task - data-like, MC-reco and MC-kine analyses. For ULS and LS pairs +/// +/// \author Fabio Colamaria , INFN Bari + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "AnalysisCore/HFSelectorCuts.h" +#include "AnalysisDataModel/HFSecondaryVertex.h" +#include "AnalysisDataModel/HFCandidateSelectionTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::aod::hf_cand_prong2; +using namespace o2::analysis::hf_cuts_d0_topik; +using namespace o2::framework::expressions; +using namespace o2::constants::math; +using namespace o2::aod::hf_d0d0bar_correlation; + +void customize(std::vector& workflowOptions) +{ + ConfigParamSpec optionDoMC{"doMC", VariantType::Bool, false, {"Run MC dedicated tasks."}}; + workflowOptions.push_back(optionDoMC); +} + +#include "Framework/runDataProcessing.h" + +/// +/// Returns deltaPhi value in range [-pi/2., 3.*pi/2], typically used for correlation studies +/// +double getDeltaPhi(double phiD, double phiDbar) +{ + return RecoDecay::constrainAngle(phiDbar - phiD, -o2::constants::math::PI / 2.); +} + +/// definition of variables for D0D0bar pairs vs eta acceptance studies (hDDbarVsEtaCut, in data-like, MC-reco and MC-kine tasks) +const double maxEtaCut = 5.; +const double ptThresholdForMaxEtaCut = 10.; +const double incrementEtaCut = 0.1; +const double incrementPtThreshold = 0.5; +const double epsilon = 1E-5; + +/// D0-D0bar correlation pair builder - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) +struct D0D0barCorrelator { + Produces entryD0D0barPair; + Produces entryD0D0barRecoInfo; + + HistogramRegistry registry{ + "registry", + //NOTE: use hMassD0 for trigger normalisation (S*0.955), and hMass2DCorrelationPairs (in final task) for 2D-sideband-subtraction purposes + {{"hPtCand", "D0,D0bar candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hPtProng0", "D0,D0bar candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hPtProng1", "D0,D0bar candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hSelectionStatus", "D0,D0bar candidates;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, + {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhi", "D0,D0bar candidates;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hY", "D0,D0bar candidates;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDDbarVsEtaCut", "D0,D0bar pairs vs #eta cut;#eta_{max};entries", {HistType::kTH2F, {{(int)(maxEtaCut / incrementEtaCut), 0., maxEtaCut}, {(int)(ptThresholdForMaxEtaCut / incrementPtThreshold), 0., ptThresholdForMaxEtaCut}}}}}}; + + Configurable dSelectionFlagD0{"dSelectionFlagD0", 1, "Selection Flag for D0"}; + Configurable dSelectionFlagD0bar{"dSelectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for candidate mass plots"}; + + void init(o2::framework::InitContext&) { + registry.add("hMass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hMassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hMassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + } + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered> const& candidates) + { + for (auto& candidate1 : candidates) { + if (cutYCandMax >= 0. && std::abs(YD0(candidate1)) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { + continue; + } + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + //fill invariant mass plots and generic info from all D0/D0bar candidates + if (candidate1.isSelD0() >= dSelectionFlagD0) { + registry.fill(HIST("hMass"), InvMassD0(candidate1), candidate1.pt()); + registry.fill(HIST("hMassD0"), InvMassD0(candidate1), candidate1.pt()); + } + if (candidate1.isSelD0bar() >= dSelectionFlagD0bar) { + registry.fill(HIST("hMass"), InvMassD0bar(candidate1), candidate1.pt()); + registry.fill(HIST("hMassD0bar"), InvMassD0bar(candidate1), candidate1.pt()); + } + registry.fill(HIST("hPtCand"), candidate1.pt()); + registry.fill(HIST("hPtProng0"), candidate1.ptProng0()); + registry.fill(HIST("hPtProng1"), candidate1.ptProng1()); + registry.fill(HIST("hEta"), candidate1.eta()); + registry.fill(HIST("hPhi"), candidate1.phi()); + registry.fill(HIST("hY"), YD0(candidate1)); + registry.fill(HIST("hSelectionStatus"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); + + //D-Dbar correlation dedicated section + //if the candidate is a D0, search for D0bar and evaluate correlations + if (candidate1.isSelD0() >= dSelectionFlagD0) { + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (candidate2.isSelD0bar() >= dSelectionFlagD0bar) { + if (cutYCandMax >= 0. && std::abs(YD0(candidate2)) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { + continue; + } + //Excluding trigger self-correlations (possible in case of both mass hypotheses accepted) + if (candidate1.mRowIndex == candidate2.mRowIndex) { + continue; + } + entryD0D0barPair(getDeltaPhi(candidate2.phi(),candidate1.phi()), + candidate2.eta() - candidate1.eta(), + candidate1.pt(), + candidate2.pt()); + entryD0D0barRecoInfo(InvMassD0(candidate1), + InvMassD0bar(candidate2), + 0); + double etaCut = 0.; + double ptCut = 0.; + do { //fill pairs vs etaCut plot + ptCut = 0.; + etaCut += incrementEtaCut; + do { //fill pairs vs etaCut plot + if (std::abs(candidate1.eta()) < etaCut && std::abs(candidate2.eta()) < etaCut && candidate1.pt() > ptCut && candidate2.pt() > ptCut) + registry.fill(HIST("hDDbarVsEtaCut"), etaCut - epsilon, ptCut + epsilon); + ptCut += incrementPtThreshold; + } while (ptCut < ptThresholdForMaxEtaCut - epsilon); + } while (etaCut < maxEtaCut - epsilon); + } + //note: candidates selected as both D0 and D0bar are used, and considered in both situation (but not auto-correlated): reflections could play a relevant role. + //another, more restrictive, option, could be to consider only candidates selected with a single option (D0 xor D0bar) + + } // end inner loop (Dbars) + } + + } //end outer loop + } +}; + +/// D0-D0bar correlation pair builder - for MC reco-level analysis (candidates matched to true signal only, but also the various bkg sources are studied) +struct D0D0barCorrelatorMCRec { + + Produces entryD0D0barPair; + Produces entryD0D0barRecoInfo; + + HistogramRegistry registry{ + "registry", + //NOTE: use hMassD0 for trigger normalisation (S*0.955), and hMass2DCorrelationPairs (in final task) for 2D-sideband-subtraction purposes + {{"hPtCandMCRec", "D0,D0bar candidates - MC reco;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hPtProng0MCRec", "D0,D0bar candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hPtProng1MCRec", "D0,D0bar candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hSelectionStatusMCRec", "D0,D0bar candidates - MC reco;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, + {"hEtaMCRec", "D0,D0bar candidates - MC reco;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhiMCRec", "D0,D0bar candidates - MC reco;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hYMCRec", "D0,D0bar candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hDDbarVsEtaCut", "D0,D0bar pairs vs #eta cut;#eta_{max};entries", {HistType::kTH2F, {{(int)(maxEtaCut / incrementEtaCut), 0., maxEtaCut}, {(int)(ptThresholdForMaxEtaCut / incrementPtThreshold), 0., ptThresholdForMaxEtaCut}}}}}}; + + Configurable dSelectionFlagD0{"dSelectionFlagD0", 1, "Selection Flag for D0"}; + Configurable dSelectionFlagD0bar{"dSelectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for candidate mass plots"}; + + void init(o2::framework::InitContext&) { + registry.add("hMassD0MCRec", "D0,D0bar candidates - MC reco;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hMassD0barMCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + } + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered> const& candidates) + { + //MC reco level + bool flagD0Signal = kFALSE; + bool flagD0barSignal = kFALSE; + for (auto& candidate1 : candidates) { + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (cutYCandMax >= 0. && std::abs(YD0(candidate1)) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { + continue; + } + if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { + //fill invariant mass plots and generic info from all D0/D0bar candidates + if (candidate1.isSelD0() >= dSelectionFlagD0 && candidate1.flagMCMatchRec() == 1 << D0ToPiK) { //only reco and matched as D0 + registry.fill(HIST("hMassD0MCRec"), InvMassD0(candidate1), candidate1.pt()); + } + if (candidate1.isSelD0bar() >= dSelectionFlagD0bar && candidate1.flagMCMatchRec() == -1 << D0ToPiK) { //only reco and matched as D0bar + registry.fill(HIST("hMassD0barMCRec"), InvMassD0bar(candidate1), candidate1.pt()); + } + registry.fill(HIST("hPtCandMCRec"), candidate1.pt()); + registry.fill(HIST("hPtProng0MCRec"), candidate1.ptProng0()); + registry.fill(HIST("hPtProng1MCRec"), candidate1.ptProng1()); + registry.fill(HIST("hEtaMCRec"), candidate1.eta()); + registry.fill(HIST("hPhiMCRec"), candidate1.phi()); + registry.fill(HIST("hYMCRec"), YD0(candidate1)); + registry.fill(HIST("hSelectionStatusMCRec"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); + } + + //D-Dbar correlation dedicated section + //if the candidate is selected ad D0, search for D0bar and evaluate correlations + if (candidate1.isSelD0() < dSelectionFlagD0) { //discard candidates not selected as D0 in outer loop + continue; + } + if (candidate1.flagMCMatchRec() == 1 << D0ToPiK) { //candidate matched to D0 (particle) + flagD0Signal = kTRUE; + } else { //candidate of bkg, wrongly selected as D0 + flagD0Signal = kFALSE; + } + for (auto& candidate2 : candidates) { + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { //check decay channel flag for candidate2 + continue; + } + if (candidate2.isSelD0bar() < dSelectionFlagD0bar) { //discard candidates not selected as D0bar in inner loop + continue; + } + if (candidate2.flagMCMatchRec() == -1 << D0ToPiK) { //candidate matched to D0bar (antiparticle) + flagD0barSignal = kTRUE; + } else { //candidate of bkg, wrongly selected as D0bar + flagD0barSignal = kFALSE; + } + if (cutYCandMax >= 0. && std::abs(YD0(candidate2)) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { + continue; + } + //choice of options (D0/D0bar signal/bkg) + int pairSignalStatus = 0; //0 = bkg/bkg, 1 = bkg/sig, 2 = sig/bkg, 3 = sig/sig + if (flagD0Signal) { + pairSignalStatus += 2; + } + if (flagD0barSignal) { + pairSignalStatus += 1; + } + entryD0D0barPair(getDeltaPhi(candidate2.phi(),candidate1.phi()), + candidate2.eta() - candidate1.eta(), + candidate1.pt(), + candidate2.pt()); + entryD0D0barRecoInfo(InvMassD0(candidate1), + InvMassD0bar(candidate2), + pairSignalStatus); + double etaCut = 0.; + double ptCut = 0.; + do { //fill pairs vs etaCut plot + ptCut = 0.; + etaCut += incrementEtaCut; + do { //fill pairs vs etaCut plot + if (std::abs(candidate1.eta()) < etaCut && std::abs(candidate2.eta()) < etaCut && candidate1.pt() > ptCut && candidate2.pt() > ptCut) + registry.fill(HIST("hDDbarVsEtaCut"), etaCut - epsilon, ptCut + epsilon); + ptCut += incrementPtThreshold; + } while (ptCut < ptThresholdForMaxEtaCut - epsilon); + } while (etaCut < maxEtaCut - epsilon); + } // end inner loop (Dbars) + + } //end outer loop + } +}; + +/// D0-D0bar correlation pair builder - for MC gen-level analysis (no filter/selection, only true signal) +struct D0D0barCorrelatorMCGen { + + Produces entryD0D0barPair; + + HistogramRegistry registry{ + "registry", + {{"hMCEvtCount", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hPtCandMCGen", "D0,D0bar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hEtaMCGen", "D0,D0bar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhiMCGen", "D0,D0bar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hYMCGen", "D0,D0bar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hcountD0D0barPerEvent", "D0,D0bar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 10.}}}}, + {"hDDbarVsEtaCut", "D0,D0bar pairs vs #eta cut;#eta_{max};entries", {HistType::kTH2F, {{(int)(maxEtaCut / incrementEtaCut), 0., maxEtaCut}, {(int)(ptThresholdForMaxEtaCut / incrementPtThreshold), 0., ptThresholdForMaxEtaCut}}}}}}; + + Configurable cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for trigger counters"}; + + void init(o2::framework::InitContext&) { + registry.add("hcountD0triggersMCGen", "D0 trigger particles - MC gen;;N of trigger D0", {HistType::kTH2F, {{1, -0.5, 0.5}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + } + + void process(aod::McCollision const& mccollision, soa::Join const& particlesMC) + { + int counterD0D0bar = 0; + registry.fill(HIST("hMCEvtCount"), 0); + //MC gen level + for (auto& particle1 : particlesMC) { + if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) { + continue; + } + //just checking if the particle is D0 or D0bar, for now + if (std::abs(particle1.pdgCode()) == 421) { + registry.fill(HIST("hPtCandMCGen"), particle1.pt()); + registry.fill(HIST("hEtaMCGen"), particle1.eta()); + registry.fill(HIST("hPhiMCGen"), particle1.phi()); + registry.fill(HIST("hYMCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); + counterD0D0bar++; + + //D-Dbar correlation dedicated section + //if it's a D0 particle, search for D0bar and evaluate correlations + if (particle1.pdgCode() == 421) { //just checking the particle PDG, not the decay channel (differently from Reco: you have a BR factor btw such levels!) + registry.fill(HIST("hcountD0triggersMCGen"), 0, particle1.pt()); //to count trigger D0 (for normalisation) + for (auto& particle2 : particlesMC) { + if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle2.px(), particle2.py(), particle2.pz()}, RecoDecay::getMassPDG(particle2.pdgCode()))) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) { + continue; + } + if (particle2.pdgCode() == -421) { + entryD0D0barPair(getDeltaPhi(particle2.phi(),particle1.phi()), + particle2.eta() - particle1.eta(), + particle1.pt(), + particle2.pt()); + double etaCut = 0.; + double ptCut = 0.; + do { //fill pairs vs etaCut plot + ptCut = 0.; + etaCut += incrementEtaCut; + do { //fill pairs vs etaCut plot + if (std::abs(particle1.eta()) < etaCut && std::abs(particle2.eta()) < etaCut && particle1.pt() > ptCut && particle2.pt() > ptCut) + registry.fill(HIST("hDDbarVsEtaCut"), etaCut - epsilon, ptCut + epsilon); + ptCut += incrementPtThreshold; + } while (ptCut < ptThresholdForMaxEtaCut - epsilon); + } while (etaCut < maxEtaCut - epsilon); + } // end D0bar check + } //end inner loop + } //end D0 check + } //end outer if (MC check D0/D0bar) + + } //end outer loop + registry.fill(HIST("hcountD0D0barPerEvent"), counterD0D0bar); + } +}; + +/// D0-D0bar correlation pair builder - LIKE SIGN - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) +struct D0D0barCorrelatorLS { + + Produces entryD0D0barPair; + Produces entryD0D0barRecoInfo; + + HistogramRegistry registry{ + "registry", + //NOTE: use hMassD0 for trigger normalisation (S*0.955), and hMass2DCorrelationPairs (in final task) for 2D-sideband-subtraction purposes + {{"hPtCand", "D0,D0bar candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hPtProng0", "D0,D0bar candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hPtProng1", "D0,D0bar candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hSelectionStatus", "D0,D0bar candidates;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, + {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhi", "D0,D0bar candidates;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hY", "D0,D0bar candidates;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}}}; + + Configurable dSelectionFlagD0{"dSelectionFlagD0", 1, "Selection Flag for D0"}; + Configurable dSelectionFlagD0bar{"dSelectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for candidate mass plots"}; + + void init(o2::framework::InitContext&) { + registry.add("hMass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hMassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hMassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + } + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered> const& candidates) + { + for (auto& candidate1 : candidates) { + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (cutYCandMax >= 0. && std::abs(YD0(candidate1)) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { + continue; + } + //fill invariant mass plots and generic info from all D0/D0bar candidates + if (candidate1.isSelD0() >= dSelectionFlagD0) { + registry.fill(HIST("hMass"), InvMassD0(candidate1), candidate1.pt()); + registry.fill(HIST("hMassD0"), InvMassD0(candidate1), candidate1.pt()); + } + if (candidate1.isSelD0bar() >= dSelectionFlagD0bar) { + registry.fill(HIST("hMass"), InvMassD0bar(candidate1), candidate1.pt()); + registry.fill(HIST("hMassD0bar"), InvMassD0bar(candidate1), candidate1.pt()); + } + registry.fill(HIST("hPtCand"), candidate1.pt()); + registry.fill(HIST("hPtProng0"), candidate1.ptProng0()); + registry.fill(HIST("hPtProng1"), candidate1.ptProng1()); + registry.fill(HIST("hEta"), candidate1.eta()); + registry.fill(HIST("hPhi"), candidate1.phi()); + registry.fill(HIST("hY"), YD0(candidate1)); + registry.fill(HIST("hSelectionStatus"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); + + double ptParticle1 = candidate1.pt(); //trigger particle is the largest-pT one + + //D-Dbar correlation dedicated section + //For like-sign, first loop on both D0 and D0bars. First candidate is for sure a D0 and D0bars (checked before, so don't re-check anything on it) + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { + continue; + } + //for the associated, has to have smaller pT, and pass D0sel if trigger passes D0sel, or D0barsel if trigger passes D0barsel + if (candidate2.pt() < ptParticle1 && ((candidate1.isSelD0() >= dSelectionFlagD0 && candidate2.isSelD0() >= dSelectionFlagD0) || (candidate1.isSelD0bar() >= dSelectionFlagD0bar && candidate2.isSelD0bar() >= dSelectionFlagD0bar))) { + if (cutYCandMax >= 0. && std::abs(YD0(candidate2)) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { + continue; + } + //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) + if (candidate1.mRowIndex == candidate2.mRowIndex) { + continue; + } + entryD0D0barPair(getDeltaPhi(candidate2.phi(),candidate1.phi()), + candidate2.eta() - candidate1.eta(), + candidate1.pt(), + candidate2.pt()); + entryD0D0barRecoInfo(InvMassD0(candidate1), + InvMassD0bar(candidate2), + 0); + } + //note: candidates selected as both D0 and D0bar are used, and considered in both situation (but not auto-correlated): reflections could play a relevant role. + //another, more restrictive, option, could be to consider only candidates selected with a single option (D0 xor D0bar) + + } // end inner loop (Dbars) + + } //end outer loop + } +}; + +/// D0-D0bar correlation pair builder - LIKE SIGN - for MC reco analysis (data-like but matching to true DO and D0bar) +struct D0D0barCorrelatorMCRecLS { + + Produces entryD0D0barPair; + Produces entryD0D0barRecoInfo; + + HistogramRegistry registry{ + "registry", + //NOTE: use hMassD0 for trigger normalisation (S*0.955), and hMass2DCorrelationPairs (in final task) for 2D-sideband-subtraction purposes + {{"hPtCandMCRec", "D0,D0bar candidates - MC reco;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hPtProng0MCRec", "D0,D0bar candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hPtProng1MCRec", "D0,D0bar candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hSelectionStatusMCRec", "D0,D0bar candidates - MC reco;selection status;entries", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, + {"hEtaMCRec", "D0,D0bar candidates - MC reco;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhiMCRec", "D0,D0bar candidates - MC reco;candidate #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hYMCRec", "D0,D0bar candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}}}; + + Configurable dSelectionFlagD0{"dSelectionFlagD0", 1, "Selection Flag for D0"}; + Configurable dSelectionFlagD0bar{"dSelectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for candidate mass plots"}; + + void init(o2::framework::InitContext&) { + registry.add("hMassD0MCRec", "D0,D0bar candidates - MC reco;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hMassD0barMCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + } + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered> const& candidates) + { + //MC reco level + for (auto& candidate1 : candidates) { + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (cutYCandMax >= 0. && std::abs(YD0(candidate1)) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(candidate1.pt()) < cutPtCandMin) { + continue; + } + if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { + //fill invariant mass plots and generic info from all D0/D0bar candidates + if (candidate1.isSelD0() >= dSelectionFlagD0 && candidate1.flagMCMatchRec() == D0ToPiK) { //only reco and matched as D0 + registry.fill(HIST("hMassD0MCRec"), InvMassD0(candidate1)); + } + if (candidate1.isSelD0bar() >= dSelectionFlagD0bar && candidate1.flagMCMatchRec() == D0ToPiK) { //only reco and matched as D0bar + registry.fill(HIST("hMassD0barMCRec"), InvMassD0bar(candidate1)); + } + registry.fill(HIST("hPtCandMCRec"), candidate1.pt()); + registry.fill(HIST("hPtprong0MCRec"), candidate1.ptProng0()); + registry.fill(HIST("hPtprong1MCRec"), candidate1.ptProng1()); + registry.fill(HIST("hEtaMCRec"), candidate1.eta()); + registry.fill(HIST("hPhiMCRec"), candidate1.phi()); + registry.fill(HIST("hYMCRec"), YD0(candidate1)); + + double ptParticle1 = candidate1.pt(); //trigger particle is the largest pT one + + //D-Dbar correlation dedicated section + //For like-sign, first loop on both D0 and D0bars. First candidate is for sure a D0 and D0bars (looping on filtered) and was already matched, so don't re-check anything on it) + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { + continue; + } + bool conditionLSForD0 = (candidate1.isSelD0() >= dSelectionFlagD0bar && candidate1.flagMCMatchRec() == 1 << D0ToPiK) && (candidate2.isSelD0() >= dSelectionFlagD0bar && candidate2.flagMCMatchRec() == 1 << D0ToPiK); + bool conditionLSForD0bar = (candidate1.isSelD0bar() >= dSelectionFlagD0bar && candidate1.flagMCMatchRec() == -1 << D0ToPiK) && (candidate2.isSelD0bar() >= dSelectionFlagD0bar && candidate2.flagMCMatchRec() == -1 << D0ToPiK); + if (candidate2.pt() < ptParticle1 && (conditionLSForD0 || conditionLSForD0bar)) { //LS pair (of D0 or of D0bar) + pt2= 0. && std::abs(YD0(candidate2)) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { + continue; + } + //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) + if (candidate1.mRowIndex == candidate2.mRowIndex) { + continue; + } + entryD0D0barPair(getDeltaPhi(candidate2.phi(),candidate1.phi()), + candidate2.eta() - candidate1.eta(), + candidate1.pt(), + candidate2.pt()); + entryD0D0barRecoInfo(InvMassD0(candidate1), + InvMassD0bar(candidate2), + 0); //for LS studies we set a dummy 0 for pairSignalStatus (there are no more the usual 4 possible combinations) + + } //end inner if (MC match) + + } // end inner loop (Dbars) + } //end outer if (MC match) + } //end outer loop + } +}; + +/// D0-D0bar correlation pair builder - for MC gen-level analysis, like sign particles +struct D0D0barCorrelatorMCGenLS { + + Produces entryD0D0barPair; + + HistogramRegistry registry{ + "registry", + {{"hMCEvtCount", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hPtCandMCGen", "D0,D0bar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hEtaMCGen", "D0,D0bar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhiMCGen", "D0,D0bar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hYMCGen", "D0,D0bar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hcountD0D0barPerEvent", "D0,D0bar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 10.}}}}}}; + + Configurable cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for trigger counters"}; + + void init(o2::framework::InitContext&) { + registry.add("hcountD0triggersMCGen", "D0 trigger particles - MC gen;;N of trigger D0", {HistType::kTH2F, {{1, -0.5, 0.5}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + } + + void process(aod::McCollision const& mccollision, soa::Join const& particlesMC) + { + int counterD0D0bar = 0; + registry.fill(HIST("hMCEvtCount"), 0); + //MC gen level + for (auto& particle1 : particlesMC) { + if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) { + continue; + } + + double ptParticle1 = particle1.pt(); //trigger particle is the largest pT one + + //Check whether particle is D0 or D0bar (and not the decay chain) + if (std::abs(particle1.pdgCode()) == 421) { + registry.fill(HIST("hPtCandMCGen"), particle1.pt()); + registry.fill(HIST("hEtaMCGen"), particle1.eta()); + registry.fill(HIST("hPhiMCGen"), particle1.phi()); + registry.fill(HIST("hYMCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); + counterD0D0bar++; + //D-Dbar correlation dedicated section + //if it's D0, search for D0bar and evaluate correlations. + registry.fill(HIST("hcountD0triggersMCGen"), 0, particle1.pt()); //to count trigger D0 (normalisation) + for (auto& particle2 : particlesMC) { + if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle2.px(), particle2.py(), particle2.pz()}, RecoDecay::getMassPDG(particle2.pdgCode()))) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) { + continue; + } + if (particle2.pt() < ptParticle1 && particle2.pdgCode() == particle1.pdgCode()) { //like-sign condition (both 421 or both -421) and pT_Trig>pT_assoc + //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) + if (particle1.mRowIndex == particle2.mRowIndex) { + continue; + } + entryD0D0barPair(getDeltaPhi(particle2.phi(),particle1.phi()), + particle2.eta() - particle1.eta(), + particle1.pt(), + particle2.pt()); + } + } // end inner loop (Dbars) + } //end outer if (MC check D0) + } //end outer loop + registry.fill(HIST("hcountD0D0barPerEvent"), counterD0D0bar); + } +}; + +/// c-cbar correlator table builder - for MC gen-level analysis +struct CCbarCorrelatorMCGen { + + Produces entryD0D0barPair; + + HistogramRegistry registry{ + "registry", + {{"hMCEvtCount", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hPtCandMCGen", "c,cbar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hEtaMCGen", "c,cbar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hYMCGen", "c,cbar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhiMCGen", "c,cbar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hcountD0D0barPerEvent", "D0,cbar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 10.}}}}}}; + + Configurable cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for trigger counters"}; + + void init(o2::framework::InitContext&) { + registry.add("hcountD0triggersMCGen", "c trigger particles - MC gen;;N of trigger D0", {HistType::kTH2F, {{1, -0.5, 0.5}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + } + + void process(aod::McCollision const& mccollision, soa::Join const& particlesMC) + { + registry.fill(HIST("hMCEvtCount"), 0); + int counterccbar = 0, counterccbarPreEtasel = 0; + + //loop over particles at MC gen level + for (auto& particle1 : particlesMC) { + if (std::abs(particle1.pdgCode()) != 4) { //search c or cbar particles + continue; + } + int partMothPDG = particlesMC.iteratorAt(particle1.mother0()).pdgCode(); + //check whether mothers of quark c/cbar are still '4'/'-4' particles - in that case the c/cbar quark comes from its own fragmentation, skip it + if (partMothPDG == particle1.pdgCode()) { + continue; + } + counterccbarPreEtasel++; //count c or cbar (before kinematic selection) + if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) { + continue; + } + registry.fill(HIST("hPtcandMCGen"), particle1.pt()); + registry.fill(HIST("hEtaMCGen"), particle1.eta()); + registry.fill(HIST("hPhiMCGen"), particle1.phi()); + registry.fill(HIST("hYMCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); + counterccbar++; //count if c or cbar don't come from themselves during fragmentation (after kinematic selection) + + //c-cbar correlation dedicated section + //if it's c, search for cbar and evaluate correlations. + if (particle1.pdgCode() == 4) { + + registry.fill(HIST("hcountD0triggersMCGen"), 0, particle1.pt()); //to count trigger c quark (for normalisation) + + for (auto& particle2 : particlesMC) { + if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle2.px(), particle2.py(), particle2.pz()}, RecoDecay::getMassPDG(particle2.pdgCode()))) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) { + continue; + } + if (particle2.pdgCode() == -4) { + //check whether mothers of quark cbar (from associated loop) are still '-4' particles - in that case the cbar quark comes from its own fragmentation, skip it + if (particlesMC.iteratorAt(particle2.mother0()).pdgCode() == -4) { + continue; + } + entryD0D0barPair(getDeltaPhi(particle2.phi(),particle1.phi()), + particle2.eta() - particle1.eta(), + particle1.pt(), + particle2.pt()); + } // end outer if (check cbar) + } // end inner loop + } //end outer if (check c) + } //end outer loop + registry.fill(HIST("hcountCCbarPerEvent"), counterccbar); + registry.fill(HIST("hcountCCbarPerEventPreEtaCut"), counterccbarPreEtasel); + } +}; + +/// c-cbar correlator table builder - for MC gen-level analysis - Like Sign +struct CCbarCorrelatorMCGenLS { + + Produces entryD0D0barPair; + + HistogramRegistry registry{ + "registry", + {{"hMCEvtCount", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}}, + {"hPtCandMCGen", "c,cbar particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{180, 0., 36.}}}}, + {"hEtaMCGen", "c,cbar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hYMCGen", "c,cbar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhiMCGen", "c,cbar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, + {"hcountD0D0barPerEvent", "D0,cbar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 10.}}}}}}; + + Configurable cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for trigger counters"}; + + void init(o2::framework::InitContext&) { + registry.add("hcountD0triggersMCGen", "c trigger particles - MC gen;;N of trigger D0", {HistType::kTH2F, {{1, -0.5, 0.5}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + } + + void process(aod::McCollision const& mccollision, soa::Join const& particlesMC) + { + registry.fill(HIST("hMCEvtCount"), 0); + int counterccbar = 0, counterccbarPreEtasel = 0; + + //loop over particles at MC gen level + for (auto& particle1 : particlesMC) { + if (std::abs(particle1.pdgCode()) != 4) { //search c or cbar particles + continue; + } + int partMothPDG = particlesMC.iteratorAt(particle1.mother0()).pdgCode(); + //check whether mothers of quark c/cbar are still '4'/'-4' particles - in that case the c/cbar quark comes from its own fragmentation, skip it + if (partMothPDG == particle1.pdgCode()) { + continue; + } + counterccbarPreEtasel++; //count c or cbar (before kinematic selection) + if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) { + continue; + } + registry.fill(HIST("hPtcandMCGen"), particle1.pt()); + registry.fill(HIST("hEtaMCGen"), particle1.eta()); + registry.fill(HIST("hPhiMCGen"), particle1.phi()); + registry.fill(HIST("hYMCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); + counterccbar++; //count if c or cbar don't come from themselves during fragmentation (after kinematic selection) + + //c-cbar correlation dedicated section + double ptParticle1 = particle1.pt(); //trigger particle is the largest pT one + registry.fill(HIST("hcountD0triggersMCGen"), 0, particle1.pt()); //to count trigger c quark (for normalisation) + + for (auto& particle2 : particlesMC) { + if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle2.px(), particle2.py(), particle2.pz()}, RecoDecay::getMassPDG(particle2.pdgCode()))) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) { + continue; + } + if (particle2.pt() < ptParticle1 && particle2.pdgCode() == particle1.pdgCode()) { + //check whether mothers of quark cbar (from associated loop) are still '-4' particles - in that case the cbar quark comes from its own fragmentation, skip it + if (particlesMC.iteratorAt(particle2.mother0()).pdgCode() == particle2.pdgCode()) { + continue; + } + entryD0D0barPair(getDeltaPhi(particle2.phi(),particle1.phi()), + particle2.eta() - particle1.eta(), + particle1.pt(), + particle2.pt()); + } // end outer if (check PDG associate) + } // end inner loop + } //end outer loop + registry.fill(HIST("hcountCCbarPerEvent"), counterccbar); + registry.fill(HIST("hcountCCbarPerEventPreEtaCut"), counterccbarPreEtasel); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{}; + const bool doMCccbar = cfgc.options().get("doMCccbar"); + const bool doMCGen = cfgc.options().get("doMCGen"); + const bool doMCRec = cfgc.options().get("doMCRec"); + const bool doLikeSign = cfgc.options().get("doLikeSign"); + if (!doLikeSign) { //unlike-sign analyses + if (doMCGen) { //MC-Gen analysis + workflow.push_back(adaptAnalysisTask(cfgc)); + } else if (doMCRec) { //MC-Reco analysis + workflow.push_back(adaptAnalysisTask(cfgc)); + } else if (doMCccbar) { //MC-Reco analysis + workflow.push_back(adaptAnalysisTask(cfgc)); + } else { //data analysis + workflow.push_back(adaptAnalysisTask(cfgc)); + } + } else { //ike-sign analyses + if (doMCGen) { //MC-Gen analysis + workflow.push_back(adaptAnalysisTask(cfgc)); + } else if (doMCRec) { //MC-Reco analysis + workflow.push_back(adaptAnalysisTask(cfgc)); + } else if (doMCccbar) { //MC-Reco analysis + workflow.push_back(adaptAnalysisTask(cfgc)); + } else { //data analysis + workflow.push_back(adaptAnalysisTask(cfgc)); + } + } + + return workflow; +} diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx new file mode 100644 index 0000000000000..ee631bc0745b3 --- /dev/null +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -0,0 +1,435 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file taskD0D0barCorrelation.cxx +/// \brief D0-D0bar analysis task - data-like, MC-reco and MC-kine analyses. For ULS and LS pairs +/// +/// \author Fabio Colamaria , INFN Bari + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "AnalysisCore/HFSelectorCuts.h" +#include "AnalysisDataModel/HFSecondaryVertex.h" +#include "AnalysisDataModel/HFCandidateSelectionTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::aod::hf_cand_prong2; +using namespace o2::analysis::hf_cuts_d0_topik; +using namespace o2::framework::expressions; +using namespace o2::constants::math; +using namespace o2::aod::hf_d0d0bar_correlation; + +namespace o2::aod +{ +using D0D0barPairFull = soa::Join; +} // namespace o2::aod + +void customize(std::vector& workflowOptions) +{ + ConfigParamSpec optionDoMC{"doMC", VariantType::Bool, false, {"Run MC dedicated tasks."}}; + workflowOptions.push_back(optionDoMC); +} + +#include "Framework/runDataProcessing.h" + +/// +/// Returns deltaPhi value in range [-pi/2., 3.*pi/2], typically used for correlation studies +/// +double getDeltaPhi(double phiD, double phiDbar) +{ + return RecoDecay::constrainAngle(phiDbar - phiD, -o2::constants::math::PI / 2.); +} + +/// +/// Returns deltaPhi value in range [-pi, pi], for resolution distributions +/// +double getDeltaPhiForResolution(double phiD, double phiDbar) +{ + return RecoDecay::constrainAngle(phiDbar - phiD, -o2::constants::math::PI); +} + +/// +/// Returns phi of candidate/particle evaluated from x and y components of segment connecting primary and secondary vertices +/// +double evaluatePhiByVertex(double xVertex1, double xVertex2, double yVertex1, double yVertex2) +{ + return RecoDecay::Phi(xVertex2 - xVertex1, yVertex2 - yVertex1); +} +/* +/// definition of axes for THnSparse (dPhi,dEta,pTD,pTDbar) - note: last two axis are dummy, will be replaced later +const int nBinsSparse[4] = {32,120,10,10}; +const double binMinSparse[4] = {-o2::constants::math::PI / 2.,-6.,0.,0.; //is the minimum for all the bins +const double binMaxSparse[4] = {3. * o2::constants::math::PI / 2.,6.,10.,10.}; //is the maximum for all the bins +*/ + +/// D0-D0bar correlation pair filling task, from pair tables - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) +/// Works on both USL and LS analyses pair tables +struct TaskD0D0barCorrelation { + + HistogramRegistry registry{ + "registry", + //NOTE: use hMassD0 (from correlator task) for normalisation, and hMass2DCorrelationPairs for 2D-sideband-subtraction purposes + {{"hMass2DCorrelationPairs", "D0,D0bar candidates 2D;inv. mass D0 (#pi K) (GeV/#it{c}^{2});inv. mass D0bar (#pi K) (GeV/#it{c}^{2});#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{200, 1.6, 2.1}, {200, 1.6, 2.1}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hDeltaEtaPtIntSignalRegion", "D0,D0bar candidates signal region;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhiPtIntSignalRegion", "D0,D0bar candidates signal region;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2DPtIntSignalRegion", "D0,D0bar candidates signal region;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hCorrel2DVsPtSignalRegion", "D0,D0bar candidates signal region;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hDeltaPtDDbarSignalRegion", "D0,D0bar candidates signal region;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPtMaxMinSignalRegion", "D0,D0bar candidates signal region;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, + {"hDeltaEtaPtIntSidebands", "D0,D0bar candidates sidebands;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhiPtIntSidebands", "D0,D0bar candidates sidebands;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2DPtIntSidebands", "D0,D0bar candidates sidebands;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hCorrel2DVsPtSidebands", "D0,D0bar candidates sidebands;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hDeltaPtDDbarSidebands", "D0,D0bar candidates sidebands;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPtMaxMinSidebands", "D0,D0bar candidates sidebands;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}}}; + + //pT ranges for correlation plots: the default values are those embedded in hf_cuts_d0_topik (i.e. the mass pT bins), but can be redefined via json files + Configurable> binsCorrelations{"ptBinsForCorrelations", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for correlation plots"}; + //signal and sideband region edges, to be defined via json file (initialised to empty) + Configurable> signalRegionInner{"signalRegionInner", std::vector(), "Inner values of signal region vs pT"}; + Configurable> signalRegionOuter{"signalRegionOuter", std::vector(), "Outer values of signal region vs pT"}; + Configurable> sidebandLeftInner{"sidebandLeftInner", std::vector(), "Inner values of left sideband vs pT"}; + Configurable> sidebandLeftOuter{"sidebandLeftOuter", std::vector(), "Outer values of left sideband vs pT"}; + Configurable> sidebandRightInner{"sidebandRightInner", std::vector(), "Inner values of right sideband vs pT"}; + Configurable> sidebandRightOuter{"sidebandRightOuter", std::vector(), "Outer values of right sideband vs pT"}; + + // redefinition of pT axes for THnSparse holding correlation entries + int nBinspTaxis = binsCorrelations->size() - 1; + const double* valuespTaxis = binsCorrelations->data(); + + void init(o2::framework::InitContext&) { + for (int i=2; i<=3; i++) { + registry.get("hMass2DCorrelationPairs")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSignalRegion")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSidebands")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + } + } + + void process(aod::D0D0barPairFull const& pairEntries) + { + for (auto& pairEntry : pairEntries) { + //fill 2D invariant mass plots + registry.fill(HIST("hMass2DCorrelationPairs"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + + //check if correlation entry belongs to signal region, sidebands or is outside both, and fill correlation plots + int pTBinD0 = o2::analysis::findBin(binsCorrelations, pairEntry.ptD0()); + int pTBinD0bar = o2::analysis::findBin(binsCorrelations, pairEntry.ptD0bar()); + + if(pairEntry.mD0() > signalRegionInner->at(pTBinD0) && pairEntry.mD0() < signalRegionOuter->at(pTBinD0) && pairEntry.mD0bar() > signalRegionInner->at(pTBinD0bar) && pairEntry.mD0bar() < signalRegionOuter->at(pTBinD0bar)) { + //in signal region + registry.fill(HIST("hCorrel2DVsPtSignalRegion"), pairEntry.deltaPhi(), pairEntry.deltaEta(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hCorrel2DPtIntSignalRegion"), pairEntry.deltaPhi(), pairEntry.deltaEta()); + registry.fill(HIST("hDeltaEtaPtIntSignalRegion"), pairEntry.deltaPhi()); + registry.fill(HIST("hDeltaPhiPtIntSignalRegion"), pairEntry.deltaEta()); + registry.fill(HIST("hDeltaPtDDbarSignalRegion"), pairEntry.ptD0bar() - pairEntry.ptD0()); + registry.fill(HIST("hDeltaPtMaxMinSignalRegion"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); + } + + if((pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandLeftOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar)) || + (pairEntry.mD0() > sidebandRightInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar)) || + (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandLeftOuter->at(pTBinD0bar)) || + (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandRightInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar))) { + //in sideband region + registry.fill(HIST("hCorrel2DVsPtSidebands"), pairEntry.deltaPhi(), pairEntry.deltaEta(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hCorrel2DPtIntSidebands"), pairEntry.deltaPhi(), pairEntry.deltaEta()); + registry.fill(HIST("hDeltaEtaPtIntSidebands"), pairEntry.deltaPhi()); + registry.fill(HIST("hDeltaPhiPtIntSidebands"), pairEntry.deltaEta()); + registry.fill(HIST("hDeltaPtDDbarSidebands"), pairEntry.ptD0bar() - pairEntry.ptD0()); + registry.fill(HIST("hDeltaPtMaxMinSidebands"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); + } + } //end loop + } +}; + +/// D0-D0bar correlation pair filling task, from pair tables - for MC reco-level analysis (candidates matched to true signal only, but also bkg sources are studied) +/// Works on both USL and LS analyses pair tables +struct TaskD0D0barCorrelationMCRec { + + HistogramRegistry registry{ + "registry", + //NOTE: use hMassD0 (from correlator task) for normalisation, and hMass2DCorrelationPairs for 2D-sideband-subtraction purposes + {{"hMass2DCorrelationPairsMCRecSigSig", "D0,D0bar candidates 2D SigSig - MC reco;inv. mass D0 (#pi K) (GeV/#it{c}^{2});inv. mass D0bar (#pi K) (GeV/#it{c}^{2});#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{200, 1.6, 2.1}, {200, 1.6, 2.1}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hMass2DCorrelationPairsMCRecSigBkg", "D0,D0bar candidates 2D SigBkg - MC reco;inv. mass D0 (#pi K) (GeV/#it{c}^{2});inv. mass D0bar (#pi K) (GeV/#it{c}^{2});#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{200, 1.6, 2.1}, {200, 1.6, 2.1}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hMass2DCorrelationPairsMCRecBkgSig", "D0,D0bar candidates 2D BkgSig - MC reco;inv. mass D0 (#pi K) (GeV/#it{c}^{2});inv. mass D0bar (#pi K) (GeV/#it{c}^{2});#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{200, 1.6, 2.1}, {200, 1.6, 2.1}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hMass2DCorrelationPairsMCRecBkgBkg", "D0,D0bar candidates 2D BkgBkg - MC reco;inv. mass D0 (#pi K) (GeV/#it{c}^{2});inv. mass D0bar (#pi K) (GeV/#it{c}^{2});#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{200, 1.6, 2.1}, {200, 1.6, 2.1}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hDeltaEtaPtIntSignalRegionMCRec", "D0,D0bar candidates signal region - MC reco;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhiPtIntSignalRegionMCRec", "D0,D0bar candidates signal region - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2DPtIntSignalRegionMCRec", "D0,D0bar candidates signal region - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hDeltaPtDDbarSignalRegionMCRec", "D0,D0bar candidates signal region - MC reco;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPtMaxMinSignalRegionMCRec", "D0,D0bar candidates signal region - MC reco;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}, + {"hCorrel2DVsPtSignalRegionMCRecSigSig", "D0,D0bar candidates signal region SigSig - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hCorrel2DVsPtSignalRegionMCRecSigBkg", "D0,D0bar candidates signal region SigBkg - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hCorrel2DVsPtSignalRegionMCRecBkgSig", "D0,D0bar candidates signal region BkgSig - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hCorrel2DVsPtSignalRegionMCRecBkgBkg", "D0,D0bar candidates signal region BkgBkg - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hDeltaEtaPtIntSidebandsMCRec", "D0,D0bar candidates sidebands - MC reco;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhiPtIntSidebandsMCRec", "D0,D0bar candidates sidebands - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2DPtIntSidebandsMCRec", "D0,D0bar candidates sidebands - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hCorrel2DVsPtSidebandsMCRecSigSig", "D0,D0bar candidates sidebands SigSig - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() - should be empty, kept for cross-check and debug + {"hCorrel2DVsPtSidebandsMCRecSigBkg", "D0,D0bar candidates sidebands SigBkg - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hCorrel2DVsPtSidebandsMCRecBkgSig", "D0,D0bar candidates sidebands BkgSig - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hCorrel2DVsPtSidebandsMCRecBkgBkg", "D0,D0bar candidates sidebands BkgBkg - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hDeltaPtDDbarSidebandsMCRec", "D0,D0bar candidates signal region - MC reco;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPtMaxMinSidebandsMCRec", "D0,D0bar candidates signal region - MC reco;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}}}; + + //pT ranges for correlation plots: the default values are those embedded in hf_cuts_d0_topik (i.e. the mass pT bins), but can be redefined via json files + Configurable> binsCorrelations{"ptBinsForCorrelations", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for correlation plots"}; + //signal and sideband region edges, to be defined via json file (initialised to empty) + Configurable> signalRegionInner{"signalRegionInner", std::vector(), "Inner values of signal region vs pT"}; + Configurable> signalRegionOuter{"signalRegionOuter", std::vector(), "Outer values of signal region vs pT"}; + Configurable> sidebandLeftInner{"sidebandLeftInner", std::vector(), "Inner values of left sideband vs pT"}; + Configurable> sidebandLeftOuter{"sidebandLeftOuter", std::vector(), "Outer values of left sideband vs pT"}; + Configurable> sidebandRightInner{"sidebandRightInner", std::vector(), "Inner values of right sideband vs pT"}; + Configurable> sidebandRightOuter{"sidebandRightOuter", std::vector(), "Outer values of right sideband vs pT"}; + + // redefinition of pT axes for THnSparse holding correlation entries + int nBinspTaxis = binsCorrelations->size() - 1; + const double* valuespTaxis = binsCorrelations->data(); + + void init(o2::framework::InitContext&) { + for (int i=2; i<=3; i++) { + registry.get("hMass2DCorrelationPairsMCRecSigSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hMass2DCorrelationPairsMCRecSigBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hMass2DCorrelationPairsMCRecBkgSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hMass2DCorrelationPairsMCRecBkgBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSignalRegionMCRecSigSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSignalRegionMCRecSigBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSignalRegionMCRecBkgSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSignalRegionMCRecBkgBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSidebandsMCRecSigSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSidebandsMCRecSigBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSidebandsMCRecBkgSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSidebandsMCRecBkgBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + } + } + + void process(aod::D0D0barPairFull const& pairEntries) + { + for (auto& pairEntry : pairEntries) { + //fill 2D invariant mass plots + switch (pairEntry.signalStatus()) { + case 0: //D0 Bkg, D0bar Bkg + registry.fill(HIST("hMass2DCorrelationPairsMCRecBkgBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + break; + case 1: //D0 Bkg, D0bar Sig + registry.fill(HIST("hMass2DCorrelationPairsMCRecBkgSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + break; + case 2: //D0 Sig, D0bar Bkg + registry.fill(HIST("hMass2DCorrelationPairsMCRecSigBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + break; + case 3: //D0 Sig, D0bar Sig + registry.fill(HIST("hMass2DCorrelationPairsMCRecSigSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + break; + default: //should not happen for MC reco + break; + } + + //check if correlation entry belongs to signal region, sidebands or is outside both, and fill correlation plots + int pTBinD0 = o2::analysis::findBin(binsCorrelations, pairEntry.ptD0()); + int pTBinD0bar = o2::analysis::findBin(binsCorrelations, pairEntry.ptD0bar()); + + if(pairEntry.mD0() > signalRegionInner->at(pTBinD0) && pairEntry.mD0() < signalRegionOuter->at(pTBinD0) && pairEntry.mD0bar() > signalRegionInner->at(pTBinD0bar) && pairEntry.mD0bar() < signalRegionOuter->at(pTBinD0bar)) { + //in signal region + registry.fill(HIST("hCorrel2DPtIntSignalRegionMCRec"), pairEntry.deltaPhi(), pairEntry.deltaEta()); + registry.fill(HIST("hDeltaEtaPtIntSignalRegionMCRec"), pairEntry.deltaPhi()); + registry.fill(HIST("hDeltaPhiPtIntSignalRegionMCRec"), pairEntry.deltaEta()); + registry.fill(HIST("hDeltaPtDDbarSignalRegionMCRec"), pairEntry.ptD0bar() - pairEntry.ptD0()); + registry.fill(HIST("hDeltaPtMaxMinSignalRegionMCRec"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); + switch (pairEntry.signalStatus()) { + case 0: //D0 Bkg, D0bar Bkg + registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecBkgBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + break; + case 1: //D0 Bkg, D0bar Sig + registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecBkgSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + break; + case 2: //D0 Sig, D0bar Bkg + registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecSigBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + break; + case 3: //D0 Sig, D0bar Sig + registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecSigSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + break; + default: //should not happen for MC reco + break; + } + } + + if((pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandLeftOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar)) || + (pairEntry.mD0() > sidebandRightInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar)) || + (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandLeftOuter->at(pTBinD0bar)) || + (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandRightInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar))) { + //in sideband region + registry.fill(HIST("hCorrel2DPtIntSidebandsMCRec"), pairEntry.deltaPhi(), pairEntry.deltaEta()); + registry.fill(HIST("hDeltaEtaPtIntSidebandsMCRec"), pairEntry.deltaPhi()); + registry.fill(HIST("hDeltaPhiPtIntSidebandsMCRec"), pairEntry.deltaEta()); + registry.fill(HIST("hDeltaPtDDbarSidebandsMCRec"), pairEntry.ptD0bar() - pairEntry.ptD0()); + registry.fill(HIST("hDeltaPtMaxMinSidebandsMCRec"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); + switch (pairEntry.signalStatus()) { + case 0: //D0 Bkg, D0bar Bkg + registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecBkgBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + break; + case 1: //D0 Bkg, D0bar Sig + registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecBkgSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + break; + case 2: //D0 Sig, D0bar Bkg + registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecSigBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + break; + case 3: //D0 Sig, D0bar Sig + registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecSigSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + break; + default: //should not happen for MC reco + break; + } + } + } //end loop + } +}; + +/// D0-D0bar correlation pair filling task, from pair tables - for MC gen-level analysis (no filter/selection, only true signal) - Ok for both USL and LS analyses +/// Works on both USL and LS analyses pair tables (and if tables are filled with quark pairs as well) +struct TaskD0D0barCorrelationMCGen { + + HistogramRegistry registry{ + "registry", + {{"hDeltaEtaPtIntMCGen", "D0,D0bar particles - MC gen;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, + {"hDeltaPhiPtIntMCGen", "D0,D0bar particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hCorrel2DPtIntMCGen", "D0,D0bar particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, + {"hCorrel2DVsPtMCGen", "D0,D0bar particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hDeltaPtDDbarMCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, + {"hDeltaPtMaxMinMCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}}}; + + //pT ranges for correlation plots: the default values are those embedded in hf_cuts_d0_topik (i.e. the mass pT bins), but can be redefined via json files + Configurable> binsCorrelations{"ptBinsForCorrelations", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for correlation plots"}; + + // redefinition of pT axes for THnSparse holding correlation entries + int nBinspTaxis = binsCorrelations->size() - 1; + const double* valuespTaxis = binsCorrelations->data(); + + void init(o2::framework::InitContext&) { + for (int i=2; i<=3; i++) { + registry.get("hCorrel2DVsPtMCGen")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + } + } + + void process(aod::D0D0barPairFull const& pairEntries) + { + for (auto& pairEntry : pairEntries) { + registry.fill(HIST("hCorrel2DVsPtMCGen"), pairEntry.deltaPhi(), pairEntry.deltaEta(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hCorrel2DPtIntMCGen"), pairEntry.deltaPhi(), pairEntry.deltaEta()); + registry.fill(HIST("hDeltaEtaPtIntMCGen"), pairEntry.deltaPhi()); + registry.fill(HIST("hDeltaPhiPtIntMCGen"), pairEntry.deltaEta()); + registry.fill(HIST("hDeltaPtDDbarMCGen"), pairEntry.ptD0bar() - pairEntry.ptD0()); + registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); + } //end loop + } +}; + +/// checks phi resolution for standard definition and sec-vtx based definition +struct TaskD0D0barCorrelationCheckPhiResolution { + + HistogramRegistry registry{ + "registry", + {{"hMass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{120, 1.5848, 2.1848}}}}, + {"hEta", "D0,D0bar candidates;candidate #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, + {"hPhiStdPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, 0., 2. * o2::constants::math::PI}, {50, 0., 50.}}}}, + {"hPhiByVtxPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, 0., 2. * o2::constants::math::PI}, {50, 0., 50.}}}}, + {"hPhiDifferenceTwoMethods", "D0,D0bar candidates;candidate #it{#Delta#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI, o2::constants::math::PI}, {50, 0., 50.}}}}, + {"hDifferenceGenPhiStdPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI, o2::constants::math::PI}, {50, 0., 50.}}}}, + {"hDifferenceGenPhiByVtxPhi", "D0,D0bar candidates;candidate #it{#varphi};#it{p}_{T}", {HistType::kTH2F, {{128, -o2::constants::math::PI, o2::constants::math::PI}, {50, 0., 50.}}}}, + {"hDeltaPhiPtIntStdPhi", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPhiPtIntByVtxPhi", "D0,D0bar candidates;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPhiVsPtStdPhi", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{36, 0., 36.}, {36, 0., 36.}, {128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, + {"hDeltaPhiVsPtByVtxPhi", "D0,D0bar candidates;#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH3F, {{36, 0., 36.}, {36, 0., 36.}, {128, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}}}; + + Configurable dSelectionFlagD0{"dSelectionFlagD0", 1, "Selection Flag for D0"}; + Configurable dSelectionFlagD0bar{"dSelectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"}; + Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; + + Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); + + void process(aod::Collision const& collision, soa::Filtered> const& candidates, aod::McParticles const& particlesMC, aod::BigTracksMC const& tracksMC) + { + for (auto& candidate1 : candidates) { + //check decay channel flag for candidate1 + if (!(candidate1.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (cutYCandMax >= 0. && std::abs(YD0(candidate1)) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && candidate1.pt() < cutPtCandMin) { + continue; + } + registry.fill(HIST("hMass"), InvMassD0(candidate1)); + registry.fill(HIST("hEta"), candidate1.eta()); + + //D-Dbar correlation dedicated section + //if it's a candidate D0, search for D0bar and evaluate correlations + if (candidate1.isSelD0() >= dSelectionFlagD0) { + double xPrimaryVertex = candidate1.index0_as().collision().posX(), yPrimaryVertex = candidate1.index0_as().collision().posY(); + double pt1 = candidate1.pt(), phi1Std = candidate1.phi(); + double phi1ByVtx = evaluatePhiByVertex(xPrimaryVertex, candidate1.xSecondaryVertex(), yPrimaryVertex, candidate1.ySecondaryVertex()); + registry.fill(HIST("hPhiStdPhi"), phi1Std, pt1); + registry.fill(HIST("hPhiByVtxPhi"), phi1ByVtx, pt1); + registry.fill(HIST("hPhiDifferenceTwoMethods"), getDeltaPhiForResolution(phi1ByVtx, phi1Std), pt1); + + //get corresponding gen-level D0, if exists, and evaluate gen-rec phi-difference with two approaches + if (std::abs(candidate1.flagMCMatchRec()) == 1 << D0ToPiK) { //ok to keep both D0 and D0bar + int indexGen = RecoDecay::getMother(particlesMC, candidate1.index0_as().mcParticle(), 421, true); //MC-gen corresponding index for MC-reco candidate + double phi1Gen = particlesMC.iteratorAt(indexGen).phi(); + registry.fill(HIST("hDifferenceGenPhiStdPhi"), getDeltaPhiForResolution(phi1Std, phi1Gen), pt1); + registry.fill(HIST("hDifferenceGenPhiByVtxPhi"), getDeltaPhiForResolution(phi1ByVtx, phi1Gen), pt1); + } + + for (auto& candidate2 : candidates) { + //check decay channel flag for candidate2 + if (!(candidate2.hfflag() & 1 << D0ToPiK)) { + continue; + } + if (candidate2.isSelD0bar() >= dSelectionFlagD0bar) { //accept only D0bar candidates + if (cutYCandMax >= 0. && std::abs(YD0(candidate2)) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && candidate2.pt() < cutPtCandMin) { + continue; + } + //Excluding self-correlations (could happen in case of reflections) + if (candidate1.mRowIndex == candidate2.mRowIndex) { + continue; + } + double pt2 = candidate2.pt(), phi2Std = candidate2.phi(); + double phi2ByVtx = evaluatePhiByVertex(xPrimaryVertex, candidate2.xSecondaryVertex(), yPrimaryVertex, candidate2.ySecondaryVertex()); + registry.fill(HIST("hDeltaPhiPtIntStdPhi"), getDeltaPhi(phi2Std, phi1Std)); + registry.fill(HIST("hDeltaPhiPtIntByVtxPhi"), getDeltaPhi(phi2ByVtx, phi1ByVtx)); + registry.fill(HIST("hDeltaPhiVsPtStdPhi"), pt1, pt2, getDeltaPhi(phi2Std, phi1Std)); + registry.fill(HIST("hDeltaPhiVsPtByVtxPhi"), pt1, pt2, getDeltaPhi(phi2ByVtx, phi1ByVtx)); + } + } // end inner loop (Dbars) + } + } //end outer loop + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{}; + //MC-based tasks + const bool doMCGen = cfgc.options().get("doMCGen"); + const bool doMCRec = cfgc.options().get("doMCRec"); + if (doMCGen) { //MC-Gen analysis + workflow.push_back(adaptAnalysisTask(cfgc)); + } else if (doMCRec) { //MC-Rec analysis + workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc)); + } else { //data analysis + workflow.push_back(adaptAnalysisTask(cfgc)); + } + return workflow; +} From 0e28ede650dbc3edf2be6ca91bcd64f11798c10d Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Tue, 30 Mar 2021 10:51:01 +0200 Subject: [PATCH 19/24] Adding definition of task switching options --- Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx | 10 ++++++++-- Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx | 6 ++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx b/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx index 73df2fb792ec2..4da99862b6668 100644 --- a/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx +++ b/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx @@ -29,8 +29,14 @@ using namespace o2::aod::hf_d0d0bar_correlation; void customize(std::vector& workflowOptions) { - ConfigParamSpec optionDoMC{"doMC", VariantType::Bool, false, {"Run MC dedicated tasks."}}; - workflowOptions.push_back(optionDoMC); + ConfigParamSpec optionDoLikeSign{"doLikeSign", VariantType::Bool, false, {"Run Like-Sign analysis."}}; + ConfigParamSpec optionDoMCccbar{"doMCccbar", VariantType::Bool, false, {"Run MC-Gen dedicated tasks."}}; + ConfigParamSpec optionDoMCGen{"doMCGen", VariantType::Bool, false, {"Run MC-Gen dedicated tasks."}}; + ConfigParamSpec optionDoMCRec{"doMCRec", VariantType::Bool, false, {"Run MC-Rec dedicated tasks."}}; + workflowOptions.push_back(optionDoLikeSign); + workflowOptions.push_back(optionDoMCccbar); + workflowOptions.push_back(optionDoMCGen); + workflowOptions.push_back(optionDoMCRec); } #include "Framework/runDataProcessing.h" diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index ee631bc0745b3..7e1100b14789d 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -34,8 +34,10 @@ using D0D0barPairFull = soa::Join; void customize(std::vector& workflowOptions) { - ConfigParamSpec optionDoMC{"doMC", VariantType::Bool, false, {"Run MC dedicated tasks."}}; - workflowOptions.push_back(optionDoMC); + ConfigParamSpec optionDoMCGen{"doMCGen", VariantType::Bool, false, {"Run MC-Gen dedicated tasks."}}; + ConfigParamSpec optionDoMCRec{"doMCRec", VariantType::Bool, false, {"Run MC-Rec dedicated tasks."}}; + workflowOptions.push_back(optionDoMCGen); + workflowOptions.push_back(optionDoMCRec); } #include "Framework/runDataProcessing.h" From 8c4992f8842090640d25560d017680450c98eba4 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Wed, 31 Mar 2021 16:03:02 +0200 Subject: [PATCH 20/24] Clang fixes and task name updates --- Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx | 112 ++++++++++-------- .../Tasks/PWGHF/taskD0D0barCorrelation.cxx | 77 ++++++------ 2 files changed, 100 insertions(+), 89 deletions(-) diff --git a/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx b/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx index 4da99862b6668..bbcbf1d2685b1 100644 --- a/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx +++ b/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx @@ -59,7 +59,7 @@ const double epsilon = 1E-5; /// D0-D0bar correlation pair builder - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) struct D0D0barCorrelator { Produces entryD0D0barPair; - Produces entryD0D0barRecoInfo; + Produces entryD0D0barRecoInfo; HistogramRegistry registry{ "registry", @@ -79,10 +79,11 @@ struct D0D0barCorrelator { Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for candidate mass plots"}; - void init(o2::framework::InitContext&) { + void init(o2::framework::InitContext&) + { registry.add("hMass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hMassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hMassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hMassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hMassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); } Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); @@ -136,7 +137,7 @@ struct D0D0barCorrelator { if (candidate1.mRowIndex == candidate2.mRowIndex) { continue; } - entryD0D0barPair(getDeltaPhi(candidate2.phi(),candidate1.phi()), + entryD0D0barPair(getDeltaPhi(candidate2.phi(), candidate1.phi()), candidate2.eta() - candidate1.eta(), candidate1.pt(), candidate2.pt()); @@ -145,7 +146,7 @@ struct D0D0barCorrelator { 0); double etaCut = 0.; double ptCut = 0.; - do { //fill pairs vs etaCut plot + do { //fill pairs vs etaCut plot ptCut = 0.; etaCut += incrementEtaCut; do { //fill pairs vs etaCut plot @@ -153,7 +154,7 @@ struct D0D0barCorrelator { registry.fill(HIST("hDDbarVsEtaCut"), etaCut - epsilon, ptCut + epsilon); ptCut += incrementPtThreshold; } while (ptCut < ptThresholdForMaxEtaCut - epsilon); - } while (etaCut < maxEtaCut - epsilon); + } while (etaCut < maxEtaCut - epsilon); } //note: candidates selected as both D0 and D0bar are used, and considered in both situation (but not auto-correlated): reflections could play a relevant role. //another, more restrictive, option, could be to consider only candidates selected with a single option (D0 xor D0bar) @@ -169,7 +170,7 @@ struct D0D0barCorrelator { struct D0D0barCorrelatorMCRec { Produces entryD0D0barPair; - Produces entryD0D0barRecoInfo; + Produces entryD0D0barRecoInfo; HistogramRegistry registry{ "registry", @@ -189,9 +190,10 @@ struct D0D0barCorrelatorMCRec { Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for candidate mass plots"}; - void init(o2::framework::InitContext&) { + void init(o2::framework::InitContext&) + { registry.add("hMassD0MCRec", "D0,D0bar candidates - MC reco;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hMassD0barMCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hMassD0barMCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); } Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); @@ -227,7 +229,7 @@ struct D0D0barCorrelatorMCRec { registry.fill(HIST("hPhiMCRec"), candidate1.phi()); registry.fill(HIST("hYMCRec"), YD0(candidate1)); registry.fill(HIST("hSelectionStatusMCRec"), candidate1.isSelD0() + (candidate1.isSelD0bar() * 2)); - } + } //D-Dbar correlation dedicated section //if the candidate is selected ad D0, search for D0bar and evaluate correlations @@ -265,7 +267,7 @@ struct D0D0barCorrelatorMCRec { if (flagD0barSignal) { pairSignalStatus += 1; } - entryD0D0barPair(getDeltaPhi(candidate2.phi(),candidate1.phi()), + entryD0D0barPair(getDeltaPhi(candidate2.phi(), candidate1.phi()), candidate2.eta() - candidate1.eta(), candidate1.pt(), candidate2.pt()); @@ -282,10 +284,10 @@ struct D0D0barCorrelatorMCRec { registry.fill(HIST("hDDbarVsEtaCut"), etaCut - epsilon, ptCut + epsilon); ptCut += incrementPtThreshold; } while (ptCut < ptThresholdForMaxEtaCut - epsilon); - } while (etaCut < maxEtaCut - epsilon); + } while (etaCut < maxEtaCut - epsilon); } // end inner loop (Dbars) - } //end outer loop + } //end outer loop } }; @@ -308,7 +310,8 @@ struct D0D0barCorrelatorMCGen { Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for trigger counters"}; - void init(o2::framework::InitContext&) { + void init(o2::framework::InitContext&) + { registry.add("hcountD0triggersMCGen", "D0 trigger particles - MC gen;;N of trigger D0", {HistType::kTH2F, {{1, -0.5, 0.5}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); } @@ -334,7 +337,7 @@ struct D0D0barCorrelatorMCGen { //D-Dbar correlation dedicated section //if it's a D0 particle, search for D0bar and evaluate correlations - if (particle1.pdgCode() == 421) { //just checking the particle PDG, not the decay channel (differently from Reco: you have a BR factor btw such levels!) + if (particle1.pdgCode() == 421) { //just checking the particle PDG, not the decay channel (differently from Reco: you have a BR factor btw such levels!) registry.fill(HIST("hcountD0triggersMCGen"), 0, particle1.pt()); //to count trigger D0 (for normalisation) for (auto& particle2 : particlesMC) { if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle2.px(), particle2.py(), particle2.pz()}, RecoDecay::getMassPDG(particle2.pdgCode()))) > cutYCandMax) { @@ -344,7 +347,7 @@ struct D0D0barCorrelatorMCGen { continue; } if (particle2.pdgCode() == -421) { - entryD0D0barPair(getDeltaPhi(particle2.phi(),particle1.phi()), + entryD0D0barPair(getDeltaPhi(particle2.phi(), particle1.phi()), particle2.eta() - particle1.eta(), particle1.pt(), particle2.pt()); @@ -358,7 +361,7 @@ struct D0D0barCorrelatorMCGen { registry.fill(HIST("hDDbarVsEtaCut"), etaCut - epsilon, ptCut + epsilon); ptCut += incrementPtThreshold; } while (ptCut < ptThresholdForMaxEtaCut - epsilon); - } while (etaCut < maxEtaCut - epsilon); + } while (etaCut < maxEtaCut - epsilon); } // end D0bar check } //end inner loop } //end D0 check @@ -373,7 +376,7 @@ struct D0D0barCorrelatorMCGen { struct D0D0barCorrelatorLS { Produces entryD0D0barPair; - Produces entryD0D0barRecoInfo; + Produces entryD0D0barRecoInfo; HistogramRegistry registry{ "registry", @@ -392,10 +395,11 @@ struct D0D0barCorrelatorLS { Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for candidate mass plots"}; - void init(o2::framework::InitContext&) { + void init(o2::framework::InitContext&) + { registry.add("hMass", "D0,D0bar candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hMassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hMassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hMassD0", "D0,D0bar candidates;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hMassD0bar", "D0,D0bar candidates;inv. mass D0bar only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); } Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); @@ -451,13 +455,13 @@ struct D0D0barCorrelatorLS { if (candidate1.mRowIndex == candidate2.mRowIndex) { continue; } - entryD0D0barPair(getDeltaPhi(candidate2.phi(),candidate1.phi()), - candidate2.eta() - candidate1.eta(), - candidate1.pt(), - candidate2.pt()); - entryD0D0barRecoInfo(InvMassD0(candidate1), - InvMassD0bar(candidate2), - 0); + entryD0D0barPair(getDeltaPhi(candidate2.phi(), candidate1.phi()), + candidate2.eta() - candidate1.eta(), + candidate1.pt(), + candidate2.pt()); + entryD0D0barRecoInfo(InvMassD0(candidate1), + InvMassD0bar(candidate2), + 0); } //note: candidates selected as both D0 and D0bar are used, and considered in both situation (but not auto-correlated): reflections could play a relevant role. //another, more restrictive, option, could be to consider only candidates selected with a single option (D0 xor D0bar) @@ -472,7 +476,7 @@ struct D0D0barCorrelatorLS { struct D0D0barCorrelatorMCRecLS { Produces entryD0D0barPair; - Produces entryD0D0barRecoInfo; + Produces entryD0D0barRecoInfo; HistogramRegistry registry{ "registry", @@ -491,9 +495,10 @@ struct D0D0barCorrelatorMCRecLS { Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for candidate mass plots"}; - void init(o2::framework::InitContext&) { + void init(o2::framework::InitContext&) + { registry.add("hMassD0MCRec", "D0,D0bar candidates - MC reco;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hMassD0barMCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hMassD0barMCRec", "D0,D0bar candidates - MC reco;inv. mass D0 only (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); } Filter filterSelectCandidates = (aod::hf_selcandidate_d0::isSelD0 >= dSelectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= dSelectionFlagD0bar); @@ -549,7 +554,7 @@ struct D0D0barCorrelatorMCRecLS { if (candidate1.mRowIndex == candidate2.mRowIndex) { continue; } - entryD0D0barPair(getDeltaPhi(candidate2.phi(),candidate1.phi()), + entryD0D0barPair(getDeltaPhi(candidate2.phi(), candidate1.phi()), candidate2.eta() - candidate1.eta(), candidate1.pt(), candidate2.pt()); @@ -583,7 +588,8 @@ struct D0D0barCorrelatorMCGenLS { Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for trigger counters"}; - void init(o2::framework::InitContext&) { + void init(o2::framework::InitContext&) + { registry.add("hcountD0triggersMCGen", "D0 trigger particles - MC gen;;N of trigger D0", {HistType::kTH2F, {{1, -0.5, 0.5}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); } @@ -624,7 +630,7 @@ struct D0D0barCorrelatorMCGenLS { if (particle1.mRowIndex == particle2.mRowIndex) { continue; } - entryD0D0barPair(getDeltaPhi(particle2.phi(),particle1.phi()), + entryD0D0barPair(getDeltaPhi(particle2.phi(), particle1.phi()), particle2.eta() - particle1.eta(), particle1.pt(), particle2.pt()); @@ -654,7 +660,8 @@ struct CCbarCorrelatorMCGen { Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for trigger counters"}; - void init(o2::framework::InitContext&) { + void init(o2::framework::InitContext&) + { registry.add("hcountD0triggersMCGen", "c trigger particles - MC gen;;N of trigger D0", {HistType::kTH2F, {{1, -0.5, 0.5}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); } @@ -704,7 +711,7 @@ struct CCbarCorrelatorMCGen { if (particlesMC.iteratorAt(particle2.mother0()).pdgCode() == -4) { continue; } - entryD0D0barPair(getDeltaPhi(particle2.phi(),particle1.phi()), + entryD0D0barPair(getDeltaPhi(particle2.phi(), particle1.phi()), particle2.eta() - particle1.eta(), particle1.pt(), particle2.pt()); @@ -735,7 +742,8 @@ struct CCbarCorrelatorMCGenLS { Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; Configurable> bins{"ptBinsForMass", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for trigger counters"}; - void init(o2::framework::InitContext&) { + void init(o2::framework::InitContext&) + { registry.add("hcountD0triggersMCGen", "c trigger particles - MC gen;;N of trigger D0", {HistType::kTH2F, {{1, -0.5, 0.5}, {(std::vector)bins, "#it{p}_{T} (GeV/#it{c})"}}}); } @@ -768,7 +776,7 @@ struct CCbarCorrelatorMCGenLS { counterccbar++; //count if c or cbar don't come from themselves during fragmentation (after kinematic selection) //c-cbar correlation dedicated section - double ptParticle1 = particle1.pt(); //trigger particle is the largest pT one + double ptParticle1 = particle1.pt(); //trigger particle is the largest pT one registry.fill(HIST("hcountD0triggersMCGen"), 0, particle1.pt()); //to count trigger c quark (for normalisation) for (auto& particle2 : particlesMC) { @@ -783,13 +791,13 @@ struct CCbarCorrelatorMCGenLS { if (particlesMC.iteratorAt(particle2.mother0()).pdgCode() == particle2.pdgCode()) { continue; } - entryD0D0barPair(getDeltaPhi(particle2.phi(),particle1.phi()), + entryD0D0barPair(getDeltaPhi(particle2.phi(), particle1.phi()), particle2.eta() - particle1.eta(), particle1.pt(), particle2.pt()); } // end outer if (check PDG associate) } // end inner loop - } //end outer loop + } //end outer loop registry.fill(HIST("hcountCCbarPerEvent"), counterccbar); registry.fill(HIST("hcountCCbarPerEventPreEtaCut"), counterccbarPreEtasel); } @@ -801,26 +809,26 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) const bool doMCccbar = cfgc.options().get("doMCccbar"); const bool doMCGen = cfgc.options().get("doMCGen"); const bool doMCRec = cfgc.options().get("doMCRec"); - const bool doLikeSign = cfgc.options().get("doLikeSign"); + const bool doLikeSign = cfgc.options().get("doLikeSign"); if (!doLikeSign) { //unlike-sign analyses - if (doMCGen) { //MC-Gen analysis - workflow.push_back(adaptAnalysisTask(cfgc)); + if (doMCGen) { //MC-Gen analysis + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"d0d0bar-correlator-mc-gen"})); } else if (doMCRec) { //MC-Reco analysis - workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"d0d0bar-correlator-mc-rec"})); } else if (doMCccbar) { //MC-Reco analysis - workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"ccbar-correlator-mc-gen"})); } else { //data analysis - workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"d0d0bar-correlator"})); } - } else { //ike-sign analyses + } else { //ike-sign analyses if (doMCGen) { //MC-Gen analysis - workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"d0d0bar-correlator-mc-gen-ls"})); } else if (doMCRec) { //MC-Reco analysis - workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"d0d0bar-correlator-mc-rec-ls"})); } else if (doMCccbar) { //MC-Reco analysis - workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"ccbar-correlator-mc-gen-ls"})); } else { //data analysis - workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"d0d0bar-correlator-ls"})); } } diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index 7e1100b14789d..60b4ee9595720 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -107,11 +107,12 @@ struct TaskD0D0barCorrelation { int nBinspTaxis = binsCorrelations->size() - 1; const double* valuespTaxis = binsCorrelations->data(); - void init(o2::framework::InitContext&) { - for (int i=2; i<=3; i++) { + void init(o2::framework::InitContext&) + { + for (int i = 2; i <= 3; i++) { registry.get("hMass2DCorrelationPairs")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); registry.get("hCorrel2DVsPtSignalRegion")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSidebands")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSidebands")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); } } @@ -120,12 +121,12 @@ struct TaskD0D0barCorrelation { for (auto& pairEntry : pairEntries) { //fill 2D invariant mass plots registry.fill(HIST("hMass2DCorrelationPairs"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); - + //check if correlation entry belongs to signal region, sidebands or is outside both, and fill correlation plots int pTBinD0 = o2::analysis::findBin(binsCorrelations, pairEntry.ptD0()); int pTBinD0bar = o2::analysis::findBin(binsCorrelations, pairEntry.ptD0bar()); - if(pairEntry.mD0() > signalRegionInner->at(pTBinD0) && pairEntry.mD0() < signalRegionOuter->at(pTBinD0) && pairEntry.mD0bar() > signalRegionInner->at(pTBinD0bar) && pairEntry.mD0bar() < signalRegionOuter->at(pTBinD0bar)) { + if (pairEntry.mD0() > signalRegionInner->at(pTBinD0) && pairEntry.mD0() < signalRegionOuter->at(pTBinD0) && pairEntry.mD0bar() > signalRegionInner->at(pTBinD0bar) && pairEntry.mD0bar() < signalRegionOuter->at(pTBinD0bar)) { //in signal region registry.fill(HIST("hCorrel2DVsPtSignalRegion"), pairEntry.deltaPhi(), pairEntry.deltaEta(), pairEntry.ptD0(), pairEntry.ptD0bar()); registry.fill(HIST("hCorrel2DPtIntSignalRegion"), pairEntry.deltaPhi(), pairEntry.deltaEta()); @@ -135,10 +136,10 @@ struct TaskD0D0barCorrelation { registry.fill(HIST("hDeltaPtMaxMinSignalRegion"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); } - if((pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandLeftOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar)) || - (pairEntry.mD0() > sidebandRightInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar)) || - (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandLeftOuter->at(pTBinD0bar)) || - (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandRightInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar))) { + if ((pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandLeftOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar)) || + (pairEntry.mD0() > sidebandRightInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar)) || + (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandLeftOuter->at(pTBinD0bar)) || + (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandRightInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar))) { //in sideband region registry.fill(HIST("hCorrel2DVsPtSidebands"), pairEntry.deltaPhi(), pairEntry.deltaEta(), pairEntry.ptD0(), pairEntry.ptD0bar()); registry.fill(HIST("hCorrel2DPtIntSidebands"), pairEntry.deltaPhi(), pairEntry.deltaEta()); @@ -170,14 +171,14 @@ struct TaskD0D0barCorrelationMCRec { {"hCorrel2DVsPtSignalRegionMCRecSigSig", "D0,D0bar candidates signal region SigSig - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() {"hCorrel2DVsPtSignalRegionMCRecSigBkg", "D0,D0bar candidates signal region SigBkg - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() {"hCorrel2DVsPtSignalRegionMCRecBkgSig", "D0,D0bar candidates signal region BkgSig - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() - {"hCorrel2DVsPtSignalRegionMCRecBkgBkg", "D0,D0bar candidates signal region BkgBkg - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hCorrel2DVsPtSignalRegionMCRecBkgBkg", "D0,D0bar candidates signal region BkgBkg - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() {"hDeltaEtaPtIntSidebandsMCRec", "D0,D0bar candidates sidebands - MC reco;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, {"hDeltaPhiPtIntSidebandsMCRec", "D0,D0bar candidates sidebands - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, {"hCorrel2DPtIntSidebandsMCRec", "D0,D0bar candidates sidebands - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, {"hCorrel2DVsPtSidebandsMCRecSigSig", "D0,D0bar candidates sidebands SigSig - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() - should be empty, kept for cross-check and debug {"hCorrel2DVsPtSidebandsMCRecSigBkg", "D0,D0bar candidates sidebands SigBkg - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() {"hCorrel2DVsPtSidebandsMCRecBkgSig", "D0,D0bar candidates sidebands BkgSig - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() - {"hCorrel2DVsPtSidebandsMCRecBkgBkg", "D0,D0bar candidates sidebands BkgBkg - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hCorrel2DVsPtSidebandsMCRecBkgBkg", "D0,D0bar candidates sidebands BkgBkg - MC reco;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() {"hDeltaPtDDbarSidebandsMCRec", "D0,D0bar candidates signal region - MC reco;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, {"hDeltaPtMaxMinSidebandsMCRec", "D0,D0bar candidates signal region - MC reco;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}}}; @@ -195,8 +196,9 @@ struct TaskD0D0barCorrelationMCRec { int nBinspTaxis = binsCorrelations->size() - 1; const double* valuespTaxis = binsCorrelations->data(); - void init(o2::framework::InitContext&) { - for (int i=2; i<=3; i++) { + void init(o2::framework::InitContext&) + { + for (int i = 2; i <= 3; i++) { registry.get("hMass2DCorrelationPairsMCRecSigSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); registry.get("hMass2DCorrelationPairsMCRecSigBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); registry.get("hMass2DCorrelationPairsMCRecBkgSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); @@ -206,9 +208,9 @@ struct TaskD0D0barCorrelationMCRec { registry.get("hCorrel2DVsPtSignalRegionMCRecBkgSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); registry.get("hCorrel2DVsPtSignalRegionMCRecBkgBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); registry.get("hCorrel2DVsPtSidebandsMCRecSigSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSidebandsMCRecSigBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSidebandsMCRecBkgSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSidebandsMCRecBkgBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSidebandsMCRecSigBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSidebandsMCRecBkgSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get("hCorrel2DVsPtSidebandsMCRecBkgBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); } } @@ -228,22 +230,22 @@ struct TaskD0D0barCorrelationMCRec { break; case 3: //D0 Sig, D0bar Sig registry.fill(HIST("hMass2DCorrelationPairsMCRecSigSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); - break; + break; default: //should not happen for MC reco - break; + break; } - + //check if correlation entry belongs to signal region, sidebands or is outside both, and fill correlation plots int pTBinD0 = o2::analysis::findBin(binsCorrelations, pairEntry.ptD0()); int pTBinD0bar = o2::analysis::findBin(binsCorrelations, pairEntry.ptD0bar()); - if(pairEntry.mD0() > signalRegionInner->at(pTBinD0) && pairEntry.mD0() < signalRegionOuter->at(pTBinD0) && pairEntry.mD0bar() > signalRegionInner->at(pTBinD0bar) && pairEntry.mD0bar() < signalRegionOuter->at(pTBinD0bar)) { + if (pairEntry.mD0() > signalRegionInner->at(pTBinD0) && pairEntry.mD0() < signalRegionOuter->at(pTBinD0) && pairEntry.mD0bar() > signalRegionInner->at(pTBinD0bar) && pairEntry.mD0bar() < signalRegionOuter->at(pTBinD0bar)) { //in signal region registry.fill(HIST("hCorrel2DPtIntSignalRegionMCRec"), pairEntry.deltaPhi(), pairEntry.deltaEta()); registry.fill(HIST("hDeltaEtaPtIntSignalRegionMCRec"), pairEntry.deltaPhi()); registry.fill(HIST("hDeltaPhiPtIntSignalRegionMCRec"), pairEntry.deltaEta()); registry.fill(HIST("hDeltaPtDDbarSignalRegionMCRec"), pairEntry.ptD0bar() - pairEntry.ptD0()); - registry.fill(HIST("hDeltaPtMaxMinSignalRegionMCRec"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); + registry.fill(HIST("hDeltaPtMaxMinSignalRegionMCRec"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); switch (pairEntry.signalStatus()) { case 0: //D0 Bkg, D0bar Bkg registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecBkgBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); @@ -256,22 +258,22 @@ struct TaskD0D0barCorrelationMCRec { break; case 3: //D0 Sig, D0bar Sig registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecSigSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); - break; + break; default: //should not happen for MC reco - break; + break; } } - if((pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandLeftOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar)) || - (pairEntry.mD0() > sidebandRightInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar)) || - (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandLeftOuter->at(pTBinD0bar)) || - (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandRightInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar))) { + if ((pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandLeftOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar)) || + (pairEntry.mD0() > sidebandRightInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar)) || + (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandLeftOuter->at(pTBinD0bar)) || + (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandRightInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar))) { //in sideband region registry.fill(HIST("hCorrel2DPtIntSidebandsMCRec"), pairEntry.deltaPhi(), pairEntry.deltaEta()); registry.fill(HIST("hDeltaEtaPtIntSidebandsMCRec"), pairEntry.deltaPhi()); registry.fill(HIST("hDeltaPhiPtIntSidebandsMCRec"), pairEntry.deltaEta()); registry.fill(HIST("hDeltaPtDDbarSidebandsMCRec"), pairEntry.ptD0bar() - pairEntry.ptD0()); - registry.fill(HIST("hDeltaPtMaxMinSidebandsMCRec"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); + registry.fill(HIST("hDeltaPtMaxMinSidebandsMCRec"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); switch (pairEntry.signalStatus()) { case 0: //D0 Bkg, D0bar Bkg registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecBkgBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); @@ -284,9 +286,9 @@ struct TaskD0D0barCorrelationMCRec { break; case 3: //D0 Sig, D0bar Sig registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecSigSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); - break; + break; default: //should not happen for MC reco - break; + break; } } } //end loop @@ -302,7 +304,7 @@ struct TaskD0D0barCorrelationMCGen { {{"hDeltaEtaPtIntMCGen", "D0,D0bar particles - MC gen;#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH1F, {{200, -10., 10.}}}}, {"hDeltaPhiPtIntMCGen", "D0,D0bar particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};entries", {HistType::kTH1F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}}}}, {"hCorrel2DPtIntMCGen", "D0,D0bar particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};entries", {HistType::kTH2F, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {200, -10., 10.}}}}, - {"hCorrel2DVsPtMCGen", "D0,D0bar particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() + {"hCorrel2DVsPtMCGen", "D0,D0bar particles - MC gen;#it{#varphi}^{D0bar}-#it{#varphi}^{D0};#it{#eta}^{D0bar}-#it{#eta}^{D0};#it{p}_{T}^{D0};#it{p}_{T}^{D0bar};entries", {HistType::kTHnSparseD, {{32, -o2::constants::math::PI / 2., 3. * o2::constants::math::PI / 2.}, {120, -6., 6.}, {10, 0., 10.}, {10, 0., 10.}}}}, //note: axes 3 and 4 (the pT) are updated in the init() {"hDeltaPtDDbarMCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{D0bar}-#it{p}_{T}^{D0};entries", {HistType::kTH1F, {{144, -36., 36.}}}}, {"hDeltaPtMaxMinMCGen", "D0,D0bar particles - MC gen;#it{p}_{T}^{max}-#it{p}_{T}^{min};entries", {HistType::kTH1F, {{72, 0., 36.}}}}}}; @@ -313,8 +315,9 @@ struct TaskD0D0barCorrelationMCGen { int nBinspTaxis = binsCorrelations->size() - 1; const double* valuespTaxis = binsCorrelations->data(); - void init(o2::framework::InitContext&) { - for (int i=2; i<=3; i++) { + void init(o2::framework::InitContext&) + { + for (int i = 2; i <= 3; i++) { registry.get("hCorrel2DVsPtMCGen")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); } } @@ -426,12 +429,12 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) const bool doMCGen = cfgc.options().get("doMCGen"); const bool doMCRec = cfgc.options().get("doMCRec"); if (doMCGen) { //MC-Gen analysis - workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"task-d0d0bar-correlation"})); } else if (doMCRec) { //MC-Rec analysis - workflow.push_back(adaptAnalysisTask(cfgc)); - workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"task-d0d0bar-correlation-mc-rec"})); + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"task-d0d0bar-correlation-check-phi-resolution"})); } else { //data analysis - workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"task-d0d0bar-correlation-mc-gen"})); } return workflow; } From 47559b1f99378bced2712dcc0d3d7f2d42d3f000 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Thu, 15 Apr 2021 09:22:00 +0200 Subject: [PATCH 21/24] Major update to D0-D0bar correlation code, split into correlators+analysis tasks --- .../include/AnalysisCore/HFSelectorCuts.h | 221 ++++++++++++++++-- Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx | 138 ++++++----- .../Tasks/PWGHF/taskD0D0barCorrelation.cxx | 191 +++++++++------ 3 files changed, 392 insertions(+), 158 deletions(-) diff --git a/Analysis/Core/include/AnalysisCore/HFSelectorCuts.h b/Analysis/Core/include/AnalysisCore/HFSelectorCuts.h index a39e846926067..4bc1ded308ffc 100644 --- a/Analysis/Core/include/AnalysisCore/HFSelectorCuts.h +++ b/Analysis/Core/include/AnalysisCore/HFSelectorCuts.h @@ -19,7 +19,11 @@ namespace pdg { enum code { kD0 = 421, - kD0bar = -421 + kD0bar = -421, + kDPlus = 411, + kLambdaCPlus = 4122, + kXiCPlus = 4232, + kJpsi = 443 }; } @@ -33,24 +37,7 @@ int findBin(o2::framework::Configurable> const& bins, T2 value) if (value >= bins->back()) { return -1; } - int step; - int bin = 0; - int count = bins->size(); - - while (count > 0) { - step = count / 2; - bin += step; - if (bins->operator[](bin) <= value) { - count -= step + 1; - } else { - bin -= step; - count = step; - } - } - if (bin == bins->size()) { - bin = 0; - } - return bin - 1; + return std::distance(bins->begin(), std::upper_bound(bins->begin(), bins->end(), value)) - 1; } // namespace per channel @@ -147,5 +134,201 @@ static const std::vector pTBinLabels = { // column labels static const std::vector cutVarLabels = {"m", "DCA", "cos theta*", "pT K", "pT Pi", "d0K", "d0pi", "d0d0", "cos pointing angle", "cos pointing angle xy", "normalized decay length XY"}; } // namespace hf_cuts_d0_topik + +namespace hf_cuts_lc_topkpi +{ +static constexpr int npTBins = 10; +static constexpr int nCutVars = 8; +// default values for the pT bin edges (can be used to configure histogram axis) +// offset by 1 from the bin numbers in cuts array +constexpr double pTBins[npTBins + 1] = { + 0., + 1., + 2., + 3., + 4., + 5., + 6., + 8., + 12., + 24., + 36.}; +auto pTBins_v = std::vector{pTBins, pTBins + npTBins + 1}; + +// default values for the cuts +constexpr double cuts[npTBins][nCutVars] = {{0.400, 0.4, 0.4, 0.4, 0.05, 0.09, 0.005, 0.}, /* pt<1 */ + {0.400, 0.4, 0.4, 0.4, 0.05, 0.09, 0.005, 0.}, /* 1 pTBinLabels = { + "pT bin 0", + "pT bin 1", + "pT bin 2", + "pT bin 3", + "pT bin 4", + "pT bin 5", + "pT bin 6", + "pT bin 7", + "pT bin 8", + "pT bin 9"}; + +// column labels +static const std::vector cutVarLabels = {"m", "pT p", "pT K", "pT Pi", "DCA", "vertex sigma", "decay length", "cos pointing angle"}; +} // namespace hf_cuts_lc_topkpi + +namespace hf_cuts_dplus_topikpi +{ +static const int npTBins = 12; +static const int nCutVars = 8; +// default values for the pT bin edges (can be used to configure histogram axis) +// offset by 1 from the bin numbers in cuts array +constexpr double pTBins[npTBins + 1] = { + 1., + 2., + 3., + 4., + 5., + 6., + 7., + 8., + 10., + 12., + 16., + 24., + 36.}; +auto pTBins_v = std::vector{pTBins, pTBins + npTBins + 1}; +//selections from pp at 5 TeV 2017 analysis https://alice-notes.web.cern.ch/node/808 +//variables: deltaInvMass ptPi ptK DecayLength NormalizedDecayLengthXY CosP CosPXY MaxNormalisedDeltaIP +constexpr double cuts[npTBins][nCutVars] = {{0.2, 0.3, 0.3, 0.07, 6., 0.96, 0.985, 2.5}, /* 1 pTBinLabels = { + "pT bin 0", + "pT bin 1", + "pT bin 2", + "pT bin 3", + "pT bin 4", + "pT bin 5", + "pT bin 6", + "pT bin 7", + "pT bin 8", + "pT bin 9", + "pT bin 10", + "pT bin 11"}; + +// column labels +static const std::vector cutVarLabels = {"deltaM", "pT Pi", "pT K", "decay length", "normalized decay length XY", "cos pointing angle", "cos pointing angle XY", "max normalized deltaIP"}; +} // namespace hf_cuts_dplus_topikpi +namespace hf_cuts_xic_topkpi +{ +static const int npTBins = 10; +static const int nCutVars = 8; +// default values for the pT bin edges (can be used to configure histogram axis) +// offset by 1 from the bin numbers in cuts array +constexpr double pTBins[npTBins + 1] = { + 0., + 1., + 2., + 3., + 4., + 5., + 6., + 8., + 12., + 24., + 36.}; +auto pTBins_v = std::vector{pTBins, pTBins + npTBins + 1}; +// m ptp ptk ptpi DCA sigmavtx dlenght cosp +constexpr double cuts[npTBins][nCutVars] = {{0.400, 0.4, 0.4, 0.4, 0.05, 0.09, 0.005, 0.}, /* pt<1 */ + {0.400, 0.4, 0.4, 0.4, 0.05, 0.09, 0.005, 0.}, /* 1 pTBinLabels = { + "pT bin 0", + "pT bin 1", + "pT bin 2", + "pT bin 3", + "pT bin 4", + "pT bin 5", + "pT bin 6", + "pT bin 7", + "pT bin 8", + "pT bin 9"}; + +// column labels +static const std::vector cutVarLabels = {"m", "pT p", "pT K", "pT Pi", "DCA", "vertex sigma", "decay length", "cos pointing angle"}; +} // namespace hf_cuts_xic_topkpi + +namespace hf_cuts_jpsi_toee +{ +static constexpr int npTBins = 9; +static constexpr int nCutVars = 4; +// default values for the pT bin edges (can be used to configure histogram axis) +// offset by 1 from the bin numbers in cuts array +constexpr double pTBins[npTBins + 1] = { + 0, + 0.5, + 1.0, + 2.0, + 3.0, + 4.0, + 5.0, + 7.0, + 10.0, + 15.0, +}; +auto pTBins_v = std::vector{pTBins, pTBins + npTBins + 1}; + +// default values for the cuts +constexpr double cuts[npTBins][nCutVars] = {{0.5, 0.2, 0.4, 1}, /* 0 pTBinLabels = { + "pT bin 0", + "pT bin 1", + "pT bin 2", + "pT bin 3", + "pT bin 4", + "pT bin 5", + "pT bin 6", + "pT bin 7", + "pT bin 8"}; +// column labels +static const std::vector cutVarLabels = {"m", "DCA_xy", "DCA_z", "pT El"}; +} // namespace hf_cuts_jpsi_toee } // namespace o2::analysis #endif diff --git a/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx b/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx index bbcbf1d2685b1..6ea037906b20e 100644 --- a/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx +++ b/Analysis/Tasks/PWGHF/D0D0barCorrelator.cxx @@ -259,6 +259,10 @@ struct D0D0barCorrelatorMCRec { if (cutPtCandMin >= 0. && std::abs(candidate2.pt()) < cutPtCandMin) { continue; } + //Excluding trigger self-correlations (possible in case of both mass hypotheses accepted) + if (candidate1.mRowIndex == candidate2.mRowIndex) { + continue; + } //choice of options (D0/D0bar signal/bkg) int pairSignalStatus = 0; //0 = bkg/bkg, 1 = bkg/sig, 2 = sig/bkg, 3 = sig/sig if (flagD0Signal) { @@ -303,7 +307,7 @@ struct D0D0barCorrelatorMCGen { {"hEtaMCGen", "D0,D0bar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hPhiMCGen", "D0,D0bar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, {"hYMCGen", "D0,D0bar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hcountD0D0barPerEvent", "D0,D0bar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 10.}}}}, + {"hcountD0D0barPerEvent", "D0,D0bar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 20.}}}}, {"hDDbarVsEtaCut", "D0,D0bar pairs vs #eta cut;#eta_{max};entries", {HistType::kTH2F, {{(int)(maxEtaCut / incrementEtaCut), 0., maxEtaCut}, {(int)(ptThresholdForMaxEtaCut / incrementPtThreshold), 0., ptThresholdForMaxEtaCut}}}}}}; Configurable cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"}; @@ -321,51 +325,52 @@ struct D0D0barCorrelatorMCGen { registry.fill(HIST("hMCEvtCount"), 0); //MC gen level for (auto& particle1 : particlesMC) { + //check if the particle is D0 or D0bar (for general plot filling and selection, so both cases are fine) - NOTE: decay channel is not probed! + if (std::abs(particle1.pdgCode()) != 421) { + continue; + } if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))) > cutYCandMax) { continue; } if (cutPtCandMin >= 0. && std::abs(particle1.pt()) < cutPtCandMin) { continue; } - //just checking if the particle is D0 or D0bar, for now - if (std::abs(particle1.pdgCode()) == 421) { - registry.fill(HIST("hPtCandMCGen"), particle1.pt()); - registry.fill(HIST("hEtaMCGen"), particle1.eta()); - registry.fill(HIST("hPhiMCGen"), particle1.phi()); - registry.fill(HIST("hYMCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); - counterD0D0bar++; + registry.fill(HIST("hPtCandMCGen"), particle1.pt()); + registry.fill(HIST("hEtaMCGen"), particle1.eta()); + registry.fill(HIST("hPhiMCGen"), particle1.phi()); + registry.fill(HIST("hYMCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); + counterD0D0bar++; - //D-Dbar correlation dedicated section - //if it's a D0 particle, search for D0bar and evaluate correlations - if (particle1.pdgCode() == 421) { //just checking the particle PDG, not the decay channel (differently from Reco: you have a BR factor btw such levels!) - registry.fill(HIST("hcountD0triggersMCGen"), 0, particle1.pt()); //to count trigger D0 (for normalisation) - for (auto& particle2 : particlesMC) { + //D-Dbar correlation dedicated section + //if it's a D0 particle, search for D0bar and evaluate correlations + if (particle1.pdgCode() == 421) { //just checking the particle PDG, not the decay channel (differently from Reco: you have a BR factor btw such levels!) + registry.fill(HIST("hcountD0triggersMCGen"), 0, particle1.pt()); //to count trigger D0 (for normalisation) + for (auto& particle2 : particlesMC) { + if (particle2.pdgCode() == -421) { if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle2.px(), particle2.py(), particle2.pz()}, RecoDecay::getMassPDG(particle2.pdgCode()))) > cutYCandMax) { continue; } if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) { continue; } - if (particle2.pdgCode() == -421) { - entryD0D0barPair(getDeltaPhi(particle2.phi(), particle1.phi()), - particle2.eta() - particle1.eta(), - particle1.pt(), - particle2.pt()); - double etaCut = 0.; - double ptCut = 0.; + entryD0D0barPair(getDeltaPhi(particle2.phi(), particle1.phi()), + particle2.eta() - particle1.eta(), + particle1.pt(), + particle2.pt()); + double etaCut = 0.; + double ptCut = 0.; + do { //fill pairs vs etaCut plot + ptCut = 0.; + etaCut += incrementEtaCut; do { //fill pairs vs etaCut plot - ptCut = 0.; - etaCut += incrementEtaCut; - do { //fill pairs vs etaCut plot - if (std::abs(particle1.eta()) < etaCut && std::abs(particle2.eta()) < etaCut && particle1.pt() > ptCut && particle2.pt() > ptCut) - registry.fill(HIST("hDDbarVsEtaCut"), etaCut - epsilon, ptCut + epsilon); - ptCut += incrementPtThreshold; - } while (ptCut < ptThresholdForMaxEtaCut - epsilon); - } while (etaCut < maxEtaCut - epsilon); - } // end D0bar check - } //end inner loop - } //end D0 check - } //end outer if (MC check D0/D0bar) + if (std::abs(particle1.eta()) < etaCut && std::abs(particle2.eta()) < etaCut && particle1.pt() > ptCut && particle2.pt() > ptCut) + registry.fill(HIST("hDDbarVsEtaCut"), etaCut - epsilon, ptCut + epsilon); + ptCut += incrementPtThreshold; + } while (ptCut < ptThresholdForMaxEtaCut - epsilon); + } while (etaCut < maxEtaCut - epsilon); + } // end D0bar check + } //end inner loop + } //end D0 check } //end outer loop registry.fill(HIST("hcountD0D0barPerEvent"), counterD0D0bar); @@ -582,7 +587,7 @@ struct D0D0barCorrelatorMCGenLS { {"hEtaMCGen", "D0,D0bar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hPhiMCGen", "D0,D0bar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, {"hYMCGen", "D0,D0bar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, - {"hcountD0D0barPerEvent", "D0,D0bar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 10.}}}}}}; + {"hcountD0D0barPerEvent", "D0,D0bar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 20.}}}}}}; Configurable cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"}; Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; @@ -599,6 +604,10 @@ struct D0D0barCorrelatorMCGenLS { registry.fill(HIST("hMCEvtCount"), 0); //MC gen level for (auto& particle1 : particlesMC) { + //check if the particle is D0 or D0bar (both can be trigger) - NOTE: decay channel is not probed! + if (std::abs(particle1.pdgCode()) != 421) { + continue; + } if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))) > cutYCandMax) { continue; } @@ -608,36 +617,36 @@ struct D0D0barCorrelatorMCGenLS { double ptParticle1 = particle1.pt(); //trigger particle is the largest pT one - //Check whether particle is D0 or D0bar (and not the decay chain) - if (std::abs(particle1.pdgCode()) == 421) { - registry.fill(HIST("hPtCandMCGen"), particle1.pt()); - registry.fill(HIST("hEtaMCGen"), particle1.eta()); - registry.fill(HIST("hPhiMCGen"), particle1.phi()); - registry.fill(HIST("hYMCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); - counterD0D0bar++; - //D-Dbar correlation dedicated section - //if it's D0, search for D0bar and evaluate correlations. - registry.fill(HIST("hcountD0triggersMCGen"), 0, particle1.pt()); //to count trigger D0 (normalisation) - for (auto& particle2 : particlesMC) { - if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle2.px(), particle2.py(), particle2.pz()}, RecoDecay::getMassPDG(particle2.pdgCode()))) > cutYCandMax) { - continue; - } - if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) { + registry.fill(HIST("hPtCandMCGen"), particle1.pt()); + registry.fill(HIST("hEtaMCGen"), particle1.eta()); + registry.fill(HIST("hPhiMCGen"), particle1.phi()); + registry.fill(HIST("hYMCGen"), RecoDecay::Y(array{particle1.px(), particle1.py(), particle1.pz()}, RecoDecay::getMassPDG(particle1.pdgCode()))); + counterD0D0bar++; + //D-Dbar correlation dedicated section + //if it's D0, search for D0bar and evaluate correlations. + registry.fill(HIST("hcountD0triggersMCGen"), 0, particle1.pt()); //to count trigger D0 (normalisation) + for (auto& particle2 : particlesMC) { + if (std::abs(particle2.pdgCode()) != 421) { //check that associated is a D0/D0bar (both are fine) + continue; + } + if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle2.px(), particle2.py(), particle2.pz()}, RecoDecay::getMassPDG(particle2.pdgCode()))) > cutYCandMax) { + continue; + } + if (cutPtCandMin >= 0. && std::abs(particle2.pt()) < cutPtCandMin) { + continue; + } + if (particle2.pt() < ptParticle1 && particle2.pdgCode() == particle1.pdgCode()) { //like-sign condition (both 421 or both -421) and pT_Trig>pT_assoc + //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) + if (particle1.mRowIndex == particle2.mRowIndex) { continue; } - if (particle2.pt() < ptParticle1 && particle2.pdgCode() == particle1.pdgCode()) { //like-sign condition (both 421 or both -421) and pT_Trig>pT_assoc - //Excluding self-correlations (in principle not possible due to the '<' condition, but could rounding break it?) - if (particle1.mRowIndex == particle2.mRowIndex) { - continue; - } - entryD0D0barPair(getDeltaPhi(particle2.phi(), particle1.phi()), - particle2.eta() - particle1.eta(), - particle1.pt(), - particle2.pt()); - } - } // end inner loop (Dbars) - } //end outer if (MC check D0) - } //end outer loop + entryD0D0barPair(getDeltaPhi(particle2.phi(), particle1.phi()), + particle2.eta() - particle1.eta(), + particle1.pt(), + particle2.pt()); + } + } // end inner loop (Dbars) + } //end outer loop registry.fill(HIST("hcountD0D0barPerEvent"), counterD0D0bar); } }; @@ -654,7 +663,7 @@ struct CCbarCorrelatorMCGen { {"hEtaMCGen", "c,cbar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hYMCGen", "c,cbar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hPhiMCGen", "c,cbar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, - {"hcountD0D0barPerEvent", "D0,cbar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 10.}}}}}}; + {"hcountD0D0barPerEvent", "D0,cbar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 20.}}}}}}; Configurable cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"}; Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; @@ -736,7 +745,7 @@ struct CCbarCorrelatorMCGenLS { {"hEtaMCGen", "c,cbar particles - MC gen;particle #it{#eta};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hYMCGen", "c,cbar candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {{100, -5., 5.}}}}, {"hPhiMCGen", "c,cbar particles - MC gen;particle #it{#varphi};entries", {HistType::kTH1F, {{32, 0., 2. * o2::constants::math::PI}}}}, - {"hcountD0D0barPerEvent", "D0,cbar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 10.}}}}}}; + {"hcountD0D0barPerEvent", "D0,cbar particles - MC gen;Number per event;entries", {HistType::kTH1F, {{20, 0., 20.}}}}}}; Configurable cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"}; Configurable cutPtCandMin{"cutPtCandMin", -1., "min. cand. pT"}; @@ -780,6 +789,9 @@ struct CCbarCorrelatorMCGenLS { registry.fill(HIST("hcountD0triggersMCGen"), 0, particle1.pt()); //to count trigger c quark (for normalisation) for (auto& particle2 : particlesMC) { + if (std::abs(particle2.pdgCode()) != 4) { //search c or cbar for associated particles + continue; + } if (cutYCandMax >= 0. && std::abs(RecoDecay::Y(array{particle2.px(), particle2.py(), particle2.pz()}, RecoDecay::getMassPDG(particle2.pdgCode()))) > cutYCandMax) { continue; } diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index 60b4ee9595720..c09db03c40085 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -103,37 +103,50 @@ struct TaskD0D0barCorrelation { Configurable> sidebandRightInner{"sidebandRightInner", std::vector(), "Inner values of right sideband vs pT"}; Configurable> sidebandRightOuter{"sidebandRightOuter", std::vector(), "Outer values of right sideband vs pT"}; - // redefinition of pT axes for THnSparse holding correlation entries - int nBinspTaxis = binsCorrelations->size() - 1; - const double* valuespTaxis = binsCorrelations->data(); - void init(o2::framework::InitContext&) { + // redefinition of pT axes for THnSparse holding correlation entries + int nBinspTaxis = binsCorrelations->size() - 1; + const double* valuespTaxis = binsCorrelations->data(); + for (int i = 2; i <= 3; i++) { - registry.get("hMass2DCorrelationPairs")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSignalRegion")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSidebands")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hMass2DCorrelationPairs"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hCorrel2DVsPtSignalRegion"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hCorrel2DVsPtSidebands"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); } } void process(aod::D0D0barPairFull const& pairEntries) { for (auto& pairEntry : pairEntries) { + //define variables for widely used quantities + double deltaPhi = pairEntry.deltaPhi(); + double deltaEta = pairEntry.deltaEta(); + double ptD0 = pairEntry.ptD0(); + double ptD0bar = pairEntry.ptD0bar(); + + //reject entries outside pT ranges of interest + double minPtAllowed = binsCorrelations->at(0); + double maxPtAllowed = binsCorrelations->at(binsCorrelations->size() - 1); + if (ptD0 < minPtAllowed || ptD0bar < minPtAllowed || ptD0 > maxPtAllowed || ptD0bar > maxPtAllowed) { + continue; + } + //fill 2D invariant mass plots - registry.fill(HIST("hMass2DCorrelationPairs"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hMass2DCorrelationPairs"), pairEntry.mD0(), pairEntry.mD0bar(), ptD0, ptD0bar); //check if correlation entry belongs to signal region, sidebands or is outside both, and fill correlation plots - int pTBinD0 = o2::analysis::findBin(binsCorrelations, pairEntry.ptD0()); - int pTBinD0bar = o2::analysis::findBin(binsCorrelations, pairEntry.ptD0bar()); + int pTBinD0 = o2::analysis::findBin(binsCorrelations, ptD0); + int pTBinD0bar = o2::analysis::findBin(binsCorrelations, ptD0bar); if (pairEntry.mD0() > signalRegionInner->at(pTBinD0) && pairEntry.mD0() < signalRegionOuter->at(pTBinD0) && pairEntry.mD0bar() > signalRegionInner->at(pTBinD0bar) && pairEntry.mD0bar() < signalRegionOuter->at(pTBinD0bar)) { //in signal region - registry.fill(HIST("hCorrel2DVsPtSignalRegion"), pairEntry.deltaPhi(), pairEntry.deltaEta(), pairEntry.ptD0(), pairEntry.ptD0bar()); - registry.fill(HIST("hCorrel2DPtIntSignalRegion"), pairEntry.deltaPhi(), pairEntry.deltaEta()); - registry.fill(HIST("hDeltaEtaPtIntSignalRegion"), pairEntry.deltaPhi()); - registry.fill(HIST("hDeltaPhiPtIntSignalRegion"), pairEntry.deltaEta()); - registry.fill(HIST("hDeltaPtDDbarSignalRegion"), pairEntry.ptD0bar() - pairEntry.ptD0()); - registry.fill(HIST("hDeltaPtMaxMinSignalRegion"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); + registry.fill(HIST("hCorrel2DVsPtSignalRegion"), deltaPhi, deltaEta, ptD0, ptD0bar); + registry.fill(HIST("hCorrel2DPtIntSignalRegion"), deltaPhi, deltaEta); + registry.fill(HIST("hDeltaEtaPtIntSignalRegion"), deltaEta); + registry.fill(HIST("hDeltaPhiPtIntSignalRegion"), deltaPhi); + registry.fill(HIST("hDeltaPtDDbarSignalRegion"), ptD0bar - ptD0); + registry.fill(HIST("hDeltaPtMaxMinSignalRegion"), std::abs(ptD0bar - ptD0)); } if ((pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandLeftOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar)) || @@ -141,12 +154,12 @@ struct TaskD0D0barCorrelation { (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandLeftOuter->at(pTBinD0bar)) || (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandRightInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar))) { //in sideband region - registry.fill(HIST("hCorrel2DVsPtSidebands"), pairEntry.deltaPhi(), pairEntry.deltaEta(), pairEntry.ptD0(), pairEntry.ptD0bar()); - registry.fill(HIST("hCorrel2DPtIntSidebands"), pairEntry.deltaPhi(), pairEntry.deltaEta()); - registry.fill(HIST("hDeltaEtaPtIntSidebands"), pairEntry.deltaPhi()); - registry.fill(HIST("hDeltaPhiPtIntSidebands"), pairEntry.deltaEta()); - registry.fill(HIST("hDeltaPtDDbarSidebands"), pairEntry.ptD0bar() - pairEntry.ptD0()); - registry.fill(HIST("hDeltaPtMaxMinSidebands"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); + registry.fill(HIST("hCorrel2DVsPtSidebands"), deltaPhi, deltaEta, ptD0, ptD0bar); + registry.fill(HIST("hCorrel2DPtIntSidebands"), deltaPhi, deltaEta); + registry.fill(HIST("hDeltaEtaPtIntSidebands"), deltaEta); + registry.fill(HIST("hDeltaPhiPtIntSidebands"), deltaPhi); + registry.fill(HIST("hDeltaPtDDbarSidebands"), ptD0bar - ptD0); + registry.fill(HIST("hDeltaPtMaxMinSidebands"), std::abs(ptD0bar - ptD0)); } } //end loop } @@ -192,72 +205,85 @@ struct TaskD0D0barCorrelationMCRec { Configurable> sidebandRightInner{"sidebandRightInner", std::vector(), "Inner values of right sideband vs pT"}; Configurable> sidebandRightOuter{"sidebandRightOuter", std::vector(), "Outer values of right sideband vs pT"}; - // redefinition of pT axes for THnSparse holding correlation entries - int nBinspTaxis = binsCorrelations->size() - 1; - const double* valuespTaxis = binsCorrelations->data(); - void init(o2::framework::InitContext&) { + // redefinition of pT axes for THnSparse holding correlation entries + int nBinspTaxis = binsCorrelations->size() - 1; + const double* valuespTaxis = binsCorrelations->data(); + for (int i = 2; i <= 3; i++) { - registry.get("hMass2DCorrelationPairsMCRecSigSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hMass2DCorrelationPairsMCRecSigBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hMass2DCorrelationPairsMCRecBkgSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hMass2DCorrelationPairsMCRecBkgBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSignalRegionMCRecSigSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSignalRegionMCRecSigBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSignalRegionMCRecBkgSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSignalRegionMCRecBkgBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSidebandsMCRecSigSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSidebandsMCRecSigBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSidebandsMCRecBkgSig")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); - registry.get("hCorrel2DVsPtSidebandsMCRecBkgBkg")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hMass2DCorrelationPairsMCRecSigSig"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hMass2DCorrelationPairsMCRecSigBkg"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hMass2DCorrelationPairsMCRecBkgSig"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hMass2DCorrelationPairsMCRecBkgBkg"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hCorrel2DVsPtSignalRegionMCRecSigSig"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hCorrel2DVsPtSignalRegionMCRecSigBkg"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hCorrel2DVsPtSignalRegionMCRecBkgSig"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hCorrel2DVsPtSignalRegionMCRecBkgBkg"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hCorrel2DVsPtSidebandsMCRecSigSig"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hCorrel2DVsPtSidebandsMCRecSigBkg"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hCorrel2DVsPtSidebandsMCRecBkgSig"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hCorrel2DVsPtSidebandsMCRecBkgBkg"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); } } void process(aod::D0D0barPairFull const& pairEntries) { for (auto& pairEntry : pairEntries) { + //define variables for widely used quantities + double deltaPhi = pairEntry.deltaPhi(); + double deltaEta = pairEntry.deltaEta(); + double ptD0 = pairEntry.ptD0(); + double ptD0bar = pairEntry.ptD0bar(); + + //reject entries outside pT ranges of interest + double minPtAllowed = binsCorrelations->at(0); + double maxPtAllowed = binsCorrelations->at(binsCorrelations->size() - 1); + if (ptD0 < minPtAllowed || ptD0bar < minPtAllowed || ptD0 > maxPtAllowed || ptD0bar > maxPtAllowed) { + continue; + } + //fill 2D invariant mass plots switch (pairEntry.signalStatus()) { case 0: //D0 Bkg, D0bar Bkg - registry.fill(HIST("hMass2DCorrelationPairsMCRecBkgBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hMass2DCorrelationPairsMCRecBkgBkg"), pairEntry.mD0(), pairEntry.mD0bar(), ptD0, ptD0bar); break; case 1: //D0 Bkg, D0bar Sig - registry.fill(HIST("hMass2DCorrelationPairsMCRecBkgSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hMass2DCorrelationPairsMCRecBkgSig"), pairEntry.mD0(), pairEntry.mD0bar(), ptD0, ptD0bar); break; case 2: //D0 Sig, D0bar Bkg - registry.fill(HIST("hMass2DCorrelationPairsMCRecSigBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hMass2DCorrelationPairsMCRecSigBkg"), pairEntry.mD0(), pairEntry.mD0bar(), ptD0, ptD0bar); break; case 3: //D0 Sig, D0bar Sig - registry.fill(HIST("hMass2DCorrelationPairsMCRecSigSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hMass2DCorrelationPairsMCRecSigSig"), pairEntry.mD0(), pairEntry.mD0bar(), ptD0, ptD0bar); break; default: //should not happen for MC reco break; } //check if correlation entry belongs to signal region, sidebands or is outside both, and fill correlation plots - int pTBinD0 = o2::analysis::findBin(binsCorrelations, pairEntry.ptD0()); - int pTBinD0bar = o2::analysis::findBin(binsCorrelations, pairEntry.ptD0bar()); + int pTBinD0 = o2::analysis::findBin(binsCorrelations, ptD0); + int pTBinD0bar = o2::analysis::findBin(binsCorrelations, ptD0bar); if (pairEntry.mD0() > signalRegionInner->at(pTBinD0) && pairEntry.mD0() < signalRegionOuter->at(pTBinD0) && pairEntry.mD0bar() > signalRegionInner->at(pTBinD0bar) && pairEntry.mD0bar() < signalRegionOuter->at(pTBinD0bar)) { //in signal region - registry.fill(HIST("hCorrel2DPtIntSignalRegionMCRec"), pairEntry.deltaPhi(), pairEntry.deltaEta()); - registry.fill(HIST("hDeltaEtaPtIntSignalRegionMCRec"), pairEntry.deltaPhi()); - registry.fill(HIST("hDeltaPhiPtIntSignalRegionMCRec"), pairEntry.deltaEta()); - registry.fill(HIST("hDeltaPtDDbarSignalRegionMCRec"), pairEntry.ptD0bar() - pairEntry.ptD0()); - registry.fill(HIST("hDeltaPtMaxMinSignalRegionMCRec"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); + registry.fill(HIST("hCorrel2DPtIntSignalRegionMCRec"), deltaPhi, deltaEta); + registry.fill(HIST("hDeltaEtaPtIntSignalRegionMCRec"), deltaEta); + registry.fill(HIST("hDeltaPhiPtIntSignalRegionMCRec"), deltaPhi); + registry.fill(HIST("hDeltaPtDDbarSignalRegionMCRec"), ptD0bar - ptD0); + registry.fill(HIST("hDeltaPtMaxMinSignalRegionMCRec"), std::abs(ptD0bar - ptD0)); switch (pairEntry.signalStatus()) { case 0: //D0 Bkg, D0bar Bkg - registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecBkgBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecBkgBkg"), deltaPhi, deltaEta, ptD0, ptD0bar); break; case 1: //D0 Bkg, D0bar Sig - registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecBkgSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecBkgSig"), deltaPhi, deltaEta, ptD0, ptD0bar); break; case 2: //D0 Sig, D0bar Bkg - registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecSigBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecSigBkg"), deltaPhi, deltaEta, ptD0, ptD0bar); break; case 3: //D0 Sig, D0bar Sig - registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecSigSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hCorrel2DVsPtSignalRegionMCRecSigSig"), deltaPhi, deltaEta, ptD0, ptD0bar); break; default: //should not happen for MC reco break; @@ -269,23 +295,23 @@ struct TaskD0D0barCorrelationMCRec { (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandLeftInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandLeftOuter->at(pTBinD0bar)) || (pairEntry.mD0() > sidebandLeftInner->at(pTBinD0) && pairEntry.mD0() < sidebandRightOuter->at(pTBinD0) && pairEntry.mD0bar() > sidebandRightInner->at(pTBinD0bar) && pairEntry.mD0bar() < sidebandRightOuter->at(pTBinD0bar))) { //in sideband region - registry.fill(HIST("hCorrel2DPtIntSidebandsMCRec"), pairEntry.deltaPhi(), pairEntry.deltaEta()); - registry.fill(HIST("hDeltaEtaPtIntSidebandsMCRec"), pairEntry.deltaPhi()); - registry.fill(HIST("hDeltaPhiPtIntSidebandsMCRec"), pairEntry.deltaEta()); - registry.fill(HIST("hDeltaPtDDbarSidebandsMCRec"), pairEntry.ptD0bar() - pairEntry.ptD0()); - registry.fill(HIST("hDeltaPtMaxMinSidebandsMCRec"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); + registry.fill(HIST("hCorrel2DPtIntSidebandsMCRec"), deltaPhi, deltaEta); + registry.fill(HIST("hDeltaEtaPtIntSidebandsMCRec"), deltaEta); + registry.fill(HIST("hDeltaPhiPtIntSidebandsMCRec"), deltaPhi); + registry.fill(HIST("hDeltaPtDDbarSidebandsMCRec"), ptD0bar - ptD0); + registry.fill(HIST("hDeltaPtMaxMinSidebandsMCRec"), std::abs(ptD0bar - ptD0)); switch (pairEntry.signalStatus()) { case 0: //D0 Bkg, D0bar Bkg - registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecBkgBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecBkgBkg"), deltaPhi, deltaEta, ptD0, ptD0bar); break; case 1: //D0 Bkg, D0bar Sig - registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecBkgSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecBkgSig"), deltaPhi, deltaEta, ptD0, ptD0bar); break; case 2: //D0 Sig, D0bar Bkg - registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecSigBkg"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecSigBkg"), deltaPhi, deltaEta, ptD0, ptD0bar); break; case 3: //D0 Sig, D0bar Sig - registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecSigSig"), pairEntry.mD0(), pairEntry.mD0bar(), pairEntry.ptD0(), pairEntry.ptD0bar()); + registry.fill(HIST("hCorrel2DVsPtSidebandsMCRecSigSig"), deltaPhi, deltaEta, ptD0, ptD0bar); break; default: //should not happen for MC reco break; @@ -311,26 +337,39 @@ struct TaskD0D0barCorrelationMCGen { //pT ranges for correlation plots: the default values are those embedded in hf_cuts_d0_topik (i.e. the mass pT bins), but can be redefined via json files Configurable> binsCorrelations{"ptBinsForCorrelations", std::vector{o2::analysis::hf_cuts_d0_topik::pTBins_v}, "pT bin limits for correlation plots"}; - // redefinition of pT axes for THnSparse holding correlation entries - int nBinspTaxis = binsCorrelations->size() - 1; - const double* valuespTaxis = binsCorrelations->data(); - void init(o2::framework::InitContext&) { + // redefinition of pT axes for THnSparse holding correlation entries + int nBinspTaxis = binsCorrelations->size() - 1; + const double* valuespTaxis = binsCorrelations->data(); + for (int i = 2; i <= 3; i++) { - registry.get("hCorrel2DVsPtMCGen")->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hCorrel2DVsPtMCGen"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); } } - void process(aod::D0D0barPairFull const& pairEntries) + void process(aod::D0D0barPair const& pairEntries) { for (auto& pairEntry : pairEntries) { - registry.fill(HIST("hCorrel2DVsPtMCGen"), pairEntry.deltaPhi(), pairEntry.deltaEta(), pairEntry.ptD0(), pairEntry.ptD0bar()); - registry.fill(HIST("hCorrel2DPtIntMCGen"), pairEntry.deltaPhi(), pairEntry.deltaEta()); - registry.fill(HIST("hDeltaEtaPtIntMCGen"), pairEntry.deltaPhi()); - registry.fill(HIST("hDeltaPhiPtIntMCGen"), pairEntry.deltaEta()); - registry.fill(HIST("hDeltaPtDDbarMCGen"), pairEntry.ptD0bar() - pairEntry.ptD0()); - registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::abs(pairEntry.ptD0bar() - pairEntry.ptD0())); + //define variables for widely used quantities + double deltaPhi = pairEntry.deltaPhi(); + double deltaEta = pairEntry.deltaEta(); + double ptD0 = pairEntry.ptD0(); + double ptD0bar = pairEntry.ptD0bar(); + + //reject entries outside pT ranges of interest + double minPtAllowed = binsCorrelations->at(0); + double maxPtAllowed = binsCorrelations->at(binsCorrelations->size() - 1); + if (ptD0 < minPtAllowed || ptD0bar < minPtAllowed || ptD0 > maxPtAllowed || ptD0bar > maxPtAllowed) { + continue; + } + + registry.fill(HIST("hCorrel2DVsPtMCGen"), deltaPhi, deltaEta, ptD0, ptD0bar); + registry.fill(HIST("hCorrel2DPtIntMCGen"), deltaPhi, deltaEta); + registry.fill(HIST("hDeltaEtaPtIntMCGen"), deltaEta); + registry.fill(HIST("hDeltaPhiPtIntMCGen"), deltaPhi); + registry.fill(HIST("hDeltaPtDDbarMCGen"), ptD0bar - ptD0); + registry.fill(HIST("hDeltaPtMaxMinMCGen"), std::abs(ptD0bar - ptD0)); } //end loop } }; @@ -429,12 +468,12 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) const bool doMCGen = cfgc.options().get("doMCGen"); const bool doMCRec = cfgc.options().get("doMCRec"); if (doMCGen) { //MC-Gen analysis - workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"task-d0d0bar-correlation"})); + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"task-d0d0bar-correlation-mc-gen"})); } else if (doMCRec) { //MC-Rec analysis workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"task-d0d0bar-correlation-mc-rec"})); workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"task-d0d0bar-correlation-check-phi-resolution"})); } else { //data analysis - workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"task-d0d0bar-correlation-mc-gen"})); + workflow.push_back(adaptAnalysisTask(cfgc, TaskName{"task-d0d0bar-correlation"})); } return workflow; } From 4e41fb8693080758a64b692ae278c7dedcf3e0a7 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Thu, 15 Apr 2021 09:34:13 +0200 Subject: [PATCH 22/24] Implementing dev updates to HFSecondaryVertex.h --- .../DataModel/include/AnalysisDataModel/HFSecondaryVertex.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h b/Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h index ec7ea0e33da91..03f26ad75c0f2 100644 --- a/Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h +++ b/Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h @@ -37,7 +37,9 @@ DECLARE_SOA_TABLE(HFSelTrack, "AOD", "HFSELTRACK", using BigTracks = soa::Join; using BigTracksMC = soa::Join; -using BigTracksPID = soa::Join; +using BigTracksPID = soa::Join; // FIXME: this is a workaround until we get the index columns to work with joins. From 928e3ea13192d9d935d9b7ad7917e7bb22462aff Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Thu, 15 Apr 2021 14:43:15 +0200 Subject: [PATCH 23/24] Fix in the branches merging --- Analysis/Tasks/PWGHF/CMakeLists.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Analysis/Tasks/PWGHF/CMakeLists.txt b/Analysis/Tasks/PWGHF/CMakeLists.txt index eead69e29ebde..58e51f2421987 100644 --- a/Analysis/Tasks/PWGHF/CMakeLists.txt +++ b/Analysis/Tasks/PWGHF/CMakeLists.txt @@ -98,11 +98,6 @@ o2_add_dpl_workflow(hf-task-bplus PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) -o2_add_dpl_workflow(hf-task-d0d0bar-correlation - SOURCES taskD0D0barCorrelation.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing - COMPONENT_NAME Analysis) - o2_add_dpl_workflow(hf-task-xic SOURCES taskXic.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing From 84645ce16a759a0c021bbf079f4b8525fe34cc39 Mon Sep 17 00:00:00 2001 From: Fabio Colamaria Date: Thu, 15 Apr 2021 14:49:02 +0200 Subject: [PATCH 24/24] Clang fix --- Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx index c8c2150366486..c09db03c40085 100644 --- a/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx +++ b/Analysis/Tasks/PWGHF/taskD0D0barCorrelation.cxx @@ -127,9 +127,9 @@ struct TaskD0D0barCorrelation { //reject entries outside pT ranges of interest double minPtAllowed = binsCorrelations->at(0); - double maxPtAllowed = binsCorrelations->at(binsCorrelations->size()-1); + double maxPtAllowed = binsCorrelations->at(binsCorrelations->size() - 1); if (ptD0 < minPtAllowed || ptD0bar < minPtAllowed || ptD0 > maxPtAllowed || ptD0bar > maxPtAllowed) { - continue; + continue; } //fill 2D invariant mass plots @@ -238,9 +238,9 @@ struct TaskD0D0barCorrelationMCRec { //reject entries outside pT ranges of interest double minPtAllowed = binsCorrelations->at(0); - double maxPtAllowed = binsCorrelations->at(binsCorrelations->size()-1); + double maxPtAllowed = binsCorrelations->at(binsCorrelations->size() - 1); if (ptD0 < minPtAllowed || ptD0bar < minPtAllowed || ptD0 > maxPtAllowed || ptD0bar > maxPtAllowed) { - continue; + continue; } //fill 2D invariant mass plots @@ -342,7 +342,7 @@ struct TaskD0D0barCorrelationMCGen { // redefinition of pT axes for THnSparse holding correlation entries int nBinspTaxis = binsCorrelations->size() - 1; const double* valuespTaxis = binsCorrelations->data(); - + for (int i = 2; i <= 3; i++) { registry.get(HIST("hCorrel2DVsPtMCGen"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); } @@ -356,10 +356,10 @@ struct TaskD0D0barCorrelationMCGen { double deltaEta = pairEntry.deltaEta(); double ptD0 = pairEntry.ptD0(); double ptD0bar = pairEntry.ptD0bar(); - + //reject entries outside pT ranges of interest double minPtAllowed = binsCorrelations->at(0); - double maxPtAllowed = binsCorrelations->at(binsCorrelations->size()-1); + double maxPtAllowed = binsCorrelations->at(binsCorrelations->size() - 1); if (ptD0 < minPtAllowed || ptD0bar < minPtAllowed || ptD0 > maxPtAllowed || ptD0bar > maxPtAllowed) { continue; }