diff --git a/PWGHF/Core/DecayChannels.h b/PWGHF/Core/DecayChannels.h index 1def8cb21e0..21a94df8f10 100644 --- a/PWGHF/Core/DecayChannels.h +++ b/PWGHF/Core/DecayChannels.h @@ -27,7 +27,6 @@ namespace o2::hf_decay // TODO // - HF cascades (Λc+ → p K0short) -// - HF cascades to LF cascades (Ωc0/Ξc0 → Ξ+ π−, Ξc+ → Ξ+ π− π+) // - Σc using HfDecayChannel = int8_t; @@ -296,6 +295,21 @@ enum DecayChannelMain : HfDecayChannel { }; } // namespace hf_cand_sigmac +// @brief XiC0 and OmegaC0 candidates: main channels +namespace hf_cand_casc_bach_qa +{ +enum DecayChannelMain : HfDecayChannel { + // XiC0 + Xic0ToXiPi = 1, // Xi- π+ → Λ π- π+ → p π- π- π+ + Xic0ToOmegaK = 2, // Ω- K+ → Λ K- K+ → p π- K- K+ + // OmegaC0 + Omegac0ToOmegaPi = 3, // Ω- π+ → Λ π- π+ → p π- π- π+ + Omegac0ToOmegaK = 4, // Ω- K+ → Λ K- K+ → p π- K- K+ + Omegac0ToXiPi = 5, // Xi- π+ → Λ π- π+ → p π- π- π+ + NChannelsMain = Omegac0ToXiPi // last channel +}; +} // namespace hf_cand_casc_bach_qa + } // namespace o2::hf_decay #endif // PWGHF_CORE_DECAYCHANNELS_H_ diff --git a/PWGHF/Core/HfHelper.h b/PWGHF/Core/HfHelper.h index 155dfda35f2..9c09a3ddbf9 100644 --- a/PWGHF/Core/HfHelper.h +++ b/PWGHF/Core/HfHelper.h @@ -491,12 +491,84 @@ struct HfHelper { return candidate.m(std::array{o2::constants::physics::MassXiMinus, o2::constants::physics::MassPiPlus}); } + template + static auto invMassOmegaczeroToXiPi(const T& candidate) + { + return candidate.m(std::array{o2::constants::physics::MassXiMinus, o2::constants::physics::MassPiPlus}); + } + template static auto invMassOmegaczeroToOmegaPi(const T& candidate) { return candidate.m(std::array{o2::constants::physics::MassOmegaMinus, o2::constants::physics::MassPiPlus}); } + template + static auto invMassOmegaczeroToOmegaK(const T& candidate) + { + return candidate.m(std::array{o2::constants::physics::MassOmegaMinus, o2::constants::physics::MassKPlus}); + } + + template + static auto yXiczero(const T& candidate) + { + return candidate.y(o2::constants::physics::MassXiC0); + } + + template + static auto eXiczero(const T& candidate) + { + return candidate.e(o2::constants::physics::MassXiC0); + } + + template + static auto ctXiczero(const T& candidate) + { + return candidate.ct(o2::constants::physics::MassXiC0); + } + + template + static auto cosThetaStarXiczeroToXiPi(const T& candidate) + { + return candidate.cosThetaStar(std::array{o2::constants::physics::MassXiMinus, o2::constants::physics::MassPiPlus}, o2::constants::physics::MassXiC0, 1); + } + + template + static auto yOmegaczero(const T& candidate) + { + return candidate.y(o2::constants::physics::MassOmegaC0); + } + + template + static auto eOmegaczero(const T& candidate) + { + return candidate.e(o2::constants::physics::MassOmegaC0); + } + + template + static auto ctOmegaczero(const T& candidate) + { + return candidate.ct(o2::constants::physics::MassOmegaC0); + } + + template + static auto cosThetaStarOmegaczeroToXiPi(const T& candidate) + { + return candidate.cosThetaStar(std::array{o2::constants::physics::MassXiMinus, o2::constants::physics::MassPiPlus}, o2::constants::physics::MassOmegaC0, 1); + } + + template + static auto cosThetaStarOmegaczeroToOmegaPi(const T& candidate) + { + return candidate.cosThetaStar(std::array{o2::constants::physics::MassOmegaMinus, o2::constants::physics::MassPiPlus}, o2::constants::physics::MassOmegaC0, 1); + } + + template + static auto cosThetaStarOmegaczeroToOmegaK(const T& candidate) + { + return candidate.cosThetaStar(std::array{o2::constants::physics::MassOmegaMinus, o2::constants::physics::MassKPlus}, o2::constants::physics::MassOmegaC0, 1); + } + // hf_cand_casc_lf_3prong template diff --git a/PWGHF/Core/HfMlResponseOmegacToOmegaPiQa.h b/PWGHF/Core/HfMlResponseOmegacToOmegaPiQa.h index 2c3fd60bcae..db270979d08 100644 --- a/PWGHF/Core/HfMlResponseOmegacToOmegaPiQa.h +++ b/PWGHF/Core/HfMlResponseOmegacToOmegaPiQa.h @@ -13,10 +13,12 @@ /// \brief Class to compute the ML response for Ωc0 → Ω- π+ (and charge-conjugate) analysis selections /// \author Yunfan Liu , China University of Geosciences /// \author Maria Fernanda Torres Cabrera , University of Houston +/// \author Fabio Catalano , University of Houston #ifndef PWGHF_CORE_HFMLRESPONSEOMEGACTOOMEGAPIQA_H_ #define PWGHF_CORE_HFMLRESPONSEOMEGACTOOMEGAPIQA_H_ +#include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/HfMlResponse.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" @@ -32,79 +34,79 @@ // the value is the corresponding value in EnumInputFeatures #define FILL_MAP_OMEGAC0(FEATURE) \ { \ - #FEATURE, static_cast(InputFeaturesOmegacToOmegaPi::FEATURE)} + #FEATURE, static_cast(InputFeaturesOmegacToOmegaPiQa::FEATURE)} + +// Specific case of CHECK_AND_FILL_VEC_OMEGAC0_FULL(OBJECT, FEATURE, GETTER) +// where OBJECT is named candidate and FEATURE = GETTER +#define CHECK_AND_FILL_VEC_OMEGAC0(GETTER) \ + case static_cast(InputFeaturesOmegacToOmegaPiQa::GETTER): { \ + inputFeatures.emplace_back(candidate.GETTER()); \ + break; \ + } // Check if the index of mCachedIndices (index associated to a FEATURE) // matches the entry in EnumInputFeatures associated to this FEATURE // if so, the inputFeatures vector is filled with the FEATURE's value // by calling the corresponding GETTER from OBJECT -#define CHECK_AND_FILL_VEC_OMEGAC0_FULL(OBJECT, FEATURE, GETTER) \ - case static_cast(InputFeaturesOmegacToOmegaPi::FEATURE): { \ - inputFeatures.emplace_back(OBJECT.GETTER()); \ - break; \ +#define CHECK_AND_FILL_VEC_OMEGAC0_FULL(OBJECT, FEATURE, GETTER) \ + case static_cast(InputFeaturesOmegacToOmegaPiQa::FEATURE): { \ + inputFeatures.emplace_back(OBJECT.GETTER()); \ + break; \ } -// Specific case of CHECK_AND_FILL_VEC_OMEGAC0_FULL(OBJECT, FEATURE, GETTER) -// where OBJECT is named candidate and FEATURE = GETTER -#define CHECK_AND_FILL_VEC_OMEGAC0(GETTER) \ - case static_cast(InputFeaturesOmegacToOmegaPi::GETTER): { \ - inputFeatures.emplace_back(candidate.GETTER()); \ - break; \ +// Variation of CHECK_AND_FILL_VEC_OMEGAC0_FULL(OBJECT, FEATURE, GETTER) +// where GETTER is a method of HfHelper +#define CHECK_AND_FILL_VEC_OMEGAC0_HFHELPER(OBJECT, FEATURE, GETTER) \ + case static_cast(InputFeaturesOmegacToOmegaPiQa::FEATURE): { \ + inputFeatures.emplace_back(HfHelper::GETTER(OBJECT)); \ + break; \ } namespace o2::analysis { -enum class InputFeaturesOmegacToOmegaPi : uint8_t { - +enum class InputFeaturesOmegacToOmegaPiQa : uint8_t { // Common variables - dcaCharmBaryonDau = 0, - dcaCascDau, + impactParameterXYCharmBachelor = 0, + impactParameterZCharmBachelor, + impactParameterXYCascade, + impactParameterZCascade, + dcaDaughters, + dcaCascadeDaughters, + cpa, + cpaCascade, + cpaCascadeToCharmHadron, + cosThetaStarPiFromOmegac, + decayLengthNormalised, + decayLengthXY, + decayLengthXYNormalised, + decayLengthXYCascade, + massCascade, nSigmaTPCPiFromV0, nSigmaTPCPiFromOmegac, nSigmaTPCKaFromCasc, - // DCAFitter variables - impactParBachFromCharmBaryonXY, - impactParBachFromCharmBaryonZ, - impactParCascXY, - impactParCascZ, - cosPACharmBaryon, - cosPACasc, - normDecayLenCharmBar, - // KFParticle variables - cosPaOmegacToPv, - kfDcaXYPiFromOmegac, - chi2TopoPiFromOmegacToPv, - invMassCascade, - massCascChi2OverNdf, - kfDcaXYCascToPv, - cosPaCascToPv, - cosThetaStarPiFromOmegac, - chi2NdfTopoOmegacToPv, - ldlCasc, - cosPaCascToOmegac, - decayLenXYCasc, - decayLenXYOmegac, - ldlOmegac, - chi2NdfTopoCascToOmegac, - chi2NdfTopoCascToPv, - chi2GeoOmegac, - chi2GeoCasc, + decayLengthNormKf, + decayLengthNormKfCascade, + chi2Geo, + chi2TopoOverNdfToPv, + chi2GeoCascade, + chi2TopoOverNdfCascadeToCharmHadron, + chi2TopoOverNdfCascadeToPv }; template -class HfMlResponseOmegacToOmegaPi : public HfMlResponse +class HfMlResponseOmegacToOmegaPiQa : public HfMlResponse { public: /// Default constructor - HfMlResponseOmegacToOmegaPi() = default; + HfMlResponseOmegacToOmegaPiQa() = default; /// Default destructor - virtual ~HfMlResponseOmegacToOmegaPi() = default; + virtual ~HfMlResponseOmegacToOmegaPiQa() = default; /// Method to get the input features vector needed for ML inference - /// \param candidate is the OMEGAC0 candidate - /// \param lamProngPi is the candidate's lamProngPi + /// \param candidate is the OmegaC0 candidate + /// \param lamProngPi is the candidate's pion from the Lambda decay /// \param cascProng is the bachelor track from the Omega decay /// \param charmBaryonProng is the bachelor pion from the OmegaC decay /// \return inputFeatures vector @@ -117,53 +119,37 @@ class HfMlResponseOmegacToOmegaPi : public HfMlResponse // Variables common to DCAFitter and KFParticle switch (idx) { - - CHECK_AND_FILL_VEC_OMEGAC0(dcaCharmBaryonDau); - CHECK_AND_FILL_VEC_OMEGAC0(dcaCascDau); + CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, impactParameterXYCharmBachelor, impactParameter1); + CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, impactParameterZCharmBachelor, impactParameterZ1); + CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, impactParameterXYCascade, impactParameter0); + CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, impactParameterZCascade, impactParameterZ0); + CHECK_AND_FILL_VEC_OMEGAC0(dcaDaughters); + CHECK_AND_FILL_VEC_OMEGAC0(dcaCascadeDaughters); + CHECK_AND_FILL_VEC_OMEGAC0(cpa); + CHECK_AND_FILL_VEC_OMEGAC0(cpaCascade); + CHECK_AND_FILL_VEC_OMEGAC0(cpaCascadeToCharmHadron); + CHECK_AND_FILL_VEC_OMEGAC0_HFHELPER(candidate, cosThetaStarPiFromOmegac, cosThetaStarOmegaczeroToOmegaPi); + CHECK_AND_FILL_VEC_OMEGAC0(decayLengthNormalised); + CHECK_AND_FILL_VEC_OMEGAC0(decayLengthXY); + CHECK_AND_FILL_VEC_OMEGAC0(decayLengthXYNormalised); + CHECK_AND_FILL_VEC_OMEGAC0(decayLengthXYCascade); + CHECK_AND_FILL_VEC_OMEGAC0(massCascade); // TPC PID variables CHECK_AND_FILL_VEC_OMEGAC0_FULL(lamProngPi, nSigmaTPCPiFromV0, tpcNSigmaPi); CHECK_AND_FILL_VEC_OMEGAC0_FULL(cascProng, nSigmaTPCKaFromCasc, tpcNSigmaKa); CHECK_AND_FILL_VEC_OMEGAC0_FULL(charmBaryonProng, nSigmaTPCPiFromOmegac, tpcNSigmaPi); } - // DCAFitter variables - if constexpr (reconstructionType == aod::hf_cand_casc_lf::ConstructMethod::DcaFitter) { - - switch (idx) { - - CHECK_AND_FILL_VEC_OMEGAC0(impactParBachFromCharmBaryonXY); - CHECK_AND_FILL_VEC_OMEGAC0(impactParBachFromCharmBaryonZ); - CHECK_AND_FILL_VEC_OMEGAC0(impactParCascXY); - CHECK_AND_FILL_VEC_OMEGAC0(impactParCascZ); - CHECK_AND_FILL_VEC_OMEGAC0(cosPACharmBaryon); - CHECK_AND_FILL_VEC_OMEGAC0(cosPACasc); - CHECK_AND_FILL_VEC_OMEGAC0(normDecayLenCharmBar); - } - } - // KFParticle variables if constexpr (reconstructionType == aod::hf_cand_casc_lf::ConstructMethod::KfParticle) { - switch (idx) { - - CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, cosPaOmegacToPv, cosPACharmBaryon); - CHECK_AND_FILL_VEC_OMEGAC0(kfDcaXYPiFromOmegac); - CHECK_AND_FILL_VEC_OMEGAC0(chi2TopoPiFromOmegacToPv); - CHECK_AND_FILL_VEC_OMEGAC0(invMassCascade); - CHECK_AND_FILL_VEC_OMEGAC0(massCascChi2OverNdf); - CHECK_AND_FILL_VEC_OMEGAC0(kfDcaXYCascToPv); - CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, cosPaCascToPv, cosPACasc); - CHECK_AND_FILL_VEC_OMEGAC0(cosThetaStarPiFromOmegac); - CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, chi2NdfTopoOmegacToPv, chi2TopoOmegacToPv); - CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, ldlCasc, cascldl); - CHECK_AND_FILL_VEC_OMEGAC0(cosPaCascToOmegac); - CHECK_AND_FILL_VEC_OMEGAC0(decayLenXYCasc); - CHECK_AND_FILL_VEC_OMEGAC0(decayLenXYOmegac); - CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, ldlOmegac, omegacldl); - CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, chi2NdfTopoCascToOmegac, chi2TopoCascToOmegac); - CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, chi2NdfTopoCascToPv, chi2TopoCascToPv); - CHECK_AND_FILL_VEC_OMEGAC0(chi2GeoOmegac); - CHECK_AND_FILL_VEC_OMEGAC0(chi2GeoCasc); + CHECK_AND_FILL_VEC_OMEGAC0(decayLengthNormKf); + CHECK_AND_FILL_VEC_OMEGAC0(decayLengthNormKfCascade); + CHECK_AND_FILL_VEC_OMEGAC0(chi2Geo); + CHECK_AND_FILL_VEC_OMEGAC0(chi2TopoOverNdfCascadeToPv); + CHECK_AND_FILL_VEC_OMEGAC0(chi2GeoCascade); + CHECK_AND_FILL_VEC_OMEGAC0(chi2TopoOverNdfCascadeToCharmHadron); + CHECK_AND_FILL_VEC_OMEGAC0(chi2TopoOverNdfToPv); } } } @@ -177,52 +163,36 @@ class HfMlResponseOmegacToOmegaPi : public HfMlResponse { // Common variables MlResponse::mAvailableInputFeatures = { - - FILL_MAP_OMEGAC0(dcaCharmBaryonDau), - FILL_MAP_OMEGAC0(dcaCascDau), + FILL_MAP_OMEGAC0(impactParameterXYCharmBachelor), + FILL_MAP_OMEGAC0(impactParameterZCharmBachelor), + FILL_MAP_OMEGAC0(impactParameterXYCascade), + FILL_MAP_OMEGAC0(impactParameterZCascade), + FILL_MAP_OMEGAC0(dcaDaughters), + FILL_MAP_OMEGAC0(dcaCascadeDaughters), + FILL_MAP_OMEGAC0(cpa), + FILL_MAP_OMEGAC0(cpaCascade), + FILL_MAP_OMEGAC0(cpaCascadeToCharmHadron), + FILL_MAP_OMEGAC0(cosThetaStarPiFromOmegac), + FILL_MAP_OMEGAC0(decayLengthNormalised), + FILL_MAP_OMEGAC0(decayLengthXY), + FILL_MAP_OMEGAC0(decayLengthXYNormalised), + FILL_MAP_OMEGAC0(decayLengthXYCascade), + FILL_MAP_OMEGAC0(massCascade), FILL_MAP_OMEGAC0(nSigmaTPCPiFromV0), FILL_MAP_OMEGAC0(nSigmaTPCPiFromOmegac), FILL_MAP_OMEGAC0(nSigmaTPCKaFromCasc)}; - // DCAFitter variables - if constexpr (reconstructionType == aod::hf_cand_casc_lf::ConstructMethod::DcaFitter) { - - std::map mapDcaFeatures{ - - FILL_MAP_OMEGAC0(impactParBachFromCharmBaryonXY), - FILL_MAP_OMEGAC0(impactParBachFromCharmBaryonZ), - FILL_MAP_OMEGAC0(impactParCascXY), - FILL_MAP_OMEGAC0(impactParCascZ), - FILL_MAP_OMEGAC0(cosPACharmBaryon), - FILL_MAP_OMEGAC0(cosPACasc), - FILL_MAP_OMEGAC0(normDecayLenCharmBar)}; - - MlResponse::mAvailableInputFeatures.insert(mapDcaFeatures.begin(), mapDcaFeatures.end()); - } - // KFParticle variables if constexpr (reconstructionType == aod::hf_cand_casc_lf::ConstructMethod::KfParticle) { std::map mapKfFeatures{ - - FILL_MAP_OMEGAC0(cosPaOmegacToPv), - FILL_MAP_OMEGAC0(kfDcaXYPiFromOmegac), - FILL_MAP_OMEGAC0(chi2TopoPiFromOmegacToPv), - FILL_MAP_OMEGAC0(invMassCascade), - FILL_MAP_OMEGAC0(massCascChi2OverNdf), - FILL_MAP_OMEGAC0(kfDcaXYCascToPv), - FILL_MAP_OMEGAC0(cosPaCascToPv), - FILL_MAP_OMEGAC0(cosThetaStarPiFromOmegac), - FILL_MAP_OMEGAC0(chi2NdfTopoOmegacToPv), - FILL_MAP_OMEGAC0(ldlCasc), - FILL_MAP_OMEGAC0(cosPaCascToOmegac), - FILL_MAP_OMEGAC0(decayLenXYCasc), - FILL_MAP_OMEGAC0(decayLenXYOmegac), - FILL_MAP_OMEGAC0(ldlOmegac), - FILL_MAP_OMEGAC0(chi2NdfTopoCascToOmegac), - FILL_MAP_OMEGAC0(chi2NdfTopoCascToPv), - FILL_MAP_OMEGAC0(chi2GeoOmegac), - FILL_MAP_OMEGAC0(chi2GeoCasc)}; + FILL_MAP_OMEGAC0(decayLengthNormKf), + FILL_MAP_OMEGAC0(decayLengthNormKfCascade), + FILL_MAP_OMEGAC0(chi2Geo), + FILL_MAP_OMEGAC0(chi2TopoOverNdfToPv), + FILL_MAP_OMEGAC0(chi2GeoCascade), + FILL_MAP_OMEGAC0(chi2TopoOverNdfCascadeToCharmHadron), + FILL_MAP_OMEGAC0(chi2TopoOverNdfCascadeToPv)}; MlResponse::mAvailableInputFeatures.insert(mapKfFeatures.begin(), mapKfFeatures.end()); } @@ -232,6 +202,8 @@ class HfMlResponseOmegacToOmegaPi : public HfMlResponse } // namespace o2::analysis #undef FILL_MAP_OMEGAC0 -#undef CHECK_AND_FILL_VEC_OMEGAC0_FULL #undef CHECK_AND_FILL_VEC_OMEGAC0 +#undef CHECK_AND_FILL_VEC_OMEGAC0_FULL +#undef CHECK_AND_FILL_VEC_OMEGAC0_HFHELPER + #endif // PWGHF_CORE_HFMLRESPONSEOMEGACTOOMEGAPIQA_H_ diff --git a/PWGHF/Core/HfMlResponseXic0ToXiPiQa.h b/PWGHF/Core/HfMlResponseXic0ToXiPiQa.h new file mode 100644 index 00000000000..a1833134ff9 --- /dev/null +++ b/PWGHF/Core/HfMlResponseXic0ToXiPiQa.h @@ -0,0 +1,231 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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 HfMlResponseXic0ToXiPiQa.h +/// \brief Class to compute the ML response for XiC0 to Xi Pi selections +/// \author Fabio Catalano , University of Houston + +#ifndef PWGHF_CORE_HFMLRESPONSEXIC0TOXIPIQA_H_ +#define PWGHF_CORE_HFMLRESPONSEXIC0TOXIPIQA_H_ + +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/HfMlResponse.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" + +#include "Tools/ML/MlResponse.h" + +#include +#include +#include +#include + +// Fill the map of available input features +// the key is the feature's name (std::string) +// the value is the corresponding value in EnumInputFeatures +#define FILL_MAP_XIC0(FEATURE) \ + { \ + #FEATURE, static_cast(InputFeaturesXic0ToXiPiQa::FEATURE)} + +// Specific case of CHECK_AND_FILL_VEC_XIC0_FULL(OBJECT, FEATURE, GETTER) +// where OBJECT is candidate and FEATURE = GETTER +#define CHECK_AND_FILL_VEC_XIC0(GETTER) \ + case static_cast(InputFeaturesXic0ToXiPiQa::GETTER): { \ + inputFeatures.emplace_back(candidate.GETTER()); \ + break; \ + } + +// Check whether the cached feature index matches FEATURE, then append +// OBJECT.GETTER() to the input feature vector +#define CHECK_AND_FILL_VEC_XIC0_FULL(OBJECT, FEATURE, GETTER) \ + case static_cast(InputFeaturesXic0ToXiPiQa::FEATURE): { \ + inputFeatures.emplace_back(OBJECT.GETTER()); \ + break; \ + } + +// Variation of CHECK_AND_FILL_VEC_XIC0_FULL for HfHelper methods +#define CHECK_AND_FILL_VEC_XIC0_HFHELPER(OBJECT, FEATURE, GETTER) \ + case static_cast(InputFeaturesXic0ToXiPiQa::FEATURE): { \ + inputFeatures.emplace_back(HfHelper::GETTER(OBJECT)); \ + break; \ + } + +namespace o2::analysis +{ +enum class InputFeaturesXic0ToXiPiQa : uint8_t { + // Common variables + impactParameterXYCharmBachelor = 0, + impactParameterZCharmBachelor, + impactParameterXYCascade, + impactParameterZCascade, + impactParameterXYCascadeBach, + impactParameterXYV0PosDau, + impactParameterXYV0NegDau, + dcaDaughters, + dcaCascadeDaughters, + dcaV0Daughters, + cpa, + cpaCascade, + cpaV0, + cpaCascadeToCharmHadron, + cpaV0ToCascade, + cosThetaStarPiFromXic0, + decayLengthXY, + decayLengthXYCascade, + decayLengthXYV0, + nSigmaTPCPiFromV0, + nSigmaTPCPrFromV0, + nSigmaTPCPiFromXic0, + nSigmaTPCPiFromCasc, + + // KFParticle variables + decayLengthNormKf, + decayLengthNormKfCascade, + chi2GeoOverNdf, + chi2TopoOverNdfToPv, + chi2GeoOverNdfCascade, + chi2TopoOverNdfCascadeToCharmHadron, + chi2TopoOverNdfCascadeToPv, + chi2GeoOverNdfV0, + chi2TopoOverNdfV0ToPv, + chi2TopoOverNdfV0ToCascade + + // Legacy KF inputs not stored in the shared QA candidate tables + // chi2TopoPiFromXicToPv, + // kfptPiFromXic +}; + +template +class HfMlResponseXic0ToXiPiQa : public HfMlResponse +{ + public: + HfMlResponseXic0ToXiPiQa() = default; + virtual ~HfMlResponseXic0ToXiPiQa() = default; + + /// Method to get the input features vector needed for ML inference + /// \param candidate is the XiC0 candidate + /// \param lamProngPi is the candidate's pion from the Lambda decay + /// \param lamProngPr is the candidate's proton from the Lambda decay + /// \param cascProng is the bachelor track from the Xi decay + /// \param charmBaryonProng is the bachelor pion from the XiC decay + /// \return inputFeatures vector + template + std::vector getInputFeatures(T1 const& candidate, T2 const& lamProngPi, T2 const& lamProngPr, + T2 const& cascProng, T3 const& charmBaryonProng) + { + std::vector inputFeatures; + inputFeatures.reserve(MlResponse::mCachedIndices.size()); + + for (const auto& idx : MlResponse::mCachedIndices) { + + // Variables common to DCAFitter and KFParticle + switch (idx) { + CHECK_AND_FILL_VEC_XIC0_FULL(candidate, impactParameterXYCharmBachelor, impactParameter1); + CHECK_AND_FILL_VEC_XIC0_FULL(candidate, impactParameterZCharmBachelor, impactParameterZ1); + CHECK_AND_FILL_VEC_XIC0_FULL(candidate, impactParameterXYCascade, impactParameter0); + CHECK_AND_FILL_VEC_XIC0_FULL(candidate, impactParameterZCascade, impactParameterZ0); + CHECK_AND_FILL_VEC_XIC0(impactParameterXYCascadeBach); + CHECK_AND_FILL_VEC_XIC0(impactParameterXYV0PosDau); + CHECK_AND_FILL_VEC_XIC0(impactParameterXYV0NegDau); + CHECK_AND_FILL_VEC_XIC0(dcaDaughters); + CHECK_AND_FILL_VEC_XIC0(dcaCascadeDaughters); + CHECK_AND_FILL_VEC_XIC0(dcaV0Daughters); + CHECK_AND_FILL_VEC_XIC0(cpa); + CHECK_AND_FILL_VEC_XIC0(cpaCascade); + CHECK_AND_FILL_VEC_XIC0(cpaV0); + CHECK_AND_FILL_VEC_XIC0(cpaCascadeToCharmHadron); + CHECK_AND_FILL_VEC_XIC0(cpaV0ToCascade); + CHECK_AND_FILL_VEC_XIC0_HFHELPER(candidate, cosThetaStarPiFromXic0, cosThetaStarXiczeroToXiPi); + CHECK_AND_FILL_VEC_XIC0(decayLengthXY); + CHECK_AND_FILL_VEC_XIC0(decayLengthXYCascade); + CHECK_AND_FILL_VEC_XIC0(decayLengthXYV0); + CHECK_AND_FILL_VEC_XIC0_FULL(lamProngPi, nSigmaTPCPiFromV0, tpcNSigmaPi); + CHECK_AND_FILL_VEC_XIC0_FULL(lamProngPr, nSigmaTPCPrFromV0, tpcNSigmaPr); + CHECK_AND_FILL_VEC_XIC0_FULL(charmBaryonProng, nSigmaTPCPiFromXic0, tpcNSigmaPi); + CHECK_AND_FILL_VEC_XIC0_FULL(cascProng, nSigmaTPCPiFromCasc, tpcNSigmaPi); + } + + // KFParticle variables + if constexpr (reconstructionType == aod::hf_cand_casc_lf::ConstructMethod::KfParticle) { + switch (idx) { + CHECK_AND_FILL_VEC_XIC0(decayLengthNormKf); + CHECK_AND_FILL_VEC_XIC0(decayLengthNormKfCascade); + CHECK_AND_FILL_VEC_XIC0(chi2GeoOverNdf); + CHECK_AND_FILL_VEC_XIC0(chi2TopoOverNdfToPv); + CHECK_AND_FILL_VEC_XIC0(chi2GeoOverNdfCascade); + CHECK_AND_FILL_VEC_XIC0(chi2TopoOverNdfCascadeToCharmHadron); + CHECK_AND_FILL_VEC_XIC0(chi2TopoOverNdfCascadeToPv); + CHECK_AND_FILL_VEC_XIC0(chi2GeoOverNdfV0); + CHECK_AND_FILL_VEC_XIC0(chi2TopoOverNdfV0ToPv); + CHECK_AND_FILL_VEC_XIC0(chi2TopoOverNdfV0ToCascade); + } + } + } + + return inputFeatures; + } + + protected: + /// Method to fill the map of available input features + void setAvailableInputFeatures() + { + // Common variables + MlResponse::mAvailableInputFeatures = { + FILL_MAP_XIC0(impactParameterXYCharmBachelor), + FILL_MAP_XIC0(impactParameterZCharmBachelor), + FILL_MAP_XIC0(impactParameterXYCascade), + FILL_MAP_XIC0(impactParameterZCascade), + FILL_MAP_XIC0(impactParameterXYCascadeBach), + FILL_MAP_XIC0(impactParameterXYV0PosDau), + FILL_MAP_XIC0(impactParameterXYV0NegDau), + FILL_MAP_XIC0(dcaDaughters), + FILL_MAP_XIC0(dcaCascadeDaughters), + FILL_MAP_XIC0(dcaV0Daughters), + FILL_MAP_XIC0(cpa), + FILL_MAP_XIC0(cpaCascade), + FILL_MAP_XIC0(cpaV0), + FILL_MAP_XIC0(cpaCascadeToCharmHadron), + FILL_MAP_XIC0(cpaV0ToCascade), + FILL_MAP_XIC0(cosThetaStarPiFromXic0), + FILL_MAP_XIC0(decayLengthXY), + FILL_MAP_XIC0(decayLengthXYCascade), + FILL_MAP_XIC0(decayLengthXYV0), + FILL_MAP_XIC0(nSigmaTPCPiFromV0), + FILL_MAP_XIC0(nSigmaTPCPrFromV0), + FILL_MAP_XIC0(nSigmaTPCPiFromXic0), + FILL_MAP_XIC0(nSigmaTPCPiFromCasc)}; + + // KFParticle variables + if constexpr (reconstructionType == aod::hf_cand_casc_lf::ConstructMethod::KfParticle) { + std::map mapKfFeatures{ + FILL_MAP_XIC0(decayLengthNormKf), + FILL_MAP_XIC0(decayLengthNormKfCascade), + FILL_MAP_XIC0(chi2GeoOverNdf), + FILL_MAP_XIC0(chi2TopoOverNdfToPv), + FILL_MAP_XIC0(chi2GeoOverNdfCascade), + FILL_MAP_XIC0(chi2TopoOverNdfCascadeToCharmHadron), + FILL_MAP_XIC0(chi2TopoOverNdfCascadeToPv), + FILL_MAP_XIC0(chi2GeoOverNdfV0), + FILL_MAP_XIC0(chi2TopoOverNdfV0ToPv), + FILL_MAP_XIC0(chi2TopoOverNdfV0ToCascade)}; + + MlResponse::mAvailableInputFeatures.insert(mapKfFeatures.begin(), mapKfFeatures.end()); + } + } +}; + +} // namespace o2::analysis + +#undef FILL_MAP_XIC0 +#undef CHECK_AND_FILL_VEC_XIC0 +#undef CHECK_AND_FILL_VEC_XIC0_FULL +#undef CHECK_AND_FILL_VEC_XIC0_HFHELPER + +#endif // PWGHF_CORE_HFMLRESPONSEXIC0TOXIPIQA_H_ diff --git a/PWGHF/D2H/Tasks/taskOmegac0ToOmegaPiQa.cxx b/PWGHF/D2H/Tasks/taskOmegac0ToOmegaPiQa.cxx index 90ebbb0d312..517198e4852 100644 --- a/PWGHF/D2H/Tasks/taskOmegac0ToOmegaPiQa.cxx +++ b/PWGHF/D2H/Tasks/taskOmegac0ToOmegaPiQa.cxx @@ -16,10 +16,10 @@ /// \author Maria Fernanda Torres Cabrera , University of Houston #include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/Core/DecayChannelsLegacy.h" +#include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/DataModel/TrackIndexSkimmingTables.h" #include "PWGLF/DataModel/mcCentrality.h" #include "Common/Core/RecoDecay.h" @@ -39,8 +39,6 @@ #include -#include - #include #include #include @@ -51,41 +49,39 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -/// Omegac0 analysis task struct HfTaskOmegac0ToOmegaPiQa { - Configurable selectionFlagOmegac0{"selectionFlagOmegac0", true, "Select Omegac0 candidates"}; + Configurable selectionFlagOmegac0{"selectionFlagOmegac0", 7, "Selection Flag for Omegac0 candidates. 1 -> skimmed, 3 -> topological, 7 -> PID, 15 -> ML"}; Configurable yCandGenMax{"yCandGenMax", 0.5, "Max. gen particle rapidity"}; Configurable yCandRecoMax{"yCandRecoMax", 0.8, "Max. cand. rapidity"}; SliceCache cache; - using Omegac0Cands = soa::Filtered>; - using Omegac0CandsKF = soa::Filtered>; - using Omegac0CandsMc = soa::Filtered>; - using Omegac0CandsMcKF = soa::Filtered>; - using Omegac0CandsMl = soa::Filtered>; - using Omegac0CandsMlKF = soa::Filtered>; - using Omegac0CandsMlMc = soa::Filtered>; - using Omegac0CandsMlMcKF = soa::Filtered>; + using Omegac0Cands = soa::Filtered>; + using Omegac0CandsKF = soa::Filtered>; + using Omegac0CandsMc = soa::Filtered>; + using Omegac0CandsMcKF = soa::Filtered>; + using Omegac0CandsMl = soa::Filtered>; + using Omegac0CandsMlKF = soa::Filtered>; + using Omegac0CandsMlMc = soa::Filtered>; + using Omegac0CandsMlMcKF = soa::Filtered>; - using Omegac0Gen = soa::Filtered>; + using Omegac0Gen = soa::Filtered>; - using Collisions = soa::Join; using CollisionsWithFT0C = soa::Join; using CollisionsWithFT0M = soa::Join; using CollisionsWithMcLabels = soa::Join; using McCollisionsWithFT0M = soa::Join; - Filter filterOmegaCToOmegaPiFlag = (aod::hf_track_index::hfflag & static_cast(BIT(aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi))) != static_cast(0); - Filter filterOmegaCMatchedRec = nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi)); - Filter filterOmegaCMatchedGen = nabs(aod::hf_cand_mc_flag::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi)); + Filter filterOmegaCMatchedRec = nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_decay::hf_cand_casc_bach_qa::DecayChannelMain::Omegac0ToOmegaPi); + Filter filterOmegaCMatchedGen = nabs(aod::hf_cand_mc_flag::flagMcMatchGen) == static_cast(hf_decay::hf_cand_casc_bach_qa::DecayChannelMain::Omegac0ToOmegaPi); + Filter filterSelectCandidates = aod::hf_sel_candidate_omegac0_qa::isSelOmegaC0ToOmegaPi >= selectionFlagOmegac0; - Preslice candOmegacPerCollision = aod::hf_cand_xic0_omegac0::collisionId; - Preslice candOmegacKFPerCollision = aod::hf_cand_xic0_omegac0::collisionId; - Preslice candOmegacMlPerCollision = aod::hf_cand_xic0_omegac0::collisionId; - Preslice candOmegacKFMlPerCollision = aod::hf_cand_xic0_omegac0::collisionId; + Preslice candOmegacPerCollision = aod::hf_cand::collisionId; + Preslice candOmegacKFPerCollision = aod::hf_cand::collisionId; + Preslice candOmegacMlPerCollision = aod::hf_cand::collisionId; + Preslice candOmegacKFMlPerCollision = aod::hf_cand::collisionId; PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; @@ -163,46 +159,27 @@ struct HfTaskOmegac0ToOmegaPiQa { registry.get(HIST("hReco"))->Sumw2(); } - template - void processData(const CandType& candidates) + template + void runDataAnalysis(const CandType& candidates) { for (const auto& candidate : candidates) { - if (!(candidate.resultSelections() == true || (candidate.resultSelections() == false && !selectionFlagOmegac0))) { - continue; - } - - double yOmegac{0.}; - if constexpr (UseKfParticle) { - yOmegac = candidate.kfRapOmegac(); - } else { - yOmegac = RecoDecay::y(std::array{candidate.pxCharmBaryon(), candidate.pyCharmBaryon(), candidate.pzCharmBaryon()}, o2::constants::physics::MassOmegaC0); - } + const auto yOmegac = HfHelper::yOmegaczero(candidate); if (yCandRecoMax >= 0. && std::abs(yOmegac) > yCandRecoMax) { continue; } if constexpr (ApplyMl) { - registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), yOmegac, candidate.mlProbOmegac()[0]); + registry.fill(HIST("hReco"), HfHelper::invMassOmegaczeroToOmegaPi(candidate), candidate.pt(), yOmegac, candidate.mlProbOmegaC0ToOmegaPi()[0]); } else { - registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), yOmegac); + registry.fill(HIST("hReco"), HfHelper::invMassOmegaczeroToOmegaPi(candidate), candidate.pt(), yOmegac); } } } - template - void processDataCent(const CandType& candidate, CollType const& collision) + template + void runDataAnalysisCentPerCandidate(const CandType& candidate, CollType const& collision) { - if (!(candidate.resultSelections() == true || (candidate.resultSelections() == false && !selectionFlagOmegac0))) { - return; - } - - double yOmegac{0.}; - if constexpr (UseKfParticle) { - yOmegac = candidate.kfRapOmegac(); - } else { - yOmegac = RecoDecay::y(std::array{candidate.pxCharmBaryon(), candidate.pyCharmBaryon(), candidate.pzCharmBaryon()}, o2::constants::physics::MassOmegaC0); - } - + const double yOmegac = HfHelper::yOmegaczero(candidate); if (yCandRecoMax >= 0. && std::abs(yOmegac) > yCandRecoMax) { return; } @@ -211,57 +188,45 @@ struct HfTaskOmegac0ToOmegaPiQa { if constexpr (UseCentrality) { float const cent = o2::hf_centrality::getCentralityColl(collision); if constexpr (ApplyMl) { - registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), yOmegac, - cent, numPvContributors, candidate.mlProbOmegac()[0]); + registry.fill(HIST("hReco"), HfHelper::invMassOmegaczeroToOmegaPi(candidate), candidate.pt(), yOmegac, cent, numPvContributors, candidate.mlProbOmegaC0ToOmegaPi()[0]); } else { - registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), yOmegac, - cent, numPvContributors); + registry.fill(HIST("hReco"), HfHelper::invMassOmegaczeroToOmegaPi(candidate), candidate.pt(), yOmegac, cent, numPvContributors); } } else { if constexpr (ApplyMl) { - registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), yOmegac, candidate.mlProbOmegac()[0]); + registry.fill(HIST("hReco"), HfHelper::invMassOmegaczeroToOmegaPi(candidate), candidate.pt(), yOmegac, candidate.mlProbOmegaC0ToOmegaPi()[0]); } else { - registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), yOmegac); + registry.fill(HIST("hReco"), HfHelper::invMassOmegaczeroToOmegaPi(candidate), candidate.pt(), yOmegac); } } } - template - void processMc(const CandType& candidates, Omegac0Gen const& mcParticles) + template + void runMcAnalysis(const CandType& candidates, Omegac0Gen const& mcParticles) { // MC rec. for (const auto& candidate : candidates) { - if (!(candidate.resultSelections() == true || (candidate.resultSelections() == false && !selectionFlagOmegac0))) { - continue; - } - - double yOmegac{0.}; - if constexpr (UseKfParticle) { - yOmegac = candidate.kfRapOmegac(); - } else { - yOmegac = RecoDecay::y(std::array{candidate.pxCharmBaryon(), candidate.pyCharmBaryon(), candidate.pzCharmBaryon()}, o2::constants::physics::MassOmegaC0); - } - + const double yOmegac = HfHelper::yOmegaczero(candidate); if (yCandRecoMax >= 0. && std::abs(yOmegac) > yCandRecoMax) { continue; } if constexpr (ApplyMl) { - registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), yOmegac, candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec(), candidate.mlProbOmegac()[0]); + registry.fill(HIST("hReco"), HfHelper::invMassOmegaczeroToOmegaPi(candidate), candidate.pt(), yOmegac, candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec(), candidate.mlProbOmegaC0ToOmegaPi()[0]); } else { - registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), yOmegac, candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec()); + registry.fill(HIST("hReco"), HfHelper::invMassOmegaczeroToOmegaPi(candidate), candidate.pt(), yOmegac, candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec()); } } // MC gen. for (const auto& particle : mcParticles) { - if (yCandGenMax >= 0. && std::abs(particle.rapidityCharmBaryonGen()) > yCandGenMax) { + double ptGen = particle.pt(); + double yGen = RecoDecay::y(particle.pVector(), o2::constants::physics::MassOmegaC0); + + if (yCandGenMax >= 0. && std::abs(yGen) > yCandGenMax) { continue; } - auto ptGen = particle.pt(); - auto yGen = particle.rapidityCharmBaryonGen(); - if (particle.originMcGen() == RecoDecay::OriginType::Prompt) { registry.fill(HIST("hMcGen"), ptGen, -1., yGen, RecoDecay::OriginType::Prompt); } else { @@ -271,23 +236,13 @@ struct HfTaskOmegac0ToOmegaPiQa { } } - template - void processMcCent(const CandType& candidates, Omegac0Gen const& mcParticles, - CollisionsWithMcLabels const& collisions, McCollisionWithCents const&) + template + void runMcAnalysisCentPerCandidate(const CandType& candidates, Omegac0Gen const& mcParticles, + CollisionsWithMcLabels const& collisions, McCollisionWithCents const&) { // MC rec. for (const auto& candidate : candidates) { - if (!(candidate.resultSelections() == true || (candidate.resultSelections() == false && !selectionFlagOmegac0))) { - continue; - } - - double yOmegac{0.}; - if constexpr (UseKfParticle) { - yOmegac = candidate.kfRapOmegac(); - } else { - yOmegac = RecoDecay::y(std::array{candidate.pxCharmBaryon(), candidate.pyCharmBaryon(), candidate.pzCharmBaryon()}, o2::constants::physics::MassOmegaC0); - } - + const double yOmegac = HfHelper::yOmegaczero(candidate); if (yCandRecoMax >= 0. && std::abs(yOmegac) > yCandRecoMax) { continue; } @@ -297,20 +252,21 @@ struct HfTaskOmegac0ToOmegaPiQa { float const mcCent = o2::hf_centrality::getCentralityColl(collision.template mcCollision_as()); if constexpr (ApplyMl) { - registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), yOmegac, mcCent, numPvContributors, candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec(), candidate.mlProbOmegac()[0]); + registry.fill(HIST("hReco"), HfHelper::invMassOmegaczeroToOmegaPi(candidate), candidate.pt(), yOmegac, mcCent, numPvContributors, candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec(), candidate.mlProbOmegaC0ToOmegaPi()[0]); } else { - registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), yOmegac, mcCent, numPvContributors, candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec()); + registry.fill(HIST("hReco"), HfHelper::invMassOmegaczeroToOmegaPi(candidate), candidate.pt(), yOmegac, mcCent, numPvContributors, candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec()); } } // MC gen. for (const auto& particle : mcParticles) { - if (yCandGenMax >= 0. && std::abs(particle.rapidityCharmBaryonGen()) > yCandGenMax) { + double ptGen = particle.pt(); + double yGen = RecoDecay::y(particle.pVector(), o2::constants::physics::MassOmegaC0); + + if (yCandGenMax >= 0. && std::abs(yGen) > yCandGenMax) { continue; } - auto ptGen = particle.pt(); - auto yGen = particle.rapidityCharmBaryonGen(); auto mcCollision = particle.template mcCollision_as(); int maxNumContrib = 0; @@ -348,13 +304,13 @@ struct HfTaskOmegac0ToOmegaPiQa { void processDataDCAFitter(Omegac0Cands const& candidates) { - processData(candidates); + runDataAnalysis(candidates); } PROCESS_SWITCH(HfTaskOmegac0ToOmegaPiQa, processDataDCAFitter, "process data with DCAFitter", false); void processDataDCAFitterMl(Omegac0CandsMl const& candidates) { - processData(candidates); + runDataAnalysis(candidates); } PROCESS_SWITCH(HfTaskOmegac0ToOmegaPiQa, processDataDCAFitterMl, "process data with DCAFitter, ML selections", false); @@ -365,7 +321,7 @@ struct HfTaskOmegac0ToOmegaPiQa { auto groupedOmegacCandidates = candidates.sliceBy(candOmegacPerCollision, collision.globalIndex()); for (const auto& candidate : groupedOmegacCandidates) { - processDataCent(candidate, collision); + runDataAnalysisCentPerCandidate(candidate, collision); } } } @@ -378,7 +334,7 @@ struct HfTaskOmegac0ToOmegaPiQa { auto groupedOmegacCandidates = candidates.sliceBy(candOmegacMlPerCollision, collision.globalIndex()); for (const auto& candidate : groupedOmegacCandidates) { - processDataCent(candidate, collision); + runDataAnalysisCentPerCandidate(candidate, collision); } } } @@ -391,7 +347,7 @@ struct HfTaskOmegac0ToOmegaPiQa { auto groupedOmegacCandidates = candidates.sliceBy(candOmegacPerCollision, collision.globalIndex()); for (const auto& candidate : groupedOmegacCandidates) { - processDataCent(candidate, collision); + runDataAnalysisCentPerCandidate(candidate, collision); } } } @@ -404,7 +360,7 @@ struct HfTaskOmegac0ToOmegaPiQa { auto groupedOmegacCandidates = candidates.sliceBy(candOmegacMlPerCollision, collision.globalIndex()); for (const auto& candidate : groupedOmegacCandidates) { - processDataCent(candidate, collision); + runDataAnalysisCentPerCandidate(candidate, collision); } } } @@ -416,13 +372,13 @@ struct HfTaskOmegac0ToOmegaPiQa { void processDataKFParticle(Omegac0CandsKF const& candidates) { - processData(candidates); + runDataAnalysis(candidates); } PROCESS_SWITCH(HfTaskOmegac0ToOmegaPiQa, processDataKFParticle, "process data with KFParticle", false); void processDataKFParticleMl(Omegac0CandsMlKF const& candidates) { - processData(candidates); + runDataAnalysis(candidates); } PROCESS_SWITCH(HfTaskOmegac0ToOmegaPiQa, processDataKFParticleMl, "process data with KFParticle, ML selections", false); @@ -433,7 +389,7 @@ struct HfTaskOmegac0ToOmegaPiQa { auto groupedOmegacCandidates = candidates.sliceBy(candOmegacKFPerCollision, collision.globalIndex()); for (const auto& candidate : groupedOmegacCandidates) { - processDataCent(candidate, collision); + runDataAnalysisCentPerCandidate(candidate, collision); } } } @@ -446,7 +402,7 @@ struct HfTaskOmegac0ToOmegaPiQa { auto groupedOmegacCandidates = candidates.sliceBy(candOmegacKFMlPerCollision, collision.globalIndex()); for (const auto& candidate : groupedOmegacCandidates) { - processDataCent(candidate, collision); + runDataAnalysisCentPerCandidate(candidate, collision); } } } @@ -459,7 +415,7 @@ struct HfTaskOmegac0ToOmegaPiQa { auto groupedOmegacCandidates = candidates.sliceBy(candOmegacKFPerCollision, collision.globalIndex()); for (const auto& candidate : groupedOmegacCandidates) { - processDataCent(candidate, collision); + runDataAnalysisCentPerCandidate(candidate, collision); } } } @@ -472,7 +428,7 @@ struct HfTaskOmegac0ToOmegaPiQa { auto groupedOmegacCandidates = candidates.sliceBy(candOmegacKFMlPerCollision, collision.globalIndex()); for (const auto& candidate : groupedOmegacCandidates) { - processDataCent(candidate, collision); + runDataAnalysisCentPerCandidate(candidate, collision); } } } @@ -485,14 +441,14 @@ struct HfTaskOmegac0ToOmegaPiQa { void processMcDCAFitter(Omegac0CandsMc const& omegaC0CandidatesMc, Omegac0Gen const& mcParticles) { - processMc(omegaC0CandidatesMc, mcParticles); + runMcAnalysis(omegaC0CandidatesMc, mcParticles); } PROCESS_SWITCH(HfTaskOmegac0ToOmegaPiQa, processMcDCAFitter, "Process MC with DCAFitter", false); void processMcDCAFitterMl(Omegac0CandsMlMc const& omegac0CandidatesMlMc, Omegac0Gen const& mcParticles) { - processMc(omegac0CandidatesMlMc, mcParticles); + runMcAnalysis(omegac0CandidatesMlMc, mcParticles); } PROCESS_SWITCH(HfTaskOmegac0ToOmegaPiQa, processMcDCAFitterMl, "Process MC with DCAFitter, ML selections", false); @@ -501,7 +457,7 @@ struct HfTaskOmegac0ToOmegaPiQa { CollisionsWithMcLabels const& collisions, McCollisionsWithFT0M const& mcCollisions) { - processMcCent(omegaC0CandidatesMc, mcParticles, collisions, mcCollisions); + runMcAnalysisCentPerCandidate(omegaC0CandidatesMc, mcParticles, collisions, mcCollisions); } PROCESS_SWITCH(HfTaskOmegac0ToOmegaPiQa, processMcDCAFitterFT0M, "Process MC with DCAFitter, FT0M centrality (from MC)", false); @@ -510,7 +466,7 @@ struct HfTaskOmegac0ToOmegaPiQa { CollisionsWithMcLabels const& collisions, McCollisionsWithFT0M const& mcCollisions) { - processMcCent(omegac0CandidatesMlMc, mcParticles, collisions, mcCollisions); + runMcAnalysisCentPerCandidate(omegac0CandidatesMlMc, mcParticles, collisions, mcCollisions); } PROCESS_SWITCH(HfTaskOmegac0ToOmegaPiQa, processMcDCAFitterMlFT0M, "Process MC with DCAFitter, ML selections, FT0M centrality (from MC)", false); @@ -521,14 +477,14 @@ struct HfTaskOmegac0ToOmegaPiQa { void processMcKFParticle(Omegac0CandsMcKF const& omegaC0CandidatesMcKF, Omegac0Gen const& mcParticles) { - processMc(omegaC0CandidatesMcKF, mcParticles); + runMcAnalysis(omegaC0CandidatesMcKF, mcParticles); } PROCESS_SWITCH(HfTaskOmegac0ToOmegaPiQa, processMcKFParticle, "Process MC with KFParticle", false); void processMcKFParticleMl(Omegac0CandsMlMcKF const& omegac0CandidatesMlMcKF, Omegac0Gen const& mcParticles) { - processMc(omegac0CandidatesMlMcKF, mcParticles); + runMcAnalysis(omegac0CandidatesMlMcKF, mcParticles); } PROCESS_SWITCH(HfTaskOmegac0ToOmegaPiQa, processMcKFParticleMl, "Process MC with KFParticle, ML selections", false); @@ -537,7 +493,7 @@ struct HfTaskOmegac0ToOmegaPiQa { CollisionsWithMcLabels const& collisions, McCollisionsWithFT0M const& mcCollisions) { - processMcCent(omegaC0CandidatesMcKF, mcParticles, collisions, mcCollisions); + runMcAnalysisCentPerCandidate(omegaC0CandidatesMcKF, mcParticles, collisions, mcCollisions); } PROCESS_SWITCH(HfTaskOmegac0ToOmegaPiQa, processMcKFParticleFT0M, "Process MC with KFParticle, FT0M centrality (from MC)", false); @@ -546,7 +502,7 @@ struct HfTaskOmegac0ToOmegaPiQa { CollisionsWithMcLabels const& collisions, McCollisionsWithFT0M const& mcCollisions) { - processMcCent(omegac0CandidatesMlMcKF, mcParticles, collisions, mcCollisions); + runMcAnalysisCentPerCandidate(omegac0CandidatesMlMcKF, mcParticles, collisions, mcCollisions); } PROCESS_SWITCH(HfTaskOmegac0ToOmegaPiQa, processMcKFParticleMlFT0M, "Process MC with KFParticle, ML selections, FT0M centrality (from MC)", false); }; diff --git a/PWGHF/DataModel/CandidateReconstructionTables.h b/PWGHF/DataModel/CandidateReconstructionTables.h index 6036b9238bc..15135b22daf 100644 --- a/PWGHF/DataModel/CandidateReconstructionTables.h +++ b/PWGHF/DataModel/CandidateReconstructionTables.h @@ -1466,6 +1466,191 @@ DECLARE_SOA_TABLE(HfToOmegaKMCGen, "AOD", "HFTOOMEKMCGEN", //! hf_cand_mc_flag::FlagMcMatchGen, hf_cand_xic0_omegac0::DebugGenCharmBar, hf_cand_xic0_omegac0::DebugGenCasc, hf_cand_xic0_omegac0::DebugGenLambda, hf_cand_xic0_omegac0::PtCharmBaryonGen, hf_cand_xic0_omegac0::RapidityCharmBaryonGen, hf_cand_mc_flag::OriginMcGen, hf_cand_mc_flag::IdxBhadMotherPart); +namespace hf_cand_casc_bach_qa +{ +DECLARE_SOA_COLUMN(XCascadeVertex, xCascadeVertex, float); +DECLARE_SOA_COLUMN(YCascadeVertex, yCascadeVertex, float); +DECLARE_SOA_COLUMN(ZCascadeVertex, zCascadeVertex, float); +DECLARE_SOA_COLUMN(XV0Vertex, xV0Vertex, float); +DECLARE_SOA_COLUMN(YV0Vertex, yV0Vertex, float); +DECLARE_SOA_COLUMN(ZV0Vertex, zV0Vertex, float); +DECLARE_SOA_COLUMN(MassCascade, massCascade, float); +DECLARE_SOA_COLUMN(MassLambda, massLambda, float); +DECLARE_SOA_COLUMN(EtaCascade, etaCascade, float); +DECLARE_SOA_COLUMN(EtaV0, etaV0, float); +DECLARE_SOA_COLUMN(CpaCascade, cpaCascade, float); +DECLARE_SOA_COLUMN(CpaXYCascade, cpaXYCascade, float); +DECLARE_SOA_COLUMN(CpaV0, cpaV0, float); +DECLARE_SOA_COLUMN(CpaXYV0, cpaXYV0, float); +DECLARE_SOA_COLUMN(CpaCascadeToCharmHadron, cpaCascadeToCharmHadron, float); +DECLARE_SOA_COLUMN(CpaXYCascadeToCharmHadron, cpaXYCascadeToCharmHadron, float); +DECLARE_SOA_COLUMN(CpaV0ToCascade, cpaV0ToCascade, float); +DECLARE_SOA_COLUMN(CpaXYV0ToCascade, cpaXYV0ToCascade, float); +DECLARE_SOA_COLUMN(ImpactParameterXYCascadeBach, impactParameterXYCascadeBach, float); +DECLARE_SOA_COLUMN(ImpactParameterZCascadeBach, impactParameterZCascadeBach, float); +DECLARE_SOA_COLUMN(ImpactParameterXYV0PosDau, impactParameterXYV0PosDau, float); +DECLARE_SOA_COLUMN(ImpactParameterZV0PosDau, impactParameterZV0PosDau, float); +DECLARE_SOA_COLUMN(ImpactParameterXYV0NegDau, impactParameterXYV0NegDau, float); +DECLARE_SOA_COLUMN(ImpactParameterZV0NegDau, impactParameterZV0NegDau, float); +DECLARE_SOA_COLUMN(DcaV0Daughters, dcaV0Daughters, float); +DECLARE_SOA_COLUMN(DcaCascadeDaughters, dcaCascadeDaughters, float); +DECLARE_SOA_COLUMN(DcaDaughters, dcaDaughters, float); + +DECLARE_SOA_DYNAMIC_COLUMN(DecayLengthCascade, decayLengthCascade, //! Cascade decay length from the parent vertex + [](float pvx, float pvy, float pvz, float svx, float svy, float svz) -> float { + return RecoDecay::distance(std::array{pvx, pvy, pvz}, std::array{svx, svy, svz}); + }); +DECLARE_SOA_DYNAMIC_COLUMN(DecayLengthXYCascade, decayLengthXYCascade, //! Cascade transverse decay length from the parent vertex + [](float pvx, float pvy, float svx, float svy) -> float { + return RecoDecay::distanceXY(std::array{pvx, pvy}, std::array{svx, svy}); + }); +DECLARE_SOA_DYNAMIC_COLUMN(DecayLengthV0, decayLengthV0, //! Lambda decay length from the cascade vertex + [](float pvx, float pvy, float pvz, float svx, float svy, float svz) -> float { + return RecoDecay::distance(std::array{pvx, pvy, pvz}, std::array{svx, svy, svz}); + }); +DECLARE_SOA_DYNAMIC_COLUMN(DecayLengthXYV0, decayLengthXYV0, //! Lambda transverse decay length from the cascade vertex + [](float pvx, float pvy, float svx, float svy) -> float { + return RecoDecay::distanceXY(std::array{pvx, pvy}, std::array{svx, svy}); + }); + +// KFParticle specific columns +DECLARE_SOA_COLUMN(Chi2Geo, chi2Geo, float); +DECLARE_SOA_COLUMN(Chi2GeoCascade, chi2GeoCascade, float); +DECLARE_SOA_COLUMN(Chi2GeoV0, chi2GeoV0, float); +DECLARE_SOA_COLUMN(NdfGeo, ndfGeo, int32_t); +DECLARE_SOA_COLUMN(NdfGeoCascade, ndfGeoCascade, int32_t); +DECLARE_SOA_COLUMN(NdfGeoV0, ndfGeoV0, int32_t); +DECLARE_SOA_COLUMN(DecayLengthNormKf, decayLengthNormKf, float); +DECLARE_SOA_COLUMN(DecayLengthNormKfCascade, decayLengthNormKfCascade, float); +DECLARE_SOA_COLUMN(DecayLengthNormKfV0, decayLengthNormKfV0, float); +DECLARE_SOA_COLUMN(Chi2TopoToPv, chi2TopoToPv, float); +DECLARE_SOA_COLUMN(Chi2TopoCascadeToPv, chi2TopoCascadeToPv, float); +DECLARE_SOA_COLUMN(Chi2TopoV0ToPv, chi2TopoV0ToPv, float); +DECLARE_SOA_COLUMN(NdfTopoToPv, ndfTopoToPv, int32_t); +DECLARE_SOA_COLUMN(NdfTopoCascadeToPv, ndfTopoCascadeToPv, int32_t); +DECLARE_SOA_COLUMN(NdfTopoV0ToPv, ndfTopoV0ToPv, int32_t); +DECLARE_SOA_COLUMN(Chi2TopoCascadeToCharmHadron, chi2TopoCascadeToCharmHadron, float); +DECLARE_SOA_COLUMN(Chi2TopoV0ToCascade, chi2TopoV0ToCascade, float); +DECLARE_SOA_COLUMN(NdfTopoCascadeToCharmHadron, ndfTopoCascadeToCharmHadron, int32_t); +DECLARE_SOA_COLUMN(NdfTopoV0ToCascade, ndfTopoV0ToCascade, int32_t); + +DECLARE_SOA_DYNAMIC_COLUMN(Chi2GeoOverNdf, chi2GeoOverNdf, + [](float chi2, int32_t ndf) -> float { return chi2 / ndf; }); +DECLARE_SOA_DYNAMIC_COLUMN(Chi2GeoOverNdfCascade, chi2GeoOverNdfCascade, + [](float chi2, int32_t ndf) -> float { return chi2 / ndf; }); +DECLARE_SOA_DYNAMIC_COLUMN(Chi2GeoOverNdfV0, chi2GeoOverNdfV0, + [](float chi2, int32_t ndf) -> float { return chi2 / ndf; }); +DECLARE_SOA_DYNAMIC_COLUMN(Chi2TopoOverNdfToPv, chi2TopoOverNdfToPv, + [](float chi2, int32_t ndf) -> float { return chi2 / ndf; }); +DECLARE_SOA_DYNAMIC_COLUMN(Chi2TopoOverNdfCascadeToPv, chi2TopoOverNdfCascadeToPv, + [](float chi2, int32_t ndf) -> float { return chi2 / ndf; }); +DECLARE_SOA_DYNAMIC_COLUMN(Chi2TopoOverNdfV0ToPv, chi2TopoOverNdfV0ToPv, + [](float chi2, int32_t ndf) -> float { return chi2 / ndf; }); +DECLARE_SOA_DYNAMIC_COLUMN(Chi2TopoOverNdfCascadeToCharmHadron, chi2TopoOverNdfCascadeToCharmHadron, + [](float chi2, int32_t ndf) -> float { return chi2 / ndf; }); +DECLARE_SOA_DYNAMIC_COLUMN(Chi2TopoOverNdfV0ToCascade, chi2TopoOverNdfV0ToCascade, + [](float chi2, int32_t ndf) -> float { return chi2 / ndf; }); + +} // namespace hf_cand_casc_bach_qa + +// Common QA candidate table for XiPi, OmegaPi and OmegaK +// Convention: Prong0 is the Cascade, Prong1 is the bachelor track +DECLARE_SOA_TABLE(HfCandCascBachBaseQa, "AOD", "HFCASCBACHBASE", + o2::soa::Index<>, + hf_cand::CollisionId, + collision::PosX, collision::PosY, collision::PosZ, + hf_cand::XSecondaryVertex, hf_cand::YSecondaryVertex, hf_cand::ZSecondaryVertex, + hf_cand_casc_bach_qa::XCascadeVertex, hf_cand_casc_bach_qa::YCascadeVertex, hf_cand_casc_bach_qa::ZCascadeVertex, + hf_cand_casc_bach_qa::XV0Vertex, hf_cand_casc_bach_qa::YV0Vertex, hf_cand_casc_bach_qa::ZV0Vertex, + hf_cand::ErrorDecayLength, hf_cand::ErrorDecayLengthXY, + hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, + hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1, + hf_cand::ImpactParameter0, hf_cand::ImpactParameter1, + hf_cand::ErrorImpactParameter0, hf_cand::ErrorImpactParameter1, + hf_cand::ImpactParameterZ0, hf_cand::ImpactParameterZ1, + hf_cand::ErrorImpactParameterZ0, hf_cand::ErrorImpactParameterZ1, + hf_cand_casc_bach_qa::ImpactParameterXYV0PosDau, hf_cand_casc_bach_qa::ImpactParameterXYV0NegDau, hf_cand_casc_bach_qa::ImpactParameterXYCascadeBach, + hf_cand_casc_bach_qa::ImpactParameterZV0PosDau, hf_cand_casc_bach_qa::ImpactParameterZV0NegDau, hf_cand_casc_bach_qa::ImpactParameterZCascadeBach, + hf_cand_casc_bach_qa::DcaDaughters, hf_cand_casc_bach_qa::DcaCascadeDaughters, hf_cand_casc_bach_qa::DcaV0Daughters, + hf_cand_casc_bach_qa::CpaCascade, hf_cand_casc_bach_qa::CpaXYCascade, + hf_cand_casc_bach_qa::CpaV0, hf_cand_casc_bach_qa::CpaXYV0, + hf_cand_casc_bach_qa::CpaCascadeToCharmHadron, hf_cand_casc_bach_qa::CpaXYCascadeToCharmHadron, + hf_cand_casc_bach_qa::CpaV0ToCascade, hf_cand_casc_bach_qa::CpaXYV0ToCascade, + hf_cand_casc_bach_qa::MassCascade, hf_cand_casc_bach_qa::MassLambda, + hf_cand_casc_bach_qa::EtaCascade, hf_cand_casc_bach_qa::EtaV0, + hf_track_index::Prong1Id, cascdata::BachelorId, cascdata::PosTrackId, cascdata::NegTrackId, + hf_track_index::HFflag, + /* dynamic columns */ + hf_cand_2prong::M, + hf_cand::Pt, + hf_cand::P, + hf_cand::PVector, + hf_cand::Eta, + hf_cand::Phi, + hf_cand::Y, + hf_cand::E, + hf_cand::Ct, + hf_cand_2prong::ImpactParameterProduct, + hf_cand_2prong::CosThetaStar, + hf_cand::DecayLength, + hf_cand::DecayLengthXY, + hf_cand::DecayLengthNormalised, + hf_cand::DecayLengthXYNormalised, + hf_cand::ImpactParameterXY, + hf_cand::Cpa, + hf_cand::CpaXY, + // TODO: investigate if these decay lenghts should not be computed w.r.t. the primary vertex + hf_cand_casc_bach_qa::DecayLengthCascade, + hf_cand_casc_bach_qa::DecayLengthXYCascade, + hf_cand_casc_bach_qa::DecayLengthV0, + hf_cand_casc_bach_qa::DecayLengthXYV0, + hf_cand::ImpactParameterNormalised0, + hf_cand::ImpactParameterNormalised1, + hf_cand::ImpactParameterZNormalised0, + hf_cand::ImpactParameterZNormalised1); + +// extended table with expression columns that can be used as arguments of dynamic columns +DECLARE_SOA_EXTENDED_TABLE_USER(HfCandCascBachExtQa, HfCandCascBachBaseQa, "HFCASCBACHEXT", + hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz); + +using HfCandCascBachQa = HfCandCascBachExtQa; + +// KF specific information for HfCandCascBach +DECLARE_SOA_TABLE(HfCandCascBachKfQa, "AOD", "HFCASCBACHKF", + hf_cand_casc_bach_qa::Chi2Geo, hf_cand_casc_bach_qa::Chi2GeoCascade, hf_cand_casc_bach_qa::Chi2GeoV0, + hf_cand_casc_bach_qa::NdfGeo, hf_cand_casc_bach_qa::NdfGeoCascade, hf_cand_casc_bach_qa::NdfGeoV0, + hf_cand_casc_bach_qa::DecayLengthNormKf, hf_cand_casc_bach_qa::DecayLengthNormKfCascade, hf_cand_casc_bach_qa::DecayLengthNormKfV0, + hf_cand_casc_bach_qa::Chi2TopoToPv, hf_cand_casc_bach_qa::Chi2TopoCascadeToPv, hf_cand_casc_bach_qa::Chi2TopoV0ToPv, + hf_cand_casc_bach_qa::NdfTopoToPv, hf_cand_casc_bach_qa::NdfTopoCascadeToPv, hf_cand_casc_bach_qa::NdfTopoV0ToPv, + hf_cand_casc_bach_qa::Chi2TopoCascadeToCharmHadron, hf_cand_casc_bach_qa::Chi2TopoV0ToCascade, + hf_cand_casc_bach_qa::NdfTopoCascadeToCharmHadron, hf_cand_casc_bach_qa::NdfTopoV0ToCascade, + /* dynamic columns */ + hf_cand_casc_bach_qa::Chi2GeoOverNdf, + hf_cand_casc_bach_qa::Chi2GeoOverNdfCascade, + hf_cand_casc_bach_qa::Chi2GeoOverNdfV0, + hf_cand_casc_bach_qa::Chi2TopoOverNdfToPv, + hf_cand_casc_bach_qa::Chi2TopoOverNdfCascadeToPv, + hf_cand_casc_bach_qa::Chi2TopoOverNdfV0ToPv, + hf_cand_casc_bach_qa::Chi2TopoOverNdfCascadeToCharmHadron, + hf_cand_casc_bach_qa::Chi2TopoOverNdfV0ToCascade); + +// table with results of reconstruction level MC matching +DECLARE_SOA_TABLE(HfCandCascBachMCRecQa, "AOD", "HFCASCBACHMCREC", //! + hf_cand_mc_flag::FlagMcMatchRec, + hf_cand_mc_flag::OriginMcRec, + hf_cand_mc_flag::FlagMcDecayChanRec, + hf_cand_mc_flag::PtBhadMotherPart, + hf_cand_mc_flag::PdgBhadMotherPart, + hf_cand_mc_flag::NTracksDecayed, + hf_cand_mc_flag::NInteractionsWithMaterial); + +// table with results of generator level MC matching +DECLARE_SOA_TABLE(HfCandCascBachMCGenQa, "AOD", "HFCASCBACHMCGEN", //! + hf_cand_mc_flag::FlagMcMatchGen, + hf_cand_mc_flag::OriginMcGen, + hf_cand_mc_flag::FlagMcDecayChanGen, + hf_cand_mc_flag::IdxBhadMotherPart); + // specific Xic to Xi Pi Pi candidate properties namespace hf_cand_xic_to_xi_pi_pi { diff --git a/PWGHF/DataModel/CandidateSelectionTables.h b/PWGHF/DataModel/CandidateSelectionTables.h index 0e06ab6797c..9681cc09b06 100644 --- a/PWGHF/DataModel/CandidateSelectionTables.h +++ b/PWGHF/DataModel/CandidateSelectionTables.h @@ -309,6 +309,7 @@ DECLARE_SOA_TABLE(HfSelToOmegaKaKf, "AOD", "HFSELTOOMEGAKAKF", DECLARE_SOA_TABLE(HfMlSelOmegacToOmegaPi, "AOD", "HFMLOMEGAC", //! hf_sel_toomegapi::MlProbOmegac); + namespace hf_sel_toomegaka { DECLARE_SOA_COLUMN(StatusPidLambda, statusPidLambda, bool); @@ -337,6 +338,30 @@ DECLARE_SOA_TABLE(HfSelToOmegaKa, "AOD", "HFSELTOOMEKA", hf_sel_toomegaka::TpcNSigmaKaFromCharmBaryon, hf_sel_toomegaka::TpcNSigmaKaFromCasc, hf_sel_toomegaka::TpcNSigmaPiFromLambda, hf_sel_toomegaka::TpcNSigmaPrFromLambda, hf_sel_toomegaka::TofNSigmaKaFromCharmBaryon, hf_sel_toomegaka::TofNSigmaKaFromCasc, hf_sel_toomegaka::TofNSigmaPiFromLambda, hf_sel_toomegaka::TofNSigmaPrFromLambda) +namespace hf_sel_candidate_omegac0_qa +{ +DECLARE_SOA_COLUMN(IsSelOmegaC0ToOmegaPi, isSelOmegaC0ToOmegaPi, int); //! +DECLARE_SOA_COLUMN(MlProbOmegaC0ToOmegaPi, mlProbOmegaC0ToOmegaPi, std::vector); //! +} // namespace hf_sel_candidate_omegac0_qa + +DECLARE_SOA_TABLE(HfSelOmegaC0ToOmegaPi, "AOD", "HFSELOMEGAC0QA", //! + hf_sel_candidate_omegac0_qa::IsSelOmegaC0ToOmegaPi); + +DECLARE_SOA_TABLE(HfMlOmegaC0ToOmegaPi, "AOD", "HFMLOMEGAC0QA", //! + hf_sel_candidate_omegac0_qa::MlProbOmegaC0ToOmegaPi); + +namespace hf_sel_candidate_to_xi_pi_qa +{ +DECLARE_SOA_COLUMN(IsSelToXiPi, isSelToXiPi, int); //! +DECLARE_SOA_COLUMN(MlProbToXiPi, mlProbToXiPi, std::vector); //! +} // namespace hf_sel_candidate_to_xi_pi_qa + +DECLARE_SOA_TABLE(HfSelToXiPiQa, "AOD", "HFSELTOXIPIQA", //! + hf_sel_candidate_to_xi_pi_qa::IsSelToXiPi); + +DECLARE_SOA_TABLE(HfMlToXiPiQa, "AOD", "HFMLTOXIPIQA", //! + hf_sel_candidate_to_xi_pi_qa::MlProbToXiPi); + } // namespace o2::aod #endif // PWGHF_DATAMODEL_CANDIDATESELECTIONTABLES_H_ diff --git a/PWGHF/TableProducer/candidateCreatorXic0Omegac0Qa.cxx b/PWGHF/TableProducer/candidateCreatorXic0Omegac0Qa.cxx index aea310d16b4..ade462fa1ca 100644 --- a/PWGHF/TableProducer/candidateCreatorXic0Omegac0Qa.cxx +++ b/PWGHF/TableProducer/candidateCreatorXic0Omegac0Qa.cxx @@ -14,13 +14,14 @@ /// /// \author Jinhyun Park , Pusan National University /// \author Krista Smith , Pusan National University +/// \author Fabio Catalano , University of Houston #ifndef HomogeneousField #define HomogeneousField // o2-linter: disable=name/macro (required by KFParticle) #endif #include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/Core/DecayChannelsLegacy.h" +#include "PWGHF/Core/DecayChannels.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/TrackIndexSkimmingTables.h" @@ -84,97 +85,75 @@ using namespace o2::hf_occupancy; using namespace o2::constants::physics; using namespace o2::hf_evsel; -struct HfCandidateCreatorXic0Omegac0Qa { +constexpr int nMcDecayChannels = hf_decay::hf_cand_casc_bach_qa::DecayChannelMain::NChannelsMain; - // Cursor to fill tables - struct : ProducesGroup { - // Candidates created with DCAFitter - Produces rowCandToXiPi; - Produces rowCandToOmegaPi; - Produces rowCandToOmegaKa; - // Candidate created with KFParticle - Produces rowCandToXiPiKf; - Produces rowCandToOmegaPiKf; - Produces rowCandToOmegaKaKf; - } cursors; +struct HfCandidateCreatorXic0Omegac0Qa { + Produces rowCandCascBatch; + // Additional information for candidates created with KFParticle + Produces rowCandCascBatchKf; - // Configurables struct : ConfigurableGroup { - + std::string prefix = "lfBuilding"; // Options for internal cascade building - DCAFitter settings // ...Initial vaules taken from PWGLF/Utils/strangenessBuilderHelper - // ---------------------------------------------------------------- - Configurable propagateToPCALF{"propagateToPCALF", true, "Create tracks version propagated to PCA"}; - Configurable maxRLF{"maxRLF", 200., "Reject PCA's above this radius"}; - Configurable maxDZIniLF{"maxDZIniLF", 1e9, "Reject (if>0) PCA candidate if tracks DZ exceeds this threshold"}; - Configurable maxDXYIniLF{"maxDXYIniLF", 4.0f, "Reject (if>0) PCA candidate if tracks DXY exceeds this threshold"}; - Configurable minParamChangeLF{"minParamChangeLF", 1.e-3, "Stop iteration if largest change of any X is smaller than this"}; - Configurable minRelChi2ChangeLF{"minRelChi2ChangeLF", 0.9, "Stop iteration if Chi2/Chi2old > this"}; - Configurable maxChi2LF{"maxChi2LF", 1e9, "Discard vertices with Chi2/Nprongs > this(or sum {DCAi^2}/Nprongs for abs. distance minimization)"}; - Configurable useAbsDCALF{"useAbsDCALF", true, "Minimise abs. distance rather than chi2"}; - Configurable useWeightedFinalPCALF{"useWeightedFinalPCALF", false, "Recalculate vertex position using track covariance, effective only if useAbsDCA is true"}; - Configurable refitWithMaterialCorrectionLF{"refitWithMaterialCorrectionLF", false, "Do refit after material correction applied"}; - + Configurable propagateToPCA{"propagateToPCA", true, "Create tracks version propagated to PCA"}; + Configurable maxR{"maxR", 200., "Reject PCA's above this radius"}; + Configurable maxDZIni{"maxDZIni", 1e9, "Reject (if>0) PCA candidate if tracks DZ exceeds this threshold"}; + Configurable maxDXYIni{"maxDXYIni", 4.0f, "Reject (if>0) PCA candidate if tracks DXY exceeds this threshold"}; + Configurable minParamChange{"minParamChange", 1.e-3, "Stop iteration if largest change of any X is smaller than this"}; + Configurable minRelChi2Change{"minRelChi2Change", 0.9, "Stop iteration if Chi2/Chi2old > this"}; + Configurable maxChi2{"maxChi2", 1e9, "Discard vertices with Chi2/Nprongs > this(or sum {DCAi^2}/Nprongs for abs. distance minimization)"}; + Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; + Configurable useWeightedFinalPCA{"useWeightedFinalPCA", false, "Recalculate vertex position using track covariance, effective only if useAbsDCA is true"}; + Configurable refitWithMaterialCorrection{"refitWithMaterialCorrection", false, "Do refit after material correction applied"}; // Options for internal V0 building // ...Initial values taken from PWGLF/Utiles/strangenessBuilderModule.h // ...Modified according to the configurable in core wagon - // --------------------------------------------------------------------- - Configurable minCrossedRowsFromLF{"minCrossedRowsFromLF", 50, "minimun TPC crossed rows for daughter tracks. Used for internal V0 Building"}; - Configurable dcanegtopvFromLF{"dcanegtopvFromLF", .1, "DCV Neg to PV"}; - Configurable dcapostopvFromLF{"dcapostopvFromLF", .1, "DCV Pos To PV"}; - Configurable v0cospaFromLF{"v0cospaFromLF", 0.95, "V0 CosPA"}; - Configurable dcav0dauFromLF{"dcav0dauFromLF", 1.0, "DCA V0 Daughters"}; - Configurable v0radiusFromLF{"v0radiusFromLF", 0.9, "v0radius"}; - Configurable maxDaughterEtaFromLF{"maxDaughterEtaFromLF", 5.0, "Maximun daughter eta (in abs value)"}; - + Configurable minCrossedRows{"minCrossedRows", 50, "minimun TPC crossed rows for daughter tracks. Used for internal V0 Building"}; + Configurable dcanegtopv{"dcanegtopv", .1, "DCV Neg to PV"}; + Configurable dcapostopv{"dcapostopv", .1, "DCV Pos To PV"}; + Configurable v0cospa{"v0cospa", 0.95, "V0 CosPA"}; + Configurable dcav0dau{"dcav0dau", 1.0, "DCA V0 Daughters"}; + Configurable v0radius{"v0radius", 0.9, "v0radius"}; + Configurable maxDaughterEta{"maxDaughterEta", 5.0, "Maximun daughter eta (in abs value)"}; // Options for internal cascade building // ...Initial values taken from PWGLF/Utiles/strangenessBuilderModule.h // ...Modified according to the configurable in core wagon - // -------------------------------------------------------------------- - Configurable dcabachtopvFromLF{"dcabachtopvFromLF", .05, "DCV Bach to PV"}; - Configurable cascradiusFromLF{"cascradiusFromLF", .9, "DCV Bach to PV"}; - Configurable casccospaFromLF{"casccospaFromLF", 0.95, "Cascade CosPA"}; - Configurable dcacascdauFromLF{"dcacascdauFromLF", 1.0, "DCA cascade daughters"}; - Configurable lambdaMassWindowFromLF{"lambdaMassWindowFromLF", 0.01, "Distance from Lambda mass(does not apply to KF path)"}; - + Configurable dcabachtopv{"dcabachtopv", .05, "DCV Bach to PV"}; + Configurable cascradius{"cascradius", .9, "DCV Bach to PV"}; + Configurable casccospa{"casccospa", 0.95, "Cascade CosPA"}; + Configurable dcacascdau{"dcacascdau", 1.0, "DCA cascade daughters"}; + Configurable lambdaMassWindow{"lambdaMassWindow", 0.01, "Distance from Lambda mass(does not apply to KF path)"}; // Options for internal cascade building - KF Building specifics // ...Initial values taken from PWGLF/Utiles/strangenessBuilderModule.h - // -------------------------------------------------------------------- - Configurable kfTuneForOmegaFromLF{"kfTuneForOmegaFromLF", false, "if enabled, take main cascade properties from omega fit instread of Xi fit(=default)"}; - Configurable kfConstructMethodFromLF{"kfConstructMethodFromLF", 2, "2 : Daughter particle masses stay fixed in construction process"}; - Configurable kfUseV0MassConstraintFromLF{"kfUseV0MassConstraintFromLF", true, "KF : Use Lambda mass constraint"}; - Configurable kfUseCascadeMassConstraintFromLF{"kfUseCascadeMassConstraintFromLF", false, "KF : Use Cascade mass constraint - WARNING : Not adequate for inv mass analysis of Xi"}; - Configurable kfDoDCAFitterPreMinimV0FromLF{"kfDoDCAFitterPreMinimV0FromLF", true, "KF : do DCAFitter pre-optimization before KF fit to include material correction for V0"}; - Configurable kfDoDCAFitterPreMinimCascFromLF{"kfDoDCAFitterPreMinimCascFromLF", false, "KF : do DCAFitter pre-optimization before KF fit to include material correction for Xi"}; - } LFConfigs; + Configurable kfTuneForOmega{"kfTuneForOmega", false, "if enabled, take main cascade properties from omega fit instread of Xi fit(=default)"}; + Configurable kfConstructMethod{"kfConstructMethod", 2, "2 : Daughter particle masses stay fixed in construction process"}; + Configurable kfUseV0MassConstraint{"kfUseV0MassConstraint", true, "KF : Use Lambda mass constraint"}; + Configurable kfUseCascadeMassConstraint{"kfUseCascadeMassConstraint", false, "KF : Use Cascade mass constraint - WARNING : Not adequate for inv mass analysis of Xi"}; + Configurable kfDoDCAFitterPreMinimV0{"kfDoDCAFitterPreMinimV0", true, "KF : do DCAFitter pre-optimization before KF fit to include material correction for V0"}; + Configurable kfDoDCAFitterPreMinimCasc{"kfDoDCAFitterPreMinimCasc", false, "KF : do DCAFitter pre-optimization before KF fit to include material correction for Xi"}; + } lfConfigs; - // For cascade building using LF strangeness builder - o2::pwglf::strangenessBuilderHelper straHelper; - - // Configurables struct : ConfigurableGroup { // Switch for filling histograms - // ----------------------------- Configurable fillHistograms{"fillHistograms", true, "fill validation plots"}; - // Magnetic field setting from CCDB - // -------------------------------- Configurable isRun2{"isRun2", false, "enable Run2 or Run3 GRP objects for magnetic field"}; Configurable ccdbUrl{"ccdbUrl", "https://alice-ccdb.cern.ch", "url of the ccdb object"}; Configurable ccdbPathLut{"ccdbPathLut", "GLO/Param/MatLUT", "Path for LUT parameterization"}; Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "path of the group file (Run2)"}; Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run3)"}; - + // Flags to enable creation for different particle species separately + Configurable createToXiPi{"createToXiPi", false, "enable XiC0 (OmegaC0) -> Xi pi candidate creation"}; + Configurable createOmegaCToOmegaPi{"createOmegaCToOmegaPi", false, "enable OmegaC0 -> Omega Pi candidate creation"}; + Configurable createOmegaCToOmegaK{"createOmegaCToOmegaK", false, "enable OmegaC0 -> Omega K candidate creation"}; // Cascade pre selection - // --------------------- Configurable doCascadePreselection{"doCascadePreselection", true, "Use invariant mass and dcaXY cuts to preselect cascade candidates"}; Configurable massToleranceCascade{"massToleranceCascade", 0.01, "Invariant mass tolerance for cascades"}; Configurable dcaXYToPVCascadeMax{"dcaXYToPVCascadeMax", 3, "Max cascade DCA to PV in XY plane"}; Configurable dcaV0DaughtersMax{"dcaV0DaughtersMax", 1.0, "Max DCA of V0 daughter"}; Configurable dcaCascDaughtersMax{"dcaCascDaughtersMax", 1.0, "Max DCA of cascade daughter"}; - // Options for DCAFitter - // --------------------- Configurable propagateToPCA{"propagateToPCA", true, "Create tracks version propagated to PCA"}; Configurable maxR{"maxR", 200., "Reject PCA's above this radius"}; Configurable maxDZIni{"maxDZIni", 4., "Reject (if>0) PCA candidate if tracks DZ exceeds this threshold"}; @@ -184,18 +163,14 @@ struct HfCandidateCreatorXic0Omegac0Qa { Configurable maxChi2{"maxChi2", 100, "Discard vertices with Chi2/Nprongs > this(or sum {DCAi^2}/Nprongs for abs. distance minimization)"}; Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; Configurable useWeightedFinalPCA{"useWeightedFinalPCA", true, "Recalculate vertex position using track covariance, effective only if useAbsDCA is true"}; - // Options for KFParticle - // ---------------------- // V0 cuts Configurable lambdaMassWindow{"lambdaMassWindow", 0.0075, "Distance from LambdaMass"}; // For KF Particle operation Configurable kfConstructMethod{"kfConstructMethod", 2, "KF Construct method"}; Configurable kfUseV0MassConstraint{"kfUseV0MassConstraint", false, "KF: Use lambda mass constraint"}; Configurable kfUseCascadeMassConstraint{"kfUseCascadeMassConstraint", false, "KF: Use lambda mass constraint"}; - // Options for QA histogram binning - // ----------------------------- // For Cascade Configurable nBinMassCasc{"nBinMassCasc", 1000, "nBinCascMass"}; Configurable minMassCasc{"minMassCasc", 1.0, "xiMassMin"}; @@ -203,7 +178,6 @@ struct HfCandidateCreatorXic0Omegac0Qa { Configurable nBinPtCasc{"nBinPtCasc", 100, "nBinPtXi"}; Configurable minPtCasc{"minPtCasc", 0.0, "minimun value of cascade"}; Configurable maxPtCasc{"maxPtCasc", 20.0, "maximum value of cascade"}; - // For Prong0 Configurable nBinMassProng0{"nBinMassProng0", 100, "nBinMassPi"}; Configurable minMassProng0{"minMassProng0", 0.0, "ptPiMin"}; @@ -211,7 +185,6 @@ struct HfCandidateCreatorXic0Omegac0Qa { Configurable nBinPtProng0{"nBinPtProng0", 100, "nBinPtProng0"}; Configurable minPtProng0{"minPtProng0", 0.0, "ptPiMin"}; Configurable maxPtProng0{"maxPtProng0", 20.0, "ptPiMax"}; - // For Charm Baryon Configurable nBinMassCharmBaryon{"nBinMassCharmBaryon", 3000, "nBinXic0Mass"}; Configurable minMassCharmBaryon{"minMassCharmBaryon", 1.0, "xic0MassMin"}; @@ -219,7 +192,6 @@ struct HfCandidateCreatorXic0Omegac0Qa { Configurable nBinPtCharmBaryon{"nBinPtCharmBaryon", 100, "nBinXic0Pt"}; Configurable minPtCharmBaryon{"minPtCharmBaryon", 0.0, "xic0PtMin"}; Configurable maxPtCharmBaryon{"maxPtCharmBaryon", 20.0, "xic0PtMax"}; - // Etc Configurable nBinCpa2Prong{"nBinCpa2Prong", 240, "nBinCpa2Prong"}; Configurable cpa2ProngMin{"cpa2ProngMin", -1.2, "cpa2ProngMin"}; @@ -237,150 +209,76 @@ struct HfCandidateCreatorXic0Omegac0Qa { o2::base::MatLayerCylSet* lut{}; o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + // For cascade building using LF strangeness builder + o2::pwglf::strangenessBuilderHelper straHelper; // DCAFitter o2::vertexing::DCAFitterN<2> df; int runNumber{0}; double magneticField{0.}; - enum CharmBaryonCandCounter { All = 0, - HfFlagPass, - CascReconstructed, - VertexFit }; + enum CharmBaryonCandCounter { + All = 0, + HfFlagPass, + CascReconstructed, + VertexFit + }; // Table aliases + using FilteredHfCascLf2Prongs = soa::Filtered; using SelectedCollisions = soa::Join; using TracksWCovIU = soa::Join; using TracksWCovDcaExtraPidPrPiKa = soa::Join; using TracksWCovExtraPidIU = soa::Join; + Filter filterSelCascBach = (configs.createToXiPi && (hf_track_index::hfflag & static_cast(BIT(hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi))) != static_cast(0)) || + (configs.createOmegaCToOmegaPi && (hf_track_index::hfflag & static_cast(BIT(hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi))) != static_cast(0)) || + (configs.createOmegaCToOmegaK && (hf_track_index::hfflag & static_cast(BIT(hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK))) != static_cast(0)); + HistogramRegistry registry{"hists"}; OutputObj zorroSummary{"zorroSummary"}; HfEventSelection hfEvSel; - // PDG Id of daughter tracks & V0s & cascades & charm baryons - Used in KFParticle - int pdgIdOfV0DauPos{}, pdgIdOfV0DauNeg{}, pdgIdOfBach{}, pdgIdOfBachRej{}, pdgIdOfCharmBach{}; - int pdgIdOfV0{}, pdgIdOfCascade{}, pdgIdOfCharmBaryon{}; - - // Track PID: PID value of tracks defined under o2::track::PID namespace - int trackPidOfCascade{}; - - // Mass of daughter tracks & V0s & cascades & charm baryons; - float massOfV0DauPos{}, massOfV0DauNeg{}, massOfCharmBach{}; - float massOfV0{}, massOfCascade{}; - // Pointer of histograms for QA std::shared_ptr hInvMassCharmBaryonToXiPi, hInvMassCharmBaryonToOmegaPi, hInvMassCharmBaryonToOmegaKa; std::shared_ptr hCandidateCounterToXiPi, hCandidateCounterToOmegaPi, hCandidateCounterToOmegaKa; void init(InitContext const&) { - std::vector processesToXiPiDca{doprocessToXiPiWithDCAFitterNoCent, /*doprocessToXiPiWithDCAFitterNoCentWithTrackedCasc,*/ doprocessToXiPiWithDCAFitterCentFT0C, doprocessToXiPiWithDCAFitterCentFT0M}; - std::vector processesToOmegaPiDca{doprocessToOmegaPiWithDCAFitterNoCent, doprocessToOmegaPiWithDCAFitterCentFT0C, doprocessToOmegaPiWithDCAFitterCentFT0M}; - std::vector processesToOmegaKaDca{doprocessToOmegaKaWithDCAFitterNoCent, doprocessToOmegaKaWithDCAFitterCentFT0C, doprocessToOmegaKaWithDCAFitterCentFT0M}; - std::vector processesToXiPiKf{doprocessToXiPiWithKFParticleNoCent, doprocessToXiPiWithKFParticleCentFT0C, doprocessToXiPiWithKFParticleCentFT0M}; - std::vector processesToOmegaPiKf{doprocessToOmegaPiWithKFParticleNoCent, doprocessToOmegaPiWithKFParticleCentFT0C, doprocessToOmegaPiWithKFParticleCentFT0M}; - std::vector processesToOmegaKaKf{doprocessToOmegaKaWithKFParticleNoCent, doprocessToOmegaKaWithKFParticleCentFT0C, doprocessToOmegaKaWithKFParticleCentFT0M}; + // Exit if workflow is not configured correctly + std::vector doprocessDCA{doprocessWithDCAFitterNoCent, /*doprocessWithDCAFitterNoCentWithTrackedCasc,*/ doprocessWithDCAFitterCentFT0C, doprocessWithDCAFitterCentFT0M}; + std::vector doprocessKF{doprocessWithKFParticleNoCent, doprocessWithKFParticleCentFT0C, doprocessWithKFParticleCentFT0M}; std::vector processesCollMonitoring{doprocessCollisionsNoCent, doprocessCollisionsCentFT0C, doprocessCollisionsCentFT0M}; + std::vector creationFlags = {configs.createToXiPi, configs.createOmegaCToOmegaPi, configs.createOmegaCToOmegaK}; - int xipiEnabledDca = std::accumulate(processesToXiPiDca.begin(), processesToXiPiDca.end(), 0); - int xipiEnabledKf = std::accumulate(processesToXiPiKf.begin(), processesToXiPiKf.end(), 0); - int omegapiEnabledDca = std::accumulate(processesToOmegaPiDca.begin(), processesToOmegaPiDca.end(), 0); - int omegapiEnabledKf = std::accumulate(processesToOmegaPiKf.begin(), processesToOmegaPiKf.end(), 0); - int omegakaEnabledDca = std::accumulate(processesToOmegaKaDca.begin(), processesToOmegaKaDca.end(), 0); - int omegakaEnabledKf = std::accumulate(processesToOmegaKaKf.begin(), processesToOmegaKaKf.end(), 0); - - // Exit if workflow is not configured correctly - More than one process function enabled for candidate to XiPi - if ((xipiEnabledDca > 0) && (xipiEnabledKf > 0)) { - LOGP(fatal, "More than one process function enabled for candidte decaying to xi pi"); + int nProcessesDCA = std::accumulate(doprocessDCA.begin(), doprocessDCA.end(), 0); + int nProcessesKF = std::accumulate(doprocessKF.begin(), doprocessKF.end(), 0); + if (nProcessesDCA + nProcessesKF != 1) { + LOGP(fatal, "One and only one process function must be enabled at a time."); } - // Exit if workflow is not configured correctly - More than one process function enabled for candidate to OmegaPi - if ((omegapiEnabledDca > 0) && (omegapiEnabledKf > 0)) { - LOGP(fatal, "More than one process function enabled for candidte decaying to omega pi"); + int nProcessesCollisions = std::accumulate(processesCollMonitoring.begin(), processesCollMonitoring.end(), 0); + if (nProcessesCollisions > 1) { + LOGP(fatal, "At most one process function for collision monitoring can be enabled at a time."); } - - // Exit if workflow is not configured correctly - More than one process function enabled for candidate to OmegaKa - if ((omegakaEnabledDca > 0) && (omegakaEnabledKf > 0)) { - LOGP(fatal, "More than one process function enabled for candidte decaying to omega ka"); + if (nProcessesCollisions == 1) { + if ((doprocessWithDCAFitterNoCent || doprocessWithKFParticleNoCent) && !doprocessCollisionsNoCent) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisionsNoCent\"?"); + } + if ((doprocessWithDCAFitterCentFT0C || doprocessWithKFParticleCentFT0C) && !doprocessCollisionsCentFT0C) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisionsCentFT0C\"?"); + } + if ((doprocessWithDCAFitterCentFT0M || doprocessWithKFParticleCentFT0M) && !doprocessCollisionsCentFT0M) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisionsCentFT0M\"?"); + } } - // Exit if workflow is not configured correctly - More than one process enabled for collision monitoring - if (std::accumulate(processesCollMonitoring.begin(), processesCollMonitoring.end(), 0) > 1) { - LOGP(fatal, "More than one process fucntion for CollMonitoring was enabled. Please choose only one process function"); + if (std::accumulate(creationFlags.begin(), creationFlags.end(), 0) == 0) { + LOGP(fatal, "At least one particle specie should be enabled for the creation."); } - // Assign pdg & mass hypothesis for each decay channel - if (xipiEnabledDca > 0 || xipiEnabledKf > 0) { - pdgIdOfV0DauPos = kProton; - pdgIdOfV0DauNeg = kPiMinus; - pdgIdOfBach = kPiMinus; - pdgIdOfBachRej = 0; // -> Not used in XiPi channel - pdgIdOfCharmBach = kPiPlus; - - pdgIdOfV0 = kLambda0; - pdgIdOfCascade = kXiMinus; - pdgIdOfCharmBaryon = kXiC0; - - trackPidOfCascade = o2::track::PID::XiMinus; - - massOfCharmBach = o2::constants::physics::MassPiPlus; - massOfV0DauPos = o2::constants::physics::MassProton; - massOfV0DauNeg = o2::constants::physics::MassPionCharged; - massOfV0 = o2::constants::physics::MassLambda; - massOfCascade = o2::constants::physics::MassXiMinus; - } else if (omegapiEnabledDca > 0 || omegapiEnabledKf > 0) { - pdgIdOfV0DauPos = kProton; - pdgIdOfV0DauNeg = kPiMinus; - pdgIdOfBach = kKMinus; - pdgIdOfBachRej = kPiMinus; - pdgIdOfCharmBach = kPiPlus; - - pdgIdOfV0 = kLambda0; - pdgIdOfCascade = kOmegaMinus; - pdgIdOfCharmBaryon = kOmegaC0; - - trackPidOfCascade = o2::track::PID::OmegaMinus; - - massOfCharmBach = o2::constants::physics::MassPiPlus; - massOfV0DauPos = o2::constants::physics::MassProton; - massOfV0DauNeg = o2::constants::physics::MassPionCharged; - massOfV0 = o2::constants::physics::MassLambda; - massOfCascade = o2::constants::physics::MassOmegaMinus; - } else if (omegakaEnabledDca > 0 || omegakaEnabledKf > 0) { - pdgIdOfV0DauPos = kProton; - pdgIdOfV0DauNeg = kPiMinus; - pdgIdOfBach = kKMinus; - pdgIdOfBachRej = kPiMinus; - pdgIdOfCharmBach = kKPlus; - - pdgIdOfV0 = kLambda0; - pdgIdOfCascade = kOmegaMinus; - pdgIdOfCharmBaryon = kOmegaC0; - - trackPidOfCascade = o2::track::PID::OmegaMinus; - - massOfCharmBach = o2::constants::physics::MassKPlus; - massOfV0DauPos = o2::constants::physics::MassProton; - massOfV0DauNeg = o2::constants::physics::MassPionCharged; - massOfV0 = o2::constants::physics::MassLambda; - massOfCascade = o2::constants::physics::MassOmegaMinus; - } LOGF(info, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); - LOGF(info, " Chosen reconstruction info: ToXiPi(%d)/ ToOmegaPi(%d)/ ToOmegaKa(%d)", xipiEnabledDca + xipiEnabledKf, omegapiEnabledDca + omegapiEnabledKf, omegakaEnabledDca + omegakaEnabledKf); - LOGF(info, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); - LOGF(info, " PDG ID of V0 positive daughter: %d", pdgIdOfV0DauPos); - LOGF(info, " PDG ID of V0 negative daughter: %d", pdgIdOfV0DauNeg); - LOGF(info, " PDG ID of V0: %d", pdgIdOfV0); - LOGF(info, " PDG ID of Bachelor: %d", pdgIdOfBach); - LOGF(info, " PDG ID of Bachelor Rej: %d", pdgIdOfBachRej); - LOGF(info, " PDG ID of Cascade: %d", pdgIdOfCascade); - LOGF(info, " PDG ID of Charm Bachelor: %d", pdgIdOfCharmBach); - LOGF(info, " PDG ID of Charm Baryon: %d", pdgIdOfCharmBaryon); - LOGF(info, "-----------------------------------------------------------------------"); - LOGF(info, " Mass of V0 set as: %f", massOfV0); - LOGF(info, " Mass of CharmBach set as: %f", massOfCharmBach); - LOGF(info, " Mass of Casc as: %f", massOfCascade); + LOGF(info, " Chosen reconstruction info: ToXiPi(%d)/ ToOmegaPi(%d)/ ToOmegaKa(%d)", configs.createToXiPi.value, configs.createOmegaCToOmegaPi.value, configs.createOmegaCToOmegaK.value); LOGF(info, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); // Add histogram to indicate which sv method was used @@ -398,41 +296,38 @@ struct HfCandidateCreatorXic0Omegac0Qa { runNumber = 0; // Initilization for strangeness builder helper - // -------------------------------------------- - // Settings for internal V0 building - straHelper.v0selections.minCrossedRows = LFConfigs.minCrossedRowsFromLF; - straHelper.v0selections.dcanegtopv = LFConfigs.dcanegtopvFromLF; - straHelper.v0selections.dcapostopv = LFConfigs.dcapostopvFromLF; - straHelper.v0selections.v0cospa = LFConfigs.v0cospaFromLF; - straHelper.v0selections.dcav0dau = LFConfigs.dcav0dauFromLF; - straHelper.v0selections.v0radius = LFConfigs.v0radiusFromLF; - straHelper.v0selections.maxDaughterEta = LFConfigs.maxDaughterEtaFromLF; + straHelper.v0selections.minCrossedRows = lfConfigs.minCrossedRows; + straHelper.v0selections.dcanegtopv = lfConfigs.dcanegtopv; + straHelper.v0selections.dcapostopv = lfConfigs.dcapostopv; + straHelper.v0selections.v0cospa = lfConfigs.v0cospa; + straHelper.v0selections.dcav0dau = lfConfigs.dcav0dau; + straHelper.v0selections.v0radius = lfConfigs.v0radius; + straHelper.v0selections.maxDaughterEta = lfConfigs.maxDaughterEta; // Settings for internal Cascade building - straHelper.cascadeselections.minCrossedRows = LFConfigs.minCrossedRowsFromLF; - straHelper.cascadeselections.dcabachtopv = LFConfigs.dcabachtopvFromLF; - straHelper.cascadeselections.cascradius = LFConfigs.cascradiusFromLF; - straHelper.cascadeselections.casccospa = LFConfigs.casccospaFromLF; - straHelper.cascadeselections.dcacascdau = LFConfigs.dcacascdauFromLF; - straHelper.cascadeselections.lambdaMassWindow = LFConfigs.lambdaMassWindowFromLF; - straHelper.cascadeselections.maxDaughterEta = LFConfigs.maxDaughterEtaFromLF; + straHelper.cascadeselections.minCrossedRows = lfConfigs.minCrossedRows; + straHelper.cascadeselections.dcabachtopv = lfConfigs.dcabachtopv; + straHelper.cascadeselections.cascradius = lfConfigs.cascradius; + straHelper.cascadeselections.casccospa = lfConfigs.casccospa; + straHelper.cascadeselections.dcacascdau = lfConfigs.dcacascdau; + straHelper.cascadeselections.lambdaMassWindow = lfConfigs.lambdaMassWindow; + straHelper.cascadeselections.maxDaughterEta = lfConfigs.maxDaughterEta; // Fitter setting - straHelper.fitter.setPropagateToPCA(LFConfigs.propagateToPCALF); - straHelper.fitter.setMaxR(LFConfigs.maxRLF); - straHelper.fitter.setMaxDZIni(LFConfigs.maxDZIniLF); - straHelper.fitter.setMaxDXYIni(LFConfigs.maxDXYIniLF); - straHelper.fitter.setMinParamChange(LFConfigs.minParamChangeLF); - straHelper.fitter.setMinRelChi2Change(LFConfigs.minRelChi2ChangeLF); - straHelper.fitter.setMaxChi2(LFConfigs.maxChi2LF); - straHelper.fitter.setUseAbsDCA(LFConfigs.useAbsDCALF); - straHelper.fitter.setWeightedFinalPCA(LFConfigs.useWeightedFinalPCALF); - straHelper.fitter.setRefitWithMatCorr(LFConfigs.refitWithMaterialCorrectionLF); + straHelper.fitter.setPropagateToPCA(lfConfigs.propagateToPCA); + straHelper.fitter.setMaxR(lfConfigs.maxR); + straHelper.fitter.setMaxDZIni(lfConfigs.maxDZIni); + straHelper.fitter.setMaxDXYIni(lfConfigs.maxDXYIni); + straHelper.fitter.setMinParamChange(lfConfigs.minParamChange); + straHelper.fitter.setMinRelChi2Change(lfConfigs.minRelChi2Change); + straHelper.fitter.setMaxChi2(lfConfigs.maxChi2); + straHelper.fitter.setUseAbsDCA(lfConfigs.useAbsDCA); + straHelper.fitter.setWeightedFinalPCA(lfConfigs.useWeightedFinalPCA); + straHelper.fitter.setRefitWithMatCorr(lfConfigs.refitWithMaterialCorrection); // Extra initialization for DCAFitter - // ---------------------------------- - if (xipiEnabledDca == 1 || omegapiEnabledDca == 1 || omegakaEnabledDca == 1) { + if (nProcessesDCA == 1) { registry.get(HIST("hVertexerType"))->Fill(aod::hf_cand::VertexerType::DCAFitter); df.setPropagateToPCA(configs.propagateToPCA); df.setMaxR(configs.maxR); @@ -446,49 +341,46 @@ struct HfCandidateCreatorXic0Omegac0Qa { } // Extra initialization for KFParticle - // ----------------------------------- - if (xipiEnabledKf == 1 || omegapiEnabledKf == 1 || omegakaEnabledKf == 1) { + if (nProcessesKF == 1) { registry.get(HIST("hVertexerType"))->Fill(aod::hf_cand::VertexerType::KfParticle); } // initailize HF event selection helper - // ------------------------------------ hfEvSel.init(registry, &zorroSummary); // Histograms for QA - // ----------------- registry.add("ReconstructedDecayChannel", "DecyayChannel", {kTH1F, {{3, 0.0, 3.0}}}); registry.get(HIST("ReconstructedDecayChannel"))->GetXaxis()->SetBinLabel(1 + hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi, "To #Xi #pi"); registry.get(HIST("ReconstructedDecayChannel"))->GetXaxis()->SetBinLabel(1 + hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi, "To #Omega #pi"); registry.get(HIST("ReconstructedDecayChannel"))->GetXaxis()->SetBinLabel(1 + hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK, "To #Omega K"); - if (xipiEnabledDca != 0 || xipiEnabledKf != 0) { - hInvMassCharmBaryonToXiPi = registry.add("hInvMassCharmBaryonToXiPi", "Charm baryon invariant mass - #Xi #pi decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{configs.nBinMassCharmBaryon, configs.minMassCharmBaryon, configs.maxMassCharmBaryon}}}); - hCandidateCounterToXiPi = registry.add("hCandidateCounterToXiPi", "Candidate counter wrt derived data - #Xi #pi decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); - registry.get(HIST("hCandidateCounterToXiPi"))->GetXaxis()->SetBinLabel(1 + All, "Total"); - registry.get(HIST("hCandidateCounterToXiPi"))->GetXaxis()->SetBinLabel(1 + HfFlagPass, "HfFlagPass"); - registry.get(HIST("hCandidateCounterToXiPi"))->GetXaxis()->SetBinLabel(1 + CascReconstructed, "CascReconstructed"); - registry.get(HIST("hCandidateCounterToXiPi"))->GetXaxis()->SetBinLabel(1 + VertexFit, "VertexFit"); + hInvMassCharmBaryonToXiPi = registry.add("hInvMassCharmBaryonToXiPi", "Charm baryon invariant mass - #Xi #pi decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{configs.nBinMassCharmBaryon, configs.minMassCharmBaryon, configs.maxMassCharmBaryon}}}); + hCandidateCounterToXiPi = registry.add("hCandidateCounterToXiPi", "Candidate counter wrt derived data - #Xi #pi decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); + registry.get(HIST("hCandidateCounterToXiPi"))->GetXaxis()->SetBinLabel(1 + All, "Total"); + registry.get(HIST("hCandidateCounterToXiPi"))->GetXaxis()->SetBinLabel(1 + HfFlagPass, "HfFlagPass"); + registry.get(HIST("hCandidateCounterToXiPi"))->GetXaxis()->SetBinLabel(1 + CascReconstructed, "CascReconstructed"); + registry.get(HIST("hCandidateCounterToXiPi"))->GetXaxis()->SetBinLabel(1 + VertexFit, "VertexFit"); + if (configs.createToXiPi) { registry.get(HIST("ReconstructedDecayChannel"))->Fill(hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi); } - if (omegapiEnabledDca != 0 || omegapiEnabledKf != 0) { - hInvMassCharmBaryonToOmegaPi = registry.add("hInvMassCharmBaryonToOmegaPi", "Charm baryon invariant mass - #Omega #pi decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{configs.nBinMassCharmBaryon, configs.minMassCharmBaryon, configs.maxMassCharmBaryon}}}); - hCandidateCounterToOmegaPi = registry.add("hCandidateCounterToOmegaPi", "Candidate counter wrt derived data - #Omega #pi decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); - registry.get(HIST("hCandidateCounterToOmegaPi"))->GetXaxis()->SetBinLabel(1 + All, "Total"); - registry.get(HIST("hCandidateCounterToOmegaPi"))->GetXaxis()->SetBinLabel(1 + HfFlagPass, "HfFlagPass"); - registry.get(HIST("hCandidateCounterToOmegaPi"))->GetXaxis()->SetBinLabel(1 + CascReconstructed, "CascReconstructed"); - registry.get(HIST("hCandidateCounterToOmegaPi"))->GetXaxis()->SetBinLabel(1 + VertexFit, "VertexFit"); + hInvMassCharmBaryonToOmegaPi = registry.add("hInvMassCharmBaryonToOmegaPi", "Charm baryon invariant mass - #Omega #pi decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{configs.nBinMassCharmBaryon, configs.minMassCharmBaryon, configs.maxMassCharmBaryon}}}); + hCandidateCounterToOmegaPi = registry.add("hCandidateCounterToOmegaPi", "Candidate counter wrt derived data - #Omega #pi decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); + registry.get(HIST("hCandidateCounterToOmegaPi"))->GetXaxis()->SetBinLabel(1 + All, "Total"); + registry.get(HIST("hCandidateCounterToOmegaPi"))->GetXaxis()->SetBinLabel(1 + HfFlagPass, "HfFlagPass"); + registry.get(HIST("hCandidateCounterToOmegaPi"))->GetXaxis()->SetBinLabel(1 + CascReconstructed, "CascReconstructed"); + registry.get(HIST("hCandidateCounterToOmegaPi"))->GetXaxis()->SetBinLabel(1 + VertexFit, "VertexFit"); + if (configs.createOmegaCToOmegaPi) { registry.get(HIST("ReconstructedDecayChannel"))->Fill(hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi); } - if (omegakaEnabledDca != 0 || omegakaEnabledKf != 0) { - hInvMassCharmBaryonToOmegaKa = registry.add("hInvMassCharmBaryonToOmegaKa", "Charm baryon invariant mass - #Omega K decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{configs.nBinMassCharmBaryon, configs.minMassCharmBaryon, configs.maxMassCharmBaryon}}}); - hCandidateCounterToOmegaKa = registry.add("hCandidateCounterToOmegaKa", "Candidate counter wrt derived data - #Omega K decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); - registry.get(HIST("hCandidateCounterToOmegaKa"))->GetXaxis()->SetBinLabel(1 + All, "Total"); - registry.get(HIST("hCandidateCounterToOmegaKa"))->GetXaxis()->SetBinLabel(1 + HfFlagPass, "HfFlagPass"); - registry.get(HIST("hCandidateCounterToOmegaKa"))->GetXaxis()->SetBinLabel(1 + CascReconstructed, "CascReconstructed"); - registry.get(HIST("hCandidateCounterToOmegaKa"))->GetXaxis()->SetBinLabel(1 + VertexFit, "VertexFit"); + hInvMassCharmBaryonToOmegaKa = registry.add("hInvMassCharmBaryonToOmegaKa", "Charm baryon invariant mass - #Omega K decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{configs.nBinMassCharmBaryon, configs.minMassCharmBaryon, configs.maxMassCharmBaryon}}}); + hCandidateCounterToOmegaKa = registry.add("hCandidateCounterToOmegaKa", "Candidate counter wrt derived data - #Omega K decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); + registry.get(HIST("hCandidateCounterToOmegaKa"))->GetXaxis()->SetBinLabel(1 + All, "Total"); + registry.get(HIST("hCandidateCounterToOmegaKa"))->GetXaxis()->SetBinLabel(1 + HfFlagPass, "HfFlagPass"); + registry.get(HIST("hCandidateCounterToOmegaKa"))->GetXaxis()->SetBinLabel(1 + CascReconstructed, "CascReconstructed"); + registry.get(HIST("hCandidateCounterToOmegaKa"))->GetXaxis()->SetBinLabel(1 + VertexFit, "VertexFit"); + if (configs.createOmegaCToOmegaK) { registry.get(HIST("ReconstructedDecayChannel"))->Fill(hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK); } @@ -521,371 +413,547 @@ struct HfCandidateCreatorXic0Omegac0Qa { } } - // template function for running charm baryon reconstruction with DCAFitter - /// \brief centEstimator is for different centrality estimators - /// \brief decayChannel is for different decay channels. 0 for XiczeroOmegaczeroToXiPi, 1 for OmegaczeroToOmegaPi, 2 for OmegaczeroToOmeagaK + // template function for running charm baryon reconstruction with DCAFitter for single candidate and decay channel + /// \brief decayChannel is for different decay channels /// \brief Colls is for collision tables joined with different centraltiy estimators /// \brief Hist is for QA histograms - template - void runCreatorWithDCAFitter(Colls const&, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const&, // -> Internal cascade building - aod::V0s const&, // -> Internal v0 building - aod::TracksWCovDca const& tracks, - TracksWCovIU const& lfTracks, - aod::BCsWithTimestamps const&, - Hist& hInvMassCharmBaryon, - Hist& hCandCounter) + template + void buildCandidateWithDCAFitter(TColl const& collision, + TLfTrack const& posTrack, + TLfTrack const& negTrack, + TLfTrack const& bachTrack, + TTrack const& trackCharmBachelor, + Hist& hInvMassCharmBaryon, + Hist& hCandCounter) { - // arrays which holds values for different decay channel reconstruction + // define constants for decay channel (default to values for Xic0/Omegac0 -> Xi pi) + int trackPidOfCascade = o2::track::PID::XiMinus; + double massOfCascade = o2::constants::physics::MassXiMinus; + double massOfCharmBach = o2::constants::physics::MassPiPlus; - // Loop over candidate - for (auto const& cand : candidates) { + if (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) { + trackPidOfCascade = o2::track::PID::OmegaMinus; + massOfCascade = o2::constants::physics::MassOmegaMinus; + massOfCharmBach = o2::constants::physics::MassPiPlus; + } - // Fill cascandidates before selection - if (configs.fillHistograms) { - hCandCounter->Fill(All); - } + if (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK) { + trackPidOfCascade = o2::track::PID::OmegaMinus; + massOfCascade = o2::constants::physics::MassOmegaMinus; + massOfCharmBach = o2::constants::physics::MassKPlus; + } - // Apply hfflag selection for different candidate reconstruction - if (!TESTBIT(cand.hfflag(), decayChannel)) { - continue; - } else { - if (configs.fillHistograms) { - hCandCounter->Fill(HfFlagPass); - } - } + // Make V0 and cascade starting from daugter tracks + // If success, fill Cascade and V0 information for reconstruction + if (!straHelper.buildCascadeCandidate(collision.globalIndex(), + collision.posX(), collision.posY(), collision.posZ(), + posTrack, + negTrack, + bachTrack, + false, // calculateBachelorBaryonVariable + false, // useCascadeMomentumAtPV + true)) { + return; + } - // Event selection - auto collision = cand.collision_as(); - float centrality{-1.f}; - const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); - if (rejectionMask != 0) { // None of the event selection satisfied -> Reject this candidate - continue; - } + float storeMass = (decayChannel == 0) ? straHelper.cascade.massXi : straHelper.cascade.massOmega; + float storePt = RecoDecay::pt(straHelper.cascade.cascadeMomentum); + registry.fill(HIST("hCascMass"), storeMass); + registry.fill(HIST("hCascPt"), storePt); + if (configs.fillHistograms) { + hCandCounter->Fill(CascReconstructed); + } - //------------------------------Set Magnetic field------------------------------ - auto bc = collision.template bc_as(); - if (runNumber != bc.runNumber()) { - LOG(info) << ">>>>>>>>>> Current run Number : " << runNumber; - initCCDB(bc, runNumber, ccdb, configs.isRun2 ? configs.ccdbPathGrp : configs.ccdbPathGrpMag, lut, configs.isRun2); - magneticField = o2::base::Propagator::Instance()->getNominalBz(); - LOG(info) << ">>>>>>>>>> Magnetic field: " << magneticField; - runNumber = bc.runNumber(); - } - straHelper.fitter.setBz(magneticField); // -> Magnetic field setting for internal cascade building - df.setBz(magneticField); // -> Magnetic field setting for charm baryon building + //------------------------------Info of V0 and cascade------------------------------ + // Cascade quantities from LF strangeness builder + // TODO: check if this is necessary or the covariance matrix can be directly used from straHelper.cascade.covariance + std::array covCasc = {0.}; + constexpr int NumCovElement = 6; + constexpr std::array MomInd = {9, 13, 14, 18, 19, 20}; + for (int i = 0; i < NumCovElement; i++) { + covCasc[MomInd[i]] = straHelper.cascade.covariance[MomInd[i]]; + covCasc[i] = straHelper.cascade.covariance[i]; + } - //------------------Intenal Cascade building------------------ - auto cascAodElement = cand.cascade_as(); - auto v0AodElement = cascAodElement.v0_as(); - auto posTrack = lfTracks.rawIteratorAt(v0AodElement.posTrackId()); - auto negTrack = lfTracks.rawIteratorAt(v0AodElement.negTrackId()); - auto bachTrack = lfTracks.rawIteratorAt(cascAodElement.bachelorId()); + //------------------------------Create cascade track------------------------------ + o2::track::TrackParCov trackCasc; + if (bachTrack.sign() < 0) { // Xi- or Omega- + trackCasc = o2::track::TrackParCov(straHelper.cascade.cascadePosition, straHelper.cascade.cascadeMomentum, covCasc, -1, true); + } else if (bachTrack.sign() > 0) { // Xi+ or Omega+ + trackCasc = o2::track::TrackParCov(straHelper.cascade.cascadePosition, straHelper.cascade.cascadeMomentum, covCasc, 1, true); + } else { + return; + } - // Make cascade starting from V0 - // If success, fill Cascade and V0 information for reconstruction - if (!straHelper.buildCascadeCandidate(collision.globalIndex(), - collision.posX(), collision.posY(), collision.posZ(), - posTrack, - negTrack, - bachTrack, - false, // calculateBachelorBaryonVariable - false, // useCascadeMomentumAtPV - true)) { - continue; - } else { - float storeMass = (decayChannel == 0) ? straHelper.cascade.massXi : straHelper.cascade.massOmega; - float storePt = RecoDecay::pt(straHelper.cascade.cascadeMomentum); - registry.fill(HIST("hCascMass"), storeMass); - registry.fill(HIST("hCascPt"), storePt); - if (configs.fillHistograms) { - hCandCounter->Fill(CascReconstructed); - } - } + trackCasc.setAbsCharge(1); + trackCasc.setPID(trackPidOfCascade); - //------------------------------Info of V0 and cascade------------------------------ - // V0 quantities from LF strangeness builder - std::array vertexV0 = {straHelper.cascade.v0Position[0], straHelper.cascade.v0Position[1], straHelper.cascade.v0Position[2]}; - std::array pVecV0DauPos = {straHelper.cascade.positiveMomentum[0], straHelper.cascade.positiveMomentum[1], straHelper.cascade.positiveMomentum[2]}; - std::array pVecV0DauNeg = {straHelper.cascade.negativeMomentum[0], straHelper.cascade.negativeMomentum[1], straHelper.cascade.negativeMomentum[2]}; - std::array pVecV0 = {pVecV0DauPos[0] + pVecV0DauNeg[0], pVecV0DauPos[1] + pVecV0DauNeg[1], pVecV0DauPos[2] + pVecV0DauNeg[2]}; - - // pseudo rapidity - V0 daughters - // float pseudorapV0Dau0 = RecoDecay::eta(pVecV0DauPos); - // float pseudorapV0Dau1 = RecoDecay::eta(pVecV0DauNeg); - - // Cascade quantities from LF strangeness builder - std::array vertexCasc = {straHelper.cascade.cascadePosition[0], straHelper.cascade.cascadePosition[1], straHelper.cascade.cascadePosition[2]}; - std::array const pVecCasc = {straHelper.cascade.cascadeMomentum[0], straHelper.cascade.cascadeMomentum[1], straHelper.cascade.cascadeMomentum[2]}; - std::array covCasc = {0.}; - constexpr int NumCovElement = 6; - constexpr int MomInd[NumCovElement] = {9, 13, 14, 18, 19, 20}; - for (int i = 0; i < NumCovElement; i++) { - covCasc[MomInd[i]] = straHelper.cascade.covariance[MomInd[i]]; - covCasc[i] = straHelper.cascade.covariance[i]; + //------------------------------Fit SV & Create Charm Baryon track------------------------------ + auto trackParCovCharmBachelor = getTrackParCov(trackCharmBachelor); + try { + if (df.process(trackCasc, trackParCovCharmBachelor) == 0) { + return; } + } catch (const std::runtime_error& error) { + LOG(info) << "Run time error found: " << error.what() << ". DCAFitter cannot work. Skipping this candidate"; + return; + } - // pseudo rapidity - cascade bachelor - // float pseudorapCascBachelor = RecoDecay::eta(straHelper.cascade.bachelorMomentum); + if (configs.fillHistograms) { + hCandCounter->Fill(VertexFit); + } - //------------------------------Create cascade track------------------------------ + //------------------------------Calculate physical properties----------------------------- + // get track momenta + std::array pVecCasc{}, pVecCharmBach{}; + df.getTrack(0).getPxPyPzGlo(pVecCasc); + df.getTrack(1).getPxPyPzGlo(pVecCharmBach); + + // get PV Properties + auto primaryVertex = getPrimaryVertex(collision); + auto covMatrixPV = primaryVertex.getCov(); + std::array pvCoord = {collision.posX(), collision.posY(), collision.posZ()}; + + // get SV Properties + auto const& secondaryVertex = df.getPCACandidate(); + auto covMatrixSV = df.calcPCACovMatrixFlat(); + std::array svCoord = {static_cast(secondaryVertex[0]), + static_cast(secondaryVertex[1]), + static_cast(secondaryVertex[2])}; + + float phi{}, theta{}; + getPointDirection(std::array{primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}, secondaryVertex, phi, theta); + float errorDecayLength = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, theta) + getRotatedCovMatrixXX(covMatrixSV, phi, theta)); + float errorDecayLengthXY = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, 0.) + getRotatedCovMatrixXX(covMatrixSV, phi, 0.)); + + // Impact parameters computed with propagatToDCABxByBz method + auto trackParCovV0DauPos = getTrackParCov(posTrack); + auto trackParCovV0DauNeg = getTrackParCov(negTrack); + auto trackParCovBach = getTrackParCov(bachTrack); + + o2::dataformats::DCA impactParameterV0DauPos, impactParameterV0DauNeg, impactParameterCascBach; + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovV0DauPos, 2.f, matCorr, &impactParameterV0DauPos); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovV0DauNeg, 2.f, matCorr, &impactParameterV0DauNeg); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovBach, 2.f, matCorr, &impactParameterCascBach); + + o2::dataformats::DCA impactParameterCasc, impactParameterCharmBach; + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackCasc, 2.f, matCorr, &impactParameterCasc); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovCharmBachelor, 2.f, matCorr, &impactParameterCharmBach); + + // get Casc and Lambda invariant mass - from LF Table + float mCasc = (decayChannel != hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) ? straHelper.cascade.massOmega : straHelper.cascade.massXi; + float mLambda = (straHelper.cascade.charge < 0) ? straHelper.v0.massLambda : straHelper.v0.massAntiLambda; + + // calculate quantities related to cascade and v0 + float cpaCasc = RecoDecay::cpa(pvCoord, straHelper.cascade.cascadePosition, straHelper.cascade.cascadeMomentum); + float cpaxyCasc = RecoDecay::cpaXY(pvCoord, straHelper.cascade.cascadePosition, straHelper.cascade.cascadeMomentum); + float cpaV0 = RecoDecay::cpa(pvCoord, straHelper.cascade.v0Position, straHelper.cascade.v0Momentum); + float cpaxyV0 = RecoDecay::cpaXY(pvCoord, straHelper.cascade.v0Position, straHelper.cascade.v0Momentum); + float cpaCascToCharmHadron = RecoDecay::cpa(svCoord, straHelper.cascade.cascadePosition, straHelper.cascade.cascadeMomentum); + float cpaxyCascToCharmHadron = RecoDecay::cpaXY(svCoord, straHelper.cascade.cascadePosition, straHelper.cascade.cascadeMomentum); + float cpaV0ToCascade = RecoDecay::cpa(straHelper.cascade.cascadePosition, straHelper.cascade.v0Position, straHelper.cascade.v0Momentum); + float cpaxyV0ToCascade = RecoDecay::cpaXY(straHelper.cascade.cascadePosition, straHelper.cascade.v0Position, straHelper.cascade.v0Momentum); + + float etaCasc = RecoDecay::eta(straHelper.cascade.cascadeMomentum); + float etaV0 = RecoDecay::eta(straHelper.cascade.v0Momentum); + + // fill control histogram + if (configs.fillHistograms) { + float massCharmBaryonCand = RecoDecay::m(std::array{pVecCasc, pVecCharmBach}, std::array{massOfCascade, massOfCharmBach}); + hInvMassCharmBaryon->Fill(massCharmBaryonCand); + } - o2::track::TrackParCov trackCasc; - if (bachTrack.sign() < 0) { // Xi- or Omega- - trackCasc = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, -1, true); - } else if (bachTrack.sign() > 0) { // Xi+ or Omega+ - trackCasc = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, 1, true); - } else { - continue; - } + //------------------------------Fill the table----------------------------- + rowCandCascBatch(collision.globalIndex(), + primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ(), + secondaryVertex[0], secondaryVertex[1], secondaryVertex[2], + straHelper.cascade.cascadePosition[0], straHelper.cascade.cascadePosition[1], straHelper.cascade.cascadePosition[2], + straHelper.cascade.v0Position[0], straHelper.cascade.v0Position[1], straHelper.cascade.v0Position[2], + errorDecayLength, errorDecayLengthXY, + pVecCasc[0], pVecCasc[1], pVecCasc[2], + pVecCharmBach[0], pVecCharmBach[1], pVecCharmBach[2], + impactParameterCasc.getY(), impactParameterCharmBach.getY(), + std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBach.getSigmaY2()), + impactParameterCasc.getZ(), impactParameterCharmBach.getZ(), + std::sqrt(impactParameterCasc.getSigmaZ2()), std::sqrt(impactParameterCharmBach.getSigmaZ2()), + impactParameterV0DauPos.getY(), impactParameterV0DauNeg.getY(), impactParameterCascBach.getY(), + impactParameterV0DauPos.getZ(), impactParameterV0DauNeg.getZ(), impactParameterCascBach.getZ(), + std::sqrt(df.getChi2AtPCACandidate()), straHelper.cascade.cascadeDaughterDCA, straHelper.cascade.v0DaughterDCA, + cpaCasc, cpaxyCasc, cpaV0, cpaxyV0, + cpaCascToCharmHadron, cpaxyCascToCharmHadron, cpaV0ToCascade, cpaxyV0ToCascade, + mCasc, mLambda, + etaCasc, etaV0, + trackCharmBachelor.globalIndex(), bachTrack.globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(), + BIT(decayChannel)); + } + + // template function for running charm baryon reconstruction with KFParticle for single candidate and decay channel + /// \brief decayChannel is for different decay channels + /// \brief Colls is for collision tables joined with different centraltiy estimators + /// \brief Hist is for QA histograms + template + void buildCandidateWithKFParticle(TColl const& collision, + TLfTrack const& posTrack, + TLfTrack const& negTrack, + TLfTrack const& bachTrack, + TTrack const& trackCharmBachelor, + Hist& hInvMassCharmBaryon, + Hist& hCandCounter) + { + // define constants for decay channel (default to values for Xic0/Omegac0 -> Xi pi) + int pdgIdOfV0DauPos = kProton; + int pdgIdOfV0DauNeg = kPiMinus; + int pdgIdOfV0 = kLambda0; + double massOfV0 = o2::constants::physics::MassLambda; + + int pdgIdOfBach = kPiMinus; + int pdgIdOfBachRej = kKMinus; // -> Not used in XiPi channel + int pdgIdOfCharmBach = kPiPlus; + int pdgIdOfCascade = kXiMinus; + int pdgIdOfCharmBaryon = kXiC0; + double massOfCascade = o2::constants::physics::MassXiMinus; + + if (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) { + pdgIdOfBach = kKMinus; + pdgIdOfBachRej = kPiMinus; + pdgIdOfCharmBach = kPiPlus; + pdgIdOfCascade = kOmegaMinus; + pdgIdOfCharmBaryon = kOmegaC0; + massOfCascade = o2::constants::physics::MassOmegaMinus; + } + + if (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK) { + pdgIdOfBach = kKMinus; + pdgIdOfBachRej = kPiMinus; + pdgIdOfCharmBach = kKPlus; + pdgIdOfCascade = kOmegaMinus; + pdgIdOfCharmBaryon = kOmegaC0; + massOfCascade = o2::constants::physics::MassOmegaMinus; + } - trackCasc.setAbsCharge(1); - trackCasc.setPID(trackPidOfCascade); + // Make cascade starting from V0 + // If success, fill Cascade and V0 information for reconstruction + if (!straHelper.buildCascadeCandidateWithKF(collision.globalIndex(), + collision.posX(), collision.posY(), collision.posZ(), + posTrack, + negTrack, + bachTrack, + false, // calculateBachelorBaryonVariables + lfConfigs.kfConstructMethod, + lfConfigs.kfTuneForOmega, + lfConfigs.kfUseV0MassConstraint, + lfConfigs.kfUseCascadeMassConstraint, + lfConfigs.kfDoDCAFitterPreMinimV0, + lfConfigs.kfDoDCAFitterPreMinimCasc)) { + return; + } - //------------------------------Fit SV & Create Charm Baryon track------------------------------ + float storeMass = (decayChannel == 0) ? straHelper.cascade.massXi : straHelper.cascade.massOmega; + float storePt = RecoDecay::pt(straHelper.cascade.cascadeMomentum); + registry.fill(HIST("hCascMass"), storeMass); + registry.fill(HIST("hCascPt"), storePt); + if (configs.fillHistograms) { + hCandCounter->Fill(CascReconstructed); + } - // Perform secondary vertex fitting - auto trackCharmBachelor = tracks.rawIteratorAt(cand.prong0Id()); - auto trackParCovCharmBachelor = getTrackParCov(trackCharmBachelor); - try { - if (df.process(trackCasc, trackParCovCharmBachelor) == 0) { - continue; + //------------------------------Cascade pre-selection------------------------------ + // ! only for Xic0, Omegac0 -> Omega K + if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK) { + if (configs.doCascadePreselection) { + if (std::abs(straHelper.cascade.cascadeDCAxy) > configs.dcaXYToPVCascadeMax) { + return; + } + // pre selection on dcaV0Daughters + if (std::abs(straHelper.cascade.v0DaughterDCA) > configs.dcaV0DaughtersMax) { + return; + } + // pre selection on dcaCascDaughters + if (std::abs(straHelper.cascade.cascadeDaughterDCA) > configs.dcaCascDaughtersMax) { + return; + } + // pre selection on invariantmass + if (std::abs(straHelper.cascade.massOmega - massOfCascade) > configs.massToleranceCascade) { + return; } - } catch (const std::runtime_error& error) { - LOG(info) << "Run time error found: " << error.what() << ". DCAFitter cannot work. Skipping this candidate"; - continue; } + } - if (configs.fillHistograms) { - hCandCounter->Fill(VertexFit); - } + //----------Create charm bayron as KF Particle object starting from V0---------- + // Create KFParticle object of V0 Daughter & Bachelor + const KFPTrack kfTrack0 = createKFPTrackFromTrack(posTrack); + const KFPTrack kfTrack1 = createKFPTrackFromTrack(negTrack); + const KFPTrack kfTrackBach = createKFPTrackFromTrack(bachTrack); + + bool isAnti = bachTrack.signed1Pt() > 0; + int bachCharge = (bachTrack.signed1Pt() > 0 ? +1 : -1); + + KFParticle kfPos(kfTrack0, (isAnti ? -pdgIdOfV0DauNeg : pdgIdOfV0DauPos)); + KFParticle kfNeg(kfTrack1, (isAnti ? -pdgIdOfV0DauPos : pdgIdOfV0DauNeg)); + KFParticle kfBach(kfTrackBach, (isAnti ? -pdgIdOfBach : pdgIdOfBach)); + KFParticle kfBachRej(kfTrackBach, (isAnti ? -pdgIdOfBachRej : pdgIdOfBachRej)); // Rej -> Used for Omegac0->OmegaPi only + + // ~~~~~~~Construct V0 with KF~~~~~~~ + const KFParticle* v0Daughters[2] = {&kfPos, &kfNeg}; + KFParticle kfV0; + kfV0.SetConstructMethod(configs.kfConstructMethod); + try { + kfV0.Construct(v0Daughters, 2); + } catch (std::runtime_error& e) { + LOG(debug) << "Failed to construct v0" << e.what(); + return; + } - //------------------------------Calculate physical properties----------------------------- - - // get track momenta - std::array pVecCascAsD, pVecCharmBachAsD; - df.getTrack(0).getPxPyPzGlo(pVecCascAsD); - df.getTrack(1).getPxPyPzGlo(pVecCharmBachAsD); - - std::array pVecCharmBaryon = {pVecCascAsD[0] + pVecCharmBachAsD[0], pVecCascAsD[1] + pVecCharmBachAsD[1], pVecCascAsD[2] + pVecCharmBachAsD[2]}; - std::array pVecBach = {straHelper.cascade.bachelorMomentum[0], straHelper.cascade.bachelorMomentum[1], straHelper.cascade.bachelorMomentum[2]}; - - // get PV Properties - auto primaryVertex = getPrimaryVertex(collision); - auto covMatrixPV = primaryVertex.getCov(); - std::array pvCoord = {collision.posX(), collision.posY(), collision.posZ()}; - - // get SV Properties - auto const& secondaryVertex = df.getPCACandidate(); - auto covMatrixSV = df.calcPCACovMatrixFlat(); - - // DCAxy and DCAz. Computed with propagatToDCABxByBz method - auto trackParCovV0DauPos = getTrackParCov(posTrack); - auto trackParCovV0DauNeg = getTrackParCov(negTrack); - auto trackParCovBach = getTrackParCov(bachTrack); - - o2::dataformats::DCA impactParameterV0DauPos, impactParameterV0DauNeg, impactParameterBach; - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovV0DauPos, 2.f, matCorr, &impactParameterV0DauPos); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovV0DauNeg, 2.f, matCorr, &impactParameterV0DauNeg); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovBach, 2.f, matCorr, &impactParameterBach); - - float dcaxyV0DauPos = impactParameterV0DauPos.getY(); - float dcaxyV0DauNeg = impactParameterV0DauNeg.getY(); - float dcaxyBach = impactParameterBach.getY(); - float dcazV0DauPos = impactParameterV0DauPos.getZ(); - float dcazV0DauNeg = impactParameterV0DauNeg.getZ(); - float dcazBach = impactParameterBach.getZ(); - - // get impact parameter. Compute with propagateToDCABxByBz method - o2::dataformats::DCA impactParameterCasc, impactParameterCharmBach; - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackCasc, 2.f, matCorr, &impactParameterCasc); // trackCasc is TrackParCov object - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovCharmBachelor, 2.f, matCorr, &impactParameterCharmBach); - // float impactParCharmBachFromCharmBayonXY = impactParameterCharmBach.getY(); - // float impactParCharmBachFromCharmBayonZ = impactParameterCharmBach.getZ(); - - // get v0 invariant mass - from LF Table - float mLambda = RecoDecay::m(std::array{pVecV0DauPos, pVecV0DauNeg}, (straHelper.cascade.charge < 0) ? std::array{massOfV0DauPos, massOfV0DauNeg} : std::array{massOfV0DauNeg, massOfV0DauPos}); - - // get Casc mass - from LF Table - float mCasc = (decayChannel != hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) ? straHelper.cascade.massOmega : straHelper.cascade.massXi; - - // get Charm baryon invariant mass - float massCharmBaryonCand = RecoDecay::m(std::array{pVecCascAsD, pVecCharmBachAsD}, std::array{massOfCascade, massOfCharmBach}); - if (configs.fillHistograms) { - hInvMassCharmBaryon->Fill(massCharmBaryonCand); - } + // Require lambda pre-selection before mass constraint + float massLam{}, sigMassLam{}; + kfV0.GetMass(massLam, sigMassLam); + if (std::abs(massLam - MassLambda0) > configs.lambdaMassWindow) { + return; + } + if (sigMassLam <= 0) { + return; + } + if ((kfV0.GetNDF() <= 0) || (kfV0.GetChi2() <= 0)) { + return; + } - // calculate cosine of pointing angle - std::array vtxCoordCharmBaryon = df.getPCACandidatePos(); - float cpaV0 = RecoDecay::cpa(pvCoord, vertexV0, pVecV0); - float cpaCasc = RecoDecay::cpa(pvCoord, vertexCasc, pVecCasc); - float cpaCharmBaryon = RecoDecay::cpa(pvCoord, vtxCoordCharmBaryon, pVecCharmBaryon); - float cpaxyV0 = RecoDecay::cpaXY(pvCoord, vertexV0, pVecV0); - float cpaxyCasc = RecoDecay::cpaXY(pvCoord, vertexCasc, pVecCasc); - float cpaxyCharmBaryon = RecoDecay::cpaXY(pvCoord, vtxCoordCharmBaryon, pVecCharmBaryon); - - // calculate decay length - float decLenV0 = RecoDecay::distance(vertexCasc, vertexV0); - float decLenCasc = RecoDecay::distance(vtxCoordCharmBaryon, vertexCasc); - float decLenCharmBaryon = RecoDecay::distance(pvCoord, vtxCoordCharmBaryon); - float phi, theta; - getPointDirection(std::array{primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}, secondaryVertex, phi, theta); - auto errorDecayLength = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, theta) + getRotatedCovMatrixXX(covMatrixSV, phi, theta)); - auto errorDecayLengthXY = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, 0.) + getRotatedCovMatrixXX(covMatrixSV, phi, 0.)); - - // calcuate ctau - float ctV0 = RecoDecay::ct(pVecV0, decLenV0, MassLambda0); - float ctCasc = RecoDecay::ct(pVecCasc, decLenCasc, massOfCascade); - float ctOmegac0 = RecoDecay::ct(pVecCharmBaryon, decLenCharmBaryon, MassOmegaC0); - float ctXic0 = RecoDecay::ct(pVecCharmBaryon, decLenCharmBaryon, MassXiC0); - - // get eta - float etaV0DauPos = posTrack.eta(); - float etaV0DauNeg = negTrack.eta(); - float etaBach = bachTrack.eta(); - float etaCharmBach = trackCharmBachelor.eta(); - float etaV0 = RecoDecay::eta(pVecV0); - float etaCasc = RecoDecay::eta(pVecCasc); - float etaCharmBaryon = RecoDecay::eta(pVecCharmBaryon); - - // DCA between daughters - float dcaV0Dau = straHelper.cascade.v0DaughterDCA; - float dcaCascDau = straHelper.cascade.cascadeDaughterDCA; - float dcaCharmBaryonDau = std::sqrt(df.getChi2AtPCACandidate()); - - //------------------------------Fill QA histograms----------------------------- - - //------------------------------Fill the table----------------------------- - if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) { - cursors.rowCandToXiPi(collision.globalIndex(), - pvCoord[0], pvCoord[1], pvCoord[2], - secondaryVertex[0], secondaryVertex[1], secondaryVertex[2], - vertexCasc[0], vertexCasc[1], vertexCasc[2], - vertexV0[0], vertexV0[1], vertexV0[2], - bachTrack.sign(), - covMatrixSV[0], covMatrixSV[1], covMatrixSV[2], covMatrixSV[3], covMatrixSV[4], covMatrixSV[5], - pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], - pVecCascAsD[0], pVecCascAsD[1], pVecCascAsD[2], - pVecCharmBachAsD[0], pVecCharmBachAsD[1], pVecCharmBachAsD[2], - pVecV0[0], pVecV0[1], pVecV0[2], - pVecBach[0], pVecBach[1], pVecBach[2], - pVecV0DauPos[0], pVecV0DauPos[1], pVecV0DauPos[2], - pVecV0DauNeg[0], pVecV0DauNeg[1], pVecV0DauNeg[2], - impactParameterCasc.getY(), impactParameterCharmBach.getY(), - impactParameterCasc.getZ(), impactParameterCharmBach.getZ(), - std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBach.getSigmaY2()), - cascAodElement.v0Id(), v0AodElement.posTrackId(), v0AodElement.negTrackId(), - cand.cascadeId(), trackCharmBachelor.globalIndex(), cascAodElement.bachelorId(), - mLambda, mCasc, massCharmBaryonCand, - cpaV0, cpaCharmBaryon, cpaCasc, - cpaxyV0, cpaxyCharmBaryon, cpaxyCasc, - ctOmegac0, ctCasc, ctV0, ctXic0, - etaV0DauPos, etaV0DauNeg, etaBach, etaCharmBach, etaCharmBaryon, etaCasc, etaV0, - dcaxyV0DauPos, dcaxyV0DauNeg, dcaxyBach, - dcazV0DauPos, dcazV0DauNeg, dcazBach, - dcaCascDau, dcaV0Dau, dcaCharmBaryonDau, - decLenCharmBaryon, decLenCasc, decLenV0, errorDecayLength, errorDecayLengthXY); - } else if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) { - cursors.rowCandToOmegaPi(collision.globalIndex(), - pvCoord[0], pvCoord[1], pvCoord[2], - secondaryVertex[0], secondaryVertex[1], secondaryVertex[2], - vertexCasc[0], vertexCasc[1], vertexCasc[2], - vertexV0[0], vertexV0[1], vertexV0[2], - bachTrack.sign(), - covMatrixSV[0], covMatrixSV[1], covMatrixSV[2], covMatrixSV[3], covMatrixSV[4], covMatrixSV[5], - pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], - pVecCascAsD[0], pVecCascAsD[1], pVecCascAsD[2], - pVecCharmBachAsD[0], pVecCharmBachAsD[1], pVecCharmBachAsD[2], - pVecV0[0], pVecV0[1], pVecV0[2], - pVecBach[0], pVecBach[1], pVecBach[2], - pVecV0DauPos[0], pVecV0DauPos[1], pVecV0DauPos[2], - pVecV0DauNeg[0], pVecV0DauNeg[1], pVecV0DauNeg[2], - impactParameterCasc.getY(), impactParameterCharmBach.getY(), - impactParameterCasc.getZ(), impactParameterCharmBach.getZ(), - std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBach.getSigmaY2()), - cascAodElement.v0Id(), v0AodElement.posTrackId(), v0AodElement.negTrackId(), - cand.cascadeId(), trackCharmBachelor.globalIndex(), cascAodElement.bachelorId(), - mLambda, mCasc, massCharmBaryonCand, - cpaV0, cpaCharmBaryon, cpaCasc, - cpaxyV0, cpaxyCharmBaryon, cpaxyCasc, - ctOmegac0, ctCasc, ctV0, - etaV0DauPos, etaV0DauNeg, etaBach, etaCharmBach, etaCharmBaryon, etaCasc, etaV0, - dcaxyV0DauPos, dcaxyV0DauNeg, dcaxyBach, - dcazV0DauPos, dcazV0DauNeg, dcazBach, - dcaCascDau, dcaV0Dau, dcaCharmBaryonDau, - decLenCharmBaryon, decLenCasc, decLenV0, errorDecayLength, errorDecayLengthXY, cand.hfflag()); - } else { - cursors.rowCandToOmegaKa(collision.globalIndex(), - pvCoord[0], pvCoord[1], pvCoord[2], - secondaryVertex[0], secondaryVertex[1], secondaryVertex[2], - vertexCasc[0], vertexCasc[1], vertexCasc[2], - vertexV0[0], vertexV0[1], vertexV0[2], - bachTrack.sign(), - covMatrixSV[0], covMatrixSV[1], covMatrixSV[2], covMatrixSV[3], covMatrixSV[4], covMatrixSV[5], - pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], - pVecCascAsD[0], pVecCascAsD[1], pVecCascAsD[2], - pVecCharmBachAsD[0], pVecCharmBachAsD[1], pVecCharmBachAsD[2], - pVecV0[0], pVecV0[1], pVecV0[2], - pVecBach[0], pVecBach[1], pVecBach[2], - pVecV0DauPos[0], pVecV0DauPos[1], pVecV0DauPos[2], - pVecV0DauNeg[0], pVecV0DauNeg[1], pVecV0DauNeg[2], - impactParameterCasc.getY(), impactParameterCharmBach.getY(), - impactParameterCasc.getZ(), impactParameterCharmBach.getZ(), - std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBach.getSigmaY2()), - cascAodElement.v0Id(), v0AodElement.posTrackId(), v0AodElement.negTrackId(), - cand.cascadeId(), trackCharmBachelor.globalIndex(), cascAodElement.bachelorId(), - mLambda, mCasc, massCharmBaryonCand, - cpaV0, cpaCharmBaryon, cpaCasc, - cpaxyV0, cpaxyCharmBaryon, cpaxyCasc, - ctOmegac0, ctCasc, ctV0, - etaV0DauPos, etaV0DauNeg, etaBach, etaCharmBach, etaCharmBaryon, etaCasc, etaV0, - dcaxyV0DauPos, dcaxyV0DauNeg, dcaxyBach, - dcazV0DauPos, dcazV0DauNeg, dcazBach, - dcaCascDau, dcaV0Dau, dcaCharmBaryonDau, - decLenCharmBaryon, decLenCasc, decLenV0, errorDecayLength, errorDecayLengthXY); + // Set mass constraint to lambda + if (configs.kfUseV0MassConstraint) { + kfV0.SetNonlinearMassConstraint(massOfV0); + } + kfV0.TransportToDecayVertex(); + kfV0.SetPDG(pdgIdOfV0); + + //~~~~~~~Construct cascade with KF~~~~~~~ + const KFParticle* cascDaughters[2] = {&kfBach, &kfV0}; + const KFParticle* cascDaughtersRej[2] = {&kfBachRej, &kfV0}; + KFParticle kfCasc, kfCascRej; + + kfCasc.SetConstructMethod(configs.kfConstructMethod); + try { + kfCasc.Construct(cascDaughters, 2); + } catch (std::runtime_error& e) { + LOG(debug) << "Failed to construct Cascade: " << e.what(); + return; + } + + float massCasc{}, sigMassCasc{}, massCascRej{}, sigMassCascRej{}; + kfCasc.GetMass(massCasc, sigMassCasc); + + if (sigMassCasc <= 0) { + return; + } + if (std::abs(massCasc - massOfCascade) > configs.massToleranceCascade) { + return; + } + if (kfCasc.GetNDF() <= 0 || kfCasc.GetChi2() <= 0) { + return; + } + kfCasc.SetPDG(pdgIdOfCascade); + + // perform cascade building on casc_rej - only for Omega + if constexpr (decayChannel != hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) { + kfCascRej.SetConstructMethod(configs.kfConstructMethod); + try { + kfCascRej.Construct(cascDaughtersRej, 2); + } catch (std::runtime_error& e) { + LOG(debug) << "Failed to construct Cascade_rej: " << e.what(); + return; } - } // candidate loop - } // end of run function - // template function for running Charm Baryon reconstruction via KFParticle method + kfCascRej.GetMass(massCascRej, sigMassCascRej); + kfCascRej.SetPDG(pdgIdOfCascade); + } + + // Set mass constraint to cascade + if (configs.kfUseCascadeMassConstraint) { + kfCasc.SetNonlinearMassConstraint(massOfCascade); + } + kfCasc.TransportToDecayVertex(); + + //~~~~~~~Construct Charm Baryon with KF~~~~~~~ + const KFPTrack kfTrackCharmBach = createKFPTrackFromTrack(trackCharmBachelor); + const KFParticle kfCharmBach(kfTrackCharmBach, (isAnti ? -pdgIdOfCharmBach : pdgIdOfCharmBach)); + const KFParticle* charmBaryonDaughters[2] = {&kfCharmBach, &kfCasc}; + + KFParticle kfCharmBaryon; + kfCharmBaryon.SetConstructMethod(configs.kfConstructMethod); + try { + kfCharmBaryon.Construct(charmBaryonDaughters, 2); + } catch (std::runtime_error& e) { + LOG(debug) << "Failed to construct Charm baryon: " << e.what(); + return; + } + + float massCharmBaryon{}, sigMassCharmBaryon{}; + kfCharmBaryon.GetMass(massCharmBaryon, sigMassCharmBaryon); + if (sigMassCharmBaryon <= 0) { + return; + } + if (kfCharmBaryon.GetNDF() <= 0 || kfCharmBaryon.GetChi2() <= 0) { + return; + } + + kfCharmBaryon.SetPDG(pdgIdOfCharmBaryon); + kfCharmBaryon.TransportToDecayVertex(); + + if (configs.fillHistograms) { + hCandCounter->Fill(VertexFit); + hInvMassCharmBaryon->Fill(massCharmBaryon); + } + + // Set production vertex + // PV + const KFPVertex kfVertex = createKFPVertexFromCollision(collision); + const KFParticle kfPv(kfVertex); + + // To V0 + kfPos.SetProductionVertex(kfV0); + kfNeg.SetProductionVertex(kfV0); + + // To Casc + KFParticle kfBachToCasc = kfBach; + KFParticle kfV0ToCasc = kfV0; + kfBachToCasc.SetProductionVertex(kfCasc); + kfV0ToCasc.SetProductionVertex(kfCasc); + + // To Charm baryon + KFParticle kfCascToCharmBaryon = kfCasc; + KFParticle kfCharmBachToCharmBaryon = kfCharmBach; + kfCascToCharmBaryon.SetProductionVertex(kfCharmBaryon); + kfCharmBachToCharmBaryon.SetProductionVertex(kfCharmBaryon); + + // To Pv + KFParticle kfV0ToPv = kfV0; + KFParticle kfCascToPv = kfCasc; + KFParticle kfCharmBachToPv = kfCharmBach; + KFParticle kfCharmBaryonToPv = kfCharmBaryon; + kfV0ToPv.SetProductionVertex(kfPv); + kfCascToPv.SetProductionVertex(kfPv); + kfCharmBachToPv.SetProductionVertex(kfPv); + kfCharmBaryonToPv.SetProductionVertex(kfPv); + + //----------Calculate physical quantities ------------- + std::array pvCoord = {collision.posX(), collision.posY(), collision.posZ()}; + std::array svCoord = {kfCharmBaryon.GetX(), kfCharmBaryon.GetY(), kfCharmBaryon.GetZ()}; + std::array vertexV0 = {kfV0.GetX(), kfV0.GetY(), kfV0.GetZ()}; + std::array vertexCasc = {kfCasc.GetX(), kfCasc.GetY(), kfCasc.GetZ()}; + std::array pVecV0 = {kfV0.GetPx(), kfV0.GetPy(), kfV0.GetPz()}; + std::array pVecCasc = {kfCasc.GetPx(), kfCasc.GetPy(), kfCasc.GetPz()}; + + auto trackParCovV0DauPos = getTrackParCovFromKFP(kfPos, convertPDGIntoPID(kfPos.GetPDG()), 1); + auto trackParCovV0DauNeg = getTrackParCovFromKFP(kfNeg, convertPDGIntoPID(kfNeg.GetPDG()), -1); + auto trackParCovBach = getTrackParCovFromKFP(kfBachToCasc, convertPDGIntoPID(kfBachToCasc.GetPDG()), bachCharge); + auto trackParCovCharmBach = getTrackParCovFromKFP(kfCharmBachToCharmBaryon, convertPDGIntoPID(kfCharmBachToCharmBaryon.GetPDG()), -bachCharge); + auto trackParCovCasc = getTrackParCovFromKFP(kfCascToCharmBaryon, convertPDGIntoPID(kfCascToCharmBaryon.GetPDG()), bachCharge); + + trackParCovV0DauPos.setAbsCharge(1); + trackParCovV0DauNeg.setAbsCharge(1); + trackParCovBach.setAbsCharge(1); + trackParCovCharmBach.setAbsCharge(1); + trackParCovCasc.setAbsCharge(1); + + // TODO: check if the impact parameter can be calculated from KFParticle directly + auto primaryVertex = getPrimaryVertex(collision); + o2::dataformats::DCA impactParameterV0DauPos, impactParameterV0DauNeg, impactParameterCascBach; + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovV0DauPos, 2.f, matCorr, &impactParameterV0DauPos); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovV0DauNeg, 2.f, matCorr, &impactParameterV0DauNeg); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovBach, 2.f, matCorr, &impactParameterCascBach); + + o2::dataformats::DCA impactParameterCasc, impactParameterCharmBach; + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovCasc, 2.f, matCorr, &impactParameterCasc); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovCharmBach, 2.f, matCorr, &impactParameterCharmBach); + + float kfDcaV0Daughters = kfNeg.GetDistanceFromParticle(kfPos); + float kfDcaCascDaughters = kfBachToCasc.GetDistanceFromParticle(kfV0ToCasc); + float kfDcaCharmBaryonDaughters = kfCharmBachToCharmBaryon.GetDistanceFromParticle(kfCascToCharmBaryon); + + // Calculate error of decay length using covariance matrix of PV and SV, same as in DCAFitter + float covMatrixPv[6]; + kfVertex.GetCovarianceMatrix(covMatrixPv); + auto* covMatrixSV = kfCharmBaryon.CovarianceMatrix(); + + double phi{}, theta{}; + getPointDirection(pvCoord, svCoord, phi, theta); + float errorDecayLength = std::sqrt(getRotatedCovMatrixXX(covMatrixPv, phi, theta) + getRotatedCovMatrixXX(covMatrixSV, phi, theta)); + float errorDecayLengthXY = std::sqrt(getRotatedCovMatrixXX(covMatrixPv, phi, 0.) + getRotatedCovMatrixXX(covMatrixSV, phi, 0.)); + + // Calculate normalised decay length using KFParticle + float dlV0{}, errDlV0{}; + kfV0ToPv.GetDecayLength(dlV0, errDlV0); + dlV0 = std::abs(dlV0); // KFParticle returns a signed decay length + + float dlCasc{}, errDlCasc{}; + kfCascToPv.GetDecayLength(dlCasc, errDlCasc); + dlCasc = std::abs(dlCasc); + + float dlCharmBaryon{}, dlXYCharmBaryon{}, errDlCharmBaryon{}, errDlXYCharmBaryon{}; + kfCharmBaryonToPv.GetDecayLength(dlCharmBaryon, errDlCharmBaryon); + kfCharmBaryonToPv.GetDecayLengthXY(dlXYCharmBaryon, errDlXYCharmBaryon); + dlCharmBaryon = std::abs(dlCharmBaryon); + + float cosPaCascToPv = RecoDecay::cpa(pvCoord, vertexCasc, pVecCasc); + float cosPaXYCascToPv = RecoDecay::cpaXY(pvCoord, vertexCasc, pVecCasc); + float cosPaV0ToPv = RecoDecay::cpa(pvCoord, vertexV0, pVecV0); + float cosPaXYV0ToPv = RecoDecay::cpaXY(pvCoord, vertexV0, pVecV0); + + float cosPaCascToCharmBaryon = RecoDecay::cpa(svCoord, vertexCasc, pVecCasc); + float cosPaXYCascToCharmBaryon = RecoDecay::cpaXY(svCoord, vertexCasc, pVecCasc); + float cosPaV0ToCasc = RecoDecay::cpa(vertexCasc, vertexV0, pVecV0); + float cosPaXYV0ToCasc = RecoDecay::cpaXY(vertexCasc, vertexV0, pVecV0); + + //------------------------------Fill the table------------------------------ + rowCandCascBatch(collision.globalIndex(), + primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ(), + kfCharmBaryon.GetX(), kfCharmBaryon.GetY(), kfCharmBaryon.GetZ(), + kfCasc.GetX(), kfCasc.GetY(), kfCasc.GetZ(), + kfV0.GetX(), kfV0.GetY(), kfV0.GetZ(), + errorDecayLength, errorDecayLengthXY, + kfCascToCharmBaryon.GetPx(), kfCascToCharmBaryon.GetPy(), kfCascToCharmBaryon.GetPz(), + kfCharmBachToCharmBaryon.GetPx(), kfCharmBachToCharmBaryon.GetPy(), kfCharmBachToCharmBaryon.GetPz(), + impactParameterCasc.getY(), impactParameterCharmBach.getY(), + std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBach.getSigmaY2()), + impactParameterCasc.getZ(), impactParameterCharmBach.getZ(), + std::sqrt(impactParameterCasc.getSigmaZ2()), std::sqrt(impactParameterCharmBach.getSigmaZ2()), + impactParameterV0DauPos.getY(), impactParameterV0DauNeg.getY(), impactParameterCascBach.getY(), + impactParameterV0DauPos.getZ(), impactParameterV0DauNeg.getZ(), impactParameterCascBach.getZ(), + kfDcaCharmBaryonDaughters, kfDcaCascDaughters, kfDcaV0Daughters, + cosPaCascToPv, cosPaXYCascToPv, cosPaV0ToPv, cosPaXYV0ToPv, + cosPaCascToCharmBaryon, cosPaXYCascToCharmBaryon, cosPaV0ToCasc, cosPaXYV0ToCasc, + massCasc, massLam, + kfCasc.GetEta(), kfV0.GetEta(), + trackCharmBachelor.globalIndex(), bachTrack.globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(), + BIT(decayChannel)); + + rowCandCascBatchKf(kfCharmBaryon.Chi2(), kfCasc.Chi2(), kfV0.Chi2(), + kfCharmBaryon.GetNDF(), kfCasc.GetNDF(), kfV0.GetNDF(), + dlCharmBaryon / errDlCharmBaryon, dlCasc / errDlCasc, dlV0 / errDlV0, + kfCharmBaryonToPv.GetChi2(), kfCascToPv.GetChi2(), kfV0ToPv.GetChi2(), + kfCharmBaryonToPv.GetNDF(), kfCascToPv.GetNDF(), kfV0ToPv.GetNDF(), + kfCascToCharmBaryon.GetChi2(), kfV0ToCasc.GetChi2(), + kfCascToCharmBaryon.GetNDF(), kfV0ToCasc.GetNDF()); + } + + // template function for running charm baryon reconstruction + /// \brief recoMethod is for different reconstruction methods (KFParticle or DCAFitter) /// \brief centEstimator is for different centrality estimators - /// \brief decayChannel is for different decay channels. 0 for XiczeroOmegaczeroToXiPi, 1 for OmegaczeroToOmegaPi, 2 for OmegaczeroToOmegaK - /// \brief Colls is for collision tables joined with different centrality estimators - /// \brief Hist is for QA histograms - template - void runCreatorWithKfParticle(Colls const&, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const&, // -> Implemented for internal cascade building - aod::V0s const&, // -> Implemented for internal cascade building - TracksWCovDcaExtraPidPrPiKa const& tracks, - TracksWCovExtraPidIU const& lfTracks, - aod::BCsWithTimestamps const&, - Hist& hInvMassCharmBaryon, - Hist& hCandCounter) + /// \brief Colls is for collision tables joined with different centraltiy estimators + template + void runCreator(Colls const&, + FilteredHfCascLf2Prongs const& candidates, + aod::Cascades const&, + aod::V0s const&, + TTracks const& tracks, + TLfTracks const& lfTracks, + aod::BCsWithTimestamps const&) { - // Loop over candidates + // Loop over candidate for (auto const& cand : candidates) { - // Fill cascandidates before selection - if (configs.fillHistograms) { - hCandCounter->Fill(All); - } - - // Apply hfflag selection - if (!TESTBIT(cand.hfflag(), decayChannel)) { - continue; - } else { - if (configs.fillHistograms) { - hCandCounter->Fill(HfFlagPass); - } - } - // Event selection auto collision = cand.collision_as(); float centrality{-1.f}; const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); - if (rejectionMask != 0) { // None of the event seletion satisfied -> Reject this candidate + if (rejectionMask != 0) { continue; } @@ -898,735 +966,157 @@ struct HfCandidateCreatorXic0Omegac0Qa { LOG(info) << ">>>>>>>>>> Magnetic field: " << magneticField; runNumber = bc.runNumber(); } - // magnetic field setting for KFParticle - straHelper.fitter.setBz(magneticField); // -> Manetic field setting for internal cascade building - KFParticle::SetField(magneticField); // -> Magnetic field setting for CharmBaryon building + // Magnetic field setting for internal cascade building + straHelper.fitter.setBz(magneticField); + // Magnetic field setting for charm baryon building + if constexpr (recoMethod == aod::hf_cand::VertexerType::DCAFitter) { + df.setBz(magneticField); + } else { + KFParticle::SetField(magneticField); + } - //------------------Intenal Cascade building------------------ + // Retrieve tracks for candidate building auto cascAodElement = cand.cascade_as(); auto v0AodElement = cascAodElement.v0_as(); auto posTrack = lfTracks.rawIteratorAt(v0AodElement.posTrackId()); auto negTrack = lfTracks.rawIteratorAt(v0AodElement.negTrackId()); auto bachTrack = lfTracks.rawIteratorAt(cascAodElement.bachelorId()); + auto trackCharmBachelor = tracks.rawIteratorAt(cand.prong0Id()); - // Make cascade starting from V0 - // If success, fill Cascade and V0 information for reconstruction - if (!straHelper.buildCascadeCandidateWithKF(collision.globalIndex(), - collision.posX(), collision.posY(), collision.posZ(), - posTrack, - negTrack, - bachTrack, - false, // calculateBachelorBaryonVariables - LFConfigs.kfConstructMethodFromLF, - LFConfigs.kfTuneForOmegaFromLF, - LFConfigs.kfUseV0MassConstraintFromLF, - LFConfigs.kfUseCascadeMassConstraintFromLF, - LFConfigs.kfDoDCAFitterPreMinimV0FromLF, - LFConfigs.kfDoDCAFitterPreMinimCascFromLF)) { - continue; - } else { - float storeMass = (decayChannel == 0) ? straHelper.cascade.massXi : straHelper.cascade.massOmega; - float storePt = RecoDecay::pt(straHelper.cascade.cascadeMomentum); - registry.fill(HIST("hCascMass"), storeMass); - registry.fill(HIST("hCascPt"), storePt); - if (configs.fillHistograms) { - hCandCounter->Fill(CascReconstructed); - } + // Fill candidates before selection + if (configs.fillHistograms) { + hCandidateCounterToXiPi->Fill(All); + hCandidateCounterToOmegaPi->Fill(All); + hCandidateCounterToOmegaKa->Fill(All); } - //------------------------------Cascade pre-selection------------------------------ - // ! only for Xic0, Omegac0 -> Omega K - if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK) { - if (configs.doCascadePreselection) { - if (std::abs(straHelper.cascade.cascadeDCAxy) > configs.dcaXYToPVCascadeMax) { - continue; - } - // pre selection on dcaV0Daughters - if (std::abs(straHelper.cascade.v0DaughterDCA) > configs.dcaV0DaughtersMax) { - continue; - } - // pre selection on dcaCascDaughters - if (std::abs(straHelper.cascade.cascadeDaughterDCA) > configs.dcaCascDaughtersMax) { - continue; - } - // pre selection on invariantmass - if (std::abs(straHelper.cascade.massOmega - massOfCascade) > configs.massToleranceCascade) { - continue; - } + // Reconstruct charm-baryon candidate for each decay channel it was skimmed for + // We need to douplicate the candidates here to account for different mass hypotheses of cascades and bachelors + if (configs.createToXiPi && TESTBIT(cand.hfflag(), hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi)) { + if (configs.fillHistograms) { + hCandidateCounterToXiPi->Fill(HfFlagPass); } - } - - //----------Create charm bayron as KF Partible object starting from V0---------- - - // Create KFParticle object of V0 Daughter & Bachelor - const KFPTrack kfTrack0 = createKFPTrackFromTrack(posTrack); - const KFPTrack kfTrack1 = createKFPTrackFromTrack(negTrack); - const KFPTrack kfTrackBach = createKFPTrackFromTrack(bachTrack); - - bool isAnti = (bachTrack.signed1Pt() > 0 ? true : false); - int bachCharge = (bachTrack.signed1Pt() > 0 ? +1 : -1); - - KFParticle kfPos(kfTrack0, (isAnti ? -pdgIdOfV0DauNeg : pdgIdOfV0DauPos)); - KFParticle kfNeg(kfTrack1, (isAnti ? -pdgIdOfV0DauPos : pdgIdOfV0DauNeg)); - KFParticle kfBach(kfTrackBach, (isAnti ? -pdgIdOfBach : pdgIdOfBach)); - KFParticle kfBachRej(kfTrackBach, (isAnti ? -pdgIdOfBachRej : pdgIdOfBachRej)); // Rej -> Used for Omegac0->OmegaPi only - - // ~~~~~~~Construct V0 with KF~~~~~~~ - const KFParticle* v0Daughters[2] = {&kfPos, &kfNeg}; - KFParticle kfV0; - kfV0.SetConstructMethod(configs.kfConstructMethod); - try { - kfV0.Construct(v0Daughters, 2); - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to construct v0" << e.what(); - continue; - } - - // Require lambda pre-selection before mass constraint - float massLam, sigMassLam; - kfV0.GetMass(massLam, sigMassLam); - if (std::abs(massLam - MassLambda0) > configs.lambdaMassWindow) { - continue; - } - if (sigMassLam <= 0) { - continue; - } - if ((kfV0.GetNDF() <= 0) || (kfV0.GetChi2() <= 0)) { - continue; - } - - // Set mass constraint to lambda - KFParticle kfV0MassConstrained = kfV0; - kfV0MassConstrained.SetNonlinearMassConstraint(massOfV0); - if (configs.kfUseV0MassConstraint) { - kfV0 = kfV0MassConstrained; - } - kfV0.TransportToDecayVertex(); - kfV0.SetPDG(pdgIdOfV0); - - //~~~~~~~Construct cascade with KF~~~~~~~ - const KFParticle* cascDaughters[2] = {&kfBach, &kfV0}; - const KFParticle* cascDaughtersRej[2] = {&kfBachRej, &kfV0}; - KFParticle kfCasc, kfCascRej; - - kfCasc.SetConstructMethod(configs.kfConstructMethod); - try { - kfCasc.Construct(cascDaughters, 2); - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to construct Cascade: " << e.what(); - continue; - } - - float massCasc, sigMassCasc, massCascRej, sigMassCascRej; - kfCasc.GetMass(massCasc, sigMassCasc); - - if (sigMassCasc <= 0) { - continue; - } - if (std::abs(massCasc - massOfCascade) > configs.massToleranceCascade) { - continue; - } - if (kfCasc.GetNDF() <= 0 || kfCasc.GetChi2() <= 0) { - continue; - } - kfCasc.SetPDG(pdgIdOfCascade); - - // perform cascade building on casc_rej - only for Omega - if constexpr (decayChannel != hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) { - kfCascRej.SetConstructMethod(configs.kfConstructMethod); - try { - kfCascRej.Construct(cascDaughtersRej, 2); - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to construct Cascade_rej: " << e.what(); - continue; + if constexpr (recoMethod == aod::hf_cand::VertexerType::DCAFitter) { + buildCandidateWithDCAFitter(collision, posTrack, negTrack, bachTrack, trackCharmBachelor, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); + } else { + buildCandidateWithKFParticle(collision, posTrack, negTrack, bachTrack, trackCharmBachelor, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); } - - kfCascRej.GetMass(massCascRej, sigMassCascRej); - kfCascRej.SetPDG(pdgIdOfCascade); } - // Set mass constraint to cascade - KFParticle kfCascMassConstrained = kfCasc; - kfCascMassConstrained.SetNonlinearMassConstraint(massOfCascade); - if (configs.kfUseCascadeMassConstraint) { - kfCasc = kfCascMassConstrained; - } - kfCasc.TransportToDecayVertex(); - - //~~~~~~~Construct Charm Baryon with KF~~~~~~~ - auto trackCharmBachelor = tracks.rawIteratorAt(cand.prong0Id()); - const KFPTrack kfTrackCharmBach = createKFPTrackFromTrack(trackCharmBachelor); - const KFParticle kfCharmBach(kfTrackCharmBach, (isAnti ? -pdgIdOfCharmBach : pdgIdOfCharmBach)); - const KFParticle* charmBaryonDaughters[2] = {&kfCharmBach, &kfCasc}; - - KFParticle kfCharmBaryon; - kfCharmBaryon.SetConstructMethod(configs.kfConstructMethod); - try { - kfCharmBaryon.Construct(charmBaryonDaughters, 2); - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to construct Charm baryon: " << e.what(); - continue; + if (configs.createOmegaCToOmegaPi && TESTBIT(cand.hfflag(), hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi)) { + if (configs.fillHistograms) { + hCandidateCounterToOmegaPi->Fill(HfFlagPass); + } + if constexpr (recoMethod == aod::hf_cand::VertexerType::DCAFitter) { + buildCandidateWithDCAFitter(collision, posTrack, negTrack, bachTrack, trackCharmBachelor, hInvMassCharmBaryonToOmegaPi, hCandidateCounterToOmegaPi); + } else { + buildCandidateWithKFParticle(collision, posTrack, negTrack, bachTrack, trackCharmBachelor, hInvMassCharmBaryonToOmegaPi, hCandidateCounterToOmegaPi); + } } - float massCharmBaryon, sigMassCharmBaryon; - kfCharmBaryon.GetMass(massCharmBaryon, sigMassCharmBaryon); - if (sigMassCharmBaryon <= 0) { - continue; - } - if (kfCharmBaryon.GetNDF() <= 0 || kfCharmBaryon.GetChi2() <= 0) { - continue; - } - kfCharmBaryon.TransportToDecayVertex(); - if (configs.fillHistograms) { - hCandCounter->Fill(VertexFit); - hInvMassCharmBaryon->Fill(massCharmBaryon); - } - kfCharmBaryon.SetPDG(pdgIdOfCharmBaryon); - - // Set production vertex - // PV - const KFPVertex kfVertex = createKFPVertexFromCollision(collision); - const KFParticle kfPv(kfVertex); - const KFParticle kfPosOrigin = kfPos; - const KFParticle kfNegOrigin = kfNeg; - - // To V0 - kfPos.SetProductionVertex(kfV0); - kfNeg.SetProductionVertex(kfV0); - - // To Casc - KFParticle kfBachToCasc = kfBach; - KFParticle kfV0ToCasc = kfV0; - kfBachToCasc.SetProductionVertex(kfCasc); - kfV0ToCasc.SetProductionVertex(kfCasc); - - // To Charm baryon - KFParticle kfCascToCharmBaryon = kfCasc; - KFParticle kfCharmBachToCharmBaryon = kfCharmBach; - kfCascToCharmBaryon.SetProductionVertex(kfCharmBaryon); - kfCharmBachToCharmBaryon.SetProductionVertex(kfCharmBaryon); - - // To Pv - KFParticle kfV0ToPv = kfV0; - KFParticle kfCascToPv = kfCasc; - KFParticle kfCharmBachToPv = kfCharmBach; - KFParticle kfCharmBaryonToPv = kfCharmBaryon; - kfV0ToPv.SetProductionVertex(kfPv); - kfCascToPv.SetProductionVertex(kfPv); - kfCharmBachToPv.SetProductionVertex(kfPv); - kfCharmBaryonToPv.SetProductionVertex(kfPv); - - //----------Reconstruct information after vertex fit---------- - auto trackParCovV0DauPos = getTrackParCovFromKFP(kfPos, convertPDGIntoPID(kfPos.GetPDG()), 1); - auto trackParCovV0DauNeg = getTrackParCovFromKFP(kfNeg, convertPDGIntoPID(kfNeg.GetPDG()), -1); - auto trackParCovBach = getTrackParCovFromKFP(kfBachToCasc, convertPDGIntoPID(kfBachToCasc.GetPDG()), bachCharge); - auto trackParCovCharmBach = getTrackParCovFromKFP(kfCharmBachToCharmBaryon, convertPDGIntoPID(kfCharmBachToCharmBaryon.GetPDG()), -bachCharge); - auto trackParCovCasc = getTrackParCovFromKFP(kfCascToCharmBaryon, convertPDGIntoPID(kfCascToCharmBaryon.GetPDG()), bachCharge); - - trackParCovV0DauPos.setAbsCharge(1); - trackParCovV0DauNeg.setAbsCharge(1); - trackParCovBach.setAbsCharge(1); - trackParCovCharmBach.setAbsCharge(1); - trackParCovCasc.setAbsCharge(1); - - std::array vertexV0 = {kfV0.GetX(), kfV0.GetY(), kfV0.GetZ()}; - std::array vertexCasc = {kfCasc.GetX(), kfCasc.GetY(), kfCasc.GetZ()}; - - std::array pVecV0DauPos = {kfPos.GetPx(), kfPos.GetPy(), kfPos.GetPz()}; - std::array pVecV0DauNeg = {kfNeg.GetPx(), kfNeg.GetPy(), kfNeg.GetPz()}; - std::array pVecV0 = {kfV0.GetPx(), kfV0.GetPy(), kfV0.GetPz()}; - std::array pVecBach = {kfBachToCasc.GetPx(), kfBachToCasc.GetPy(), kfBachToCasc.GetPz()}; - std::array pVecCharmBachelorAsD = {kfCharmBachToCharmBaryon.GetPx(), kfCharmBachToCharmBaryon.GetPy(), kfCharmBachToCharmBaryon.GetPz()}; - std::array pVecCharmBaryon = {kfCharmBaryon.GetPx(), kfCharmBaryon.GetPy(), kfCharmBaryon.GetPz()}; - - auto* covVtxCharmBaryon = kfCharmBaryon.CovarianceMatrix(); - float covMatrixPv[6]; - kfVertex.GetCovarianceMatrix(covMatrixPv); - - std::array pvCoord = {collision.posX(), collision.posY(), collision.posZ()}; - - //----------Calculate physical quantities and fill candidate table---------- - - // impact parameters - std::array impactParameterV0DauPos; - std::array impactParameterV0DauNeg; - std::array impactParameterBach; - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovV0DauPos, 2.f, matCorr, &impactParameterV0DauPos); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovV0DauNeg, 2.f, matCorr, &impactParameterV0DauNeg); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovBach, 2.f, matCorr, &impactParameterBach); - float dcaxyV0DauPos = impactParameterV0DauPos[0]; - float dcaxyV0DauNeg = impactParameterV0DauNeg[0]; - float dcaxyBach = impactParameterBach[0]; - float dcazV0DauPos = impactParameterV0DauPos[1]; - float dcazV0DauNeg = impactParameterV0DauNeg[1]; - float dcazBach = impactParameterBach[1]; - - o2::dataformats::DCA impactParameterCasc, impactParameterCharmBachelor; - auto primaryVertex = getPrimaryVertex(collision); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovCasc, 2.f, matCorr, &impactParameterCasc); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovCharmBach, 2.f, matCorr, &impactParameterCharmBachelor); - - // get Chi2Topo/NDF - float chi2NdfTopoV0ToPv = kfV0ToPv.GetChi2() / kfV0ToPv.GetNDF(); - float chi2NdfTopoCascToPv = kfCascToPv.GetChi2() / kfCascToPv.GetNDF(); - float chi2NdfTopoCharmBachToPv = kfCharmBachToPv.GetChi2() / kfCharmBachToPv.GetNDF(); - float chi2NdfTopoCharmBaryonToPv = kfCharmBaryonToPv.GetChi2() / kfCharmBaryonToPv.GetNDF(); - float chi2NdfTopoBachToCasc = kfBachToCasc.GetChi2() / kfBachToCasc.GetNDF(); - float chi2NdfTopoV0ToCasc = kfV0ToCasc.GetChi2() / kfV0ToCasc.GetNDF(); - float chi2NdfTopoCharmBachToCharmBaryon = kfCharmBachToCharmBaryon.GetChi2() / kfCharmBachToCharmBaryon.GetNDF(); - float chi2NdfTopoCascToCharmBaryon = kfCascToCharmBaryon.GetChi2() / kfCascToCharmBaryon.GetNDF(); - - // get ldl - float ldlV0 = ldlFromKF(kfV0, kfPv); - float ldlCasc = ldlFromKF(kfCasc, kfPv); - float ldlCharmBaryon = ldlFromKF(kfCharmBaryon, kfPv); - - // get DCAs - float kfDcaV0Daughters = kfNeg.GetDistanceFromParticle(kfPos); - float kfDcaCascDaughters = kfBachToCasc.GetDistanceFromParticle(kfV0ToCasc); - float kfDcaCharmBaryonDaughters = kfCharmBachToCharmBaryon.GetDistanceFromParticle(kfCascToCharmBaryon); - float kfDcaXYCharmBachelorToPv = kfCharmBachToCharmBaryon.GetDistanceFromVertexXY(kfPv); - float kfDcaXYCascToPv = kfCascToCharmBaryon.GetDistanceFromVertexXY(kfPv); - - // get decay length - In XY - float decayLXYV0, errDecayLXYV0; - kfV0ToCasc.GetDecayLengthXY(decayLXYV0, errDecayLXYV0); - - float decayLXYCasc, errDecayLXYCasc; - kfCascToCharmBaryon.GetDecayLengthXY(decayLXYCasc, errDecayLXYCasc); - - float decayLXYCharmBaryon, errDecayLXYCharmBaryon; - kfCharmBaryonToPv.GetDecayLengthXY(decayLXYCharmBaryon, errDecayLXYCharmBaryon); - - // get decay length - In XYZ - float decayLV0 = RecoDecay::distance(std::array{kfCasc.GetX(), kfCasc.GetY(), kfCasc.GetZ()}, std::array{kfV0.GetX(), kfV0.GetY(), kfV0.GetZ()}); - float decayLCasc = RecoDecay::distance(std::array{kfCharmBaryon.GetX(), kfCharmBaryon.GetY(), kfCharmBaryon.GetZ()}, std::array{kfCasc.GetX(), kfCasc.GetY(), kfCasc.GetZ()}); - float decayLCharmBaryon = RecoDecay::distance(std::array{collision.posX(), collision.posY(), collision.posZ()}, std::array{kfCharmBaryon.GetX(), kfCharmBaryon.GetY(), kfCharmBaryon.GetZ()}); - - double phiCharmBaryon, thetaCharmBaryon; - getPointDirection(std::array{primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}, std::array{kfCharmBaryon.GetX(), kfCharmBaryon.GetY(), kfCharmBaryon.GetZ()}, phiCharmBaryon, thetaCharmBaryon); - float errDecayLCharmBaryon = std::sqrt(getRotatedCovMatrixXX(covMatrixPv, phiCharmBaryon, thetaCharmBaryon) + getRotatedCovMatrixXX(covVtxCharmBaryon, phiCharmBaryon, thetaCharmBaryon)); - - // get cosine of pointing angle - float cosPaV0ToPv = cpaFromKF(kfV0, kfPv); - float cosPaCascToPv = cpaFromKF(kfCasc, kfPv); - float cosPaCharmBaryonToPv = cpaFromKF(kfCharmBaryon, kfPv); - - float cosPaXYV0ToPv = RecoDecay::cpaXY(pvCoord, vertexV0, pVecV0); - float cosPaXYCascToPv = cpaXYFromKF(kfCasc, kfPv); - float cosPaXYCharmBaryonToPv = cpaXYFromKF(kfCharmBaryon, kfPv); - - float cosPaV0ToCasc = cpaFromKF(kfV0, kfCasc); - float cosPaCascToCharmBaryon = cpaFromKF(kfCasc, kfCharmBaryon); - float cosPaXYV0ToCasc = RecoDecay::cpaXY(vertexCasc, vertexV0, pVecV0); - float cosPaXYCascToCharmBaryon = cpaXYFromKF(kfCasc, kfCharmBaryon); - - float deviationCharmBachToPv = kfCalculateChi2ToPrimaryVertex(kfCharmBaryon, kfPv); // -> For Omegac0 - - // KF pT, eta - float ptCasc = kfCascToCharmBaryon.GetPt(); - float ptCharmBachelor = kfCharmBachToCharmBaryon.GetPt(); - float ptCharmBaryon = kfCharmBaryon.GetPt(); - float yCharmBaryon = kfCharmBaryon.GetRapidity(); - - // get KF cosThetaStar - float cosThetaStarCharmBachelor = -99.0; - float cosThetaStarKaFromOmegac0 = -99.0; - float cosThetaStarKaFromXic0 = -99.0; - - if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) { - cosThetaStarCharmBachelor = cosThetaStarFromKF(0, pdgIdOfCharmBaryon, pdgIdOfCharmBach, pdgIdOfCascade, kfCharmBachToCharmBaryon, kfCascToCharmBaryon, pdgdb); - } - if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK) { // -> Only requeted to be calculated and filled for Xic0/Omegac0 -> Omega K - cosThetaStarKaFromOmegac0 = cosThetaStarFromKF(0, 4332, 321, 3334, kfCharmBachToCharmBaryon, kfCascToCharmBaryon, pdgdb); - cosThetaStarKaFromXic0 = cosThetaStarFromKF(0, 4132, 321, 3334, kfCharmBachToCharmBaryon, kfCascToCharmBaryon, pdgdb); + if (configs.createOmegaCToOmegaK && TESTBIT(cand.hfflag(), hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK)) { + if (configs.fillHistograms) { + hCandidateCounterToOmegaKa->Fill(HfFlagPass); + } + if constexpr (recoMethod == aod::hf_cand::VertexerType::DCAFitter) { + buildCandidateWithDCAFitter(collision, posTrack, negTrack, bachTrack, trackCharmBachelor, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaKa); + } else { + buildCandidateWithKFParticle(collision, posTrack, negTrack, bachTrack, trackCharmBachelor, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaKa); + } } + } // candidate loop + } // end of run function - // KF ct - float ctV0 = kfV0ToCasc.GetLifeTime(); - float ctCasc = kfCascToCharmBaryon.GetLifeTime(); - float ctCharmBaryon = kfCharmBaryonToPv.GetLifeTime(); - - //------------------------------Calculate physical quantities and fill candidate table------------------------------ - - //------------------------------Fill the table------------------------------ - if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) { - cursors.rowCandToXiPiKf(collision.globalIndex(), // Global index of collision - pvCoord[0], pvCoord[1], pvCoord[2], // coordination of PV - vertexCasc[0], vertexCasc[1], vertexCasc[2], // Decay position of kfCasc - vertexV0[0], vertexV0[1], vertexV0[2], - bachTrack.sign(), - covVtxCharmBaryon[0], covVtxCharmBaryon[1], covVtxCharmBaryon[2], covVtxCharmBaryon[3], covVtxCharmBaryon[4], covVtxCharmBaryon[5], - pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], // x, y, z momentum of charm baryon - kfCascToCharmBaryon.GetPx(), kfCascToCharmBaryon.GetPy(), kfCascToCharmBaryon.GetPz(), - pVecCharmBachelorAsD[0], pVecCharmBachelorAsD[1], pVecCharmBachelorAsD[2], - pVecV0[0], pVecV0[1], pVecV0[2], - pVecBach[0], pVecBach[1], pVecBach[2], - pVecV0DauPos[0], pVecV0DauPos[1], pVecV0DauPos[2], - pVecV0DauNeg[0], pVecV0DauNeg[1], pVecV0DauNeg[2], - cascAodElement.v0Id(), v0AodElement.posTrackId(), v0AodElement.negTrackId(), - cand.cascadeId(), trackCharmBachelor.globalIndex(), cascAodElement.bachelorId(), - massLam, massCasc, massCharmBaryon, - cosPaV0ToPv, cosPaCascToPv, - ctCasc, ctV0, ctCharmBaryon, - kfPos.GetEta(), kfNeg.GetEta(), kfBach.GetEta(), kfCharmBachToCharmBaryon.GetEta(), - kfCharmBaryon.GetEta(), kfCasc.GetEta(), kfV0.GetEta(), - dcaxyV0DauPos, dcaxyV0DauNeg, dcaxyBach, - kfDcaCascDaughters, kfDcaV0Daughters, kfDcaCharmBaryonDaughters, - kfDcaXYCharmBachelorToPv, kfDcaXYCascToPv, - kfV0.GetChi2(), kfCasc.GetChi2(), kfCharmBaryon.GetChi2(), kfV0MassConstrained.GetChi2(), kfCascMassConstrained.GetChi2(), - ldlV0, ldlCasc, // ldlCharmBaryon, - chi2NdfTopoV0ToPv, chi2NdfTopoCascToPv, chi2NdfTopoCharmBachToPv, chi2NdfTopoCharmBaryonToPv, - chi2NdfTopoV0ToCasc, chi2NdfTopoCascToCharmBaryon, - decayLXYV0, decayLXYCasc, decayLXYCharmBaryon, - cosPaV0ToCasc, cosPaCascToCharmBaryon, // cosPaXYV0ToCasc, cosPaXYCascToCharmBaryon, - yCharmBaryon, // ptCharmBachelor, ptCharmBaryon, - cosThetaStarCharmBachelor, - kfV0.GetNDF(), kfCasc.GetNDF(), kfCharmBaryon.GetNDF(), kfV0MassConstrained.GetNDF(), kfCascMassConstrained.GetNDF(), - kfV0.GetChi2() / kfV0.GetNDF(), kfCasc.GetChi2() / kfCasc.GetNDF(), kfCharmBaryon.GetChi2() / kfCharmBaryon.GetNDF(), kfV0MassConstrained.GetChi2() / kfV0MassConstrained.GetNDF(), kfCascMassConstrained.GetChi2() / kfCascMassConstrained.GetNDF()); - } else if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) { - cursors.rowCandToOmegaPi(collision.globalIndex(), - pvCoord[0], pvCoord[1], pvCoord[2], - 0.f, 0.f, 0.f, // -> vertexCharmBaryonFromFitter. For KF, this is 0 - vertexCasc[0], vertexCasc[1], vertexCasc[2], - vertexV0[0], vertexV0[1], vertexV0[2], - bachTrack.sign(), - covVtxCharmBaryon[0], covVtxCharmBaryon[1], covVtxCharmBaryon[2], covVtxCharmBaryon[3], covVtxCharmBaryon[4], covVtxCharmBaryon[5], - kfCharmBaryon.GetPx(), kfCharmBaryon.GetPy(), kfCharmBaryon.GetPz(), - kfCascToCharmBaryon.GetPx(), kfCascToCharmBaryon.GetPy(), kfCascToCharmBaryon.GetPz(), - kfCharmBachToCharmBaryon.GetPx(), kfCharmBachToCharmBaryon.GetPy(), kfCharmBachToCharmBaryon.GetPz(), - pVecV0[0], pVecV0[1], pVecV0[2], - pVecBach[0], pVecBach[1], pVecBach[2], - pVecV0DauPos[0], pVecV0DauPos[1], pVecV0DauPos[2], - pVecV0DauNeg[0], pVecV0DauNeg[1], pVecV0DauNeg[2], - impactParameterCasc.getY(), impactParameterCharmBachelor.getY(), - impactParameterCasc.getZ(), impactParameterCharmBachelor.getZ(), - std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBachelor.getSigmaY2()), - cascAodElement.v0Id(), v0AodElement.posTrackId(), v0AodElement.negTrackId(), - cand.cascadeId(), trackCharmBachelor.globalIndex(), cascAodElement.bachelorId(), - massLam, massCasc, massCharmBaryon, - cosPaV0ToPv, cosPaCharmBaryonToPv, cosPaCascToPv, cosPaXYV0ToPv, cosPaXYCharmBaryonToPv, cosPaXYCascToPv, - ctCharmBaryon, ctCasc, ctV0, - kfPos.GetEta(), kfNeg.GetEta(), kfBach.GetEta(), kfCharmBachToCharmBaryon.GetEta(), - kfCharmBaryon.GetEta(), kfCasc.GetEta(), kfV0.GetEta(), - dcaxyV0DauPos, dcaxyV0DauNeg, dcaxyBach, - dcazV0DauPos, dcazV0DauNeg, dcazBach, - kfDcaCascDaughters, straHelper.cascade.v0DaughterDCA, kfDcaCharmBaryonDaughters, - decayLCharmBaryon, decayLCasc, decayLV0, errDecayLCharmBaryon, errDecayLXYCharmBaryon, cand.hfflag()); - - cursors.rowCandToOmegaPiKf(kfDcaXYCharmBachelorToPv, kfDcaXYCascToPv, - kfV0.GetChi2(), kfCasc.GetChi2(), kfCharmBaryon.GetChi2(), kfV0MassConstrained.GetChi2(), kfCascMassConstrained.GetChi2(), - ldlV0, ldlCasc, ldlCharmBaryon, - chi2NdfTopoV0ToPv, chi2NdfTopoCascToPv, chi2NdfTopoCharmBachToPv, chi2NdfTopoCharmBaryonToPv, deviationCharmBachToPv, - chi2NdfTopoV0ToCasc, chi2NdfTopoCascToCharmBaryon, - decayLXYV0, decayLXYCasc, decayLXYCharmBaryon, - cosPaV0ToCasc, cosPaCascToCharmBaryon, cosPaXYV0ToCasc, cosPaXYCascToCharmBaryon, - kfCharmBaryon.GetRapidity(), ptCharmBachelor, ptCharmBaryon, - cosThetaStarKaFromOmegac0, - kfV0.GetNDF(), kfCasc.GetNDF(), kfCharmBaryon.GetNDF(), kfV0MassConstrained.GetNDF(), kfCascMassConstrained.GetNDF(), - kfV0.GetChi2() / kfV0.GetNDF(), kfCasc.Chi2() / kfCasc.GetNDF(), kfCharmBaryon.GetChi2() / kfCharmBaryon.GetNDF(), - kfV0MassConstrained.GetChi2() / kfV0.GetNDF(), kfCascMassConstrained.Chi2() / kfCasc.GetNDF(), - massCascRej); - - } else { - cursors.rowCandToOmegaKaKf(collision.globalIndex(), - collision.posX(), collision.posY(), collision.posZ(), - kfPv.GetX(), kfPv.GetY(), kfPv.GetZ(), - straHelper.cascade.v0Position[0], straHelper.cascade.v0Position[1], straHelper.cascade.v0Position[2], - straHelper.cascade.v0Momentum[0], straHelper.cascade.v0Momentum[1], straHelper.cascade.v0Momentum[2], - straHelper.cascade.cascadePosition[0], straHelper.cascade.cascadePosition[1], straHelper.cascade.cascadePosition[2], - straHelper.cascade.cascadeMomentum[0], straHelper.cascade.cascadeMomentum[1], straHelper.cascade.cascadeMomentum[2], - kfV0.GetX(), kfV0.GetY(), kfV0.GetZ(), - kfV0.GetPx(), kfV0.GetPy(), kfV0.GetPz(), - kfCasc.GetX(), kfCasc.GetY(), kfCasc.GetZ(), - kfCasc.GetPx(), kfCasc.GetPy(), kfCasc.GetPz(), - kfCharmBaryon.GetX(), kfCharmBaryon.GetY(), kfCharmBaryon.GetZ(), - kfCharmBaryon.GetPx(), kfCharmBaryon.GetPy(), kfCharmBaryon.GetPz(), - straHelper.cascade.charge, - kfPos.GetEta(), kfNeg.GetEta(), kfBach.GetEta(), kfCharmBach.GetEta(), kfV0.GetEta(), kfCasc.GetEta(), kfCharmBaryon.GetEta(), kfCharmBaryon.GetRapidity(), - impactParameterCharmBachelor.getY(), std::sqrt(impactParameterCharmBachelor.getSigmaY2()), impactParameterCasc.getY(), std::sqrt(impactParameterCasc.getSigmaY2()), - kfDcaV0Daughters, kfDcaCascDaughters, kfDcaCharmBaryonDaughters, - cosPaV0ToPv, cosPaCascToPv, cosPaCharmBaryonToPv, cosPaXYV0ToPv, cosPaXYCascToPv, cosPaXYCharmBaryonToPv, cosPaV0ToCasc, cosPaCascToCharmBaryon, cosPaXYV0ToCasc, cosPaXYCascToCharmBaryon, - kfV0.GetChi2() / kfV0.GetNDF(), kfCasc.GetChi2() / kfCasc.GetNDF(), kfCharmBaryon.GetChi2() / kfCharmBaryon.GetNDF(), - kfV0MassConstrained.GetChi2() / kfV0MassConstrained.GetNDF(), kfCascMassConstrained.GetChi2() / kfCascMassConstrained.GetNDF(), - chi2NdfTopoV0ToCasc, chi2NdfTopoBachToCasc, chi2NdfTopoCharmBachToCharmBaryon, chi2NdfTopoCascToCharmBaryon, // Topological constraints to mother - chi2NdfTopoV0ToPv, chi2NdfTopoCascToPv, chi2NdfTopoCharmBachToPv, chi2NdfTopoCharmBaryonToPv, // Topological constraints to PV - ldlV0, ldlCasc, ldlCharmBaryon, - decayLXYV0, decayLXYCasc, decayLXYCharmBaryon, - massLam, sigMassLam, massCasc, sigMassCasc, massCascRej, sigMassCascRej, massCharmBaryon, sigMassCharmBaryon, - ptCharmBaryon, ptCharmBachelor, ptCasc, - cosThetaStarKaFromOmegac0, cosThetaStarKaFromXic0, ctV0, ctCasc, ctCharmBaryon, - cascAodElement.v0Id(), v0AodElement.posTrackId(), v0AodElement.negTrackId(), cand.cascadeId(), cascAodElement.bachelorId(), trackCharmBachelor.globalIndex()); - } - } // end candidate loop - } // end of runCreator - - ///////////////////////////////////////////////////// - /// /// - /// Process functions with DCAFitter /// - /// /// - ///////////////////////////////////////////////////// - - /*~~~~~~~~~~~~~~*/ - /*~~~To Xi Pi~~~*/ - /*~~~~~~~~~~~~~~*/ - void processToXiPiWithDCAFitterNoCent(SelectedCollisions const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - aod::TracksWCovDca const& tracks, - TracksWCovIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) + // Process functions with DCAFitter + void processWithDCAFitterNoCent(SelectedCollisions const& collisions, + FilteredHfCascLf2Prongs const& candidates, + aod::Cascades const& cascades, + aod::V0s const& v0s, + aod::TracksWCovDca const& tracks, + TracksWCovIU const& lfTracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runCreatorWithDCAFitter(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); + runCreator(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithDCAFitterNoCent, "Charm candidte reconstruction with Xi Pi via DcaFitter method, no centrality", true); + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processWithDCAFitterNoCent, "Charm-baryon candidate reconstruction with DcaFitter method, no centrality", true); +// TODO: add support for tracked cascades #if 0 - void processToXiPiWithDCAFitterNoCentWithTrackedCasc(SelectedCollisions const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::TrackedCascades const& cascades, - aod::V0s const& v0s, - TrackedCascLinked const& trackedCascLinked, - TracksWCovDcaExtraPidPrPiKa const& tracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) + void processWithDCAFitterNoCentWithTrackedCasc(SelectedCollisions const& collisions, + FilteredHfCascLf2Prongs const& candidates, + aod::TrackedCascades const& cascades, + aod::V0s const& v0s, + TrackedCascLinked const& trackedCascLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runCreatorWithDCAFitter(collisions, candidates, trackedCascFull, trackedCascLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); + runCreator(collisions, candidates, trackedCascFull, trackedCascLinked, tracks, bcsWithTimestamps); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithDCAFitterNoCentWithTrackedCasc, "Charm candidte reconstruction with Xi Pi via DcaFitter method with tracked cascade, no centrality", false); + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processWithDCAFitterNoCentWithTrackedCasc, "Charm-baryon candidate reconstruction with DcaFitter method with tracked cascade, no centrality", false); #endif - void processToXiPiWithDCAFitterCentFT0C(soa::Join const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - aod::TracksWCovDca const& tracks, - TracksWCovIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) + void processWithDCAFitterCentFT0C(soa::Join const& collisions, + FilteredHfCascLf2Prongs const& candidates, + aod::Cascades const& cascades, + aod::V0s const& v0s, + aod::TracksWCovDca const& tracks, + TracksWCovIU const& lfTracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runCreatorWithDCAFitter(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); + runCreator(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithDCAFitterCentFT0C, "Charm candidate reconstruction with Xi Pi via DcaFitter method, centrality selection on FT0C", false); - - void processToXiPiWithDCAFitterCentFT0M(soa::Join const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - aod::TracksWCovDca const& tracks, - TracksWCovIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processWithDCAFitterCentFT0C, "Charm-baryon candidate reconstruction with DcaFitter method, centrality selection on FT0C", false); + + void processWithDCAFitterCentFT0M(soa::Join const& collisions, + FilteredHfCascLf2Prongs const& candidates, + aod::Cascades const& cascades, + aod::V0s const& v0s, + aod::TracksWCovDca const& tracks, + TracksWCovIU const& lfTracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runCreatorWithDCAFitter(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); + runCreator(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithDCAFitterCentFT0M, "Charm candidate reconstruction with Xi Pi via DcaFitter method, centrality selection on FT0M", false); - - /*~~~~~~~~~~~~~~~~~*/ - /*~~~To Omega Pi~~~*/ - /*~~~~~~~~~~~~~~~~~*/ - void processToOmegaPiWithDCAFitterNoCent(SelectedCollisions const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - aod::TracksWCovDca const& tracks, - TracksWCovIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processWithDCAFitterCentFT0M, "Charm-baryon candidate reconstruction with DcaFitter method, centrality selection on FT0M", false); + + // Process functions with KFParticle + void processWithKFParticleNoCent(SelectedCollisions const& collisions, + FilteredHfCascLf2Prongs const& candidates, + aod::Cascades const& cascades, + aod::V0s const& v0s, + TracksWCovDcaExtraPidPrPiKa const& tracks, + TracksWCovExtraPidIU const& lfTracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runCreatorWithDCAFitter(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaPi, hCandidateCounterToOmegaPi); + runCreator(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaPiWithDCAFitterNoCent, "Charm candidte reconstruction with Omega Pi via DcaFitter method, no centrality", false); - - void processToOmegaPiWithDCAFitterCentFT0C(soa::Join const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - aod::TracksWCovDca const& tracks, - TracksWCovIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processWithKFParticleNoCent, "Charm-baryon candidate reconstruction with KFParticle method, no centrality", false); + + void processWithKFParticleCentFT0C(soa::Join const& collisions, + FilteredHfCascLf2Prongs const& candidates, + aod::Cascades const& cascades, + aod::V0s const& v0s, + TracksWCovDcaExtraPidPrPiKa const& tracks, + TracksWCovExtraPidIU const& lfTracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runCreatorWithDCAFitter(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaPi, hCandidateCounterToOmegaPi); + runCreator(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaPiWithDCAFitterCentFT0C, "Charm candidate reconstruction with Omega Pi via DcaFitter method, centrality selection on FT0C", false); - - void processToOmegaPiWithDCAFitterCentFT0M(soa::Join const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - aod::TracksWCovDca const& tracks, - TracksWCovIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processWithKFParticleCentFT0C, "Charm-baryon candidate reconstruction with KFParticle method, centrality on FT0C", false); + + void processWithKFParticleCentFT0M(soa::Join const& collisions, + FilteredHfCascLf2Prongs const& candidates, + aod::Cascades const& cascades, + aod::V0s const& v0s, + TracksWCovDcaExtraPidPrPiKa const& tracks, + TracksWCovExtraPidIU const& lfTracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runCreatorWithDCAFitter(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaPi, hInvMassCharmBaryonToOmegaPi); + runCreator(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaPiWithDCAFitterCentFT0M, "Charm candidate reconstruction with Omega Pi via DcaFitter method, centrality selection on FT0M", false); - - /*~~~~~~~~~~~~~~~~~*/ - /*~~~To Omega Ka~~~*/ - /*~~~~~~~~~~~~~~~~~*/ - void processToOmegaKaWithDCAFitterNoCent(SelectedCollisions const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - aod::TracksWCovDca const& tracks, - TracksWCovIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) - { - runCreatorWithDCAFitter(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaKa); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaKaWithDCAFitterNoCent, "Charm candidte reconstruction with Omega Ka via DcaFitter method, no centrality", false); - - void processToOmegaKaWithDCAFitterCentFT0C(soa::Join const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - aod::TracksWCovDca const& tracks, - TracksWCovIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) - { - runCreatorWithDCAFitter(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaKa); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaKaWithDCAFitterCentFT0C, "Charm candidate reconstruction with Omega Ka via DcaFitter method, centrality selection on FT0C", false); - - void processToOmegaKaWithDCAFitterCentFT0M(soa::Join const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - aod::TracksWCovDca const& tracks, - TracksWCovIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) - { - runCreatorWithDCAFitter(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaPi); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaKaWithDCAFitterCentFT0M, "Charm candidate reconstruction with Omega Ka via DcaFitter method, centrality selection on FT0M", false); - - ///////////////////////////////////////////////////// - /// /// - /// Process functions with KFParticle /// - /// /// - ///////////////////////////////////////////////////// - - /*~~~~~~~~~~~~~~*/ - /*~~~To Xi Pi~~~*/ - /*~~~~~~~~~~~~~~*/ - void processToXiPiWithKFParticleNoCent(SelectedCollisions const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - TracksWCovDcaExtraPidPrPiKa const& tracks, - TracksWCovExtraPidIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) - { - runCreatorWithKfParticle(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithKFParticleNoCent, "Charm Baryon decaying to Xi Pi reconstruction via KFParticle method, no centrality", false); - - void processToXiPiWithKFParticleCentFT0C(soa::Join const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - TracksWCovDcaExtraPidPrPiKa const& tracks, - TracksWCovExtraPidIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) - { - runCreatorWithKfParticle(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithKFParticleCentFT0C, "Charm Baryon decaying to Xi Pi reconstruction via KFParticle method, centrality on FT0C", false); - - void processToXiPiWithKFParticleCentFT0M(soa::Join const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - TracksWCovDcaExtraPidPrPiKa const& tracks, - TracksWCovExtraPidIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) - { - runCreatorWithKfParticle(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithKFParticleCentFT0M, "Charm Baryon decaying to Xi Pireconstruction via KFParticle method, centrality on FT0M", false); - - /*~~~~~~~~~~~~~~~~~*/ - /*~~~To Omega Pi~~~*/ - /*~~~~~~~~~~~~~~~~~*/ - void processToOmegaPiWithKFParticleNoCent(SelectedCollisions const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - TracksWCovDcaExtraPidPrPiKa const& tracks, - TracksWCovExtraPidIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) - { - runCreatorWithKfParticle(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaPi, hCandidateCounterToOmegaPi); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaPiWithKFParticleNoCent, "Charm Baryon decaying to Omega Pi reconstruction via KFParticle method, no centrality", false); - - void processToOmegaPiWithKFParticleCentFT0C(soa::Join const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - TracksWCovDcaExtraPidPrPiKa const& tracks, - TracksWCovExtraPidIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) - { - runCreatorWithKfParticle(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaPi, hCandidateCounterToOmegaPi); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaPiWithKFParticleCentFT0C, "Charm Baryon decaying to Omega Pi reconstruction via KFParticle method, centrality on FT0C", false); - - void processToOmegaPiWithKFParticleCentFT0M(soa::Join const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - TracksWCovDcaExtraPidPrPiKa const& tracks, - TracksWCovExtraPidIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) - { - runCreatorWithKfParticle(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaPi, hCandidateCounterToOmegaPi); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaPiWithKFParticleCentFT0M, "Charm Baryong decaying to Omega Pi reconstruction via KFParticle method, centrality on FT0M", false); - - /*~~~~~~~~~~~~~~~~~*/ - /*~~~To Omega Ka~~~*/ - /*~~~~~~~~~~~~~~~~~*/ - void processToOmegaKaWithKFParticleNoCent(SelectedCollisions const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - TracksWCovDcaExtraPidPrPiKa const& tracks, - TracksWCovExtraPidIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) - { - runCreatorWithKfParticle(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaKa); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaKaWithKFParticleNoCent, "Charm Baryon decaying to Omega Ka reconstruction via KFParticle method, no centrality", false); - - void processToOmegaKaWithKFParticleCentFT0C(soa::Join const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - TracksWCovDcaExtraPidPrPiKa const& tracks, - TracksWCovExtraPidIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) - { - runCreatorWithKfParticle(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaKa); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaKaWithKFParticleCentFT0C, "Charm Baryon decaying to Omega Ka reconstruction via KFParticle method, centrality on FT0C", false); - - void processToOmegaKaWithKFParticleCentFT0M(soa::Join const& collisions, - aod::HfCascLf2Prongs const& candidates, - aod::Cascades const& cascades, - aod::V0s const& v0s, - TracksWCovDcaExtraPidPrPiKa const& tracks, - TracksWCovExtraPidIU const& lfTracks, - aod::BCsWithTimestamps const& bcsWithTimestamps) - { - runCreatorWithKfParticle(collisions, candidates, cascades, v0s, tracks, lfTracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaKa); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaKaWithKFParticleCentFT0M, "Charm Baryong decaying to Omega Ka reconstruction via KFParticle method, centrality on FT0M", false); - - /////////////////////////////////////////////////////////////// - /// /// - /// Process functions for Collision monitoring /// - /// /// - /////////////////////////////////////////////////////////////// + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processWithKFParticleCentFT0M, "Charm-baryon candidate reconstruction with KFParticle method, centrality on FT0M", false); + // Process functions for Collision monitoring void processCollisionsNoCent(soa::Join const& collisions, aod::BCsWithTimestamps const&) { @@ -1677,51 +1167,35 @@ struct HfCandidateCreatorXic0Omegac0Qa { }; struct HfCandidateCreatorXic0Omegac0QaMc { - - // Cursor to fill tables - struct : ProducesGroup { - - Produces rowMcMatchRecXicToXiPi; - Produces rowMcMatchGenXicToXiPi; - Produces rowMcMatchRecOmegacToXiPi; - Produces rowMcMatchGenOmegacToXiPi; - Produces rowMcMatchRecToOmegaPi; - Produces rowMcMatchGenToOmegaPi; - Produces rowMcMatchRecToOmegaKa; - Produces rowMcMatchGenToOmegaKa; - - } cursors; + Spawns rowCandidateCascBach; + Produces rowMcMatchRecCascBach; + Produces rowMcMatchGenCascBach; // Configurables struct : ConfigurableGroup { - Configurable rejectBackground{"rejectBackground", false, "Reject particles from background events"}; // -> Used for only Xic0 Configurable acceptTrackInteractionWithMaterial{"acceptTrackInteractionWithMaterial", false, "Accept candidates with final daughters interacting with materials"}; - Configurable fillMcHistograms{"fillMcHistograms", true, "Fill validation plots"}; - Configurable fillResidualTable{"fillResidualTable", true, "Fill table contaning residuals and pulls of PV and SV"}; // Configurable matchDecayedPions{"matchedDecayedPions", true, "Match also candidates with daughter pion tracks that decay with kinked toploogy"}; - } configs; - enum McMatchFlag : uint8_t { - None = 0, - CharmBaryonUnmatched, - CascUnmatched, - V0Unmatched, - NumberMcMatchFlag - }; + std::array pdgOfCharmBaryon{+kXiC0, +kXiC0, +kOmegaC0, +kOmegaC0, +kOmegaC0}; + std::array pdgOfCascade{+kXiMinus, +kOmegaMinus, +kOmegaMinus, +kOmegaMinus, +kXiMinus}; + std::array pdgOfCharmBachelor{+kPiPlus, +kKPlus, +kPiPlus, +kKPlus, +kPiPlus}; + std::array pdgOfBachelor{+kPiMinus, +kKMinus, +kKMinus, +kKMinus, +kPiMinus}; - std::array pdgOfCharmBaryon{+kXiC0, +kOmegaC0, +kOmegaC0, +kOmegaC0}; - std::array pdgOfCascade{+kXiMinus, +kXiMinus, +kOmegaMinus, +kOmegaMinus}; - std::array pdgOfCharmBachelor{+kPiPlus, +kPiPlus, +kPiPlus, +kKPlus}; - std::array pdgOfBachelor{+kPiMinus, +kPiMinus, +kKMinus, +kKMinus}; + std::array decayChannelFlags{hf_decay::hf_cand_casc_bach_qa::DecayChannelMain::Xic0ToXiPi, + hf_decay::hf_cand_casc_bach_qa::DecayChannelMain::Xic0ToOmegaK, + hf_decay::hf_cand_casc_bach_qa::DecayChannelMain::Omegac0ToOmegaPi, + hf_decay::hf_cand_casc_bach_qa::DecayChannelMain::Omegac0ToOmegaK, + hf_decay::hf_cand_casc_bach_qa::DecayChannelMain::Omegac0ToXiPi}; // Table aliases using TracksWMcIU = soa::Join; using McCollisionsNoCents = soa::Join; using McCollisionsFT0Cs = soa::Join; using McCollisionsFT0Ms = soa::Join; - using McCollisionsCentFT0Ms = soa::Join; // -> Used for subscription for process functions of centrality with FT0Ms + using McCollisionsCentFT0Ms = soa::Join; + using McCollisionsCentFT0Cs = soa::Join; using BCsInfo = soa::Join; Preslice mcParticlesPerMcCollision = aod::mcparticle::mcCollisionId; @@ -1736,99 +1210,39 @@ struct HfCandidateCreatorXic0Omegac0QaMc { { const auto& workflows = initContext.services().get(); for (const DeviceSpec& device : workflows.devices) { - if (device.name.compare("hf-candidate-creator-xic0-omegac0-qa") == 0) { + if (device.name == "hf-candidate-creator-xic0-omegac0-qa") { hfEvSelMc.init(device, registry); break; } } - - // Add histograms for QA - if (configs.fillMcHistograms) { - registry.add("hGenCharmBaryonPtRapidityTight", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); - registry.add("hGenCharmBaryonPtRapidityLoose", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); - } - } - - // Helper function to fill in table for MC Rec - ///@brief decay Channel is the chosen reconstruction channel - ///@brief flag - ///@brief debug - ///@brief origin - ///@brief collisionMatched - ///@brief pt - ///@brief pdgcode - template - void fillRecoMcTableByDecayChannel(int8_t flag, int8_t debug, int8_t origin, bool collisionMatched, float pt, int pdgCode) - { - if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi) { - cursors.rowMcMatchRecXicToXiPi(flag, debug, origin, collisionMatched, pt, pdgCode); - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToXiPi) { - cursors.rowMcMatchRecOmegacToXiPi(flag, debug, origin, collisionMatched, pt, pdgCode); - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi) { - cursors.rowMcMatchRecToOmegaPi(flag, debug, origin, collisionMatched, pt, pdgCode); - } else { - cursors.rowMcMatchRecToOmegaKa(flag, debug, origin, collisionMatched, pt, pdgCode); - } } - // Helper function to fill in table for MC Gen - ///@brief decay Channel is the chosen reconstruction channel - ///@brief flag - ///@brief debug - ///@brief origin - ///@brief collisionMatched - ///@brief pt - ///@brief pdgcode - template - void fillGenMcTableByDecayChannel(int8_t flag, int8_t debugGenCharmBaryon, int8_t debugGenCascade, int8_t debugGenLambda, float ptCharmBaryon, float yCharmBaryon, int8_t origin, int idxMother) - { - if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi) { - cursors.rowMcMatchGenXicToXiPi(flag, debugGenCharmBaryon, debugGenCascade, debugGenLambda, ptCharmBaryon, yCharmBaryon, origin, idxMother); - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToXiPi) { - cursors.rowMcMatchGenOmegacToXiPi(flag, debugGenCharmBaryon, debugGenCascade, debugGenLambda, ptCharmBaryon, yCharmBaryon, origin, idxMother); - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi) { - cursors.rowMcMatchGenToOmegaPi(flag, debugGenCharmBaryon, debugGenCascade, debugGenLambda, ptCharmBaryon, yCharmBaryon, origin, idxMother); - } else { - cursors.rowMcMatchGenToOmegaKa(flag, debugGenCharmBaryon, debugGenCascade, debugGenLambda, ptCharmBaryon, yCharmBaryon, origin, idxMother); - } - } - - template - void runXic0Omegac0Mc(TRecoCand const& candidates, - TracksWMcIU const&, + template + void runXic0Omegac0Mc(TracksWMcIU const& tracks, aod::McParticles const& mcParticles, Colls const& collsWithMcLabels, McCollisions const& mcCollisions, BCsInfo const&) { - int indexRec{-1}; - int indexRecCharmBaryon{-1}; - int8_t sign{-9}; - int8_t signCasc{-9}; - int8_t signV0{-9}; - int8_t flag{0}; - int8_t origin{0}; - int8_t debug{0}; - int8_t debugGenCharmBaryon{0}; - int8_t debugGenCasc{0}; - int8_t debugGenV0{0}; - bool collisionMatched = false; - float ptCharmBaryonGen = -999.; - float yCharmBaryonGen = -999.; - - //////////////////////////////////// - // Match reconstructed candidates // - //////////////////////////////////// - - for (const auto& candidate : candidates) { - - flag = 0; - origin = RecoDecay::OriginType::None; - debug = McMatchFlag::None; - collisionMatched = false; + rowCandidateCascBach->bindExternalIndices(&tracks); + + // Match reconstructed candidates + for (const auto& candidate : *rowCandidateCascBach) { + int indexRecCharmBaryon = -1; + int indexRecCascade = -1; + int indexRecV0 = -1; + int8_t sign = 0; + int8_t signCasc = 0; + int8_t signV0 = 0; + int8_t flagChannelMain = 0; + int8_t flagChannelResonant = 0; // TODO: Implement resonant channel matching + int8_t origin = 0; + int8_t nKinkedTracks = 0; // TODO: Implement kinked track matching + int8_t nInteractionsWithMaterial = 0; // TODO: Implement interaction with material matching + std::vector idxBhadMothers{}; - auto arrayDaughters = std::array{candidate.template bachelorFromCharmBaryon_as(), + auto arrayDaughters = std::array{candidate.template prong1_as(), candidate.template bachelor_as(), candidate.template posTrack_as(), candidate.template negTrack_as()}; @@ -1851,59 +1265,46 @@ struct HfCandidateCreatorXic0Omegac0QaMc { } } if (fromBkg) { - // fill the tables - fillRecoMcTableByDecayChannel(flag, debug, origin, collisionMatched, -1.f, 0); + rowMcMatchRecCascBach(flagChannelMain, origin, flagChannelResonant, -1.f, 0, 0, 0); continue; } } - // CharmBaryon -> Charm bachelor + Cascade - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, pdgOfCharmBaryon[decayChannel], std::array{pdgOfCharmBachelor[decayChannel], pdgOfBachelor[decayChannel], +kProton, +kPiMinus}, true, &sign, 3); - indexRecCharmBaryon = indexRec; - if (indexRec == -1) { // Xic0 not reconstructed - debug = McMatchFlag::CharmBaryonUnmatched; - } - if (indexRec > -1) { - // Cascade -> Bachelor + V0 - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersCasc, pdgOfCascade[decayChannel], std::array{pdgOfBachelor[decayChannel], +kProton, +kPiMinus}, true, &signCasc, 2); - if (indexRec == -1) { // Xi- not reconstructed - debug = McMatchFlag::CascUnmatched; - } - if (indexRec > -1) { - // V0 -> Pos + Neg - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1); - if (indexRec == -1) { // V0 not reconstructed - debug = McMatchFlag::V0Unmatched; - } - if (indexRec > -1) { - flag = sign * (1 << decayChannel); - collisionMatched = candidate.template collision_as().mcCollisionId() == mcParticles.iteratorAt(indexRecCharmBaryon).mcCollisionId(); + for (int decayChannel = 0; decayChannel < nMcDecayChannels; ++decayChannel) { + // CharmBaryon -> Charm bachelor + Cascade + indexRecCharmBaryon = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, pdgOfCharmBaryon[decayChannel], std::array{pdgOfCharmBachelor[decayChannel], pdgOfBachelor[decayChannel], +kProton, +kPiMinus}, true, &sign, 3); + + if (indexRecCharmBaryon > -1) { + // Cascade -> Bachelor + V0 + indexRecCascade = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersCasc, pdgOfCascade[decayChannel], std::array{pdgOfBachelor[decayChannel], +kProton, +kPiMinus}, true, &signCasc, 2); + + if (indexRecCascade > -1) { + // V0 -> Pos + Neg + indexRecV0 = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1); + + if (indexRecV0 > -1) { + flagChannelMain = sign * decayChannelFlags[decayChannel]; + break; + } } } } - // Check if charm baryon is from b-hadron decay(prompt vs non-prompt) - if (flag != 0) { + // Check if charm baryon is from b-hadron decay (prompt vs non-prompt) + if (flagChannelMain != 0) { auto particle = mcParticles.rawIteratorAt(indexRecCharmBaryon); origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); } if (origin == RecoDecay::OriginType::NonPrompt) { auto bHadMother = mcParticles.rawIteratorAt(idxBhadMothers[0]); - fillRecoMcTableByDecayChannel(flag, debug, origin, collisionMatched, bHadMother.pt(), bHadMother.pdgCode()); + rowMcMatchRecCascBach(flagChannelMain, origin, flagChannelResonant, bHadMother.pt(), bHadMother.pdgCode(), nKinkedTracks, nInteractionsWithMaterial); } else { - fillRecoMcTableByDecayChannel(flag, debug, origin, collisionMatched, -1.f, 0); - } - if (debug == McMatchFlag::CascUnmatched || debug == McMatchFlag::V0Unmatched) { - LOGF(info, "WARNING: Charm baryon decays in the expected final state but the condition on the intermediate states are not fullfilled"); + rowMcMatchRecCascBach(flagChannelMain, origin, flagChannelResonant, -1.f, 0, nKinkedTracks, nInteractionsWithMaterial); } } // candidate loop - /////////////////////////////// - // Match generated particles // - /////////////////////////////// - + // Match generated particles for (const auto& mcCollision : mcCollisions) { - const auto& mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); float centrality{-1.f}; @@ -1926,251 +1327,102 @@ struct HfCandidateCreatorXic0Omegac0QaMc { hfEvSelMc.fillHistograms(mcCollision, rejectionMask, nSplitColl); - if (rejectionMask != 0) { // At least one event selection not satisfied --> Reject all particles from this event + if (rejectionMask != 0) { for (unsigned int i = 0; i < mcParticlesPerMcColl.size(); ++i) { - fillGenMcTableByDecayChannel(0, 0, 0, 0, -999., -999., RecoDecay::OriginType::None, -1); + rowMcMatchGenCascBach(0, 0, 0, -1); } continue; } // Match generated particles for (auto const& particle : mcParticlesPerMcColl) { - ptCharmBaryonGen = -999.; - yCharmBaryonGen = -999.; - flag = 0; - sign = -9; - debugGenCharmBaryon = 0; - debugGenCasc = 0; - debugGenV0 = 0; - origin = RecoDecay::OriginType::None; + int8_t flagChannelMain = 0; + int8_t flagChannelResonant = 0; // TODO: Implement resonant channel matching + int8_t origin = RecoDecay::OriginType::None; + int8_t sign = 0; + std::vector idxBhadMothers{}; - const float kYCutTight = 0.5; - const float kYCutLoose = 0.8; // Reject particles from background events if (particle.fromBackgroundEvent() && configs.rejectBackground) { - fillGenMcTableByDecayChannel(flag, debugGenCharmBaryon, debugGenCasc, debugGenV0, ptCharmBaryonGen, yCharmBaryonGen, origin, -1); + rowMcMatchGenCascBach(flagChannelMain, origin, flagChannelResonant, -1); continue; } - // Charm Baryon -> Cascade + Charm bachelor - if (RecoDecay::isMatchedMCGen(mcParticles, particle, pdgOfCharmBaryon[decayChannel], std::array{pdgOfCascade[decayChannel], pdgOfCharmBachelor[decayChannel]}, true, &sign)) { - debugGenCharmBaryon = 1; - ptCharmBaryonGen = particle.pt(); - yCharmBaryonGen = particle.y(); - - for (auto const& daughterCharm : particle.template daughters_as()) { - if (std::abs(daughterCharm.pdgCode()) != pdgOfCascade[decayChannel]) { - continue; - } - // Xi -> Lambda + pi - if (RecoDecay::isMatchedMCGen(mcParticles, daughterCharm, pdgOfCascade[decayChannel], std::array{+kLambda0, pdgOfBachelor[decayChannel]}, true)) { - debugGenCasc = 1; // -> Matched Xi- - for (auto const& daughterCascade : daughterCharm.template daughters_as()) { - if (std::abs(daughterCascade.pdgCode()) != +kLambda0) { - continue; - } - - // Lambda -> p + pi - if (RecoDecay::isMatchedMCGen(mcParticles, daughterCascade, +kLambda0, std::array{+kProton, +kPiMinus}, true)) { - debugGenV0 = 1; // -> Matched Lambda0 - flag = sign * (1 << decayChannel); - } - } // V0 daughter loop - } // cascade daughter loop - } - } // charm daughter loop - - if (flag != 0) { - origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); - if (std::abs(yCharmBaryonGen) < kYCutTight) { - registry.fill(HIST("hGenCharmBaryonPtRapidityTight"), ptCharmBaryonGen); - } - if (std::abs(yCharmBaryonGen) < kYCutLoose) { - registry.fill(HIST("hGenCharmBaryonPtRapidityLoose"), ptCharmBaryonGen); + for (int decayChannel = 0; decayChannel < nMcDecayChannels; ++decayChannel) { + // Charm Baryon -> Cascade + Charm bachelor + if (RecoDecay::isMatchedMCGen(mcParticles, particle, pdgOfCharmBaryon[decayChannel], std::array{pdgOfCascade[decayChannel], pdgOfCharmBachelor[decayChannel]}, true, &sign)) { + for (auto const& daughterCharm : particle.template daughters_as()) { + if (std::abs(daughterCharm.pdgCode()) != pdgOfCascade[decayChannel]) { + continue; + } + + // Cascade -> Lambda + pi + if (RecoDecay::isMatchedMCGen(mcParticles, daughterCharm, pdgOfCascade[decayChannel], std::array{+kLambda0, pdgOfBachelor[decayChannel]}, true)) { + for (auto const& daughterCascade : daughterCharm.template daughters_as()) { + if (std::abs(daughterCascade.pdgCode()) != +kLambda0) { + continue; + } + + // Lambda -> p + pi + if (RecoDecay::isMatchedMCGen(mcParticles, daughterCascade, +kLambda0, std::array{+kProton, +kPiMinus}, true)) { + flagChannelMain = sign * decayChannelFlags[decayChannel]; + break; + } + } // V0 daughter loop + } // cascade daughter loop + } // charm daughter loop } } // Check if charm is prompt or non-prompt + if (flagChannelMain != 0) { + origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); + } if (origin == RecoDecay::OriginType::NonPrompt) { - fillGenMcTableByDecayChannel(flag, debugGenCharmBaryon, debugGenCasc, debugGenV0, ptCharmBaryonGen, yCharmBaryonGen, origin, idxBhadMothers[0]); + rowMcMatchGenCascBach(flagChannelMain, origin, flagChannelResonant, idxBhadMothers[0]); } else { - fillGenMcTableByDecayChannel(flag, debugGenCharmBaryon, debugGenCasc, debugGenV0, ptCharmBaryonGen, yCharmBaryonGen, origin, -1); + rowMcMatchGenCascBach(flagChannelMain, origin, flagChannelResonant, -1); } } // particle loop - } // end of collision loop + } - } // template run function + // void processMcEmpty(aod::Collisions const&) + // { + // } + // PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcEmpty, "Empty process function to prevent workflow from getting stuck", true); - void processMcEmpty(aod::Collisions const&) - { - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcEmpty, "Empty process function to prevent workflow from getting stuck", true); - - ///////////////////////////////////////////////////// - /// /// - /// Process functions with DCAFitter /// - /// /// - ///////////////////////////////////////////////////// - - //~~~~~~~~~~~~~~~~// - //~~~~To Xi Pi~~~~// - //~~~~~~~~~~~~~~~~// - void processMcXicToXiPiWithDCAFitterNoCent(aod::HfCandToXiPi const& candidates, - TracksWMcIU const& tracks, - aod::McParticles const& mcParticles, - soa::Join const& mcCollisions, - McCollisionsNoCents const& collsWithMcLabels, - BCsInfo const& bcs) + void processMcNoCent(TracksWMcIU const& tracks, + aod::McParticles const& mcParticles, + soa::Join const& mcCollisions, + McCollisionsNoCents const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); + runXic0Omegac0Mc(tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcXicToXiPiWithDCAFitterNoCent, "Perform MC matching of DCAFitter reconstructed Xic0 to Xi Pi. No cents", false); - - void processMcXicToXiPiWithDCAFitterCentFT0C(aod::HfCandToXiPi const& candidates, - TracksWMcIU const& tracks, - aod::McParticles const& mcParticles, - soa::Join const& mcCollisions, - McCollisionsFT0Cs const& collsWithMcLabels, - BCsInfo const& bcs) - { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcXicToXiPiWithDCAFitterCentFT0C, "Perform MC matching of DCAFitter reconstructed Xic0 to Xi Pi. Cents with FT0C", false); - - void processMcXicToXiPiWithDCAFitterCentFT0M(aod::HfCandToXiPi const& candidates, - TracksWMcIU const& tracks, - aod::McParticles const& mcParticles, - McCollisionsCentFT0Ms const& mcCollisions, - McCollisionsFT0Ms const& collsWithMcLabels, - BCsInfo const& bcs) - { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcXicToXiPiWithDCAFitterCentFT0M, "Perform MC matching of DCAFitter reconstructed Xic0 to Xi Pi. Cents with FT0M", false); - - void processMcOmegacToXiPiWithDCAFitterNoCent(aod::HfCandToXiPi const& candidates, - TracksWMcIU const& tracks, - aod::McParticles const& mcParticles, - soa::Join const& mcCollisions, - McCollisionsNoCents const& collsWithMcLabels, - BCsInfo const& bcs) - { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToXiPiWithDCAFitterNoCent, "Perform MC matching of DCAFitter reconstructed Omegac0 to Xi Pi. No cents", false); - - void processMcOmegacToXiPiWithDCAFitterCentFT0C(aod::HfCandToXiPi const& candidates, - TracksWMcIU const& tracks, - aod::McParticles const& mcParticles, - soa::Join const& mcCollisions, - McCollisionsFT0Cs const& collsWithMcLabels, - BCsInfo const& bcs) - { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToXiPiWithDCAFitterCentFT0C, "Perform MC matching of DCAFitter reconstructed Omeagc0 to Xi Pi. Cents with FT0C", false); - - void processMcOmegacToXiPiWithDCAFitterCentFT0M(aod::HfCandToXiPi const& candidates, - TracksWMcIU const& tracks, - aod::McParticles const& mcParticles, - McCollisionsCentFT0Ms const& mcCollisions, - McCollisionsFT0Ms const& collsWithMcLabels, - BCsInfo const& bcs) - { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToXiPiWithDCAFitterCentFT0M, "Perform MC matching of DCAFitter reconstructed Omegac0 to Xi Pi. Cents with FT0M", false); - - //~~~~~~~~~~~~~~~~~~~// - //~~~~To Omega Pi~~~~// - //~~~~~~~~~~~~~~~~~~~// - void processMcOmegacToOmegaPiWithDCAFitterNoCent(aod::HfCandToOmegaPi const& candidates, - TracksWMcIU const& tracks, - aod::McParticles const& mcParticles, - soa::Join const& mcCollisions, - McCollisionsNoCents const& collsWithMcLabels, - BCsInfo const& bcs) - { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToOmegaPiWithDCAFitterNoCent, "Perform MC matching of DCAFitter reconstructed Omegac0 to Omega Pi. No cents", false); - - void processMcOmegacToOmegaPiWithDCAFitterCentFT0C(aod::HfCandToOmegaPi const& candidates, - TracksWMcIU const& tracks, - aod::McParticles const& mcParticles, - soa::Join const& mcCollisions, - McCollisionsFT0Cs const& collsWithMcLabels, - BCsInfo const& bcs) - { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToOmegaPiWithDCAFitterCentFT0C, "Perform MC matching of DCAFitter reconstructed Omegac0 to Omega Pi. Cents with FT0C", false); - - void processMcOmegacToOmegaPiWithDCAFitterCentFT0M(aod::HfCandToOmegaPi const& candidates, - TracksWMcIU const& tracks, - aod::McParticles const& mcParticles, - McCollisionsCentFT0Ms const& mcCollisions, - McCollisionsFT0Ms const& collsWithMcLabels, - BCsInfo const& bcs) - { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToOmegaPiWithDCAFitterCentFT0M, "Perform MC matching of DCAFitter reconstructed Omegac0 to Omega Pi. Cents with FT0M", false); - - //~~~~~~~~~~~~~~~~~~// - //~~~~To Omega Ka~~~~// - //~~~~~~~~~~~~~~~~~~// - void processMcOmegacToOmegaKaWithDCAFitterNoCent(aod::HfCandToOmegaK const& candidates, - TracksWMcIU const& tracks, - aod::McParticles const& mcParticles, - soa::Join const& mcCollisions, - McCollisionsNoCents const& collsWithMcLabels, - BCsInfo const& bcs) - { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToOmegaKaWithDCAFitterNoCent, "Perform MC matching of DCAFitter reconstructed Omegac0 to Omega Ka. No cents", false); - - void processMcOmegacToOmegaKaWithDCAFitterCentFT0C(aod::HfCandToOmegaK const& candidates, - TracksWMcIU const& tracks, - aod::McParticles const& mcParticles, - soa::Join const& mcCollisions, - McCollisionsFT0Cs const& collsWithMcLabels, - BCsInfo const& bcs) - { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToOmegaKaWithDCAFitterCentFT0C, "Perform MC matching of DCAFitter reconstructed Omegac0 to Omega Ka. Cents with FT0C", false); - - void processMcOmegacToOmegaKaWithDCAFitterCentFT0M(aod::HfCandToOmegaK const& candidates, - TracksWMcIU const& tracks, - aod::McParticles const& mcParticles, - McCollisionsCentFT0Ms const& mcCollisions, - McCollisionsFT0Ms const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcNoCent, "Process MC - no centrality", false); + + void processMcCentFT0C(TracksWMcIU const& tracks, + aod::McParticles const& mcParticles, + McCollisionsCentFT0Cs const& mcCollisions, + McCollisionsFT0Cs const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); + runXic0Omegac0Mc(tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToOmegaKaWithDCAFitterCentFT0M, "Perform MC matching of DCAFitter reconstructed Omegac0 to Omega Ka. Cents with FT0M", false); - - ///////////////////////////////////////////////////// - /// /// - /// Process functions with KFParticle /// - /// /// - ///////////////////////////////////////////////////// - void processMcXicToXiPiWithKFParticleNoCent(aod::HfCandToXiPiKf const& candidates, - TracksWMcIU const& tracks, - aod::McParticles const& mcParticles, - soa::Join const& mcCollisions, - McCollisionsNoCents const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcCentFT0C, "Process MC - centrality with FT0C", false); + + void processMcCentFT0M(TracksWMcIU const& tracks, + aod::McParticles const& mcParticles, + McCollisionsCentFT0Ms const& mcCollisions, + McCollisionsFT0Ms const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); + runXic0Omegac0Mc(tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcXicToXiPiWithKFParticleNoCent, "Perform MC matching of KFParticle reconstructed Xic0 to Xi Pi. No cents", false); + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcCentFT0M, "Process MC - centrality with FT0M", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPiQa.cxx b/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPiQa.cxx index 2f3ff74b2fe..2af3fd47a54 100644 --- a/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPiQa.cxx +++ b/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPiQa.cxx @@ -15,11 +15,13 @@ /// \author Fabio Catalano , University of Houston /// \author Maria Fernanda Torres Cabrera , University of Houston +#include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/HfMlResponseOmegacToOmegaPiQa.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/DataModel/TrackIndexSkimmingTables.h" #include "PWGHF/Utils/utilsAnalysis.h" #include "Common/Core/RecoDecay.h" @@ -62,17 +64,16 @@ enum PidInfoStored { PiFromCharm }; -enum { +enum RecoMethod { doDcaFitter = 0, doKfParticle }; /// Struct for applying Omegac0 -> Omega pi selection cuts struct HfCandidateSelectorToOmegaPiQa { - // DCAFitter and KFParticle - Produces hfSelToOmegaPi; - // ML selection - filled for both DCAFitter and KFParticle - Produces hfMlSelToOmegaPi; + // Filled for both DCAFitter and KFParticle + Produces hfSelOmegaC0ToOmegaPiCandidate; + Produces hfMlOmegaC0ToOmegaPiCandidate; // cuts from SelectorCuts.h - pT dependent cuts Configurable> binsPt{"binsPt", std::vector{hf_cuts_omegac_to_omega_pi::vecBinsPt}, "pT bin limits"}; @@ -175,8 +176,9 @@ struct HfCandidateSelectorToOmegaPiQa { Configurable nClustersItsInnBarrMin{"nClustersItsInnBarrMin", 1, "Minimum number of ITS clusters in inner barrel requirement for pi <- charm baryon"}; Configurable itsChi2PerClusterMax{"itsChi2PerClusterMax", 36, "Maximum value of chi2 fit over ITS clusters for pi <- charm baryon"}; - o2::analysis::HfMlResponseOmegacToOmegaPi hfMlResponseDca; - o2::analysis::HfMlResponseOmegacToOmegaPi hfMlResponseKf; + // TODO: is it needed to have separate ML response for DCAFitter and KFParticle? + o2::analysis::HfMlResponseOmegacToOmegaPiQa hfMlResponseDca; + o2::analysis::HfMlResponseOmegacToOmegaPiQa hfMlResponseKf; std::vector outputMlOmegac; o2::ccdb::CcdbApi ccdbApi; @@ -184,7 +186,7 @@ struct HfCandidateSelectorToOmegaPiQa { TrackSelectorPr selectorProton; TrackSelectorKa selectorKaon; - using TracksSel = soa::Join; + using TracksSel = soa::Join; using TracksSelLf = soa::Join; HistogramRegistry registry{"registry"}; // for QA of selections @@ -221,6 +223,10 @@ struct HfCandidateSelectorToOmegaPiQa { LOGP(fatal, "Exactly one process function for selector can be enabled at a time."); } + if (usePidTpcOnly == usePidTpcTofCombined) { + LOGF(fatal, "Check the PID configurables, usePidTpcOnly and usePidTpcTofCombined can't have the same value"); + } + selectorPion.setRangePtTpc(ptPiPidTpcMin, ptPiPidTpcMax); selectorPion.setRangeNSigmaTpc(-nSigmaTpcPiMax, nSigmaTpcPiMax); selectorPion.setRangeNSigmaTpcCondTof(-nSigmaTpcCombinedPiMax, nSigmaTpcCombinedPiMax); @@ -345,7 +351,6 @@ struct HfCandidateSelectorToOmegaPiQa { // HfMlResponse initialization if (applyMl) { if (doprocessOmegac0SelectorWithKFParticle) { - registry.add("hBDTScoreKF", "hBDTScoreKF", {HistType::kTH1D, {{100, 0.0f, 1.0f, "score"}}}); hfMlResponseKf.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); if (loadModelsFromCCDB) { ccdbApi.init(ccdbUrl); @@ -356,7 +361,6 @@ struct HfCandidateSelectorToOmegaPiQa { hfMlResponseKf.cacheInputFeaturesIndices(namesInputFeatures); hfMlResponseKf.init(); } else if (doprocessOmegac0SelectorWithDCAFitter) { - registry.add("hBDTScoreDCA", "hBDTScoreDCA", {HistType::kTH1D, {{100, 0.0f, 1.0f, "score"}}}); hfMlResponseDca.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); if (loadModelsFromCCDB) { ccdbApi.init(ccdbUrl); @@ -367,6 +371,8 @@ struct HfCandidateSelectorToOmegaPiQa { hfMlResponseDca.cacheInputFeaturesIndices(namesInputFeatures); hfMlResponseDca.init(); } + + registry.add("hMlScore", "hMlScore", {HistType::kTH1D, {{100, 0.0f, 1.0f, "score"}}}); } } @@ -376,13 +382,12 @@ struct HfCandidateSelectorToOmegaPiQa { template bool selectOnLf(const T& candidate) { - registry.fill(HIST("hSelStatusLf"), 0.0); // Eta selection of V0, Cascade daughters - double etaV0PosDau = candidate.etaV0PosDau(); - double etaV0NegDau = candidate.etaV0NegDau(); - double etaKaFromCasc = candidate.etaBachFromCasc(); + double etaV0PosDau = candidate.template posTrack_as().eta(); + double etaV0NegDau = candidate.template negTrack_as().eta(); + double etaKaFromCasc = candidate.template bachelor_as().eta(); if (std::abs(etaV0PosDau) > etaTrackLFDauMax) { return false; @@ -400,8 +405,8 @@ struct HfCandidateSelectorToOmegaPiQa { registry.fill(HIST("hSelStatusLf"), 3.0); // Minimum radius cut - double radiusV0 = RecoDecay::sqrtSumOfSquares(candidate.xDecayVtxV0(), candidate.yDecayVtxV0()); - double radiusCasc = RecoDecay::sqrtSumOfSquares(candidate.xDecayVtxCascade(), candidate.yDecayVtxCascade()); + double radiusV0 = RecoDecay::sqrtSumOfSquares(candidate.xV0Vertex(), candidate.yV0Vertex()); + double radiusCasc = RecoDecay::sqrtSumOfSquares(candidate.xCascadeVertex(), candidate.yCascadeVertex()); if (radiusV0 < radiusV0Min) { return false; @@ -413,121 +418,129 @@ struct HfCandidateSelectorToOmegaPiQa { registry.fill(HIST("hSelStatusLf"), 5.0); // Cosine of pointing angle - if (candidate.cosPAV0() < cosPAV0Min) { + if (candidate.cpaV0() < cosPAV0Min) { return false; } registry.fill(HIST("hSelStatusLf"), 6.0); - if (candidate.cosPACasc() < cosPACascMin) { + if (candidate.cpaCascade() < cosPACascMin) { return false; } registry.fill(HIST("hSelStatusLf"), 7.0); // Distance of Closest Approach(DCA) - if (candidate.dcaV0Dau() > dcaV0DauMax) { + if (candidate.dcaV0Daughters() > dcaV0DauMax) { return false; } registry.fill(HIST("hSelStatusLf"), 8.0); - if (candidate.dcaCascDau() > dcaCascDauMax) { + if (candidate.dcaCascadeDaughters() > dcaCascDauMax) { return false; } registry.fill(HIST("hSelStatusLf"), 9.0); - if (std::abs(candidate.dcaXYToPvV0Dau0()) < dcaPosToPvMin) { + if (std::abs(candidate.impactParameterXYV0PosDau()) < dcaPosToPvMin) { return false; } registry.fill(HIST("hSelStatusLf"), 10.0); - if (std::abs(candidate.dcaXYToPvV0Dau1()) < dcaNegToPvMin) { + if (std::abs(candidate.impactParameterXYV0NegDau()) < dcaNegToPvMin) { return false; } registry.fill(HIST("hSelStatusLf"), 11.0); - if (std::abs(candidate.dcaXYToPvCascDau()) < dcaBachToPvMin) { + if (std::abs(candidate.impactParameterXYCascadeBach()) < dcaBachToPvMin) { return false; } registry.fill(HIST("hSelStatusLf"), 12.0); // pT: Bachelor - double ptKaFromCasc = RecoDecay::sqrtSumOfSquares(candidate.pxBachFromCasc(), candidate.pyBachFromCasc()); + double ptKaFromCasc = candidate.template bachelor_as().pt(); if (std::abs(ptKaFromCasc) < ptKaFromCascMin) { return false; } registry.fill(HIST("hSelStatusLf"), 13.0); // Extra cuts for KFParticle - if constexpr (svReco == doKfParticle) { + if constexpr (svReco == RecoMethod::doKfParticle) { if (kfConfigurableGroup.applyKFpreselections) { // Cosine of Pointing angle - if (candidate.cosPaV0ToCasc() < kfConfigurableGroup.cosPaV0ToCascMin) { + if (candidate.cpaV0ToCascade() < kfConfigurableGroup.cosPaV0ToCascMin) { return false; } registry.fill(HIST("hSelStatusLf"), 14.0); // Chi2 - if (candidate.v0Chi2OverNdf() < 0 || candidate.v0Chi2OverNdf() > kfConfigurableGroup.v0Chi2OverNdfMax) { + if (candidate.chi2GeoOverNdfV0() < 0 || candidate.chi2GeoOverNdfV0() > kfConfigurableGroup.v0Chi2OverNdfMax) { return false; } registry.fill(HIST("hSelStatusLf"), 15.0); - if (candidate.cascChi2OverNdf() < 0 || candidate.cascChi2OverNdf() > kfConfigurableGroup.cascChi2OverNdfMax) { + if (candidate.chi2GeoOverNdfCascade() < 0 || candidate.chi2GeoOverNdfCascade() > kfConfigurableGroup.cascChi2OverNdfMax) { return false; } registry.fill(HIST("hSelStatusLf"), 16.0); - if (candidate.chi2TopoCascToPv() < 0 || candidate.chi2TopoCascToPv() > kfConfigurableGroup.chi2TopoCascToPvMax) { + if (candidate.chi2TopoCascadeToPv() < 0 || candidate.chi2TopoCascadeToPv() > kfConfigurableGroup.chi2TopoCascToPvMax) { return false; } registry.fill(HIST("hSelStatusLf"), 17.0); - if (candidate.chi2TopoV0ToCasc() < 0 || candidate.chi2TopoV0ToCasc() > kfConfigurableGroup.chi2TopoV0ToCascMax) { + if (candidate.chi2TopoV0ToCascade() < 0 || candidate.chi2TopoV0ToCascade() > kfConfigurableGroup.chi2TopoV0ToCascMax) { return false; } registry.fill(HIST("hSelStatusLf"), 18.0); // ldl - if (candidate.v0ldl() < kfConfigurableGroup.v0LdlMin) { + if (candidate.decayLengthNormKfV0() < kfConfigurableGroup.v0LdlMin) { return false; } registry.fill(HIST("hSelStatusLf"), 19.0); - if (candidate.cascldl() < kfConfigurableGroup.cascLdlMin) { + if (candidate.decayLengthNormKfCascade() < kfConfigurableGroup.cascLdlMin) { return false; } registry.fill(HIST("hSelStatusLf"), 20.0); // Decay length - if (std::abs(candidate.decayLenXYLambda()) < kfConfigurableGroup.decayLenXYLambdaMin) { + if (std::abs(candidate.decayLengthXYV0()) < kfConfigurableGroup.decayLenXYLambdaMin) { return false; } registry.fill(HIST("hSelStatusLf"), 21.0); - if (std::abs(candidate.decayLenXYCasc()) < kfConfigurableGroup.decayLenXYCascMin) { + if (std::abs(candidate.decayLengthXYCascade()) < kfConfigurableGroup.decayLenXYCascMin) { return false; } registry.fill(HIST("hSelStatusLf"), 22.0); - // Competing Xi rejection - if (kfConfigurableGroup.applyCompetingCascRejection) { - const auto invMassXiHypothesis = candidate.cascRejectInvmass(); - - if (std::abs(invMassXiHypothesis - o2::constants::physics::MassXiMinus) < kfConfigurableGroup.cascadeRejMassWindow) { - registry.fill(HIST("hSelCompetingCasc"), 0.0); - return false; - } + // TODO: fix cascRejectInvmass variable needed not available in the current table - registry.fill(HIST("hSelCompetingCasc"), 1.0); - registry.fill(HIST("hInvMassXiMinus_rej_cut"), invMassXiHypothesis); - } + // Competing Xi rejection + // if (kfConfigurableGroup.applyCompetingCascRejection) { + // const auto invMassXiHypothesis = candidate.cascRejectInvmass(); + // + // if (std::abs(invMassXiHypothesis - o2::constants::physics::MassXiMinus) < kfConfigurableGroup.cascadeRejMassWindow) { + // registry.fill(HIST("hSelCompetingCasc"), 0.0); + // return false; + // } + // + // registry.fill(HIST("hSelCompetingCasc"), 1.0); + // registry.fill(HIST("hInvMassXiMinus_rej_cut"), invMassXiHypothesis); + //} } } else { // Impact parameter - if (std::abs(candidate.impactParCascXY()) < impactParameterXYCascMin || std::abs(candidate.impactParCascXY()) > impactParameterXYCascMax) { + if (std::abs(candidate.impactParameter0()) < impactParameterXYCascMin || std::abs(candidate.impactParameter0()) > impactParameterXYCascMax) { return false; } registry.fill(HIST("hSelStatusLf"), 14.0); - if (std::abs(candidate.impactParCascZ()) < impactParameterZCascMin || std::abs(candidate.impactParCascZ()) > impactParameterZCascMax) { + if (std::abs(candidate.impactParameterZ0()) < impactParameterZCascMin || std::abs(candidate.impactParameterZ0()) > impactParameterZCascMax) { return false; } registry.fill(HIST("hSelStatusLf"), 15.0); } - // If passes all cuts, return true + if (!(std::abs(candidate.massLambda() - o2::constants::physics::MassLambda0) < v0MassWindow)) { + return false; + } + if (!(std::abs(candidate.massCascade() - o2::constants::physics::MassOmegaMinus) < cascadeMassWindow)) { + return false; + } + return true; } @@ -535,88 +548,165 @@ struct HfCandidateSelectorToOmegaPiQa { // Apply cuts with charm baryon & charm bachelor related informations // returns true if all cuts are passed template - bool selectOnHf(const T& candidate, const int& inputPtBin) + bool selectOnHf(const T& candidate, TracksSel const& tracks) { + auto ptCandOmegac = candidate.pt(); + int ptBin = findBin(binsPt, ptCandOmegac); + if (ptBin == -1) { + return false; + } + + // pT selection + if (ptCandOmegac < ptCandMin || ptCandOmegac > ptCandMax) { + return false; + } + registry.fill(HIST("hSelStatusHf"), 0.0); // eta selection on charm bayron bachelor - if (std::abs(candidate.etaBachFromCharmBaryon()) > etaTrackCharmBachMax) { + auto trackPiFromCharm = tracks.rawIteratorAt(candidate.prong1Id()); + if (std::abs(trackPiFromCharm.eta()) > etaTrackCharmBachMax) { return false; } registry.fill(HIST("hSelStatusHf"), 1.0); // Distance of Closest Approach(DCA) - if (candidate.dcaCharmBaryonDau() > dcaCharmBaryonDauMax) { + if (candidate.dcaDaughters() > dcaCharmBaryonDauMax) { return false; } registry.fill(HIST("hSelStatusHf"), 2.0); // pT: Charm Bachelor - double ptPiFromCharmBaryon = RecoDecay::sqrtSumOfSquares(candidate.pxBachFromCharmBaryon(), candidate.pyBachFromCharmBaryon()); - if (inputPtBin < 0 || ptPiFromCharmBaryon < cuts->get(inputPtBin, "pT pi from Omegac")) { + if (trackPiFromCharm.pt() < cuts->get(ptBin, "pT pi from Omegac")) { return false; } registry.fill(HIST("hSelStatusHf"), 3.0); // specific selections with KFParticle output - if constexpr (svReco == doKfParticle) { + if constexpr (svReco == RecoMethod::doKfParticle) { if (kfConfigurableGroup.applyKFpreselections) { // Omegac Pt selection - if (std::abs(candidate.kfptOmegac()) <= ptCandMin || std::abs(candidate.kfptOmegac()) >= ptCandMax) { + if (std::abs(candidate.pt()) <= ptCandMin || std::abs(candidate.pt()) >= ptCandMax) { return false; } registry.fill(HIST("hSelStatusHf"), 4.0); // Cosine of pointing angle - if (candidate.cosPaCascToOmegac() < kfConfigurableGroup.cosPaCascToOmegacMin) { + if (candidate.cpaCascadeToCharmHadron() < kfConfigurableGroup.cosPaCascToOmegacMin) { return false; } registry.fill(HIST("hSelStatusHf"), 5.0); // Chi2 - if (candidate.omegacChi2OverNdf() < 0 || candidate.omegacChi2OverNdf() > kfConfigurableGroup.omegacChi2OverNdfMax) { + if (candidate.chi2GeoOverNdfCascade() < 0 || candidate.chi2GeoOverNdfCascade() > kfConfigurableGroup.omegacChi2OverNdfMax) { return false; } registry.fill(HIST("hSelStatusHf"), 6.0); - if (candidate.chi2TopoOmegacToPv() < 0 || candidate.chi2TopoOmegacToPv() > kfConfigurableGroup.chi2TopoOmegacToPvMax) { + if (candidate.chi2TopoCascadeToPv() < 0 || candidate.chi2TopoCascadeToPv() > kfConfigurableGroup.chi2TopoOmegacToPvMax) { return false; } registry.fill(HIST("hSelStatusHf"), 7.0); - if (candidate.chi2TopoCascToOmegac() < 0 || candidate.chi2TopoCascToOmegac() > kfConfigurableGroup.chi2TopoCascToOmegacMax) { + if (candidate.chi2TopoCascadeToCharmHadron() < 0 || candidate.chi2TopoCascadeToCharmHadron() > kfConfigurableGroup.chi2TopoCascToOmegacMax) { return false; } registry.fill(HIST("hSelStatusHf"), 8.0); // Decay Length - if (std::abs(candidate.decayLenXYOmegac()) > kfConfigurableGroup.decayLenXYOmegacMax) { + if (std::abs(candidate.decayLengthXY()) > kfConfigurableGroup.decayLenXYOmegacMax) { return false; } registry.fill(HIST("hSelStatusHf"), 9.0); // ctau - if (std::abs(candidate.cTauOmegac()) > kfConfigurableGroup.cTauOmegacMax) { + if (std::abs(HfHelper::ctOmegaczero(candidate)) > kfConfigurableGroup.cTauOmegacMax) { return false; } registry.fill(HIST("hSelStatusHf"), 10.0); // Omegac l/dl - if (candidate.omegacldl() > kfConfigurableGroup.omegacLdlMax) { + if (candidate.decayLengthNormKf() > kfConfigurableGroup.omegacLdlMax) { return false; } registry.fill(HIST("hSelStatusHf"), 11.0); } } else { // Impact parameter - if ((std::abs(candidate.impactParBachFromCharmBaryonXY()) < impactParameterXYPiFromCharmBaryonMin) || (std::abs(candidate.impactParBachFromCharmBaryonXY()) > impactParameterXYPiFromCharmBaryonMax)) { + if ((std::abs(candidate.impactParameter1()) < impactParameterXYPiFromCharmBaryonMin) || (std::abs(candidate.impactParameter1()) > impactParameterXYPiFromCharmBaryonMax)) { return false; } registry.fill(HIST("hSelStatusHf"), 4.0); - if ((std::abs(candidate.impactParBachFromCharmBaryonZ()) < impactParameterZPiFromCharmBaryonMin) || (std::abs(candidate.impactParBachFromCharmBaryonZ()) > impactParameterZPiFromCharmBaryonMax)) { + if ((std::abs(candidate.impactParameterZ1()) < impactParameterZPiFromCharmBaryonMin) || (std::abs(candidate.impactParameterZ1()) > impactParameterZPiFromCharmBaryonMax)) { return false; } registry.fill(HIST("hSelStatusHf"), 5.0); } - // If passes all cuts, return true + double const invMassCharmBaryon = HfHelper::invMassOmegaczeroToOmegaPi(candidate); + if ((invMassCharmBaryon < invMassCharmBaryonMin) || (invMassCharmBaryon > invMassCharmBaryonMax)) { + return false; + } + + return true; + } + + // Track quality selection + template + bool selectOnTrackQuality(T1 const& trackPiFromLam, T1 const& trackPrFromLam, T1 const& trackKaFromCasc, T2 const& trackPiFromCharm) + { + // TPC clusters selections + registry.fill(HIST("hSelStatusCluster"), 0.0); + + if (applyTrkSelLf) { + if (!isSelectedTrackTpcQuality(trackPiFromLam, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { + return false; + } + registry.fill(HIST("hSelStatusCluster"), 1.0); + + if (!isSelectedTrackTpcQuality(trackPrFromLam, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { + return false; + } + registry.fill(HIST("hSelStatusCluster"), 2.0); + + if (!isSelectedTrackTpcQuality(trackKaFromCasc, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { + return false; + } + registry.fill(HIST("hSelStatusCluster"), 3.0); + } + + if (!isSelectedTrackTpcQuality(trackPiFromCharm, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { + return false; + } + registry.fill(HIST("hSelStatusCluster"), 4.0); + + // ITS clusters selection + if (!isSelectedTrackItsQuality(trackPiFromCharm, nClustersItsMin, itsChi2PerClusterMax) || trackPiFromCharm.itsNClsInnerBarrel() < nClustersItsInnBarrMin) { + return false; + } + registry.fill(HIST("hSelStatusCluster"), 5.0); + + return true; + } + + // apply PID selection on the decay products + bool isSelectedPID(const TrackSelectorPID::Status pidPrFromLam, const TrackSelectorPID::Status pidPiFromLam, const TrackSelectorPID::Status pidKaFromCasc, const TrackSelectorPID::Status pidPiFromCharmBaryon) + { + // TODO: check PID logic, usually we require particles to not be TrackSelectorPID::Rejected + registry.fill(HIST("hSelStatusPID"), 0.0); + + if (pidPrFromLam != TrackSelectorPID::Accepted || pidPiFromLam != TrackSelectorPID::Accepted) { + return false; + } + registry.fill(HIST("hSelStatusPID"), 1.0); + + if (pidKaFromCasc != TrackSelectorPID::Accepted) { + return false; + } + registry.fill(HIST("hSelStatusPID"), 2.0); + + if (pidPiFromCharmBaryon != TrackSelectorPID::Accepted) { + return false; + } + registry.fill(HIST("hSelStatusPID"), 3.0); + return true; } @@ -625,23 +715,30 @@ struct HfCandidateSelectorToOmegaPiQa { TracksSel const& tracks, TracksSelLf const& lfTracks) { - // looping over charm baryon candidates + // looping over charm-baryon candidates for (const auto& candidate : candidates) { - bool resultSelections = true; // True if the candidate passes all the selections, False otherwise + int statusOmegaC0ToOmegaPi = 0; outputMlOmegac.clear(); + if (!TESTBIT(candidate.hfflag(), aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi)) { + hfSelOmegaC0ToOmegaPiCandidate(statusOmegaC0ToOmegaPi); + if (applyMl) { + hfMlOmegaC0ToOmegaPiCandidate(outputMlOmegac); + } + continue; + } + SETBIT(statusOmegaC0ToOmegaPi, aod::SelectionStep::RecoSkims); + auto trackV0PosDau = lfTracks.rawIteratorAt(candidate.posTrackId()); auto trackV0NegDau = lfTracks.rawIteratorAt(candidate.negTrackId()); auto trackKaFromCasc = lfTracks.rawIteratorAt(candidate.bachelorId()); - auto trackPiFromCharm = tracks.rawIteratorAt(candidate.bachelorFromCharmBaryonId()); + auto trackPiFromCharm = tracks.rawIteratorAt(candidate.prong1Id()); auto trackPiFromLam = trackV0NegDau; auto trackPrFromLam = trackV0PosDau; - int8_t const signDecay = candidate.signDecay(); // sign of pi <- cascade - - if (signDecay > 0) { + if (trackPiFromCharm.sign() < 0) { trackPiFromLam = trackV0PosDau; trackPrFromLam = trackV0NegDau; registry.fill(HIST("hSelSignDec"), 1); // anti-particle decay @@ -649,232 +746,96 @@ struct HfCandidateSelectorToOmegaPiQa { registry.fill(HIST("hSelSignDec"), 0); // particle decay } - // pT selection - auto ptCandOmegac = RecoDecay::pt(candidate.pxCharmBaryon(), candidate.pyCharmBaryon()); - - if (ptCandOmegac < ptCandMin || ptCandOmegac > ptCandMax) { - resultSelections = false; - } - - int pTBin = findBin(binsPt, ptCandOmegac); - if (pTBin == -1) { - resultSelections = false; - } + // Topological selection + track quality selection + const bool selectedLf = selectOnLf(candidate); + const bool selectedHf = selectOnHf(candidate, tracks); + const bool selectedTrackQuality = selectOnTrackQuality(trackPiFromLam, trackPrFromLam, trackKaFromCasc, trackPiFromCharm); - // Topological selection - const bool selectionResOnLF = selectOnLf(candidate); - const bool selectionResOnHF = selectOnHf(candidate, pTBin); - if (!selectionResOnLF || !selectionResOnHF) { - resultSelections = false; - } - - // TPC clusters selections - if (resultSelections) { - registry.fill(HIST("hSelStatusCluster"), 0.0); - } - if (applyTrkSelLf) { - if (!isSelectedTrackTpcQuality(trackPiFromLam, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { - resultSelections = false; - } else { - if (resultSelections) { - registry.fill(HIST("hSelStatusCluster"), 1.0); - } - } - - if (!isSelectedTrackTpcQuality(trackPrFromLam, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { - resultSelections = false; - } else { - if (resultSelections) { - registry.fill(HIST("hSelStatusCluster"), 2.0); - } - } - - if (!isSelectedTrackTpcQuality(trackKaFromCasc, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { - resultSelections = false; - } else { - if (resultSelections) { - registry.fill(HIST("hSelStatusCluster"), 3.0); - } - } - } - - if (!isSelectedTrackTpcQuality(trackPiFromCharm, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { - resultSelections = false; - } else { - if (resultSelections) { - registry.fill(HIST("hSelStatusCluster"), 4.0); - } - } - - // ITS clusters selection - if (!isSelectedTrackItsQuality(trackPiFromCharm, nClustersItsMin, itsChi2PerClusterMax) || trackPiFromCharm.itsNClsInnerBarrel() < nClustersItsInnBarrMin) { - resultSelections = false; - } else { - if (resultSelections) { - registry.fill(HIST("hSelStatusCluster"), 5.0); + if (!selectedLf || !selectedHf || !selectedTrackQuality) { + hfSelOmegaC0ToOmegaPiCandidate(statusOmegaC0ToOmegaPi); + if (applyMl) { + hfMlOmegaC0ToOmegaPiCandidate(outputMlOmegac); } + continue; } + SETBIT(statusOmegaC0ToOmegaPi, aod::SelectionStep::RecoTopol); // Track level PID selection - if (resultSelections) { - registry.fill(HIST("hSelStatusPID"), 0.0); - } - int statusPidPrFromLam = -999; - int statusPidPiFromLam = -999; - int statusPidKaFromCasc = -999; - int statusPidPiFromCharmBaryon = -999; - - int infoTpcStored = 0; - int infoTofStored = 0; - - if (usePidTpcOnly == usePidTpcTofCombined) { - LOGF(fatal, "Check the PID configurables, usePidTpcOnly and usePidTpcTofCombined can't have the same value"); - } - - if (trackPiFromLam.hasTPC()) { - SETBIT(infoTpcStored, PiFromLam); - } - if (trackPrFromLam.hasTPC()) { - SETBIT(infoTpcStored, PrFromLam); - } - if (trackKaFromCasc.hasTPC()) { - SETBIT(infoTpcStored, KaFromCasc); - } - if (trackPiFromCharm.hasTPC()) { - SETBIT(infoTpcStored, PiFromCharm); - } - if (trackPiFromLam.hasTOF()) { - SETBIT(infoTofStored, PiFromLam); - } - if (trackPrFromLam.hasTOF()) { - SETBIT(infoTofStored, PrFromLam); - } - if (trackKaFromCasc.hasTOF()) { - SETBIT(infoTofStored, KaFromCasc); - } - if (trackPiFromCharm.hasTOF()) { - SETBIT(infoTofStored, PiFromCharm); - } + TrackSelectorPID::Status pidPrFromLam{}; + TrackSelectorPID::Status pidPiFromLam{}; + TrackSelectorPID::Status pidKaFromCasc{}; + TrackSelectorPID::Status pidPiFromCharmBaryon{}; if (usePidTpcOnly) { - statusPidPrFromLam = selectorProton.statusTpc(trackPrFromLam); - statusPidPiFromLam = selectorPion.statusTpc(trackPiFromLam); - statusPidKaFromCasc = selectorKaon.statusTpc(trackKaFromCasc); - statusPidPiFromCharmBaryon = selectorPion.statusTpc(trackPiFromCharm); + pidPrFromLam = selectorProton.statusTpc(trackPrFromLam); + pidPiFromLam = selectorPion.statusTpc(trackPiFromLam); + pidKaFromCasc = selectorKaon.statusTpc(trackKaFromCasc); + pidPiFromCharmBaryon = selectorPion.statusTpc(trackPiFromCharm); } else if (usePidTpcTofCombined) { - statusPidPrFromLam = selectorProton.statusTpcOrTof(trackPrFromLam); - statusPidPiFromLam = selectorPion.statusTpcOrTof(trackPiFromLam); - statusPidKaFromCasc = selectorKaon.statusTpcOrTof(trackKaFromCasc); - statusPidPiFromCharmBaryon = selectorPion.statusTpcOrTof(trackPiFromCharm); - } - - bool statusPidLambda = (statusPidPrFromLam == TrackSelectorPID::Accepted) && (statusPidPiFromLam == TrackSelectorPID::Accepted); - if (statusPidLambda && resultSelections) { - registry.fill(HIST("hSelStatusPID"), 1.0); - } - bool statusPidCascade = (statusPidLambda && statusPidKaFromCasc == TrackSelectorPID::Accepted); - if (statusPidCascade && resultSelections) { - registry.fill(HIST("hSelStatusPID"), 2.0); - } - bool statusPidCharmBaryon = (statusPidCascade && statusPidPiFromCharmBaryon == TrackSelectorPID::Accepted); - if (statusPidCharmBaryon && resultSelections) { - registry.fill(HIST("hSelStatusPID"), 3.0); + pidPrFromLam = selectorProton.statusTpcOrTof(trackPrFromLam); + pidPiFromLam = selectorPion.statusTpcOrTof(trackPiFromLam); + pidKaFromCasc = selectorKaon.statusTpcOrTof(trackKaFromCasc); + pidPiFromCharmBaryon = selectorPion.statusTpcOrTof(trackPiFromCharm); } - // invariant mass cuts - bool statusInvMassLambda = false; - bool statusInvMassCascade = false; - bool statusInvMassCharmBaryon = false; - - double const invMassLambda = candidate.invMassLambda(); - double const invMassCascade = candidate.invMassCascade(); - double const invMassCharmBaryon = candidate.invMassCharmBaryon(); - - if (std::abs(invMassLambda - o2::constants::physics::MassLambda0) < v0MassWindow) { - statusInvMassLambda = true; - } - if (std::abs(invMassCascade - o2::constants::physics::MassOmegaMinus) < cascadeMassWindow) { - statusInvMassCascade = true; - } - if ((invMassCharmBaryon >= invMassCharmBaryonMin) && (invMassCharmBaryon <= invMassCharmBaryonMax)) { - statusInvMassCharmBaryon = true; - } - - // Fill in selection result - if (!statusPidLambda || !statusPidCascade || !statusPidCharmBaryon || - !statusInvMassLambda || !statusInvMassCascade || !statusInvMassCharmBaryon) { - resultSelections = false; - } - - // Check candidate pT range for ML inference - if (applyMl && findBin(binsPtMl, ptCandOmegac) == -1) { - resultSelections = false; + if (!isSelectedPID(pidPrFromLam, pidPiFromLam, pidKaFromCasc, pidPiFromCharmBaryon)) { + hfSelOmegaC0ToOmegaPiCandidate(statusOmegaC0ToOmegaPi); + if (applyMl) { + hfMlOmegaC0ToOmegaPiCandidate(outputMlOmegac); + } + continue; } + SETBIT(statusOmegaC0ToOmegaPi, aod::SelectionStep::RecoPID); - // ML BDT selection - if (applyMl && resultSelections) { + if (applyMl && findBin(binsPtMl, candidate.pt()) != -1) { + // ML selections bool isSelectedMlOmegac = false; - std::vector inputFeaturesOmegaC = {}; - - if constexpr (svReco == doKfParticle) { - inputFeaturesOmegaC = hfMlResponseKf.getInputFeatures(candidate, trackPiFromLam, trackKaFromCasc, trackPiFromCharm); - isSelectedMlOmegac = hfMlResponseKf.isSelectedMl(inputFeaturesOmegaC, ptCandOmegac, outputMlOmegac); - if (isSelectedMlOmegac) { - registry.fill(HIST("hBDTScoreKF"), outputMlOmegac[0]); - } else { - resultSelections = false; - } - } else if constexpr (svReco == doDcaFitter) { - inputFeaturesOmegaC = hfMlResponseDca.getInputFeatures(candidate, trackPiFromLam, trackKaFromCasc, trackPiFromCharm); - isSelectedMlOmegac = hfMlResponseDca.isSelectedMl(inputFeaturesOmegaC, ptCandOmegac, outputMlOmegac); - if (isSelectedMlOmegac) { - registry.fill(HIST("hBDTScoreDCA"), outputMlOmegac[0]); - } else { - resultSelections = false; - } + + if constexpr (svReco == RecoMethod::doKfParticle) { + std::vector inputFeaturesOmegaC = hfMlResponseKf.getInputFeatures(candidate, trackPiFromLam, trackKaFromCasc, trackPiFromCharm); + isSelectedMlOmegac = hfMlResponseKf.isSelectedMl(inputFeaturesOmegaC, candidate.pt(), outputMlOmegac); + } else if constexpr (svReco == RecoMethod::doDcaFitter) { + std::vector inputFeaturesOmegaC = hfMlResponseDca.getInputFeatures(candidate, trackPiFromLam, trackKaFromCasc, trackPiFromCharm); + isSelectedMlOmegac = hfMlResponseDca.isSelectedMl(inputFeaturesOmegaC, candidate.pt(), outputMlOmegac); } - } - if (applyMl) { - hfMlSelToOmegaPi(outputMlOmegac); - } + registry.fill(HIST("hMlScore"), outputMlOmegac[0]); - hfSelToOmegaPi(statusPidLambda, statusPidCascade, statusPidCharmBaryon, statusInvMassLambda, statusInvMassCascade, statusInvMassCharmBaryon, resultSelections, infoTpcStored, infoTofStored, - trackPiFromCharm.tpcNSigmaPi(), trackKaFromCasc.tpcNSigmaKa(), trackPiFromLam.tpcNSigmaPi(), trackPrFromLam.tpcNSigmaPr(), - trackPiFromCharm.tofNSigmaPi(), trackKaFromCasc.tofNSigmaKa(), trackPiFromLam.tofNSigmaPi(), trackPrFromLam.tofNSigmaPr()); + hfMlOmegaC0ToOmegaPiCandidate(outputMlOmegac); - // Fill in invariant mass histogram - if (statusPidLambda && statusPidCascade && statusPidCharmBaryon && statusInvMassLambda && statusInvMassCascade && statusInvMassCharmBaryon && resultSelections) { - registry.fill(HIST("hInvMassCharmBaryon"), invMassCharmBaryon); - if constexpr (svReco == doKfParticle) { - registry.fill(HIST("hPtCharmBaryon"), candidate.kfptOmegac()); - } else { - registry.fill(HIST("hPtCharmBaryon"), ptCandOmegac); + if (!isSelectedMlOmegac) { + hfSelOmegaC0ToOmegaPiCandidate(statusOmegaC0ToOmegaPi); + continue; } + SETBIT(statusOmegaC0ToOmegaPi, aod::SelectionStep::RecoMl); } + registry.fill(HIST("hInvMassCharmBaryon"), HfHelper::invMassOmegaczeroToOmegaPi(candidate)); + registry.fill(HIST("hPtCharmBaryon"), candidate.pt()); + + hfSelOmegaC0ToOmegaPiCandidate(statusOmegaC0ToOmegaPi); } // end of candidate loop } // end run function /////////////////////////////////// /// Process with DCAFitter // /////////////////////////////////// - void processOmegac0SelectorWithDCAFitter(aod::HfCandToOmegaPi const& candidates, + void processOmegac0SelectorWithDCAFitter(HfCandCascBachQa const& candidates, TracksSel const& tracks, TracksSelLf const& lfTracks) { - runOmegac0Selector(candidates, tracks, lfTracks); + runOmegac0Selector(candidates, tracks, lfTracks); } PROCESS_SWITCH(HfCandidateSelectorToOmegaPiQa, processOmegac0SelectorWithDCAFitter, "Omegac0 candidate selection with DCAFitter output", true); //////////////////////////////////// /// Process with KFParticle // //////////////////////////////////// - void processOmegac0SelectorWithKFParticle(soa::Join const& candidates, + void processOmegac0SelectorWithKFParticle(soa::Join const& candidates, TracksSel const& tracks, TracksSelLf const& lfTracks) { - runOmegac0Selector(candidates, tracks, lfTracks); + runOmegac0Selector(candidates, tracks, lfTracks); } PROCESS_SWITCH(HfCandidateSelectorToOmegaPiQa, processOmegac0SelectorWithKFParticle, "Omegac0 candidate selection with KFParticle output", false); diff --git a/PWGHF/TableProducer/candidateSelectorToXiPiQa.cxx b/PWGHF/TableProducer/candidateSelectorToXiPiQa.cxx index 2c8dfc1cbb7..f6aa3f485c9 100644 --- a/PWGHF/TableProducer/candidateSelectorToXiPiQa.cxx +++ b/PWGHF/TableProducer/candidateSelectorToXiPiQa.cxx @@ -15,12 +15,13 @@ /// \author Jinhyun Park , Pusan National University /// \author Krista Smith , Pusan National University -#include "PWGHF/Core/HfMlResponseXic0ToXiPi.h" -#include "PWGHF/Core/HfMlResponseXic0ToXiPiKf.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/HfMlResponseXic0ToXiPiQa.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/DataModel/TrackIndexSkimmingTables.h" #include "PWGHF/Utils/utilsAnalysis.h" #include "Common/Core/RecoDecay.h" @@ -69,12 +70,8 @@ enum { /// Struct for applying Omegac0/Xic0 selection cuts struct HfCandidateSelectorToXiPiQa { - // DCAFitter - Produces hfSelToXiPi; - // KFParticle - Produces hfSelToXiPiKf; - // ML selection - Filled with both DCAFitter and KFParticle - Produces hfMlToXiPi; + Produces hfSelToXiPi; + Produces hfMlToXiPi; // cuts from SelectorCuts.h - pT dependent cuts Configurable> binsPt{"binsPt", std::vector{hf_cuts_xic_to_xi_pi::vecBinsPt}, "pT bin limits"}; @@ -142,21 +139,25 @@ struct HfCandidateSelectorToXiPiQa { Configurable nClustersItsInnBarrMin{"nClustersItsInnBarrMin", 1, "Minimum number of ITS clusters in inner barrel requirement for pi <- charm baryon"}; Configurable itsChi2PerClusterMax{"itsChi2PerClusterMax", 36, "Maximum value of chi2 fit over ITS clusters for pi <- charm baryon"}; - o2::analysis::HfMlResponseXic0ToXiPi hfMlResponseDca; - o2::analysis::HfMlResponseXic0ToXiPiKf hfMlResponseKf; + o2::analysis::HfMlResponseXic0ToXiPiQa hfMlResponseDca; + o2::analysis::HfMlResponseXic0ToXiPiQa hfMlResponseKf; std::vector outputMlXic0ToXiPi; o2::ccdb::CcdbApi ccdbApi; TrackSelectorPi selectorPion; TrackSelectorPr selectorProton; - using TracksSel = soa::Join; + using TracksSel = soa::Join; using TracksSelLf = soa::Join; HistogramRegistry registry{"registry"}; // for QA of selections void init(InitContext const&) { + if (doprocessSelectionDCAFitter && doprocessSelectionKFParticle) { + LOGF(fatal, "Enable only one XiPi selector mode"); + } + selectorPion.setRangePtTpc(ptPiPidTpcMin, ptPiPidTpcMax); selectorPion.setRangeNSigmaTpc(-nSigmaTpcPiMax, nSigmaTpcPiMax); selectorPion.setRangeNSigmaTpcCondTof(-nSigmaTpcCombinedPiMax, nSigmaTpcCombinedPiMax); @@ -295,15 +296,18 @@ struct HfCandidateSelectorToXiPiQa { // Selection on LF related informations // returns true if all cuts are passed template - bool selectOnLf(const T& candidate, const int& inputPtBin) + bool selectOnLf(const T& candidate, const int& inputPtBin, TracksSelLf const& lfTracks) { + auto trackV0PosDau = lfTracks.rawIteratorAt(candidate.posTrackId()); + auto trackV0NegDau = lfTracks.rawIteratorAt(candidate.negTrackId()); + auto trackPiFromCasc = lfTracks.rawIteratorAt(candidate.bachelorId()); registry.fill(HIST("hSelStatusLf"), 0.0); // Eta selection of V0, Cascade daughters - double etaV0PosDau = candidate.etaV0PosDau(); - double etaV0NegDau = candidate.etaV0NegDau(); - double etaPiFromCasc = candidate.etaBachFromCasc(); + double etaV0PosDau = trackV0PosDau.eta(); + double etaV0NegDau = trackV0NegDau.eta(); + double etaPiFromCasc = trackPiFromCasc.eta(); if (std::abs(etaV0PosDau) > etaTrackLFDauMax || std::abs(etaV0NegDau) > etaTrackLFDauMax || std::abs(etaPiFromCasc) > etaTrackLFDauMax) { return false; @@ -311,8 +315,8 @@ struct HfCandidateSelectorToXiPiQa { registry.fill(HIST("hSelStatusLf"), 1.0); // Minimum radius cut - double radiusV0 = RecoDecay::sqrtSumOfSquares(candidate.xDecayVtxV0(), candidate.yDecayVtxV0()); - double radiusCasc = RecoDecay::sqrtSumOfSquares(candidate.xDecayVtxCascade(), candidate.yDecayVtxCascade()); + double radiusV0 = RecoDecay::sqrtSumOfSquares(candidate.xV0Vertex(), candidate.yV0Vertex()); + double radiusCasc = RecoDecay::sqrtSumOfSquares(candidate.xCascadeVertex(), candidate.yCascadeVertex()); if (radiusV0 < radiusV0Min) { return false; @@ -324,44 +328,43 @@ struct HfCandidateSelectorToXiPiQa { registry.fill(HIST("hSelStatusLf"), 3.0); // Cosine of pointing angle - if (candidate.cosPAV0() < cuts->get(inputPtBin, "cosPAV0")) { + if (candidate.cpaV0() < cuts->get(inputPtBin, "cosPAV0")) { return false; } registry.fill(HIST("hSelStatusLf"), 4.0); - if (candidate.cosPACasc() < cuts->get(inputPtBin, "cosPACasc")) { + if (candidate.cpaCascade() < cuts->get(inputPtBin, "cosPACasc")) { return false; } registry.fill(HIST("hSelStatusLf"), 5.0); // Distance of Closest Approach(DCA) - if (candidate.dcaV0Dau() > cuts->get(inputPtBin, "dcaV0Dau")) { + if (candidate.dcaV0Daughters() > cuts->get(inputPtBin, "dcaV0Dau")) { return false; } registry.fill(HIST("hSelStatusLf"), 6.0); - if (candidate.dcaCascDau() > cuts->get(inputPtBin, "dcaCascDau")) { + if (candidate.dcaCascadeDaughters() > cuts->get(inputPtBin, "dcaCascDau")) { return false; } registry.fill(HIST("hSelStatusLf"), 7.0); - if (std::abs(candidate.dcaXYToPvV0Dau0()) < cuts->get(inputPtBin, "dcaXYToPvV0Dau0")) { + if (std::abs(candidate.impactParameterXYV0PosDau()) < cuts->get(inputPtBin, "dcaXYToPvV0Dau0")) { return false; } registry.fill(HIST("hSelStatusLf"), 8.0); - if (std::abs(candidate.dcaXYToPvV0Dau1()) < cuts->get(inputPtBin, "dcaXYToPvV0Dau1")) { + if (std::abs(candidate.impactParameterXYV0NegDau()) < cuts->get(inputPtBin, "dcaXYToPvV0Dau1")) { return false; } registry.fill(HIST("hSelStatusLf"), 9.0); - if (std::abs(candidate.dcaXYToPvCascDau()) < cuts->get(inputPtBin, "dcaXYToPvCascDau")) { + if (std::abs(candidate.impactParameterXYCascadeBach()) < cuts->get(inputPtBin, "dcaXYToPvCascDau")) { return false; } registry.fill(HIST("hSelStatusLf"), 10.0); // pT: Bachelor - double ptPiFromCasc = RecoDecay::sqrtSumOfSquares(candidate.pxBachFromCasc(), candidate.pyBachFromCasc()); - if (std::abs(ptPiFromCasc) < ptPiFromCascMin) { + if (std::abs(trackPiFromCasc.pt()) < ptPiFromCascMin) { return false; } registry.fill(HIST("hSelStatusLf"), 11.0); @@ -369,13 +372,13 @@ struct HfCandidateSelectorToXiPiQa { // Extra cuts for KFParticle if constexpr (svReco == doKfParticle) { // Cosine of Pointing angle - if (candidate.cosPaV0ToCasc() < cuts->get(inputPtBin, "cosPaV0ToCasc")) { + if (candidate.cpaV0ToCascade() < cuts->get(inputPtBin, "cosPaV0ToCasc")) { return false; } registry.fill(HIST("hSelStatusLf"), 12.0); // DCA - if (std::abs(candidate.kfDcaXYCascToPv()) > cuts->get(inputPtBin, "kfDcaXYCascToPv")) { + if (std::abs(candidate.impactParameter0()) > cuts->get(inputPtBin, "kfDcaXYCascToPv")) { return false; } registry.fill(HIST("hSelStatusLf"), 13.0); @@ -385,50 +388,50 @@ struct HfCandidateSelectorToXiPiQa { return false; } registry.fill(HIST("hSelStatusLf"), 14.0); - if (candidate.chi2GeoCasc() < 0 || candidate.chi2GeoCasc() > cuts->get(inputPtBin, "chi2GeoCasc")) { + if (candidate.chi2GeoCascade() < 0 || candidate.chi2GeoCascade() > cuts->get(inputPtBin, "chi2GeoCasc")) { return false; } registry.fill(HIST("hSelStatusLf"), 15.0); - if (candidate.chi2TopoV0ToPv() > 0 && candidate.chi2TopoV0ToPv() < cuts->get(inputPtBin, "chi2TopoV0ToPv")) { + if (candidate.chi2TopoOverNdfV0ToPv() > 0 && candidate.chi2TopoOverNdfV0ToPv() < cuts->get(inputPtBin, "chi2TopoV0ToPv")) { return false; } registry.fill(HIST("hSelStatusLf"), 16.0); - if (candidate.chi2TopoCascToPv() < 0 || candidate.chi2TopoCascToPv() > cuts->get(inputPtBin, "chi2TopoCascToPv")) { + if (candidate.chi2TopoOverNdfCascadeToPv() < 0 || candidate.chi2TopoOverNdfCascadeToPv() > cuts->get(inputPtBin, "chi2TopoCascToPv")) { return false; } registry.fill(HIST("hSelStatusLf"), 17.0); - if (candidate.chi2TopoV0ToCasc() < 0 || candidate.chi2TopoV0ToCasc() > cuts->get(inputPtBin, "chi2TopoV0ToCasc")) { + if (candidate.chi2TopoOverNdfV0ToCascade() < 0 || candidate.chi2TopoOverNdfV0ToCascade() > cuts->get(inputPtBin, "chi2TopoV0ToCasc")) { return false; } registry.fill(HIST("hSelStatusLf"), 18.0); // ldl - if (candidate.v0ldl() < cuts->get(inputPtBin, "v0ldl")) { + if (candidate.decayLengthNormKfV0() < cuts->get(inputPtBin, "v0ldl")) { return false; } registry.fill(HIST("hSelStatusLf"), 19.0); - if (candidate.cascldl() < cuts->get(inputPtBin, "cascldl")) { + if (candidate.decayLengthNormKfCascade() < cuts->get(inputPtBin, "cascldl")) { return false; } registry.fill(HIST("hSelStatusLf"), 20.0); // Decay length - if (std::abs(candidate.decayLenXYLambda()) < cuts->get(inputPtBin, "decayLenXYLambda")) { + if (std::abs(candidate.decayLengthXYV0()) < cuts->get(inputPtBin, "decayLenXYLambda")) { return false; } registry.fill(HIST("hSelStatusLf"), 21.0); - if (std::abs(candidate.decayLenXYCasc()) < cuts->get(inputPtBin, "decayLenXYCasc")) { + if (std::abs(candidate.decayLengthXYCascade()) < cuts->get(inputPtBin, "decayLenXYCasc")) { return false; } registry.fill(HIST("hSelStatusLf"), 22.0); } else { // Impact parameter(DCA?) - if (std::abs(candidate.impactParCascXY()) < impactParXYCascMin || std::abs(candidate.impactParCascXY()) > impactParXYCascMax) { + if (std::abs(candidate.impactParameter0()) < impactParXYCascMin || std::abs(candidate.impactParameter0()) > impactParXYCascMax) { return false; } registry.fill(HIST("hSelStatusLf"), 12.0); - if (std::abs(candidate.impactParCascZ()) < impactParZCascMin || std::abs(candidate.impactParCascZ()) > impactParZCascMax) { + if (std::abs(candidate.impactParameterZ0()) < impactParZCascMin || std::abs(candidate.impactParameterZ0()) > impactParZCascMax) { return false; } registry.fill(HIST("hSelStatusLf"), 13.0); @@ -442,24 +445,25 @@ struct HfCandidateSelectorToXiPiQa { // Apply cuts with charm baryon & charm bachelor related informations // returns true if all cuts are passed template - bool selectOnHf(const T& candidate, const int& inputPtBin) + bool selectOnHf(const T& candidate, const int& inputPtBin, TracksSel const& tracks) { + auto trackPiFromCharm = tracks.rawIteratorAt(candidate.prong1Id()); registry.fill(HIST("hSelStatusHf"), 0.0); // eta selection on charm bayron bachelor - if (std::abs(candidate.etaBachFromCharmBaryon()) > etaTrackCharmBachMax) { + if (std::abs(trackPiFromCharm.eta()) > etaTrackCharmBachMax) { return false; } registry.fill(HIST("hSelStatusHf"), 1.0); // Distance of Closest Approach(DCA) - if (candidate.dcaCharmBaryonDau() > cuts->get(inputPtBin, "dcaCharmBaryonDau")) { + if (candidate.dcaDaughters() > cuts->get(inputPtBin, "dcaCharmBaryonDau")) { return false; } registry.fill(HIST("hSelStatusHf"), 2.0); // pT: Charm Bachelor - double ptPiFromCharmBaryon = RecoDecay::sqrtSumOfSquares(candidate.pxBachFromCharmBaryon(), candidate.pyBachFromCharmBaryon()); + double ptPiFromCharmBaryon = RecoDecay::sqrtSumOfSquares(candidate.pxProng1(), candidate.pyProng1()); if (ptPiFromCharmBaryon < cuts->get(inputPtBin, "ptPiFromCharmBaryon")) { return false; } @@ -468,53 +472,54 @@ struct HfCandidateSelectorToXiPiQa { // specific selections with KFParticle output if constexpr (svReco == doKfParticle) { // Cosine of pointing angle - if (candidate.cosPaCascToXic() < cuts->get(inputPtBin, "cosPaCascToXic")) { + if (candidate.cpaCascadeToCharmHadron() < cuts->get(inputPtBin, "cosPaCascToXic")) { return false; } registry.fill(HIST("hSelStatusHf"), 4.0); // DCA - if (std::abs(candidate.kfDcaXYPiFromXic()) > cuts->get(inputPtBin, "kfDcaXYPiFromXic")) { + if (std::abs(candidate.impactParameter1()) > cuts->get(inputPtBin, "kfDcaXYPiFromXic")) { return false; } registry.fill(HIST("hSelStatusHf"), 5.0); // Chi2 - if (candidate.chi2GeoXic() < 0 || candidate.chi2GeoXic() > cuts->get(inputPtBin, "chi2GeoXic")) { + if (candidate.chi2Geo() < 0 || candidate.chi2Geo() > cuts->get(inputPtBin, "chi2GeoXic")) { return false; } registry.fill(HIST("hSelStatusHf"), 6.0); - if (candidate.chi2TopoXicToPv() < 0 || candidate.chi2TopoXicToPv() > cuts->get(inputPtBin, "chi2TopoXicToPv")) { + if (candidate.chi2TopoOverNdfToPv() < 0 || candidate.chi2TopoOverNdfToPv() > cuts->get(inputPtBin, "chi2TopoXicToPv")) { return false; } registry.fill(HIST("hSelStatusHf"), 7.0); - if (candidate.chi2TopoPiFromXicToPv() < 0 || candidate.chi2TopoPiFromXicToPv() > cuts->get(inputPtBin, "chi2TopoPiFromXicToPv")) { - return false; - } - registry.fill(HIST("hSelStatusHf"), 8.0); - if (candidate.chi2TopoCascToXic() < 0 || candidate.chi2TopoCascToXic() > cuts->get(inputPtBin, "chi2TopoCascToXic")) { + // TODO: check if this is needed + // The QA KF table has no dedicated charm-bachelor-to-PV topological chi2 column. + // if (candidate.chi2TopoPiFromXicToPv() < 0 || candidate.chi2TopoPiFromXicToPv() > cuts->get(inputPtBin, "chi2TopoPiFromXicToPv")) { + // return false; + // } + // registry.fill(HIST("hSelStatusHf"), 8.0); + if (candidate.chi2TopoOverNdfCascadeToCharmHadron() < 0 || candidate.chi2TopoOverNdfCascadeToCharmHadron() > cuts->get(inputPtBin, "chi2TopoCascToXic")) { return false; } registry.fill(HIST("hSelStatusHf"), 9.0); // Decay Length - if (std::abs(candidate.decayLenXYXic()) > cuts->get(inputPtBin, "decayLenXYXic")) { + if (std::abs(candidate.decayLengthXY()) > cuts->get(inputPtBin, "decayLenXYXic")) { return false; } registry.fill(HIST("hSelStatusHf"), 10.0); // ctau - if (std::abs(candidate.cTauXic()) > cuts->get(inputPtBin, "cTauXic")) { + if (std::abs(HfHelper::ctXiczero(candidate)) > cuts->get(inputPtBin, "cTauXic")) { return false; } registry.fill(HIST("hSelStatusHf"), 11.0); } else { - // Impact parameter(DCA?) - if ((std::abs(candidate.impactParBachFromCharmBaryonXY()) < impactParXYPiFromCharmBaryonMin) || (std::abs(candidate.impactParBachFromCharmBaryonXY()) > impactParXYPiFromCharmBaryonMax)) { + if ((std::abs(candidate.impactParameter1()) < impactParXYPiFromCharmBaryonMin) || (std::abs(candidate.impactParameter1()) > impactParXYPiFromCharmBaryonMax)) { return false; } registry.fill(HIST("hSelStatusHf"), 4.0); - if ((std::abs(candidate.impactParBachFromCharmBaryonZ()) < impactParZPiFromCharmBaryonMin) || (std::abs(candidate.impactParBachFromCharmBaryonZ()) > impactParZPiFromCharmBaryonMax)) { + if ((std::abs(candidate.impactParameterZ1()) < impactParZPiFromCharmBaryonMin) || (std::abs(candidate.impactParameterZ1()) > impactParZPiFromCharmBaryonMax)) { return false; } registry.fill(HIST("hSelStatusHf"), 5.0); @@ -531,21 +536,27 @@ struct HfCandidateSelectorToXiPiQa { { // looping over charm baryon candidates for (const auto& candidate : candidates) { - - bool resultSelections = true; // True if the candidate passes all the selections, False otherwise + int selectionStatus = 0; outputMlXic0ToXiPi.clear(); + if (!TESTBIT(candidate.hfflag(), hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi)) { + hfSelToXiPi(selectionStatus); + if (applyMl) { + hfMlToXiPi(outputMlXic0ToXiPi); + } + continue; + } + SETBIT(selectionStatus, aod::SelectionStep::RecoSkims); + auto trackV0PosDau = lfTracks.rawIteratorAt(candidate.posTrackId()); auto trackV0NegDau = lfTracks.rawIteratorAt(candidate.negTrackId()); auto trackPiFromCasc = lfTracks.rawIteratorAt(candidate.bachelorId()); - auto trackPiFromCharm = tracks.rawIteratorAt(candidate.bachelorFromCharmBaryonId()); + auto trackPiFromCharm = tracks.rawIteratorAt(candidate.prong1Id()); auto trackPiFromLam = trackV0NegDau; auto trackPrFromLam = trackV0PosDau; - int8_t signDecay = candidate.signDecay(); // sign of pi <- cascade - - if (signDecay > 0) { + if (trackPiFromCharm.sign() < 0) { trackPiFromLam = trackV0PosDau; trackPrFromLam = trackV0NegDau; registry.fill(HIST("hSelSignDec"), 1); // anti-particle decay @@ -554,106 +565,88 @@ struct HfCandidateSelectorToXiPiQa { } // pT selection - auto ptCandXic0 = RecoDecay::pt(candidate.pxCharmBaryon(), candidate.pyCharmBaryon()); + auto ptCandXic0 = candidate.pt(); int pTBin = findBin(binsPt, ptCandXic0); if (pTBin == -1) { - resultSelections = false; + hfSelToXiPi(selectionStatus); + if (applyMl) { + hfMlToXiPi(outputMlXic0ToXiPi); + } + continue; } // Topological selection - const bool selectionResOnLF = selectOnLf(candidate, pTBin); - const bool selectionResOnHF = selectOnHf(candidate, pTBin); - if (!selectionResOnLF || !selectionResOnHF) { - resultSelections = false; - } + const bool selectionResOnLF = selectOnLf(candidate, pTBin, lfTracks); + const bool selectionResOnHF = selectOnHf(candidate, pTBin, tracks); // TPC clusters selections - if (resultSelections) { - registry.fill(HIST("hSelStatusCluster"), 0.0); - } + bool selectedTrackQuality = true; + registry.fill(HIST("hSelStatusCluster"), 0.0); if (applyTrkSelLf) { if (!isSelectedTrackTpcQuality(trackPiFromLam, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { - resultSelections = false; + selectedTrackQuality = false; } else { - if (resultSelections) { - registry.fill(HIST("hSelStatusCluster"), 1.0); - } + registry.fill(HIST("hSelStatusCluster"), 1.0); } if (!isSelectedTrackTpcQuality(trackPrFromLam, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { - resultSelections = false; + selectedTrackQuality = false; } else { - if (resultSelections) { - registry.fill(HIST("hSelStatusCluster"), 2.0); - } + registry.fill(HIST("hSelStatusCluster"), 2.0); } if (!isSelectedTrackTpcQuality(trackPiFromCasc, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { - resultSelections = false; + selectedTrackQuality = false; } else { - if (resultSelections) { - registry.fill(HIST("hSelStatusCluster"), 3.0); - } + registry.fill(HIST("hSelStatusCluster"), 3.0); } } if (!isSelectedTrackTpcQuality(trackPiFromCharm, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { - resultSelections = false; + selectedTrackQuality = false; } else { - if (resultSelections) { - registry.fill(HIST("hSelStatusCluster"), 4.0); - } + registry.fill(HIST("hSelStatusCluster"), 4.0); } // ITS clusters selection if (!isSelectedTrackItsQuality(trackPiFromCharm, nClustersItsMin, itsChi2PerClusterMax) || trackPiFromCharm.itsNClsInnerBarrel() < nClustersItsInnBarrMin) { - resultSelections = false; + selectedTrackQuality = false; } else { - if (resultSelections) { - registry.fill(HIST("hSelStatusCluster"), 5.0); - } + registry.fill(HIST("hSelStatusCluster"), 5.0); } - // Track level PID selection - if (resultSelections) { - registry.fill(HIST("hSelStatusPID"), 0.0); + const double invMassCharmBaryon = HfHelper::invMassXiczeroToXiPi(candidate); + if (selectionResOnLF && selectionResOnHF && selectedTrackQuality) { + registry.fill(HIST("hInvMassCharmBaryonWoPidInvMassCut"), invMassCharmBaryon); } - int statusPidPrFromLam = -999; - int statusPidPiFromLam = -999; - int statusPidPiFromCasc = -999; - int statusPidPiFromCharmBaryon = -999; - int infoTpcStored = 0; - int infoTofStored = 0; + const bool statusInvMassLambda = std::abs(candidate.massLambda() - o2::constants::physics::MassLambda0) < v0MassWindow; + const bool statusInvMassCascade = std::abs(candidate.massCascade() - o2::constants::physics::MassXiMinus) < cascMassWindow; + + bool statusInvMassCharmBaryon = (invMassCharmBaryon >= invMassCharmBaryonMin) && (invMassCharmBaryon <= invMassCharmBaryonMax); + + if (!selectionResOnLF || !selectionResOnHF || !selectedTrackQuality || !statusInvMassLambda || !statusInvMassCascade || !statusInvMassCharmBaryon) { + hfSelToXiPi(selectionStatus); + if (applyMl) { + hfMlToXiPi(outputMlXic0ToXiPi); + } + registry.fill(HIST("hInvMassCharmBaryonBkg"), invMassCharmBaryon); + + continue; + } + SETBIT(selectionStatus, aod::SelectionStep::RecoTopol); + + // Track level PID selection + registry.fill(HIST("hSelStatusPID"), 0.0); if (usePidTpcOnly == usePidTpcTofCombined) { LOGF(fatal, "Check the PID configurables, usePidTpcOnly and usePidTpcTofCombined can't have the same value"); } - if (trackPiFromLam.hasTPC()) { - SETBIT(infoTpcStored, PiFromLam); - } - if (trackPrFromLam.hasTPC()) { - SETBIT(infoTpcStored, PrFromLam); - } - if (trackPiFromCasc.hasTPC()) { - SETBIT(infoTpcStored, PiFromCasc); - } - if (trackPiFromCharm.hasTPC()) { - SETBIT(infoTpcStored, PiFromCharm); - } - if (trackPiFromLam.hasTOF()) { - SETBIT(infoTofStored, PiFromLam); - } - if (trackPrFromLam.hasTOF()) { - SETBIT(infoTofStored, PrFromLam); - } - if (trackPiFromCasc.hasTOF()) { - SETBIT(infoTofStored, PiFromCasc); - } - if (trackPiFromCharm.hasTOF()) { - SETBIT(infoTofStored, PiFromCharm); - } + TrackSelectorPID::Status statusPidPrFromLam{}; + TrackSelectorPID::Status statusPidPiFromLam{}; + TrackSelectorPID::Status statusPidPiFromCasc{}; + TrackSelectorPID::Status statusPidPiFromCharmBaryon{}; if (usePidTpcOnly) { statusPidPrFromLam = selectorProton.statusTpc(trackPrFromLam); @@ -667,80 +660,50 @@ struct HfCandidateSelectorToXiPiQa { statusPidPiFromCharmBaryon = selectorPion.statusTpcOrTof(trackPiFromCharm); } - bool statusPidLambda = (statusPidPrFromLam == TrackSelectorPID::Accepted) && (statusPidPiFromLam == TrackSelectorPID::Accepted); - if (statusPidLambda && resultSelections) { + const bool statusPidLambda = (statusPidPrFromLam == TrackSelectorPID::Accepted) && (statusPidPiFromLam == TrackSelectorPID::Accepted); + if (statusPidLambda) { registry.fill(HIST("hSelStatusPID"), 1.0); } - bool statusPidCascade = (statusPidLambda && statusPidPiFromCasc == TrackSelectorPID::Accepted); - if (statusPidCascade && resultSelections) { + const bool statusPidCascade = statusPidLambda && statusPidPiFromCasc == TrackSelectorPID::Accepted; + if (statusPidCascade) { registry.fill(HIST("hSelStatusPID"), 2.0); } - bool statusPidCharmBaryon = (statusPidCascade && statusPidPiFromCharmBaryon == TrackSelectorPID::Accepted); - if (statusPidCharmBaryon && resultSelections) { + const bool statusPidCharmBaryon = statusPidCascade && statusPidPiFromCharmBaryon == TrackSelectorPID::Accepted; + if (statusPidCharmBaryon) { registry.fill(HIST("hSelStatusPID"), 3.0); } - // invariant mass cuts - bool statusInvMassLambda = false; - bool statusInvMassCascade = false; - bool statusInvMassCharmBaryon = false; - - double invMassLambda = candidate.invMassLambda(); - double invMassCascade = candidate.invMassCascade(); - double invMassCharmBaryon = candidate.invMassCharmBaryon(); - - if (std::abs(invMassLambda - o2::constants::physics::MassLambda0) < v0MassWindow) { - statusInvMassLambda = true; - } - if (std::abs(invMassCascade - o2::constants::physics::MassXiMinus) < cascMassWindow) { - statusInvMassCascade = true; - } - if ((invMassCharmBaryon >= invMassCharmBaryonMin) && (invMassCharmBaryon <= invMassCharmBaryonMax)) { - statusInvMassCharmBaryon = true; - } - - // Fill in selection result - if constexpr (svReco == doDcaFitter) { - hfSelToXiPi(statusPidLambda, statusPidCascade, statusPidCharmBaryon, statusInvMassLambda, statusInvMassCascade, statusInvMassCharmBaryon, resultSelections, infoTpcStored, infoTofStored, - trackPiFromCharm.tpcNSigmaPi(), trackPiFromCasc.tpcNSigmaPi(), trackPiFromLam.tpcNSigmaPi(), trackPrFromLam.tpcNSigmaPr(), - trackPiFromCharm.tofNSigmaPi(), trackPiFromCasc.tofNSigmaPi(), trackPiFromLam.tofNSigmaPi(), trackPrFromLam.tofNSigmaPr()); - } else { - // Convert resultSelectrions to false if one of pid status and inv status is false - // This is only needed for KF(currently) since output selection table doesn't contain those information - if (!statusPidCharmBaryon || !statusInvMassLambda || !statusInvMassCascade || !statusInvMassCharmBaryon) { - resultSelections = false; + if (!statusPidCharmBaryon) { + hfSelToXiPi(selectionStatus); + if (applyMl) { + hfMlToXiPi(outputMlXic0ToXiPi); } - hfSelToXiPiKf(resultSelections, - trackPiFromCharm.tpcNSigmaPi(), trackPiFromCasc.tpcNSigmaPi(), trackPiFromLam.tpcNSigmaPi(), trackPrFromLam.tpcNSigmaPr(), - trackPiFromCharm.tofNSigmaPi(), trackPiFromCasc.tofNSigmaPi(), trackPiFromLam.tofNSigmaPi(), trackPrFromLam.tofNSigmaPr()); + registry.fill(HIST("hInvMassCharmBaryonBkg"), invMassCharmBaryon); + continue; } + SETBIT(selectionStatus, aod::SelectionStep::RecoPID); // ML BDT selection if required - if (applyMl) { + if (applyMl && findBin(binsPtMl, ptCandXic0) != -1) { bool isSelectedMlXic0 = false; if constexpr (svReco == doDcaFitter) { - auto inputFeaturesXic0 = hfMlResponseDca.getInputFeatures(candidate, trackPiFromLam, trackPiFromCasc, trackPiFromCharm); + auto inputFeaturesXic0 = hfMlResponseDca.getInputFeatures(candidate, trackPiFromLam, trackPrFromLam, trackPiFromCasc, trackPiFromCharm); isSelectedMlXic0 = hfMlResponseDca.isSelectedMl(inputFeaturesXic0, ptCandXic0, outputMlXic0ToXiPi); } else { auto inputFeaturesXic0 = hfMlResponseKf.getInputFeatures(candidate, trackPiFromLam, trackPrFromLam, trackPiFromCasc, trackPiFromCharm); isSelectedMlXic0 = hfMlResponseKf.isSelectedMl(inputFeaturesXic0, ptCandXic0, outputMlXic0ToXiPi); } - hfMlToXiPi(outputMlXic0ToXiPi); - - if (!isSelectedMlXic0) { - continue; + if (isSelectedMlXic0) { + SETBIT(selectionStatus, aod::SelectionStep::RecoMl); } } - // Fill in invariant mass histogram - if (resultSelections) { - registry.fill(HIST("hInvMassCharmBaryonWoPidInvMassCut"), invMassCharmBaryon); - } - if (statusPidLambda && statusPidCascade && statusPidCharmBaryon && statusInvMassLambda && statusInvMassCascade && statusInvMassCharmBaryon && resultSelections) { - registry.fill(HIST("hInvMassCharmBaryon"), invMassCharmBaryon); - } else { - registry.fill(HIST("hInvMassCharmBaryonBkg"), invMassCharmBaryon); + registry.fill(HIST("hInvMassCharmBaryon"), invMassCharmBaryon); + + hfSelToXiPi(selectionStatus); + if (applyMl) { + hfMlToXiPi(outputMlXic0ToXiPi); } } // end of candidate loop @@ -749,7 +712,7 @@ struct HfCandidateSelectorToXiPiQa { /////////////////////////////////// /// Process with DCAFitter // /////////////////////////////////// - void processSelectionDCAFitter(aod::HfCandToXiPi const& candidates, TracksSel const& tracks, TracksSelLf const& lfTracks) + void processSelectionDCAFitter(aod::HfCandCascBachQa const& candidates, TracksSel const& tracks, TracksSelLf const& lfTracks) { runSelection(candidates, tracks, lfTracks); } @@ -758,7 +721,7 @@ struct HfCandidateSelectorToXiPiQa { //////////////////////////////////// /// Process with KFParticle // //////////////////////////////////// - void processSelectionKFParticle(aod::HfCandToXiPiKf const& candidates, TracksSel const& tracks, TracksSelLf const& lfTracks) + void processSelectionKFParticle(soa::Join const& candidates, TracksSel const& tracks, TracksSelLf const& lfTracks) { runSelection(candidates, tracks, lfTracks); } diff --git a/PWGHF/TableProducer/treeCreatorOmegac0ToOmegaPiQa.cxx b/PWGHF/TableProducer/treeCreatorOmegac0ToOmegaPiQa.cxx index 55ba2da9efc..6f7128bd76c 100644 --- a/PWGHF/TableProducer/treeCreatorOmegac0ToOmegaPiQa.cxx +++ b/PWGHF/TableProducer/treeCreatorOmegac0ToOmegaPiQa.cxx @@ -17,9 +17,11 @@ /// \author Maria Fernanda Torres Cabrera , University of Houston #include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/DataModel/TrackIndexSkimmingTables.h" #include "PWGLF/DataModel/mcCentrality.h" #include "Common/Core/RecoDecay.h" @@ -35,8 +37,7 @@ #include #include -#include - +#include #include using namespace o2; @@ -70,19 +71,12 @@ DECLARE_SOA_COLUMN(ZDecayVtxCascade, zDecayVtxCascade, float); DECLARE_SOA_COLUMN(XDecayVtxV0, xDecayVtxV0, float); DECLARE_SOA_COLUMN(YDecayVtxV0, yDecayVtxV0, float); DECLARE_SOA_COLUMN(ZDecayVtxV0, zDecayVtxV0, float); -DECLARE_SOA_COLUMN(SignDecay, signDecay, int8_t); // sign of ka <- omega DECLARE_SOA_COLUMN(PxCharmBaryon, pxCharmBaryon, float); DECLARE_SOA_COLUMN(PyCharmBaryon, pyCharmBaryon, float); DECLARE_SOA_COLUMN(PzCharmBaryon, pzCharmBaryon, float); -DECLARE_SOA_COLUMN(PxCasc, pxCasc, float); -DECLARE_SOA_COLUMN(PyCasc, pyCasc, float); -DECLARE_SOA_COLUMN(PzCasc, pzCasc, float); DECLARE_SOA_COLUMN(PxPiFromCharmBaryon, pxPiFromCharmBaryon, float); DECLARE_SOA_COLUMN(PyPiFromCharmBaryon, pyPiFromCharmBaryon, float); DECLARE_SOA_COLUMN(PzPiFromCharmBaryon, pzPiFromCharmBaryon, float); -DECLARE_SOA_COLUMN(PxLambda, pxLambda, float); -DECLARE_SOA_COLUMN(PyLambda, pyLambda, float); -DECLARE_SOA_COLUMN(PzLambda, pzLambda, float); DECLARE_SOA_COLUMN(PtCharmBaryon, ptCharmBaryon, float); DECLARE_SOA_COLUMN(PtPiFromCharmBaryon, ptPiFromCharmBaryon, float); DECLARE_SOA_COLUMN(PxKaFromCasc, pxKaFromCasc, float); @@ -96,8 +90,6 @@ DECLARE_SOA_COLUMN(PyNegV0Dau, pyNegV0Dau, float); DECLARE_SOA_COLUMN(PzNegV0Dau, pzNegV0Dau, float); DECLARE_SOA_COLUMN(ImpactParCascXY, impactParCascXY, float); DECLARE_SOA_COLUMN(ImpactParPiFromCharmBaryonXY, impactParPiFromCharmBaryonXY, float); -DECLARE_SOA_COLUMN(ImpactParCascZ, impactParCascZ, float); -DECLARE_SOA_COLUMN(ImpactParPiFromCharmBaryonZ, impactParPiFromCharmBaryonZ, float); DECLARE_SOA_COLUMN(ErrImpactParCascXY, errImpactParCascXY, float); DECLARE_SOA_COLUMN(ErrImpactParPiFromCharmBaryonXY, errImpactParPiFromCharmBaryonXY, float); DECLARE_SOA_COLUMN(InvMassLambda, invMassLambda, float); @@ -106,30 +98,18 @@ DECLARE_SOA_COLUMN(InvMassCharmBaryon, invMassCharmBaryon, float); DECLARE_SOA_COLUMN(CosPAV0, cosPAV0, float); DECLARE_SOA_COLUMN(CosPACharmBaryon, cosPACharmBaryon, float); DECLARE_SOA_COLUMN(CosPACasc, cosPACasc, float); -DECLARE_SOA_COLUMN(CosPAXYV0, cosPAXYV0, float); -DECLARE_SOA_COLUMN(CosPAXYCharmBaryon, cosPAXYCharmBaryon, float); -DECLARE_SOA_COLUMN(CosPAXYCasc, cosPAXYCasc, float); -DECLARE_SOA_COLUMN(CTauCascade, cTauCascade, float); -DECLARE_SOA_COLUMN(CTauV0, cTauV0, float); DECLARE_SOA_COLUMN(EtaV0PosDau, etaV0PosDau, float); DECLARE_SOA_COLUMN(EtaV0NegDau, etaV0NegDau, float); DECLARE_SOA_COLUMN(EtaKaFromCasc, etaKaFromCasc, float); DECLARE_SOA_COLUMN(EtaPiFromCharmBaryon, etaPiFromCharmBaryon, float); DECLARE_SOA_COLUMN(EtaCharmBaryon, etaCharmBaryon, float); -DECLARE_SOA_COLUMN(EtaCascade, etaCascade, float); -DECLARE_SOA_COLUMN(EtaV0, etaV0, float); DECLARE_SOA_COLUMN(DcaXYToPvV0Dau0, dcaXYToPvV0Dau0, float); DECLARE_SOA_COLUMN(DcaXYToPvV0Dau1, dcaXYToPvV0Dau1, float); DECLARE_SOA_COLUMN(DcaXYToPvCascDau, dcaXYToPvCascDau, float); -DECLARE_SOA_COLUMN(DcaZToPvV0Dau0, dcaZToPvV0Dau0, float); -DECLARE_SOA_COLUMN(DcaZToPvV0Dau1, dcaZToPvV0Dau1, float); -DECLARE_SOA_COLUMN(DcaZToPvCascDau, dcaZToPvCascDau, float); DECLARE_SOA_COLUMN(DcaCascDau, dcaCascDau, float); DECLARE_SOA_COLUMN(DcaV0Dau, dcaV0Dau, float); DECLARE_SOA_COLUMN(DcaCharmBaryonDau, dcaCharmBaryonDau, float); DECLARE_SOA_COLUMN(DecLenCharmBaryon, decLenCharmBaryon, float); -DECLARE_SOA_COLUMN(DecLenCascade, decLenCascade, float); -DECLARE_SOA_COLUMN(DecLenV0, decLenV0, float); DECLARE_SOA_COLUMN(ErrorDecayLengthCharmBaryon, errorDecayLengthCharmBaryon, float); DECLARE_SOA_COLUMN(NormImpParCascade, normImpParCascade, double); DECLARE_SOA_COLUMN(NormImpParPiFromCharmBar, normImpParPiFromCharmBar, double); @@ -146,14 +126,11 @@ DECLARE_SOA_COLUMN(KfDcaXYCascToPv, kfDcaXYCascToPv, float); DECLARE_SOA_COLUMN(Chi2GeoV0, chi2GeoV0, float); DECLARE_SOA_COLUMN(Chi2GeoCasc, chi2GeoCasc, float); DECLARE_SOA_COLUMN(Chi2GeoOmegac, chi2GeoOmegac, float); -DECLARE_SOA_COLUMN(Chi2MassV0, chi2MassV0, float); -DECLARE_SOA_COLUMN(Chi2MassCasc, chi2MassCasc, float); DECLARE_SOA_COLUMN(V0ldl, v0ldl, float); DECLARE_SOA_COLUMN(Cascldl, cascldl, float); DECLARE_SOA_COLUMN(Omegacldl, omegacldl, float); DECLARE_SOA_COLUMN(Chi2TopoV0ToPv, chi2TopoV0ToPv, float); DECLARE_SOA_COLUMN(Chi2TopoCascToPv, chi2TopoCascToPv, float); -DECLARE_SOA_COLUMN(Chi2TopoPiFromOmegacToPv, chi2TopoPiFromOmegacToPv, float); DECLARE_SOA_COLUMN(Chi2TopoOmegacToPv, chi2TopoOmegacToPv, float); DECLARE_SOA_COLUMN(Chi2TopoV0ToCasc, chi2TopoV0ToCasc, float); DECLARE_SOA_COLUMN(Chi2TopoCascToOmegac, chi2TopoCascToOmegac, float); @@ -165,37 +142,20 @@ DECLARE_SOA_COLUMN(CosPaV0ToPv, cosPaV0ToPv, float); DECLARE_SOA_COLUMN(CosPaCascToOmegac, cosPaCascToOmegac, float); DECLARE_SOA_COLUMN(CosPaCascToPv, cosPaCascToPv, float); DECLARE_SOA_COLUMN(CosPaOmegacToPv, cosPaOmegacToPv, float); -DECLARE_SOA_COLUMN(KfRapOmegac, kfRapOmegac, float); DECLARE_SOA_COLUMN(KfptPiFromOmegac, kfptPiFromOmegac, float); DECLARE_SOA_COLUMN(KfptOmegac, kfptOmegac, float); DECLARE_SOA_COLUMN(CosThetaStarPiFromOmegac, cosThetaStarPiFromOmegac, float); -DECLARE_SOA_COLUMN(CtOmegac, ctOmegac, float); DECLARE_SOA_COLUMN(EtaOmegac, etaOmegac, float); DECLARE_SOA_COLUMN(V0Ndf, v0Ndf, float); DECLARE_SOA_COLUMN(CascNdf, cascNdf, float); DECLARE_SOA_COLUMN(OmegacNdf, omegacNdf, float); -DECLARE_SOA_COLUMN(MassV0Ndf, massV0Ndf, float); -DECLARE_SOA_COLUMN(MassCascNdf, massCascNdf, float); DECLARE_SOA_COLUMN(V0Chi2OverNdf, v0Chi2OverNdf, float); DECLARE_SOA_COLUMN(CascChi2OverNdf, cascChi2OverNdf, float); DECLARE_SOA_COLUMN(OmegacChi2OverNdf, omegacChi2OverNdf, float); -DECLARE_SOA_COLUMN(MassV0Chi2OverNdf, massV0Chi2OverNdf, float); -DECLARE_SOA_COLUMN(MassCascChi2OverNdf, massCascChi2OverNdf, float); -DECLARE_SOA_COLUMN(CascRejectInvmass, cascRejectInvmass, float); // from creator - MC DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); // reconstruction level DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int8_t); -DECLARE_SOA_COLUMN(CollisionMatched, collisionMatched, bool); -// from selector -DECLARE_SOA_COLUMN(StatusPidLambda, statusPidLambda, bool); -DECLARE_SOA_COLUMN(StatusPidCascade, statusPidCascade, bool); -DECLARE_SOA_COLUMN(StatusPidCharmBaryon, statusPidCharmBaryon, bool); -DECLARE_SOA_COLUMN(StatusInvMassLambda, statusInvMassLambda, bool); -DECLARE_SOA_COLUMN(StatusInvMassCascade, statusInvMassCascade, bool); -DECLARE_SOA_COLUMN(StatusInvMassCharmBaryon, statusInvMassCharmBaryon, bool); -DECLARE_SOA_COLUMN(ResultSelections, resultSelections, bool); -DECLARE_SOA_COLUMN(PidTpcInfoStored, pidTpcInfoStored, int); -DECLARE_SOA_COLUMN(PidTofInfoStored, pidTofInfoStored, int); +// particle PID DECLARE_SOA_COLUMN(TpcNSigmaPiFromCharmBaryon, tpcNSigmaPiFromCharmBaryon, float); DECLARE_SOA_COLUMN(TpcNSigmaKaFromCasc, tpcNSigmaKaFromCasc, float); DECLARE_SOA_COLUMN(TpcNSigmaPiFromLambda, tpcNSigmaPiFromLambda, float); @@ -214,8 +174,8 @@ DECLARE_SOA_TABLE(HfOmegac0ToOmegaPi, "AOD", "HFTOOMEGAPI", full::XDecayVtxCharmBaryon, full::YDecayVtxCharmBaryon, full::ZDecayVtxCharmBaryon, full::XDecayVtxCascade, full::YDecayVtxCascade, full::ZDecayVtxCascade, full::XDecayVtxV0, full::YDecayVtxV0, full::ZDecayVtxV0, - full::SignDecay, - full::PtCharmBaryon, full::PtPiFromCharmBaryon, + full::PtCharmBaryon, + full::PtPiFromCharmBaryon, full::PxCharmBaryon, full::PyCharmBaryon, full::PzCharmBaryon, full::PxPiFromCharmBaryon, full::PyPiFromCharmBaryon, full::PzPiFromCharmBaryon, full::PxKaFromCasc, full::PyKaFromCasc, full::PzKaFromCasc, @@ -225,7 +185,9 @@ DECLARE_SOA_TABLE(HfOmegac0ToOmegaPi, "AOD", "HFTOOMEGAPI", full::ErrImpactParCascXY, full::ErrImpactParPiFromCharmBaryonXY, full::InvMassLambda, full::InvMassCascade, full::InvMassCharmBaryon, full::CosPAV0, full::CosPACharmBaryon, full::CosPACasc, - full::EtaV0PosDau, full::EtaV0NegDau, full::EtaKaFromCasc, full::EtaPiFromCharmBaryon, full::EtaCharmBaryon, + full::EtaV0PosDau, full::EtaV0NegDau, full::EtaKaFromCasc, + full::EtaPiFromCharmBaryon, + full::EtaCharmBaryon, full::DcaXYToPvV0Dau0, full::DcaXYToPvV0Dau1, full::DcaXYToPvCascDau, full::DcaCascDau, full::DcaV0Dau, full::DcaCharmBaryonDau, full::DecLenCharmBaryon, @@ -233,12 +195,9 @@ DECLARE_SOA_TABLE(HfOmegac0ToOmegaPi, "AOD", "HFTOOMEGAPI", full::NormDecayLenCharmBar, full::IsPionGlbTrkWoDca, full::PionItsNCls, full::NTpcRowsPion, full::NTpcRowsKaFromCasc, full::NTpcRowsPosV0Dau, full::NTpcRowsNegV0Dau, - full::StatusPidLambda, full::StatusPidCascade, full::StatusPidCharmBaryon, - full::StatusInvMassLambda, full::StatusInvMassCascade, full::StatusInvMassCharmBaryon, full::ResultSelections, - full::PidTpcInfoStored, full::PidTofInfoStored, full::TpcNSigmaPiFromCharmBaryon, full::TpcNSigmaKaFromCasc, full::TpcNSigmaPiFromLambda, full::TpcNSigmaPrFromLambda, full::TofNSigmaPiFromCharmBaryon, full::TofNSigmaKaFromCasc, full::TofNSigmaPiFromLambda, full::TofNSigmaPrFromLambda, - full::FlagMcMatchRec, full::OriginMcRec, full::CollisionMatched); + full::FlagMcMatchRec, full::OriginMcRec); DECLARE_SOA_TABLE(HfKfOmegac, "AOD", "HFKFOMEGAC", full::Centrality, @@ -248,21 +207,18 @@ DECLARE_SOA_TABLE(HfKfOmegac, "AOD", "HFKFOMEGAC", full::KfDcaXYPiFromOmegac, full::DcaCascDau, full::DcaV0Dau, full::DcaCharmBaryonDau, full::KfDcaXYCascToPv, full::DcaXYToPvV0Dau0, full::DcaXYToPvV0Dau1, full::DcaXYToPvCascDau, full::Chi2GeoV0, full::Chi2GeoCasc, full::Chi2GeoOmegac, - full::Chi2MassV0, full::Chi2MassCasc, full::V0ldl, full::Cascldl, full::Omegacldl, - full::Chi2TopoV0ToPv, full::Chi2TopoCascToPv, full::Chi2TopoPiFromOmegacToPv, full::Chi2TopoOmegacToPv, + full::Chi2TopoV0ToPv, full::Chi2TopoCascToPv, + full::Chi2TopoOmegacToPv, full::Chi2TopoV0ToCasc, full::Chi2TopoCascToOmegac, full::DecayLenXYLambda, full::DecayLenXYCasc, full::DecayLenXYOmegac, full::CosPaV0ToCasc, full::CosPaV0ToPv, full::CosPaCascToOmegac, full::CosPaCascToPv, full::CosPaOmegacToPv, full::InvMassLambda, full::InvMassCascade, full::InvMassCharmBaryon, - full::KfRapOmegac, full::KfptPiFromOmegac, full::KfptOmegac, - full::CosThetaStarPiFromOmegac, full::CtOmegac, full::EtaOmegac, + full::KfptPiFromOmegac, full::KfptOmegac, full::CosThetaStarPiFromOmegac, + full::EtaOmegac, full::V0Ndf, full::CascNdf, full::OmegacNdf, - full::MassV0Ndf, full::MassCascNdf, full::V0Chi2OverNdf, full::CascChi2OverNdf, full::OmegacChi2OverNdf, - full::MassV0Chi2OverNdf, full::MassCascChi2OverNdf, full::CascRejectInvmass, - full::ResultSelections, - full::FlagMcMatchRec, full::OriginMcRec, full::CollisionMatched); + full::FlagMcMatchRec, full::OriginMcRec); } // namespace o2::aod /// Writes the full information in an output TTree @@ -272,23 +228,25 @@ struct HfTreeCreatorToOmegaPiQa { Produces rowKfCandidate; Produces rowEv; + Configurable selectionFlagOmegac0{"selectionFlagOmegac0", 7, "Selection Flag for Omegac0 candidates. 1 -> skimmed, 3 -> topological, 7 -> PID, 15 -> ML"}; Configurable zPvCut{"zPvCut", 10., "Cut on absolute value of primary vertex z coordinate"}; Configurable keepOnlyMcSignal{"keepOnlyMcSignal", true, "Fill MC tree only with signal candidates"}; - using MyTrackTable = soa::Join; + using TracksSel = soa::Join; + using TracksSelLf = soa::Join; - using CandSel = soa::Filtered>; - using CandKfSel = soa::Filtered>; - using CandMcSel = soa::Filtered>; - using CandKfMcSel = soa::Filtered>; + using CandSel = soa::Filtered>; + using CandKfSel = soa::Filtered>; + using CandMcSel = soa::Filtered>; + using CandKfMcSel = soa::Filtered>; using CollsSel = soa::Join; using CollsSelWithFT0M = soa::Join; using CollsWithMcLabels = soa::Join; using McCollsWithFT0M = soa::Join; - Filter filterOmegaCToOmegaPiFlag = (o2::aod::hf_track_index::hfflag & static_cast(BIT(aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi))) != static_cast(0); - Filter filterSelectCandidates = aod::hf_sel_toomegapi::resultSelections == true; + Filter filterOmegaCMatchedRec = nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_decay::hf_cand_casc_bach_qa::DecayChannelMain::Omegac0ToOmegaPi); + Filter filterSelectCandidates = aod::hf_sel_candidate_omegac0_qa::isSelOmegaC0ToOmegaPi >= selectionFlagOmegac0; void init(InitContext const&) { @@ -307,7 +265,7 @@ struct HfTreeCreatorToOmegaPiQa { } template - void fillCandidate(const T& candidate, int8_t flagMc, int8_t originMc, bool collisionMatched, float centrality = -999.f) + void fillCandidate(const T& candidate, TracksSel const& tracks, TracksSelLf const& lfTracks, int8_t flagMc, int8_t originMc, float centrality = -999.f) { // save all candidate information @@ -318,157 +276,148 @@ struct HfTreeCreatorToOmegaPiQa { } } + // retrive PID information + auto trackV0PosDau = lfTracks.rawIteratorAt(candidate.posTrackId()); + auto trackV0NegDau = lfTracks.rawIteratorAt(candidate.negTrackId()); + auto trackKaFromCasc = lfTracks.rawIteratorAt(candidate.bachelorId()); + auto trackPiFromCharm = tracks.rawIteratorAt(candidate.prong1Id()); + + auto trackPiFromLam = trackV0NegDau; + auto trackPrFromLam = trackV0PosDau; + if (trackPiFromCharm.sign() < 0) { + trackPiFromLam = trackV0PosDau; + trackPrFromLam = trackV0NegDau; + } + if constexpr (svReco == DCAFITTER) { - rowCandidate(candidate.xPv(), - candidate.yPv(), - candidate.zPv(), + auto const& collision = candidate.template collision_as(); + rowCandidate(collision.posX(), + collision.posY(), + collision.posZ(), centrality, - candidate.template collision_as().numContrib(), - candidate.template collision_as().chi2(), - candidate.xDecayVtxCharmBaryon(), - candidate.yDecayVtxCharmBaryon(), - candidate.zDecayVtxCharmBaryon(), - candidate.xDecayVtxCascade(), - candidate.yDecayVtxCascade(), - candidate.zDecayVtxCascade(), - candidate.xDecayVtxV0(), - candidate.yDecayVtxV0(), - candidate.zDecayVtxV0(), - candidate.signDecay(), - RecoDecay::pt(candidate.pxCharmBaryon(), candidate.pyCharmBaryon()), - RecoDecay::pt(candidate.pxBachFromCharmBaryon(), candidate.pyBachFromCharmBaryon()), - candidate.pxCharmBaryon(), - candidate.pyCharmBaryon(), - candidate.pzCharmBaryon(), - candidate.pxBachFromCharmBaryon(), - candidate.pyBachFromCharmBaryon(), - candidate.pzBachFromCharmBaryon(), - candidate.pxBachFromCasc(), - candidate.pyBachFromCasc(), - candidate.pzBachFromCasc(), - candidate.pxPosV0Dau(), - candidate.pyPosV0Dau(), - candidate.pzPosV0Dau(), - candidate.pxNegV0Dau(), - candidate.pyNegV0Dau(), - candidate.pzNegV0Dau(), - candidate.impactParCascXY(), - candidate.impactParBachFromCharmBaryonXY(), - candidate.errImpactParCascXY(), - candidate.errImpactParBachFromCharmBaryonXY(), - candidate.invMassLambda(), - candidate.invMassCascade(), - candidate.invMassCharmBaryon(), - candidate.cosPAV0(), - candidate.cosPACharmBaryon(), - candidate.cosPACasc(), - candidate.etaV0PosDau(), - candidate.etaV0NegDau(), - candidate.etaBachFromCasc(), - candidate.etaBachFromCharmBaryon(), - candidate.etaCharmBaryon(), - candidate.dcaXYToPvV0Dau0(), - candidate.dcaXYToPvV0Dau1(), - candidate.dcaXYToPvCascDau(), - candidate.dcaCascDau(), - candidate.dcaV0Dau(), - candidate.dcaCharmBaryonDau(), - candidate.decLenCharmBaryon(), - candidate.errorDecayLengthCharmBaryon(), - candidate.impactParCascXY() / candidate.errImpactParCascXY(), - candidate.impactParBachFromCharmBaryonXY() / candidate.errImpactParBachFromCharmBaryonXY(), - candidate.normDecayLenCharmBar(), - candidate.template bachelorFromCharmBaryon_as().isGlobalTrackWoDCA(), - candidate.template bachelorFromCharmBaryon_as().itsNCls(), - candidate.template bachelorFromCharmBaryon_as().tpcNClsCrossedRows(), - candidate.template bachelor_as().tpcNClsCrossedRows(), - candidate.template posTrack_as().tpcNClsCrossedRows(), - candidate.template negTrack_as().tpcNClsCrossedRows(), - candidate.statusPidLambda(), - candidate.statusPidCascade(), - candidate.statusPidCharmBaryon(), - candidate.statusInvMassLambda(), - candidate.statusInvMassCascade(), - candidate.statusInvMassCharmBaryon(), - candidate.resultSelections(), - candidate.pidTpcInfoStored(), - candidate.pidTofInfoStored(), - candidate.tpcNSigmaPiFromCharmBaryon(), - candidate.tpcNSigmaKaFromCasc(), - candidate.tpcNSigmaPiFromLambda(), - candidate.tpcNSigmaPrFromLambda(), - candidate.tofNSigmaPiFromCharmBaryon(), - candidate.tofNSigmaKaFromCasc(), - candidate.tofNSigmaPiFromLambda(), - candidate.tofNSigmaPrFromLambda(), + collision.numContrib(), + collision.chi2(), + candidate.xSecondaryVertex(), + candidate.ySecondaryVertex(), + candidate.zSecondaryVertex(), + candidate.xCascadeVertex(), + candidate.yCascadeVertex(), + candidate.zCascadeVertex(), + candidate.xV0Vertex(), + candidate.yV0Vertex(), + candidate.zV0Vertex(), + candidate.pt(), + RecoDecay::pt(candidate.pxProng1(), candidate.pyProng1()), + candidate.px(), + candidate.py(), + candidate.pz(), + candidate.pxProng1(), + candidate.pyProng1(), + candidate.pzProng1(), + trackKaFromCasc.px(), + trackKaFromCasc.py(), + trackKaFromCasc.pz(), + trackV0PosDau.px(), + trackV0PosDau.py(), + trackV0PosDau.pz(), + trackV0NegDau.px(), + trackV0NegDau.py(), + trackV0NegDau.pz(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.errorImpactParameter0(), + candidate.errorImpactParameter1(), + candidate.massLambda(), + candidate.massCascade(), + HfHelper::invMassOmegaczeroToOmegaPi(candidate), + candidate.cpaV0(), + candidate.cpa(), + candidate.cpaCascade(), + trackV0PosDau.eta(), + trackV0NegDau.eta(), + trackKaFromCasc.eta(), + RecoDecay::eta(std::array{candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()}), + candidate.eta(), + candidate.impactParameterXYV0PosDau(), + candidate.impactParameterXYV0NegDau(), + candidate.impactParameterXYCascadeBach(), + candidate.dcaCascadeDaughters(), + candidate.dcaV0Daughters(), + candidate.dcaDaughters(), + candidate.decayLength(), + candidate.errorDecayLength(), + candidate.impactParameterNormalised0(), + candidate.impactParameterNormalised1(), + candidate.decayLengthNormalised(), + trackPiFromCharm.isGlobalTrackWoDCA(), + trackPiFromCharm.itsNCls(), + trackPiFromCharm.tpcNClsCrossedRows(), + trackKaFromCasc.tpcNClsCrossedRows(), + trackV0PosDau.tpcNClsCrossedRows(), + trackV0NegDau.tpcNClsCrossedRows(), + trackPiFromCharm.tpcNSigmaPi(), + trackKaFromCasc.tpcNSigmaKa(), + trackPiFromLam.tpcNSigmaPi(), + trackPrFromLam.tpcNSigmaPr(), + trackPiFromCharm.tofNSigmaPi(), + trackKaFromCasc.tofNSigmaKa(), + trackPiFromLam.tofNSigmaPi(), + trackPrFromLam.tofNSigmaPr(), flagMc, - originMc, - collisionMatched); + originMc); } else { rowKfCandidate(centrality, candidate.template collision_as().numContrib(), - candidate.tpcNSigmaPiFromCharmBaryon(), - candidate.tofNSigmaPiFromCharmBaryon(), - candidate.tpcNSigmaKaFromCasc(), - candidate.tofNSigmaKaFromCasc(), - candidate.tpcNSigmaPiFromLambda(), - candidate.tofNSigmaPiFromLambda(), - candidate.tpcNSigmaPrFromLambda(), - candidate.tofNSigmaPrFromLambda(), - candidate.kfDcaXYPiFromOmegac(), - candidate.dcaCascDau(), - candidate.dcaV0Dau(), - candidate.dcaCharmBaryonDau(), - candidate.kfDcaXYCascToPv(), - candidate.dcaXYToPvV0Dau0(), - candidate.dcaXYToPvV0Dau1(), - candidate.dcaXYToPvCascDau(), + trackPiFromCharm.tpcNSigmaPi(), + trackPiFromCharm.tofNSigmaPi(), + trackKaFromCasc.tpcNSigmaKa(), + trackKaFromCasc.tofNSigmaKa(), + trackPiFromLam.tpcNSigmaPi(), + trackPiFromLam.tofNSigmaPi(), + trackPrFromLam.tpcNSigmaPr(), + trackPrFromLam.tofNSigmaPr(), + candidate.impactParameter1(), + candidate.dcaCascadeDaughters(), + candidate.dcaV0Daughters(), + candidate.dcaDaughters(), + candidate.impactParameter0(), + candidate.impactParameterXYV0PosDau(), + candidate.impactParameterXYV0NegDau(), + candidate.impactParameterXYCascadeBach(), candidate.chi2GeoV0(), - candidate.chi2GeoCasc(), - candidate.chi2GeoOmegac(), - candidate.chi2MassV0(), - candidate.chi2MassCasc(), - candidate.v0ldl(), - candidate.cascldl(), - candidate.omegacldl(), + candidate.chi2GeoCascade(), + candidate.chi2Geo(), + candidate.decayLengthNormKfV0(), + candidate.decayLengthNormKfCascade(), + candidate.decayLengthNormKf(), candidate.chi2TopoV0ToPv(), - candidate.chi2TopoCascToPv(), - candidate.chi2TopoPiFromOmegacToPv(), - candidate.chi2TopoOmegacToPv(), - candidate.chi2TopoV0ToCasc(), - candidate.chi2TopoCascToOmegac(), - candidate.decayLenXYLambda(), - candidate.decayLenXYCasc(), - candidate.decayLenXYOmegac(), - candidate.cosPaV0ToCasc(), - candidate.cosPAV0(), - candidate.cosPaCascToOmegac(), - candidate.cosPACasc(), - candidate.cosPACharmBaryon(), - candidate.invMassLambda(), - candidate.invMassCascade(), - candidate.invMassCharmBaryon(), - candidate.kfRapOmegac(), - candidate.kfptPiFromOmegac(), - candidate.kfptOmegac(), - candidate.cosThetaStarPiFromOmegac(), - candidate.cTauOmegac(), - candidate.etaCharmBaryon(), - candidate.v0Ndf(), - candidate.cascNdf(), - candidate.omegacNdf(), - candidate.massV0Ndf(), - candidate.massCascNdf(), - candidate.v0Chi2OverNdf(), - candidate.cascChi2OverNdf(), - candidate.omegacChi2OverNdf(), - candidate.massV0Chi2OverNdf(), - candidate.massCascChi2OverNdf(), - candidate.cascRejectInvmass(), - candidate.resultSelections(), + candidate.chi2TopoCascadeToPv(), + candidate.chi2TopoToPv(), + candidate.chi2TopoV0ToCascade(), + candidate.chi2TopoCascadeToCharmHadron(), + candidate.decayLengthXYV0(), + candidate.decayLengthXYCascade(), + candidate.decayLengthXY(), + candidate.cpaV0ToCascade(), + candidate.cpaV0(), + candidate.cpaCascadeToCharmHadron(), + candidate.cpaCascade(), + candidate.cpa(), + candidate.massLambda(), + candidate.massCascade(), + HfHelper::invMassOmegaczeroToOmegaPi(candidate), + RecoDecay::pt(candidate.pxProng1(), candidate.pyProng1()), + candidate.pt(), + HfHelper::cosThetaStarOmegaczeroToOmegaPi(candidate), + candidate.eta(), + candidate.ndfGeoV0(), + candidate.ndfGeoCascade(), + candidate.ndfGeo(), + candidate.chi2GeoOverNdfV0(), + candidate.chi2GeoOverNdfCascade(), + candidate.chi2GeoOverNdf(), flagMc, - originMc, - collisionMatched); + originMc); } } @@ -483,7 +432,8 @@ struct HfTreeCreatorToOmegaPiQa { //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// void processData(CollsSel const& collisions, - MyTrackTable const&, + TracksSel const& tracks, + TracksSelLf const& lfTracks, CandSel const& candidates) { // Filling event properties @@ -495,12 +445,13 @@ struct HfTreeCreatorToOmegaPiQa { // Filling candidate properties rowCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, -7, RecoDecay::OriginType::None, false); + fillCandidate(candidate, tracks, lfTracks, -7, RecoDecay::OriginType::None); } } void processDataCent(CollsSelWithFT0M const& collisions, - MyTrackTable const&, + TracksSel const& tracks, + TracksSelLf const& lfTracks, CandSel const& candidates) { // Filling event properties @@ -512,7 +463,7 @@ struct HfTreeCreatorToOmegaPiQa { // Filling candidate properties rowCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, -7, RecoDecay::OriginType::None, false); + fillCandidate(candidate, tracks, lfTracks, -7, RecoDecay::OriginType::None); } } @@ -524,6 +475,8 @@ struct HfTreeCreatorToOmegaPiQa { //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// void processKfData(CollsSel const& collisions, + TracksSel const& tracks, + TracksSelLf const& lfTracks, CandKfSel const& candidates) { // Filling event properties @@ -535,11 +488,13 @@ struct HfTreeCreatorToOmegaPiQa { // Filling candidate properties rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, -7, RecoDecay::OriginType::None, false); + fillCandidate(candidate, tracks, lfTracks, -7, RecoDecay::OriginType::None); } } void processKfDataCent(CollsSelWithFT0M const& collisions, + TracksSel const& tracks, + TracksSelLf const& lfTracks, CandKfSel const& candidates) { // Filling event properties @@ -551,7 +506,7 @@ struct HfTreeCreatorToOmegaPiQa { // Filling candidate properties rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, -7, RecoDecay::OriginType::None, false); + fillCandidate(candidate, tracks, lfTracks, -7, RecoDecay::OriginType::None); } } @@ -563,7 +518,8 @@ struct HfTreeCreatorToOmegaPiQa { //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// void processMc(CollsSel const& collisions, - MyTrackTable const&, + TracksSel const& tracks, + TracksSelLf const& lfTracks, CandMcSel const& candidates) { // Filling event properties @@ -578,12 +534,13 @@ struct HfTreeCreatorToOmegaPiQa { if (keepOnlyMcSignal && candidate.originMcRec() == RecoDecay::OriginType::None) { continue; } - fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.originMcRec(), candidate.collisionMatched()); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec()); } } void processMcCent(CollsWithMcLabels const& collisions, - MyTrackTable const&, + TracksSel const& tracks, + TracksSelLf const& lfTracks, CandMcSel const& candidates, McCollsWithFT0M const&) { @@ -601,7 +558,7 @@ struct HfTreeCreatorToOmegaPiQa { } auto mcCollision = candidate.collision_as().mcCollision_as(); float centFt0m = o2::hf_centrality::getCentralityColl(mcCollision); - fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.originMcRec(), candidate.collisionMatched(), centFt0m); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec(), centFt0m); } } @@ -613,6 +570,8 @@ struct HfTreeCreatorToOmegaPiQa { //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// void processKfMc(CollsSel const& collisions, + TracksSel const& tracks, + TracksSelLf const& lfTracks, CandKfMcSel const& candidates) { // Filling event properties @@ -627,11 +586,13 @@ struct HfTreeCreatorToOmegaPiQa { if (keepOnlyMcSignal && candidate.originMcRec() == RecoDecay::OriginType::None) { continue; } - fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.originMcRec(), candidate.collisionMatched()); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec()); } } void processKfMcCent(CollsWithMcLabels const& collisions, + TracksSel const& tracks, + TracksSelLf const& lfTracks, CandKfMcSel const& candidates, McCollsWithFT0M const&) { @@ -649,7 +610,7 @@ struct HfTreeCreatorToOmegaPiQa { } auto mcCollision = candidate.collision_as().mcCollision_as(); float centFt0m = o2::hf_centrality::getCentralityColl(mcCollision); - fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.originMcRec(), candidate.collisionMatched(), centFt0m); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec(), centFt0m); } } diff --git a/PWGHF/TableProducer/treeCreatorToXiPiQa.cxx b/PWGHF/TableProducer/treeCreatorToXiPiQa.cxx index ea8b6fbebb0..93dcf26670d 100644 --- a/PWGHF/TableProducer/treeCreatorToXiPiQa.cxx +++ b/PWGHF/TableProducer/treeCreatorToXiPiQa.cxx @@ -17,7 +17,9 @@ /// \author Krista Smith , Pusan National University #include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/Core/DecayChannelsLegacy.h" +#include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGLF/DataModel/mcCentrality.h" @@ -37,8 +39,7 @@ #include #include -#include - +#include #include using namespace o2; @@ -79,9 +80,6 @@ DECLARE_SOA_COLUMN(XDecayVtxV0, xDecayVtxV0, float); DECLARE_SOA_COLUMN(YDecayVtxV0, yDecayVtxV0, float); DECLARE_SOA_COLUMN(ZDecayVtxV0, zDecayVtxV0, float); DECLARE_SOA_COLUMN(SignDecay, signDecay, int8_t); // sign of pi <- xi -DECLARE_SOA_COLUMN(CovVtxCharmBaryonXX, covVtxCharmBaryonXX, float); -DECLARE_SOA_COLUMN(CovVtxCharmBaryonYY, covVtxCharmBaryonYY, float); -DECLARE_SOA_COLUMN(CovVtxCharmBaryonZZ, covVtxCharmBaryonZZ, float); DECLARE_SOA_COLUMN(PxCharmBaryon, pxCharmBaryon, float); DECLARE_SOA_COLUMN(PyCharmBaryon, pyCharmBaryon, float); DECLARE_SOA_COLUMN(PzCharmBaryon, pzCharmBaryon, float); @@ -158,19 +156,7 @@ DECLARE_SOA_COLUMN(NTpcRowsPosV0Dau, nTpcRowsPosV0Dau, int16_t); DECLARE_SOA_COLUMN(NTpcRowsNegV0Dau, nTpcRowsNegV0Dau, int16_t); // from creator - MC DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); // reconstruction level -DECLARE_SOA_COLUMN(DebugMcRec, debugMcRec, int8_t); // debug flag for mis-association reconstruction level DECLARE_SOA_COLUMN(OriginRec, originRec, int8_t); -DECLARE_SOA_COLUMN(CollisionMatched, collisionMatched, bool); -// from selector -DECLARE_SOA_COLUMN(StatusPidLambda, statusPidLambda, bool); -DECLARE_SOA_COLUMN(StatusPidCascade, statusPidCascade, bool); -DECLARE_SOA_COLUMN(StatusPidCharmBaryon, statusPidCharmBaryon, bool); -DECLARE_SOA_COLUMN(StatusInvMassLambda, statusInvMassLambda, bool); -DECLARE_SOA_COLUMN(StatusInvMassCascade, statusInvMassCascade, bool); -DECLARE_SOA_COLUMN(StatusInvMassCharmBaryon, statusInvMassCharmBaryon, bool); -DECLARE_SOA_COLUMN(ResultSelections, resultSelections, bool); -DECLARE_SOA_COLUMN(PidTpcInfoStored, pidTpcInfoStored, int); -DECLARE_SOA_COLUMN(PidTofInfoStored, pidTofInfoStored, int); DECLARE_SOA_COLUMN(TpcNSigmaPiFromCharmBaryon, tpcNSigmaPiFromCharmBaryon, float); DECLARE_SOA_COLUMN(TpcNSigmaPiFromCasc, tpcNSigmaPiFromCasc, float); DECLARE_SOA_COLUMN(TpcNSigmaPiFromLambda, tpcNSigmaPiFromLambda, float); @@ -239,12 +225,10 @@ DECLARE_SOA_TABLE(HfToXiPiFulls, "AOD", "HFTOXIPIFULL", full::XDecayVtxCascade, full::YDecayVtxCascade, full::ZDecayVtxCascade, full::XDecayVtxV0, full::YDecayVtxV0, full::ZDecayVtxV0, full::SignDecay, - full::CovVtxCharmBaryonXX, full::CovVtxCharmBaryonYY, full::CovVtxCharmBaryonZZ, full::PtCharmBaryon, full::PtPiFromCharmBaryon, full::PxCharmBaryon, full::PyCharmBaryon, full::PzCharmBaryon, full::PxCasc, full::PyCasc, full::PzCasc, full::PxPiFromCharmBaryon, full::PyPiFromCharmBaryon, full::PzPiFromCharmBaryon, - full::PxLambda, full::PyLambda, full::PzLambda, full::PxPiFromCasc, full::PyPiFromCasc, full::PzPiFromCasc, full::PxPosV0Dau, full::PyPosV0Dau, full::PzPosV0Dau, full::PxNegV0Dau, full::PyNegV0Dau, full::PzNegV0Dau, @@ -253,7 +237,7 @@ DECLARE_SOA_TABLE(HfToXiPiFulls, "AOD", "HFTOXIPIFULL", full::ErrImpactParCascXY, full::ErrImpactParPiFromCharmBaryonXY, full::InvMassLambda, full::InvMassCascade, full::InvMassCharmBaryon, full::CosPAV0, full::CosPACharmBaryon, full::CosPACasc, full::CosPAXYV0, full::CosPAXYCharmBaryon, full::CosPAXYCasc, - full::CTauOmegac, full::CTauCascade, full::CTauV0, full::CTauXic, + full::CTauOmegac, full::EtaV0PosDau, full::EtaV0NegDau, full::EtaPiFromCasc, full::EtaPiFromCharmBaryon, full::EtaCharmBaryon, full::EtaCascade, full::EtaV0, full::DcaXYToPvV0Dau0, full::DcaXYToPvV0Dau1, full::DcaXYToPvCascDau, @@ -262,12 +246,9 @@ DECLARE_SOA_TABLE(HfToXiPiFulls, "AOD", "HFTOXIPIFULL", full::DecLenCharmBaryon, full::DecLenCascade, full::DecLenV0, full::ErrorDecayLengthCharmBaryon, full::ErrorDecayLengthXYCharmBaryon, full::NormImpParCascade, full::NormImpParPiFromCharmBar, full::NormDecayLenCharmBar, full::IsPionGlbTrkWoDca, full::PionItsNCls, full::NTpcRowsPion, full::NTpcRowsPiFromCasc, full::NTpcRowsPosV0Dau, full::NTpcRowsNegV0Dau, - full::StatusPidLambda, full::StatusPidCascade, full::StatusPidCharmBaryon, - full::StatusInvMassLambda, full::StatusInvMassCascade, full::StatusInvMassCharmBaryon, full::ResultSelections, - full::PidTpcInfoStored, full::PidTofInfoStored, full::TpcNSigmaPiFromCharmBaryon, full::TpcNSigmaPiFromCasc, full::TpcNSigmaPiFromLambda, full::TpcNSigmaPrFromLambda, full::TofNSigmaPiFromCharmBaryon, full::TofNSigmaPiFromCasc, full::TofNSigmaPiFromLambda, full::TofNSigmaPrFromLambda, - full::FlagMcMatchRec, full::DebugMcRec, full::OriginRec, full::CollisionMatched); + full::FlagMcMatchRec, full::OriginRec); DECLARE_SOA_TABLE(HfToXiPiLites, "AOD", "HFTOXIPILITE", full::XPv, full::YPv, full::ZPv, full::Centrality, collision::NumContrib, collision::Chi2, @@ -291,10 +272,9 @@ DECLARE_SOA_TABLE(HfToXiPiLites, "AOD", "HFTOXIPILITE", full::ErrorDecayLengthCharmBaryon, full::NormImpParCascade, full::NormImpParPiFromCharmBar, full::IsPionGlbTrkWoDca, full::PionItsNCls, full::NTpcRowsPion, full::NTpcRowsPiFromCasc, full::NTpcRowsPosV0Dau, full::NTpcRowsNegV0Dau, - full::PidTpcInfoStored, full::PidTofInfoStored, full::TpcNSigmaPiFromCharmBaryon, full::TpcNSigmaPiFromCasc, full::TpcNSigmaPiFromLambda, full::TpcNSigmaPrFromLambda, full::TofNSigmaPiFromCharmBaryon, full::TofNSigmaPiFromCasc, full::TofNSigmaPiFromLambda, full::TofNSigmaPrFromLambda, - full::FlagMcMatchRec, full::OriginRec, full::CollisionMatched); + full::FlagMcMatchRec, full::OriginRec); DECLARE_SOA_TABLE(HfKfXicFulls, "AOD", "HFKFXICFULL", full::Centrality, @@ -303,9 +283,8 @@ DECLARE_SOA_TABLE(HfKfXicFulls, "AOD", "HFKFXICFULL", full::KfDcaXYPiFromXic, full::DcaCascDau, full::DcaV0Dau, full::DcaCharmBaryonDau, full::KfDcaXYCascToPv, full::DcaXYToPvV0Dau0, full::DcaXYToPvV0Dau1, full::DcaXYToPvCascDau, full::Chi2GeoV0, full::Chi2GeoCasc, full::Chi2GeoXic, - full::Chi2MassV0, full::Chi2MassCasc, full::V0ldl, full::Cascldl, - full::Chi2TopoV0ToPv, full::Chi2TopoCascToPv, full::Chi2TopoPiFromXicToPv, full::Chi2TopoXicToPv, + full::Chi2TopoV0ToPv, full::Chi2TopoCascToPv, full::Chi2TopoXicToPv, full::Chi2TopoV0ToCasc, full::Chi2TopoCascToXic, full::DecayLenXYLambda, full::DecayLenXYCasc, full::DecayLenXYXic, full::CosPaV0ToCasc, full::CosPaV0ToPv, full::CosPaCascToXic, full::CosPaCascToPv, // full::CosPaXicToPv, @@ -313,11 +292,8 @@ DECLARE_SOA_TABLE(HfKfXicFulls, "AOD", "HFKFXICFULL", full::KfRapXic, full::KfptPiFromXic, full::KfptXic, full::CosThetaStarPiFromXic, full::CtXic, full::EtaXic, full::V0Ndf, full::CascNdf, full::XicNdf, - full::MassV0Ndf, full::MassCascNdf, full::V0Chi2OverNdf, full::CascChi2OverNdf, full::XicChi2OverNdf, - full::MassV0Chi2OverNdf, full::MassCascChi2OverNdf, - full::ResultSelections, - full::FlagMcMatchRec, full::DebugMcRec, full::OriginRec, full::CollisionMatched); + full::FlagMcMatchRec, full::OriginRec); DECLARE_SOA_TABLE(HfCandToXiPiGen, "AOD", "HFCANDTOXIPIGEN", full::InvMassCharmBaryon, @@ -346,28 +322,35 @@ struct HfTreeCreatorToXiPiQa { Produces rowCandidateParticles; Produces rowEv; + Configurable selectionFlag{"selectionFlag", 7, "Selection threshold: 1 skims, 3 topology, 7 PID, 15 ML"}; Configurable zPvCut{"zPvCut", 10., "Cut on absolute value of primary vertex z coordinate"}; - Configurable genSelection{"genSelection", o2::aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi, "Decay channel to be used to match particle information"}; + Configurable decayChannelSelection{"decayChannelSelection", hf_decay::hf_cand_casc_bach_qa::DecayChannelMain::Xic0ToXiPi, "Decay channel used to match particle information"}; Configurable fillGenTable{"fillGenTable", true, "Fill generated MC information if requested"}; - using MyTrackTable = soa::Join; - using MyCandTableDca = soa::Join; - using MyCandTableKf = soa::Join; - using MyCandTableXic0McDca = soa::Join; - using MyCandTableXic0McKf = soa::Join; - using MyCandTableOmegac0McDca = soa::Join; + using MyTrackTable = soa::Join; + using MyTrackTableLf = soa::Join; + using MyCandTableDca = soa::Filtered>; + using MyCandTableKf = soa::Filtered>; + using MyCandTableXic0McDca = soa::Filtered>; + using MyCandTableXic0McKf = soa::Filtered>; + using MyCandTableOmegac0McDca = MyCandTableXic0McDca; using MyEventTable = soa::Join; using MyEventTableWithFT0C = soa::Join; using MyEventTableWithFT0M = soa::Join; using MyEventTableWithNTracksPV = soa::Join; using MyEventTableWithMcLabels = soa::Join; + using MyEventTableWithMcLabelsFT0C = soa::Join; + using MyEventTableWithMcLabelsFT0M = soa::Join; + using MyEventTableWithMcLabelsNTracksPV = soa::Join; - using MatchedGenXiPi = soa::Filtered>; + using MatchedGenXiPi = soa::Filtered>; using McCollisionsCentFT0Cs = soa::Join; using McCollisionsCentFT0Ms = soa::Join; - Filter filterGenXiPi = nabs(aod::hf_cand_mc_flag::flagMcMatchGen) == static_cast(BIT(genSelection)); + Filter filterSelectCandidates = aod::hf_sel_candidate_to_xi_pi_qa::isSelToXiPi >= selectionFlag; + Filter filterRecXiPi = nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(decayChannelSelection); + Filter filterGenXiPi = nabs(aod::hf_cand_mc_flag::flagMcMatchGen) == static_cast(decayChannelSelection); PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; @@ -391,272 +374,250 @@ struct HfTreeCreatorToXiPiQa { } template - void fillCandidate(const T& candidate, int8_t flagMc, int8_t debugMc, int8_t originMc, bool collisionMatched) + void fillCandidate(const T& candidate, MyTrackTable const& tracks, MyTrackTableLf const& lfTracks, int8_t flagMc, int8_t originMc) { - // save all candidate information float centrality = -999.f; if constexpr (useCentrality) { const auto& collision = candidate.template collision_as(); centrality = o2::hf_centrality::getCentralityColl(collision); } + auto trackV0PosDau = lfTracks.rawIteratorAt(candidate.posTrackId()); + auto trackV0NegDau = lfTracks.rawIteratorAt(candidate.negTrackId()); + auto trackPiFromCasc = lfTracks.rawIteratorAt(candidate.bachelorId()); + auto trackPiFromCharm = tracks.rawIteratorAt(candidate.prong1Id()); + + auto trackPiFromLam = trackV0NegDau; + auto trackPrFromLam = trackV0PosDau; + if (trackPiFromCharm.sign() < 0) { + trackPiFromLam = trackV0PosDau; + trackPrFromLam = trackV0NegDau; + } + if constexpr (svReco == DCAFITTER) { if constexpr (tableSize == LITE) { - rowCandidateLite(candidate.xPv(), - candidate.yPv(), - candidate.zPv(), + rowCandidateLite(candidate.posX(), + candidate.posY(), + candidate.posZ(), centrality, candidate.template collision_as().numContrib(), candidate.template collision_as().chi2(), - candidate.xDecayVtxCharmBaryon(), - candidate.yDecayVtxCharmBaryon(), - candidate.zDecayVtxCharmBaryon(), - candidate.xDecayVtxCascade(), - candidate.yDecayVtxCascade(), - candidate.zDecayVtxCascade(), - candidate.xDecayVtxV0(), - candidate.yDecayVtxV0(), - candidate.zDecayVtxV0(), - candidate.signDecay(), - RecoDecay::pt(candidate.pxCharmBaryon(), candidate.pyCharmBaryon()), - RecoDecay::pt(candidate.pxBachFromCharmBaryon(), candidate.pyBachFromCharmBaryon()), - candidate.pxCharmBaryon(), - candidate.pyCharmBaryon(), - candidate.pzCharmBaryon(), - candidate.pxBachFromCharmBaryon(), - candidate.pyBachFromCharmBaryon(), - candidate.pzBachFromCharmBaryon(), - candidate.pxBachFromCasc(), - candidate.pyBachFromCasc(), - candidate.pzBachFromCasc(), - candidate.pxPosV0Dau(), - candidate.pyPosV0Dau(), - candidate.pzPosV0Dau(), - candidate.pxNegV0Dau(), - candidate.pyNegV0Dau(), - candidate.pzNegV0Dau(), - candidate.impactParCascXY(), - candidate.impactParBachFromCharmBaryonXY(), - candidate.errImpactParCascXY(), - candidate.errImpactParBachFromCharmBaryonXY(), - candidate.invMassLambda(), - candidate.invMassCascade(), - candidate.invMassCharmBaryon(), - candidate.cosPAV0(), - candidate.cosPACharmBaryon(), - candidate.cosPACasc(), - candidate.etaV0PosDau(), - candidate.etaV0NegDau(), - candidate.etaBachFromCasc(), - candidate.etaBachFromCharmBaryon(), - candidate.etaCharmBaryon(), - candidate.dcaXYToPvV0Dau0(), - candidate.dcaXYToPvV0Dau1(), - candidate.dcaXYToPvCascDau(), - candidate.dcaCascDau(), - candidate.dcaV0Dau(), - candidate.dcaCharmBaryonDau(), - candidate.errorDecayLengthCharmBaryon(), - candidate.impactParCascXY() / candidate.errImpactParCascXY(), - candidate.impactParBachFromCharmBaryonXY() / candidate.errImpactParBachFromCharmBaryonXY(), - candidate.template bachelorFromCharmBaryon_as().isGlobalTrackWoDCA(), - candidate.template bachelorFromCharmBaryon_as().itsNCls(), - candidate.template bachelorFromCharmBaryon_as().tpcNClsCrossedRows(), - candidate.template bachelor_as().tpcNClsCrossedRows(), - candidate.template posTrack_as().tpcNClsCrossedRows(), - candidate.template negTrack_as().tpcNClsCrossedRows(), - candidate.pidTpcInfoStored(), - candidate.pidTofInfoStored(), - candidate.tpcNSigmaPiFromCharmBaryon(), - candidate.tpcNSigmaPiFromCasc(), - candidate.tpcNSigmaPiFromLambda(), - candidate.tpcNSigmaPrFromLambda(), - candidate.tofNSigmaPiFromCharmBaryon(), - candidate.tofNSigmaPiFromCasc(), - candidate.tofNSigmaPiFromLambda(), - candidate.tofNSigmaPrFromLambda(), + candidate.xSecondaryVertex(), + candidate.ySecondaryVertex(), + candidate.zSecondaryVertex(), + candidate.xCascadeVertex(), + candidate.yCascadeVertex(), + candidate.zCascadeVertex(), + candidate.xV0Vertex(), + candidate.yV0Vertex(), + candidate.zV0Vertex(), + trackPiFromCasc.sign(), + candidate.pt(), + RecoDecay::pt(candidate.pxProng1(), candidate.pyProng1()), + candidate.px(), + candidate.py(), + candidate.pz(), + candidate.pxProng1(), + candidate.pyProng1(), + candidate.pzProng1(), + trackPiFromCasc.px(), + trackPiFromCasc.py(), + trackPiFromCasc.pz(), + trackV0PosDau.px(), + trackV0PosDau.py(), + trackV0PosDau.pz(), + trackV0NegDau.px(), + trackV0NegDau.py(), + trackV0NegDau.pz(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.errorImpactParameter0(), + candidate.errorImpactParameter1(), + candidate.massLambda(), + candidate.massCascade(), + HfHelper::invMassXiczeroToXiPi(candidate), + candidate.cpaV0(), + candidate.cpa(), + candidate.cpaCascade(), + trackV0PosDau.eta(), + trackV0NegDau.eta(), + trackPiFromCasc.eta(), + trackPiFromCharm.eta(), + candidate.eta(), + candidate.impactParameterXYV0PosDau(), + candidate.impactParameterXYV0NegDau(), + candidate.impactParameterXYCascadeBach(), + candidate.dcaCascadeDaughters(), + candidate.dcaV0Daughters(), + candidate.dcaDaughters(), + candidate.errorDecayLength(), + candidate.impactParameterNormalised0(), + candidate.impactParameterNormalised1(), + trackPiFromCharm.isGlobalTrackWoDCA(), + trackPiFromCharm.itsNCls(), + trackPiFromCharm.tpcNClsCrossedRows(), + trackPiFromCasc.tpcNClsCrossedRows(), + trackV0PosDau.tpcNClsCrossedRows(), + trackV0NegDau.tpcNClsCrossedRows(), + trackPiFromCharm.tpcNSigmaPi(), + trackPiFromCasc.tpcNSigmaPi(), + trackPiFromLam.tpcNSigmaPi(), + trackPrFromLam.tpcNSigmaPr(), + trackPiFromCharm.tofNSigmaPi(), + trackPiFromCasc.tofNSigmaPi(), + trackPiFromLam.tofNSigmaPi(), + trackPrFromLam.tofNSigmaPr(), flagMc, - originMc, - collisionMatched); + originMc); } else { - rowCandidateFull(candidate.xPv(), - candidate.yPv(), - candidate.zPv(), + rowCandidateFull(candidate.posX(), + candidate.posY(), + candidate.posZ(), centrality, candidate.template collision_as().numContrib(), candidate.template collision_as().chi2(), - candidate.xDecayVtxCharmBaryon(), - candidate.yDecayVtxCharmBaryon(), - candidate.zDecayVtxCharmBaryon(), - candidate.xDecayVtxCascade(), - candidate.yDecayVtxCascade(), - candidate.zDecayVtxCascade(), - candidate.xDecayVtxV0(), - candidate.yDecayVtxV0(), - candidate.zDecayVtxV0(), - candidate.signDecay(), - candidate.covVtxCharmBaryon0(), - candidate.covVtxCharmBaryon3(), - candidate.covVtxCharmBaryon5(), - RecoDecay::pt(candidate.pxCharmBaryon(), candidate.pyCharmBaryon()), - RecoDecay::pt(candidate.pxBachFromCharmBaryon(), candidate.pyBachFromCharmBaryon()), - candidate.pxCharmBaryon(), - candidate.pyCharmBaryon(), - candidate.pzCharmBaryon(), - candidate.pxCasc(), - candidate.pyCasc(), - candidate.pzCasc(), - candidate.pxBachFromCharmBaryon(), - candidate.pyBachFromCharmBaryon(), - candidate.pzBachFromCharmBaryon(), - candidate.pxLambda(), - candidate.pyLambda(), - candidate.pzLambda(), - candidate.pxBachFromCasc(), - candidate.pyBachFromCasc(), - candidate.pzBachFromCasc(), - candidate.pxPosV0Dau(), - candidate.pyPosV0Dau(), - candidate.pzPosV0Dau(), - candidate.pxNegV0Dau(), - candidate.pyNegV0Dau(), - candidate.pzNegV0Dau(), - candidate.impactParCascXY(), - candidate.impactParBachFromCharmBaryonXY(), - candidate.impactParCascZ(), - candidate.impactParBachFromCharmBaryonZ(), - candidate.errImpactParCascXY(), - candidate.errImpactParBachFromCharmBaryonXY(), - candidate.invMassLambda(), - candidate.invMassCascade(), - candidate.invMassCharmBaryon(), - candidate.cosPAV0(), - candidate.cosPACharmBaryon(), - candidate.cosPACasc(), - candidate.cosPAXYV0(), - candidate.cosPAXYCharmBaryon(), - candidate.cosPAXYCasc(), - candidate.cTauOmegac(), - candidate.cTauCascade(), - candidate.cTauV0(), - candidate.cTauXic(), - candidate.etaV0PosDau(), - candidate.etaV0NegDau(), - candidate.etaBachFromCasc(), - candidate.etaBachFromCharmBaryon(), - candidate.etaCharmBaryon(), + candidate.xSecondaryVertex(), + candidate.ySecondaryVertex(), + candidate.zSecondaryVertex(), + candidate.xCascadeVertex(), + candidate.yCascadeVertex(), + candidate.zCascadeVertex(), + candidate.xV0Vertex(), + candidate.yV0Vertex(), + candidate.zV0Vertex(), + trackPiFromCasc.sign(), + candidate.pt(), + RecoDecay::pt(candidate.pxProng1(), candidate.pyProng1()), + candidate.px(), + candidate.py(), + candidate.pz(), + candidate.pxProng0(), + candidate.pyProng0(), + candidate.pzProng0(), + candidate.pxProng1(), + candidate.pyProng1(), + candidate.pzProng1(), + trackPiFromCasc.px(), + trackPiFromCasc.py(), + trackPiFromCasc.pz(), + trackV0PosDau.px(), + trackV0PosDau.py(), + trackV0PosDau.pz(), + trackV0NegDau.px(), + trackV0NegDau.py(), + trackV0NegDau.pz(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameterZ0(), + candidate.impactParameterZ1(), + candidate.errorImpactParameter0(), + candidate.errorImpactParameter1(), + candidate.massLambda(), + candidate.massCascade(), + HfHelper::invMassXiczeroToXiPi(candidate), + candidate.cpaV0(), + candidate.cpa(), + candidate.cpaCascade(), + candidate.cpaXYV0(), + candidate.cpaXY(), + candidate.cpaXYCascade(), + HfHelper::ctXiczero(candidate), + trackV0PosDau.eta(), + trackV0NegDau.eta(), + trackPiFromCasc.eta(), + trackPiFromCharm.eta(), + candidate.eta(), candidate.etaCascade(), candidate.etaV0(), - candidate.dcaXYToPvV0Dau0(), - candidate.dcaXYToPvV0Dau1(), - candidate.dcaXYToPvCascDau(), - candidate.dcaZToPvV0Dau0(), - candidate.dcaZToPvV0Dau1(), - candidate.dcaZToPvCascDau(), - candidate.dcaCascDau(), - candidate.dcaV0Dau(), - candidate.dcaCharmBaryonDau(), - candidate.decLenCharmBaryon(), - candidate.decLenCascade(), - candidate.decLenV0(), - candidate.errorDecayLengthCharmBaryon(), - candidate.errorDecayLengthXYCharmBaryon(), - candidate.impactParCascXY() / candidate.errImpactParCascXY(), - candidate.impactParBachFromCharmBaryonXY() / candidate.errImpactParBachFromCharmBaryonXY(), - candidate.decLenCharmBaryon() / candidate.errorDecayLengthCharmBaryon(), - candidate.template bachelorFromCharmBaryon_as().isGlobalTrackWoDCA(), - candidate.template bachelorFromCharmBaryon_as().itsNCls(), - candidate.template bachelorFromCharmBaryon_as().tpcNClsCrossedRows(), - candidate.template bachelor_as().tpcNClsCrossedRows(), - candidate.template posTrack_as().tpcNClsCrossedRows(), - candidate.template negTrack_as().tpcNClsCrossedRows(), - candidate.statusPidLambda(), - candidate.statusPidCascade(), - candidate.statusPidCharmBaryon(), - candidate.statusInvMassLambda(), - candidate.statusInvMassCascade(), - candidate.statusInvMassCharmBaryon(), - candidate.resultSelections(), - candidate.pidTpcInfoStored(), - candidate.pidTofInfoStored(), - candidate.tpcNSigmaPiFromCharmBaryon(), - candidate.tpcNSigmaPiFromCasc(), - candidate.tpcNSigmaPiFromLambda(), - candidate.tpcNSigmaPrFromLambda(), - candidate.tofNSigmaPiFromCharmBaryon(), - candidate.tofNSigmaPiFromCasc(), - candidate.tofNSigmaPiFromLambda(), - candidate.tofNSigmaPrFromLambda(), + candidate.impactParameterXYV0PosDau(), + candidate.impactParameterXYV0NegDau(), + candidate.impactParameterXYCascadeBach(), + candidate.impactParameterZV0PosDau(), + candidate.impactParameterZV0NegDau(), + candidate.impactParameterZCascadeBach(), + candidate.dcaCascadeDaughters(), + candidate.dcaV0Daughters(), + candidate.dcaDaughters(), + candidate.decayLength(), + candidate.decayLengthCascade(), + candidate.decayLengthV0(), + candidate.errorDecayLength(), + candidate.errorDecayLengthXY(), + candidate.impactParameterNormalised0(), + candidate.impactParameterNormalised1(), + candidate.decayLengthNormalised(), + trackPiFromCharm.isGlobalTrackWoDCA(), + trackPiFromCharm.itsNCls(), + trackPiFromCharm.tpcNClsCrossedRows(), + trackPiFromCasc.tpcNClsCrossedRows(), + trackV0PosDau.tpcNClsCrossedRows(), + trackV0NegDau.tpcNClsCrossedRows(), + trackPiFromCharm.tpcNSigmaPi(), + trackPiFromCasc.tpcNSigmaPi(), + trackPiFromLam.tpcNSigmaPi(), + trackPrFromLam.tpcNSigmaPr(), + trackPiFromCharm.tofNSigmaPi(), + trackPiFromCasc.tofNSigmaPi(), + trackPiFromLam.tofNSigmaPi(), + trackPrFromLam.tofNSigmaPr(), flagMc, - debugMc, - originMc, - collisionMatched); + originMc); } } else { if constexpr (tableSize == LITE) { // currently, no lite sized table for KFParticle } else { rowKfCandidate(centrality, - candidate.tpcNSigmaPiFromCharmBaryon(), - candidate.tofNSigmaPiFromCharmBaryon(), - candidate.tpcNSigmaPiFromCasc(), - candidate.tofNSigmaPiFromCasc(), - candidate.tpcNSigmaPiFromLambda(), - candidate.tofNSigmaPiFromLambda(), - candidate.tpcNSigmaPrFromLambda(), - candidate.tofNSigmaPrFromLambda(), - candidate.kfDcaXYPiFromXic(), - candidate.dcaCascDau(), - candidate.dcaV0Dau(), - candidate.dcaCharmBaryonDau(), - candidate.kfDcaXYCascToPv(), - candidate.dcaXYToPvV0Dau0(), - candidate.dcaXYToPvV0Dau1(), - candidate.dcaXYToPvCascDau(), + trackPiFromCharm.tpcNSigmaPi(), + trackPiFromCharm.tofNSigmaPi(), + trackPiFromCasc.tpcNSigmaPi(), + trackPiFromCasc.tofNSigmaPi(), + trackPiFromLam.tpcNSigmaPi(), + trackPiFromLam.tofNSigmaPi(), + trackPrFromLam.tpcNSigmaPr(), + trackPrFromLam.tofNSigmaPr(), + candidate.impactParameter1(), + candidate.dcaCascadeDaughters(), + candidate.dcaV0Daughters(), + candidate.dcaDaughters(), + candidate.impactParameter0(), + candidate.impactParameterXYV0PosDau(), + candidate.impactParameterXYV0NegDau(), + candidate.impactParameterXYCascadeBach(), candidate.chi2GeoV0(), - candidate.chi2GeoCasc(), - candidate.chi2GeoXic(), - candidate.chi2MassV0(), - candidate.chi2MassCasc(), - candidate.v0ldl(), - candidate.cascldl(), - candidate.chi2TopoV0ToPv(), - candidate.chi2TopoCascToPv(), - candidate.chi2TopoPiFromXicToPv(), - candidate.chi2TopoXicToPv(), - candidate.chi2TopoV0ToCasc(), - candidate.chi2TopoCascToXic(), - candidate.decayLenXYLambda(), - candidate.decayLenXYCasc(), - candidate.decayLenXYXic(), - candidate.cosPaV0ToCasc(), - candidate.cosPAV0(), - candidate.cosPaCascToXic(), - candidate.cosPACasc(), - candidate.invMassLambda(), - candidate.invMassCascade(), - candidate.invMassCharmBaryon(), - candidate.kfRapXic(), - RecoDecay::sqrtSumOfSquares(candidate.pxBachFromCharmBaryon(), candidate.pyBachFromCharmBaryon()), - RecoDecay::sqrtSumOfSquares(candidate.pxCharmBaryon(), candidate.pyCharmBaryon()), - candidate.cosThetaStarPiFromXic(), - candidate.cTauXic(), - candidate.etaCharmBaryon(), - candidate.v0Ndf(), - candidate.cascNdf(), - candidate.xicNdf(), - candidate.massV0Ndf(), - candidate.massCascNdf(), - candidate.v0Chi2OverNdf(), - candidate.cascChi2OverNdf(), - candidate.xicChi2OverNdf(), - candidate.massV0Chi2OverNdf(), - candidate.massCascChi2OverNdf(), - candidate.resultSelections(), + candidate.chi2GeoCascade(), + candidate.chi2Geo(), + candidate.decayLengthNormKfV0(), + candidate.decayLengthNormKfCascade(), + candidate.chi2TopoOverNdfV0ToPv(), + candidate.chi2TopoOverNdfCascadeToPv(), + candidate.chi2TopoOverNdfToPv(), + candidate.chi2TopoOverNdfV0ToCascade(), + candidate.chi2TopoOverNdfCascadeToCharmHadron(), + candidate.decayLengthXYV0(), + candidate.decayLengthXYCascade(), + candidate.decayLengthXY(), + candidate.cpaV0ToCascade(), + candidate.cpaV0(), + candidate.cpaCascadeToCharmHadron(), + candidate.cpaCascade(), + candidate.massLambda(), + candidate.massCascade(), + HfHelper::invMassXiczeroToXiPi(candidate), + HfHelper::yXiczero(candidate), + RecoDecay::sqrtSumOfSquares(candidate.pxProng1(), candidate.pyProng1()), + candidate.pt(), + HfHelper::cosThetaStarXiczeroToXiPi(candidate), + HfHelper::ctXiczero(candidate), + candidate.eta(), + candidate.ndfGeoV0(), + candidate.ndfGeoCascade(), + candidate.ndfGeo(), + candidate.chi2GeoOverNdfV0(), + candidate.chi2GeoOverNdfCascade(), + candidate.chi2GeoOverNdf(), flagMc, - debugMc, - originMc, - collisionMatched); + originMc); } } } @@ -667,7 +628,7 @@ struct HfTreeCreatorToXiPiQa { for (const auto& particle : mcParticles) { auto ptGen = particle.pt(); - auto yGen = particle.rapidityCharmBaryonGen(); + auto yGen = particle.y(); int nContribMax = 0; bool recoCollPassedTvx = false; @@ -721,7 +682,8 @@ struct HfTreeCreatorToXiPiQa { //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// void processDataFull(MyEventTable const& collisions, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableDca const& candidates) { // Filling event properties @@ -733,12 +695,13 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowCandidateFull.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + fillCandidate(candidate, tracks, lfTracks, -7, RecoDecay::OriginType::None); } } void processDataLite(MyEventTable const& collisions, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableDca const& candidates) { // Filling event properties @@ -750,12 +713,13 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowCandidateLite.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + fillCandidate(candidate, tracks, lfTracks, -7, RecoDecay::OriginType::None); } } void processDataLiteWithFT0M(MyEventTableWithFT0M const& collisions, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableDca const& candidates) { // Filling event properties @@ -767,12 +731,13 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowCandidateLite.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + fillCandidate(candidate, tracks, lfTracks, -7, RecoDecay::OriginType::None); } } void processDataLiteWithFT0C(MyEventTableWithFT0C const& collisions, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableDca const& candidates) { // Filling event properties @@ -784,12 +749,13 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowCandidateLite.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + fillCandidate(candidate, tracks, lfTracks, -7, RecoDecay::OriginType::None); } } void processDataLiteWithNTracksPV(MyEventTableWithNTracksPV const& collisions, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableDca const& candidates) { // Filling event properties @@ -801,7 +767,7 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowCandidateLite.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + fillCandidate(candidate, tracks, lfTracks, -7, RecoDecay::OriginType::None); } } @@ -815,7 +781,8 @@ struct HfTreeCreatorToXiPiQa { //*~~~~~~~Data with KFParticle~~~~~~~~*// //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// void processKfData(MyEventTable const& collisions, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableKf const& candidates) { // Filling event properties @@ -827,12 +794,13 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + fillCandidate(candidate, tracks, lfTracks, -7, RecoDecay::OriginType::None); } } void processKfDataWithFT0M(MyEventTableWithFT0M const& collisions, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableKf const& candidates) { // Filling event properties @@ -844,12 +812,13 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + fillCandidate(candidate, tracks, lfTracks, -7, RecoDecay::OriginType::None); } } void processKfDataWithFT0C(MyEventTableWithFT0C const& collisions, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableKf const& candidates) { // Filling event properties @@ -861,12 +830,13 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + fillCandidate(candidate, tracks, lfTracks, -7, RecoDecay::OriginType::None); } } void processKfDataWithNTracksPV(MyEventTableWithNTracksPV const& collisions, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableKf const& candidates) { // Filling event properties @@ -878,7 +848,7 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + fillCandidate(candidate, tracks, lfTracks, -7, RecoDecay::OriginType::None); } } @@ -893,7 +863,8 @@ struct HfTreeCreatorToXiPiQa { void processMcFullXic0(MyEventTableWithMcLabels const& collsWithMcLable, aod::McCollisions const&, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableXic0McDca const& candidates, MatchedGenXiPi const& mcParticles) { @@ -906,7 +877,7 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowCandidateFull.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec()); } // Filling particle properties if requested @@ -918,7 +889,8 @@ struct HfTreeCreatorToXiPiQa { void processMcFullOmegac0(MyEventTableWithMcLabels const& collsWithMcLable, aod::McCollisions const&, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableOmegac0McDca const& candidates, MatchedGenXiPi const& mcParticles) { @@ -931,7 +903,7 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowCandidateFull.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec()); } // Filling particle properties if requested @@ -943,7 +915,8 @@ struct HfTreeCreatorToXiPiQa { void processMcLiteXic0(MyEventTableWithMcLabels const& collsWithMcLable, aod::McCollisions const&, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableXic0McDca const& candidates, MatchedGenXiPi const& mcParticles) { @@ -956,7 +929,7 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowCandidateLite.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, candidate.flagMcMatchRec(), -7, candidate.originMcRec(), candidate.collisionMatched()); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec()); } // Filling particle properties if requested @@ -966,9 +939,10 @@ struct HfTreeCreatorToXiPiQa { } } - void processMcLiteXic0WithFT0C(MyEventTableWithMcLabels const& collsWithMcLable, + void processMcLiteXic0WithFT0C(MyEventTableWithMcLabelsFT0C const& collsWithMcLable, McCollisionsCentFT0Cs const&, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableXic0McDca const& candidates, MatchedGenXiPi const& mcParticles) { @@ -981,7 +955,7 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowCandidateLite.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, candidate.flagMcMatchRec(), -7, candidate.originMcRec(), candidate.collisionMatched()); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec()); } // Filling particle properties if requested @@ -991,9 +965,10 @@ struct HfTreeCreatorToXiPiQa { } } - void processMcLiteXic0WithFT0M(MyEventTableWithMcLabels const& collsWithMcLable, + void processMcLiteXic0WithFT0M(MyEventTableWithMcLabelsFT0M const& collsWithMcLable, McCollisionsCentFT0Ms const&, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableXic0McDca const& candidates, MatchedGenXiPi const& mcParticles) { @@ -1006,7 +981,7 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowCandidateLite.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, candidate.flagMcMatchRec(), -7, candidate.originMcRec(), candidate.collisionMatched()); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec()); } // Filling particle properties if requested @@ -1016,9 +991,10 @@ struct HfTreeCreatorToXiPiQa { } } - void processMcLiteXic0WithNTracksPV(MyEventTableWithMcLabels const& collsWithMcLable, + void processMcLiteXic0WithNTracksPV(MyEventTableWithMcLabelsNTracksPV const& collsWithMcLable, aod::McCollisions const&, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableXic0McDca const& candidates, MatchedGenXiPi const& mcParticles) { @@ -1031,7 +1007,7 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowCandidateLite.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, candidate.flagMcMatchRec(), -7, candidate.originMcRec(), candidate.collisionMatched()); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec()); } // Filling particle properties if requested @@ -1043,7 +1019,8 @@ struct HfTreeCreatorToXiPiQa { void processMcLiteOmegac0(MyEventTableWithMcLabels const& collsWithMcLable, aod::McCollisions const&, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableOmegac0McDca const& candidates, MatchedGenXiPi const& mcParticles) { @@ -1056,7 +1033,7 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowCandidateLite.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, candidate.flagMcMatchRec(), -7, candidate.originMcRec(), candidate.collisionMatched()); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec()); } // Filling particle properties if requested @@ -1079,7 +1056,8 @@ struct HfTreeCreatorToXiPiQa { //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// void processKfMcXic0(MyEventTableWithMcLabels const& collsWithMcLable, aod::McCollisions const&, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableXic0McKf const& candidates, MatchedGenXiPi const& mcParticles) { @@ -1092,7 +1070,7 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec()); } // Filling particle properties if requested @@ -1102,9 +1080,10 @@ struct HfTreeCreatorToXiPiQa { } } - void processKfMcXic0WithFT0C(MyEventTableWithMcLabels const& collsWithMcLable, + void processKfMcXic0WithFT0C(MyEventTableWithMcLabelsFT0C const& collsWithMcLable, McCollisionsCentFT0Cs const&, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableXic0McKf const& candidates, MatchedGenXiPi const& mcParticles) { @@ -1117,7 +1096,7 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec()); } // Filling particle properties if requested @@ -1127,9 +1106,10 @@ struct HfTreeCreatorToXiPiQa { } } - void processKfMcXic0WithFT0M(MyEventTableWithMcLabels const& collsWithMcLable, + void processKfMcXic0WithFT0M(MyEventTableWithMcLabelsFT0M const& collsWithMcLable, McCollisionsCentFT0Ms const&, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableXic0McKf const& candidates, MatchedGenXiPi const& mcParticles) { @@ -1142,7 +1122,7 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate properties rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec()); } // Filling particle properties if requested @@ -1152,9 +1132,10 @@ struct HfTreeCreatorToXiPiQa { } } - void processKfMcXic0WithNTracksPV(MyEventTableWithMcLabels const& collsWithMcLable, + void processKfMcXic0WithNTracksPV(MyEventTableWithMcLabelsNTracksPV const& collsWithMcLable, aod::McCollisions const&, - MyTrackTable const&, + MyTrackTable const& tracks, + MyTrackTableLf const& lfTracks, MyCandTableXic0McKf const& candidates, MatchedGenXiPi const& mcParticles) { @@ -1167,7 +1148,7 @@ struct HfTreeCreatorToXiPiQa { // Filling candidate table rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); + fillCandidate(candidate, tracks, lfTracks, candidate.flagMcMatchRec(), candidate.originMcRec()); } // Filling particle properties if requested