diff --git a/PWGHF/DataModel/CandidateReconstructionTables.h b/PWGHF/DataModel/CandidateReconstructionTables.h index 5df712115b9..568e14a40b6 100644 --- a/PWGHF/DataModel/CandidateReconstructionTables.h +++ b/PWGHF/DataModel/CandidateReconstructionTables.h @@ -1768,7 +1768,7 @@ namespace hf_cand_xic_to_xi_pi_pi { DECLARE_SOA_INDEX_COLUMN_FULL(Pi0, pi0, int, Tracks, "_pi0"); DECLARE_SOA_INDEX_COLUMN_FULL(Pi1, pi1, int, Tracks, "_pi1"); -DECLARE_SOA_COLUMN(Sign, sign, float); +DECLARE_SOA_COLUMN(Sign, sign, int8_t); DECLARE_SOA_COLUMN(InvMassXicPlus, invMassXicPlus, float); DECLARE_SOA_COLUMN(InvMassXi, invMassXi, float); DECLARE_SOA_COLUMN(InvMassLambda, invMassLambda, float); diff --git a/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx index 18ef07264db..d12c5d799d2 100644 --- a/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx @@ -300,7 +300,7 @@ struct HfCandidateCreatorXicToXiPiPi { //----------------------------calculate physical properties----------------------- // Charge of charm baryon - int signXic = casc.sign() < 0 ? +1 : -1; + int8_t signXic = casc.sign() < 0 ? +1 : -1; // get SV properties const auto& secondaryVertex = df.getPCACandidate(); @@ -561,7 +561,7 @@ struct HfCandidateCreatorXicToXiPiPi { //---------------------calculate physical parameters of XicPlus candidate---------------------- // sign of charm baryon - int signXic = casc.sign() < 0 ? +1 : -1; + int8_t signXic = casc.sign() < 0 ? +1 : -1; // transport XicPlus daughters to XicPlus decay vertex (secondary vertex) float secondaryVertex[3] = {0.}; @@ -1073,7 +1073,7 @@ struct HfCandidateCreatorXicToXiPiPiExpressions { // Fill tables rowMcMatchRec(flag, origin); - if (fillResidualTable) { + if (flag != 0 && fillResidualTable) { rowResiduals(origin, momentumResiduals[0], momentumResiduals[1], pvResiduals[0], pvResiduals[1], pvResiduals[2], pvPulls[0], pvPulls[1], pvPulls[2], diff --git a/PWGHF/TableProducer/candidateSelectorXicToXiPiPi.cxx b/PWGHF/TableProducer/candidateSelectorXicToXiPiPi.cxx index addb435e4a5..bb0bbf04c78 100644 --- a/PWGHF/TableProducer/candidateSelectorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorXicToXiPiPi.cxx @@ -110,7 +110,8 @@ struct HfCandidateSelectorXicToXiPiPi { TpcTrackQualityPiFromCharm, ItsTrackQualityPiFromCharm, PidSelected, - BdtSelected }; + BdtSelected, + NSelectionCriteria }; using TracksExtraWPid = soa::Join; @@ -118,6 +119,10 @@ struct HfCandidateSelectorXicToXiPiPi { void init(InitContext&) { + if ((doprocessData + doprocessMc) != 1) { + LOGP(fatal, "Enable exactly one process function at a time."); + } + if (usePid) { // pion selectorPion.setRangePtTpc(ptPidTpcMin, ptPidTpcMax); @@ -136,22 +141,36 @@ struct HfCandidateSelectorXicToXiPiPi { } if (fillHistogram) { - registry.add("hSelCandidates", ";;entries", {HistType::kTH1F, {{15, -0.5, 14.5}}}); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + All, "All"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + Pt, "#it{p}_{T}"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + Mass, "#Delta M"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + Rapidity, "y"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + Eta, "#eta"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + EtaDaughters, "#eta final state daughters"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + PtPionFromXicPlus, "#it{p}_{T} (#pi #leftarrow #Xi_{c}^{+})"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + Chi2SV, "#chi^{2}_{SV}"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + MinDecayLength, "Decay length"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + MaxInvMassXiPiPairs, "M_{#Xi #pi}"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + TpcTrackQualityXiDaughters, "TPC track quality selection on #Xi daughters"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + TpcTrackQualityPiFromCharm, "TPC track quality selection on #pi #leftarrow #Xi_{c}^{+}"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + ItsTrackQualityPiFromCharm, "ITS track quality selection on #pi #leftarrow #Xi_{c}^{+}"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + PidSelected, "PID selection"); - registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(1 + BdtSelected, "BDT selection"); + std::string labels[NSelectionCriteria]; + labels[All] = "All"; + labels[Pt] = "#it{p}_{T}"; + labels[Mass] = "#Delta M"; + labels[Rapidity] = "y"; + labels[Eta] = "#eta"; + labels[EtaDaughters] = "#eta final state daughters"; + labels[PtPionFromXicPlus] = "#it{p}_{T} (#pi #leftarrow #Xi_{c}^{+})"; + labels[Chi2SV] = "#chi^{2}_{SV}"; + labels[MinDecayLength] = "Decay length"; + labels[MaxInvMassXiPiPairs] = "M_{#Xi #pi}"; + labels[TpcTrackQualityXiDaughters] = "TPC track quality selection on #Xi daughters"; + labels[TpcTrackQualityPiFromCharm] = "TPC track quality selection on #pi #leftarrow #Xi_{c}^{+}"; + labels[ItsTrackQualityPiFromCharm] = "ITS track quality selection on #pi #leftarrow #Xi_{c}^{+}"; + labels[PidSelected] = "PID selection"; + labels[BdtSelected] = "BDT selection"; + + if (doprocessData) { + registry.add("hSelCandidates", ";;entries", {HistType::kTH1F, {{NSelectionCriteria, -0.5f, +NSelectionCriteria - 0.5f}}}); + for (int iBin = 0; iBin < NSelectionCriteria; ++iBin) { + registry.get(HIST("hSelCandidates"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); + } + } else if (doprocessMc) { + registry.add("hSelCandidatesRecSig", ";;entries", {HistType::kTH1F, {{NSelectionCriteria, -0.5f, +NSelectionCriteria - 0.5f}}}); + registry.add("hSelCandidatesRecBkg", ";;entries", {HistType::kTH1F, {{NSelectionCriteria, -0.5f, +NSelectionCriteria - 0.5f}}}); + for (int iBin = 0; iBin < NSelectionCriteria; ++iBin) { + registry.get(HIST("hSelCandidatesRecSig"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); + registry.get(HIST("hSelCandidatesRecBkg"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); + } + } } if (applyMl) { @@ -167,31 +186,87 @@ struct HfCandidateSelectorXicToXiPiPi { } } - /// Conjugate-independent topological cuts - /// \param candidate is candidate - /// \return true if candidate passes all cuts - template - bool isSelectedXic(const T1& hfCandXic, - const float& etaPi0, - const float& etaPi1, - const float& etaPiFromXi, - const float& etaV0PosDau, - const float& etaV0NegDau) + /// Apply PID selection + /// \param statusPidPi0 PID status of prong1 with pion hypothesis + /// \param statusPidPi1 PID status of prong2 with pion hypothesis + /// \param statusPidPiXi PID status of bachelor track with pion hypothesis + /// \param statusPidPrLam PID status of V0 daughter with proton hypothesis + /// \param statusPidPiLam PID status of V0 daughter with pion hypothesis + /// \param usePidTpcOnly switch to check only TPC status + /// \return true if prongs of Xic candidate pass all PID selections + bool isSelectedPid(TrackSelectorPID::Status const statusPidPi0, + TrackSelectorPID::Status const statusPidPi1, + TrackSelectorPID::Status const statusPidPiXi, + TrackSelectorPID::Status const statusPidPrLam, + TrackSelectorPID::Status const statusPidPiLam, + bool const useTpcPidOnly) + { + if (useTpcPidOnly) { + if ((statusPidPi0 != TrackSelectorPID::Accepted && statusPidPi0 != TrackSelectorPID::NotApplicable) || (statusPidPi1 != TrackSelectorPID::Accepted && statusPidPi1 != TrackSelectorPID::NotApplicable) || (statusPidPiXi != TrackSelectorPID::Accepted && statusPidPiXi != TrackSelectorPID::NotApplicable) || (statusPidPrLam != TrackSelectorPID::Accepted && statusPidPrLam != TrackSelectorPID::NotApplicable) || (statusPidPiLam != TrackSelectorPID::Accepted && statusPidPiLam != TrackSelectorPID::NotApplicable)) { + return false; + } + return true; + } + if (statusPidPi0 == TrackSelectorPID::Rejected || statusPidPi1 == TrackSelectorPID::Rejected || statusPidPiXi == TrackSelectorPID::Rejected || statusPidPrLam == TrackSelectorPID::Rejected || statusPidPiLam == TrackSelectorPID::Rejected) { + return false; + } + return true; + } + + /// Combine kinematic, topological, track quality and PID selections + /// \param hfCandXic Xic candidate + /// \param statusXicToXiPiPi Flag to store selection status as defined in hf_sel_candidate_xic::XicToXiPiPiSelectionStep + /// \param isMatchedSignal Flag to indicate if the candidate is matched to a genereated XiCplus MC particle + /// \return true if Xic candidate passes all selections, otherwise false + template + bool isSelectedXicToXiPiPiCandidateWoMl(XicCandidate const& hfCandXic, + TracksExtraWPid const&, + int& statusXicToXiPiPi, + bool const isMatchedSignal = false) { - auto candpT = hfCandXic.pt(); - int pTBin = findBin(binsPt, candpT); + // Successful reconstruction + SETBIT(statusXicToXiPiPi, hf_sel_candidate_xic::XicToXiPiPiSelectionStep::RecoTotal); // RecoTotal = 0 --> statusXicToXiPiPi += 1 + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), All); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), All); + } else if (fillHistogram && !isMc) { + registry.fill(HIST("hSelCandidates"), All); + } + + // Retrieve daughter tracks + auto trackPi0 = hfCandXic.template pi0_as(); + auto trackPi1 = hfCandXic.template pi1_as(); + auto trackPiFromXi = hfCandXic.template bachelor_as(); + auto trackV0PosDau = hfCandXic.template posTrack_as(); + auto trackV0NegDau = hfCandXic.template negTrack_as(); + + //////////////////////////////////////////////// + // Kinematic and topological selection // + //////////////////////////////////////////////// + + // check whether candidate is in analyzed pT range + auto ptCandXic = hfCandXic.pt(); + int pTBin = findBin(binsPt, ptCandXic); if (pTBin == -1) { return false; } - if (fillHistogram) { + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), Pt); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), Pt); + } else if (fillHistogram && !isMc) { registry.fill(HIST("hSelCandidates"), Pt); } - // check whether candidate mass is within a defined mass window if (std::abs(hfCandXic.invMassXicPlus() - o2::constants::physics::MassXiCPlus) > cuts->get(pTBin, "m")) { return false; } - if (fillHistogram) { + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), Mass); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), Mass); + } else if (fillHistogram && !isMc) { registry.fill(HIST("hSelCandidates"), Mass); } @@ -199,7 +274,11 @@ struct HfCandidateSelectorXicToXiPiPi { if (std::abs(hfCandXic.y(o2::constants::physics::MassXiCPlus)) > cuts->get(pTBin, "y")) { return false; } - if (fillHistogram) { + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), Rapidity); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), Rapidity); + } else if (fillHistogram && !isMc) { registry.fill(HIST("hSelCandidates"), Rapidity); } @@ -207,15 +286,23 @@ struct HfCandidateSelectorXicToXiPiPi { if (std::abs(hfCandXic.eta()) > cuts->get(pTBin, "eta")) { return false; } - if (fillHistogram) { + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), Eta); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), Eta); + } else if (fillHistogram && !isMc) { registry.fill(HIST("hSelCandidates"), Eta); } // cut on pseudorapidity of final state daughters - if (std::abs(etaPi0) > cuts->get(pTBin, "eta Daughters") || std::abs(etaPi1) > cuts->get(pTBin, "eta Daughters") || std::abs(etaPiFromXi) > cuts->get(pTBin, "eta Daughters") || std::abs(etaV0PosDau) > cuts->get(pTBin, "eta Daughters") || std::abs(etaV0NegDau) > cuts->get(pTBin, "eta Daughters")) { + if (std::abs(trackPi0.eta()) > cuts->get(pTBin, "eta Daughters") || std::abs(trackPi1.eta()) > cuts->get(pTBin, "eta Daughters") || std::abs(trackPiFromXi.eta()) > cuts->get(pTBin, "eta Daughters") || std::abs(trackV0PosDau.eta()) > cuts->get(pTBin, "eta Daughters") || std::abs(trackV0NegDau.eta()) > cuts->get(pTBin, "eta Daughters")) { return false; } - if (fillHistogram) { + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), EtaDaughters); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), EtaDaughters); + } else if (fillHistogram && !isMc) { registry.fill(HIST("hSelCandidates"), EtaDaughters); } @@ -223,7 +310,11 @@ struct HfCandidateSelectorXicToXiPiPi { if (hfCandXic.ptProng1() < cuts->get(pTBin, "pT Pi0") || hfCandXic.ptProng2() < cuts->get(pTBin, "pT Pi1")) { return false; } - if (fillHistogram) { + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), PtPionFromXicPlus); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), PtPionFromXicPlus); + } else if (fillHistogram && !isMc) { registry.fill(HIST("hSelCandidates"), PtPionFromXicPlus); } @@ -231,7 +322,11 @@ struct HfCandidateSelectorXicToXiPiPi { if (hfCandXic.chi2PCA() > cuts->get(pTBin, "chi2SV")) { return false; } - if (fillHistogram) { + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), Chi2SV); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), Chi2SV); + } else if (fillHistogram && !isMc) { registry.fill(HIST("hSelCandidates"), Chi2SV); } @@ -239,7 +334,11 @@ struct HfCandidateSelectorXicToXiPiPi { if (hfCandXic.decayLength() < cuts->get(pTBin, "min decay length") || hfCandXic.decayLengthXY() < cuts->get(pTBin, "min decay length XY")) { return false; } - if (fillHistogram) { + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), MinDecayLength); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), MinDecayLength); + } else if (fillHistogram && !isMc) { registry.fill(HIST("hSelCandidates"), MinDecayLength); } @@ -247,42 +346,171 @@ struct HfCandidateSelectorXicToXiPiPi { if (hfCandXic.invMassXiPi0() > cuts->get(pTBin, "max inv mass Xi-Pi0") || hfCandXic.invMassXiPi1() > cuts->get(pTBin, "max inv mass Xi-Pi1")) { return false; } - if (fillHistogram) { + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), MaxInvMassXiPiPairs); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), MaxInvMassXiPiPairs); + } else if (fillHistogram && !isMc) { registry.fill(HIST("hSelCandidates"), MaxInvMassXiPiPairs); } - return true; - } + // Successful kinematic and topological selection + SETBIT(statusXicToXiPiPi, hf_sel_candidate_xic::XicToXiPiPiSelectionStep::RecoKinTopol); // RecoKinTopol = 1 --> statusXicToXiPiPi += 2 + + //////////////////////////////////////////////// + // Track quality selection // + //////////////////////////////////////////////// + if (doTrackQualitySelection) { + // TPC track quality selection on Xi daughters (bachelor pion and V0 daughters) + if (!isSelectedTrackTpcQuality(trackPiFromXi, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax) || + !isSelectedTrackTpcQuality(trackV0PosDau, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax) || + !isSelectedTrackTpcQuality(trackV0NegDau, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { + return false; + } + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), TpcTrackQualityXiDaughters); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), TpcTrackQualityXiDaughters); + } else if (fillHistogram && !isMc) { + registry.fill(HIST("hSelCandidates"), TpcTrackQualityXiDaughters); + } - /// Apply PID selection - /// \param statusPidPi0 PID status of trackPi0 (prong1 of Xic candidate) - /// \param statusPidPi1 PID status of trackPi1 (prong2 of Xic candidate) - /// \param statusPidPiXi PID status of trackPiXi (Bachelor of cascade candidate) - /// \param statusPidPrLam PID status of trackPr (positive daughter of V0 candidate) - /// \param statusPidPiLam PID status of trackPiLam (negative daughter of V0 candidate) - /// \param usePidTpcOnly switch to check only TPC status - /// \return true if prongs of Xic candidate pass all selections - bool selectionPid(TrackSelectorPID::Status const statusPidPi0, - TrackSelectorPID::Status const statusPidPi1, - TrackSelectorPID::Status const statusPidPiXi, - TrackSelectorPID::Status const statusPidPrLam, - TrackSelectorPID::Status const statusPidPiLam, - bool const useTpcPidOnly) - { - if (useTpcPidOnly) { - if ((statusPidPi0 != TrackSelectorPID::Accepted && statusPidPi0 != TrackSelectorPID::NotApplicable) || (statusPidPi1 != TrackSelectorPID::Accepted && statusPidPi1 != TrackSelectorPID::NotApplicable) || (statusPidPiXi != TrackSelectorPID::Accepted && statusPidPiXi != TrackSelectorPID::NotApplicable) || (statusPidPrLam != TrackSelectorPID::Accepted && statusPidPrLam != TrackSelectorPID::NotApplicable) || (statusPidPiLam != TrackSelectorPID::Accepted && statusPidPiLam != TrackSelectorPID::NotApplicable)) { + // TPC track quality selection on pions from charm baryon + if (!isSelectedTrackTpcQuality(trackPi0, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax) || + !isSelectedTrackTpcQuality(trackPi1, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { return false; } - return true; + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), TpcTrackQualityPiFromCharm); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), TpcTrackQualityPiFromCharm); + } else if (fillHistogram && !isMc) { + registry.fill(HIST("hSelCandidates"), TpcTrackQualityPiFromCharm); + } + + // ITS track quality selection on pions from charm baryon + if ((!isSelectedTrackItsQuality(trackPi0, nClustersItsMin, itsChi2PerClusterMax) || trackPi0.itsNClsInnerBarrel() < nClustersItsInnBarrMin) || + (!isSelectedTrackItsQuality(trackPi0, nClustersItsMin, itsChi2PerClusterMax) || trackPi1.itsNClsInnerBarrel() < nClustersItsInnBarrMin)) { + return false; + } + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), ItsTrackQualityPiFromCharm); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), ItsTrackQualityPiFromCharm); + } else if (fillHistogram && !isMc) { + registry.fill(HIST("hSelCandidates"), ItsTrackQualityPiFromCharm); + } + + // Successful track quality selection + SETBIT(statusXicToXiPiPi, hf_sel_candidate_xic::XicToXiPiPiSelectionStep::RecoTrackQuality); // RecoTrackQuality = 2 --> statusXicToXiPiPi += 4 + } else if (fillHistogram) { + if (isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), TpcTrackQualityXiDaughters); + registry.fill(HIST("hSelCandidatesRecSig"), TpcTrackQualityPiFromCharm); + registry.fill(HIST("hSelCandidatesRecSig"), ItsTrackQualityPiFromCharm); + } else if (isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), TpcTrackQualityXiDaughters); + registry.fill(HIST("hSelCandidatesRecBkg"), TpcTrackQualityPiFromCharm); + registry.fill(HIST("hSelCandidatesRecBkg"), ItsTrackQualityPiFromCharm); + } else if (!isMc) { + registry.fill(HIST("hSelCandidates"), TpcTrackQualityXiDaughters); + registry.fill(HIST("hSelCandidates"), TpcTrackQualityPiFromCharm); + registry.fill(HIST("hSelCandidates"), ItsTrackQualityPiFromCharm); + } } - if (statusPidPi0 == TrackSelectorPID::Rejected || statusPidPi1 == TrackSelectorPID::Rejected || statusPidPiXi == TrackSelectorPID::Rejected || statusPidPrLam == TrackSelectorPID::Rejected || statusPidPiLam == TrackSelectorPID::Rejected) { - return false; + + //////////////////////////////////////////////// + // PID selection // + //////////////////////////////////////////////// + if (usePid) { + TrackSelectorPID::Status statusPidPi0 = TrackSelectorPID::NotApplicable; + TrackSelectorPID::Status statusPidPi1 = TrackSelectorPID::NotApplicable; + TrackSelectorPID::Status statusPidPiXi = TrackSelectorPID::NotApplicable; + TrackSelectorPID::Status statusPidPrLam = TrackSelectorPID::NotApplicable; + TrackSelectorPID::Status statusPidPiLam = TrackSelectorPID::NotApplicable; + + // assign proton and pion hypothesis to V0 daughters + auto trackPr = trackV0PosDau; + auto trackPiFromLam = trackV0NegDau; + if (hfCandXic.sign() < 0) { + trackPr = trackV0NegDau; + trackPiFromLam = trackV0PosDau; + } + + if (useTpcPidOnly) { + statusPidPi0 = selectorPion.statusTpc(trackPi0); + statusPidPi1 = selectorPion.statusTpc(trackPi1); + statusPidPiXi = selectorPion.statusTpc(trackPiFromXi); + statusPidPrLam = selectorProton.statusTpc(trackPr); + statusPidPiLam = selectorPion.statusTpc(trackPiFromLam); + } else { + statusPidPi0 = selectorPion.statusTpcOrTof(trackPi0); + statusPidPi1 = selectorPion.statusTpcOrTof(trackPi1); + statusPidPiXi = selectorPion.statusTpcOrTof(trackPiFromXi); + statusPidPrLam = selectorProton.statusTpcOrTof(trackPr); + statusPidPiLam = selectorPion.statusTpcOrTof(trackPiFromLam); + } + + if (!isSelectedPid(statusPidPi0, statusPidPi1, statusPidPiXi, statusPidPrLam, statusPidPiLam, useTpcPidOnly.value)) { + return false; + } + + // Successful PID selection + SETBIT(statusXicToXiPiPi, hf_sel_candidate_xic::XicToXiPiPiSelectionStep::RecoPID); // RecoPID = 3 --> statusXicToXiPiPi += 8 + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), PidSelected); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), PidSelected); + } else if (fillHistogram && !isMc) { + registry.fill(HIST("hSelCandidates"), PidSelected); + } + } else if (fillHistogram) { + if (isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), PidSelected); + } else if (isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), PidSelected); + } else { + registry.fill(HIST("hSelCandidates"), PidSelected); + } } + return true; } - void process(aod::HfCandXic const& hfCandsXic, - TracksExtraWPid const&) + /// Apply BDT selection + /// \param hfCandXic Xic candidate + /// \param statusXicToXiPiPi Flag to store selection status as defined in hf_sel_candidate_xic::XicToXiPiPiSelectionStep + /// \param isMatchedSignal Flag to indicate if the candidate is matched to a genereated XiCplus MC particle + template + void isBdtSelected(XicCandidate const& hfCandXic, + int& statusXicToXiPiPi, + bool const isMatchedSignal = false) + { + bool isSelectedMlXicToXiPiPi = false; + float ptCandXic = hfCandXic.pt(); + + std::vector inputFeaturesXicToXiPiPi = hfMlResponse.getInputFeatures(hfCandXic); + isSelectedMlXicToXiPiPi = hfMlResponse.isSelectedMl(inputFeaturesXicToXiPiPi, ptCandXic, outputMlXicToXiPiPi); + + hfMlXicToXiPiPiCandidate(outputMlXicToXiPiPi); + + if (!isSelectedMlXicToXiPiPi) { + return; + } + + // Successful ML selection + SETBIT(statusXicToXiPiPi, hf_sel_candidate_xic::XicToXiPiPiSelectionStep::RecoMl); // RecoPID = 4 --> statusXicToXiPiPi += 16 + if (fillHistogram && isMc && isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecSig"), BdtSelected); + } else if (fillHistogram && isMc && !isMatchedSignal) { + registry.fill(HIST("hSelCandidatesRecBkg"), BdtSelected); + } else if (fillHistogram && !isMc) { + registry.fill(HIST("hSelCandidates"), BdtSelected); + } + } + + void processData(aod::HfCandXic const& hfCandsXic, + TracksExtraWPid const& tracks) { for (const auto& hfCandXic : hfCandsXic) { int statusXicToXiPiPi = 0; @@ -290,144 +518,63 @@ struct HfCandidateSelectorXicToXiPiPi { outputMlXicToXiPiPi.clear(); } - float ptCandXic = hfCandXic.pt(); - auto trackPi0 = hfCandXic.pi0_as(); - auto trackPi1 = hfCandXic.pi1_as(); - auto trackPiFromXi = hfCandXic.bachelor_as(); - auto trackV0PosDau = hfCandXic.posTrack_as(); - auto trackV0NegDau = hfCandXic.negTrack_as(); - - // Succesful reconstruction - SETBIT(statusXicToXiPiPi, hf_sel_candidate_xic::XicToXiPiPiSelectionStep::RecoTotal); // RecoTotal = 0 --> statusXicToXiPiPi += 1 - - // kinematic and topological selection - if (!isSelectedXic(hfCandXic, trackPi0.eta(), trackPi1.eta(), trackPiFromXi.eta(), trackV0PosDau.eta(), trackV0NegDau.eta())) { + // Kinematic, topological, track quality and PID selections + if (!isSelectedXicToXiPiPiCandidateWoMl(hfCandXic, tracks, statusXicToXiPiPi)) { hfSelXicToXiPiPiCandidate(statusXicToXiPiPi); if (applyMl) { hfMlXicToXiPiPiCandidate(outputMlXicToXiPiPi); } continue; } - SETBIT(statusXicToXiPiPi, hf_sel_candidate_xic::XicToXiPiPiSelectionStep::RecoKinTopol); // RecoKinTopol = 1 --> statusXicToXiPiPi += 2 - - // track quality selection - if (doTrackQualitySelection) { - if (!isSelectedTrackTpcQuality(trackPiFromXi, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax) || - !isSelectedTrackTpcQuality(trackV0PosDau, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax) || - !isSelectedTrackTpcQuality(trackV0NegDau, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { - hfSelXicToXiPiPiCandidate(statusXicToXiPiPi); - if (applyMl) { - hfMlXicToXiPiPiCandidate(outputMlXicToXiPiPi); - } - continue; - } - if (fillHistogram) { - registry.fill(HIST("hSelCandidates"), TpcTrackQualityXiDaughters); - } - if (!isSelectedTrackTpcQuality(trackPi0, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax) || - !isSelectedTrackTpcQuality(trackPi1, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { - hfSelXicToXiPiPiCandidate(statusXicToXiPiPi); - if (applyMl) { - hfMlXicToXiPiPiCandidate(outputMlXicToXiPiPi); - } - continue; - } - if (fillHistogram) { - registry.fill(HIST("hSelCandidates"), TpcTrackQualityPiFromCharm); - } + // ML selection + if (applyMl) { + isBdtSelected(hfCandXic, statusXicToXiPiPi); + } else if (fillHistogram) { + registry.fill(HIST("hSelCandidates"), BdtSelected); + } - if ((!isSelectedTrackItsQuality(trackPi0, nClustersItsMin, itsChi2PerClusterMax) || trackPi0.itsNClsInnerBarrel() < nClustersItsInnBarrMin) || - (!isSelectedTrackItsQuality(trackPi0, nClustersItsMin, itsChi2PerClusterMax) || trackPi1.itsNClsInnerBarrel() < nClustersItsInnBarrMin)) { - hfSelXicToXiPiPiCandidate(statusXicToXiPiPi); - if (applyMl) { - hfMlXicToXiPiPiCandidate(outputMlXicToXiPiPi); - } - continue; - } - if (fillHistogram) { - registry.fill(HIST("hSelCandidates"), ItsTrackQualityPiFromCharm); - } + hfSelXicToXiPiPiCandidate(statusXicToXiPiPi); + } + } + PROCESS_SWITCH(HfCandidateSelectorXicToXiPiPi, processData, "Select candidates without MC matching information", true); - SETBIT(statusXicToXiPiPi, hf_sel_candidate_xic::XicToXiPiPiSelectionStep::RecoTrackQuality); // RecoTrackQuality = 2 --> statusXicToXiPiPi += 4 - } - if (!doTrackQualitySelection && fillHistogram) { - registry.fill(HIST("hSelCandidates"), TpcTrackQualityXiDaughters); - registry.fill(HIST("hSelCandidates"), TpcTrackQualityPiFromCharm); - registry.fill(HIST("hSelCandidates"), ItsTrackQualityPiFromCharm); + void processMc(soa::Join const& hfCandsXic, + TracksExtraWPid const& tracks) + { + for (const auto& hfCandXic : hfCandsXic) { + int statusXicToXiPiPi = 0; + if (applyMl) { + outputMlXicToXiPiPi.clear(); } - // track-level PID selection - if (usePid) { - TrackSelectorPID::Status statusPidPi0 = TrackSelectorPID::NotApplicable; - TrackSelectorPID::Status statusPidPi1 = TrackSelectorPID::NotApplicable; - TrackSelectorPID::Status statusPidPiXi = TrackSelectorPID::NotApplicable; - TrackSelectorPID::Status statusPidPrLam = TrackSelectorPID::NotApplicable; - TrackSelectorPID::Status statusPidPiLam = TrackSelectorPID::NotApplicable; - - // assign proton and pion hypothesis to V0 daughters - auto trackPr = trackV0PosDau; - auto trackPiFromLam = trackV0NegDau; - if (hfCandXic.sign() < 0) { - trackPr = trackV0NegDau; - trackPiFromLam = trackV0PosDau; - } - - if (useTpcPidOnly) { - statusPidPi0 = selectorPion.statusTpc(trackPi0); - statusPidPi1 = selectorPion.statusTpc(trackPi1); - statusPidPiXi = selectorPion.statusTpc(trackPiFromXi); - statusPidPrLam = selectorProton.statusTpc(trackPr); - statusPidPiLam = selectorPion.statusTpc(trackPiFromLam); - } else { - statusPidPi0 = selectorPion.statusTpcOrTof(trackPi0); - statusPidPi1 = selectorPion.statusTpcOrTof(trackPi1); - statusPidPiXi = selectorPion.statusTpcOrTof(trackPiFromXi); - statusPidPrLam = selectorProton.statusTpcOrTof(trackPr); - statusPidPiLam = selectorPion.statusTpcOrTof(trackPiFromLam); - } + bool isMatchedCandidate = false; + if (hfCandXic.flagMcMatchRec() != int8_t(0)) { + isMatchedCandidate = true; + } - if (!selectionPid(statusPidPi0, statusPidPi1, statusPidPiXi, statusPidPrLam, statusPidPiLam, useTpcPidOnly.value)) { - hfSelXicToXiPiPiCandidate(statusXicToXiPiPi); - if (applyMl) { - hfMlXicToXiPiPiCandidate(outputMlXicToXiPiPi); - } - continue; - } - SETBIT(statusXicToXiPiPi, hf_sel_candidate_xic::XicToXiPiPiSelectionStep::RecoPID); // RecoPID = 3 --> statusXicToXiPiPi += 8 - if (fillHistogram) { - registry.fill(HIST("hSelCandidates"), PidSelected); + // Kinematic, topological, track quality and PID selections + if (!isSelectedXicToXiPiPiCandidateWoMl(hfCandXic, tracks, statusXicToXiPiPi, isMatchedCandidate)) { + hfSelXicToXiPiPiCandidate(statusXicToXiPiPi); + if (applyMl) { + hfMlXicToXiPiPiCandidate(outputMlXicToXiPiPi); } - } - if (!usePid && fillHistogram) { - registry.fill(HIST("hSelCandidates"), PidSelected); + continue; } // ML selection if (applyMl) { - bool isSelectedMlXicToXiPiPi = false; - std::vector inputFeaturesXicToXiPiPi = hfMlResponse.getInputFeatures(hfCandXic); - - isSelectedMlXicToXiPiPi = hfMlResponse.isSelectedMl(inputFeaturesXicToXiPiPi, ptCandXic, outputMlXicToXiPiPi); - - hfMlXicToXiPiPiCandidate(outputMlXicToXiPiPi); - - if (!isSelectedMlXicToXiPiPi) { - hfSelXicToXiPiPiCandidate(statusXicToXiPiPi); - continue; - } - SETBIT(statusXicToXiPiPi, hf_sel_candidate_xic::XicToXiPiPiSelectionStep::RecoMl); // RecoPID = 4 --> statusXicToXiPiPi += 16 - if (fillHistogram) { - registry.fill(HIST("hSelCandidates"), BdtSelected); - } - } - if (!applyMl && fillHistogram) { - registry.fill(HIST("hSelCandidates"), BdtSelected); + isBdtSelected(hfCandXic, statusXicToXiPiPi, isMatchedCandidate); + } else if (fillHistogram && isMatchedCandidate) { + registry.fill(HIST("hSelCandidatesRecSig"), BdtSelected); + } else if (fillHistogram && !isMatchedCandidate) { + registry.fill(HIST("hSelCandidatesRecBkg"), BdtSelected); } hfSelXicToXiPiPiCandidate(statusXicToXiPiPi); } } + PROCESS_SWITCH(HfCandidateSelectorXicToXiPiPi, processMc, "Select candidates with MC matching information", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx index 5f8e44e4a4b..4a90516eaa2 100644 --- a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx @@ -43,6 +43,7 @@ namespace o2::aod { namespace full { +DECLARE_SOA_COLUMN(ParticleFlag, particleFlag, int8_t); //! hf_cand_xic_to_xi_pi_pi::Sign for data, hf_cand_xic_to_xi_pi_pi::FlagMcMatchRec for MC DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int); //! Selection flag of candidate (output of candidateSelector) // vertices DECLARE_SOA_COLUMN(Chi2SV, chi2SV, float); //! Chi2 of candidate vertex @@ -79,10 +80,9 @@ DECLARE_SOA_COLUMN(MaxNormalisedDeltaIP, maxNormalisedDeltaIP, float); } // namespace full DECLARE_SOA_TABLE(HfCandXicToXiPiPiLites, "AOD", "HFXICXI2PILITE", - hf_cand_xic_to_xi_pi_pi::FlagMcMatchRec, + full::ParticleFlag, hf_cand_xic_to_xi_pi_pi::OriginRec, full::CandidateSelFlag, - hf_cand_xic_to_xi_pi_pi::Sign, full::Y, full::Eta, full::Phi, @@ -117,23 +117,17 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiLites, "AOD", "HFXICXI2PILITE", full::MaxNormalisedDeltaIP); DECLARE_SOA_TABLE(HfCandXicToXiPiPiLiteKfs, "AOD", "HFXICXI2PILITKF", - hf_cand_xic_to_xi_pi_pi::FlagMcMatchRec, + full::ParticleFlag, hf_cand_xic_to_xi_pi_pi::OriginRec, full::CandidateSelFlag, - hf_cand_xic_to_xi_pi_pi::Sign, full::Y, full::Eta, full::Phi, - full::P, full::Pt, full::PtXi, full::PtPi0, full::PtPi1, full::M, - hf_cand_xic_to_xi_pi_pi::InvMassXi, - hf_cand_xic_to_xi_pi_pi::InvMassLambda, - hf_cand_xic_to_xi_pi_pi::InvMassXiPi0, - hf_cand_xic_to_xi_pi_pi::InvMassXiPi1, full::Chi2SV, full::Ct, full::DecayLength, @@ -146,6 +140,8 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiLiteKfs, "AOD", "HFXICXI2PILITKF", hf_cand_xic_to_xi_pi_pi::CpaXYXi, hf_cand_xic_to_xi_pi_pi::CpaLambda, hf_cand_xic_to_xi_pi_pi::CpaXYLambda, + hf_cand_xic_to_xi_pi_pi::CpaLambdaToXi, + hf_cand_xic_to_xi_pi_pi::CpaXYLambdaToXi, full::ImpactParameterXi, full::ImpactParameterNormalisedXi, full::ImpactParameterPi0, @@ -153,6 +149,24 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiLiteKfs, "AOD", "HFXICXI2PILITKF", full::ImpactParameterPi1, full::ImpactParameterNormalisedPi1, full::MaxNormalisedDeltaIP, + hf_cand_xic_to_xi_pi_pi::DcaXiDaughters, + hf_cand_xic_to_xi_pi_pi::DcaV0Daughters, + hf_cand_xic_to_xi_pi_pi::DcaXYCascToPV, + hf_cand_xic_to_xi_pi_pi::DcaZCascToPV, + hf_cand_xic_to_xi_pi_pi::DcaBachelorToPV, + hf_cand_xic_to_xi_pi_pi::DcaPosToPV, + hf_cand_xic_to_xi_pi_pi::DcaNegToPV, + // PID information + hf_cand_xic_to_xi_pi_pi::NSigTpcPiFromXicPlus0, + hf_cand_xic_to_xi_pi_pi::NSigTpcPiFromXicPlus1, + hf_cand_xic_to_xi_pi_pi::NSigTpcBachelorPi, + hf_cand_xic_to_xi_pi_pi::NSigTpcPiFromLambda, + hf_cand_xic_to_xi_pi_pi::NSigTpcPrFromLambda, + hf_cand_xic_to_xi_pi_pi::NSigTofPiFromXicPlus0, + hf_cand_xic_to_xi_pi_pi::NSigTofPiFromXicPlus1, + hf_cand_xic_to_xi_pi_pi::NSigTofBachelorPi, + hf_cand_xic_to_xi_pi_pi::NSigTofPiFromLambda, + hf_cand_xic_to_xi_pi_pi::NSigTofPrFromLambda, // KF specific columns full::Chi2GeoXi, full::Chi2GeoLambda, @@ -172,10 +186,9 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiLiteKfs, "AOD", "HFXICXI2PILITKF", hf_cand_xic_to_xi_pi_pi::DcaXYPi1Xi); DECLARE_SOA_TABLE(HfCandXicToXiPiPiFulls, "AOD", "HFXICXI2PIFULL", - hf_cand_xic_to_xi_pi_pi::FlagMcMatchRec, + full::ParticleFlag, hf_cand_xic_to_xi_pi_pi::OriginRec, full::CandidateSelFlag, - hf_cand_xic_to_xi_pi_pi::Sign, full::Y, full::Eta, full::Phi, @@ -235,23 +248,17 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiFulls, "AOD", "HFXICXI2PIFULL", hf_cand_xic_to_xi_pi_pi::NSigTofPrFromLambda); DECLARE_SOA_TABLE(HfCandXicToXiPiPiFullKfs, "AOD", "HFXICXI2PIFULKF", - hf_cand_xic_to_xi_pi_pi::FlagMcMatchRec, + full::ParticleFlag, hf_cand_xic_to_xi_pi_pi::OriginRec, full::CandidateSelFlag, - hf_cand_xic_to_xi_pi_pi::Sign, full::Y, full::Eta, full::Phi, - full::P, full::Pt, full::PtXi, full::PtPi0, full::PtPi1, full::M, - hf_cand_xic_to_xi_pi_pi::InvMassXi, - hf_cand_xic_to_xi_pi_pi::InvMassLambda, - hf_cand_xic_to_xi_pi_pi::InvMassXiPi0, - hf_cand_xic_to_xi_pi_pi::InvMassXiPi1, full::Chi2SV, full::Ct, full::DecayLength, @@ -264,6 +271,8 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiFullKfs, "AOD", "HFXICXI2PIFULKF", hf_cand_xic_to_xi_pi_pi::CpaXYXi, hf_cand_xic_to_xi_pi_pi::CpaLambda, hf_cand_xic_to_xi_pi_pi::CpaXYLambda, + hf_cand_xic_to_xi_pi_pi::CpaLambdaToXi, + hf_cand_xic_to_xi_pi_pi::CpaXYLambdaToXi, full::ImpactParameterXi, full::ImpactParameterNormalisedXi, full::ImpactParameterPi0, @@ -271,21 +280,25 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiFullKfs, "AOD", "HFXICXI2PIFULKF", full::ImpactParameterPi1, full::ImpactParameterNormalisedPi1, full::MaxNormalisedDeltaIP, + hf_cand_xic_to_xi_pi_pi::DcaXiDaughters, + hf_cand_xic_to_xi_pi_pi::DcaV0Daughters, + hf_cand_xic_to_xi_pi_pi::DcaXYCascToPV, + hf_cand_xic_to_xi_pi_pi::DcaZCascToPV, + hf_cand_xic_to_xi_pi_pi::DcaBachelorToPV, + hf_cand_xic_to_xi_pi_pi::DcaPosToPV, + hf_cand_xic_to_xi_pi_pi::DcaNegToPV, // additional columns only stored in the full candidate table - hf_cand_xic_to_xi_pi_pi::CpaLambdaToXi, - hf_cand_xic_to_xi_pi_pi::CpaXYLambdaToXi, + hf_cand_xic_to_xi_pi_pi::InvMassXi, + hf_cand_xic_to_xi_pi_pi::InvMassXiPi0, + hf_cand_xic_to_xi_pi_pi::InvMassXiPi1, + hf_cand_xic_to_xi_pi_pi::InvMassLambda, + full::P, full::PPi0, full::PPi1, hf_cand_xic_to_xi_pi_pi::PBachelorPi, hf_cand_xic_to_xi_pi_pi::PPiFromLambda, hf_cand_xic_to_xi_pi_pi::PPrFromLambda, - hf_cand_xic_to_xi_pi_pi::DcaXiDaughters, - hf_cand_xic_to_xi_pi_pi::DcaV0Daughters, - hf_cand_xic_to_xi_pi_pi::DcaPosToPV, - hf_cand_xic_to_xi_pi_pi::DcaNegToPV, - hf_cand_xic_to_xi_pi_pi::DcaBachelorToPV, - hf_cand_xic_to_xi_pi_pi::DcaXYCascToPV, - hf_cand_xic_to_xi_pi_pi::DcaZCascToPV, + // PID information hf_cand_xic_to_xi_pi_pi::NSigTpcPiFromXicPlus0, hf_cand_xic_to_xi_pi_pi::NSigTpcPiFromXicPlus1, hf_cand_xic_to_xi_pi_pi::NSigTpcBachelorPi, @@ -362,19 +375,18 @@ struct HfTreeCreatorXicToXiPiPi { template void fillCandidateTable(const T& candidate) { - int8_t flagMc = 0; + int8_t particleFlag = candidate.sign(); int8_t originMc = 0; if constexpr (doMc) { - flagMc = candidate.flagMcMatchRec(); + particleFlag = candidate.flagMcMatchRec(); originMc = candidate.originRec(); } if constexpr (!doKf) { if (fillCandidateLiteTable) { rowCandidateLite( - flagMc, + particleFlag, originMc, candidate.isSelXicToXiPiPi(), - candidate.sign(), candidate.y(o2::constants::physics::MassXiCPlus), candidate.eta(), candidate.phi(), @@ -409,10 +421,9 @@ struct HfTreeCreatorXicToXiPiPi { candidate.maxNormalisedDeltaIP()); } else { rowCandidateFull( - flagMc, + particleFlag, originMc, candidate.isSelXicToXiPiPi(), - candidate.sign(), candidate.y(o2::constants::physics::MassXiCPlus), candidate.eta(), candidate.phi(), @@ -474,23 +485,17 @@ struct HfTreeCreatorXicToXiPiPi { } else { if (fillCandidateLiteTable) { rowCandidateLiteKf( - flagMc, + particleFlag, originMc, candidate.isSelXicToXiPiPi(), - candidate.sign(), candidate.y(o2::constants::physics::MassXiCPlus), candidate.eta(), candidate.phi(), - candidate.p(), candidate.pt(), candidate.ptProng0(), candidate.ptProng1(), candidate.ptProng2(), candidate.invMassXicPlus(), - candidate.invMassXi(), - candidate.invMassLambda(), - candidate.invMassXiPi0(), - candidate.invMassXiPi1(), candidate.chi2PCA(), candidate.ct(o2::constants::physics::MassXiCPlus), candidate.kfDecayLength(), @@ -503,6 +508,8 @@ struct HfTreeCreatorXicToXiPiPi { candidate.cpaXYXi(), candidate.cpaLambda(), candidate.cpaXYLambda(), + candidate.cpaLambdaToXi(), + candidate.cpaXYLambdaToXi(), candidate.impactParameter0(), candidate.impactParameterNormalised0(), candidate.impactParameter1(), @@ -510,6 +517,24 @@ struct HfTreeCreatorXicToXiPiPi { candidate.impactParameter2(), candidate.impactParameterNormalised2(), candidate.maxNormalisedDeltaIP(), + candidate.dcaXiDaughters(), + candidate.dcaV0Daughters(), + candidate.dcaXYCascToPV(), + candidate.dcaZCascToPV(), + candidate.dcaBachelorToPV(), + candidate.dcaPosToPV(), + candidate.dcaNegToPV(), + // PID information + candidate.nSigTpcPiFromXicPlus0(), + candidate.nSigTpcPiFromXicPlus1(), + candidate.nSigTpcBachelorPi(), + candidate.nSigTpcPiFromLambda(), + candidate.nSigTpcPrFromLambda(), + candidate.nSigTofPiFromXicPlus0(), + candidate.nSigTofPiFromXicPlus1(), + candidate.nSigTofBachelorPi(), + candidate.nSigTofPiFromLambda(), + candidate.nSigTofPrFromLambda(), // KF-specific columns candidate.kfCascadeChi2(), candidate.kfV0Chi2(), @@ -529,23 +554,17 @@ struct HfTreeCreatorXicToXiPiPi { candidate.dcaXYPi1Xi()); } else { rowCandidateFullKf( - flagMc, + particleFlag, originMc, candidate.isSelXicToXiPiPi(), - candidate.sign(), candidate.y(o2::constants::physics::MassXiCPlus), candidate.eta(), candidate.phi(), - candidate.p(), candidate.pt(), candidate.ptProng0(), candidate.ptProng1(), candidate.ptProng2(), candidate.invMassXicPlus(), - candidate.invMassXi(), - candidate.invMassLambda(), - candidate.invMassXiPi0(), - candidate.invMassXiPi1(), candidate.chi2PCA(), candidate.ct(o2::constants::physics::MassXiCPlus), candidate.kfDecayLength(), @@ -558,6 +577,8 @@ struct HfTreeCreatorXicToXiPiPi { candidate.cpaXYXi(), candidate.cpaLambda(), candidate.cpaXYLambda(), + candidate.cpaLambdaToXi(), + candidate.cpaXYLambdaToXi(), candidate.impactParameter0(), candidate.impactParameterNormalised0(), candidate.impactParameter1(), @@ -565,21 +586,25 @@ struct HfTreeCreatorXicToXiPiPi { candidate.impactParameter2(), candidate.impactParameterNormalised2(), candidate.maxNormalisedDeltaIP(), + candidate.dcaXiDaughters(), + candidate.dcaV0Daughters(), + candidate.dcaXYCascToPV(), + candidate.dcaZCascToPV(), + candidate.dcaBachelorToPV(), + candidate.dcaPosToPV(), + candidate.dcaNegToPV(), // additional columns only stored in the full candidate table - candidate.cpaLambdaToXi(), - candidate.cpaXYLambdaToXi(), + candidate.invMassXi(), + candidate.invMassXiPi0(), + candidate.invMassXiPi1(), + candidate.invMassLambda(), + candidate.p(), candidate.pProng1(), candidate.pProng2(), candidate.pBachelorPi(), candidate.pPiFromLambda(), candidate.pPrFromLambda(), - candidate.dcaXiDaughters(), - candidate.dcaV0Daughters(), - candidate.dcaPosToPV(), - candidate.dcaNegToPV(), - candidate.dcaBachelorToPV(), - candidate.dcaXYCascToPV(), - candidate.dcaZCascToPV(), + // PID information candidate.nSigTpcPiFromXicPlus0(), candidate.nSigTpcPiFromXicPlus1(), candidate.nSigTpcBachelorPi(),