diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 4caf0166303..7475a70a5a5 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -208,7 +208,8 @@ namespace fdhf enum CharmHadronMassHypo { wrongParticle = 0, lcToPKPi = 1, - lcToPiKP = 2 + lcToPiKP = 2, + dplusToPiKPi = 4 }; DECLARE_SOA_COLUMN(GIndexCol, gIndexCol, int); //! Global index for the collision DECLARE_SOA_COLUMN(TimeStamp, timeStamp, int64_t); //! Timestamp for the collision @@ -227,7 +228,7 @@ DECLARE_SOA_COLUMN(Prong2Eta, prong2Eta, float); //! Track et DECLARE_SOA_COLUMN(Prong0Phi, prong0Phi, float); //! Track phi of charm hadron prong0 DECLARE_SOA_COLUMN(Prong1Phi, prong1Phi, float); //! Track phi of charm hadron prong1 DECLARE_SOA_COLUMN(Prong2Phi, prong2Phi, float); //! Track phi of charm hadron prong2 -DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int8_t); //! Selection of mass hypothesis for charm hadron (1 for Lc -> pkpi, 2 for Lc -> pikp) +DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int8_t); //! Selection of mass hypothesis for charm hadron (1 for Lc -> pkpi, 2 for Lc -> pikp, 4 for D+ -> pikpi) DECLARE_SOA_COLUMN(BDTBkg, bdtBkg, float); //! Background score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTPrompt, bdtPrompt, float); //! Prompt signal score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTFD, bdtFD, float); //! Feed-down score using Boosted Decision Tree for charm hadron diff --git a/PWGCF/FemtoDream/Core/femtoDreamContainer.h b/PWGCF/FemtoDream/Core/femtoDreamContainer.h index 5e0222a4f07..3d95fc08311 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamContainer.h +++ b/PWGCF/FemtoDream/Core/femtoDreamContainer.h @@ -202,10 +202,12 @@ class FemtoDreamContainer { const float kT = FemtoDreamMath::getkT(part1, mMassOne, part2, mMassTwo); if constexpr (isHF) { - float mP2; - if (part2.candidateSelFlag() == o2::aod::fdhf::lcToPKPi) { + float mP2 = 0.0; + if (part2.candidateSelFlag() == o2::aod::fdhf::dplusToPiKPi) { + mP2 = part2.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); + } else if (part2.candidateSelFlag() == o2::aod::fdhf::lcToPKPi) { mP2 = part2.m(std::array{o2::constants::physics::MassProton, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); - } else { + } else if (part2.candidateSelFlag() == o2::aod::fdhf::lcToPiKP) { mP2 = part2.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); } mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/relPairkstarmP2"), femtoObs, mP2); diff --git a/PWGCF/FemtoDream/Core/femtoDreamUtils.h b/PWGCF/FemtoDream/Core/femtoDreamUtils.h index c5db8dcc70e..f9bb60633f3 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamUtils.h +++ b/PWGCF/FemtoDream/Core/femtoDreamUtils.h @@ -52,6 +52,9 @@ inline float getMass(int pdgCode) case o2::constants::physics::Pdg::kPhi: mass = o2::constants::physics::MassPhi; break; + case o2::constants::physics::Pdg::kDPlus: + mass = o2::constants::physics::MassDPlus; + break; case o2::constants::physics::Pdg::kLambdaCPlus: mass = o2::constants::physics::MassLambdaCPlus; break; diff --git a/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx b/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx index a605bc74f6c..5502b7e302f 100644 --- a/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx +++ b/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx @@ -13,6 +13,7 @@ /// \brief Tasks that produces the track tables used for the pairing /// \author Ravindra Singh, GSI, ravindra.singh@cern.ch /// \author Biao Zhang, Heidelberg University, biao.zhang@cern.ch +/// \author Yunfan Liu, Central China Normal University, yunfan.l@cern.ch #include "PWGCF/DataModel/FemtoDerived.h" #include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" @@ -21,6 +22,7 @@ #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Core/DecayChannels.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/HfMlResponseDplusToPiKPi.h" #include "PWGHF/Core/HfMlResponseLcToPKPi.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" @@ -87,6 +89,11 @@ enum MlMode : uint8_t { FillMlFromNewBDT }; +// decay channels +enum DecayChannel { DplusToPiKPi = 0, + LcToPKPi +}; + struct HfFemtoDreamProducer { Produces outputCollision; @@ -119,9 +126,9 @@ struct HfFemtoDreamProducer { Configurable isDebug{"isDebug", true, "Enable Debug tables"}; Configurable isRun3{"isRun3", true, "Running on Run3 or pilot"}; - /// Lc table - Configurable selectionFlagLc{"selectionFlagLc", 1, "Selection Flag for Lc"}; - Configurable useCent{"useCent", false, "Enable centrality for lc"}; + /// Charm hadron table + Configurable selectionFlagHadron{"selectionFlagHadron", 1, "Selection Flag for Charm Hadron: 1 for Lc, 7 for Dplus (Topologic and PID cuts)"}; + Configurable useCent{"useCent", false, "Enable centrality for Charm Hadron"}; Configurable trkPDGCode{"trkPDGCode", 2212, "PDG code of the selected track for Monte Carlo truth"}; Configurable> trkCharge{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kSign, "trk"), std::vector{-1, 1}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kSign, "Track selection: ")}; @@ -141,7 +148,7 @@ struct HfFemtoDreamProducer { Configurable> trkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsIbMin, "trk"), std::vector{-1.f, 1.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsIbMin, "Track selection: ")}; Configurable> trkITSnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsMin, "trk"), std::vector{-1.f, 2.f, 4.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsMin, "Track selection: ")}; // ML inference - Configurable applyMlMode{"applyMlMode", 1, "None: 0, BDT model from Lc selector: 1, New BDT model on Top of Lc selector: 2"}; + Configurable applyMlMode{"applyMlMode", 1, "None: 0, BDT model from candidate selector: 1, New BDT model on Top of candidate selector: 2"}; Configurable> binsPtMl{"binsPtMl", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; Configurable> cutDirMl{"cutDirMl", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; Configurable> cutsMl{"cutsMl", {hf_cuts_ml::Cuts[0], hf_cuts_ml::NBinsPt, hf_cuts_ml::NCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "ML selections per pT bin"}; @@ -152,6 +159,8 @@ struct HfFemtoDreamProducer { HfHelper hfHelper; o2::analysis::HfMlResponseLcToPKPi hfMlResponse; + o2::analysis::HfMlResponseDplusToPiKPi hfMlResponseDplus; + std::vector outputMlDplus = {}; std::vector outputMlPKPi = {}; std::vector outputMlPiKP = {}; o2::ccdb::CcdbApi ccdbApi; @@ -162,6 +171,8 @@ struct HfFemtoDreamProducer { float magField; int runNumber; + using CandidateDplus = soa::Join; + using CandidateDplusMc = soa::Join; using CandidateLc = soa::Join; using CandidateLcMc = soa::Join; @@ -176,14 +187,16 @@ struct HfFemtoDreamProducer { using GeneratedMc = soa::Filtered>; - Filter filterSelectCandidateLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagLc || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagLc); + Filter filterSelectCandidateDplus = (aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagHadron || aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagHadron); + Filter filterSelectCandidateLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagHadron || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagHadron); HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry trackRegistry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; void init(InitContext&) { - std::array processes = {doprocessDataCharmHad, doprocessMcCharmHad, doprocessDataCharmHadWithML, doprocessMcCharmHadWithML, doprocessMcCharmHadGen}; + std::array processes = {doprocessDataDplusToPiKPi, doprocessMcDplusToPiKPi, doprocessDataDplusToPiKPiWithML, doprocessMcDplusToPiKPiWithML, doprocessMcDplusToPiKPiGen, + doprocessDataLcToPKPi, doprocessMcLcToPKPi, doprocessDataLcToPKPiWithML, doprocessMcLcToPKPiWithML, doprocessMcLcToPKPiGen}; if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { LOGP(fatal, "One and only one process function must be enabled at a time."); } @@ -404,7 +417,7 @@ struct HfFemtoDreamProducer { return fIsTrackFilled; } - template + template void fillCharmHadronTable(CollisionType const& col, TrackType const& tracks, CandType const& candidates) { const auto vtxZ = col.posZ(); @@ -451,44 +464,15 @@ struct HfFemtoDreamProducer { bool isTrackFilled = false; bool isSelectedMlLcToPKPi = true; bool isSelectedMlLcToPiKP = true; + bool isSelectedMlDplusToPiKPi = true; for (const auto& candidate : candidates) { + outputMlDplus = {-1.0f, -1.0f, -1.0f}; outputMlPKPi = {-1.0f, -1.0f, -1.0f}; outputMlPiKP = {-1.0f, -1.0f, -1.0f}; auto trackPos1 = candidate.template prong0_as(); // positive daughter (negative for the antiparticles) auto trackNeg = candidate.template prong1_as(); // negative daughter (positive for the antiparticles) auto trackPos2 = candidate.template prong2_as(); // positive daughter (negative for the antiparticles) - if constexpr (useCharmMl) { - /// fill with ML information - /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { - if (candidate.mlProbLcToPKPi().size() > 0) { - outputMlPKPi.at(0) = candidate.mlProbLcToPKPi()[0]; /// bkg score - outputMlPKPi.at(1) = candidate.mlProbLcToPKPi()[1]; /// prompt score - outputMlPKPi.at(2) = candidate.mlProbLcToPKPi()[2]; /// non-prompt score - } - if (candidate.mlProbLcToPiKP().size() > 0) { - outputMlPiKP.at(0) = candidate.mlProbLcToPiKP()[0]; /// bkg score - outputMlPiKP.at(1) = candidate.mlProbLcToPiKP()[1]; /// prompt score - outputMlPiKP.at(2) = candidate.mlProbLcToPiKP()[2]; /// non-prompt score - } - } else if (applyMlMode == FillMlFromNewBDT) { - isSelectedMlLcToPKPi = false; - isSelectedMlLcToPiKP = false; - if (candidate.mlProbLcToPKPi().size() > 0) { - std::vector inputFeaturesLcToPKPi = hfMlResponse.getInputFeatures(candidate, true); - isSelectedMlLcToPKPi = hfMlResponse.isSelectedMl(inputFeaturesLcToPKPi, candidate.pt(), outputMlPKPi); - } - if (candidate.mlProbLcToPiKP().size() > 0) { - std::vector inputFeaturesLcToPiKP = hfMlResponse.getInputFeatures(candidate, false); - isSelectedMlLcToPiKP = hfMlResponse.isSelectedMl(inputFeaturesLcToPiKP, candidate.pt(), outputMlPKPi); - } - if (!isSelectedMlLcToPKPi && !isSelectedMlLcToPiKP) - continue; - } else { - LOGF(fatal, "Please check your Ml configuration!!"); - } - } auto bc = col.template bc_as(); int64_t timeStamp = bc.timestamp(); auto fillTable = [&](int CandFlag, @@ -526,8 +510,65 @@ struct HfFemtoDreamProducer { } } }; - fillTable(0, candidate.isSelLcToPKPi(), outputMlPKPi.at(0), outputMlPKPi.at(1), outputMlPKPi.at(2)); - fillTable(1, candidate.isSelLcToPiKP(), outputMlPiKP.at(0), outputMlPiKP.at(1), outputMlPiKP.at(2)); + if constexpr (channel == DecayChannel::DplusToPiKPi) { + if constexpr (useCharmMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score + if (applyMlMode == FillMlFromSelector) { + if (candidate.mlProbDplusToPiKPi().size() > 0) { + outputMlDplus.at(0) = candidate.mlProbDplusToPiKPi()[0]; /// bkg score + outputMlDplus.at(1) = candidate.mlProbDplusToPiKPi()[1]; /// prompt score + outputMlDplus.at(2) = candidate.mlProbDplusToPiKPi()[2]; /// non-prompt score + } + } else if (applyMlMode == FillMlFromNewBDT) { + isSelectedMlDplusToPiKPi = false; + if (candidate.mlProbDplusToPiKPi().size() > 0) { + std::vector inputFeaturesDplusToPiKPi = hfMlResponseDplus.getInputFeatures(candidate); + isSelectedMlDplusToPiKPi = hfMlResponseDplus.isSelectedMl(inputFeaturesDplusToPiKPi, candidate.pt(), outputMlDplus); + } + if (!isSelectedMlDplusToPiKPi) + continue; + } else { + LOGF(fatal, "Please check your Ml configuration!!"); + } + } + fillTable(2, candidate.isSelDplusToPiKPi(), outputMlDplus.at(0), outputMlDplus.at(1), outputMlDplus.at(2)); + + } else if constexpr (channel == DecayChannel::LcToPKPi) { + if constexpr (useCharmMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score + if (applyMlMode == FillMlFromSelector) { + if (candidate.mlProbLcToPKPi().size() > 0) { + outputMlPKPi.at(0) = candidate.mlProbLcToPKPi()[0]; /// bkg score + outputMlPKPi.at(1) = candidate.mlProbLcToPKPi()[1]; /// prompt score + outputMlPKPi.at(2) = candidate.mlProbLcToPKPi()[2]; /// non-prompt score + } + if (candidate.mlProbLcToPiKP().size() > 0) { + outputMlPiKP.at(0) = candidate.mlProbLcToPiKP()[0]; /// bkg score + outputMlPiKP.at(1) = candidate.mlProbLcToPiKP()[1]; /// prompt score + outputMlPiKP.at(2) = candidate.mlProbLcToPiKP()[2]; /// non-prompt score + } + } else if (applyMlMode == FillMlFromNewBDT) { + isSelectedMlLcToPKPi = false; + isSelectedMlLcToPiKP = false; + if (candidate.mlProbLcToPKPi().size() > 0) { + std::vector inputFeaturesLcToPKPi = hfMlResponse.getInputFeatures(candidate, true); + isSelectedMlLcToPKPi = hfMlResponse.isSelectedMl(inputFeaturesLcToPKPi, candidate.pt(), outputMlPKPi); + } + if (candidate.mlProbLcToPiKP().size() > 0) { + std::vector inputFeaturesLcToPiKP = hfMlResponse.getInputFeatures(candidate, false); + isSelectedMlLcToPiKP = hfMlResponse.isSelectedMl(inputFeaturesLcToPiKP, candidate.pt(), outputMlPKPi); + } + if (!isSelectedMlLcToPKPi && !isSelectedMlLcToPiKP) + continue; + } else { + LOGF(fatal, "Please check your Ml configuration!!"); + } + } + fillTable(0, candidate.isSelLcToPKPi(), outputMlPKPi.at(0), outputMlPKPi.at(1), outputMlPKPi.at(2)); + fillTable(1, candidate.isSelLcToPiKP(), outputMlPiKP.at(0), outputMlPiKP.at(1), outputMlPiKP.at(2)); + } } if (!isTrackFilled) { @@ -571,22 +612,97 @@ struct HfFemtoDreamProducer { return true; } - template + template void fillCharmHadMcGen(ParticleType particles) { // Filling particle properties rowCandCharmHadGen.reserve(particles.size()); - for (const auto& particle : particles) { - if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { - rowCandCharmHadGen( - particle.mcCollisionId(), - particle.flagMcMatchGen(), - particle.originMcGen()); + if constexpr (channel == DecayChannel::DplusToPiKPi) { + for (const auto& particle : particles) { + if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { + rowCandCharmHadGen( + particle.mcCollisionId(), + particle.flagMcMatchGen(), + particle.originMcGen()); + } + } + } else if constexpr (channel == DecayChannel::LcToPKPi) { + for (const auto& particle : particles) { + if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { + rowCandCharmHadGen( + particle.mcCollisionId(), + particle.flagMcMatchGen(), + particle.originMcGen()); + } } } } - void processDataCharmHad(FemtoFullCollision const& col, + /// DplusToPiKPi + void processDataDplusToPiKPi(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + soa::Filtered const& candidates) + { + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + + fillCharmHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfFemtoDreamProducer, processDataDplusToPiKPi, + "Provide experimental data for DplusToPiKPi femto", false); + + void processDataDplusToPiKPiWithML(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + soa::Filtered> const& candidates) + { + + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + + fillCharmHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfFemtoDreamProducer, processDataDplusToPiKPiWithML, + "Provide experimental data for DplusToPiKPi with ml", false); + + void processMcDplusToPiKPi(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::McParticles const&, + CandidateDplusMc const& candidates) + { + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + + fillCharmHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfFemtoDreamProducer, processMcDplusToPiKPi, "Provide Mc for DplusToPiKPi", false); + + void processMcDplusToPiKPiWithML(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::McParticles const&, + soa::Join const& candidates) + { + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + + fillCharmHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfFemtoDreamProducer, processMcDplusToPiKPiWithML, "Provide Mc for DplusToPiKPi with ml", false); + + void processMcDplusToPiKPiGen(GeneratedMc const& particles) + { + + fillCharmHadMcGen(particles); + } + PROCESS_SWITCH(HfFemtoDreamProducer, processMcDplusToPiKPiGen, "Provide Mc Generated DplusToPiKPi", false); + + /// LcToPKPi + void processDataLcToPKPi(FemtoFullCollision const& col, aod::BCsWithTimestamps const&, FemtoHFTracks const& tracks, soa::Filtered const& candidates) @@ -594,12 +710,12 @@ struct HfFemtoDreamProducer { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates); } - PROCESS_SWITCH(HfFemtoDreamProducer, processDataCharmHad, - "Provide experimental data for charm hadron femto", false); + PROCESS_SWITCH(HfFemtoDreamProducer, processDataLcToPKPi, + "Provide experimental data for Lc(PKPi)-proton femto", false); - void processDataCharmHadWithML(FemtoFullCollision const& col, + void processDataLcToPKPiWithML(FemtoFullCollision const& col, aod::BCsWithTimestamps const&, FemtoHFTracks const& tracks, soa::Filtered()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates); } - PROCESS_SWITCH(HfFemtoDreamProducer, processDataCharmHadWithML, - "Provide experimental data for charm hadron femto with ml", false); + PROCESS_SWITCH(HfFemtoDreamProducer, processDataLcToPKPiWithML, + "Provide experimental data for Lc(PKPi)-proton femto with ml", false); - void processMcCharmHad(FemtoFullCollisionMc const& col, + void processMcLcToPKPi(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, aod::McParticles const&, @@ -623,11 +739,11 @@ struct HfFemtoDreamProducer { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates); } - PROCESS_SWITCH(HfFemtoDreamProducer, processMcCharmHad, "Provide Mc for charm hadron", false); + PROCESS_SWITCH(HfFemtoDreamProducer, processMcLcToPKPi, "Provide Mc for lctopkpi", false); - void processMcCharmHadWithML(FemtoFullCollisionMc const& col, + void processMcLcToPKPiWithML(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, aod::McParticles const&, @@ -637,16 +753,16 @@ struct HfFemtoDreamProducer { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates); } - PROCESS_SWITCH(HfFemtoDreamProducer, processMcCharmHadWithML, "Provide Mc for charm hadron with ml", false); + PROCESS_SWITCH(HfFemtoDreamProducer, processMcLcToPKPiWithML, "Provide Mc for lctopkpi with ml", false); - void processMcCharmHadGen(GeneratedMc const& particles) + void processMcLcToPKPiGen(GeneratedMc const& particles) { - fillCharmHadMcGen(particles); + fillCharmHadMcGen(particles); } - PROCESS_SWITCH(HfFemtoDreamProducer, processMcCharmHadGen, "Provide Mc Generated charm hadron", false); + PROCESS_SWITCH(HfFemtoDreamProducer, processMcLcToPKPiGen, "Provide Mc Generated lctopkpi", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx index bd9c2679ff5..3644cd3ed3c 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx @@ -9,10 +9,11 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file taskCharmHadronsFemtoDream.cxx.cxx +/// \file taskCharmHadronsFemtoDream.cxx /// \brief Tasks that reads the track tables used for the pairing and builds pairs of two tracks /// \author Ravindra SIngh, GSI, ravindra.singh@cern.ch /// \author Biao Zhang, Heidelberg University, biao.zhang@cern.ch +/// \author Yunfan Liu, Central China Normal University, yunfan.l@cern.ch #include "PWGCF/DataModel/FemtoDerived.h" #include "PWGCF/FemtoDream/Core/femtoDreamContainer.h" @@ -43,6 +44,7 @@ #include #include #include +#include using namespace o2; using namespace o2::aod; @@ -51,6 +53,11 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::analysis::femtoDream; +inline o2::framework::expressions::Node coshEta(o2::framework::expressions::Node&& eta) +{ + return (nexp(std::move(eta)) + nexp(0.0f - std::move(eta))) * 0.5f; +} + struct HfTaskCharmHadronsFemtoDream { enum TrackCharge { @@ -58,27 +65,14 @@ struct HfTaskCharmHadronsFemtoDream { NegativeCharge = -1 }; - /// Binning configurables - ConfigurableAxis bin4Dkstar{"bin4Dkstar", {1500, 0., 6.}, "binning kstar for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; - ConfigurableAxis bin4DMult{"bin4Dmult", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f}, "multiplicity Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; - ConfigurableAxis bin4DmT{"bin4DmT", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; - ConfigurableAxis bin4DmultPercentile{"bin4DmultPercentile", {10, 0.0f, 100.0f}, "multiplicity percentile Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; - ConfigurableAxis binInvMass{"binInvMass", {400, 2.10, 2.50}, "InvMass binning"}; - ConfigurableAxis binpTCharm{"binpTCharm", {360, 0, 36}, "pT binning of charm hadron"}; - ConfigurableAxis binTempFitVarTrack{"binTempFitVarTrack", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot (Track)"}; - ConfigurableAxis binmT{"binmT", {225, 0., 7.5}, "binning mT"}; - ConfigurableAxis binmultTempFit{"binmultTempFit", {1, 0, 1}, "multiplicity Binning for the TempFitVar plot"}; - ConfigurableAxis binMulPercentile{"binMulPercentile", {10, 0.0f, 100.0f}, "multiplicity percentile Binning"}; - ConfigurableAxis binpTTrack{"binpTTrack", {50, 0.5, 10.05}, "pT binning of the pT vs. TempFitVar plot (Track)"}; - ConfigurableAxis binEta{"binEta", {{200, -1.5, 1.5}}, "eta binning"}; - ConfigurableAxis binPhi{"binPhi", {{200, 0, TMath::TwoPi()}}, "phi binning"}; - ConfigurableAxis binkT{"binkT", {150, 0., 9.}, "binning kT"}; - ConfigurableAxis binkstar{"binkstar", {1500, 0., 6.}, "binning kstar"}; - ConfigurableAxis binNSigmaTPC{"binNSigmaTPC", {1600, -8, 8}, "Binning of Nsigma TPC plot"}; - ConfigurableAxis binNSigmaTOF{"binNSigmaTOF", {3000, -15, 15}, "Binning of the Nsigma TOF plot"}; - ConfigurableAxis binNSigmaTPCTOF{"binNSigmaTPCTOF", {3000, -15, 15}, "Binning of the Nsigma TPC+TOF plot"}; - ConfigurableAxis binTPCClusters{"binTPCClusters", {163, -0.5, 162.5}, "Binning of TPC found clusters plot"}; - Configurable ConfTempFitVarMomentum{"ConfTempFitVarMomentum", 0, "Momentum used for binning: 0 -> pt; 1 -> preco; 2 -> ptpc"}; + constexpr static int OriginRecPrompt = 1; + constexpr static int OriginRecFD = 2; + + Produces rowFemtoResultCharm; + Produces rowFemtoResultTrk; + Produces rowFemtoResultColl; + + Configurable confTempFitVarMomentum{"confTempFitVarMomentum", 0, "Momentum used for binning: 0 -> pt; 1 -> preco; 2 -> ptpc"}; /// Particle 2 (Charm Hadrons) Configurable charmHadBkgBDTmax{"charmHadBkgBDTmax", 1., "Maximum background bdt score for Charm Hadron (particle 2)"}; @@ -104,14 +98,10 @@ struct HfTaskCharmHadronsFemtoDream { Configurable smearingByOrigin{"smearingByOrigin", false, "Obtain the smearing matrix differential in the MC origin of particle 1 and particle 2. High memory consumption. Use with care!"}; Configurable use4D{"use4D", false, "Enable four dimensional histogramms (to be used only for analysis with high statistics): k* vs multiplicity vs multiplicity percentil vs mT"}; Configurable useCPR{"useCPR", false, "Close Pair Rejection"}; - ConfigurableAxis dummy{"dummy", {1, 0, 1}, "dummy axis"}; // Mixing configurables - ConfigurableAxis mixingBinMult{"mixingBinMult", {VARIABLE_WIDTH, 0.0f, 20.0f, 60.0f, 200.0f}, "Mixing bins - multiplicity"}; - ConfigurableAxis mixingBinMultPercentile{"mixingBinMultPercentile", {VARIABLE_WIDTH, 0.0f, 100.f}, "Mixing bins - multiplicity percentile"}; - ConfigurableAxis mixingBinVztx{"mixingBinVztx", {VARIABLE_WIDTH, -10.0f, -4.f, 0.f, 4.f, 10.f}, "Mixing bins - z-vertex"}; - Configurable mixingDepth{"mixingDepth", 5, "Number of events for mixing"}; Configurable mixingBinPolicy{"mixingBinPolicy", 0, "Binning policy for mixing - 0: multiplicity, 1: multipliciy percentile, 2: both"}; + Configurable mixingDepth{"mixingDepth", 5, "Number of events for mixing"}; /// Event selection struct : ConfigurableGroup { @@ -133,23 +123,7 @@ struct HfTaskCharmHadronsFemtoDream { Configurable etaTrack1Min{"etaTrack1Min", -10., "Minimum eta of partricle 1 (Track)"}; Configurable ptTrack1Min{"ptTrack1Min", 0., "Minimum pT of partricle 1 (Track)"}; - ColumnBinningPolicy colBinningMult{{mixingBinVztx, mixingBinMult}, true}; - ColumnBinningPolicy colBinningMultPercentile{{mixingBinVztx, mixingBinMultPercentile}, true}; - ColumnBinningPolicy colBinningMultMultPercentile{{mixingBinVztx, mixingBinMult, mixingBinMultPercentile}, true}; - - FemtoDreamContainer sameEventCont; - FemtoDreamContainer mixedEventCont; - FemtoDreamPairCleaner pairCleaner; - FemtoDreamDetaDphiStar pairCloseRejectionSE; - FemtoDreamDetaDphiStar pairCloseRejectionME; - Filter eventMultiplicity = aod::femtodreamcollision::multNtr >= eventSel.multMin && aod::femtodreamcollision::multNtr <= eventSel.multMax; - Filter eventMultiplicityPercentile = aod::femtodreamcollision::multV0M >= eventSel.multPercentileMin && aod::femtodreamcollision::multV0M <= eventSel.multPercentileMax; - Filter hfCandSelFilter = aod::fdhf::candidateSelFlag >= static_cast(charmHadCandSel.value); - Filter hfMcSelFilter = nabs(aod::fdhf::flagMc) == static_cast(charmHadMcSel.value); - Filter trackEtaFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta < etaTrack1Max, true); - Filter trackEtaFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta > etaTrack1Min, true); - Filter trackPtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt < ptTrack1Max, true); - Filter trackPtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt > ptTrack1Min, true); + SliceCache cache; using FilteredCharmCands = soa::Filtered; using FilteredCharmCand = FilteredCharmCands::iterator; @@ -169,7 +143,66 @@ struct HfTaskCharmHadronsFemtoDream { using FilteredFDParticles = soa::Filtered>; using FilteredFDParticle = FilteredFDParticles::iterator; - femtodreamcollision::BitMaskType BitMask = 1 << 0; + Filter eventMultiplicity = aod::femtodreamcollision::multNtr >= eventSel.multMin && aod::femtodreamcollision::multNtr <= eventSel.multMax; + Filter eventMultiplicityPercentile = aod::femtodreamcollision::multV0M >= eventSel.multPercentileMin && aod::femtodreamcollision::multV0M <= eventSel.multPercentileMax; + Filter hfCandSelFilter = aod::fdhf::candidateSelFlag >= static_cast(charmHadCandSel.value); + Filter hfMcSelFilter = nabs(aod::fdhf::flagMc) == static_cast(charmHadMcSel.value); + Filter trackEtaFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta < etaTrack1Max, true); + Filter trackEtaFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta > etaTrack1Min, true); + Filter trackPtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt < ptTrack1Max, true); + Filter trackPtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt > ptTrack1Min, true); + + Preslice perCol = aod::femtodreamparticle::fdCollisionId; + + /// Partition for particle 1 + Partition partitionTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, cutBitTrack1)) && ifnode(aod::femtodreamparticle::pt * coshEta(aod::femtodreamparticle::eta) <= pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, tpcTofBitTrack1)); + + Partition partitionMcTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + (ncheckbit(aod::femtodreamparticle::cut, cutBitTrack1)) && + ifnode(aod::femtodreamparticle::pt * coshEta(aod::femtodreamparticle::eta) <= pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, tpcTofBitTrack1)); + + /// Partition for particle 2 + Partition partitionCharmHadron = aod::fdhf::bdtBkg < charmHadBkgBDTmax && aod::fdhf::bdtFD < charmHadFdBDTmax && aod::fdhf::bdtFD > charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmHadPromptBDTmin; + Partition partitionMcCharmHadron = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; + + /// Axis configurables + ConfigurableAxis dummy{"dummy", {1, 0, 1}, "dummy axis"}; + /// Binning configurables + ConfigurableAxis bin4Dkstar{"bin4Dkstar", {1500, 0., 6.}, "binning kstar for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; + ConfigurableAxis bin4DMult{"bin4DMult", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f}, "multiplicity Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; + ConfigurableAxis bin4DmT{"bin4DmT", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; + ConfigurableAxis bin4DmultPercentile{"bin4DmultPercentile", {10, 0.0f, 100.0f}, "multiplicity percentile Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; + ConfigurableAxis binInvMass{"binInvMass", {400, 2.10, 2.50}, "InvMass binning"}; + ConfigurableAxis binpTCharm{"binpTCharm", {360, 0, 36}, "pT binning of charm hadron"}; + ConfigurableAxis binTempFitVarTrack{"binTempFitVarTrack", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot (Track)"}; + ConfigurableAxis binmT{"binmT", {225, 0., 7.5}, "binning mT"}; + ConfigurableAxis binmultTempFit{"binmultTempFit", {1, 0, 1}, "multiplicity Binning for the TempFitVar plot"}; + ConfigurableAxis binMulPercentile{"binMulPercentile", {10, 0.0f, 100.0f}, "multiplicity percentile Binning"}; + ConfigurableAxis binpTTrack{"binpTTrack", {50, 0.5, 10.05}, "pT binning of the pT vs. TempFitVar plot (Track)"}; + ConfigurableAxis binEta{"binEta", {{200, -1.5, 1.5}}, "eta binning"}; + ConfigurableAxis binPhi{"binPhi", {{200, 0, 2.f * 3.14159274101257324e+00f}}, "phi binning"}; + ConfigurableAxis binkT{"binkT", {150, 0., 9.}, "binning kT"}; + ConfigurableAxis binkstar{"binkstar", {1500, 0., 6.}, "binning kstar"}; + ConfigurableAxis binNSigmaTPC{"binNSigmaTPC", {1600, -8, 8}, "Binning of Nsigma TPC plot"}; + ConfigurableAxis binNSigmaTOF{"binNSigmaTOF", {3000, -15, 15}, "Binning of the Nsigma TOF plot"}; + ConfigurableAxis binNSigmaTPCTOF{"binNSigmaTPCTOF", {3000, -15, 15}, "Binning of the Nsigma TPC+TOF plot"}; + ConfigurableAxis binTPCClusters{"binTPCClusters", {163, -0.5, 162.5}, "Binning of TPC found clusters plot"}; + // Mixing axis configurables + ConfigurableAxis mixingBinMult{"mixingBinMult", {VARIABLE_WIDTH, 0.0f, 20.0f, 60.0f, 200.0f}, "Mixing bins - multiplicity"}; + ConfigurableAxis mixingBinMultPercentile{"mixingBinMultPercentile", {VARIABLE_WIDTH, 0.0f, 100.f}, "Mixing bins - multiplicity percentile"}; + ConfigurableAxis mixingBinVztx{"mixingBinVztx", {VARIABLE_WIDTH, -10.0f, -4.f, 0.f, 4.f, 10.f}, "Mixing bins - z-vertex"}; + + ColumnBinningPolicy colBinningMult{{mixingBinVztx, mixingBinMult}, true}; + ColumnBinningPolicy colBinningMultPercentile{{mixingBinVztx, mixingBinMultPercentile}, true}; + ColumnBinningPolicy colBinningMultMultPercentile{{mixingBinVztx, mixingBinMult, mixingBinMultPercentile}, true}; + + FemtoDreamContainer sameEventCont; + FemtoDreamContainer mixedEventCont; + FemtoDreamPairCleaner pairCleaner; + FemtoDreamDetaDphiStar pairCloseRejectionSE; + FemtoDreamDetaDphiStar pairCloseRejectionME; + + femtodreamcollision::BitMaskType bitMask = 1 << 0; /// Histogramming for particle 1 FemtoDreamParticleHisto allTrackHisto; @@ -181,29 +214,12 @@ struct HfTaskCharmHadronsFemtoDream { HistogramRegistry registry{"CorrelationsAndQA", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry registryMixQa{"registryMixQa"}; HistogramRegistry registryCharmHadronQa{"registryCharmHadronQa"}; - /// Partition for particle 1 - - Partition partitionTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, cutBitTrack1)) && ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, tpcTofBitTrack1)); - - Partition partitionMcTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && - (ncheckbit(aod::femtodreamparticle::cut, cutBitTrack1)) && - ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, tpcTofBitTrack1)); - - /// Partition for particle 2 - Partition partitionCharmHadron = aod::fdhf::bdtBkg < charmHadBkgBDTmax && aod::fdhf::bdtFD < charmHadFdBDTmax && aod::fdhf::bdtFD > charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmHadPromptBDTmin; - Partition partitionMcCharmHadron = aod::fdhf::originMcRec == 1 || aod::fdhf::originMcRec == 2; float massOne = o2::analysis::femtoDream::getMass(pdgCodeTrack1); float massTwo = o2::analysis::femtoDream::getMass(charmHadPDGCode); int8_t partSign = 0; int64_t processType = 0; - SliceCache cache; - Preslice perCol = aod::femtodreamparticle::fdCollisionId; - Produces rowFemtoResultCharm; - Produces rowFemtoResultTrk; - Produces rowFemtoResultColl; - void init(InitContext& /*context*/) { // setup columnpolicy for binning @@ -249,6 +265,30 @@ struct HfTaskCharmHadronsFemtoDream { registryMixQa.fill(HIST("MixingQA/hSECollisionPool"), col.posZ(), col.multNtr()); } + /// Compute the charm hadron candidates mass with the daughter masses + /// assumes the candidate is either a D+ or Λc+ + template + float getCharmHadronMass(const Candidate& cand) + { + float invMass = 0.0f; + if (charmHadPDGCode == o2::constants::physics::Pdg::kLambdaCPlus) { + if (cand.candidateSelFlag() == 1) { + invMass = cand.m(std::array{o2::constants::physics::MassProton, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); + return invMass; + } else { + invMass = cand.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); + return invMass; + } + } + // D+ → π K π (PDG: 411) + if (charmHadPDGCode == o2::constants::physics::Pdg::kDPlus) { + invMass = cand.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); + return invMass; + } + // Add more channels as needed + return invMass; + } + /// This function processes the same event and takes care of all the histogramming template void doSameEvent(PartitionType& sliceTrk1, CandType& sliceCharmHad, TableTracks const& parts, Collision const& col) @@ -270,9 +310,10 @@ struct HfTaskCharmHadronsFemtoDream { continue; } + constexpr int CutBitChargePositive = 2; // proton track charge float chargeTrack = 0.; - if ((p1.cut() & 2) == 2) { + if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) { chargeTrack = PositiveCharge; } else { chargeTrack = NegativeCharge; @@ -283,12 +324,7 @@ struct HfTaskCharmHadronsFemtoDream { continue; } - float invMass; - if (p2.candidateSelFlag() == 1) { - invMass = p2.m(std::array{o2::constants::physics::MassProton, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); - } else { - invMass = p2.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); - } + float invMass = getCharmHadronMass(p2); if (invMass < charmHadMinInvMass || invMass > charmHadMaxInvMass) { continue; @@ -298,7 +334,7 @@ struct HfTaskCharmHadronsFemtoDream { continue; } /// Filling QA histograms of the selected tracks - selectedTrackHisto.fillQA(p1, static_cast(ConfTempFitVarMomentum.value), col.multNtr(), col.multV0M()); + selectedTrackHisto.fillQA(p1, static_cast(confTempFitVarMomentum.value), col.multNtr(), col.multV0M()); int charmHadMc = 0; int originType = 0; @@ -349,13 +385,13 @@ struct HfTaskCharmHadronsFemtoDream { { // Mixed events that contain the pair of interest - Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & BitMask) == BitMask; - PartitionMaskedCol1.bindTable(cols); + Partition partitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & bitMask) == bitMask; + partitionMaskedCol1.bindTable(cols); - Partition PartitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & BitMask) == BitMask; - PartitionMaskedCol2.bindTable(cols); + Partition partitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & bitMask) == bitMask; + partitionMaskedCol2.bindTable(cols); - for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockFullIndexPolicy(policy, mixingDepth.value, -1, *PartitionMaskedCol1.mFiltered, *PartitionMaskedCol2.mFiltered))) { + for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockFullIndexPolicy(policy, mixingDepth.value, -1, *partitionMaskedCol1.mFiltered, *partitionMaskedCol2.mFiltered))) { // make sure that tracks in the same events are not mixed if (collision1.globalIndex() == collision2.globalIndex()) { continue; @@ -366,7 +402,7 @@ struct HfTaskCharmHadronsFemtoDream { auto sliceTrk1 = part1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); auto sliceCharmHad = part2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(sliceTrk1, sliceCharmHad))) { + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(sliceTrk1, sliceCharmHad))) { if (useCPR.value) { if (pairCloseRejectionME.isClosePair(p1, p2, parts, collision1.magField())) { @@ -381,12 +417,8 @@ struct HfTaskCharmHadronsFemtoDream { if (kstar > highkstarCut) { continue; } - float invMass; - if (p2.candidateSelFlag() == 1) { - invMass = p2.m(std::array{o2::constants::physics::MassProton, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); - } else { - invMass = p2.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); - } + + float invMass = getCharmHadronMass(p2); if (invMass < charmHadMinInvMass || invMass > charmHadMaxInvMass) { continue; @@ -411,19 +443,14 @@ struct HfTaskCharmHadronsFemtoDream { auto sliceCharmHad = partitionCharmHadron->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); /// Filling QA histograms of the all tracks and all charm hadrons before pairing for (auto const& part : sliceTrk1) { - allTrackHisto.fillQA(part, static_cast(ConfTempFitVarMomentum.value), col.multNtr(), col.multV0M()); + allTrackHisto.fillQA(part, static_cast(confTempFitVarMomentum.value), col.multNtr(), col.multV0M()); } for (auto const& part : sliceCharmHad) { - float invMass; - if (part.candidateSelFlag() == 1) { - invMass = part.m(std::array{o2::constants::physics::MassProton, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); - } else { - invMass = part.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); - } + float invMass = getCharmHadronMass(part); registryCharmHadronQa.fill(HIST("CharmHadronQA/hPtVsMass"), part.pt(), invMass); } - if ((col.bitmaskTrackOne() & BitMask) != BitMask || (col.bitmaskTrackTwo() & BitMask) != BitMask) { + if ((col.bitmaskTrackOne() & bitMask) != bitMask || (col.bitmaskTrackTwo() & bitMask) != bitMask) { return; } doSameEvent(sliceTrk1, sliceCharmHad, parts, col); @@ -470,10 +497,10 @@ struct HfTaskCharmHadronsFemtoDream { } /// Filling QA histograms of the all mc tracks before pairing for (auto const& part : sliceMcTrk1) { - allTrackHisto.fillQA(part, static_cast(ConfTempFitVarMomentum.value), col.multNtr(), col.multV0M()); + allTrackHisto.fillQA(part, static_cast(confTempFitVarMomentum.value), col.multNtr(), col.multV0M()); } - if ((col.bitmaskTrackOne() & BitMask) != BitMask || (col.bitmaskTrackTwo() & BitMask) != BitMask) { + if ((col.bitmaskTrackOne() & bitMask) != bitMask || (col.bitmaskTrackTwo() & bitMask) != bitMask) { return; } doSameEvent(sliceMcTrk1, sliceMcCharmHad, parts, col);